集成指南
令牌支付产品可为您的网站或应用构建线上自动扣款功能,买家在首次支付时完成签约授权后,后续支付仅需一次点击即可完成或由您的后台直接扣款。其适用于以下场景:
- 周期性支付:如订阅与会员服务,由您自己管理扣款周期。
- 小额高频支付、复购率高的场景:如游戏和电商,可为买家提供快捷流畅的支付流程。
令牌支付产品支持在不同终端类型(Web/WAP/App)上部署,并且您只需要一次集成,就可以接入多种支付方式,如电子钱包、银行转账等。
Web/WAP
iOS
Android
用户体验
以下图片展示了买家进行授权与支付的体验流程:
授权
Web
WAP
Antom 提供扫码授权和登录授权两种授权方式,不同支付方式的用户体验可能存在差异。
扫码授权
登录授权
买家跳转到支付方式 Web 页面,通过扫描页面二维码进行授权。

买家跳转到支付方式的 Web 页面,通过输入账号和密码完成授权。

Antom 提供 App 授权和登录授权两种授权方式,不同支付方式的用户体验可能存在差异。
App 授权
登录授权
买家跳转到支付方式 App 页面,通过拉起支付方式 App 进行授权。

买家跳转到支付方式的 H5 页面,通过输入账号和密码完成授权。

支付
买家点击支付后发起扣款的用户体验如下图所示:

后续的周期性支付不需要买家参与,您直接从后台发起扣款请求即可。
支付流程
在首次令牌支付前,您需获得买家授权。买家授权后,您使用授权码获取支付令牌直接发起令牌化服务,后续支付无需重复授权流程。具体流程如下图所示:

- 买家进入结账页面。
- 获取签约授权链接。
买家选择支付方式后,调用 consult 接口获取授权链接。
- 获取授权结果。
您可通过支付方式返回的重构 URL 或者异步通知获取授权结果。
- 申请支付令牌。
调用 applyToken 接口来申请支付令牌(accessToken),获取到对应令牌后存储到本地。
- 发起支付。
在获得买家授权后,您可以直接调用 pay(令牌支付)接口发起令牌化服务。
- 获取支付结果。
通过以下两种方法之一获取支付结果:
- 异步通知:在 pay(令牌支付)接口中设置 paymentNotifyUrl 字段,以指定接收异步通知的地址。当支付成功或过期时,Antom 会使用 notifyPayment 向您发送异步通知。
- 同步查询:调用 inquiryPayment 接口来查询支付状态。
集成步骤
要获得买家授权并进行支付,请完成以下集成步骤:
- 获取签约授权链接
- 跳转至支付方式页面进行授权
- 获取授权结果
- 申请支付令牌
- 发起支付
步骤 1:获取签约授权链接 服务端
Antom 提供多种语言的服务器端接口库。以下代码以 Java 为例,您需要安装 Java 6 及更高版本。
1. 安装接口库
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>{latest_version}</version>
</dependency>2. 初始化请求实例
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. 发起签约授权请求
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();
// 处理错误情况
}
}以下为请求报文的代码示例:
Web
WAP
{
"authRedirectUrl": "http://www.yourRedirectUrl.com",
"authState": "556c1e32-3723-4b02-88ed-8c46087540ca",
"customerBelongsTo": "TOSSPAY",
"scopes": [
"AGREEMENT_PAY"
],
"terminalType": "WEB"
}{
"authRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_113.html",
"authState": "STATE_20250325101650291",
"customerBelongsTo": "TOSSPAY",
"scopes": [
"AGREEMENT_PAY"
],
"terminalType": "WAP",
"osType": "ANDROID"
}4. 接收授权咨询响应
接口的响应包含买家需要跳转的授权链接:
Web
WAP
{
"authUrl": "https://pay.toss.im/payfront/web/billing?billingKey=5RMRHqdZPPaSr5AP4wkw43&source=AlipayConnect&needCallback=false",
"normalUrl": "https://pay.toss.im/payfront/web/billing?billingKey=5RMRHqdZPPaSr5AP4wkw43&source=AlipayConnect&needCallback=false",
"webRequestMethod": "GET",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}{
"appIdentifier": "viva.republica.toss",
"authUrl": "https://pay.toss.im/payfront/web/billing?billingKey=moeoiG8rm2PUPawM3ZrXde&source=AlipayConnect&needCallback=false",
"normalUrl": "https://pay.toss.im/payfront/web/billing?billingKey=moeoiG8rm2PUPawM3ZrXde&source=AlipayConnect&needCallback=false",
"webRequestMethod": "GET",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}下表展示了接口响应中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 authState 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
答:不同支付方式在不同端类型下,Antom 可能会返回 normalUrl、applinkUrl、schemeUrl 这三种链接中的一个或多个,商户服务端需将此 URL 传递给商户前端进行跳转,各链接的具体信息请查阅跳转链接使用最佳实践。
问:如何设置 terminalType?
答:terminalType 的有效值如下:
- 如果买家在 PC 浏览器发起交易,需要将 terminalType 指定为 WEB。
- 如果买家在移动浏览器上发起交易,需要将 terminalType 指定为 WAP。添加 osType 参数,并根据买家的设备填写相应的系统参数ANDROID或IOS。
您需要传递正确的 terminalType 以获取正确的跳转 URL,若传递错误可能会影响签约成功率。
问:请求字段值可以使用中文字符吗?
答:为了避免特定支付方式的不兼容情况,请求中的字段请勿使用中文字符。
问:收到返回的 normalUrl 后应该怎么做?
答:对于在 PC 浏览器中进行的交易,Antom 在 consult 响应中返回 normalUrl 参数。您的服务器需要传入此链接给客户端进行跳转。建议不要缓存返回的 normalUrl,当重新发起授权时,需要获取新的 normalUrl 用于跳转。
步骤 2:跳转至支付方式页面进行授权 客户端
服务端获取签约授权链接后,需将该链接传递给客户端,您的客户端会将买家跳转至签约授权页面。以下是客户端加载 URL 的代码示例(其中的 URL 指 consult 接口响应返回的 applinkUrl、schemeUrl 或 normalUrl):
Web
WAP
if (URL != null) {
window.open(URL, '_blank');
}window.location.href = URL;常见问题
问:如何处理不同的支付体验?
以下图片展示了支付方式签约页面的渲染效果:

步骤 3:获取授权结果
1. 回跳商户页面
当买家在支付方式授权页面进行相关操作后,可能会发生授权成功或授权失败的情况,这两种情况下的后续跳转如下:
- 授权成功:授权成功后,买家通常会跳转回商户页面,页面地址为 authRediectUrl、authCode、authState 三个参数重构的 URL,但也有可能因为买家操作或者网络原因导致无法回跳。
- 授权失败:
- 如果买家主动点击放弃授权等原因退出授权页面,部分支付方式支持买家回跳到商户页面,该商户页面地址为 authRediectUrl。
- 如果买家超时未授权或者授权失败则无法回跳到商户页面。
注意:
- 授权链接只能使用一次,如果买家授权失败,您需要重新调用 consult 接口并提供一个新的 authState 值。
- Boost 支付方式如果需要回跳商户页面,请联系 Antom 技术支持申请配置。
2. 获取授权码
买家在步骤 2 完成授权后,您可以通过以下方式之一获取授权码(authCode):
- 从支付方式返回的重构 URL 中获取 authCode。
- 从 Antom 发送的异步授权通知中获取 authCode。
从重构 URL 中获取授权码
从授权通知中获取授权码
从重构 URL 中获取授权码
客户端
授权成功后,买家会跳转到支付方式返回的重构 URL,该 URL 由以下三个部分组成:
- 您在 consult 接口中传入的 authRedirectUrl 参数的值,如 https://www.alipay.com/。
- 您在 consult 接口中传入的 authState 参数的值,如 663A8FA9-D836-48EE-8AA1-1FF682989DC7。
- 该支付方式返回的 authCode,如 281004138596827069301079。
以下是重构 URL 的示例:
https://www.alipay.com/&authState=663A8FA9-D836-48EE-8AA1-1FF682989DC7&authCode=281004138596827069301079您可以通过重构链接获取 authCode 值。但在使用 authCode 之前,需要检查重构 URL 中 authState 的值是否与 consult 接口传入的 authState 参数值一致,并进行以下处理:
- 如果 authState 的值不一致,则该重构 URL 不可信,因为跳转过程中可能发生了被攻击等恶性事件,重构 URL 中的 authCode 不可用。
- 如果 authState 的值一致,可以使用该 authCode 发起申请支付令牌请求。
从授权通知中获取授权码
服务端
由于网络问题或其他原因,您可能无法获取重构 URL。此时,您可以按照以下步骤从 Antom 发送的异步授权通知中获取授权码(authCode):
- 配置接收异步授权通知的 webhook URL。按照 Antom Dashboard > 开发者 > 通知地址 路径,为 alipay.ams.authorizations.notify 接口增加通知地址。具体操作请参阅通知地址。
- 买家同意授权后,您将收到 Antom 发送的 notifyAuthorization。当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。以下是异步授权通知请求的代码示例:
{
"authCode": "28100113_1631148338197000019ba74",
"authState": "489767958497",
"authorizationNotifyType": "AUTHCODE_CREATED",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success",
"resultStatus": "S"
}
}根据授权结果的请求中 result.resultStatus 的值(仅返回
S
)获取授权码(authCode):- S:表示授权成功,并返回以下字段:
- authState:用于发起授权而分配的专属 ID。该字段的值用于验证是否与 consult 请求中指定的 authState 值一致。
- authorizationNotifyType:本场景下仅会返回 AUTHCODE_CREATED,表示买家在商户客户端成功发起令牌支付的授权。
- authCode:买家完成授权后生成的授权码,使用此授权码来请求支付令牌。
- 您需要按照以下方法对 Antom 发送的授权结果通知进行验签:
@PostMapping("/receiveAuthNotify")
@ResponseBody
public Result receiveAuthNotify(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");
try {
// 验签
boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
if (!verifyResult) {
throw new RuntimeException("Invalid notify signature");
}
// 反序列化通知体
AlipayAuthNotify authNotify = JSON.parseObject(notifyBody, AlipayAuthNotify.class);
if (authNotify != null && "SUCCESS".equals(authNotify.getResult().getResultCode())) {
// 获取 authCode 以申请支付令牌
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();
}
- 无论是否授权成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
}
}常见问题
问:是否可以同时使用以上两种方式获取 authCode?
答:是的,您可以同时通过重构 URL 和异步授权通知两种方式获取 authCode。如果您获得了多个 authCode,请使用最先收到的 authCode,在申请支付令牌时不要重复使用相同的 authCode 值。
问:什么时候会发送通知?
答:买家授权完成后,Antom 会向您发送异步通知。
问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
- 因网络原因未收到异步通知。
- 如果收到来自 Antom 的异步通知,但您没有按照处理通知的示例代码格式进行响应。
通知最多可重新发送 8 次,或直到收到正确的响应以终止发送。发送间隔为:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和 15 小时。
问:在响应异步通知时,需要添加签名吗?
问:如何判断授权失败?
答:如果等待超过 15 分钟,您未能获取到 authCode,则可以判定本次授权失败。您可以重新引导买家进行授权。
用户体验
以下图片展示了买家进行授权与支付的体验流程:
授权
Antom 提供 App 授权和登录授权两种授权方式,不同支付方式的用户体验可能存在差异。
App 授权
登录授权
买家跳转到支付方式 App 页面,通过拉起支付方式 App 进行授权。

买家跳转到支付方式的 H5 页面,通过输入账号和密码完成授权。

支付
买家点击支付后发起扣款的用户体验如下图所示:

后续的周期性支付不需要买家参与,您直接从后台发起扣款请求即可。
支付流程
在首次令牌支付前,您需获得买家授权。买家授权后,您使用授权码获取支付令牌直接发起令牌化服务,后续支付无需重复授权流程。具体流程如下图所示:

- 买家进入结账页面。
- 获取签约授权链接。
买家选择支付方式后,调用 consult 接口获取授权链接。
- 获取授权结果。
您可通过支付方式返回的重构 URL 或者异步通知获取授权结果。
- 申请支付令牌。
调用 applyToken 接口来申请支付令牌(accessToken),获取到对应令牌后存储到本地。
- 发起支付。
在获得买家授权后,您可以直接调用 pay(令牌支付)接口发起令牌化服务。
- 获取支付结果。
通过以下两种方法之一获取支付结果:
- 异步通知:在 pay(令牌支付)接口中设置 paymentNotifyUrl 字段,以指定接收异步通知的地址。当支付成功或过期时,Antom 会使用 notifyPayment 向您发送异步通知。
- 同步查询:调用 inquiryPayment 接口来查询支付状态。
集成步骤
要获得买家授权并进行支付,请完成以下集成步骤:
- 获取签约授权链接
- 跳转至支付方式页面进行授权
- 获取授权结果
- 申请支付令牌
- 发起支付
步骤 1:获取签约授权链接 服务端
Antom 提供多种语言的服务器端接口库。以下代码以 Java 为例,您需要安装 Java 6 及更高版本。
1. 安装接口库
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>{latest_version}</version>
</dependency>2. 初始化请求实例
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. 发起签约授权请求
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": "kademo://auth",
"authState": "STATE_20250325101702257",
"customerBelongsTo": "TOSSPAY",
"scopes": [
"AGREEMENT_PAY"
],
"terminalType": "APP",
"osType": "IOS"
}4. 接收授权咨询响应
接口的响应包含买家需要跳转的授权链接:
{
"appIdentifier": "viva.republica.toss",
"applinkUrl": "https://toss.onelink.me/3563614660?pid=referral&af_force_deeplink=true&af_dp=supertoss%3A%2F%2Fpay%2FbillingKey%3FbillingKey%3D0a5acO7999DSjKgJM8Kxf9%26skipResult%3Dfalse%26shouldAutoClose%3Dfalse&source=AlipayConnect&needCallback=false",
"authUrl": "https://toss.onelink.me/3563614660?pid=referral&af_force_deeplink=true&af_dp=supertoss%3A%2F%2Fpay%2FbillingKey%3FbillingKey%3D0a5acO7999DSjKgJM8Kxf9%26skipResult%3Dfalse%26shouldAutoClose%3Dfalse&source=AlipayConnect&needCallback=false",
"normalUrl": "https://pay.toss.im/payfront/web/billing?billingKey=0a5acO7999DSjKgJM8Kxf9&source=AlipayConnect&needCallback=false",
"schemeUrl": "supertoss://pay/billingKey?billingKey=0a5acO7999DSjKgJM8Kxf9&source=AlipayConnect&needCallback=false",
"webRequestMethod": "GET",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}下表展示了接口响应中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 authState 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
答:不同支付方式在不同端类型下,Antom 可能会返回 normalUrl、applinkUrl、schemeUrl 这三种链接中的一个或多个,商户服务端需将此 URL 传递给商户前端进行跳转,各链接的具体信息请查阅跳转链接使用最佳实践。
问:如何设置 terminalType?
答:terminalType 的有效值如下:
- 如果买家在移动应用内发起交易,需要将 terminalType 指定为 APP。添加 osType 参数,并根据买家的移动设备填写相应的系统参数ANDROID或IOS。
您需要传递正确的 terminalType 以获取正确的跳转 URL,若传递错误可能会影响签约成功率。
问:请求字段值可以使用中文字符吗?
答:为了避免特定支付方式的不兼容情况,请求中的字段请勿使用中文字符。
问:收到返回的 normalUrl 后应该怎么做?
答:对于在 PC 浏览器中进行的交易,Antom 在 consult 响应中返回 normalUrl 参数。您的服务器需要传入此链接给客户端进行跳转。建议不要缓存返回的 normalUrl,当重新发起授权时,需要获取新的 normalUrl 用于跳转。
步骤 2:跳转至支付方式页面进行授权 客户端
服务端获取签约授权链接后,需将该链接传递给客户端,您的客户端会将买家跳转至签约授权页面。以下是客户端加载 URL 的代码示例(其中的 URL 指 consult 接口响应返回的 applinkUrl、schemeUrl 或 normalUrl):
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url] options:@{} completionHandler:nil];
}else{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url]];
}常见问题
问:如何处理不同的支付体验?
以下图片展示了支付方式签约页面的渲染效果:

步骤 3:获取授权结果
1. 回跳商户页面
当买家在支付方式授权页面进行相关操作后,可能会发生授权成功或授权失败的情况,这两种情况下的后续跳转如下:
- 授权成功:授权成功后,买家通常会跳转回商户页面,页面地址为 authRediectUrl、authCode、authState 三个参数重构的 URL,但也有可能因为买家操作或者网络原因导致无法回跳。
- 授权失败:
- 如果买家主动点击放弃授权等原因退出授权页面,部分支付方式支持买家回跳到商户页面,该商户页面地址为 authRediectUrl。
- 如果买家超时未授权或者授权失败则无法回跳到商户页面。
注意:
- 授权链接只能使用一次,如果买家授权失败,您需要重新调用 consult 接口并提供一个新的 authState 值。
- Boost 支付方式如果需要回跳商户页面,请联系 Antom 技术支持申请配置。
2. 获取授权码
买家在步骤 2 完成授权后,您可以通过以下方式之一获取授权码(authCode):
- 从支付方式返回的重构 URL 中获取 authCode。
- 从 Antom 发送的异步授权通知中获取 authCode。
从重构 URL 中获取授权码
从授权通知中获取授权码
从重构 URL 中获取授权码
客户端
授权成功后,买家会跳转到支付方式返回的重构 URL,该 URL 由以下三个部分组成:
- 您在 consult 接口中传入的 authRedirectUrl 参数的值,如 https://www.alipay.com/。
- 您在 consult 接口中传入的 authState 参数的值,如 663A8FA9-D836-48EE-8AA1-1FF682989DC7。
- 该支付方式返回的 authCode,如 281004138596827069301079。
以下是重构 URL 的示例:
https://www.alipay.com/?authCode=d2f60253-ecdc-e9bc-27d1-566970191040&authState=663A8FA9-D836-48EE-8AA1-1FF682989DC7&authCode=xxxxx您可以通过重构链接获取 authCode 值。但在使用 authCode 之前,需要检查重构 URL 中 authState 的值是否与 consult 接口传入的 authState 参数值一致,并进行以下处理:
- 如果 authState 的值不一致,则该重构 URL 不可信,因为跳转过程中可能发生了被攻击等恶性事件,重构 URL 中的 authCode 不可用。
- 如果 authState 的值一致,可以使用该 authCode 发起申请支付令牌请求。
从授权通知中获取授权码
服务端
由于网络问题或其他原因,您可能无法获取重构 URL。此时,您可以按照以下步骤从 Antom 发送的异步授权通知中获取授权码(authCode):
- 配置接收异步授权通知的 webhook URL。按照 Antom Dashboard > 开发者 > 通知地址 路径,为 alipay.ams.authorizations.notify 接口增加通知地址。具体操作请参阅通知地址。
- 买家同意授权后,您将收到 Antom 发送的 notifyAuthorization。当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。以下是异步授权通知请求的代码示例:
{
"authCode": "28100113_1631148338197000019ba74",
"authState": "489767958497",
"authorizationNotifyType": "AUTHCODE_CREATED",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success",
"resultStatus": "S"
}
}根据授权结果的请求中 result.resultStatus 的值(仅返回
S
)获取授权码(authCode):- S:表示授权成功,并返回以下字段:
- authState:用于发起授权而分配的专属 ID。该字段的值用于验证是否与 consult 请求中指定的 authState 值一致。
- authorizationNotifyType:本场景下仅会返回 AUTHCODE_CREATED,表示买家在商户客户端成功发起令牌支付的授权。
- authCode:买家完成授权后生成的授权码,使用此授权码来请求支付令牌。
- 您需要按照以下方法对 Antom 发送的授权结果通知进行验签:
@PostMapping("/receiveAuthNotify")
@ResponseBody
public Result receiveAuthNotify(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");
try {
// 验签
boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
if (!verifyResult) {
throw new RuntimeException("Invalid notify signature");
}
// 反序列化通知体
AlipayAuthNotify authNotify = JSON.parseObject(notifyBody, AlipayAuthNotify.class);
if (authNotify != null && "SUCCESS".equals(authNotify.getResult().getResultCode())) {
// 获取 authCode 以申请支付令牌
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();
}
- 无论是否授权成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
}
}常见问题
问:是否可以同时使用以上两种方式获取 authCode?
答:是的,您可以同时通过重构 URL 和异步授权通知两种方式获取 authCode。如果您获得了多个 authCode,请使用最先收到的 authCode,在申请支付令牌时不要重复使用相同的 authCode 值。
问:什么时候会发送通知?
答:买家授权完成后,Antom 会向您发送异步通知。
问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
- 因网络原因未收到异步通知。
- 如果收到来自 Antom 的异步通知,但您没有按照处理通知的示例代码格式进行响应。
通知最多可重新发送 8 次,或直到收到正确的响应以终止发送。发送间隔为:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和 15 小时。
问:在响应异步通知时,需要添加签名吗?
问:如何判断授权失败?
答:如果等待超过 15 分钟,您未能获取到 authCode,则可以判定本次授权失败。您可以重新引导买家进行授权。
用户体验
以下图片展示了买家进行授权与支付的体验流程:
授权
Antom 提供 App 授权和登录授权两种授权方式,不同支付方式的用户体验可能存在差异。
App 授权
登录授权
买家跳转到支付方式 App 页面,通过拉起支付方式 App 进行授权。

买家跳转到支付方式的 H5 页面,通过输入账号和密码完成授权。

支付
买家点击支付后发起扣款的用户体验如下图所示:

后续的周期性支付不需要买家参与,您直接从后台发起扣款请求即可。
支付流程
在首次令牌支付前,您需获得买家授权。买家授权后,您使用授权码获取支付令牌直接发起令牌化服务,后续支付无需重复授权流程。具体流程如下图所示:

- 买家进入结账页面。
- 获取签约授权链接。
买家选择支付方式后,调用 consult 接口获取授权链接。
- 获取授权结果。
您可通过支付方式返回的重构 URL 或者异步通知获取授权结果。
- 申请支付令牌。
调用 applyToken 接口来申请支付令牌(accessToken),获取到对应令牌后存储到本地。
- 发起支付。
在获得买家授权后,您可以直接调用 pay(令牌支付)接口发起令牌化服务。
- 获取支付结果。
通过以下两种方法之一获取支付结果:
- 异步通知:在 pay(令牌支付)接口中设置 paymentNotifyUrl 字段,以指定接收异步通知的地址。当支付成功或过期时,Antom 会使用 notifyPayment 向您发送异步通知。
- 同步查询:调用 inquiryPayment 接口来查询支付状态。
集成步骤
要获得买家授权并进行支付,请完成以下集成步骤:
- 获取签约授权链接
- 跳转至支付方式页面进行授权
- 获取授权结果
- 申请支付令牌
- 发起支付
步骤 1:获取签约授权链接 服务端
Antom 提供多种语言的服务器端接口库。以下代码以 Java 为例,您需要安装 Java 6 及更高版本。
1. 安装接口库
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>{latest_version}</version>
</dependency>2. 初始化请求实例
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. 发起签约授权请求
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": "kademo://auth",
"authState": "STATE_20250325101702257",
"customerBelongsTo": "TOSSPAY",
"scopes": [
"AGREEMENT_PAY"
],
"terminalType": "APP",
"osType": "ANDROID"
}4. 接收授权咨询响应
接口的响应包含买家需要跳转的授权链接:
{
"appIdentifier": "viva.republica.toss",
"applinkUrl": "https://toss.onelink.me/3563614660?pid=referral&af_force_deeplink=true&af_dp=supertoss%3A%2F%2Fpay%2FbillingKey%3FbillingKey%3D0a5acO7999DSjKgJM8Kxf9%26skipResult%3Dfalse%26shouldAutoClose%3Dfalse&source=AlipayConnect&needCallback=false",
"authUrl": "https://toss.onelink.me/3563614660?pid=referral&af_force_deeplink=true&af_dp=supertoss%3A%2F%2Fpay%2FbillingKey%3FbillingKey%3D0a5acO7999DSjKgJM8Kxf9%26skipResult%3Dfalse%26shouldAutoClose%3Dfalse&source=AlipayConnect&needCallback=false",
"normalUrl": "https://pay.toss.im/payfront/web/billing?billingKey=0a5acO7999DSjKgJM8Kxf9&source=AlipayConnect&needCallback=false",
"schemeUrl": "supertoss://pay/billingKey?billingKey=0a5acO7999DSjKgJM8Kxf9&source=AlipayConnect&needCallback=false",
"webRequestMethod": "GET",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}下表展示了接口响应中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
注意:如果您未收到响应报文,可能是网络超时所致。建议更换 authState 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
答:不同支付方式在不同端类型下,Antom 可能会返回 normalUrl、applinkUrl、schemeUrl 这三种链接中的一个或多个,商户服务端需将此 URL 传递给商户前端进行跳转,各链接的具体信息请查阅跳转链接使用最佳实践。
问:如何设置 terminalType?
答:terminalType 的有效值如下:
- 如果买家在移动应用内发起交易,需要将 terminalType 指定为 APP。添加 osType 参数,并根据买家的移动设备填写相应的系统参数ANDROID或IOS。
您需要传递正确的 terminalType 以获取正确的跳转 URL,若传递错误可能会影响签约成功率。
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的不兼容情况,请求中的字段请勿使用中文字符。
问:收到返回的 normalUrl 后应该怎么做?
答:对于在 PC 浏览器中进行的交易,Antom 在 consult 响应中返回 normalUrl 参数。您的服务器需要传入此链接给客户端进行跳转。建议不要缓存返回的 normalUrl,当重新发起授权时,需要获取新的 normalUrl 用于跳转。
步骤 2:跳转至支付方式页面进行授权 客户端
服务端获取签约授权链接后,需将该链接传递给客户端,您的客户端会将买家跳转至签约授权页面。以下是客户端加载 URL 的代码示例(其中的 URL 指 consult 接口响应返回的 applinkUrl、schemeUrl 或 normalUrl):
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 使用 startActivity 函数跳转到钱包 App
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}常见问题
问:如何处理不同的支付体验?
以下图片展示了支付方式签约页面的渲染效果:

步骤 3:获取授权结果
1. 回跳商户页面
当买家在支付方式授权页面进行相关操作后,可能会发生授权成功或授权失败的情况,这两种情况下的后续跳转如下:
- 授权成功:授权成功后,买家通常会跳转回商户页面,页面地址为 authRediectUrl、authCode、authState 三个参数重构的 URL,但也有可能因为买家操作或者网络原因导致无法回跳。
- 授权失败:
- 如果买家主动点击放弃授权等原因退出授权页面,部分支付方式支持买家回跳到商户页面,该商户页面地址为 authRediectUrl。
- 如果买家超时未授权或者授权失败则无法回跳到商户页面。
注意:
- 授权链接只能使用一次,如果买家授权失败,您需要重新调用 consult 接口并提供一个新的 authState 值。
- Boost 支付方式如果需要回跳商户页面,请联系 Antom 技术支持申请配置。
2. 获取授权码
买家在步骤 2 完成授权后,您可以通过以下方式之一获取授权码(authCode):
- 从支付方式返回的重构 URL 中获取 authCode。
- 从 Antom 发送的异步授权通知中获取 authCode。
从重构 URL 中获取授权码
从授权通知中获取授权码
从重构 URL 中获取授权码
客户端
授权成功后,买家会跳转到支付方式返回的重构 URL,该 URL 由以下三个部分组成:
- 您在 consult 接口中传入的 authRedirectUrl 参数的值,如 https://www.alipay.com/。
- 您在 consult 接口中传入的 authState 参数的值,如 663A8FA9-D836-48EE-8AA1-1FF682989DC7。
- 该支付方式返回的 authCode,如 281004138596827069301079。
以下是重构 URL 的示例:
https://www.alipay.com/?authCode=d2f60253-ecdc-e9bc-27d1-566970191040&authState=663A8FA9-D836-48EE-8AA1-1FF682989DC7&authCode=xxxxx您可以通过重构链接获取 authCode 值。但在使用 authCode 之前,需要检查重构 URL 中 authState 的值是否与 consult 接口传入的 authState 参数值一致,并进行以下处理:
- 如果 authState 的值不一致,则该重构 URL 不可信,因为跳转过程中可能发生了被攻击等恶性事件,重构 URL 中的 authCode 不可用。
- 如果 authState 的值一致,可以使用该 authCode 发起申请支付令牌请求。
从授权通知中获取授权码
服务端
由于网络问题或其他原因,您可能无法获取重构 URL。此时,您可以按照以下步骤从 Antom 发送的异步授权通知中获取授权码(authCode):
- 配置接收异步授权通知的 webhook URL。按照 Antom Dashboard > 开发者 > 通知地址 路径,为 alipay.ams.authorizations.notify 接口增加通知地址。具体操作请参阅通知地址。
- 买家同意授权后,您将收到 Antom 发送的 notifyAuthorization。当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。以下是异步授权通知请求的代码示例:
{
"authCode": "28100113_1631148338197000019ba74",
"authState": "489767958497",
"authorizationNotifyType": "AUTHCODE_CREATED",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success",
"resultStatus": "S"
}
}根据授权结果的请求中 result.resultStatus 的值(仅返回
S
)获取授权码(authCode):- S:表示授权成功,并返回以下字段:
- authState:用于发起授权而分配的专属 ID。该字段的值用于验证是否与 consult 请求中指定的 authState 值一致。
- authorizationNotifyType:本场景下仅会返回 AUTHCODE_CREATED,表示买家在商户客户端成功发起令牌支付的授权。
- authCode:买家完成授权后生成的授权码,使用此授权码来请求支付令牌。
- 您需要按照以下方法对 Antom 发送的授权结果通知进行验签:
@PostMapping("/receiveAuthNotify")
@ResponseBody
public Result receiveAuthNotify(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");
try {
// 验签
boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
if (!verifyResult) {
throw new RuntimeException("Invalid notify signature");
}
// 反序列化通知体
AlipayAuthNotify authNotify = JSON.parseObject(notifyBody, AlipayAuthNotify.class);
if (authNotify != null && "SUCCESS".equals(authNotify.getResult().getResultCode())) {
// 获取 authCode 以申请支付令牌
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();
}
- 无论是否授权成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
}
}常见问题
问:是否可以同时使用以上两种方式获取 authCode?
答:是的,您可以同时通过重构 URL 和异步授权通知两种方式获取 authCode。如果您获得了多个 authCode,请使用最先收到的 authCode,在申请支付令牌时不要重复使用相同的 authCode 值。
问:什么时候会发送通知?
答:买家授权完成后,Antom 会向您发送异步通知。
问:Antom 会重新发送异步通知吗?
答:会。对于以下情况,异步通知将在 24 小时内自动重新发送:
- 因网络原因未收到异步通知。
- 如果收到来自 Antom 的异步通知,但您没有按照处理通知的示例代码格式进行响应。
通知最多可重新发送 8 次,或直到收到正确的响应以终止发送。发送间隔为:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和 15 小时。
问:在响应异步通知时,需要添加签名吗?
问:如何判断授权失败?
答:如果等待超过 15 分钟,您未能获取到 authCode,则可以判定本次授权失败。您可以重新引导买家进行授权。
步骤 4:申请支付令牌 服务端
在收到授权码(authCode)后一分钟内,调用 applyToken 接口来申请支付令牌(accessToken)。否则,授权码(authCode)将过期并失效。只有获得 accessToken 后,后续才能从买家账户自动代扣款。
public static void applyToken() {
String authCode = "yourAuthCode";
AlipayAuthApplyTokenRequest alipayPayRequest = new AlipayAuthApplyTokenRequest();
// 设置 grantType
alipayPayRequest.setGrantType(GrantType.AUTHORIZATION_CODE);
// 设置请求授权的目标支付方式
alipayPayRequest.setCustomerBelongsTo(CustomerBelongsTo.GCASH);
// 设置 authCode
alipayPayRequest.setAuthCode(authCode);
// 申请支付令牌
AlipayAuthApplyTokenResponse authApplyTokenResponse;
try {
authApplyTokenResponse = CLIENT.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// 处理错误情况
}
}以下是申请支付令牌的请求报文示例:
{
"authCode": "663A8FA9D83648EE8AA11FF68298XXXX",
"customerBelongsTo": "GCASH",
"grantType": "AUTHORIZATION_CODE"
}以下是申请支付令牌的响应报文示例:
{
"accessToken": "281011030220200914TLsu9RhgUv87Lf1111****",
"accessTokenExpiryTime": "2022-09-14T17:14:16+08:00",
"extendInfo": "{"userId":"100000111111****","userLoginId":"6017271****"}",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "Success",
"resultStatus": "S"
},
"userLoginId": "6017271****"
}下表展示了申请支付令牌的响应报文中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
注意:如果您未收到响应报文,可能是网络超时所致。建议使用原请求参数重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
问:authCode 可以多次调用吗?
答:不可以,authCode 只能使用一次。
答:不可以,authCode 只能使用一次。
问:authCode 的有效时间是多久?
答:通常为一分钟,建议您在一分钟内完成支付令牌的申请。
支付令牌有效期
关于令牌支付支持的支付方式,支付令牌有效期如下表所示:
注意:PayPay 首次签约完成后,有效期为 1 年。若在有效期内发生成功交易,则有效期将自该交易成功之日起自动顺延 1 年。
步骤 5:发起支付 服务端
买家授权成功后,您可以为买家提供代扣款服务,即买家在后续的购物中,每次付款都无需输入支付信息,系统自动完成订单对应金额的扣款。
发起令牌支付时,请指定以下参数:
public static void pay() {
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
// 替换为您的 paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPayRequest.setPaymentRequestId(paymentRequestId);
// 设置金额
// 转换金额单位(实际金额应该在您的服务端计算)
Amount amount = Amount.builder().currency("SGD").value("550000").build();
alipayPayRequest.setPaymentAmount(amount);
// 指定支付方式
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("GCASH").
paymentMethodId("2828XXX77801726307481000Iba1Pm20IU171000179").build();
alipayPayRequest.setPaymentMethod(paymentMethod);
// 设置买家信息
Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();
// 替换为您的 orderId
String orderId = UUID.randomUUID().toString();
// 设置订单信息
Order order = Order.builder().referenceOrderId(orderId).
orderDescription("antom api testing order").orderAmount(amount).buyer(buyer).build();
alipayPayRequest.setOrder(order);
// 设置环境信息
Env env = Env.builder().terminalType(TerminalType.WEB).clientIp("114.121.121.01").build();
alipayPayRequest.setEnv(env);
// 替换为您的通知地址
alipayPayRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");
AlipayPayResponse alipayPayResponse;
try {
alipayPayResponse = CLIENT.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// 处理错误情况
}
}以下是请求报文的代码示例:
{
"env": {
"clientIp": "114.121.121.01",
"terminalType": "WEB"
},
"order": {
"buyer": {
"referenceBuyerId": "yourBuyerId"
},
"orderAmount": {
"currency": "SGD",
"value": "550000"
},
"orderDescription": "antom api testing order",
"referenceOrderId": "f69cb774-8d47-4da9-bf91-08c656581cdf"
},
"paymentAmount": {
"currency": "SGD",
"value": "550000"
},
"paymentMethod": {
"paymentMethodId": "2828XXX77801726307481000Iba1Pm20IU171000179",
"paymentMethodType": "GCASH"
},
"paymentNotifyUrl": "http://www.yourNotifyUrl.com",
"paymentRequestId": "AGREEMENT_PAYMENT_REQUEST_2020070316170XXXX",
"productCode": "AGREEMENT_PAYMENT"
}以下是响应报文的代码示例:
{
"paymentAmount": {
"currency": "SGD",
"value": "550000"
},
"paymentCreateTime": "2020-07-03T01:17:50-07:00",
"paymentId": "2020070311401080010018840027964XXXX",
"paymentRequestId": "AGREEMENT_PAYMENT_REQUEST_2020070316170XXXX",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "Success",
"resultStatus": "S"
}
}下表展示了响应报文中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
注意:如果您未收到响应报文,可能是网络超时所致。建议使用原 paymentRequestId 重新调用接口。如果问题未解决,请联系 Antom 技术支持。
常见问题
问:如何设置 terminalType?
答:terminalType 的有效值如下:
- 如果买家在 PC 浏览器发起交易,需要将 terminalType 指定为 WEB。
- 如果买家在移动浏览器上发起交易,需要将 terminalType 指定为 WAP。添加 osType 参数,并根据买家的移动设备填写相应的系统参数ANDROID或IOS。
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的不兼容情况,请勿在请求字段中使用中文字符。
问:如何设置接收支付通知的地址?
答:在 pay(令牌支付)接口中指定 paymentNotifyUrl 以接收支付结果(notifyPayment)的异步通知,或者在 Antom Dashboard 中配置接收地址。如果请求和 Antom Dashboard 都指定了地址,则请求中指定的值优先。
获取支付结果
您可以选择以下方法之一获取交易结果:
- 接收来自 Antom 的异步通知
- 主动查询支付结果
接收异步通知
查询支付结果
1. 设置接收通知的 webhook URL
完成支付或支付失败时,Antom 会向您设置的 webhook URL 发送异步通知,您可以选择以下两种方法中的一种来设置接收通知的 webhook URL:
- 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以通过 pay(令牌支付)接口请求的 paymentNotifyUrl 字段传入该笔订单的异步通知接收 URL。
- 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置 webhook URL。具体操作请参阅通知地址。
以下是异步通知请求体的代码示例:
{
"actualPaymentAmount": {
"currency": "HKD",
"value": "98080"
},
"customsDeclarationAmount": {},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "HKD",
"value": "98080"
},
"paymentCreateTime": "2024-09-27T00:23:36-07:00",
"paymentId": "202409271940108001001881E0211235544",
"paymentRequestId": "bc93d19e-e1f6-4b68-b6b1-3d6ddc2a792a",
"paymentTime": "2024-09-27T00:23:46-07:00",
"pspCustomerInfo": {
"pspCustomerId": "20881221121****",
"pspName": "ALIPAY_HK"
},
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}下表展示了支付结果的异步通知中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
2. 异步通知验签
您需要按照以下方法对 Antom 发送的支付通知进行验签:
/**
* 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();
// 从请求头中获取所需的参数
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();
}
}
} 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();
}无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,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 小时。
问:在响应异步通知时,需要添加签名吗?
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=%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"
}
}- SUCCESS:支付成功。
- FAIL:支付失败。
- PROCESSING:支付处理中。
- CANCELLED:支付已被取消。
常见问题
问:我应该多久调用一次支付结果查询接口?
问:在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
- result:表示 inquiryPayment 接口调用的结果,需要根据 paymentStatus 来判断订单状态:
- SUCCESS:支付成功。
- FAIL:支付失败。
- PROCESSING:支付处理中。
- CANCELLED:支付已被取消。
- paymentAmount:表示支付的金额。
支付后操作
完成支付后,您可对交易进行以下支付后的操作:
取消交易
取消授权
买家完成授权后,您需在商户侧提供授权协议取消功能,原因如下:
- 保障买家对其授权协议的自主管理权,允许买家根据个人账户安全策略或服务使用需求,随时终止已建立的授权关系。
- 由于部分支付方式存在系统级限制,同一电子钱包账户在单一商户维度仅允许维持一个或者少量有效授权凭证。
退款
对账
最佳实践
支付方式特性
以下表格展示不同支付方式在完成授权后是否会返回买家的登录 ID(userLoginID),以及返回的 ID 格式示例: