全托管订阅支付

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

订阅支付体验

以下为集成 Checkout Page 首次订阅和后续扣款的用户体验:
首次订阅
后续扣款

支付流程

使用 Antom Checkout Page 全托管模式订阅支付的流程包括以下步骤:
卡支付、Google Pay 和 Apple Pay
APM 支付

订阅生命周期

以下图片分别展示了不同支付方式的订阅生命周期:
卡支付、Google Pay 和 Apple Pay
APM 支付

集成准备

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

集成步骤

开始集成,请按照以下步骤操作:
  1. 创建支付会话
  2. 跳转至 Antom Checkout Page 页面
  3. 授权/支付结果通知
  4. (可选)请款并获取请款通知
  5. 获取订阅通知

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

您可以调用 createPaymentSession(单笔支付)接口并传入订单信息,创建支付会话后跳转至 Antom Checkout Page。
创建支付会话请求包含以下关键参数:
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 createPaymentSession(单笔支付)
以下示例代码展示了如何调用 createPaymentSession(单笔支付)接口:
public static void createPaymentSession() {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.CHECKOUT_PAYMENT);

  // 设置订阅信息
  SubscriptionInfo subscriptionInfo = new SubscriptionInfo();
  subscriptionInfo.setSubscriptionDescription("TEST_SUBSCRIPTION");
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
  subscriptionInfo.setSubscriptionStartTime(ZonedDateTime.now().format(formatter));
  subscriptionInfo.setSubscriptionEndTime(ZonedDateTime.now().plusYears(1).format(formatter));
  subscriptionInfo.setSubscriptionNotifyUrl("https://your.example.com/subscriptionNotify");

  // 设置订阅周期规则
  PeriodRule periodRule = new PeriodRule();
  periodRule.setPeriodType("YEAR");
  periodRule.setPeriodCount(1);
  subscriptionInfo.setPeriodRule(periodRule);
  alipayPaymentSessionRequest.setSubscriptionInfo(subscriptionInfo);

  // 设置金额
  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();

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

  // 设置支付方式
  AvailablePaymentMethod availablePaymentMethod = new AvailablePaymentMethod();
  HashMap<String, Object> methodData = new HashMap<>();
  methodData.put("is3DSAuthentication", true);
  List<PaymentMethodTypeItem> paymentMethodTypeList = new ArrayList<>();
  PaymentMethodTypeItem paymentMethodTypeItem = new PaymentMethodTypeItem();
  paymentMethodTypeItem.setPaymentMethodType("CARD");
  availablePaymentMethod.setPaymentMethodTypeList(paymentMethodTypeList);
  availablePaymentMethod.setPaymentMethodMetaData(methodData);
  alipayPaymentSessionRequest.setAvailablePaymentMethod(availablePaymentMethod);

  // 设置环境
  Env env = Env.builder().terminalType(TerminalType.WEB).clientIp("1.2.3.4").build();
  alipayPaymentSessionRequest.setEnv(env);

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

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

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

  // 替换为您的 clientId
  alipayPaymentSessionRequest.setClientId(clientId);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;

  try {
      alipayPaymentSessionResponse = defaultAlipayClient.execute(alipayPaymentSessionRequest);
  } catch (AlipayApiException e) {
      String errorMsg = e.getMessage();
      // 处理错误情况
  }
}
以下为请求报文示例:
{
  "env": {
      "clientIp": "1.*.*.*",
      "terminalType": "WEB"
  },
  "order": {
      "buyer": {
          "referenceBuyerId": "yourBuyerId"
      },
      "orderAmount": {
          "currency": "SGD",
          "value": "6000"
      },
      "orderDescription": "antom ckp testing order",
      "referenceOrderId": "9aec4249-1934-4294-8c30-1993a157da5f"
  },
  "paymentAmount": {
      "currency": "SGD",
      "value": "6000"
  },

  "availablePaymentMethod": {
      "paymentMethodMetaData": {
          "is3DSAuthentication": true
      },
      "paymentMethodTypeList": []
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com/payment/receiveNotify",
  "paymentRedirectUrl": "http://www.yourRedirectUrl.com/payment/redirect",
  "paymentRequestId": "601e5c9e-78b3-455e-84bb-ee41f88c6c07",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "CHECKOUT_PAYMENT",
  "settlementStrategy": {
      "settlementCurrency": "USD"
  },
  "subscriptionInfo": {
      "periodRule": {
          "periodCount": 1,
          "periodType": "YEAR"
      },
      "subscriptionDescription": "TEST_SUBSCRIPTION",
      "subscriptionEndTime": "2027-03-12T10:38:54+08:00",
      "subscriptionNotifyUrl": "https://your.example.com/subscription/notify",
      "subscriptionStartTime": "2026-03-12T10:38:54+08:00"
  }
}
以下代码展示了一个响应的示例,其中包含以下关键参数:
  • paymentSessionData:将返回给前端的支付会话数据。
  • paymentSessionExpiryTime:支付会话的过期时间。
  • normalUrlCheckout Page 页面的跳转链接。
{
  "normalUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=cwnCzs7PcMfU03oKT1F%2BPHrpJmhr5k%2FF8nAcL4GP4PIin2bG4nFyF0NmqIOyf8Lt7Rh1%2BmgE27Csjx3Xhr8lkA%3D%3D%26%26SG%26%26188%26%26eyJlbGlnaWJsZUVhc3lQYXlNYXJrZXRpbmciOmZhbHNlLCJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImRpc3BsYXlBbnRvbUxvZ29cIjpcInRydWVcIn0iLCJuZWVkQWNjb3VudENvbmZpcm1QYWdlIjpmYWxzZSwicGF5bWVudFNlc3Npb25Db25maWciOnsicGF5bWVudE1ldGhvZENhdGVnb3J5VHlwZSI6IkFMTCIsInByb2R1Y3RTY2VuZSI6IkNIRUNLT1VUX1BBWU1FTlQiLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn0sInNlY3VyaXR5Q29uZmlnIjp7ImFwcElkIjoiIiwiYXBwTmFtZSI6Ik9uZUFjY291bnQiLCJiaXpUb2tlbiI6IjZUY2RicjJyRjNyUFl4NGhrVnJIcWJ2aiIsImdhdGV3YXkiOiJodHRwczovL2ltZ3Mtc2VhLmFsaXBheS5jb20vbWd3Lmh0bSIsImg1Z2F0ZXdheSI6Imh0dHBzOi8vb3Blbi1zZWEtZ2xvYmFsLmFsaXBheS5jb20vYXBpL29wZW4vcmlza19jbGllbnQiLCJ3b3JrU3BhY2VJZCI6IiJ9LCJza2lwUmVuZGVy******udE1ldGhvZCI6ZmFsc2V9&shadow=true",
  "paymentSessionData": "4dChA3EBSSxaN9XOjRZ0zN3C8l8xUEAXQJRPDA5O+7TYW/kJ9tR76f**********vPiEEUII0uZciWVbjNIpxElA==&&SG&&188&&eyJlbGlnaWJsZUVhc3lQYXlNYXJrZXRpbmciOmZhbHNlLCJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImRpc3BsYXlMYXlvdXRcIjpcIkxFRlRfT1JERVJfQU5EX1JJR0hUX1BBWU1FTlRcIixcInRoZW1lVHlwZVwiOlwiQ1VTVE9NSVpFXCIsXCJkaXNwbGF5QW50b21Mb2dvXCI6XCJmYWxzZVwifSIsIm5lZWRBY2NvdW50Q29uZmlybVBhZ2UiOmZhbHNlLCJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifSwic2VjdXJpdHlDb25maWciOnsiYXBwSWQiOiIiLCJhcHBOYW1lIjoiT25lQWNjb3VudCIsImJpelRva2VuIjoiNlRjZGJyMnJGM3JQWXg0aGtWckhxYnZqIiwiZ2F0ZXdheSI6Imh0dHBzOi8vaW1ncy1zZWEuYWxpcGF5LmNvbS9tZ3cuaHRtIiwiaDVnYXRld2F5IjoiaHR0cHM6Ly9vcGVuLXNlYS1nbG9iYWwuYWxpcGF5LmNvbS9hcGkvb3Blbi9yaXNrX2NsaWVudCIsIndvcmtTcGFjZUlkIjoiIn0sInN********ZXJQYXltZW50TWV0aG9kIjpmYWxzZX0=",
  "paymentSessionExpiryTime": "2026-03-12T11:38:59+08:00",
  "paymentSessionId": "4dChA3EBSSxaN9XOjRZ0zN3C8l8x*********DA5O+7S4zYs/gYmYI0w5X1FgRTmT",
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
下表展示了响应代码中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
注意:如果您未收到响应报文,可能是网络超时所致,请更换 paymentRequestId 重新调用接口以解决问题。

步骤 2:跳转至 Antom Checkout Page 页面(normalUrl)
客户端

商户服务端拿到 Antom 返回的 Checkout Page 页面地址(normalUrl )后,将该地址传递给前端,由商户前端跳转至 Antom Checkout Page 页面。
以下为商户前端加载 normalUrl 的示例代码:
Web
WAP
下图展示了跳转的 Antom Checkout Page 页面效果:
image.png

3D 验证页面

首笔交易是买家参与的交易,需要进行身份验证,用于保障后续买家不在场的周期性扣费的安全。因此对于首笔交易的身份验证要求见下表:
常见问题

问:paymentRedirectUrl 在传参上有些什么注意点?
答:默认设置为 HTTPS 地址,同时 URL 中的特殊字符能进行编码处理,否则会支付异常。

问:支付结果页内容如何展示?
答:您需要通过在 createPaymentSession(单笔支付)接口中指定 paymentRedirectUrl 字段来提供一个 HTTPS 地址。该地址用于在商户端显示支付结果。在支付成功和支付失败的情况下,可能都有入口可以从支付方式端回跳到商户页面。因此,请勿将 paymentRedirectUrl 固定写成“订阅创建成功页面”,而是以服务端返回的结果为准,避免引起买家误解。

问:回跳商户结果页是否代表订阅创建成功?
答:不能仅凭回跳商户页面来判断订阅创建是否成功,具体有以下三种情况:
  • 买家支付成功后,可能因网络等原因导致未能回跳至商户页。
  • 即使买家未完成支付,也可能通过支付方式端的入口回跳至商户页面。
  • 即使买家完成支付,也可能因为请款失败而导致订阅关系没有生效。

步骤 3:授权或支付结果通知
服务端

在支付处理流程中,Antom 会根据不同的支付方式类型向您发送相应的结果通知。
  • 对于卡支付、Google PayApple Pay 支付场景,Antom 发送的是授权结果通知,告知您授权是否成功。只有授权支付成功后才会触发请款,请依据请款结果作为发货依据。
  • 对于 APM 支付场景,当支付成功或失败时 Antom 会发送的是支付结果通知。
卡、Google Pay 和 Apple Pay
APM 支付

(可选)步骤 4:请款并获取请款通知
服务端

注意
  • 卡支付场景下必须请款,只有授权支付成功才会触发请款。
  • 部分 APM 支付方式需要请款,如 Apple PayGoogle PayPay by Bank,同时也只有授权支付成功才会触发请款
授权支付成功后,Antom 默认自动为您请款,也支持您手动发起请款。同时,Antom 会使用 notifyCapture(单笔支付)将请款结果通知发送给您,您也可以通过主动查询来获取请款结果。您需要根据请款结果来决定是否发货,具体操作请参阅请款

步骤 5:获取订阅通知
服务端

订阅关系生效后,Antom 会为您发送以下通知:

首期订阅通知

Antom 将通过 HTTPS 向您在接口或 Antom Dashboard 中配置的 Webhook 推送以下事件通知:
订阅状态通知
当期扣款结果通知
常见问题

问:Antom 会重新发送异步通知吗?
会。对于以下情况,异步通知将在 24 小时内自动重新发送:
  • 由于网络原因未收到异步通知。
  • 如果收到来自 Antom 的异步通知,但您没有按照返回收到确认信息的格式进行响应。
通知可以重发最多 8 次,或者直到收到正确的响应以终止传递。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和 15 小时。

问:收到支付结果通知是否需要验签?
答:需要。通过验签 Antom 会发送保障回调请求给您,验签时请注意拼装待验签报文时需按标准处理:
<http-method> <http-uri> <client-id>.<request-time>.<request-body>
,特别是针对
<request-body>
需直接取值而非解析 JSON 后拼装。

问:若首次支付失败,订阅关系会生效吗?
答:当订阅开通的首次扣款失败时,订阅关系将不会生效,Antom 系统会通过 Webhook 推送 subscriptionStatus
TERMINATED
的状态通知给您,表明订阅开通失败。

问:订阅超时时间是多久?
答:
  • 针对 APM 类支付方式,默认为 80 分钟超时时间;
  • 针对卡支付/Apple Pay/Google Pay,默认为 7 天超时时间。
您还可以通过 subscriptionExpiryTime 字段来指定过期时间。

订阅续期通知

当订阅创建成功并建立有效关系后,Antom 系统将会根据您配置的订阅规则,自动发起续订扣款,并通过 Webhook 推送相应的支付结果通知,实现周期性扣费。触发续订扣款的时间和规则如下:
  • 触发时间:续订扣款将在下一个订阅周期起始日的前 24 小时自动触发。您可以依据上一周期支付结果通知中的 periodEndTime 字段,向前推 24 小时以判断下一周期扣款的发起时间。
  • 周期规则:续费周期及扣款频率将按照订阅时设定的 periodRule 执行,例如按日、按月、按季度或按年扣款。
卡支付、Google Pay 和 Apple Pay
APM 支付
常见问题

问:若扣款失败会导致订阅关系失效吗?
答:创建订阅的首期扣款如果失败,订阅关系将不会生效;若订阅关系已生效但后续的周期扣款失败(如余额不足),订阅状态仍保持有效;若未主动取消订阅,Antom 将会在下一期继续周期扣款。

问:扣款失败会发送当期扣款通知吗,会重试吗?
答:扣款失败会发送扣款失败通知。卡支付、Google PayApple Pay 的订阅支付场景下,Antom 不会发起重试;APM 的订阅支付场景下,Antom 会发起多次重试。商户侧如需自行发起重试,可联系技术支持确定方案。

问:假如首期扣款是 2 月 28 日、3 月 31 日或 4 月 30 日这些月末时间点,那下一期的扣费时间怎么定义?
答:订阅的周期逻辑为按选定的日期来发起下一次扣款,如果下一个周期没有这个日期,则往前推到最后一天,例如:
  • 首期 1.28,二期 2.28,三期 3.28,四期 4.28。
  • 首期 1.31,二期 2.28,三期 3.31,四期 4.30。
  • 首期 1.30,二期 2.28,三期 3.30,四期 4.30。

问:后续的周期扣款如何跟首期合约关联?
答:针对周期扣款通知,可以根据通知请求中的 subscriptionRequestId subscriptionId 与首期合约关联。针对卡支付、Google PayApple Pay 的周期扣款,Antom 还会额外发送授权结果通知和请款结果通知,这两个通知可以根据 paymentId 关联到周期扣款通知中的 paymentId 并最终关联上首期合约的 subscriptionId

订阅后操作

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

查询订阅相关信息
服务端

订阅确认后,您可以查询以下订阅信息:

查询交易
服务端

除了可以通过异步通知的功能获取买家的支付结果,同时也支持您通过主动查询服务来获取对应的结果。您可以调用 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();
      // 处理错误情况
  }
}
以下代码展示了一个响应报文的示例:
{
  "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=your_SESSION_DATA",
  "paymentRequestId": "PAYMENT_202503****0039086_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 字段可能的值:
注意:在查询交易时,如果买家没有提交订单,就会一致报错
ORDER_NOT_EXIST
,提交订单以后才不会报错。

订阅试用
服务端

Antom 提供订阅试用功能,帮助买家在正式购买订阅计划前,以免费或优惠价格在限定时间内体验产品或服务。详情请参阅订阅试用文档。

终止订阅
服务端

终止订阅功能允许买家在不需要继续使用相关服务时,随时取消当前订阅。详情请参阅终止订阅文档。

取消交易
服务端

对于支付成功后的订单,如买家在当天内申请取消订单或退款,您可以通过 Antom 提供的取消交易能力将订单状态取消或解冻。此外,对于尚未完成支付的订单,您也可以直接进行取消,具体的集成方案见取消交易文档。

退款
服务端

对于已支付成功的订单,如您需向买家发起退款,Antom 提供以下两种方式。
  • 由您的运营人员直接在 Antom Dashboard 平台上进行人工退款。
  • 通过接入 refund 接口发起退款。
Antom 的退款能力如下:
  • 支持全额退款。
  • 支持部分多次退款,多次退款的总金额需小于等于请款金额。
具体的集成方案见退款文档。

争议
服务端

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

对账
服务端

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

更多内容

指定支付方式

您可以在 Antom Dashboard 支付 > 收银台设置 >支付方式 中配置指定支付方式。您也可以通过在 createPaymentSession(单笔支付)接口传入参数,指定在 Checkout Page 上展示的支付方式、支付方式列表的排序,以及极速支付方式的展示,具体步骤请参阅指定支付方式
注意:如果您通过接口传入参数来指定支付方式,则优先取接口传值。
此功能为您带来以下优势:
  • 根据您的业务地区过滤当地的支付方式
  • 按照您的偏好对支付方式进行排序
  • 可以将主流的支付方式如 AlipayApple PayGoogle Pay 以极速支付的形式展示