令牌支付
本文介绍了如何通过桌面网页浏览器实现自动扣款功能的集成方案。集成后,您的网站即可上线自动扣款服务。买家首次授权后,后续支付无需重复输入密码,将直接从网站完成扣款操作,适合需要快速扣款的商业场景。
用户体验
以下图片展示了买家进行授权与支付的体验流程:
授权
买家跳转到 Antom 页面,通过输入账号和密码完成授权。目前仅支持从商户 web 端发起授权。
支付流程
支付流程由以下集成步骤组成:

- 买家进入结账页面。
- 获取签约授权链接。
- 买家选择支付方式并提交订单后,商户端调用 consult 接口以获取授权链接。
- 获取授权结果。
- 商户可通过支付方式返回的重构 URL 或者异步通知获取授权结果。
- 申请支付令牌。
- 调用 applyToken 接口来申请支付令牌,获取到对应令牌后存储到本地。
- 发起支付并获取支付结果。
- 在获得买家授权后,商户端直接调用 pay(令牌支付)接口发起代扣服务,并通过同步响应、支付查询或者支付 notifyPayment 获取支付结果。
集成准备
在您开始集成前,请阅读集成指南及接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:
- 已获得 client ID。
- 已完成密钥配置。
- 已完成异步通知接收地址的配置。
- 集成服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
集成步骤
要获得买家授权并进行代扣,请完成以下集成步骤:
- 获取并跳转到授权链接
- 获取授权结果
- 申请支付令牌
- 发起代扣
- 获取支付结果
步骤 1: 获取并跳转到授权链接
1. 调用咨询接口
在 consult 请求中传入以下参数:
参数名称 | 是否必需? | 描述 |
customerBelongsTo | 是 | 买家使用的钱包。在 Antom 全球商家账户中,该参数的值固定为 |
authRedirectUrl | 是 | 授权完成后,用于将买家跳转到商户页面的链接。 |
terminalType | 是 | 指商户端所在的终端类型。此场景下,字段值为 |
authState | 是 | 识别授权请求而传入的字符串。 |
scopes | 是 | 在此场景中,该字段设置为 |
以下代码为调用 consult 接口以获取授权链接的示例:
public static void authorizationConsult() {
AlipayAuthConsultRequest alipayAuthConsultRequest = new AlipayAuthConsultRequest();
// 替换为您的 authState
String authState = UUID.randomUUID().toString();
alipayAuthConsultRequest.setAuthState(authState);
// 设置请求授权的目标支付方式
alipayAuthConsultRequest.setCustomerBelongsTo(CustomerBelongsTo.TOSSPAY);
// 设置授权范围
alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});
// 设置 terminalType
alipayAuthConsultRequest.setTerminalType(TerminalType.WEB);
// 替换为您的 authRedirectUrl
alipayAuthConsultRequest.setAuthRedirectUrl("http://www.yourRedirectUrl.com");
// 执行授权查询
AlipayAuthConsultResponse alipayAuthConsultResponse;
try {
alipayAuthConsultResponse = CLIENT.execute(alipayAuthConsultRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// 处理错误情况
}
}以下为请求报文的代码示例:
{
"authRedirectUrl": "https://www.alipay.com",
"authState": "STATE-2348729823419",
"customerBelongsTo": "ANTOM_BIZ_ACCOUNT",
"scopes": [
"AGREEMENT_PAY"
],
"terminalType": "WEB"
}consult 接口的响应将返回包含买家需要跳转的授权链接(normalUrl)。涉及的参数如下:
参数名称 | 是否必需? | 描述 |
normalUrl | 是 | 将买家重定向到默认浏览器或嵌入式 WebView 中的 WAP 或网页的 URL。 |
result.resultCode | 是 | 结果代码,指示调用接口的结果。 |
以下代码显示了响应报文的示例:
{
"normalUrl": "http://page.alipay.net/page/antom-web-checkout-v2/aba-page/pages/auto-debit/index.html?requestHost=http%3A%2F%2Fimgs-50.sggz00b.dev.alipay.net%2Fmgw.htm&sessionData=d%2BS5ZKdIDx%2BhKUl3jkhBVF9eQXMMS2tLO%2BhFc7BWVtOkjaQV982mcQW5GfOnCaGTlrpaD2EI5zsp2%2BUju6eEhg%3D%3D%26%26SG%26%26188&groupId=GROUP_20241001122147828",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}2. 跳转到授权链接
当您的服务器获取到 normalUrl 后,将该链接传给客户端。您的前端页面会执行将买家跳转到 normalUrl 指定的地址的操作。以下是客户端在 Web 终端加载 URL 的代码示例:
if (URL != null) {
window.open(URL, '_blank');
}以下图片展示了支付方式签约页面的渲染效果:

步骤 2:获取授权结果
回跳商户页面
当买家在支付方式授权页面进行相关操作后,可能会发生授权成功或授权失败的情况。这两种情况下的后续跳转如下:
- 授权成功:授权成功后,买家通常会跳转回商户页面,页面地址为 authRediectUrl、authCode、authState 三个参数重构的 URL,但也有可能因为买家操作或者网络原因导致无法回跳。
- 授权失败:
- 如果买家主动点击放弃授权等原因退出授权页面,部分支付方式支持买家回跳到商户页面,该商户页面地址为 authRediectUrl。
- 如果买家超时未授权或者授权失败则无法回跳到商户页面。
获取授权码
买家完成授权后,您可以通过以下方式之一获取授权码(authCode):
- 从支付方式返回的重构链接中获取 authCode。
- 从 Antom 发送的异步授权通知中获取 authCode。
从重构链接获取 authCode
在完成授权流程后,买家会跳转到支付方式返回的重构链接。此链接由以下三个部分组成:
以下是重构链接的示例:
https://www.alipay.com/?authCode=d2f60253-ecdc-e9bc-27d1-566970191040&authState=663A8FA9-D836-48EE-8AA1-1FF682989DC7您可以通过重构链接获取 authCode 值。但在使用 authCode 之前,需要检查重构 URL 中 authState 的值是否与 consult 接口传入的 authState 参数值一致,并进行以下处理:
- 如果 authState 的值不一致,则该重构 URL 不可信,因为跳转过程中可能发生了被攻击等恶性事件,重构 URL 中的 authCode 不可用。
- 如果 authState 的值一致,可以使用该 authCode 发起申请支付令牌请求。
常见问题
问:是否可以同时使用以上两种方式获取 authCode?
答:是的,您可以同时通过重构 URL 和异步授权通知两种方式获取 authCode。如果您获得了多个 authCode,请使用最先收到的 authCode,在申请支付令牌时不要重复使用相同的 authCode 值。
问:如何判断授权失败?
答:如果等待超过 1 小时,您未能获取到 authCode,则可以判定本次授权失败。您可以重新引导买家进行授权。
步骤 3:申请支付令牌
在收到授权码(authCode)后 10 分钟内,调用 applyToken 接口来申请支付令牌(accessToken)。否则,authCode 将过期并失效。只有获得 accessToken,才能实现对买家账户的自动扣款。
调用 applyToken 接口时,请在请求中正确传入以下参数:
参数名称 | 是否必需? | 描述 |
grantType | 是 | 传入固定值为 |
customerBelongsTo | 是 | 传入您请求授权的目标支付方式。 |
authCode | 是 | 传入您收到的 authcode 值。 |
以下是调用 申请支付令牌 接口的代码示例:
AlipayAuthApplyTokenRequest alipayPayRequest = new AlipayAuthApplyTokenRequest();
alipayPayRequest.setClientId(CLIENT_ID);
alipayPayRequest.setPath("/ams/sandbox/api/v1/authorizations/applyToken");
alipayPayRequest.setGrantType(GrantType.AUTHORIZATION_CODE);
alipayPayRequest.setCustomerBelongsTo(CustomerBelongsTo.Antom business account);
alipayPayRequest.setAuthCode("663A8FA9D83648EE8AA11FF68298XXXX");
//申请令牌
AlipayPayResponse alipayPayResponse = null;
try {
alipayPayResponse = defaultAlipayClient.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// 处理错误情况
}以下是请求报文示例:
{
"authCode": "663A8FA9D83648EE8AA11FF68298XXXX",
"customerBelongsTo": "ANTOM_BIZ_ACCOUNT",
"grantType": "AUTHORIZATION_CODE"
}在响应中,您将收到以下关键参数:
- accessToken:支付令牌。
以下是响应报文示例:
{
"accessToken": "28208803011714191738919323000j9i8i8fU2f17100XXXX",
"accessTokenExpiryTime": "2125-02-07T17:08:43+08:00",
"extendInfo": "{\"userLoginId\":\"haiqing.XXX@antgroup.com\",\"userId\":\"218812021964XXXX\"}",
"userLoginId": "haiqing.XXX@antgroup.com",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}以下为申请支付令牌的响应报文中 result.resultStatus 字段可能返回的值,您可以根据指引进行处理:
result.resultStatus | 信息 | 后续操作 |
| 请求成功。 | 获取支付令牌成功,包含以下字段:
|
| 未知问题。 | 建议使用原请求参数重新调用接口。如果问题未解决,请联系 Antom 技术支持。 |
| 请求失败。 | 建议根据 result.resultCode 的提示对相关问题进行处理。由于 authCode 只能使用一次,需要从步骤 1 重新开始,获取并跳转到授权链接。获取新的 authCode 后,再次调用 applyToken 接口。 |
注意:
- 由于历史原因,以上关键参数适用于新商户,令牌有效期限为 100 年。若之前已经使用了accessTokenExpiryTime、refreshToken 和 refreshTokenExpiryTime 字段,您可以继续维持原有逻辑。
- 如果您未收到响应报文,可能是网络超时所致,建议使用原请求参数重新调用接口。如果问题未解决,请联系 Antom 技术支持。
- 如果调用接口后收到了响应,但响应中未返回支付令牌(accessToken),请采取以下措施:
- 如果 result.resultStatus 的值为
U,请使用相同的参数和值再次发起请求。- 如果 result.resultStatus 的值为
F,根据 result.resultCode 提供的提示解决相关问题。如果需要再次调用 applyToken 接口获取支付令牌,由于 authCode 只能使用一次,需要从步骤 1 重新开始,获取授权链接,并跳转到授权链接。获取新的 authCode 后,再次调用 applyToken 接口。
- 如果需要向买家显示授权账户,使用在 applyToken 接口中返回的 userLoginId 字段的值。该字段返回的值已经经过隐私保护处理,可以直接显示。
常见问题
问:是否支持异步通知获取支付令牌?
答:不支持。目前仅支持同步返回获取支付令牌。
问:令牌的有效期是多久?
答:100 年。
步骤 4:发起代扣
在获得买家授权后,您可以直接为买家提供代扣服务,无需他们在每次支付时都进行授权流程。
发起代扣时,请指定以下参数:
字段类型 | 字段名 | 是否必需? | 描述 |
基本字段 | paymentRequestId | 是 | 由商户生成的专属 ID,每次发起支付时都会创建新 ID。 |
| paymentAmount | 是 | 您请求以订单币种接收的付款金额。 | |
paymentRedirectUrl | 是 | 支付完成后买方被重定向到的商家页面URL。 | |
| paymentNotifyUrl | 否 | 用于接收支付结果通知的链接。 支付结果通知地址可以通过接口传输,或者在门户中设置固定值。 | |
paymentMethod.paymentMethodType | 是 | 付款方法选项中包含的付款方法类型。 | |
| paymentMethod.paymentMethodId | 是 | 属于买方的付款方式的唯一 ID。调用 applyToken 接口获取的支付令牌(accessToken)的值。 | |
订单字段 | order.orderAmount | 是 | 商户直接向客户提供的商品或服务金额。 |
order.referenceOrderId | 是 | 商户系统中用于识别订单的唯一编号。 | |
order.goods | 是 | 货物信息,包括订单中货物的 ID、名称、价格和数量。需注意:
| |
| order.buyer | 是 | 包括买家的 ID、姓名、电话号码和电子邮件的买家信息。传入该参数时,必须同时传入 referenceBuyerId 和 buyerName.fullName。 | |
order.transit | 否 | 行程信息,包括出行方式、行程段和乘客信息。在机票场景下,此字段必填。当 transit 信息为必填项,则 transitType 、legs.departureTime、legs.departureAddress.city、legs.arrivalAddress.city 和 legs.carrierNo 字段为必传。 |
上述参数并不全面,请参阅 pay(令牌支付)接口以获取完整参数列表以及特定支付方式的额外要求。
以下是不同场景下请求报文的代码示例:
机票场景
{
"order": {
"transit": {
"transitType": "FLIGHT",
"legs": [
{
"departureTime": "2024-11-27T12:01:01+08:00",
"departureAddress": {
"city": "SZX" //需要符合IATA三位码
},
"arrivalAddress": {
"city": "HKG" //需要符合IATA三位码
},
"carrierNo": "111"
}
]
},
"orderAmount": {
"currency": "CNY",
"value": "1000"
},
"orderDescription": "Cappuccino #grande (Mika's coffee shop)",
"referenceOrderId": "ORDER_2022111414171****",
"buyer": {
"referenceBuyerId": "test1234****",
"buyerName": {
"fullName": "Dehua Skr Liu"
}
},
"goods": [
{
"referenceGoodsId": "GoodsId-32078",
"goodsUnitAmount": {
"currency": "CNY",
"value": "1000"
},
"goodsQuantity": "1",
"goodsName": "机票-日期-航班号-出发-到达"
}
]
},
"env": {
"terminalType": "WEB"
},
"paymentAmount": {
"currency": "CNY",
"value": "1000"
},
"paymentMethod": {
"paymentMethodType": "ANTOM_BIZ_ACCOUNT",
"paymentMethodId": "28208803000517871730802054000MyNIvBt2HK17100****"
},
"settlementStrategy": {
"settlementCurrency": "CNY"
},
"paymentNotifyUrl": "https://www.alipay.com/notify",
"paymentRequestId": "PAY_2022111414171****",
"productCode": "AGREEMENT_PAYMENT"
}以下为响应示例代码:
{
"actualPaymentAmount": {
"currency": "HKD",
"value": "1000"
},
"paymentAmount": {
"currency": "HKD",
"value": "1000"
},
"paymentCreateTime": "2024-10-21T21:00:53-07:00",
"paymentId": "2024102219401080010018874020964****",
"paymentRequestId": "paymentRequestId_172956965****",
"paymentTime": "2024-10-21T21:01:08-07:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}步骤 5:获取支付结果
买家完成支付或支付超时后,可以通过以下方式之一获取相应的支付结果:
- 接收来自 Antom 的异步通知
- 主动查询支付结果
查询支付结果
发起 inquiryPayment 请求,并传入以下参数:
参数名称 | 是否必需? | 描述 |
paymentRequestId | 是 | 由商户生成的支付请求 ID。 |
以下是示例代码:
{
"paymentRequestId": "10152024052741013451092402****"
}以下为 inquiryPayment 响应的代码示例:
{
"actualPaymentAmount": {
"currency": "HKD",
"value": "1000"
},
"paymentAmount": {
"currency": "HKD",
"value": "1000"
},
"paymentId": "2024052719401080010018842022553****",
"paymentMethodType": "ANTOM_BIZ_ACCOUNT",
"paymentRedirectUrl": "https://xxx.com/bgt_launch_app_callback.html?browser_callback_new=1&chTransId=SO000124052709420662253642020002",
"paymentRequestId": "10152024052741013451092402****",
"paymentResultCode": "SUCCESS",
"paymentResultMessage": "success",
"paymentStatus": "SUCCESS",
"paymentTime": "2024-05-27T02:27:27-07:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}通过 result 字段返回接口调用结果。订单状态需要根据 paymentStatus 来判断:
SUCCESS:表示支付成功。FAIL:表示支付失败。PROCESSING:表示支付处理中。CANCELLED:表示支付已经被取消。
接收异步通知
完成支付或支付失败时,Antom 会通过 pay(令牌支付)接口中的 paymentNotifyUrl 参数指定的地址发送异步通知(notifyPayment),您也可以在 Antom Dashboard 中配置该地址。
以下是通知请求示例代码:
{
"actualPaymentAmount": {
"currency": "HKD",
"value": "1000"
},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "HKD",
"value": "1000"
},
"paymentCreateTime": "2024-05-27T02:27:13-07:00",
"paymentId": "2024052719401080010018842022553****",
"paymentRequestId": "10152024052741013451092402****",
"paymentResultInfo": {},
"paymentTime": "2024-05-27T02:27:27-07:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。您需要对 Antom 发送的支付通知进行验签,关于如何验证通知的签名并做出响应,请参阅处理通知。
无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success"
}
}常见问题
问:什么时候会发送通知?
答:这取决于支付是否完成:
- 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。
- 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。代扣默认关单时间是 1 分钟。
问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
- 由于网络原因未收到异步通知。
- 如果收到来自 Antom 的异步通知,但您没有按照处理通知的示例代码格式进行响应。
通知可以重发最多 8 次,或者直到收到正确的响应以终止传递。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和15 小时。
问:在响应异步通知时,需要添加签名吗?
答:如果您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。
问:在通知中需要使用哪些关键参数?
答: 请注意以下关键参数:
- result:表示订单的支付结果。
- paymentRequestId:用于咨询、取消和对账的支付请求 ID。
- paymentId:Antom 生成的支付订单 ID,用于退款和对账。
- paymentAmount:表示支付金额。
问:如果买家的 Antom bussiness account 里的币种和支付请求传入的币种不一致,交易是否会失败?
答:交易会失败。
支付后
完成支付后,您可对交易进行以下支付后的操作:
取消授权
授权完成后,您需为买家提供授权协议取消功能。欲了解更多详情,参见取消授权。
取消交易
下单后您可以在一定时间窗口期内通过使用 cancel 接口主动关闭某笔交易,支付成功后可在 T+1日的 00:15(UTC+8:00)之前取消(T 为交易日)。具体操作参见取消交易。
退款
在支付成功后,您可以通过调用 refund 接口对成功支付的交易发起退款。具体操作参见退款。
对账
交易完成后,您可以使用 Antom 提供的财务报告进行对账。请参阅对账了解关于如何对账和 Antom 结算规则的更多信息。
最佳实践
Antom 为您提供支付结果展示、支付失败重试、接口超时时间设置等最佳实践方案,请参阅最佳实践了解详情。