嵌入模式

Antom Checkout Page 是一款高效便捷的低代码集成支付页面产品,支持多种主流支付方式并覆盖全球多个地区,满足不同市场和场景的需求。通过简单的开发配置,您即可快速搭建一个界面专业、功能齐全的收银台页面,为买家提供流畅便捷的支付体验,同时显著提升支付接入效率,助力业务增长。

本方案通过 SDK 形式实现集成,由您的商品加购页面嵌入 Antom Checkout Page 完成支付。

用户体验

下图展示一般场景下,商户将 Antom Checkout Page 嵌入至自己网页的用户体验流程:

Pc.png

下图展示部分支付方式会在内嵌的 Checkout Page 中跳转至具体第三方支付页面的用户体验流程:

Pc-1.png

支付流程

使用 Antom Checkout Page 全托管模式支付的流程包括以下步骤:

嵌入模式-中文版-最新.png

  1. 买家在商户侧下单。
  2. 创建支付会话请求。

当买家在商户侧下单,您需要调用 支付会话创建(收银台) 接口获取调用 SDK 的 paymentSessionData 

  1. 调用客户端SDK。

商户客户端通过 paymentSessionData  调用 SDK 内嵌 Checkout Page 组件在商户网页中,之后买家在 Checkout Page 组件中提交支付,SDK 会处理支付流程。

  1. 获取支付结果。

通过异步通知获取支付结果。 在 支付会话创建(收银台) 接口中设置 paymentNotifyUrl 参数,以指定接收异步通知的地址。当支付请求成功或过期时,Antom 会通过 支付通知 接口向您发送异步通知。

支付集成步骤

请按照以下步骤开始集成:

  1. 创建支付会话
  2. 嵌入 Antom Checkout Page
  3. 异步通知处理 

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

买家在商品详情或者购物车页面点击支付,支付时可以选择 Antom 提供的支付方式。若需配置支付方式,请参见指定支付方式。当买家进行支付时,您需要收集关键信息,如支付请求 ID、订单信息、支付重定向链接和支付结果通知链接。您可以调用 支付会话创建(收银台)接口并传入订单信息,创建支付会话后跳转至 Antom Checkout Page。

1. 安装接口库

您可以在 GitHub 上找到最新版本。

copy
<dependency>
   <groupId>com.alipay.global.sdk</groupId>
   <artifactId>global-open-sdk-java</artifactId>
   <version>{latest_version}</version>
</dependency>

2. 初始化请求实例

创建一个单例资源以向 Antom 发起请求。

copy
import com.alipay.global.api.AlipayClient;
import com.alipay.global.api.DefaultAlipayClient;
import com.alipay.global.api.model.constants.EndPointConstants;

public class Sample {
    public static final String        CLIENT_ID            = "";
    public static final String        ANTOM_PUBLIC_KEY     = "";
    public static final String        MERCHANT_PRIVATE_KEY = "";

    private final static AlipayClient CLIENT               = new DefaultAlipayClient(
            EndPointConstants.SG, MERCHANT_PRIVATE_KEY, ANTOM_PUBLIC_KEY, CLIENT_ID);

}

3. 调用支付会话创建接口

以下示例代码展示了如何调用 支付会话创建(收银台)接口:

copy
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);

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

    // 设置金额 
    Amount amount = Amount.builder().currency("SGD").value("4200").build();
    alipayPaymentSessionRequest.setPaymentAmount(amount);

    // 设置支付方式 
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("SHOPEEPAY_SG").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // 替换为您的 orderId  
    String orderId = UUID.randomUUID().toString();

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

    // 设置订单信息
    Order order = Order.builder().referenceOrderId(orderId)
        .orderDescription("antom testing order").orderAmount(amount).buyer(buyer).build();
    alipayPaymentSessionRequest.setOrder(order);

    // 替换为您的通知地址
    alipayPaymentSessionRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");

    // 替换为您的跳转地址
    alipayPaymentSessionRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");

    AlipayPaymentSessionResponse alipayPaymentSessionResponse = null;
    try {
        alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // 处理错误情况
    }
}

4. 创建支付会话

如果您的支付方式中包含卡支付,支付会话参数中必须传入商户端的买家信息。详情请参见卡支付

以下是请求参数重点字段:

类型

字段

是否必需

描述

基础字段

productCode

此场景下该字段的值固定为 CASHIER_PAYMENT

productScene

此场景下该字段的值固定为 CHECKOUT_PAYMENT

paymentRequestId

商户为识别支付请求而分配的专属 ID。
paymentAmount

商户请求以订单币种收取的支付金额。

paymentRedirectUrl

支付完成后买家被重定向到的商户页面链接。
paymentNotifyUrl

支付结果通知地址,可通过接口指定或在 Antom Dashboard 上设置固定值。
settlementStrategy

支付请求的结算策略。如果您签署了多个结算币种,需在接口中指定 settlementCurrency

locale

商户指定的 Antom Checkout Page展示语言。如果该字段为空或设置为自动,则将使用浏览器的默认语言设置,通常为英文。

订单字段

order.orderAmount

商户端订单金额。

order.referenceOrderId

商户端订单号。

order.orderDescription

商户端订单描述。

以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 支付会话创建(收银台)

以下代码展示了一个请求报文的示例:

copy
{
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "goods": [
      {
        "goodsBrand": "Antom Brand",
        "goodsCategory": "outdoor goods/bag",
        "goodsImageUrl": "https://mdn.alipayobjects.com/portal_pdqp4x/afts/file/A*H8M9RrxlArAAAAAAAAAAAAAAAQAAAQ",
        "goodsName": "Classic Woman Bag",
        "goodsQuantity": "1",
        "goodsSkuName": "Black",
        "goodsUnitAmount": {
          "currency": "SGD",
          "value": "6000"
        },
        "goodsUrl": "https://yourGoodsUrl",
        "referenceGoodsId": "yourGoodsId"
      }
    ],
    "orderAmount": {
      "currency": "SGD",
      "value": "6000"
    },
    "orderDescription": "antom ckp testing order",
    "referenceOrderId": "c3df9b82-ff67-424b-880b-06c3615b46ea"
  },
  "paymentAmount": {
    "currency": "SGD",
    "value": "6000"
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com/payment/receiveNotify",
  "paymentRedirectUrl": "http://localhost:8080/index.html?paymentRequestId=597795b7-c812-4132-bd7d-c55914eefdcb",
  "paymentRequestId": "597795b7-c812-4132-bd7d-c55914eefdcb",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "CHECKOUT_PAYMENT"
}

以下代码展示了一个响应的示例,其中包含以下参数:

  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
  • normalUrl: Checkout Page 的跳转链接。
copy
{
    "normalUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=1iwX2rH5kXnUGT5372d0kHD7PwcgPmRSMgAsvKs8hqRkqobbtWbep59PU2eO5w72h%2B%2XXXX",
    "paymentSessionData": "1iwX2rH5kXnUGT5372d0kHD7PwcgPmRSMgAsvKs8hqRkqobbtWbep59PU2eO5w72h+/c278B+P+nDVNzrQySQQ==&&SG&&188&&eyJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSXXXX",
    "paymentSessionExpiryTime": "2025-03-19T16:21:06+08:00",
    "paymentSessionId": "1iwX2rH5kXnUGT5372d0kHD7PwcgPmRSMgAsvKs8hqSln4WiVZXXXX",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

下表展示了请求报文中 result.resultStatus 字段可能返回的值,请您指引进行处理:

result.resultStatus

信息

下一步操作

S 表示支付会话创建成功。

获取 Antom Checkout Page 链接(normalUrl) 并返回给商户前端。具体操作步骤请参见步骤 2

U表示由于未知原因支付会话创建失败。更换 paymentRequestId 重新调用接口以解决问题。如果问题未解决,请联系 Antom 技术支持。
F表示支付会话创建失败。请检查并验证当前接口所需的请求字段(包括头部字段和正文字段)是否正确传递并有效。

注意:如果您未收到响应报文,可能是网络超时所致。更换 paymentRequestId 重新调用接口以解决问题。

步骤 2:嵌入 Antom Checkout Page 客户端

SDK 是用于处理支付流程的组件,为了收集信息以及根据 支付会话创建(收银台)接口中指定的支付方式在应用间切换,您需要通过创建支付会话来启动 SDK。

1. 安装 

在开始集成之前,请确保已完成以下环境准备:

  • 处理兼容性问题:为 Internet Explorer 和其他旧版浏览器提供相应的 Polyfills。建议在构建项目时使用 babel-preset-env 来解决浏览器兼容性问题。
  • 使用以下推荐的浏览器版本:
    • 移动浏览器:
      • iOS 11 及以上版本。
      • Android 5.0 及以上版本。
    • 对于计算机浏览器,请使用以下推荐版本:

imageEdge

Lastest 2 versions

imageFirefox

Lastest 2 versions

imageChrome

Lastest 2 versions

imageSafari

Lastest 2 versions

imageOpera

Lastest 2 versions

imageElectron

Lastest 2 versions

请查阅 Web/WAP 端集成 SDK 资源包文档来集成 SDK 资源包。

2. 初始化 SDK 

使用 AMSCheckoutPage 来创建 SDK 实例。配置对象包括以下参数: 

参数名称

是否必需

描述

environment

用于传递环境信息。有效值包括:

  • sandbox:沙箱环境
  • prod:生产环境

onEventCallback

一个回调函数,在 SDK 运行期间,当发生支付事件(如支付结果或表单提交错误)时,返回特定的事件代码。有关更多信息,请参阅 SDK 参考信息

以下示例代码展示了如何实例化 SDK:

copy
npm:
import { AMSCheckoutPage } from '@alipay/ams-checkout' // 包管理
const checkoutApp = new AMSCheckoutPage({
  environment: "sandbox",
  onEventCallback: ({code, message}) => {},
});
cdn:
// CDN引入方式下:使用 window.AMSCheckoutPage 实例化
const checkoutApp = new AMSCheckoutPage({
  environment: "sandbox",
  onEventCallback: ({code, message}) => {},
});

3. 调用 SDK 

当买家下单跳转 Antom Checkout Page 时您需要创建 SDK 并使用支付会话进行初始化。

创建 DOM 节点

在您的收银台页面创建一个 DOM 节点用于嵌入 Antom Checkout Page 组件。

copy
<div class="content">
  <div class="checkout-container" id="ckp-embed-wrapper"></div>
</div>
创建组件

使用实例对象中的 mountComponent 函数来创建 Antom Checkout Page 组件:

参数名称

是否必需

描述

sessionData

使用 sessionData 参数创建配置对象:将通过 支付会话创建(收银台)接口在响应中获取的完整 paymentSessionData 参数传递给 sessionData 参数。

copy
async function create(sessionData) {
  await checkoutApp.mountComponent({ 
    sessionData: sessionData, 
  },'#ckp-embed-wrapper');
}
销毁组件

在以下情况下,调用 unmount 方法来释放 SDK 组件资源:

copy
// Free SDK component resources
checkoutApp.unmount();

4. 支付结果处理

支付结果将通过 onEventCallback 函数给出,您需要通过 onEventCallback 结果中的数据自定义支付结果的处理流程。这里的支付结果仅用于前端显示,最终订单状态以服务器端为准。 

以下是 onEventCallback 可能返回的支付结果事件代码:

事件代码

消息

解决方案

SDK_PAYMENT_SUCCESSFUL

支付成功。

建议将买家重定向到支付结果页面。

SDK_PAYMENT_FAIL

支付失败。

建议您检查在 onEventCallback 结果数据中 paymentResultCode 的值以获取详细信息。根据提供的信息,引导买家重新尝试支付。

SDK_PAYMENT_CLICK_BACK_TO_MERCHANT

买家点击结果页的 Back to merchant 控件时触发的事件。

建议将买家重定向到支付结果页面。

SDK_PAYMENT_CANCEL

买家在未提交订单的情况下退出了支付页面。

在有效期内,可以使用 paymentSessionData 重新调用SDK;如果已过期,需要重新请求paymentSessionData

以下示例代码展示了如何处理回调函数 onEventCallback

copy
function onEventCallback({ code, result }) {
  switch (code) {
    case 'SDK_PAYMENT_SUCCESSFUL':
      // Payment was successful. Redirect buyers to the payment result page.
      break;
    case 'SDK_PAYMENT_FAIL':
      console.log('Check the payment result data', result);
      // Payment failed. Guide buyers to retry the payment based on the provided information.
      break;
    case 'SDK_PAYMENT_CANCEL':
      // Guide buyers to retry the payment.
      break;
    case 'SDK_PAYMENT_CLICK_BACK_TO_MERCHANT':
      // User click the back to merchant buttom. Redirect buyers to the payment result page.
      break;
    default:
      break;
  }
}

下图为商户页面嵌入 Antom Checkout Page 的渲染图:

Group 2117129530.png

步骤 3:异步通知处理服务端

1. 设置接收通知的 webhook URL

您可以选择以下两种方法中的一种来设置接受通知的 webhook URL:

  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 支付会话创建(收银台)接口请求的 paymentNotifyUrl 字段传入该笔订单的接收异步通知 URL。
  • 若您的所有订单都有一个统一的通知 URL,您则可以 Antom Dashboard开发者 > 通知地址 中设置 webhook URL。具体操作请参见通知地址

APM 支付

当支付成功或失败时,Antom 会向您在 支付会话创建(收银台)接口的 paymentNotifyUrl 参数中指定的地址发送异步通知(支付通知)。收到 Antom 的通知后,您需要按照返回收到确认信息返回响应。 

Antom 允许您在 支付会话创建(收银台)接口的 paymentNotifyUrl 参数中指定链接。如果每个支付的地址相同,也可以在 Antom Dashboard 中配置该地址。

以下代码展示了通知请求的示例: 

  • paymentRequestId:用于咨询、取消和对账的支付请求 ID。
  • paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
  • paymentAmount:表示支付金额。
  • paymentMethodType:表示买家使用的支付方式。
copy
{
  "actualPaymentAmount": {
    "currency": "KRW",
    "value": "100"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "KRW",
    "value": "100"
  },
  "paymentCreateTime": "2024-04-19T01:10:49-07:00",
  "paymentId": "20240419194010800100188350218317930",
  "paymentRequestId": "amsdmpay_yuqian_fyf_0b3bd5e9-14bd-4cea-b288-091d9c6862ed",
  "paymentResultInfo": {},
  "paymentTime": "2024-04-19T01:12:14-07:00",
  "pspCustomerInfo": {
    "pspCustomerId": "a070c0d1b89af442c6aa01886f0183de812a5d3d4fe15c771145b2b844a9dd67",
    "pspName": "TOSSPAY"
  },
  "paymentMethodType": "TOSSPAY",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

您可能会收到请求报文中 result.resultStatus 字段的不同值,请您根据下表指引进行处理:

result.resultStatus

信息

下一步操作

S

表示支付成功。

您可推进订单状态。

F

表示支付失败。请您引导买家重新下单。

常见问题

问:何时会发送通知?

答:不同场景异步通知的发送时间不同。

  • 如果支付成功,Antom 通常会在 3 到 5 秒内发送异步通知。对于某些支付方式,如柜台支付(OTC),通知可能会稍有延迟。
  • 如果买家未提交支付,在支付会话超时时, Antom 不会发送异步通知。
  • 如果买家提交了支付但最终支付未完成:
    • 最后一次提交支付的支付单关单时,若支付会话仍在有效期,Antom 会在支付会话过期时发送异步通知。
    • 最后一次提交支付的支付单关单时,若支付会话已过期,Antom 会在最后一次支付单关单时发送异步通知。

注意:支付会话默认有效期为 1 小时,不同支付方式关闭订单所需时间会有所不同,通常默认为 14 分钟。

问:异步通知会被重新发送吗?

答:是的,对于以下情况,异步通知会在 24 小时内自动重新发送:

  • 由于网络原因未收到异步通知。
  • 您收到来自 Antom 的异步通知后,没有按照处理通知的示例代码格式对通知做出响应。

通知至多重发 8 次或直至收到正确响应终止发送。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时,15 小时。

问:在通知中需要使用哪些关键参数?

答:通知中存在以下关键参数:

  • result:代表订单的支付结果。
  • paymentRequestId:商户生成的支付请求号,用于查询、撤销、对账。
  • paymentId:Antom 生成的支付单号,用于退款、对账。
  • paymentAmount:如有金额核对的需求,可以消费这个字段。
  • paymentMethodType:表示买家使用的支付方式。

问:有两个异步通知类型,应该用哪一个作为发货的依据?

答:当您收到 notifyType 为 PAYMENT_RESULT 类型的通知时,需要优先判断 paymentMethodType 是否为 CARD,若不为 CARD,则可根据该通知结果选择是否发货。如果为 CARD,需要等待 CAPTURE_RESULT 类型通知,再决策是否发货。

2. 异步通知验签

若您收到 Antom 的异步通知,需要您在返回中按照示例代码格式返回响应,但无需做加签处理。

您需要对 Antom 发送的支付通知进行验签。

copy
/**
 * receive notify
 *
 * @param request    request
 * @param notifyBody notify body
 * @return Result
 */
@PostMapping("/receiveNotify")
@ResponseBody
public Result receiveNotify(HttpServletRequest request, @RequestBody String notifyBody) {
    // retrieve the required parameters from http request
    String requestUri = request.getRequestURI();
    String requestMethod = request.getMethod();
    // retrieve the required parameters from request header
    String requestTime = request.getHeader("request-time");
    String clientId = request.getHeader("client-id");
    String signature = request.getHeader("signature");
    try {
        // verify the signature of notification
        boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
                                                          requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
        if (!verifyResult) {
            throw new RuntimeException("Invalid notify signature");
        }
        // deserialize the notification body
        JSONObject jsonObject = JSON.parseObject(notifyBody);
        String notifyType = (String)jsonObject.get("notifyType");
        if("PAYMENT_RESULT".equals(notifyType)){
            AlipayPayResultNotify paymentNotify = jsonObject.toJavaObject(AlipayPayResultNotify.class);
            if (paymentNotify != null && "SUCCESS".equals(paymentNotify.getResult().getResultCode())) {
                // handle your own business logic.
                // e.g. The relationship between payment information and users is kept in the database.
                System.out.println("receive payment notify: " + JSON.toJSONString(paymentNotify));
                return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
            }
        }else if("CAPTURE_RESULT".equals(notifyType)){
            AlipayCaptureResultNotify captureNotify = jsonObject.toJavaObject(AlipayCaptureResultNotify.class);
            if (captureNotify != null && "SUCCESS".equals(captureNotify.getResult().getResultCode())) {
                // handle your own business logic.
                System.out.println("receive capture notify: " + JSON.toJSONString(captureNotify));
                return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
            }
        }
    } catch (Exception e) {
        // handle error condition
        return Result.builder().resultCode("FAIL").resultMessage("fail.").resultStatus(ResultStatusType.F).build();
    }
    return Result.builder().resultCode("SYSTEM_ERROR").resultMessage("system error.").resultStatus(ResultStatusType.F).build();
}

您无需对响应通知结果做加签处理,但是对于每个通知请求均需按以下固定格式响应,与订单支付成功与否无关。

copy
{
    "result": {
        "resultCode": "SUCCESS",
        "resultStatus": "S",
        "resultMessage": "success"
    }
}

支付后操作

查询交易

除了可以通过异步通知的功能获取买家的支付结果,同时也支持您通过主动查询服务来获取对应的结果。您可以调用 支付结果查询 接口,可使用支付会话中的 paymentRequestId 查询支付状态。

以下代码展示了如何调用 支付结果查询 接口:

copy
public static void inquiryPayment() {
    AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();
    // replace with your paymentRequestId
    alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");
    AlipayPayQueryResponse alipayPayQueryResponse = null;
    try {
        alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // handle error condition
    }
}

以下代码展示了一个响应报文的示例:

copy
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "1"
    },
    "customsDeclarationAmount": {
        "currency": "CNY",
        "value": "7"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "1"
    },
    "paymentId": "20250305194010800100188690281017336",
    "paymentMethodType": "ALIPAY_CN",
    "paymentRedirectUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=%2BCUim8L0KviXagaygm9xBL5jZ%2F75w6gAX1nn8pcuFuGkIsMoHtD6U88YSyMrMJvorbwnBg5uQv8e6pyvIpjDQQ%3D%3D%26%26SG%26%26188%26%26eyJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImxvY2FsZVwiOlwiZW5fVVNcIixcImRpc3BsYXlBbnRvbUxvZ29cIjpcInRydWVcIn0iLCJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifSwic2VjdXJpdHlDb25maWciOnsiYXBwSWQiOiIiLCJhcHBOYW1lIjoiT25lQWNjb3VudCIsImJpelRva2VuIjoiNlRjZGJyMnJGM3JQWXg0aGtWckhxYnZqIiwiZ2F0ZXdheSI6Imh0dHBzOi8vaW1ncy1zZWEuYWxpcGF5LmNvbS9tZ3cuaHRtIiwiaDVnYXRld2F5IjoiaHR0cHM6Ly9vcGVuLXNlYS1nbG9iYWwuYWxpcGF5LmNvbS9hcGkvb3Blbi9yaXNrX2NsaWVudCIsIndvcmtTcGFjZUlkIjoiIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpmYWxzZX0%3D",
    "paymentRequestId": "PAYMENT_20250305220039086_AUTO",
    "paymentResultCode": "SUCCESS",
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2025-03-05T06:02:34-08:00",
    "pspCustomerInfo": {
        "pspName": "ALIPAY_CN"
    },
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

下表展示了响应报文中 paymentStatus 字段可能的值:

paymentStatus

信息

SUCCESS表示支付成功。
FAIL表示支付失败。

注意:在查询交易时,如果买家没有提交订单,就会一致报错 ORDER_NOT_EXIST,提交订单以后才不会报错。

退款

若您需要了解 Antom 的退款规则及如何对成功的交易发起退款,详情请参见退款

争议

若买家选择使用卡支付方式,会涉及到争议相关的集成,详情请参见争议。

对账

交易完成后,使用 Antom 提供的财务报告进行对账。有关如何对账和 Antom 结算规则的更多信息,请参阅对账

支付方式特性

卡支付

如果您的支付方式中包含卡支付,支付会话参数中必须传入商户端的买家信息。在 order.buyer 字段中,至少需要提供 referenceBuyerIdbuyerPhoneNobuyerEmail 三者中的一项。如果未传入买家信息,买家在选择卡支付方式并提交支付时,页面将出现错误,导致支付流程无法完成。

copy
{
    "order": {
        ...
        "buyer": {
            "referenceBuyerId": "88888888",
            "buyerEmail": "gaga@test.com",
            "buyerPhoneNo": "18888888888"
        }
    },
...
}

启用 3D Secure 2

若您想了解有关 3D Secure 2 的详细信息,请参阅 3D Secure 2 验证

  • 如果您已经具备风控能力,或已经接入了第三方风控服务:您可以根据自身的风险评估,通过 支付会话创建(收银台)接口指定字段 availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication 的值为 TRUE 
  • 如果您还没有风险控制能力:您可以联系 Antom 业务团队启用 Antom 盗卡风险服务。在服务中,Antom 的风控模型将帮助您决策交易是否需要 3DS 安全验证。在此场景下您不需要设置 availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication 的值。
copy
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "is3DSAuthentication": true
        }
    },  
  ...
}

当交易通过 3DS 认证后,会在异步通知中增加对应的 3DS 信息,见 paymentResultInfo.threeDSResult 字段。

copy
{
    "actualPaymentAmount": {
        "currency": "HKD",
        "value": "10"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "HKD",
        "value": "10"
    },
    "paymentCreateTime": "2025-03-01T02:58:03-08:00",
    "paymentId": "20250301194010800100188350280757901",
    "paymentMethodType": "CARD",
    "paymentRequestId": "PAYMENT_20250301185416669_AUTO",
    "paymentResultInfo": {
        "avsResultRaw": "I",
        "cardBrand": "VISA",
        "cardCategory": "CONSUMER",
        "cardNo": "************0197",
        "cardToken": "ALIPAYEfG2DFbGx2Eh739qU+VMnCPEe7MfRKfMfC5k7k/IFASWpAh/vCxHV3dPYpbkGz1iyWCloE4MwfmN48sP8+rSPQ==",
        "cvvResultRaw": "",
        "funding": "CREDIT",
        "issuingCountry": "HK",
        "networkTransactionId": "585060394953881",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "AJkBAyh5UQAAAAAKNEBgdQAAAAA=",
            "eci": "05",
            "threeDSVersion": "2.2.0"
        }
    },
    "paymentTime": "2025-03-01T02:58:19-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

APM 支付

Przelewy24

当买家选择 Przelewy24 支付时,可通过以下方式优化邮箱输入体验:

您可以在支付会话接口中传入availablePaymentMethod.paymentMethodMetaData.payerEmail 参数,  Antom Checkout Page 将自动在支付选项中预填充该邮箱,无需您手动输入。

示例代码:

copy
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "payerEmail": "123221321@test.com",
        }
    },  
  ...
}

买家在选择 Przelewy24 支付时,会预填充邮箱地址:

嵌入模式

Mercado pago

当买家选择 Mercado pago 支付时,可通过以下方式优化邮箱输入体验:

  • 您可以在支付会话接口中传入availablePaymentMethod.paymentMethodMetaData.payerEmail 参数,  Antom Checkout Page 将自动在支付选项中预填充该邮箱,无需您手动输入。
  • 您也可以在支付会话接口中传入availablePaymentMethod.paymentMethodMetaData.cpf 参数,  Antom Checkout Page 将自动在支付选项中预填充巴西税号,无需您手动输入。

示例代码:

copy
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "payerEmail": "123221321@test.com",
        }
    },  
  ...
}

买家在选择 Mercado Pago 支付时,会预填充邮箱地址:

嵌入模式

更多内容

指定支付方式

您可以通过修改 支付会话创建(收银台)的参数来指定 Antom Checkout Page 支付方式的显示,支付方式列表排序,以及极速支付方式的展示。

优势

  • 根据您的展业地区过滤当地的支付方式
  • 可以把您所偏好的支付方式进行排序
  • 可以把主流的支付方式如 Alipay、Apple Pay、Google Pay 以极速支付的形式展示

如何启用

您可以通过接口参数传入或 Antom Dashboard收银台页面 支付方式 中配置指定支付方式。如果您通过接口传入,则优先取接口传值。

接口参数传入

指定并过滤支付方式展示

copy
{ ...
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN",
        "expressCheckout": true,
        "paymentMethodOrder": "0"
      },
      {
        "paymentMethodType": "TNG",
        "expressCheckout": false,
        "paymentMethodOrder": "1"
      }
    ]
  }
}

支付方式排序

copy
{ ...
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN",
        "expressCheckout": true,
        "paymentMethodOrder": "0"
      },
      {
        "paymentMethodType": "TNG",
        "expressCheckout": false,
        "paymentMethodOrder": "1"
      }
    ]
  }
}

极速支付方式展示

copy
{ ...
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN",
        "expressCheckout": true,
        "paymentMethodOrder": "0"
      },
      {
        "paymentMethodType": "TRUEMONEY",
        "expressCheckout": false,
        "paymentMethodOrder": "1"
      }
    ]
  }
}

Antom Tokenization

您可以通过保存和传递买家卡的令牌信息完成存卡支付,买家体验如下:

image

优势

  • 让买家存储他们的付款方式,以便下次获得更快的结账体验
  • 存储支付方式信息后,显示详细的支付方式信息可以增加买家支付时的信任度
  • 数据显示,使用 cardToken 支付可以获得更高的支付成功率

如何启用

您可以通过以下步骤完成已存卡交易

  1. 显示绑卡按钮通过 支付会话创建(收银台)接口指定 availablePaymentMethod.paymentMethodMetaData.tokenizeMode 字段的值为  ASKFORCONSENT可以在 Antom Checkout Page 的卡支付选项中展示存卡按钮。
copy
{
...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "tokenizeMode": "ASKFORCONSENT"
        }
    }
}
  1. 首次支付后绑卡。当买家在您的页面保存银行卡信息时,请务必将其与买家信息关联,并在您的服务端保存相应的银行卡信息。( 从 支付通知 接口中的 paymentResultInfo 字段中获取 cardToken 的值)。
copy
{
    "actualPaymentAmount": {
        "currency": "HKD",
        "value": "10"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "HKD",
        "value": "10"
    },
    "paymentCreateTime": "2025-03-01T02:58:03-08:00",
    "paymentId": "20250301194010800100188350280757901",
    "paymentMethodType": "CARD",
    "paymentRequestId": "PAYMENT_20250301185416669_AUTO",
    "paymentResultInfo": {
        "avsResultRaw": "I",
        "cardBrand": "VISA",
        "cardCategory": "CONSUMER",
        "cardNo": "************0197",
        "cardToken": "ALIPAYEfG2DFbGx2Eh739qU+VMnCPEe7MfRKfMfC5k7k/IFASWpAh/vCxHV3dPYpbkGz1iyWCloE4MwfmN48sP8+rSPQ==",
        "cvvResultRaw": "",
        "funding": "CREDIT",
        "issuingCountry": "HK",
        "networkTransactionId": "585060394953881",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "AJkBAyh5UQAAAAAKNEBgdQAAAAA=",
            "eci": "05",
            "threeDSVersion": "2.2.0"
        }
    },
    "paymentTime": "2025-03-01T02:58:19-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
  1. 后续使用 cardToken 支付。当买家存在已保存的银行卡时,您需要通过 支付会话创建(收银台)接口传递卡的令牌信息,从而在 Antom收银台展示买家已存卡,买家可以使用已存卡完成支付。

以下示例展示了买家使用已存银行卡支付时, 支付会话创建(收银台) 接口使用银行卡令牌发起的请求示例:

copy
{
  ...
    "savedPaymentMethods": [
        {
            "paymentMethodType": "CARD",
            "paymentMethodId": "ALIPAYEfG2DFbGx2Eh739qU+VMnCPEe7MfRKfMfC5k7k/IFASWpAh/vCxHV3dPYpbkGz1iyWCloE4MwfmN48sP8+rSPQ=="
        }
    ]
}