调用 Elavon customer payment API 时找不到 HostedPaymentData
结论
HostedPaymentData 不是 merchant detail API 返回的对象,也不会根据返回的 XML 自动生成。你引用的 URL 指向的是 Java + HTML/JavaScript 示例:
.../process-payment/java/html_js
示例中的 HostedPaymentData 很可能是 Java SDK 或示例工程定义的数据模型,无法直接用于 C# 的 TransactionController.cs。除非项目已经引用了包含该类型的 .NET assembly,否则添加 using 也解决不了问题。
先获取商户配置,再发起 Hosted Payments,这个整体思路可能没有问题。问题在于,Java 示例代码不能直接移植到 ASP.NET MVC。
为什么会出现这个错误
下面这行代码要求当前 C# 项目中已经存在 HostedPaymentData 类型:
var hostedPaymentData = new HostedPaymentData();
编译器会从这些位置查找该类型:
- 当前项目中的类;
- 已引用项目中的
public类; - 已安装并引用的 .NET assembly 或 NuGet 包;
using指向的命名空间。
merchant detail API 返回的 XML 是运行时数据,不能在编译阶段为项目创建 HostedPaymentData 类型。因此,即使 XML 已经成功获取并传递,编译错误仍然存在。
应该如何处理
1. 确认文档语言和产品版本
先检查 Elavon 文档页面能否切换到 C#、.NET 或 REST 示例。路径中包含 /java/ 的代码不能作为 C# SDK 的使用依据。
同时确认 merchant detail API 和 payment API 是否属于同一个 Elavon 产品、环境及 API 版本。Elavon 有多个支付产品,名称相似的数据模型未必能够互换。
2. 检查官方示例或 SDK 中是否真的存在该类型
如果 Elavon 为这套 Hosted Payments API 提供了 .NET SDK,可以按以下步骤处理:
- 下载或安装与当前 API 版本对应的 .NET SDK;
- 在项目中引用相关 DLL 或 NuGet 包;
- 查找 assembly 中
HostedPaymentData的完整命名空间; - 使用完整类型名,或添加对应的
using。
只有当 SDK 中确实存在该类型时,下面的代码才有效:
using Elavon.SomeNamespace;
// ...
var hostedPaymentData = new HostedPaymentData();
这里的 Elavon.SomeNamespace 只是用于说明代码结构,并不是真实命名空间。具体名称应以下载的 SDK、API 文档或示例工程为准。
你可以通过 IDE 的对象浏览器、解决方案搜索或“转到类型”功能查找:
HostedPaymentData
如果整个 .NET SDK 中都找不到这个名称,就没有必要继续尝试添加不同的 using。
3. 没有 .NET 类型时,定义自己的请求模型
如果该 API 通过 HTTP 提交 XML、JSON 或表单字段,并且官方没有提供 .NET SDK,那么 HostedPaymentData 只是示例工程使用的封装类。此时需要按照接口定义创建自己的 C# DTO。
例如:
public sealed class HostedPaymentRequest
{
public string MerchantId { get; set; }
public string Amount { get; set; }
public string Currency { get; set; }
public string OrderReference { get; set; }
public string ReturnUrl { get; set; }
}
然后在控制器中使用这个类型:
[HttpPost]
public async Task<ActionResult> Create(Eslopes collection)
{
var request = new HostedPaymentRequest
{
MerchantId = collection.MerchantId,
Amount = collection.Amount,
Currency = collection.Currency,
OrderReference = collection.OrderReference,
ReturnUrl = collection.ReturnUrl
};
// 按 Elavon 当前接口文档要求:
// 1. 序列化为 XML、JSON 或表单数据;
// 2. 加入认证信息或签名;
// 3. 发送到 Hosted Payments 对应的测试环境端点;
// 4. 处理返回的 session、token 或跳转地址。
return View();
}
这些属性只用于展示 C# 模型的组织方式。实际字段名、必填项、数据类型和序列化格式必须严格遵循当前 Elavon API 版本的定义,不能根据 Java 类名自行推断。
如果接口要求 XML,可以为模型添加 XML 映射:
using System.Xml.Serialization;
[XmlRoot("HostedPaymentRequest")]
public sealed class HostedPaymentRequest
{
[XmlElement("merchantId")]
public string MerchantId { get; set; }
[XmlElement("amount")]
public string Amount { get; set; }
[XmlElement("currency")]
public string Currency { get; set; }
}
序列化示例:
private static string SerializeToXml<T>(T value)
{
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, value);
return writer.ToString();
}
}
XML 元素名称同样要以接口规范为准。
不要把 merchant detail 响应直接当作支付请求
merchant detail API 的响应通常用于读取商户配置或可用能力,并不等同于 process payment 接口要求的请求体。更合理的流程是:
- 服务端读取并验证商户配置;
- 按照 Hosted Payments 规范创建支付会话或支付请求;
- 将接口返回的 token、session ID 或托管页面地址传给前端;
- 前端加载 Elavon 托管的支付页面或组件;
- 服务端验证最终支付结果。
使用 Hosted Payments 时,敏感卡数据一般应由 Elavon 托管的页面或字段采集。不要为了复现 Java 示例,让 ASP.NET MVC 控制器接收、记录或保存完整卡号、CVV 等数据,否则会扩大 PCI DSS 合规范围。
还要注意异步调用
在 ASP.NET MVC 中调用远程支付接口时,不建议采用同步阻塞方式。控制器可以改为异步:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Eslopes collection)
{
if (!ModelState.IsValid)
{
return View(collection);
}
var paymentRequest = BuildPaymentRequest(collection);
var paymentResult = await SendPaymentRequestAsync(paymentRequest);
return View("Result", paymentResult);
}
BuildPaymentRequest 和 SendPaymentRequestAsync 需要根据 Elavon 的实际请求格式实现。
最终要解决的并不是“该添加哪个 using”,而是找到正确的 .NET 集成资料。如果官方 .NET SDK 包含 HostedPaymentData,就引用对应的 SDK 和命名空间;如果不包含,就按照 REST/XML 规范定义自己的 C# 请求模型。Java 示例中的同名类型不能直接用于 C# 项目。
备注:内容仅供参考。
