APM 支付
收银台支付服务为您的网站和应用程序提供全方位的支付解决方案,支持桌面浏览器、移动浏览器等多场景无缝对接。通过一次性集成即可快速接入多种在线支付方式,包括电子钱包、网银转账和银行卡支付等,有效降低技术门槛。您可以根据个人偏好选择便捷安全的支付方式,享受更优质的支付体验。
用户体验
以下为各类支付方式的用户体验:
一种基于独立账户体系的电子支付解决方案。通过电子钱包账户,买家可轻松完成线上购物或线下消费支付,实现高效、安全、便捷的支付体验。
支付流程
各类支付方式的支付流程由以下集成步骤组成:
- 买家进入结账页面。
- 创建支付请求。
买家选择支付方式并提交订单后,商户服务端根据支付方式、金额、币种、商品等交易信息,调用 支付(收银台)接口以发起支付请求。 - 处理支付推进链接。
商户客户端跳转至支付请求返回的 URL 页面,或唤起相关应用程序完成支付。支付推进链接根据支付方式的特性执行不同的操作,如收集信息、重定向买家、调用应用、显示二维码和进行验证。 - 获取支付结果。
商户服务端接收 Antom 服务端返回的支付结果通知,并根据结果进行相应的业务处理。通过以下两种方法之一获取支付结果:
支付集成
开始集成,请按照以下步骤操作:
- 添加支付方式列表
- 创建支付订单
- 获取跳转支付推进链接
- 接收异步通知
步骤 1:添加支付方式列表
在买家下单页面的支付方式列表中,展示本次需要集成的支付方式标识和名称,供买家根据自身需求和偏好选择。
您可以通过以下两种方式获取标识和名称:
- 自助获取:可通过品牌资产自助获取支付方式的标识和名称。如遇部分支付方式无法在线获取,请联系 Antom 技术支持协助获取。
- 调用 咨询 接口:根据币种、交易发起终端类型、买家所在地区以及已签约的支付方式,获取当前交易支持的支付方式和标识链接(logoUrl)。
注意:
- 支付方式列表页面需要由您自行实现。
- 如果您选择自主获取支付方式的标识和名称,可跳过以下步骤,直接跳转至步骤 2:创建支付订单继续集成流程。
Antom 提供了多种语言的服务器端接口库。以下代码以 Java 为例,其他语言请集成 Antom SDK。
1. 安装接口库
您可以在 GitHub 上找到最新版本。
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>{latest_version}</version>
</dependency>
2. 初始化请求实例
创建一个单例资源以向 Antom 发起请求。
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. 创建支付咨询请求
支付咨询请求包含以下关键参数。
参数名称 | 是否必需? | 描述 |
productCode | 是 | 此场景下该字段固定为 |
paymentFactor.presentmentMode | 是 | 此场景下该字段固定为 |
paymentAmount | 是 | 支付金额,需按下单币种的最小单位设置。 |
settlementStrategy.settlementCurrency | 是 | 该笔支付的结算币种,若业务签约了多个结算币种,需在接口中指定。 |
env.terminalType | 是 | 买家发起交易的环境:
|
有关完整参数的更多信息,请参阅 咨询 接口。
以下代码为调用 咨询 接口的示例:
public static void executeConsult() {
AlipayPayConsultRequest alipayPayConsultRequest = new AlipayPayConsultRequest();
alipayPayConsultRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// 设置 amount
Amount amount = Amount.builder().value("4200").currency("USD").build();
alipayPayConsultRequest.setPaymentAmount(amount);
// 设置 env 信息
Env env = Env.builder().terminalType(TerminalType.WEB).build();
alipayPayConsultRequest.setEnv(env);
AlipayPayConsultResponse alipayPayConsultResponse = null;
try {
alipayPayConsultResponse = CLIENT.execute(alipayPayConsultRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// 处理错误情况
}
}
以下代码显示了请求报文的示例:
{
"env": {
"terminalType": "WEB"
},
"paymentAmount": {
"currency": "USD",
"value": "30000"
},
"settlementStrategy": {
"settlementCurrency": "USD"
},
"paymentFactor": {
"presentmentMode": "TILE"
},
"productCode": "CASHIER_PAYMENT"
}
响应代码中涉及以下关键参数。
参数名称 | 描述 |
result.resultStatus | 指 咨询 接口的调用状态。 |
paymentOptions.enabled | 用于判断支付方式是否可用。 |
paymentOptions.logo.logoName | 支付方式的标识名称。 |
paymentOptions.logo.logoUrl | 支付方式的标识链接。 |
以下代码显示了响应报文的示例:
{
"paymentOptions": [
{
"enabled": true,
"logo": {
"logoName": "FPX",
"logoUrl": "https://resource.alipayplus.com/storage/ipaymentmngfd5e514400714344/2024/06/13/e08cb444-be0d-45b9-8a8d-44966aad5825.png"
},
"paymentMethodCategory": "ONLINE_BANKING",
"paymentMethodRegion": [
"MY"
],
"paymentMethodType": "ONLINEBANKING_FPX",
"preferred": false
},
{
"disableReason": "CURRENT_CHANNEL_NOT_EXIST",
"enabled": false,
"logo": {
"logoName": "Bank of Ayudhya Online Banking",
"logoUrl": "https://gw.alipay.com/antom/icon/medium/default/BankofAyutthaya.svg"
},
"paymentMethodCategory": "ONLINE_BANKING",
"paymentMethodRegion": [
"TH"
],
"paymentMethodType": "ONLINEBANKING_BANKOFAYUDHYA",
"preferred": false
}
],
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
下表展示了响应代码中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
result.resultStatus | 信息 | 后续操作 |
| 调用成功。 | 当 paymentOptions.enabled 为 |
| 调用失败。 | 请参考错误码进行下一步操作。 |
| 未知原因。 | 若返回 |
注意:如果您未收到响应报文,可能是网络超时所致,请重新调用接口以解决问题。
下图展示了添加支付方式后的页面效果:
常见问题
问:什么是 allowedPaymentMethodRegions?
答:指支付方式所属国家或地区的代码列表,此参数的值为二位字母的 ISO 3166 国家代码或
GLOBAL
。若不传入该值,将全量返回支持的所有支付方式列表。若传入HK
,则会以白名单形式生效,仅返回中国香港地区支持的支付方式列表。问:什么是 userRegion?
答:指买家所在国家或地区的代码,请参阅 ISO 3166 国家代码标准了解更多信息。若不传入该值,不会影响支付方式列表的筛选,仅起到排序功能。若传入
HK
,则会将中国香港地区的支付方式在返回列表中以高优先级排序。
步骤 2:创建支付订单
调用 支付(收银台)接口,您需要收集买家的支付方式、订单信息、设备信息、支付金额等提交支付请求。
注意:如果您在步骤 1 中选择通过 调用 API 接口 方式添加支付方式列表,表示已安装接口库和发送初始化请求。此时您无需再次操作,可直接跳转至创建支付请求继续集成流程。
Antom 提供了多种语言的服务器端接口库。以下代码以 Java 为例,其他语言请集成 Antom SDK。
1. 安装接口库
您可以在 GitHub 上找到最新版本。
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>{latest_version}</version>
</dependency>
2. 初始化请求实例
创建一个单例资源以向 Antom 发起请求。
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. 创建支付请求
支付请求包含以下关键参数。
参数名称 | 是否必需? | 描述 |
productCode | 是 | 在此场景中,该字段设置为 CASHIER_PAYMENT 。 |
paymentRequestId | 是 | 商户生成的专属 ID。 |
paymentAmount | 是 | 支付金额,以支付货币的最小单位设置。 |
paymentMethod | 是 | 支付方式枚举值。 |
paymentRedirectUrl | 是 | 商户端支付结果页,需根据服务端结果展示,非固定为成功页。 |
paymentNotifyUrl | 否 | 支付结果通知地址,可通过接口指定或在门户上设置固定值。 |
settlementStrategy | 是 | 支付请求的结算策略。如果您签署了多个结算货币,需要在接口中指定。 |
order | 是 | 包括订单金额、订单 ID 和订单描述的订单信息。 |
env.terminalType | 是 | 买家发起交易的环境:
|
env.osType | 否 | 买家发起交易的环境。当在商户手机浏览器网站发起,则 env.osType = |
有关完整参数的更多信息,请参阅 支付(收银台)接口。
以下代码为调用 支付(收银台)接口以发起支付请求的示例:
public static void executePayWithCard() {
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setClientId(CLIENT_ID);
alipayPayRequest.setPath("/ams/api/v1/payments/pay");
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// 替换为您的 paymentRequestId
alipayPayRequest.setPaymentRequestId("paymentRequestId01");
// 设置 amount
Amount amount = new Amount();
amount.setCurrency("HKD");
amount.setValue("100");
alipayPayRequest.setPaymentAmount(amount);
// 设置 paymentMethod
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setPaymentMethodType("ALIPAY_HK");
alipayPayRequest.setPaymentMethod(paymentMethod);
// 设置 order 信息
Order order = new Order();
order.setReferenceOrderId("referenceOrderId01");
order.setOrderDescription("antom test order");
order.setOrderAmount(amount);
alipayPayRequest.setOrder(order);
//设置 env 信息
Env env = new Env();
env.setTerminalType(TerminalType.WAP);
env.setClientIp("114.121.121.01");
env.setOsType(OsType.ANDROID);
alipayPayRequest.setEnv(env);
// 替换为您的 notifyUrl
alipayPayRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");
// 替换为您的 redirectUrl
alipayPayRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");
//进行支付
AlipayPayResponse alipayPayResponse = null;
try {
alipayPayResponse = defaultAlipayClient.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// 处理错误情况
}
}
以下代码显示了请求报文的示例:
{
"paymentNotifyUrl": "http://www.yourNotifyUrl.com",
"paymentRequestId": "paymentRequestId01",
"env": {
"terminalType": "WAP",
"clientIp": "114.121.121.01",
"osType": "ANDROID"
},
"paymentAmount": {
"currency": "HKD",
"value": "100"
},
"productCode": "CASHIER_PAYMENT",
"paymentRedirectUrl": "http://www.yourRedirectUrl.com",
"paymentMethod": {
"paymentMethodType": "ALIPAY_HK"
},
"order": {
"orderAmount": {
"currency": "HKD",
"value": "100"
},
"referenceOrderId": "referenceOrderId01",
"orderDescription": "antom test order"
}
}
响应代码中涉及以下关键参数。
参数名称 | 描述 |
result.resultStatus | 指 支付(收银台)接口的调用状态。 |
normalUrl | 将买家跳转到默认浏览器或嵌入式 WebView 中的 WAP 或 WEB 页面的链接。 |
applinkUrl | 将买家跳转到已安装的目标应用中,或未安装目标应用的 WAP 页面中的链接。 |
schemeUrl | 在 Android 或 iOS 系统中,应用安装完成后,将买家跳转到应用的 URL scheme。 |
以下代码显示了响应报文的示例:
{
"appIdentifier": "my.com.myboost",
"applinkUrl": "https://myboost.app.link/IvWm7QZkfjb?%24fallback_url=https%3A%2F%2Fmsp.boost-my.com%2Fonlinepayment%2Fauthorise&source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A",
"normalUrl": "https://msp.boost-my.com/onlinepayment/authorise?source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A",
"orderCodeForm": {
"codeDetails": [
{
"codeValue": "https://global.alipay.com/281002040098ZClz8ZTk46JEsh1jzyU3zx0A",
"displayType": "TEXT"
},
{
"codeValue": "https://global.alipay.com/merchant/order/showQrImage.htm?code=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A&picSize=L",
"displayType": "BIGIMAGE"
},
{
"codeValue": "https://global.alipay.com/merchant/order/showQrImage.htm?code=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A&picSize=M",
"displayType": "MIDDLEIMAGE"
},
{
"codeValue": "https://global.alipay.com/merchant/order/showQrImage.htm?code=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A&picSize=S",
"displayType": "SMALLIMAGE"
}
],
"expireTime": "2025-04-03T01:18:36-07:00"
},
"paymentActionForm": "{\"method\":\"GET\",\"paymentActionFormType\":\"RedirectActionForm\",\"redirectUrl\":\"https://myboost.app.link/IvWm7QZkfjb?%24fallback_url=https%3A%2F%2Fmsp.boost-my.com%2Fonlinepayment%2Fauthorise&source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A\"}",
"paymentAmount": {
"currency": "MYR",
"value": "230"
},
"paymentCreateTime": "2025-04-03T01:04:37-07:00",
"paymentData": "{\"codeValue\":\"https://global.alipay.com/281002040098ZClz8ZTk46JEsh1jzyU3zx0A\",\"displayPaymentAmount\":\"2.30\",\"displayPaymentCurrency\":\"MYR\",\"wallets\":[{\"enabled\":true,\"redirectionInfo\":{\"appIdentifier\":\"my.com.myboost\",\"applinkUrl\":\"https://myboost.app.link/IvWm7QZkfjb?%24fallback_url=https%3A%2F%2Fmsp.boost-my.com%2Fonlinepayment%2Fauthorise&source=alipay-connect&codeValue=${codeValue}\",\"normalUrl\":\"https://msp.boost-my.com/onlinepayment/authorise?source=alipay-connect&codeValue=${codeValue}\",\"schemeUrl\":\"boostapp://inAppDeeplink?deeplink_path=deeplink/onetimepayment&source=alipay-connect&codeValue=${codeValue}\"},\"walletBrandName\":\"Boost\",\"walletLogo\":{\"logoName\":\"BOOST\",\"logoUrl\":\"https://gw.alipay.com/icon/large/rectangle/BOOST.png\"},\"walletName\":\"BOOST\"}]}",
"paymentId": "20250403194010800100188550285911975",
"paymentRequestId": "PAY_20250403160436230",
"redirectActionForm": {
"method": "GET",
"redirectUrl": "https://myboost.app.link/IvWm7QZkfjb?%24fallback_url=https%3A%2F%2Fmsp.boost-my.com%2Fonlinepayment%2Fauthorise&source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A"
},
"schemeUrl": "boostapp://inAppDeeplink?deeplink_path=deeplink/onetimepayment&source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040098ZClz8ZTk46JEsh1jzyU3zx0A",
"result": {
"resultCode": "PAYMENT_IN_PROCESS",
"resultMessage": "payment in process",
"resultStatus": "U"
}
}
下表展示了响应代码中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
result.resultStatus | 信息 | 后续操作 |
| 支付成功。 | 无需进一步操作。 |
| 支付失败。 | 关闭当前交易订单或重新更换 paymentRequestId 后再次发起支付请求。 |
| 未知原因。 |
|
注意:如果您未收到响应报文,可能是网络超时所致。关闭当前交易订单或重新更换 paymentRequestId 后再次发起支付请求。
常见问题
问:如何确认响应代码中需要消费的 URL 类型?
答:不同支付方式在不同端类型下,Antom 可能会返回以下三种 URL 中的一种或多种:normalUrl、applinkUrl 和 schemeUrl。商户服务端需将这些 URL 传递给商户前端,可以选择任选一种 URL 进行跳转消费。
问:什么是 paymentId?
答:如果您需要存储相应的订单 ID 以备后续退款和对账,可以指定 paymentId。
问:如何设置 terminalType?
答:terminalType 的有效值为:
- 如果买家在 PC 端发起交易,需要将 terminalType 指定为
WEB
。- 如果买家在移动浏览器上发起交易,需要将 terminalType 指定为
WAP
。添加 osType 参数,并根据买家的手机填写相应的系统参数ANDROID
或IOS
。- 如果买家在应用内发起交易,需要将 terminalType 指定为
APP
。
步骤 3:获取跳转支付推进链接
商户服务端拿到 Antom 返回的支付推进链接后,将该地址传递给前端,由商户前端跳转至支付方式页面。不同类型的支付推进链接如下表所示:
类型 | 描述 | 示例 URL |
normalUrl | 一个 HTTPS 地址的链接,用于在同一浏览器页面上重定向到支付方式的网站页面。 | URL=serverResponse.normal |
applinkUrl | 在支付过程中用于重定向的 Android App Link 或 iOS Universal Link。 | URL=serverResponse.applink |
schemeUrl | 用于打开支付方式应用的 URL scheme。 | URL=serverResponse.scheme |
请参阅支付推进链接了解更多内容。
以下为商户前端加载支付推进链接的示例代码:
if (URL != null) {
window.open(URL, '_blank');
}
下图展示支付方式收银台页面的效果:
不同支付方式在不同终端会返回不同的支付推进链接,Antom 基于您传入的 paymentMethod 和 terminalType 决策返回不同的支付推进链接。下表列举了不同终端返回的支付推进链接类型及其用户体验。关于具体的不同支付方式返回的支付推进链接内容,请参阅支付方式返回链接了解更多详情。
支付推进链接类型 | 功能 | 用户体验 |
applinkUrl |
|
|
schemeUrl |
|
|
normalUrl |
|
|
您在 支付(收银台)接口中指定的 paymentRedirectUrl 字段提供了一个 HTTPS 地址,该地址用于在商户端页面显示支付结果。以下为您的支付结果页面示例:
常见问题
问:如何处理不同的支付体验?
答:您无需处理不同支付方式的不同体验,只需通过前端页面重定向到 normalUrl。不同的支付体验由 normalUrl 负责完成渲染和支付流程。
问:如何展示支付结果页内容?
答:在支付成功和失败的情况下,可能都有入口可以从支付方式端回跳到商户页面。为避免引起误解,请以服务端返回的结果为准,不要将 paymentRedirectUrl 固定为“支付成功页面”。如果从 App 端发起交易,paymentRedirectUrl 需设置为商户应用程序的 scheme 地址。
问:回跳至商户结果页面是否代表支付成功?
答:不能仅凭回跳至商户页面来判断支付是否成功,可能存在以下情况导致回跳商户页失败:
- 买家支付成功后,可能因网络等原因导致未能回跳至商户页面。
- 当买家未完成支付时,也可能通过支付方式端的入口回跳至商户页面。
- Antom 不会在 paymentRedirectUrl 拼接表示支付结果的字段信息。
步骤 4:接收异步通知
完成支付或支付失败时,Antom 会通过 支付(收银台)接口中的参数 paymentNotifyUrl 指定的地址发送异步通知(支付通知)。
- 您可以选择以下两种方法中的一种来设置接收通知的地址:
- 若您的每个订单都有单独的通知 URL,建议在每笔请求中设置通知 URL。您可以通过 支付(收银台)接口请求的 paymentNotifyUrl 字段中传入该笔订单的异步通知接收地址。
- 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置通知 URL。具体操作请参阅通知地址。
支付通知中涉及以下关键参数:
参数名称 | 是否必需? | 描述 |
resultStatus | 是 | 表示订单支付结果的状态。 |
paymentRequestId | 是 | 商户发起支付的唯一 ID。 |
paymentAmount | 是 | 表示支付金额。 |
有关完整参数的更多信息,请参阅 支付通知。
以下代码显示了请求报文的示例:
{
"notifyType": "PAYMENT_RESULT",
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
},
"paymentRequestId": "2020010123456789XXXX",
"paymentId": "2020010123456789XXXX",
"paymentAmount": {
"value": "8000",
"currency": "EUR"
},
"paymentCreateTime": "2020-01-01T12:01:00+08:30",
"paymentTime": "2020-01-01T12:01:01+08:30"
}
下表展示了支付结果的异步通知中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:
result.resultStatus | 信息 | 后续操作 |
| 支付成功。 | 可从中获取以下字段信息:
|
| 支付失败。 | 关闭当前交易订单或更换 paymentRequestId 后再次发起支付请求。 |
注意:完成支付或支付失败时,商户的服务端都会收到异步通知。但当部分失败场景(如参数异常)时,支付(收银台)接口会同步返回
F
,Antom 不会发送异步通知,您可根据返回的F
状态直接关闭订单。
- 当您收到 Antom 的异步通知,需要您在返回中按照示例代码格式返回响应,但无需做加签处理。
您需要按照以下方法对 Antom 发送的支付通知进行验签:
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;
@RestController
public class PaymentNotifyHandleBySDK {
/**
* alipay public key, used to verify signature
*/
private static final String SERVER_PUBLIC_KEY = "";
/**
* payment result notify processor
* using <a href="https://spring.io">Spring Framework</a>
*
* @param request HttpServletRequest
* @param notifyBody notify body
* @return
*/
@PostMapping("/payNotify")
public Object payNotifyHandler(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");
Result result;
AlipayResponse response = new AlipayResponse();
try {
// 验证通知的签名
boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
if (!verifyResult) {
throw new RuntimeException("Invalid notify signature");
}
// 反序列化通知内容
// 根据通知结果更新订单状态
// 响应服务器以表示已收到通知
result = new Result("SUCCESS", "success", ResultStatusType.S);
} catch (Exception e) {
String errorMsg = e.getMessage();
// 处理错误情况
result = new Result("ERROR", errorMsg, ResultStatusType.F);
}
response.setResult(result);
return ResponseEntity.ok().body(response);
}
}
无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
}
}
常见问题
问:何时会发送支付结果通知?
答:这取决于支付是否完成:
- 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。对于某些支付方式,如现金支付,通知可能会稍有延迟。
- 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。
问:异步通知会被重新发送吗?
答:是的,对于以下情况,异步通知会在 24 小时内自动重新发送:
- 如果由于网络原因未收到异步通知。
- 如果您收到来自 Antom 的异步通知,但您没有按照处理通知的示例代码格式对通知做出响应。
通知最多可以重发 8 次,或者直到收到正确的响应以终止发送。发送间隔如下:0 分钟、2 分钟、10 分钟、10 分钟、1 小时、2 小时、6 小时和15 小时。
问:在响应异步通知时,我需要加签吗?
答:如果您收到来自 Antom 的异步通知,您需要按照处理通知的示例代码格式返回响应,但不需要对响应进行签名。
问:收到支付结果通知后是否需要验签?
答: 需要。为确保回调请求确实由 Antom 发送,在验签时需要进行验证。在拼装待验签的报文时,必须按照以下标准顺序处理:
<http-method> <http-uri> <client-id>.<request-time>.<request-body>
。请注意拼装request-body
时应直接取其原始值,而不要解析成 JSON 后再拼装。
支付后操作
以下内容将介绍支付后如何通过服务端主动查询交易状态、发起交易取消以及退款操作的具体方法,帮助您实现稳定可靠的支付管理体验。
查询交易
Antom 提供发送异步通知的功能,同时也支持主动查询支付结果。调用 支付结果查询 接口,通过以下参数查询支付结果:
参数名称 | 是否必需? | 描述 |
paymentRequestId | 否 | 商户生成的支付请求 ID。 |
有关完整参数的更多信息,请参阅 支付结果查询 接口。
以下为调用 支付结果查询 接口的代码示例:
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();
// 处理错误情况
}
}
以下为请求示例:
{
"paymentRequestId": "REQUEST_20250327164938236"
}
以下为响应的代码示例:
{
"actualPaymentAmount": {
"currency": "THB",
"value": "299"
},
"paymentAmount": {
"currency": "THB",
"value": "299"
},
"paymentId": "20250217194010800100188760278262487",
"paymentMethodType": "TRUEMONEY",
"paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
"paymentRequestId": "3IOS47F3C9B7D96",
"paymentResultCode": "SUCCESS",
"paymentResultMessage": "success.",
"paymentStatus": "SUCCESS",
"paymentTime": "2025-02-17T08:06:43-08:00",
"pspCustomerInfo": {
"pspName": "TRUEMONEY"
},
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
请根据响应中的 paymentStatus 字段进行处理:
paymentStatus | 描述 | 后续操作 |
| 支付成功。 | 无需后续操作。 |
| 支付失败。 | 关闭订单或更换 paymentRequestId 再次发起请求。 |
| 支付进行中。 | 建议等待一段时间后继续查询状态或关闭订单再重新查询。 |
常见问题
问:调用 支付结果查询 接口时应该消费哪些字段?
答:请注意以下关键参数:
- result:表示此 支付结果查询 接口调用的结果,需要根据 paymentStatus 来判断订单状态:
SUCCESS
和FAIL
表示最终结果。PROCESSING
表示处理中。
- paymentAmount:表示支付的金额。
问:发起查询的推荐间隔是多久?
答:推荐以轮询的形式调用 支付结果查询 接口,间隔 2 秒,直到获取最终的支付结果或收到异步支付结果通知为止。
取消交易
对于支付成功后的订单,如果买家在当天内申请取消订单或退款,您可以通过 Antom 提供的取消支付能力将订单状态取消或解冻。此外,对于尚未完成支付的订单,您也可以直接进行取消。请参阅取消交易了解关于取消支付集成方案的更多内容。
退款
在支付成功后,您可以通过以下两种方法发起退款:
- 调用接口:您可以通过调用 退款 接口对成功支付的交易发起退款。
- 使用 Antom Dashboard 退款:关于如何发起退款并查看退款结果,请参阅发起退款。
Antom 支持的退款能力如下:
- 支持全额退款。
- 支持部分多次退款,多次退款的总金额需小于等于请款金额。
请参阅退款了解关于退款集成方案的更多内容。
最佳实践
为了提高集成效率,Antom 为您提供客户端优化、回跳商户页展示、支付失败重试、接口超时时间设置、中间页优化等最佳实践方案,请参阅最佳实践了解详情。
支付方式特性
本部分内容旨在系统阐述各类支付方式在支持特性方面的差异。
取消交易能力
不同支付方式的取消交易窗口期有差异,请参阅取消交易了解详情。
退款能力
不同支付方式的退款能力不同,主要为能否支持退款和支持退款的周期。请参阅支持的支付方式,了解更多关于退款能力的内容。
默认关单时间
请参阅默认关单时间,了解更多关于支付方式支持的关单详情。
集成要点
以下为不同支付方式的集成要点及建议方案。
支付方式 | 要点 | 建议方案 |
PayPay |
| paymentRedirectUrl 字段长度不要超过 255 字符。 |
QRIS | 存在单边账情况。 | 调用单边账的 支付结果查询 接口以获取支付结果并提前感知单边账的发生,请联系 Antom 技术支持获取更多内容。 |
PromptPay | 存在单边账情况。 | 调用单边账的 支付结果查询 接口以获取支付结果并提前感知单边账的发生,请联系 Antom 技术支持获取更多内容。 |
Maybank | 支付完成后,会延迟 5 分钟发送异步通知。 | 为买家展示订单确认中的状态提示。 |
OVO/Pix/BANCOMAT Pay | 无法自动拉起钱包。 | 需手动拉起钱包完成支付。 |
Siam Commercial Bank |
| 提示买家可能存在支付手续费(由买家在银行的等级决策收取的费用金额)。 |
Bank of Ayudhya |
| 提示买家可能存在支付手续费(由买家在银行的等级决策收取的费用金额)。 |
GoPay/Bangkok Bank/KrungThai Bank | 不支持 PC 端。 | 无 |
NAVER Pay | PC 客户端需额外集成:买家登录后,支付不会在原页面直接完成,而是自动打开一个新的标签页重定向。 | 开启浏览器弹窗权限,并在代码中通过创建新的 browser 对象(或窗口)打开弹窗页面进行支付处理。 |
Mercado Pago (巴西) | 会消费 buyerEmail 字段从而导致支付直接失败。 | 传入 payerEmail 字段。 |