Antom, leading provider of tailored payment solutions

Payment Element 集成

Antom Payment Element 是基于 SDK 集成的支付组件,旨在为您打造完美无缝的支付体验,助力提升支付转化率。针对不同的终端类型,Antom 提供以下适配方案:
  • Web/WAP 端:适用于浏览器及移动网页环境的 Web Element
  • App 端(Android & iOS & Flutter):专为商户自有移动应用设计的 Mobile Element
各端 Payment Element 支持的能力如下表所示:
特性
描述
Web/WAP
Android
iOS
Flutter
Payment Element 渲染支付方式列表
您可以选择由 Payment Element 为您默认在收银台页面上渲染所有支持的支付方式。您也可以通过指定支付方式,灵活选择需要展示的选项。
✔️
✔️
✔️
✔️
商户自行渲染支付方式(单支付方式集成)
您可以按照业务需求指定单个支付方式,以展示定制化的支付方式列表。
注意:对于部分支付方式(例如卡支付),您需要嵌入 Payment Element 渲染的支付要素组件。
✔️
✔️
✔️
✔️
嵌入式体验
支付表单直接内嵌在您的商户页面中,体验无缝集成。
✔️
❌
❌
❌
弹窗式体验
点击后弹出独立窗口完成支付,集成简单且安全隔离。
❌
✔️
✔️
✔️
使用 appearance 参数自定义支付界面的视觉样式和布局,包括主题选择、布局配置和 CSS 样式自定义。
✔️
✔️
✔️
✔️
自定义支付按钮
您可以自定义支付按钮。当买家点击您自定义的支付按钮时,您需调用 submitPayment() 方法来提交支付。
✔️
❌
❌
❌
Web/WAP

用户体验

Web
以下图片展示了不同场景下使用 Payment Element 的用户体验:
Payment Element 渲染支付方式列表
以下图片展示了嵌入 Payment Element 渲染的支付方式的模板:
如您选择由 Payment Element 渲染支付方式列表,Payment Element 默认在收银台页面上渲染所有支持的支付方式。以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
存卡支付
由 Payment Element 处理存卡支付场景:
商户自行渲染支付方式
以下图片展示了商户自行渲染支付方式的模板:
如您通过自行指定支付方式渲染支付方式列表,以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
WAP
以下图片展示了不同场景下使用 Payment Element 的用户体验:
Payment Element 渲染支付方式列表
以下图片展示了嵌入 Payment Element 渲染的支付方式的模板:
如您选择由 Payment Element 渲染支付方式列表,Payment Element 默认在收银台页面上渲染所有支持的支付方式。以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
存卡支付
由 Payment Element 处理存卡支付场景:
商户自行渲染支付方式
以下图片展示了商户自行渲染支付方式的模板:
如您通过自行指定支付方式渲染支付方式列表,以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:

订单生命周期

以下是不同支付方式的生命周期:
APM 支付
对于 APM 支付,如 Alipay、Touch'n Go eWallet 等支付方式,当您发起支付请求且买家完成支付后,资金将直接转移到您的账户中。您可在窗口期内对订单进行撤销或者退款操作。
卡支付、Apple Pay、Google Pay
对于卡支付、Apple Pay、Google Pay,订单主要包括以下阶段:
  1. 授权:买家使用银行卡完成支付后,其资金将处于冻结状态。买家下单至完成授权期间,您都可以在窗口期内对订单发起撤销。
  2. 请款:你可以通过手动请款将买家的冻结资金转移到您的账户;或通过自动请款让 Antom 替您完成请款,具体信息请参阅请款。请款完成后,若有需要,您可以在窗口期内发起退款。
  3. 拒付:您需要根据情况发起拒付抗辩申请,具体信息请参阅争议。

支付流程

以下图片展示了如何通过 Payment Element 集成单笔支付:
Payment Element 渲染支付方式
商户自行渲染支付方式
  1. 买家进入结账页面并发起支付。
  2. 创建支付会话请求。
    您可以调用 createPaymentSession(单笔支付)接口获取支付会话。
  3. 调用 Payment Element。
    在客户端,通过支付会话调用 Payment Element。您可以选择由 Payment Element 或者您自行渲染支付方式,同时 Payment Element 会根据支付方式的特性处理信息、收集支付要素、进行重定向、应用调用、二维码显示、验证等流程。当支付完成后,根据您的设置以及支付方式特性,您需要按照 submitPayment().then() 方法返回的结果处理跳转流程或者由系统自动回跳到您的支付结果页面。
  4. 获取支付结果。
    通过以下两种方法之一获取支付结果:
注意:在卡支付、Apple Pay、Google Pay 支付场景下,采用的是授权请款模式。步骤 1 至 4 仅完成了授权部分,即买家使用银行卡完成支付,其资金处于冻结状态。为了将买家的冻结资金转至您的账户,您还需要集成请款步骤。请款成功的结果将作为您发货的依据。
  1. 发起请款并获取请款结果。
默认情况下,Antom 会自动为您处理资金请款。您也可以通过调用 capture(单笔支付)接口来手动进行请款。随后,通过以下两种方法之一获取请款结果:

集成准备

在您开始集成前,请阅读集成指南及接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:
  • 已获得 client ID。
  • 已完成密钥配置。
  • 已完成异步通知接收地址的配置。
  • 集成 Antom 服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
  • 参阅 Web/WAP 端集成 SDK 资源包文档来集成客户端 SDK 资源包,并注意使用最新或不低于 1.46.0 版本的 SDK。

集成步骤

请按照以下步骤开始集成:
  1. 创建支付会话
  2. 调用 Payment Element
  3. 获取支付结果
  4. 发起请款

步骤 1:创建支付会话
服务端

传入订单信息以调用 createPaymentSession(单笔支付)接口来创建支付会话,获取唤起 Payment Element 的 paymentSessionData。您可选择由您自定义收银台的支付方式列表或由 Payment Element 为您渲染支付方式列表,并在调用 createPaymentSession(单笔支付)接口时传入相应的参数:
Payment Element 渲染支付方式
当您使用 Payment Element 渲染的支付方式列表时,您只需传入以下参数。Payment Element 默认在收银台页面上渲染所有支持的支付方式,您也可以通过指定支付方式来选择您需要的支付方式。
参数名称
是否必需
描述
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy
是
支付请求的结算策略。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.WAP).osType(OsType.IOS).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
如果由 Payment Element 渲染收银台的支付方式列表,则会展示所有支付方式。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "WAP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "IOS"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
商户自行渲染支付方式
当您自行渲染支付方式列表时,您必须传入下表中列出的指定支付方式参数。请注意,对于部分支付方式(例如卡支付),您需要嵌入 Payment Element 渲染的支付要素组件。以下是提供卡支付选项时调用 createPaymentSession(单笔支付)接口的最佳时机:
类型
参数名称
是否必需
描述
基础参数
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy.settlementCurrency
是
该笔支付的结算币种,若业务签约了多个结算币种,需在接口中指定。
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
卡支付信息参数(具体请参考卡支付特性)
paymentFactor.captureMode
否
请款模式。有效值为:
  • AUTOMATIC:表示在授权后,Antom 自动进行请款。当值为空或未传递此参数时,默认为此值。
  • MANUAL:表示您通过调用 capture(单笔支付)接口进行手动请款。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication
否
您需要根据当前交易的风险和拒付情况,决定是否设置交易认证类型为 3DS 认证。有效值为:
  • true:指交易认证类型为 3DS 认证。
  • false:指交易认证类型为非 3DS 认证。如果此参数为空或未传递,默认为此值。
availablePaymentMethod.paymentMethodMetaData.tokenizeMode
否
如果您需要存储卡信息,可通过此参数让 Antom 帮您保存卡信息,Antom 会将卡信息替换为一个唯一且安全的 token 用于后续支付。有效值为:
  • ENABLED:表示您已获得买家绑卡授权,需要存储卡信息用于后续支付。
  • DISABLED:表示您不需要存储卡信息。当值为空或不指定此参数时同样适用。
  • ASKFORCONSENT:在中间页向买家展示存卡按钮,允许买家选择是否存储卡信息。
availablePaymentMethod.paymentMethodMetaData.isCardOnFile
否
表示该笔交易使用的卡是否曾在商户侧完成过支付并存档。有效值为:
  • true:指该笔交易使用的卡是曾在商户侧完成过支付的已存卡。在已存卡支付场景下,将该参数设置为 true。
  • false:默认值。指该笔交易使用的是未在商户侧进行过支付的新卡。
savedPaymentMethods.paymentMethodId
否
存卡交易下使用,代表传入新卡交易时返回的 cardToken 信息。
指定支付方式参数(具体请参考指定支付方式)
availablePaymentMethod.paymentMethodTypeList.paymentMethodType
否
指定具体的支付方式,支持指定单个或者多个支付方式。参见支付方式枚举值以查看有效值。
availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder
否
设置支付方式的优先级顺序。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.WAP).osType(OsType.IOS).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  // 替换为您的指定支付方式
  AvailablePaymentMethod availablePaymentMethods = AvailablePaymentMethod.builder()
    .paymentMethodTypeList(
      List.of(PaymentMethodTypeItem.builder().paymentMethodType("ALIPAY_CN").build())
    )
    .build();
  alipayPaymentSessionRequest.setAvailablePaymentMethod(availablePaymentMethods);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
当您自行渲染支付方式列表时,需要通过指定单个支付方式集成。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "WAP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "IOS"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // 指定支付方式
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
以下代码展示了一个响应的示例,其中包含以下参数:
  • result.resultStatus:createPaymentSession(单笔支付)接口的调用结果。
  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
{
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
以下是创建支付会话响应中 result.resultStatus 可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付会话已成功创建,同时返回 paymentSessionData。
请继续执行后续步骤。
U
未知问题。
建议更换 paymentRequestId 以解决问题。如果问题未解决,请联系 Antom 技术支持。
F
支付会话创建失败。
建议检查并验证当前接口所需的请求字段(包括头部字段和正文字段)是否正确传递并有效。
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 paymentRequestId 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的兼容性问题,请求中的参数请勿使用中文字符。
​
问:如何设置接收支付通知的地址?
答:在 createPaymentSession(单笔支付)接口的请求中指定 paymentNotifyUrl 参数,以接收支付结果的异步通知(notifyPayment),或者在 Antom Dashboard 中配置接收地址。如果请求和 Antom Dashboard 中都指定了地址,请求中的值优先。
​
问:返回的 paymentSessionData 是否需要处理后再传给客户端?
答:请勿对 paymentSessionData 进行任何处理,否则可能会导致调用 Payment Element 失败。

步骤 2:调用 Payment Element
客户端

在您的客户端使用 paymentSessionData 调用 Payment Element,在买家提交支付后,Payment Element 会根据不同支付方式,负责展示二维码、跳转支付方式页面、3DS 认证、回跳商户结果页等流程。
根据您在步骤 1 中选择渲染支付方式列表的方式(由您自行渲染或由 Payment Element 渲染支付方式列表),以下是不同渲染方式的对比:
方法
集成步骤
由您自行渲染支付方式列表(单支付方式集成)
Payment Element 需要采集支付要素
  1. 调用 mount() 方法来嵌入 Payment Element 渲染出来的支付要素采集组件。
  2. 买家点击您自定义的支付按钮后,您需调用 submitPayment() 方法来提交支付。
Payment Element 不需要采集支付要素
调用 mount() 方法后无需嵌入 Payment Element 渲染的支付要素采集组件。买家点击您自定义的支付按钮后,您可以直接调用 submitPayment() 方法来提交支付。
由 Payment Element 渲染支付方式列表
  1. 调用 mount() 方法来嵌入 Payment Element 渲染出来的支付方式列表。
  2. 买家点击您自定义的支付按钮后,您需调用 submitPayment() 方法来提交支付。
  1. 在服务端获取到 paymentSessionData 后,使用 AMSElement 类来创建 Payment Element 实例。以下是使用 CDN 或 npm 实例化 SDK 的示例代码:
CDN
// 获取浏览器语言
let language = navigator.language || navigator.userLanguage;
language = language.replace("-", "_"); // 将 "-" 替换为 "_"

// 创建 Payment Element 实例
const elementPayment = new window.AMSElement({
  environment: "sandbox",
  locale: "en_US",
  sessionData: sessionData,
});
npm
import { AMSElement, ThemeType, PaymentElementLayout } from "@alipay/ams-checkout"; // 包管理

// 获取浏览器语言
let language = navigator.language || navigator.userLanguage;
language = language.replace("-", "_"); // 将 "-" 替换为 "_"

// 创建 AMSElement 实例
const elementPayment = new AMSElement({
  environment: "sandbox",
  locale: "en_US",
  sessionData: sessionData,
});
  1. 使用实例对象中的 mount() 方法来创建支付组件,如果需要嵌入组件则将组件嵌入到指定视图里。调用 mount() 方法前,您可以自行添加 loading 效果,并在 .then() 方法中处理回调时关闭 loading 效果。若回调结果包含错误信息,请通过 error?.code 判断具体错误类型,并参阅回调函数事件码获取详细错误原因及处理建议。如果不存在错误信息,则表示 mount() 渲染成功。
注意:
  • 如您需要嵌入支付要素采集组件(详见需要嵌入的支付方式),建议嵌入 Payment Element 的容器宽度不小于 375px,并且不限制高度,以便由 Payment Element 自动撑开容器。
  • mount() 方法中 notRedirectAfterComplete 参数的不同配置会影响商户页面的跳转方式,详情请参阅回跳商户页面。
  • 由 Payment Element 渲染支付方式列表时,mount() 方法中的 merchantAppointParam.singleOption 参数默认值为 skip,当仅指定一个支付方式时,会跳过支付方式列表,直接进入支付流程。若需展示支付方式列表,可将该参数的值改为 list。
以下是使用 mount() 方法来创建支付组件的示例代码:
let loading = false;

// 自定义外观
const appearance = {
  theme: "default",
  layout: {
    type: "Accordion"
  },
  variables: {},
};

// 调用 mount 时先设置外部容器的 loading 状态
loading = true;

// 嵌入 document.querySelector("#payment-element") 这个节点中
elementPayment.mount({
    type: 'payment',
    appearance: appearance,
    notRedirectAfterComplete: false,
    merchantAppointParam: {
      singleOption: 'skip'
    }
  },
  '#payment-element',
).then(({
  error
}) => {
  // 自行关闭外部容器的 loading 状态
  loading = false;

  // 消费错误信息,根据 error.code 处理异常
  if (error && error?.code) {
    // PARAM_INVALID: SDK 入参异常,建议检查集成代码
    // UI_STATE_ERROR: mount 调用时机异常,建议检查集成代码
    console.log(error.message);

    if (error?.code === 'INITALIZE_API_TIMEOUT') {
      // 支付信息查询接口超时,导致收银台渲染失败,建议引导买家重试

    } else if (error?.code === 'INITALIZE_WEB_TIMEOUT') {
      // 收银台静态资源加载超时,建议引导买家重试

    }...
    return;
  }
  // mount 渲染成功,无需处理
})
  1. 买家点击您自定义的支付按钮后,您需调用 submitPayment() 方法提交支付。调用 submitPayment() 方法前,您可以自行添加 loading 效果,并在 .then() 方法中处理回调时关闭 loading 效果。建议在买家点击支付按钮后展示 loading 状态,以避免其在短时间内重复提交。收到 Payment Element 返回的支付结果后,可根据实际结果引导买家重新发起支付或跳转至支付结果页。
    • 若回调结果包含错误信息,您可根据 status 的值简化集成处理,具体操作请参考以下示例代码。您也可根据 error?.code 来进行精细化的异常处理,并参阅回调函数事件码获取详细错误原因及处理建议。
    • 如不存在错误信息,请根据 status 的值进行后续操作。
let loading = false;

function checkout() {
  loading = true;
  // 当买家点击支付按钮时:
  elementPayment.submitPayment().then(({ status, userCanceled3D, session, error }) => {
    // 自行关闭外部容器的 loading 状态
    loading = false;

    if (error) {
      // 先处理错误信息
      const { code, message, traceId, context } = error;

      if (userCanceled3D) {
        // 买家主动关闭 3D 弹窗,建议从服务端轮询结果
      }

      if (status === "PROCESSING") {
        // 因网络异常或渠道不稳定导致状态未知. 建议从服务端轮询结果
      } else {
        // FAIL 失败
        // 表单校验不通过,Payment Element 已提示买家,建议忽略
        if (code === "FORM_INVALID") {
          return;
        }

        toast(message);

        // 或根据 code 精细化定制体验
        if (code) {
          // xxx
        }
      }
      return;
    }

    if (status === "SUCCESS") {
      // 成功 SUCCESS。部分场景 Payment Element 会有 toast 提示,建议直接跳转结果页
    } else if (status === "CANCELLED") {
      // 订单已取消, 如无该场景可忽略
    } else {
      // 可添加监控
    }
  });
}
  1. (可选)您可调用 submitPayment() 方法传入 handleActions 参数以控制是否由 Payment Element 处理自动跳转:
let loading = false;

function checkout() {
  loading = true;
  // 当买家点击支付按钮时:
  elementPayment
    .submitPayment({ handleActions: false })
    .then(({ status, userCanceled3D, session, error }) => {
      // 自行关闭外部容器的 loading 状态
      loading = false;

      if (error) {
        // 先处理错误信息
        const { code, message, traceId, context } = error;

        if (userCanceled3D) {
          // 买家主动关闭 3DS 弹窗,建议从服务端轮询结果
        }

        if (status === "PROCESSING") {
          // 因网络异常或渠道不稳定导致状态未知. 建议从服务端轮询结果
        } else {
          // FAIL 失败
          // 表单校验不通过,Payment Element 已提示买家,建议忽略
          if (code === "FORM_INVALID") {
            return;
          }

          toast(message);

          // 或根据 code 精细化定制体验
          if (code) {
            // xxx
          }
        }
        return;
      }

      if (status === "SUCCESS") {
        // 成功 SUCCESS。部分场景 Payment Element 会有 toast 提示,建议直接跳转结果页
      } else if (status === "CANCELLED") {
        // 订单已取消, 如无该场景可忽略
      } else {
        // 可添加监控
      }

      if (session && session.nextAction) {
        const { normalUrl, appLinkUrl, schemeUrl } = session.nextAction;

        const userAgent = navigator.userAgent || navigator.vendor || window.opera;
        if (/iphone|ipad|ipod/i.test(userAgent)) {
          // iOS 浏览器端
          if (appLinkUrl) {
            window.open(appLinkUrl, "_blank");
            return;
          } else if (schemeUrl) {
            window.open(schemeUrl, "_blank");
            return;
          }
        } else if (/android/i.test(userAgent)) {
          // Android 浏览器端
          if (appLinkUrl) {
            window.open(schemeUrl, "_blank");
            return;
          } else if (schemeUrl) {
            window.open(appLinkUrl, "_blank");
            return;
          }
        }

        // PC 端/Web 端/WAP 端
        window.open(normalUrl, "_blank");
      }
    });
}
  1. (可选)您可调用 submitPayment() 方法传入 shippingInfo 参数以提交收货地址信息:
let loading = false;

const shippingInfo = {
  shippingAddress: {
    region: "CN",
    state: "SM",
    city: "Shanghai",
    address1: "88 Century Avenue",
    address2: "Floor 20, Tower A, Lujiazui",
    zipCode: "200120",
  },
  shippingPhoneNo: "+86 18200000000",
  shippingName: {
    firstName: "Cui",
    lastName: "Tom",
    middleName: "**",
    fullName: "Tom ** Cui",
  },
};

function checkout() {
  loading = true;
  // 当买家点击支付按钮时:
  elementPayment
    .submitPayment({ shippingInfo: shippingInfo, handleActions: true })
    .then(({ status, userCanceled3D, session, error }) => {
      // 自行关闭外部容器的 loading 状态
      loading = false;

      if (error) {
        // 先处理错误信息
        const { code, message, traceId, context } = error;

        if (userCanceled3D) {
          // 买家主动关闭 3D 弹窗,建议从服务端轮询结果
        }

        if (status === "PROCESSING") {
          // 因网络异常或渠道不稳定导致状态未知. 建议从服务端轮询结果
        } else {
          // FAIL 失败
          // 表单校验不通过,Payment Element 已提示买家,建议忽略
          if (code === "FORM_INVALID") {
            return;
          }

          toast(message);

          // 或根据 code 精细化定制体验
          if (code) {
            // xxx
          }
        }
        return;
      }

      if (status === "SUCCESS") {
        // 成功 SUCCESS。部分场景 Payment Element 会有 toast 提示,建议直接跳转结果页
      } else if (status === "CANCELLED") {
        // 订单已取消, 如无该场景可忽略
      } else {
        // 可添加监控
      }

      if (session && session.nextAction) {
        const { normalUrl, appLinkUrl, schemeUrl } = session.nextAction;

        const userAgent = navigator.userAgent || navigator.vendor || window.opera;
        if (/iphone|ipad|ipod/i.test(userAgent)) {
          // iOS 浏览器端
          if (appLinkUrl) {
            window.open(appLinkUrl, "_blank");
            return;
          } else if (schemeUrl) {
            window.open(schemeUrl, "_blank");
            return;
          }
        } else if (/android/i.test(userAgent)) {
          // Android 浏览器端
          if (appLinkUrl) {
            window.open(schemeUrl, "_blank");
            return;
          } else if (schemeUrl) {
            window.open(appLinkUrl, "_blank");
            return;
          }
        }

        // PC 端/Web 端/WAP 端
        window.open(normalUrl, "_blank");
      }
    });
}

校验当前所选支付方式的支付要素

调用 validateFields() 方法可验证当前所选支付方式下的表单要素是否填写完整且格式有效,方便您在提交支付前执行自定义校验流程或业务逻辑。该方法会根据已选择的支付方式自动识别并校验所需参数,您无需手动维护参数列表。即使未主动调用 validateFields(),在执行 submitPayment() 时,若表单存在异常,组件也会自动展示相应的错误提示:
let loading = false;

function checkout() {
  loading = true;

  // 校验当前所选支付方式支付要素
  elementPayment.validateFields().then(({isValid}) => {
    console.log(isValid);
    // 表单校验不通过
    if (!isValid) {
      console.log('表单校验不通过');
      return;
    }
  });

  // 校验通过后可发起 submitPayment()
  elementPayment.submitPayment().then(({ status, userCanceled3D, session, error }) => {
    ...
  })
}

存卡支付场景配置 CVV 验证

为提升支付便捷性及交易成功率,mount() 方法中的 merchantAppointParam.storedCard.needCVV 参数默认值为 false,即存卡支付场景默认不进行 CVV 验证。如您的业务场景对支付安全有特殊要求,可将该参数设为 true 以启用 CVV 验证。
注意:若非必要,建议您保持默认值 false,避免要求买家再次输入 CVV 码,以优化支付体验并提高交易成功率。
以下是指定存卡支付场景需要 CVV 验证的示例代码:
// 嵌入 document.querySelector("#payment-element") 这个节点中
elementPayment.mount({
    ...
    merchantAppointParam: {
      storedCard: {
          needCVV: false
      }
    }
  },
  '#payment-element',
).then(({
error
}) => {
  ...
})

监听组件事件

调用 on() 方法可监听组件事件,包含以下事件类型:
  • paymentMethodChanged 事件:当买家切换支付方式时触发,回调函数接收一个参数 payload,其中包含支付方式变更相关数据。
elementPayment.on("paymentMethodChanged", ({ type, name }) => {
  console.log(type + name);
});
  • billingAddressChanged 事件:当买家编辑账单地址表单数据时触发,回调函数接收一个参数 payload,其中包含最新的账单地址表单数据。
elementPayment.on("billingAddressChanged", ({ sameAsShipping, billingAddress }) => {
  console.log(sameAsShipping + JSON.stringify(billingAddress));
});

卸载 Payment Element

调用 destroy() 方法以释放 Payment Element 组件占用的资源:
elementPayment.destroy();
常见问题
问:是否可以在 PC 应用或移动应用中使用 Webview 集成 Web Element?
答:目前不支持。

步骤 3:获取支付结果
服务端

在买家完成支付或支付超时后, Antom 会通过服务器交互将相应的支付结果发送给您,您可以通过以下方法之一获取支付结果:
  • 接收来自 Antom 的异步通知
  • 主动查询支付结果
接收异步通知
1. 设置接收通知的 webhook URL
完成支付或支付失败时,Antom 会向您设置的 webhook URL 发送异步通知,您可以选择以下两种方法中的一种来设置接收通知的 webhook URL(若两者都设置,则以接口请求中指定的 URL 优先):
  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 createPaymentSession(单笔支付)接口请求的 paymentNotifyUrl 参数传入该笔订单的异步通知接收 URL。
  • 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置 webhook URL。具体操作请参阅通知地址。
以下是异步通知请求体的代码示例:
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe", // 存储 cardToken 用于后续存卡支付使用
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
授权成功。
可以发起请款。
F
授权失败。
建议更换 paymentRequestId 重新发起支付。
APM 支付
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "paymentCreateTime": "2025-02-04T22:11:19-08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "ALIPAY_HK",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {},
  "paymentTime": "2025-02-04T22:14:25-08:00",
  "pspCustomerInfo": {
    "pspCustomerId": "216022003753XXXX",
    "pspName": "ALIPAY_HK"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付成功。
可以进行发货。
F
支付失败。
建议更换 paymentRequestId 重新发起支付。
2. 异步通知验签
当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
您需要按照以下方法对 Antom 发送的支付通知进行验签:
import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentNotifyHandleBySDK {

  /**
   * alipay public key, used to verify signature
   */
  private static final String SERVER_PUBLIC_KEY = "";

  /**
   * payment result notify processor
   * using <a href="https://spring.io">Spring Framework</a>
   *
   * @param request    HttpServletRequest
   * @param notifyBody notify body
   * @return
   */
  @PostMapping("/payNotify")
  public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {
    // 从 HTTP 请求中获取所需的参数
    String requestUri = request.getRequestURI();
    String requestMethod = request.getMethod();

    // 从请求头中获取所需的参数
    String requestTime = request.getHeader("request-time");
    String clientId = request.getHeader("client-id");
    String signature = request.getHeader("signature");

    Result result;
    AlipayResponse response = new AlipayResponse();

    try {
      // 验签
      boolean verifyResult = WebhookTool.checkSignature(
        requestUri,
        requestMethod,
        clientId,
        requestTime,
        signature,
        notifyBody,
        SERVER_PUBLIC_KEY
      );
      if (!verifyResult) {
        throw new RuntimeException("Invalid notify signature");
      }

      // 反序列化通知体

      // 根据通知结果更新订单状态

      // 向服务器响应已接收通知
      result = new Result("SUCCESS", "success", ResultStatusType.S);
    } catch (Exception e) {
      String errorMsg = e.getMessage();
      // 处理错误情况
      result = new Result("ERROR", errorMsg, ResultStatusType.F);
    }
    response.setResult(result);
    return ResponseEntity.ok().body(response);
  }
}
无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
常见问题
问:什么时候会发送通知?
答:这取决于支付是否完成:
  • 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。对于现金支付,通知可能会稍有延迟。
  • 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。

问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
  • 由于网络原因未收到异步通知。
  • 如果收到来自 Antom 的异步通知,但您没有按照返回收到确认信息的格式进行响应。
通知可以重发最多 8 次,或者直到收到正确的响应以终止传递。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和15 小时。
​
问:在响应异步通知时,需要添加签名吗?
答:不需要。如果您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
​
问:我在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
  • result:对于 APM 支付,其表示支付最终结果。对于 Apple Pay、Google Pay 和卡支付,则仅代表授权结果,需要进一步发起请款。
  • paymentRequestId:用于咨询、取消和对账的支付请求 ID。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
  • paymentAmount:表示支付金额。
主动查询结果
无论是 APM 支付、卡支付、Apple Pay 或者 Google Pay,您均可以调用 inquiryPayment 接口并传入 paymentRequestId 来主动查询支付或授权支付结果。
调用 inquiryPayment 接口的示例代码如下:
public static void inquiryPayment() {
  AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();

  // 替换为您的 paymentRequestId
  alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");

  AlipayPayQueryResponse alipayPayQueryResponse = null;
  try {
    alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
  } catch (AlipayApiException e) {
    String errorMsg = e.getMessage();
    // 处理错误情况
  }
}
以下代码展示了请求报文的示例:
{
  "paymentRequestId": "paymentRequestId01"
}
以下代码展示了响应报文的示例:
APM 支付
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "authExpiryTime": "2024-12-17T21:56:56-08:00",
  "cardInfo": {
    "cardBrand": "VISA",
    "funding": "CREDIT",
    "issuingCountry": "US"
  },
  "paymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "CARD",
  "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultInfo": {
    "avsResultRaw": "M",
    "cardBrand": "VISA",
    "cardNo": "************9954",
    "cvvResultRaw": "U",
    "funding": "CREDIT",
    "issuingCountry": "US",
    "networkTransactionId": "123qwe456rew",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentTime": "2024-12-10T21:56:57-08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
请根据响应中 paymentStatus 参数的值进行处理,具体返回值请参阅接口文档。
常见问题
问:使用 inquiryPayment 接口查询支付或授权状态时,应注意哪些关键参数?
答:请注意以下关键参数:
  • result:仅表示本次 inquiryPayment 接口的调用结果。对于 APM 支付,订单的支付结果需要根据 paymentStatus 进行判断(SUCCESS 成功/FAIL 失败/PROCESSING 处理中)。对于卡支付、Apple Pay 和 Google Pay,paymentStatus 仅代表授权结果,是否发货需要依赖请款结果决策。
  • paymentAmount:用于核对支付金额。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
​
问:我应该多久调用一次 inquiryPayment 接口?
答:以 2 秒的间隔持续调用 inquiryPayment 接口,直到获取最终的支付结果或收到异步支付结果通知为止。

步骤 4:请款
服务端
仅卡支付、Apple Pay、Google Pay

Antom 提供自动请款和手动请款两种请款方式,您可根据业务需求自行选择。请款后,您可以通过异步通知或主动查询来获取请款结果,您需要根据请款结果来决定是否发货。具体操作请参阅请款。
iOS

用户体验

以下图片展示了不同场景下使用 Payment Element 的用户体验:
Payment Element 渲染支付方式
以下图片展示了以弹窗形式调用 Payment Element 渲染的支付方式的模板:
如您选择由 Payment Element 渲染支付方式列表,Payment Element 默认在收银台页面上渲染所有支持的支付方式。以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
存卡支付
由 Payment Element 处理存卡支付场景:
商户自行渲染支付方式
以下图片展示了商户自行渲染支付方式的模板:
如您通过自行指定支付方式渲染支付方式列表,以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:

订单生命周期

以下是不同支付方式的生命周期。
APM 支付
对于 APM 支付,如 Alipay、Touch'n Go eWallet 等支付方式,当您发起支付请求且买家完成支付后,资金将直接转移到您的账户中。您可在窗口期内对订单进行撤销或者退款操作。
卡支付、Apple Pay、Google Pay
对于卡支付、Apple Pay、Google Pay,订单主要包括以下阶段:
  1. 授权:买家使用银行卡完成支付后,其资金将处于冻结状态。买家下单至完成授权期间,您都可以在窗口期内对订单发起撤销。
  2. 请款:你可以通过手动请款将买家的冻结资金转移到您的账户;或通过自动请款让 Antom 替您完成请款,具体信息请参阅请款。请款完成后,若有需要,您可以在窗口期内发起退款。
  3. 拒付:您需要根据情况发起拒付抗辩申请,具体信息请参阅争议。

支付流程

以下图片展示了如何通过 Payment Element 集成单笔支付:
Payment Element 渲染支付方式
商户自行渲染支付方式
  1. 买家进入结账页面并发起支付。
  2. 创建支付会话请求。
    您可以调用 createPaymentSession(单笔支付)接口获取支付会话。
  3. 调用 Payment Element。
    在客户端,通过支付会话调用 Payment Element。您可以选择由 Payment Element 或者您自行渲染支付方式,同时 Payment Element 会根据支付方式的特性处理信息、收集支付要素、进行重定向、应用调用、二维码显示、验证等流程。当支付完成后,根据您的设置以及支付方式特性,您需要按照 onSubmitPayCallback() 方法返回的结果处理跳转流程或者由系统自动回跳到您的支付结果页面。
  4. 获取支付结果。
    通过以下两种方法之一获取支付结果:
注意:在卡支付、Apple Pay 和 Google Pay 支付场景下,采用的是授权请款模式。步骤 1 至 4 仅完成了授权部分,即买家使用银行卡完成支付,其资金处于冻结状态。为了将买家的冻结资金转至您的账户,您还需要集成请款步骤。请款成功的结果将作为您发货的依据。
  1. 发起请款并获取请款结果。
默认情况下,Antom 会自动为您处理资金请款。您也可以通过调用 capture(单笔支付)接口来手动进行请款。随后,通过以下两种方法之一获取请款结果:

集成准备

在您开始集成前,请阅读集成指南及接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:
  • 已获得 client ID。
  • 已完成密钥配置。
  • 已完成异步通知接收地址的配置。
  • 集成 Antom 服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
  • 参阅 iOS 端集成 SDK 资源包文档来集成客户端 SDK 资源包,并注意使用最新或不低于 1.46.0 版本的 SDK。

集成步骤

请按照以下步骤开始集成:
  1. (可选)预加载 SDK
  2. 创建支付会话
  3. 调用 Payment Element
  4. 获取支付结果
  5. 发起请款

(可选)步骤 1:预加载 SDK
客户端

在创建支付会话前,强烈建议您调用 preload() 方法预加载 SDK,以提升收银台页面的渲染速度,减少买家在支付过程中的等待时间。按照以下代码示例执行预加载操作:
[AMSPaymentElement.shared preload];

步骤 2:创建支付会话
服务端

传入订单信息以调用 createPaymentSession(单笔支付)接口来创建支付会话,获取唤起 Payment Element 的 paymentSessionData。您可选择自行渲染支付方式列表或由 Payment Element 渲染支付方式列表。
建议您在买家点击支付按钮后创建支付会话,并根据你所选择的渲染收银台支付方式列表的方式,在调用 createPaymentSession(单笔支付)接口时传入相应的参数:
Payment Element 渲染支付方式
当您使用 Payment Element 渲染的支付方式列表时,您只需传入以下参数。Payment Element 默认在收银台页面上渲染所有支持的支付方式,您也可以通过指定支付方式来选择您需要的支付方式。
参数名称
是否必需
描述
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy
是
支付请求的结算策略。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.APP).osType(OsType.IOS).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
如果由 Payment Element 渲染收银台的支付方式列表,则会展示所有支付方式。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "APP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "IOS"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
商户自行渲染支付方式
当您自行渲染支付方式列表时,您必须传入下表中列出的指定支付方式参数。如果 Payment Element 需要采集支付要素,则需要传入下表中列出的卡支付信息参数。
类型
参数名称
是否必需
描述
基础参数
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy.settlementCurrency
是
该笔支付的结算币种,若业务签约了多个结算币种,需在接口中指定。
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
卡支付信息参数(具体请参考卡支付特性)
paymentFactor.captureMode
否
请款模式。有效值为:
  • AUTOMATIC:表示在授权后,Antom 自动进行请款。当值为空或未传递此参数时,默认为此值。
  • MANUAL:表示您通过调用 capture(单笔支付)接口进行手动请款。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication
否
您需要根据当前交易的风险和拒付情况,决定是否设置交易认证类型为 3DS 认证。有效值为:
  • true:指交易认证类型为 3DS 认证。
  • false:指交易认证类型为非 3DS 认证。如果此参数为空或未传递,默认为此值。
availablePaymentMethod.paymentMethodMetaData.tokenizeMode
否
如果您需要存储卡信息,可通过此参数让 Antom 帮您保存卡信息,Antom 会将卡信息替换为一个唯一且安全的 token 用于后续支付。有效值为:
  • ENABLED:表示您已获得买家绑卡授权,需要存储卡信息用于后续支付。
  • DISABLED:表示您不需要存储卡信息。当值为空或不指定此参数时同样适用。
  • ASKFORCONSENT:在中间页向买家展示存卡按钮,允许买家选择是否存储卡信息。
availablePaymentMethod.paymentMethodMetaData.isCardOnFile
否
表示该笔交易使用的卡是否曾在商户侧完成过支付并存档。有效值为:
  • true:指该笔交易使用的卡是曾在商户侧完成过支付的已存卡。在已存卡支付场景下,将该参数设置为 true。
  • false:默认值。指该笔交易使用的是未在商户侧进行过支付的新卡。
savedPaymentMethods.paymentMethodId
否
存卡交易下使用,代表传入新卡交易时返回的 cardToken 信息。
指定支付方式参数(具体请参考指定支付方式)
availablePaymentMethod.paymentMethodTypeList.paymentMethodType
否
指定具体的支付方式,支持指定单个或者多个支付方式。参见支付方式枚举值以查看有效值。
availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder
否
设置支付方式的优先级顺序。
availablePaymentMethod.paymentMethodTypeList.expressCheckout
否
设置是否使用支付方式的极速支付形式。目前仅 ALIPAY_CN、APPLEPAY 和 GOOGLEPAY 可以被设置为极速支付。有效值为:
  • true:表示设置该支付方式为极速支付。
  • false:表示不将该支付方式设置为极速支付。
注意:该参数目前仅支持在 Android 及 iOS 使用。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.APP).osType(OsType.IOS).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  // 替换为您的指定支付方式
  AvailablePaymentMethod availablePaymentMethods = AvailablePaymentMethod.builder()
    .paymentMethodTypeList(
      List.of(PaymentMethodTypeItem.builder().paymentMethodType("ALIPAY_CN").build())
    )
    .build();
  alipayPaymentSessionRequest.setAvailablePaymentMethod(availablePaymentMethods);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
当您自行渲染支付方式列表时,需要通过指定单个支付方式集成。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "APP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "IOS"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // 指定支付方式
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
以下代码展示了一个响应的示例,其中包含以下参数:
  • result.resultStatus:createPaymentSession(单笔支付)接口的调用结果。
  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
{
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
以下是创建支付会话响应中 result.resultStatus 可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付会话已成功创建,同时返回 paymentSessionData。
请继续执行后续步骤。
U
未知问题。
建议更换 paymentRequestId 以解决问题。如果问题未解决,请联系 Antom 技术支持。
F
支付会话创建失败。
建议检查并验证当前接口所需的请求字段(包括头部字段和正文字段)是否正确传递并有效。
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 paymentRequestId 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的兼容性问题,请求中的参数请勿使用中文字符。
​
问:如何设置接收支付通知的地址?
答:在 createPaymentSession(单笔支付)接口的请求中指定 paymentNotifyUrl 参数,以接收支付结果的异步通知(notifyPayment),或者在 Antom Dashboard 中配置接收地址。如果请求和 Antom Dashboard 中都指定了地址,请求中的值优先。
​
问:返回的 paymentSessionData 是否需要处理后再传给客户端?
答:请勿对 paymentSessionData 进行任何处理,否则可能会导致调用 Payment Element 失败。

步骤 3:调用 Payment Element
客户端

在您的客户端使用 paymentSessionData 调用 Payment Element,在买家提交支付后,Payment Element 会根据不同支付方式,负责展示二维码、跳转支付方式页面、3DS 认证、回跳商户结果页等流程。
  1. 在服务端获取到 paymentSessionData 后,使用 AMSPaymentElement 类创建 Payment Element 实例。
    1. 创建AMSPaymentElementConfiguration对象,并完成 SDK 配置。
    1. 实现AMSPaymentProtocol,用于处理后续流程中的相应事件。
以下是使用 AMSPaymentElement 创建 Payment Element 实例的示例代码:
#import <AMSComponent/AMSComponent-Swift.h>

// 创建一个 AMSPaymentElementConfiguration 对象
AMSPaymentElementConfiguration *componentConfig = [AMSPaymentElementConfiguration new];
componentConfig.locale = @"en_US";


NSString *appearance = @"{\n  \"theme\": \"night\",\n  \"layout\": {\n    \"type\": \"Tabs\"\n  },\n  \"variables\": {\n    \"content-quaternary\": \"#FFFF00\"\n  }\n}"; 

// 设置沙箱环境。如果将其置空,则默认使用线上正式环境
NSDictionary *options = @{@"showLoading": @"true", 
                          @"sandbox": @"true", 
                          @"appearance": appearance
                          };
componentConfig.options = options;

// initConfiguration 用法
[[AMSPaymentElement shared] initConfiguration:componentConfig completion:^(AMSStatusResult * _Nonnull result) {
    // 处理 initConfiguration 用法阶段错误事件
    if (result.error) {
        // 处理失败
        if ([result.error.code isEqualToString:@"UI_STATE_ERROR"]) {
            NSLog(@"integration code error, please check the integration code");
        } else {
            NSLog(@"unknown error, please contact support");
        }
    } else {
        // 处理成功
    }
}];

// 设置回调来监听收银台页面的支付事件
[AMSPaymentElement shared].paymentDelegate = self;

// 服务端调用 创建支付会话 接口以获取 paymentSessionData


#pragma AMSPaymentProtocol
// 回调事件码方式 处理 submitPay 阶段事件码
- (void)onSubmitPayCallback:(AMSStatusResult *)eventResult {
    AMSStatusResultType statusType = eventResult.status;
    AMSResultError *error = eventResult.error;

    switch (statusType) {
        case AMSStatusResultTypePROCESSING:
            if (error && error.code) {
                if ([@"PAYMENT_IN_PROCESS" isEqualToString:error.code]) {
                    NSLog(@"payment is in processing, please try polling the payment result from the server");
                } else if ([@"USER_CANCELED" isEqualToString:error.code]) {
                    NSLog(@"user cancelled the payment process, please try invoke createComponent again");
                } else if ([@"UNKNOWN_EXCEPTION" isEqualToString:error.code]) {
                    NSLog(@"unknown exception, please contact support");
                } else if ([@"PAYMENT_RESULT_TIMEOUT" isEqualToString:error.code]) {
                    NSLog(@"get payment result timeout, please try polling the payment result from the server");
                }
            }
            break;
        case AMSStatusResultTypeCANCELLED:
            // 继续执行下一 case
        case AMSStatusResultTypeSUCCESS:
            NSLog(@"payment cancelled or success, do nothing");
            break;
        case AMSStatusResultTypeFAIL:
            if (error && error.code) {
                if ([@"ORDER_IS_CANCELLED" isEqualToString:error.code]) {
                    NSLog(@"the merchant has proactively canceled the order, please check on your own.");
                } else if ([@"ORDER_IS_CLOSED" isEqualToString:error.code]) {
                    NSLog(@"the order has timed out and is closed, please re-initiate payment using a new paymentRequestId.");
                } else {
                    NSLog(@"unknown error, please contact support");
                }
            }
            break;
        default:
            break;
    }
}
  1. 使用实例对象中的 createComponent() 方法来调用 Payment Element。
// 回调事件码方式 createComponent 用法 
[[AMSPaymentElement shared] createComponent:paymentSessionData completion:^(AMSStatusResult * _Nonnull result) {
    if (result.error) {
        // 处理失败
        if ([result.error.code isEqualToString:@"UI_STATE_ERROR"]) {
            NSLog(@"integration code error, please check the integration code");
        } else if ([result.error.code isEqualToString:@"PARAM_INVALID"]) {
            NSLog(@"session data invalid, please check the session data");
        } else if ([result.error.code isEqualToString:@"INITIALIZE_WEB_TIMEOUT"]) {
            NSLog(@"web app timeout, please invoke component again");
        } else {
            NSLog(@"unknown error, please contact support");
        }
    } else {
        // 处理成功
    }
}];

卸载 Payment Element

调用 onDestroy() 方法来释放 SDK 组件资源。
// 释放 SDK 组件资源
[[AMSPaymentElement shared] onDestroy];

步骤 4:获取支付结果
服务端

在买家完成支付或支付超时后, Antom 会通过服务器交互将相应的支付结果发送给您,您可以通过以下方法之一获取支付结果:
  • 接收来自 Antom 的异步通知
  • 主动查询支付结果
接收异步通知
1. 设置接收通知的 webhook URL
完成支付或支付失败时,Antom 会向您设置的 webhook URL 发送异步通知,您可以选择以下两种方法中的一种来设置接收通知的 webhook URL(若两者都设置,则以接口请求中指定的 URL 优先):
  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 createPaymentSession(单笔支付)接口请求的 paymentNotifyUrl 参数传入该笔订单的异步通知接收 URL。
  • 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置 webhook URL。具体操作请参阅通知地址。
以下是异步通知请求体的代码示例:
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe", // 存储 cardToken 用于后续存卡支付使用
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
授权成功。
可以发起请款。
F
授权失败。
建议更换 paymentRequestId 重新发起支付。
APM 支付
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "paymentCreateTime": "2025-02-04T22:11:19-08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "ALIPAY_HK",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {},
  "paymentTime": "2025-02-04T22:14:25-08:00",
  "pspCustomerInfo": {
    "pspCustomerId": "216022003753XXXX",
    "pspName": "ALIPAY_HK"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付成功。
可以进行发货。
F
支付失败。
建议更换 paymentRequestId 重新发起支付。
2. 异步通知验签
当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
您需要按照以下方法对 Antom 发送的支付通知进行验签:
import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentNotifyHandleBySDK {

  /**
   * alipay public key, used to verify signature
   */
  private static final String SERVER_PUBLIC_KEY = "";

  /**
   * payment result notify processor
   * using <a href="https://spring.io">Spring Framework</a>
   *
   * @param request    HttpServletRequest
   * @param notifyBody notify body
   * @return
   */
  @PostMapping("/payNotify")
  public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {
    // 从 HTTP 请求中获取所需的参数
    String requestUri = request.getRequestURI();
    String requestMethod = request.getMethod();

    // 从请求头中获取所需的参数
    String requestTime = request.getHeader("request-time");
    String clientId = request.getHeader("client-id");
    String signature = request.getHeader("signature");

    Result result;
    AlipayResponse response = new AlipayResponse();

    try {
      // 验签
      boolean verifyResult = WebhookTool.checkSignature(
        requestUri,
        requestMethod,
        clientId,
        requestTime,
        signature,
        notifyBody,
        SERVER_PUBLIC_KEY
      );
      if (!verifyResult) {
        throw new RuntimeException("Invalid notify signature");
      }

      // 反序列化通知体

      // 根据通知结果更新订单状态

      // 向服务器响应已接收通知
      result = new Result("SUCCESS", "success", ResultStatusType.S);
    } catch (Exception e) {
      String errorMsg = e.getMessage();
      // 处理错误情况
      result = new Result("ERROR", errorMsg, ResultStatusType.F);
    }
    response.setResult(result);
    return ResponseEntity.ok().body(response);
  }
}
无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
常见问题
问:什么时候会发送通知?
答:这取决于支付是否完成:
  • 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。对于现金支付,通知可能会稍有延迟。
  • 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。

问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
  • 由于网络原因未收到异步通知。
  • 如果收到来自 Antom 的异步通知,但您没有按照返回收到确认信息的格式进行响应。
通知可以重发最多 8 次,或者直到收到正确的响应以终止传递。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和15 小时。
​
问:在响应异步通知时,需要添加签名吗?
答:不需要。如果您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
​
问:我在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
  • result:对于 APM 支付,其表示支付最终结果。对于 Apple Pay、Google Pay 和卡支付,则仅代表授权结果,需要进一步发起请款。
  • paymentRequestId:用于咨询、取消和对账的支付请求 ID。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
  • paymentAmount:表示支付金额。
主动查询结果
无论是 APM 支付、卡支付、Apple Pay 或者 Google Pay,您均可以调用 inquiryPayment 接口并传入 paymentRequestId 来主动查询支付或授权支付结果。
调用 inquiryPayment 接口的示例代码如下:
public static void inquiryPayment() {
  AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();

  // 替换为您的 paymentRequestId
  alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");

  AlipayPayQueryResponse alipayPayQueryResponse = null;
  try {
    alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
  } catch (AlipayApiException e) {
    String errorMsg = e.getMessage();
    // 处理错误情况
  }
}
以下代码展示了请求报文的示例:
{
  "paymentRequestId": "paymentRequestId01"
}
以下代码展示了响应报文的示例:
APM 支付
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "authExpiryTime": "2024-12-17T21:56:56-08:00",
  "cardInfo": {
    "cardBrand": "VISA",
    "funding": "CREDIT",
    "issuingCountry": "US"
  },
  "paymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "CARD",
  "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultInfo": {
    "avsResultRaw": "M",
    "cardBrand": "VISA",
    "cardNo": "************9954",
    "cvvResultRaw": "U",
    "funding": "CREDIT",
    "issuingCountry": "US",
    "networkTransactionId": "123qwe456rew",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentTime": "2024-12-10T21:56:57-08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
请根据响应中 paymentStatus 参数的值进行处理,具体返回值请参阅接口文档。
常见问题
问:使用 inquiryPayment 接口查询支付或授权状态时,应注意哪些关键参数?
答:请注意以下关键参数:
  • result:仅表示本次 inquiryPayment 接口的调用结果。对于 APM 支付,订单的支付结果需要根据 paymentStatus 进行判断(SUCCESS 成功/FAIL 失败/PROCESSING 处理中)。对于卡支付、Apple Pay 和 Google Pay,paymentStatus 仅代表授权结果,是否发货需要依赖请款结果决策。
  • paymentAmount:用于核对支付金额。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
​
问:我应该多久调用一次 inquiryPayment 接口?
答:以 2 秒的间隔持续调用 inquiryPayment 接口,直到获取最终的支付结果或收到异步支付结果通知为止。

步骤 5:请款
服务端
仅卡支付、Apple Pay

Antom 提供自动请款和手动请款两种请款方式,您可根据业务需求自行选择。请款后,您可以通过异步通知或主动查询来获取请款结果,您需要根据请款结果来决定是否发货。具体操作请参阅请款。
Android

用户体验

以下图片展示了不同场景下使用 Payment Element 的用户体验:
Payment Element 渲染支付方式
以下图片展示了以弹窗形式调用 Payment Element 渲染的支付方式的模板:
如您选择由 Payment Element 渲染支付方式列表,Payment Element 默认在收银台页面上渲染所有支持的支付方式。以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
存卡支付
由 Payment Element 处理存卡支付场景:
商户自行渲染支付方式
以下图片展示了商户自行渲染支付方式的模板:
如您通过自行指定支付方式渲染支付方式列表,以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:

订单生命周期

以下是不同支付方式的生命周期。
APM 支付
对于 APM 支付,如 Alipay、Touch'n Go eWallet 等支付方式,当您发起支付请求且买家完成支付后,资金将直接转移到您的账户中。您可在窗口期内对订单进行撤销或者退款操作。
卡支付、Apple Pay、Google Pay
对于卡支付、Apple Pay、Google Pay,订单主要包括以下阶段:
  1. 授权:买家使用银行卡完成支付后,其资金将处于冻结状态。买家下单至完成授权期间,您都可以在窗口期内对订单发起撤销。
  2. 请款:你可以通过手动请款将买家的冻结资金转移到您的账户;或通过自动请款让 Antom 替您完成请款,具体信息请参阅请款。请款完成后,若有需要,您可以在窗口期内发起退款。
  3. 拒付:您需要根据情况发起拒付抗辩申请,具体信息请参阅争议。

支付流程

以下图片展示了如何通过 Payment Element 集成单笔支付:
Payment Element 渲染支付方式
商户自行渲染支付方式
  1. 买家进入结账页面并发起支付。
  2. 创建支付会话请求。
    您可以调用 createPaymentSession(单笔支付)接口获取支付会话。
  3. 调用 Payment Element。
    在客户端,通过支付会话调用 Payment Element。您可以选择由 Payment Element 或者您自行渲染支付方式,同时 Payment Element 会根据支付方式的特性处理信息、收集支付要素、进行重定向、应用调用、二维码显示、验证等流程。当支付完成后,根据您的设置以及支付方式特性,您需要按照onSubmitPayCallback() 方法返回的结果处理跳转流程或者由系统自动回跳到您的支付结果页面。
  4. 获取支付结果。
    通过以下两种方法之一获取支付结果:
注意:在卡支付、Apple Pay 和 Google Pay 支付场景下,采用的是授权请款模式。步骤 1 至 4 仅完成了授权部分,即买家使用银行卡完成支付,其资金处于冻结状态。为了将买家的冻结资金转至您的账户,您还需要集成请款步骤。请款成功的结果将作为您发货的依据。
  1. 发起请款并获取请款结果。
默认情况下,Antom 会自动为您处理资金请款。您也可以通过调用 capture(单笔支付)接口来手动进行请款。随后,通过以下两种方法之一获取请款结果:

集成准备

在您开始集成前,请阅读集成指南及接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:
  • 已获得 client ID。
  • 已完成密钥配置。
  • 已完成异步通知接收地址的配置。
  • 集成 Antom 服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
  • 参阅 Android 端集成 SDK 资源包文档来集成客户端 SDK 资源包,并注意使用最新或不低于 1.46.0 版本的 SDK。

集成步骤

请按照以下步骤开始集成:
  1. (可选)预加载 SDK
  2. 创建支付会话
  3. 调用 Payment Element
  4. 获取支付结果
  5. 发起请款

(可选)步骤 1:预加载 SDK
客户端

在创建支付会话前,强烈建议您调用 preload() 方法预加载 SDK,以提升收银台页面的渲染速度,减少买家在支付过程中的等待时间。按照以下代码示例执行预加载操作:
AMSPaymentElement.preload(getApplicationContext());

步骤 2:创建支付会话
服务端

传入订单信息以调用 createPaymentSession(单笔支付)接口来创建支付会话,获取唤起 Payment Element 的 paymentSessionData。您可选择自行渲染支付方式列表或由 Payment Element 渲染支付方式列表。
建议您在买家点击支付按钮后创建支付会话,并根据你所选择的渲染收银台支付方式列表的方式,在调用 createPaymentSession(单笔支付)接口时传入相应的参数:
Payment Element 渲染支付方式
当您使用 Payment Element 渲染的支付方式列表时,您只需传入以下参数。Payment Element 默认在收银台页面上渲染所有支持的支付方式,您也可以通过指定支付方式来选择您需要的支付方式。
参数名称
是否必需
描述
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy
是
支付请求的结算策略。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.APP).osType(OsType.ANDROID).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
如果由 Payment Element 渲染收银台的支付方式列表,则会展示所有支付方式。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "APP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "ANDROID"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
商户自行渲染支付方式
当您自行渲染支付方式列表时,您必须传入下表中列出的指定支付方式参数。如果 Payment Element 需要采集支付要素,则需要传入下表中列出的卡支付信息参数。
类型
参数名称
是否必需
描述
基础参数
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy.settlementCurrency
是
该笔支付的结算币种,若业务签约了多个结算币种,需在接口中指定。
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
卡支付信息参数(具体请参考卡支付特性)
paymentFactor.captureMode
否
请款模式。有效值为:
  • AUTOMATIC:表示在授权后,Antom 自动进行请款。当值为空或未传递此参数时,默认为此值。
  • MANUAL:表示您通过调用 capture(单笔支付)接口进行手动请款。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication
否
您需要根据当前交易的风险和拒付情况,决定是否设置交易认证类型为 3DS 认证。有效值为:
  • true:指交易认证类型为 3DS 认证。
  • false:指交易认证类型为非 3DS 认证。如果此参数为空或未传递,默认为此值。
availablePaymentMethod.paymentMethodMetaData.tokenizeMode
否
如果您需要存储卡信息,可通过此参数让 Antom 帮您保存卡信息,Antom 会将卡信息替换为一个唯一且安全的 token 用于后续支付。有效值为:
  • ENABLED:表示您已获得买家绑卡授权,需要存储卡信息用于后续支付。
  • DISABLED:表示您不需要存储卡信息。当值为空或不指定此参数时同样适用。
  • ASKFORCONSENT:在中间页向买家展示存卡按钮,允许买家选择是否存储卡信息。
availablePaymentMethod.paymentMethodMetaData.isCardOnFile
否
表示该笔交易使用的卡是否曾在商户侧完成过支付并存档。有效值为:
  • true:指该笔交易使用的卡是曾在商户侧完成过支付的已存卡。在已存卡支付场景下,将该参数设置为 true。
  • false:默认值。指该笔交易使用的是未在商户侧进行过支付的新卡。
savedPaymentMethods.paymentMethodId
否
存卡交易下使用,代表传入新卡交易时返回的 cardToken 信息。
指定支付方式参数(具体请参考指定支付方式)
availablePaymentMethod.paymentMethodTypeList.paymentMethodType
否
指定具体的支付方式,支持指定单个或者多个支付方式。参见支付方式枚举值以查看有效值。
availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder
否
设置支付方式的优先级顺序。
availablePaymentMethod.paymentMethodTypeList.expressCheckout
否
设置是否使用支付方式的极速支付形式。目前仅 ALIPAY_CN、APPLEPAY 和 GOOGLEPAY 可以被设置为极速支付。有效值为:
  • true:表示设置该支付方式为极速支付。
  • false:表示不将该支付方式设置为极速支付。
注意:该参数目前仅支持在 Android 及 iOS 使用。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.APP).osType(OsType.ANDROID).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  // 替换为您的指定支付方式
  AvailablePaymentMethod availablePaymentMethods = AvailablePaymentMethod.builder()
    .paymentMethodTypeList(
      List.of(PaymentMethodTypeItem.builder().paymentMethodType("ALIPAY_CN").build())
    )
    .build();
  alipayPaymentSessionRequest.setAvailablePaymentMethod(availablePaymentMethods);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
当您自行渲染支付方式列表时,需要通过指定单个支付方式集成。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "APP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "ANDROID"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // 指定支付方式
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
以下代码展示了一个响应的示例,其中包含以下参数:
  • result.resultStatus:createPaymentSession(单笔支付)接口的调用结果。
  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
{
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
以下是创建支付会话响应中 result.resultStatus 可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付会话已成功创建,同时返回 paymentSessionData。
请继续执行后续步骤。
U
未知问题。
建议更换 paymentRequestId 以解决问题。如果问题未解决,请联系 Antom 技术支持。
F
支付会话创建失败。
建议检查并验证当前接口所需的请求字段(包括头部字段和正文字段)是否正确传递并有效。
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 paymentRequestId 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的兼容性问题,请求中的参数请勿使用中文字符。
​
问:如何设置接收支付通知的地址?
答:在 createPaymentSession(单笔支付)接口的请求中指定 paymentNotifyUrl 参数,以接收支付结果的异步通知(notifyPayment),或者在 Antom Dashboard 中配置接收地址。如果请求和 Antom Dashboard 中都指定了地址,请求中的值优先。
​
问:返回的 paymentSessionData 是否需要处理后再传给客户端?
答:请勿对 paymentSessionData 进行任何处理,否则可能会导致调用 Payment Element 失败。

步骤 3:调用 Payment Element
客户端

在您的客户端使用 paymentSessionData 调用 Payment Element,在买家提交支付后,Payment Element 会根据不同支付方式,负责展示二维码、跳转支付方式页面、3DS 认证、回跳商户结果页等流程。
  1. 在服务端获取到 paymentSessionData 后,使用 AMSPaymentElement 类来创建 SDK 实例。
    1. 创建 AMSBaseConfiguration对象,并完成 SDK 配置。
    1. 注册 OnCreateComponentListener()监听器,用于处理调用支付组件及拉起支付页面流程中的相关事件。
    1. 注册 OnSubmitPayListener(),用于处理发起支付过程中的相关事件。
以下是使用 AMSPaymentElement 创建 SDK 实例的示例代码:
AMSPaymentElementConfiguration configuration = new AMSPaymentElementConfiguration();
configuration.setLocale(new Locale("en", "US"));
configuration.setOption("showLoading", "true");
configuration.setOption("sandbox", "true");
configuration.setOption("notRedirectAfterComplete", "false");
String appearance =
  "{\"theme\":\"night\",\"layout\":{\"type\":\"accordion\"},\"variables\":{\"content-primary\":\"#ff5b4d\"}}";
configuration.setOption("appearance", appearance);

configuration.setOnCreateComponentListener(
  new OnCreateComponentListener() {
    @Override
    public void onCreateComponentCallback(AMSStatusResult statusResult) {
      if (statusResult.getError() != null) {
        switch (statusResult.getError().getCode()) {
          case "UI_STATE_ERROR":
            System.out.println("integration code error, please check the integration code");
            break;
          case "PARAM_INVALID":
            System.out.println("session data invalid, please check the session data");
            break;
          case "INITIALIZE_WEB_TIMEOUT":
            System.out.println("web app timeout, please invoke component again");
            break;
          default:
            System.out.println("unknown error, please contact support");
            break;
        }
      }
    }
  }
);

configuration.setOnSubmitPayListener(
  new OnSubmitPayListener() {
    @Override
    public void onSubmitPayCallback(AMSStatusResult statusResult) {
      AMSStatus status = statusResult.getStatus();
      AMSResultError error = statusResult.getError();
      if (status == AMSStatus.PROCESSING) {
        if (error != null && error.getCode() != null) {
          if ("PAYMENT_IN_PROCESS".equals(error.getCode())) {
            System.out.println(
              "payment is in processing, please try polling the payment result from the server"
            );
          } else if ("USER_CANCELED".equals(error.getCode())) {
            System.out.println(
              "user cancelled the payment process, please try invoke createComponent again"
            );
          } else if ("UNKNOWN_EXCEPTION".equals(error.getCode())) {
            System.out.println("unknown exception, please contact support");
          } else if ("PAYMENT_RESULT_TIMEOUT".equals(error.getCode())) {
            System.out.println(
              "get payment result timeout, please try polling the payment result from the server"
            );
          }
        }
      } else if (status == AMSStatus.CANCELLED || status == AMSStatus.SUCCESS) {
        System.out.println("payment cancelled or success, do nothing");
      } else if (status == AMSStatus.FAIL) {
        if (error != null && error.getCode() != null) {
          if ("ORDER_IS_CANCELLED".equals(error.getCode())) {
            System.out.println(
              "the merchant has proactively canceled the order, please check on your own."
            );
          } else if (
            "ORDER_IS_CLOSED".equals(error.getCode()) ||
            "INQUIRY_PAYMENT_SESSION_FAILED".equals(error.getCode())
          ) {
            System.out.println(
              "the order has timed out and is closed, please re-initiate payment using a new paymentRequestId."
            );
          } else {
            System.out.println("unknown error, please contact support");
          }
        }
      }
    }
  }
);

AMSPaymentElement amsPaymentElement = new AMSPaymentElement.Builder(
  this,
  (AMSPaymentElementConfiguration) configuration
).build();
  1. 使用实例对象中的 createComponent() 方法来调用 Payment Element:
// 创建支付会话时获取的 paymentSessionData
String paymentSessionData = "exxxxe";

amsPaymentElement.createComponent(this, paymentSessionData);

卸载 Payment Element

调用 onDestroy() 方法来释放 SDK 组件资源:
// 释放 SDK 组件资源
amsPaymentElement.onDestroy();

步骤 4:获取支付结果
服务端

在买家完成支付或支付超时后, Antom 会通过服务器交互将相应的支付结果发送给您,您可以通过以下方法之一获取支付结果:
  • 接收来自 Antom 的异步通知
  • 主动查询支付结果
接收异步通知
1. 设置接收通知的 webhook URL
完成支付或支付失败时,Antom 会向您设置的 webhook URL 发送异步通知,您可以选择以下两种方法中的一种来设置接收通知的 webhook URL(若两者都设置,则以接口请求中指定的 URL 优先):
  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 createPaymentSession(单笔支付)接口请求的 paymentNotifyUrl 参数传入该笔订单的异步通知接收 URL。
  • 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置 webhook URL。具体操作请参阅通知地址。
以下是异步通知请求体的代码示例:
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe", // 存储 cardToken 用于后续存卡支付使用
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
授权成功。
可以发起请款。
F
授权失败。
建议更换 paymentRequestId 重新发起支付。
APM 支付
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "paymentCreateTime": "2025-02-04T22:11:19-08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "ALIPAY_HK",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {},
  "paymentTime": "2025-02-04T22:14:25-08:00",
  "pspCustomerInfo": {
    "pspCustomerId": "216022003753XXXX",
    "pspName": "ALIPAY_HK"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付成功。
可以进行发货。
F
支付失败。
建议更换 paymentRequestId 重新发起支付。
2. 异步通知验签
当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
您需要按照以下方法对 Antom 发送的支付通知进行验签:
import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentNotifyHandleBySDK {

  /**
   * alipay public key, used to verify signature
   */
  private static final String SERVER_PUBLIC_KEY = "";

  /**
   * payment result notify processor
   * using <a href="https://spring.io">Spring Framework</a>
   *
   * @param request    HttpServletRequest
   * @param notifyBody notify body
   * @return
   */
  @PostMapping("/payNotify")
  public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {
    // 从 HTTP 请求中获取所需的参数
    String requestUri = request.getRequestURI();
    String requestMethod = request.getMethod();

    // 从请求头中获取所需的参数
    String requestTime = request.getHeader("request-time");
    String clientId = request.getHeader("client-id");
    String signature = request.getHeader("signature");

    Result result;
    AlipayResponse response = new AlipayResponse();

    try {
      // 验签
      boolean verifyResult = WebhookTool.checkSignature(
        requestUri,
        requestMethod,
        clientId,
        requestTime,
        signature,
        notifyBody,
        SERVER_PUBLIC_KEY
      );
      if (!verifyResult) {
        throw new RuntimeException("Invalid notify signature");
      }

      // 反序列化通知体

      // 根据通知结果更新订单状态

      // 向服务器响应已接收通知
      result = new Result("SUCCESS", "success", ResultStatusType.S);
    } catch (Exception e) {
      String errorMsg = e.getMessage();
      // 处理错误情况
      result = new Result("ERROR", errorMsg, ResultStatusType.F);
    }
    response.setResult(result);
    return ResponseEntity.ok().body(response);
  }
}
无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
常见问题
问:什么时候会发送通知?
答:这取决于支付是否完成:
  • 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。对于现金支付,通知可能会稍有延迟。
  • 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。

问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
  • 由于网络原因未收到异步通知。
  • 如果收到来自 Antom 的异步通知,但您没有按照返回收到确认信息的格式进行响应。
通知可以重发最多 8 次,或者直到收到正确的响应以终止传递。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和15 小时。
​
问:在响应异步通知时,需要添加签名吗?
答:不需要。如果您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
​
问:我在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
  • result:对于 APM 支付,其表示支付最终结果。对于 Apple Pay、Google Pay 和卡支付,则仅代表授权结果,需要进一步发起请款。
  • paymentRequestId:用于咨询、取消和对账的支付请求 ID。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
  • paymentAmount:表示支付金额。
主动查询结果
无论是 APM 支付、卡支付、Apple Pay 或者 Google Pay,您均可以调用 inquiryPayment 接口并传入 paymentRequestId 来主动查询支付或授权支付结果。
调用 inquiryPayment 接口的示例代码如下:
public static void inquiryPayment() {
  AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();

  // 替换为您的 paymentRequestId
  alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");

  AlipayPayQueryResponse alipayPayQueryResponse = null;
  try {
    alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
  } catch (AlipayApiException e) {
    String errorMsg = e.getMessage();
    // 处理错误情况
  }
}
以下代码展示了请求报文的示例:
{
  "paymentRequestId": "paymentRequestId01"
}
以下代码展示了响应报文的示例:
APM 支付
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "authExpiryTime": "2024-12-17T21:56:56-08:00",
  "cardInfo": {
    "cardBrand": "VISA",
    "funding": "CREDIT",
    "issuingCountry": "US"
  },
  "paymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "CARD",
  "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultInfo": {
    "avsResultRaw": "M",
    "cardBrand": "VISA",
    "cardNo": "************9954",
    "cvvResultRaw": "U",
    "funding": "CREDIT",
    "issuingCountry": "US",
    "networkTransactionId": "123qwe456rew",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentTime": "2024-12-10T21:56:57-08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
请根据响应中 paymentStatus 参数的值进行处理,具体返回值请参阅接口文档。
常见问题
问:使用 inquiryPayment 接口查询支付或授权状态时,应注意哪些关键参数?
答:请注意以下关键参数:
  • result:仅表示本次 inquiryPayment 接口的调用结果。对于 APM 支付,订单的支付结果需要根据 paymentStatus 进行判断(SUCCESS 成功/FAIL 失败/PROCESSING 处理中)。对于卡支付、Apple Pay 和 Google Pay,paymentStatus 仅代表授权结果,是否发货需要依赖请款结果决策。
  • paymentAmount:用于核对支付金额。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
​
问:我应该多久调用一次 inquiryPayment 接口?
答:以 2 秒的间隔持续调用 inquiryPayment 接口,直到获取最终的支付结果或收到异步支付结果通知为止。

步骤 5:请款
服务端
仅卡支付、Google Pay

Antom 提供自动请款和手动请款两种请款方式,您可根据业务需求自行选择。请款后,您可以通过异步通知或主动查询来获取请款结果,您需要根据请款结果来决定是否发货。具体操作请参阅请款。
Flutter

用户体验

以下图片展示了不同场景下使用 Payment Element 的用户体验:
iOS
Payment Element 渲染支付方式
以下图片展示了以弹窗形式调用 Payment Element 渲染的支付方式的模板:
如您选择由 Payment Element 渲染支付方式列表,Payment Element 默认在收银台页面上渲染所有支持的支付方式。以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
存卡支付
由 Payment Element 处理存卡支付场景:
商户自行渲染支付方式
以下图片展示了商户自行渲染支付方式的模板:
如您通过自行指定支付方式渲染支付方式列表,以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
Android
Payment Element 渲染支付方式
以下图片展示了以弹窗形式调用 Payment Element 渲染的支付方式的模板:
如您选择由 Payment Element 渲染支付方式列表,Payment Element 默认在收银台页面上渲染所有支持的支付方式。以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:
存卡支付
由 Payment Element 处理存卡支付场景:
商户自行渲染支付方式
以下图片展示了商户自行渲染支付方式的模板:
如您通过自行指定支付方式渲染支付方式列表,以下图片展示了不同支付方式的用户体验:
扫码支付
由 Payment Element 展示二维码以完成支付:
跳转支付方式页面支付
由 Payment Element 负责跳转到支付方式的页面以完成支付:
新卡支付
由 Payment Element 展示卡要素收集页以完成支付:

订单生命周期

以下是不同支付方式的生命周期。
APM 支付
对于 APM 支付,如 Alipay、Touch'n Go eWallet 等支付方式,当您发起支付请求且买家完成支付后,资金将直接转移到您的账户中。您可在窗口期内对订单进行撤销或者退款操作。
卡支付、Apple Pay、Google Pay
对于卡支付、Apple Pay、Google Pay,订单主要包括以下阶段:
  1. 授权:买家使用银行卡完成支付后,其资金将处于冻结状态。买家下单至完成授权期间,您都可以在窗口期内对订单发起撤销。
  2. 请款:你可以通过手动请款将买家的冻结资金转移到您的账户;或通过自动请款让 Antom 替您完成请款,具体信息请参阅请款。请款完成后,若有需要,您可以在窗口期内发起退款。
  3. 拒付:您需要根据情况发起拒付抗辩申请,具体信息请参阅争议。

支付流程

以下图片展示了如何通过 Payment Element 集成单笔支付:
Payment Element 渲染支付方式
商户自行渲染支付方式
  1. 买家进入结账页面并发起支付。
  2. 创建支付会话请求。
    您可以调用 createPaymentSession(单笔支付)接口获取支付会话。
  3. 调用 Payment Element。
    在客户端,通过支付会话调用 Payment Element。您可以选择由 Payment Element 或者您自行渲染支付方式,同时 Payment Element 会根据支付方式的特性处理信息、收集支付要素、进行重定向、应用调用、二维码显示、验证等流程。当支付完成后,根据您的设置以及支付方式特性,您需要按照onSubmitPayCallback() 方法返回的结果处理跳转流程或者由系统自动回跳到您的支付结果页面。
  4. 获取支付结果。
    通过以下两种方法之一获取支付结果:
注意:在卡支付、Apple Pay 和 Google Pay 支付场景下,采用的是授权请款模式。步骤 1 至 4 仅完成了授权部分,即买家使用银行卡完成支付,其资金处于冻结状态。为了将买家的冻结资金转至您的账户,您还需要集成请款步骤。请款成功的结果将作为您发货的依据。
  1. 发起请款并获取请款结果。
默认情况下,Antom 会自动为您处理资金请款。您也可以通过调用 capture(单笔支付)接口来手动进行请款。随后,通过以下两种方法之一获取请款结果:

集成准备

在您开始集成前,请阅读集成指南及接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:
  • 已获得 client ID。
  • 已完成密钥配置。
  • 已完成异步通知接收地址的配置。
  • 集成 Antom 服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
  • 参阅 Flutter SDK 文档来集成客户端 SDK 资源包。

集成步骤

请按照以下步骤开始集成:
  1. (可选)预加载 SDK
  2. 创建支付会话
  3. 调用 Payment Element
  4. 获取支付结果
  5. 发起请款

(可选)步骤 1:预加载 SDK
客户端

在创建支付会话前,强烈建议您调用 preload() 方法预加载 SDK,以提升收银台页面的渲染速度,减少买家在支付过程中的等待时间。按照以下代码示例执行预加载操作:
// 预加载 Payment Element SDK
AMSPaymentElement.preload();

步骤 2:创建支付会话
服务端

传入订单信息以调用 createPaymentSession(单笔支付)接口来创建支付会话,获取唤起 Payment Element 的 paymentSessionData。您可选择自行渲染支付方式列表或由 Payment Element 渲染支付方式列表。
建议您在买家点击支付按钮后创建支付会话,并根据你所选择的渲染收银台支付方式列表的方式,在调用 createPaymentSession(单笔支付)接口时传入相应的参数:
Payment Element 渲染支付方式
当您使用 Payment Element 渲染的支付方式列表时,您只需传入以下参数。Payment Element 默认在收银台页面上渲染所有支持的支付方式,您也可以通过指定支付方式来选择您需要的支付方式。
参数名称
是否必需
描述
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy
是
支付请求的结算策略。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.APP).osType(OsType.IOS).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
如果由 Payment Element 渲染收银台的支付方式列表,则会展示所有支付方式。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "APP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "IOS"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
商户自行渲染支付方式
自行渲染支付方式列表:当您自行渲染支付方式列表时,您必须传入下表中列出的指定支付方式参数。如果 Payment Element 需要采集支付要素,则需要传入下表中列出的卡支付信息参数。
类型
参数名称
是否必需
描述
基础参数
productCode
是
此场景下该值固定为 CASHIER_PAYMENT。
productScene
是
此场景下该值固定为 ELEMENT_PAYMENT。
paymentRequestId
是
由商户生成的专属 ID,每次发起支付时需使用新的 ID。
paymentAmount
是
支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。
paymentRedirectUrl
是
商户端支付结果页,需根据服务端结果展示,不是一个固定的成功页面。
paymentNotifyUrl
否
支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。
settlementStrategy.settlementCurrency
是
该笔支付的结算币种,若业务签约了多个结算币种,需在接口中指定。
order.referenceOrderId
是
商户端订单号。
order.orderAmount
是
商户侧向买家提供服务或商品的订单金额。此参数用于买家的消费记录或支付结果页面展示。其包含以下参数:
  • currency:币种代码。其值为遵循 ISO 4217 标准的三位币种代码。
  • value:以最小币种单位的正整数形式表示的金额值。
注意:若存在商品信息,则 order.orderAmount.value 的值需与商品明细计算出的总金额完全匹配,否则接口将返回参数校验错误。计算逻辑:Σ(goods[i].goodsUnitAmount.value × goods[i].goodsQuantity) = order.orderAmount.value
order.orderDescription
是
商户端订单描述。
env.terminalType
否
商户服务适用的终端类型。有效值为:
  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。
注意:在 Apple Pay 和 Google Pay 支付场景下,此参数为必传。
env.osType
否
买家发起交易的操作系统类型。有效值为:
  • IOS:表示操作系统为苹果的 iOS。
  • ANDROID:表示操作系统为谷歌的 Android。
注意:当 env.terminalType 为 WAP 或 APP 时,请指定此参数。
env.clientIp
否
买家的 IP 地址。
注意:卡支付、Apple Pay 和 Google Pay 场景下需要提供此信息。
卡支付信息参数(具体请参考卡支付特性)
paymentFactor.captureMode
否
请款模式。有效值为:
  • AUTOMATIC:表示在授权后,Antom 自动进行请款。当值为空或未传递此参数时,默认为此值。
  • MANUAL:表示您通过调用 capture(单笔支付)接口进行手动请款。
order.buyer
是
商户端买家信息。至少需要提供以下三者其中一个信息:
  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail
availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication
否
您需要根据当前交易的风险和拒付情况,决定是否设置交易认证类型为 3DS 认证。有效值为:
  • true:指交易认证类型为 3DS 认证。
  • false:指交易认证类型为非 3DS 认证。如果此参数为空或未传递,默认为此值。
availablePaymentMethod.paymentMethodMetaData.tokenizeMode
否
如果您需要存储卡信息,可通过此参数让 Antom 帮您保存卡信息,Antom 会将卡信息替换为一个唯一且安全的 token 用于后续支付。有效值为:
  • ENABLED:表示您已获得买家绑卡授权,需要存储卡信息用于后续支付。
  • DISABLED:表示您不需要存储卡信息。当值为空或不指定此参数时同样适用。
  • ASKFORCONSENT:在中间页向买家展示存卡按钮,允许买家选择是否存储卡信息。
availablePaymentMethod.paymentMethodMetaData.isCardOnFile
否
表示该笔交易使用的卡是否曾在商户侧完成过支付并存档。有效值为:
  • true:指该笔交易使用的卡是曾在商户侧完成过支付的已存卡。在已存卡支付场景下,将该参数设置为 true。
  • false:默认值。指该笔交易使用的是未在商户侧进行过支付的新卡。
savedPaymentMethods.paymentMethodId
否
存卡交易下使用,代表传入新卡交易时返回的 cardToken 信息。
指定支付方式参数(具体请参考指定支付方式)
availablePaymentMethod.paymentMethodTypeList.paymentMethodType
否
指定具体的支付方式,支持指定单个或者多个支付方式。参见支付方式枚举值以查看有效值。
availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder
否
设置支付方式的优先级顺序。
availablePaymentMethod.paymentMethodTypeList.expressCheckout
否
设置是否使用支付方式的极速支付形式。目前仅 ALIPAY_CN、APPLEPAY 和 GOOGLEPAY 可以被设置为极速支付。有效值为:
  • true:表示设置该支付方式为极速支付。
  • false:表示不将该支付方式设置为极速支付。
注意:该参数目前仅支持在 Android 及 iOS 使用。
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)。
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

  // 替换为您的环境信息
  Env env = Env.builder().terminalType(TerminalType.APP).osType(OsType.IOS).build();
  alipayPaymentSessionRequest.setEnv(env);

  // 替换为您的 paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // 转换金额单位(实际应用中,金额应在您的服务器端计算)
  // 详情请参考:<a href="https://docs.antom.com/ac/ref_zh-cn/cc">金额的使用规则</a>
  long amountMinorLong = Money.of(
    CurrencyUnit.of(payment.currency),
    new BigDecimal(payment.amountValue)
  ).getAmountMinorLong();

  // 设置金额
  Amount amount = Amount.builder()
    .currency(payment.currency)
    .value(String.valueOf(amountMinorLong))
    .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // 设置支付策略
  // 替换为您现有的结算货币
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
    .settlementCurrency("USD")
    .build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // 设置买家信息
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // 替换为您的 orderId
  String orderId = UUID.randomUUID().toString();
  // 设置订单信息
  Order order = Order.builder()
    .referenceOrderId(orderId)
    .orderDescription("antom sdk testing order")
    .orderAmount(amount)
    .buyer(buyer)
    .build();
  alipayPaymentSessionRequest.setOrder(order);

  // 替换为您的通知地址
  // 或者在 Antom Dashboard 配置: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">通知地址</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl(
    "https://www.yourNotifyUrl.com/payment/receivePaymentNotify"
  );

  // 替换为您的跳转地址
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
    "https://localhost:8080/index.html?paymentRequestId=" + paymentRequestId
  );

  // 替换为您的指定支付方式
  AvailablePaymentMethod availablePaymentMethods = AvailablePaymentMethod.builder()
    .paymentMethodTypeList(
      List.of(PaymentMethodTypeItem.builder().paymentMethodType("ALIPAY_CN").build())
    )
    .build();
  alipayPaymentSessionRequest.setAvailablePaymentMethod(availablePaymentMethods);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
    long startTime = System.currentTimeMillis();
    System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
    alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    System.out.println(
      "payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n"
    );
  } catch (AlipayApiException e) {
    return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok()
    .body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
当您自行渲染支付方式列表时,需要通过指定单个支付方式集成。以下代码展示了一个请求报文的示例:
{
  "env": {
    "terminalType": "APP",
    "clientIp": "***.***.***.***", // 买家 IP 地址
    "osType": "IOS"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // 指定支付方式
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
以下代码展示了一个响应的示例,其中包含以下参数:
  • result.resultStatus:createPaymentSession(单笔支付)接口的调用结果。
  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
{
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
以下是创建支付会话响应中 result.resultStatus 可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付会话已成功创建,同时返回 paymentSessionData。
请继续执行后续步骤。
U
未知问题。
建议更换 paymentRequestId 以解决问题。如果问题未解决,请联系 Antom 技术支持。
F
支付会话创建失败。
建议检查并验证当前接口所需的请求字段(包括头部字段和正文字段)是否正确传递并有效。
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 paymentRequestId 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的兼容性问题,请求中的参数请勿使用中文字符。
​
问:如何设置接收支付通知的地址?
答:在 createPaymentSession(单笔支付)接口的请求中指定 paymentNotifyUrl 参数,以接收支付结果的异步通知(notifyPayment),或者在 Antom Dashboard 中配置接收地址。如果请求和 Antom Dashboard 中都指定了地址,请求中的值优先。
​
问:返回的 paymentSessionData 是否需要处理后再传给客户端?
答:请勿对 paymentSessionData 进行任何处理,否则可能会导致调用 Payment Element 失败。

步骤 3:调用 Payment Element
客户端

在您的客户端使用 paymentSessionData 调用 Payment Element,在买家提交支付后,Payment Element 会根据不同支付方式,负责展示二维码、跳转支付方式页面、3DS 认证、回跳商户结果页等流程。
  1. 在服务端获取到 paymentSessionData 后,使用 AMSPaymentElement 类来创建 Payment Element 实例。
a. 调用 init() 方法进行初始化,并在 configurations 对象中传入相关配置项:
final element = AMSPaymentElement();

element.init(
  {
    "locale": "en_US",
    "showLoading": "true",
    "sandbox": "true",
    "notRedirectAfterComplete": "false",
    "appearance":
    "{"theme":"default","layout":{"type":"accordion"},"variables":{}}",
  },
  (result) {
    if (result.getStatus() == AMSStatus.SUCCESS) {
      // 初始化成功,继续调用 createComponent()
      print('Initialization succeeded');
    } else {
      // 初始化失败,检查 result.getError()
      final error = result.getError();
      print('Initialization failed: ${error?.getCode()} - ${error?.getMessage()}');
    }
  },
);
注意:init() 方法中 "notRedirectAfterComplete" 的不同配置会影响商户页面的跳转方式,详情请参阅回跳商户页面。
b. 在 init() 方法中实现 onResult 回调函数,用于监控支付组件初始化流程中的异常事件,请参阅回调参数中的错误 code 和 message 进行处理。
c. (可选)在 setOnSubmitPayListener() 方法中实现 onSubmitPayCallback() 回调函数,用于监控支付过程中的事件,请参阅回调参数中的错误 code 和 message 进行处理。
注意:强烈建议您使用 setOnSubmitPayListener() 方法监控支付事件,以提升用户体验。
d. 调用 createComponent() 方法创建并展示支付组件 UI,并实现 onResult 回调函数,用于监控支付组件创建流程中的异常事件,请参阅回调参数中的错误 code 和 message 进行处理。
以下是使用 AMSPaymentElement 创建 Payment Element 实例的示例代码:
AMSPaymentElement.preload();

// 创建 AMSPaymentElement 实例
AMSPaymentElement amsPaymentElement = AMSPaymentElement();

// 设置配置项,参数设置可参考下文
Map<String, dynamic> amsPaymentElementConfiguration = {
  "locale": "en_US",
  "showLoading": "true",
  "sandbox": "true",
  "notRedirectAfterComplete": "false",
  "appearance":
  "{"theme":"default","layout":{"type":"accordion"},"variables":{}}",
};

// 初始化并监听初始化结果
amsPaymentElement?.init(config, (result) {
  if (result.getError() != null && result.getError()?.getCode() != null) {
    print(
      "code: ${result.getError()?.getCode()}, message: ${result.getError()?.getMessage()}",
    );
  }
});

// 可选,但强烈建议设置支付状态监听,按照错误码和错误信息进行相应处理,具体处理建议请参考事件码列表
amsPaymentElement?.setOnSubmitPayListener((result) {
  AMSStatus? status = result.getStatus();
  if (status != AMSStatus.SUCCESS) {
    AMSResultError? error = result.getError();
    String code = error?.getCode() ?? "";
    String message = error?.getMessage() ?? "";
    print("code: $code, message: $message");
  }
});


// 创建支付会话时获取的 paymentSessionData
String paymentSessionData = "exxxxe";

// 使用实例对象中的 createComponent 方法来调用 Payment Element,并设置调用结果监听,如果错误码不为空,可参考事件码列表进行处理
amsPaymentElement.createComponent(sessionData, (result) {
  if (result.getError() != null && result.getError()?.getCode() != null) {
    print(
      "code: ${result.getError()?.getCode()}, message: ${result.getError()?.getMessage()}",
    );
  }
});

卸载 Payment Element

调用 destroy() 方法释放 SDK 组件资源:
// 释放 SDK 组件资源
amsPaymentElement.destroy();

步骤 4:获取支付结果
服务端

在买家完成支付或支付超时后, Antom 会通过服务器交互将相应的支付结果发送给您,您可以通过以下方法之一获取支付结果:
  • 接收来自 Antom 的异步通知
  • 主动查询支付结果
接收异步通知
1. 设置接收通知的 webhook URL
完成支付或支付失败时,Antom 会向您设置的 webhook URL 发送异步通知,您可以选择以下两种方法中的一种来设置接收通知的 webhook URL(若两者都设置,则以接口请求中指定的 URL 优先):
  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 createPaymentSession(单笔支付)接口请求的 paymentNotifyUrl 参数传入该笔订单的异步通知接收 URL。
  • 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置 webhook URL。具体操作请参阅通知地址。
以下是异步通知请求体的代码示例:
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken": "exxxxe", // 存储 cardToken 用于后续存卡支付使用
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
授权成功。
可以发起请款。
F
授权失败。
建议更换 paymentRequestId 重新发起支付。
APM 支付
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "HKD",
    "value": "100"
  },
  "paymentCreateTime": "2025-02-04T22:11:19-08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "ALIPAY_HK",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {},
  "paymentTime": "2025-02-04T22:14:25-08:00",
  "pspCustomerInfo": {
    "pspCustomerId": "216022003753XXXX",
    "pspName": "ALIPAY_HK"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
下表展示了支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:
result.resultStatus
信息
后续操作
S
支付成功。
可以进行发货。
F
支付失败。
建议更换 paymentRequestId 重新发起支付。
2. 异步通知验签
当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
您需要按照以下方法对 Antom 发送的支付通知进行验签:
import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentNotifyHandleBySDK {

  /**
   * alipay public key, used to verify signature
   */
  private static final String SERVER_PUBLIC_KEY = "";

  /**
   * payment result notify processor
   * using <a href="https://spring.io">Spring Framework</a>
   *
   * @param request    HttpServletRequest
   * @param notifyBody notify body
   * @return
   */
  @PostMapping("/payNotify")
  public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {
    // 从 HTTP 请求中获取所需的参数
    String requestUri = request.getRequestURI();
    String requestMethod = request.getMethod();

    // 从请求头中获取所需的参数
    String requestTime = request.getHeader("request-time");
    String clientId = request.getHeader("client-id");
    String signature = request.getHeader("signature");

    Result result;
    AlipayResponse response = new AlipayResponse();

    try {
      // 验签
      boolean verifyResult = WebhookTool.checkSignature(
        requestUri,
        requestMethod,
        clientId,
        requestTime,
        signature,
        notifyBody,
        SERVER_PUBLIC_KEY
      );
      if (!verifyResult) {
        throw new RuntimeException("Invalid notify signature");
      }

      // 反序列化通知体

      // 根据通知结果更新订单状态

      // 向服务器响应已接收通知
      result = new Result("SUCCESS", "success", ResultStatusType.S);
    } catch (Exception e) {
      String errorMsg = e.getMessage();
      // 处理错误情况
      result = new Result("ERROR", errorMsg, ResultStatusType.F);
    }
    response.setResult(result);
    return ResponseEntity.ok().body(response);
  }
}
无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
常见问题
问:什么时候会发送通知?
答:这取决于支付是否完成:
  • 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。对于现金支付,通知可能会稍有延迟。
  • 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。

问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
  • 由于网络原因未收到异步通知。
  • 如果收到来自 Antom 的异步通知,但您没有按照返回收到确认信息的格式进行响应。
通知可以重发最多 8 次,或者直到收到正确的响应以终止传递。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和15 小时。
​
问:在响应异步通知时,需要添加签名吗?
答:不需要。如果您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
​
问:我在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
  • result:对于 APM 支付,其表示支付最终结果。对于 Apple Pay、Google Pay 和卡支付,则仅代表授权结果,需要进一步发起请款。
  • paymentRequestId:用于咨询、取消和对账的支付请求 ID。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
  • paymentAmount:表示支付金额。
主动查询结果
无论是 APM 支付、卡支付、Apple Pay 或者 Google Pay,您均可以调用 inquiryPayment 接口并传入 paymentRequestId 来主动查询支付或授权支付结果。
调用 inquiryPayment 接口的示例代码如下:
public static void inquiryPayment() {
  AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();

  // 替换为您的 paymentRequestId
  alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");

  AlipayPayQueryResponse alipayPayQueryResponse = null;
  try {
    alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
  } catch (AlipayApiException e) {
    String errorMsg = e.getMessage();
    // 处理错误情况
  }
}
以下代码展示了请求报文的示例:
{
  "paymentRequestId": "paymentRequestId01"
}
以下代码展示了响应报文的示例:
APM 支付
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
卡支付、Apple Pay、Google Pay
{
  "actualPaymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "authExpiryTime": "2024-12-17T21:56:56-08:00",
  "cardInfo": {
    "cardBrand": "VISA",
    "funding": "CREDIT",
    "issuingCountry": "US"
  },
  "paymentAmount": {
    "currency": "USD",
    "value": "5000"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "CARD",
  "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultInfo": {
    "avsResultRaw": "M",
    "cardBrand": "VISA",
    "cardNo": "************9954",
    "cvvResultRaw": "U",
    "funding": "CREDIT",
    "issuingCountry": "US",
    "networkTransactionId": "123qwe456rew",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentTime": "2024-12-10T21:56:57-08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
请根据响应中 paymentStatus 参数的值进行处理,具体返回值请参阅接口文档。
常见问题
问:使用 inquiryPayment 接口查询支付或授权状态时,应注意哪些关键参数?
答:请注意以下关键参数:
  • result:仅表示本次 inquiryPayment 接口的调用结果。对于 APM 支付,订单的支付结果需要根据 paymentStatus 进行判断(SUCCESS 成功/FAIL 失败/PROCESSING 处理中)。对于卡支付、Apple Pay 和 Google Pay,paymentStatus 仅代表授权结果,是否发货需要依赖请款结果决策。
  • paymentAmount:用于核对支付金额。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
​
问:我应该多久调用一次 inquiryPayment 接口?
答:以 2 秒的间隔持续调用 inquiryPayment 接口,直到获取最终的支付结果或收到异步支付结果通知为止。

步骤 5:请款
服务端
仅卡支付、Google Pay

Antom 提供自动请款和手动请款两种请款方式,您可根据业务需求自行选择。请款后,您可以通过异步通知或主动查询来获取请款结果,您需要根据请款结果来决定是否发货。具体操作请参阅请款。

支付后操作

完成支付后,您可对交易进行以下支付后的操作:

取消交易
服务端

对于支付成功的订单,如果买家在当天内申请取消订单或退款,您可以通过 Antom 提供的取消支付能力将订单取消或解冻资金。此外,对于尚未完成支付的订单,您也可以直接进行取消。具体操作请参阅取消交易。

退款
服务端

不同支付方式的退款能力各有差异,若您需要了解 Antom 的退款规则及如何对成功的交易发起退款,请参阅退款。

争议
服务端

当某笔交易发生争议时,Antom 为您提供争议处理相关服务。更多信息请参阅争议运营手册和争议实施方案。

支付方式特性

本节内容为您阐述各类支付方式在支持特性方面的差异。

默认关单时间

各支付方式的默认订单关闭时间有所不同,具体请参阅支付方式默认关单时间。
注意:由于 Payment Element 订单默认有效期为 1 小时,实际关单时间需在支付方式原有默认时间基础上增加 1 小时。例如,若某支付方式默认关单时间为 14 分钟,则 Payment Element 订单的实际关单时间将为 1 小时 14 分钟。

集成要点

参阅集成关键注意事项了解不同支付方式的集成要点及建议方案。

卡支付特性

Payment Element 支持以下卡支付特性,点击了解不同特性的具体信息及使用方法:

更多内容

Antom 还为您提供以下定制化内容:
  • 自定义外观样式:Antom 提供了丰富的样式自定义能力,包含主题、布局以及 CSS 样式自定义功能。
  • Google Pay:通过 Google Pay 服务,买家可以使用存储在其 Google 账户中的信用卡或借记卡来进行支付。使用 Payment Element,您无需另外集成 Google Pay 的 SDK,Payment Element 会为您加载 Google Pay,并可指定 Google Pay 为极速支付形式。
  • Apple Pay:通过 Apple Pay 服务,买家可以使用存储在其 Apple Pay 账户中的信用卡或借记卡来进行支付。使用 Payment Element,您无需另外集成 Apple Pay 的 SDK,Payment Element 会为您加载 Apple Pay,并可指定 Apple Pay 为极速支付形式。

指定支付方式

您可以通过在 createPaymentSession(单笔支付)接口传入参数,指定在 Payment Element 上展示的支付方式、支付方式列表的排序,以及极速支付方式的展示。此功能为您带来以下优势:
  • 根据您的业务地区过滤当地的支付方式
  • 按照您的偏好对支付方式进行排序
  • 可以将主流的支付方式如 Alipay、Apple Pay、Google Pay 以极速支付的形式展示(仅支持 App 端)
具体步骤请参阅指定支付方式。

需要嵌入的支付方式

以下支付方式需要您嵌入支付要素采集组件:
支付方式类型
支付方式
枚举值
卡
CARD
CARD
CARD
CARD
CARD
CARD
CARD
CARD
CARD
CARD
CARD
电子钱包
OVO
Mercado Pago(墨西哥)
MERCADOPAGO_MX
Mercado Pago(巴西)
MERCADOPAGO_BR
Mercado Pago(秘鲁)
MERCADOPAGO_PE
Mercado Pago(智利)
MERCADOPAGO_CL
现金支付
SEVENELEVEN
KONBINI
网银转账
BANCOMATPAY
BLIK
ONLINEBANKING_PAYEASY
ONLINEBANKING_FPX

支付重试机制

Antom 为您提供支付重试机制。通过 createPaymentSession(单笔支付)接口创建的支付会话,允许买家在支付会话有效期内多次尝试支付并自由切换支付方式,无需商户服务端重新调用接口。更多信息请参阅支付重试机制。