Antom, leading provider of tailored payment solutions

嵌入模式

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

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

用户体验

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

Web1.png

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

Web2.png

注意:

  • 目前 APO Checkout Page 的嵌入模式仅支持 PC、H5 端,不支持 APP 端。
  • APO Checkout Page 的嵌入模式不支持 Apple Pay,请接入全托管模式。

支付流程

使用 APO Checkout Page 嵌入模式支付的流程包括以下步骤:

嵌入模式中文.png

  1. 买家在商户侧下单。
  2. 创建支付会话请求。
    当
    买家在商户侧下单,您需要调用 createPaymentSession 接口获取调用 SDK 的 paymentSessionData。
  3. 调用客户端SDK。
    商
    户客户端通过 paymentSessionData  调用 SDK 内嵌 Checkout Page 组件在商户网页中,之后买家在 Checkout Page 组件中提交支付,SDK 会处理支付流程。
  4. 获取支付结果。
    通过异步通知获取支付结果。 在 createPaymentSession 接口中设置 paymentNotifyUrl  参数,以指定接收异步通知的地址。当支付请求成功或过期时,APO 会通过 notifyPayment 接口向您发送异步通知。

注意:

  • 当支付方式是卡、Google Pay、PayPal 时,APO 还会额外通过 notifyCapture 接口发送请款结果给您。您需要依赖请款成功作为发货依据。
  • 若在多机构下开通了同一个支付方式,请在 APO Dashboard 完成路由配置。若不配置,则 APO 会采取随机路由规则。

集成准备

在您开始集成前,请阅读集成指南及接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:

  • 已获得 client ID 和 agent token(适用于 ISV 模型)。
  • 已完成密钥配置。
  • 已完成异步通知接收地址的配置。
  • 集成服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
  • 参阅 Web/WAP 端集成 SDK 资源包文档来集成客户端 SDK 资源包,并注意使用最新或不低于 1.41.0 版本的 SDK

集成步骤

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

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

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

您在开通 APO 服务时可以指定支付方式。若需配置支付方式,请参见指定支付方式。当买家进行支付时,您需要收集关键信息,如支付请求 ID、订单信息、支付重定向链接和支付结果通知链接。您可以调用 createPaymentSession 接口并传入订单信息,创建支付会话后获取唤起 APO Checkout Page 的 paymentSessionData。

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

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

类型

字段

是否必需

描述

基础字段

productCode

是

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

productScene

是

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

paymentRequestId

是

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

是

商户请求以订单币种收取的支付金额。需按下单币种的最小单位设置,如 CNY 为分,KRW 为元。

paymentRedirectUrl

是

商户端支付结果页。需根据服务端结果展示,非固定为成果页,必须为 HTTPS 地址。
paymentNotifyUrl

否

支付结果通知地址,可通过接口指定或在 APO Dashboard 上设置固定值。如果通过 APO Dashboard 设置,则该字段不可传。必须为 HTTPS 地址。
settlementStrategy

否

该参数只对 Antom 收单机构生效,用于该笔支付的结算策略。如果您签署了多个结算币种,需在接口中指定 settlementCurrency。

locale

否

商户指定的 APO Checkout Page 展示语言。若传入语言不支持则默认展示英文。

订单字段

order.orderAmount

是

商户端订单金额。

order.referenceOrderId

是

商户端订单号。

order.orderDescription

是

商户端订单描述。
order.goods

否

详细商品信息。

注意:

  • 当支付方式是 PayPal 时,此参数必传。
  • 所有商品的金额总和需要等于 paymentAmount/orderAmount。
  • 如果是虚拟商品,请指定参数 order.goods.deliveryMethodType 的值为 DIGITAL。
order.shipping

否

配送信息。

注意:当支付方式是 PayPal 且此交易是实物销售时,此参数必传。

以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession 接口。

以下示例代码展示了如何调用 createPaymentSession 接口:

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

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

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

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

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

    // 设置商品信息
    Goods goods = Goods.builder().goodsBrand("Antom Brand").goodsCategory("outdoor goods/bag").goodsName("Classic Woman Bag").goodsQuantity("1")
    .goodsSkuName("Black").goodsImageUrl("https://mdn.alipayobjects.com/portal_pdqp4x/afts/file/A*H8M9RrxlArAAAAAAAAAAAAAAAQAAAQ")
    .goodsUnitAmount(amount).goodsUrl("https://yourGoodsUrl").referenceGoodsId("yourGoodsId").build();

    // 设置订单信息
    Order order = Order.builder().referenceOrderId(orderId)
    .orderDescription("antom ckp testing order").orderAmount(amount).buyer(buyer).goods(Stream.of(goods).collect(Collectors.toList())).build();
    alipayPaymentSessionRequest.setOrder(order);

    // 替换为您的通知地址
    // 或者在这里配置您的通知地址: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
    alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receiveNotify");
    // 替换为您的跳转地址
    alipayPaymentSessionRequest.setPaymentRedirectUrl(
        "http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);

    AlipayPaymentSessionResponse alipayPaymentSessionResponse;
    try {
        System.out.println("paymentSession request: " + JSON.toJSONString(alipayPaymentSessionRequest));
        alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
        System.out.println("paymentSession response: " + JSON.toJSONString(alipayPaymentSessionResponse));
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // 处理错误情况
    }
}

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

{
  "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-06c3615b****"
  },
  "paymentAmount": {
    "currency": "SGD",
    "value": "6000"
  },
  "paymentFactor":{
    "isAuthorization":true
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com/payment/receiveNotify",
  "paymentRedirectUrl": "http://localhost:8080/index.html?paymentRequestId=597795b7-c812-4132-bd7d-c55914eefdcb",
  "paymentRequestId": "597795b7-c812-4132-bd7d-c55914ee****",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "CHECKOUT_PAYMENT"
}

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

  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
  • normalUrl: Checkout Page 的跳转链接。(在嵌入式场景下,可以忽略该字段。)
{
    "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 表示支付会话创建成功。

商户客户端通过 paymentSessionData 调用 SDK。

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

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

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

SDK 是用于处理支付流程的组件,为了收集信息以及根据 createPaymentSession 接口中指定的支付方式在应用间切换,您需要通过创建支付会话获取的 paymentSessionData 来启动 SDK,将 APO Checkout Page 无缝嵌入其网页支付界面。买家在该页面提交支付请求后,SDK 将自动完成交易流程的加密通信、风险校验及支付指令处理,实现端到端的支付闭环管理。

1. 初始化 SDK 

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

参数名称

是否必需

描述

environment

是

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

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

onEventCallback

否

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

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

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}) => {},
});

2. 调用 SDK 

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

创建 DOM 节点

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

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

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

参数名称

是否必需

描述

sessionData

是

使用 sessionData 参数创建配置对象:将通过 createPaymentSession 接口在响应中获取的完整 paymentSessionData 参数传递给 sessionData 参数。

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

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

  • 当买家切换视图离开结账页面时,释放 createPaymentSession 中创建的组件资源。
  • 当买家发起多次支付时,释放之前 createPaymentSession 中创建的组件资源。
  • 在获取最终支付结果后释放组件资源。
// Free SDK component resources
checkoutApp.unmount();

3. 支付结果处理

支付结果将通过 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:

function onEventCallback({ code, result }) {
  switch (code) {
    case 'SDK_PAYMENT_SUCCESSFUL':
      // 支付成功。买家跳转到支付结果页面。
      break;
    case 'SDK_PAYMENT_FAIL':
      console.log('Check the payment result data', result);
      // 支付失败。引导买家根据提供的支付信息重试。
      break;
    case 'SDK_PAYMENT_CANCEL':
      // 引导买家重新支付。
      break;
    case 'SDK_PAYMENT_CLICK_BACK_TO_MERCHANT':
      // 买家点击“返回商家”按钮。买家跳转到支付结果页面。
      break;
    default:
      break;
  }
}

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

CKP.png

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

1. 设置接收通知的 webhook URL

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

  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 createPaymentSession 接口请求的 paymentNotifyUrl 字段传入该笔订单的接收异步通知 URL。
  • 若您的所有订单都有一个统一的通知 URL,您则可以在 APO Dashboard > 开发者 > 通知地址 中设置 webhook URL。

当支付成功或失败时,APO 会向您在 createPaymentSession 接口的 paymentNotifyUrl 参数中指定的地址发送异步通知(notifyPayment)。收到 APO 的通知后,您需要按照返回收到确认信息返回响应。同时建议保存收单机构相关信息( acquirerInfo 参数),具体原因请查看单号说明。

APO 允许您在 createPaymentSession 接口的 paymentNotifyUrl 参数中指定链接。如果每个支付的地址相同,也可以在 APO Dashboard 中配置该地址。

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

{
    "acquirerInfo": {
        "acquirerMerchantId": "21********99147",
        "acquirerName": "ALIPAY",
        "acquirerResultCode": "SUCCESS",
        "acquirerResultMessage": "success",
        "acquirerTransactionId": "2025061819********0188540299977984",
        "referenceRequestId": "PAYMENT_20250618100222331_AUTO"
    },
    "customsDeclarationAmount": {
        "currency": "CNY",
        "value": "10"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "CNY",
        "value": "10"
    },
    "paymentCreateTime": "2025-06-17T19:02:31-07:00",
    "paymentId": "2025061819********0188540299977984",
    "paymentMethodType": "ALIPAY_CN",
    "paymentRequestId": "PAYMENT_20250618100222331_AUTO",
    "paymentResultInfo": {

    },
    "paymentTime": "2025-06-17T19:02:50-07:00",
    "pspCustomerInfo": {
        "pspCustomerId": "20*******9879519",
        "pspName": "ALIPAY_CN"
    },
    "pspPaymentId": "2025061*********11432765638",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

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

result.resultStatus

信息

下一步操作

S

表示支付成功。

您可推进订单状态,并使用以下字段信息进行支付的后续操作。

  • paymentRequestId :用于咨询、取消和对账的支付请求 ID。
  • paymentId :表示由 APO 生成的支付订单 ID,用于退款和对账。
  • paymentAmount :表示支付金额。
  • paymentMethodType :表示买家使用的支付方式。

F

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

常见问题

问:何时会发送通知?

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

  • 如果支付成功,APO 通常会在 3 到 5 秒内发送异步通知。对于某些支付方式,如柜台支付(OTC),通知可能会稍有延迟。
  • 如果买家未提交支付,在支付会话超时时, APO 不会发送异步通知。

注意:支付会话默认有效期为 1 小时,不同机构的不同支付方式关闭订单所需时间会有所不同,通常 Antom 下的支付方式默认为 14 分钟,但例如 PayEasy、Kobini 是 7 天。

问:买家提交支付后多久能收到关单通知?

答:如果买家在支付会话有效期内选择某种支付方式提交支付,最长时延即为最终的支付方式超时时间加上支付会话有效期,例如支付会话有效期为一小时,买家在 59 分钟时选择银行转账支付且未最终支付,那您则会在 59 分钟 + 48 小时后(各支付方式超时不一致时间)收到关单的异步通知。

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

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

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

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

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

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

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

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

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

2. 异步通知验签

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

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

/**
 * receive notify
 *
 * @param request    request
 * @param notifyBody notify body
 * @return Result
 */
@PostMapping("/receiveNotify")
@ResponseBody
public Result receiveNotify(HttpServletRequest request, @RequestBody String notifyBody) {
    // 从 http 请求中获取所需参数  
    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 {
        // 通知验签
        boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
                                                          requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
        if (!verifyResult) {
            throw new RuntimeException("Invalid notify signature");
        }
        // 反序列化通知主体
        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())) {
                // 处理您自己的业务逻辑
                // 例如:支付信息与买家之间的关系保存在数据库中。  
                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())) {
                // 处理您自己的业务逻辑
                System.out.println("receive capture notify: " + JSON.toJSONString(captureNotify));
                return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
            }
        }
    } catch (Exception e) {
        // 处理错误情况
        return Result.builder().resultCode("FAIL").resultMessage("fail.").resultStatus(ResultStatusType.F).build();
    }
    return Result.builder().resultCode("SYSTEM_ERROR").resultMessage("system error.").resultStatus(ResultStatusType.F).build();
}

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

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

支付后操作

查询交易

除了可以通过异步通知的功能获取买家的支付结果,同时也支持您通过主动查询服务来获取对应的结果。您可以调用 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();
        // 处理错误情况
    }
}

建议保存收单机构相关信息( acquirerInfo 参数),具体原因请查看单号说明。以下代码展示了一个响应报文的示例:

{
    "acquirerInfo": {
        "acquirerMerchantId": "76476400001****",
        "acquirerName": "2C2P",
        "acquirerTransactionId": "823c1fe4-1168-4abc-9687-c42f3269****",
        "referenceRequestId": "202504301903130001032028917****"
    },
    "acquirerReferenceNo": "202504301903130001032028917****",
    "paymentAmount": {
        "currency": "USD",
        "value": "110"
    },
    "paymentCreateTime": "2025-04-30T00:16:12-07:00",
    "paymentId": "2025043019401089010011132026330****",
    "paymentMethodType": "MIXEDCARD",
    "paymentRequestId": "PAYMENT_20250430151543077_****",
    "paymentResultCode": "SUCCESS",
    "paymentResultInfo": {
        "avsResultRaw": "",
        "cardBin": "53**32",
        "cardBrand": "MASTERCARD",
        "cardNo": "************1310",
        "cardholderName": "*******",
        "cvvResultRaw": "",
        "expiryMonth": "**",
        "expiryYear": "**",
        "fingerprint": "2684e4fa13af655191************0aff65851486d4f575183f46",
        "funding": "CREDIT",
        "issuerName": "CHINA MERCHANTS BANK",
        "issuingCountry": "CN",
        "lastFour": "1310",
        "threeDSResult": {
            "cavv": "",
            "eci": "00",
            "threeDSType": "INTERNAL",
            "xid": ""
        }
    },
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2025-04-30T00:16:14-07:00",
    "transactions": [
        {
            "acquirerInfo": {
                "acquirerMerchantId": "76476400001****",
                "acquirerName": "2C2P",
                "referenceRequestId": "202504301903130101032028917****"
            },
            "transactionAmount": {
                "currency": "USD",
                "value": "110"
            },
            "transactionId": "2025043019401089010011132026318****",
            "transactionRequestId": "PAYMENT_20250430151543077_****",
            "transactionResult": {
                "resultCode": "SUCCESS",
                "resultMessage": "success",
                "resultStatus": "S"
            },
            "transactionStatus": "SUCCESS",
            "transactionTime": "2025-04-30T00:16:15-07:00",
            "transactionType": "CAPTURE"
        }
    ],
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

响应报文中 paymentMethodType 和 transactions.transactionType 字段的值将表示不同的状态。以下列出具体场景下返回值的说明:

当 paymentMethodType 不为 CARD、APPLEPAY 或 GOOGLEPAY 时,您需根据响应报文里 paymentStatus(支付状态)进行处理。返回的值包括:

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

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

退款 服务端

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

争议 服务端

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

对账

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

支付方式特性

卡支付

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

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

启用 3D Secure2

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

  • 您可以根据自身的风险评估,通过 createPaymentSession 接口指定参数 availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication 的值为 TRUE,此时 APO 会设置该笔交易为 3D 验证传递给下游收单机构。
  • 若您不设置该参数或设置参数 availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication 的值为 FALSE,APO 会设置该笔交易为非 3D 验证传递给下游收单机构,但是最后会以收单机构的处理为准。
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "is3DSAuthentication": true
        }
    },  
  ...
}

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

{
    "acquirerInfo": {
        "acquirerMerchantId": "219117000551****",
        "acquirerName": "ALIPAY",
        "acquirerResultCode": "SUCCESS",
        "acquirerResultMessage": "success",
        "acquirerTransactionId": "2025043019401080010019178029053****",
        "referenceRequestId": "PAYMENT_20250430155835598_****"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "GBP",
        "value": "100"
    },
    "paymentCreateTime": "2025-04-30T00:59:08-07:00",
    "paymentId": "2025043019401080010019178029053****",
    "paymentMethodType": "CARD",
    "paymentRequestId": "PAYMENT_20250430155835598_****",
    "paymentResultInfo": {
        "avsResultRaw": "U",
        "cardBin": "53**32",
        "cardBrand": "MASTERCARD",
        "cardCategory": "CONSUMER",
        "cardNo": "************1310",
        "cardholderName": "*******",
        "cvvResultRaw": "U",
        "expiryMonth": "**",
        "expiryYear": "**",
        "funding": "CREDIT",
        "issuingCountry": "CN",
        "lastFour": "1310",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "kAPDv**********+btfgoJhBG+N",
            "eci": "02",
            "threeDSOffered": true,
            "threeDSVersion": "2.2.0"
        }
    },
    "paymentTime": "2025-04-30T00:59:28-07:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

APM 支付

Antom Przelewy24

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

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

示例代码:

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

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

przelewy 1.png

Mercado pago

当买家选择 Mercado pago 支付时,将涉及的字段如下:

收单机构

支付方式

收集支付要素

支付要素参数名

最佳实践

Antom

Mercado Pago(巴西)

巴西个人税号

paymentMethodMetaData.cpf

引导买家在商户页面输入巴西个人税号,并手动打开 Mercado Pago 应用完成支付。

Antom

Mercado Pago

(巴西、墨西哥、智利和秘鲁)

买家的电子邮件 

paymentMethodMetaData.payerEmail 

引导买家在商户页面输入电子邮件,并手动打开 Mercado Pago 应用来完成支付。 

您可以通过以下方式优化邮箱或巴西个人税号输入体验:

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

示例代码:

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

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

mercado 1.png

更多内容

指定支付方式

您可以在 APO Dashboard 的 收银台设置 > 支付方式 中配置指定支付方式。您也可以通过在 createPaymentSession 接口传入参数,指定在 Checkout Page 上展示的支付方式、支付方式列表的排序,以及极速支付方式的展示。

注意:如需通过后台配置支付方式,请联系 APO 技术支持。

此功能为您带来以下优势:

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

要指定支付方式,请在 createPaymentSession 接口的 availablePaymentMethod 参数中,传入以下参数:

参数名称是否必需描述
paymentMethodTypeList否

买家可用的支付方式列表。其包含以下参数:

  • paymentMethodType:支付方式选项中包含的支付方式类型。参见支付方式枚举值以查看有效值。
  • paymentMethodOrder:您设置的支付方式优先级顺序,以序号表示,序号越小,优先级越高。如果未进行设置,将使用 Antom 默认的排序方式。
  • expressCheckout:设置是否使用支付方式的极速支付形式,目前仅 ALIPAY_CN、APPLEPAY 和 GOOGLEPAY 可以被设置为极速支付。有效值为:
    • true:表示设置该支付方式为极速支付。
    • false:表示不将该支付方式设置为极速支付。

APO Tokenization

如果买家选择卡支付,Checkout Page 可以允许买家通过 APO Tokenization 的能力在首次支付时保存卡信息,在后续的支付中则无需重新输入信息,Checkout Page 即可展示买家的脱敏卡号进行支付。

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

image

优势

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

如何启用

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

  1. 显示绑卡按钮。通过 createPaymentSession 接口指定 availablePaymentMethod.paymentMethodMetaData.tokenizeMode 字段的值为  ASKFORCONSENT,就可以在 APO Checkout Page 的卡支付选项中展示存卡按钮。
{
...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "tokenizeMode": "ASKFORCONSENT"
        }
    }
}
  1. 首次支付后绑卡。当买家在您的页面保存银行卡信息时,请务必将其与买家信息关联,并在您的服务端保存相应的银行卡信息。( 从 notifyPayment 接口中的 paymentResultInfo 字段中获取 cardToken 的值)。
{
    "acquirerInfo": {
        "acquirerMerchantId": "219117000551****",
        "acquirerName": "ALIPAY",
        "acquirerResultCode": "SUCCESS",
        "acquirerResultMessage": "success",
        "acquirerTransactionId": "2025043019401080010019178029053****",
        "referenceRequestId": "PAYMENT_20250430155835598_****"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "GBP",
        "value": "100"
    },
    "paymentCreateTime": "2025-04-30T00:59:08-07:00",
    "paymentId": "2025043019401080010019178029053****",
    "paymentMethodType": "CARD",
    "paymentRequestId": "PAYMENT_20250430155835598_****",
    "paymentResultInfo": {
        "avsResultRaw": "U",
        "cardBin": "53**32",
        "cardBrand": "MASTERCARD",
        "cardCategory": "CONSUMER",
        "cardNo": "************1310",
        "cardToken": "ALIPAY5ITT+wDZhYuE1f********************vJ5BksK4yWCloE4MwfmN48sP1+rSPQ==",
        "cardholderName": "*******",
        "cvvResultRaw": "U",
        "expiryMonth": "**",
        "expiryYear": "**",
        "funding": "CREDIT",
        "issuingCountry": "CN",
        "lastFour": "1310",
        "networkTransactionId": "MCGQ120DH****",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "kAPDv**********+btfgoJhBG+N",
            "eci": "02",
            "threeDSOffered": true,
            "threeDSVersion": "2.2.0"
        }
    },
    "paymentTime": "2025-04-30T00:59:28-07:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
  1. 后续使用 cardToken 支付。当买家存在已保存的银行卡时,您需要通过 createPaymentSession 接口传递卡的令牌信息,从而在 APO 收银台展示买家已存卡,买家可以使用已存卡完成支付。

以下示例展示了买家使用已存银行卡支付时, createPaymentSession 接口使用银行卡令牌发起的请求示例:

{
  ...
    "savedPaymentMethods": [
        {
            "paymentMethodType": "CARD",
            "paymentMethodId": "ALIPAYEfG2DFbGx2Eh739qU+VMnCPEe7MfRKfMfC5k7k/IFASWpAh/vCxHV3dPYpbkGz1iyWCloE4MwfmN48sP8+rS****"
        }
    ]
}