PAYATHON 2026

调用 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,可以按以下步骤处理:

  1. 下载或安装与当前 API 版本对应的 .NET SDK;
  2. 在项目中引用相关 DLL 或 NuGet 包;
  3. 查找 assembly 中 HostedPaymentData 的完整命名空间;
  4. 使用完整类型名,或添加对应的 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 接口要求的请求体。更合理的流程是:

  1. 服务端读取并验证商户配置;
  2. 按照 Hosted Payments 规范创建支付会话或支付请求;
  3. 将接口返回的 token、session ID 或托管页面地址传给前端;
  4. 前端加载 Elavon 托管的支付页面或组件;
  5. 服务端验证最终支付结果。

使用 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# 项目。

备注:内容仅供参考。