APM 支付(Web/WAP)
Antom SDK 是一个预构建的用户界面组件,简化了集成 Antom 支付服务的过程。此组件提供了一种简单快捷的方式来集成 Antom 支持的所有支付方式,包括信用卡、数字钱包、银行转账、网上银行等。
SDK 组件可以自动适应买家的设备和位置,根据支付方式的特性执行信息收集、重定向、应用切换、显示二维码等任务。您可以在您的网站或应用上轻松提供全面的支付解决方案,节省构建每个支付界面和流程所需的时间和资源。
用户体验
以下图表展示了在购物网站或移动网页应用上支付的用户流程:
Web用户体验
D SDK
MERCHANT
MERCHANT
四
BANK PAGE
注意:如果您希望为买家提供 Alipay+ 统一支付体验,而不是上述用户体验,请参阅 Alipay+ 统一支付收银台,并联系Antom 技术支持获取更多集成详情。
支付流程
每种支付方式的支付流程包括以下步骤:
- 买家进入结账页面。
- 创建支付会话请求。
买家选择支付方式并提交订单后,您可以通过调用 支付会话创建(收银台)接口获取支付会话。 - 调用客户端SDK。
在客户端,通过支付会话调用 SDK。SDK 会根据支付方式的特性处理信息收集、重定向、应用调用、二维码显示、验证等流程。 - 获取支付结果。
通过以下两种方法之一获取支付结果:
- 异步通知:在 支付会话创建(收银台)接口中设置 paymentNotifyUrl 字段,以指定接收异步通知的地址。当支付成功或过期时, Antom 会使用 支付通知 向您发送异步通知。
- 同步查询:调用 支付结果查询 接口来查询支付状态。
集成步骤
开始集成,请按照以下步骤开始集成:
- 创建支付会话
- 创建并调用 SDK
- 获取支付结果
步骤 1:创建支付会话
当买家选择 Antom 提供的支付方式时,您需要收集关键信息,如支付请求 ID、订单金额、支付方式、订单描述、支付重定向链接和支付结果通知链接,调用 支付会话创建(收银台)接口来创建支付会话,并将支付会话返回给客户端。
Antom 提供了多种语言的服务器端接口库。以下代码以 Java 为例,您需要安装 Java 6 或更高版本。
安装接口库
您可以在 GitHub 上找到最新版本。
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>2.0.36</version>
</dependency>
初始化请求实例
创建一个单例资源以向 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);
}
创建支付会话
创建支付会话包括以下参数:
参数名称 | 是否必需 | 描述 |
productCode | ✅ | 值设置为 |
paymentRequestId | ✅ | 由商户生成的专属 ID,每次发起支付时需使用新的 ID。 |
paymentAmount | ✅ | 支付金额,应根据订单货币的最小单位设置,例如, |
paymentMethod | ✅ | 支付方式枚举 |
paymentRedirectUrl | ✅ | 商户的支付结果页面,根据服务器端的结果,不是一个固定的成功页面。 |
order | ✅ | 订单信息,包括订单金额、商户订单 ID 和订单描述。 |
paymentNotifyUrl | 支付结果通知地址,可通过接口传递,也可通过门户设置为固定值。 | |
settlementStrategy | 支付的结算货币,如果业务签约了多个结算货币,需要在接口中指定。 |
以上参数是创建支付会话的基本参数,完整参数和特定支付方式的额外要求请参考 支付会话创建(收银台)。
调用支付会话创建接口的示例代码
以下示例代码展示了如何调用 支付会话创建(收银台)接口:
private static void createPaymentSession() {
AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);
// set amount
Amount amount = Amount.builder().currency("SGD").value("4200").build();
alipayPaymentSessionRequest.setPaymentAmount(amount);
// set paymentMethod
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("SHOPEEPAY_SG").build();
alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);
// replace with your orderId
String orderId = UUID.randomUUID().toString();
// set buyer info
Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();
// set order info
Order order = Order.builder().referenceOrderId(orderId)
.orderDescription("antom testing order").orderAmount(amount).buyer(buyer).build();
alipayPaymentSessionRequest.setOrder(order);
// replace with your notify url
alipayPaymentSessionRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");
// replace with your redirect url
alipayPaymentSessionRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");
AlipayPaymentSessionResponse alipayPaymentSessionResponse = null;
try {
alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
}
以下代码显示了一个请求报文的示例:
{
"order": {
"buyer": {
"referenceBuyerId": "yourBuyerId"
},
"orderAmount": {
"currency": "SGD",
"value": "4200"
},
"orderDescription": "antom testing order",
"referenceOrderId": "referenceOrderId01"
},
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentMethod": {
"paymentMethodType": "SHOPEEPAY_SG"
},
"paymentNotifyUrl": "https://www.yourNotifyUrl.com",
"paymentRedirectUrl": "https://www.yourMerchantWeb.com",
"paymentRequestId": "paymentRequestId01",
"productCode": "CASHIER_PAYMENT"
}
以下代码显示了一个响应的示例,其中包含以下参数:
- paymentSessionData:将返回给前端的支付会话数据
- paymentSessionExpiryTime:支付会话的过期时间。
{
"paymentSessionData": "gM5Y/Go6+IXMPSOZrYtukCdodtwxuSFsn1vRPSB8CzkDqlb1g2W7dDipOkoMRs/x2W7g7qVhjEM7RUGroIT8Cw==&&SG&&188&&eyJhY3Rpb24iOnsiYXBwIjp7fSwibmVlZFZlcmlmeUFuZFJlc3VtZSI6ZmFsc2UsInNraXBTZGtRdWVyeSI6ZmFsc2UsIndhcCI6e30sIndlYiI6e319LCJjbGllbnRJZCI6IlNBTkRCT1hfNVlCWjBMMlpIUjhSMDg5NzgiLCJleHRlbmRJbmZvIjoie1widmVyc2lvbk1hcFwiOntcIndlYlwiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcImlPU1wiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcIkFuZHJvaWRcIjp7XCIxLjEuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMS4wXCJ9LFwiMS4yLjBcIjp7XCJ0YXJnZXRXZWJWZXJpc29uXCI6XCIxLjIuMFwifX19fSIsInBheW1lbnRTZXNzaW9uQ29uZmlnIjp7InBheW1lbnRNZXRob2RDYXRlZ29yeVR5cGUiOiJBUE0iLCJwcm9kdWN0U2NlbmUiOiJDQVNISUVSX1BBWU1FTlQiLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn19",
"paymentSessionExpiryTime": "2024-01-01T00:00:00+08:00",
"paymentSessionId": "gM5Y/Go6+IXMPSOZrYtukCdodtwxuSFsn1vRPSB8Czn6HfgqNzo2ogbIk1NUQS35",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
常见问题
问:请求参数的值可以使用中文字符吗?
答:为了避免特定支付方式的兼容性问题,请求中的字段请勿使用中文字符。
问:如何设置接收支付通知的链接?
答:在 支付会话创建(收银台)接口中指定 paymentNotifyUrl 字段,以接收支付结果的异步通知(支付通知),或者在 Antom Dashboard 中配置接收链接。如果请求和 Antom Dashboard 中都指定了链接,请求中的值优先。
步骤 2:创建并调用 SDK
Antom SDK 是用于处理支付流程的组件。为了收集信息、在应用间切换以及根据 支付会话创建(收银台)接口中指定的支付方式显示二维码,您需要通过创建支付会话来启动 SDK。
买家在页面上选择支付方式后,您需要创建并使用支付会话初始化 SDK。
安装
在开始集成之前,请确保已完成以下环境准备:
- 处理兼容性问题:为 Internet Explorer 和其他旧版浏览器提供相应的 polyfills。建议在构建项目时使用 babel-preset-env 来解决浏览器兼容性问题。
- 使用以下推荐的浏览器版本:
- 对于移动浏览器:
- iOS 11 及以后版本。
- Android 5.0 及以后版本。
- 对于电脑浏览器,推荐使用以下版本:
请查阅 Web/WAP 端集成 SDK 资源包文档来集成 SDK 资源包。
初始化 SDK
通过使用AMSCashierPayment
并指定基础配置来创建 SDK 实例。配置对象包括以下参数:
参数名称 | 是否必需 | 描述 |
environment | ✅ | 用于传递环境信息。有效值为:
|
locale | 用于传递语言信息。有效值如下所示。您可以根据支付方式的地区选择要传递的值。如果传递其他值,默认使用本地语言:
| |
analytics | 用于配置和分析数据。它包含以下值:
| |
onLog | 这是一个回调方法,用于生成 SDK 执行期间的日志错误信息和接口 异常。 | |
onEventCallback | 一个回调函数,在 SDK 运行期间,当发生支付事件(如支付结果或表单提交错误)时返回特定的事件代码。有关更多信息,请参阅参考资料。 |
以下示例代码展示了如何获取浏览器语言:
let language = navigator.language || navigator.userLanguage;
language = language.replace("-", "_"); // Replace "-" with "_"
以下示例代码展示了如何实例化 SDK:
// import { AMSCashierPayment } from '@alipay/ams-checkout'
const checkoutApp = new window.AMSCashierPayment({
environment: "sandbox",
locale: "en_US",
onLog: ({code, message}) => {},
onEventCallback: ({code, message}) => {},
});
//Request the server to get paymentSessionData
调用 SDK
使用实例对象中的 createComponent
函数来创建支付组件:
参数名称 | 是否必需 | 描述 |
sessionData | ✅ | 使用 sessionData 参数创建配置对象:将通过 支付会话创建(收银台)接口在响应中获取的完整 paymentSessionData 参数传递给 sessionData 。 |
appearance | 自定义外观主题配置,包含以下子参数:
|
以下示例代码展示了如何调用createComponent
:
async function create(sessionData) {
await checkoutApp.createComponent({
sessionData: sessionData,
appearance:{
showLoading: true, // Set as true by default to enable the default loading pattern
}
});
}
在以下情况下调用unmount
方法以释放 SDK 组件资源:
- 当买家切换视图离开支付页面时,释放 支付会话创建(收银台)中创建的组件资源。
- 当买家发起多次支付时,释放之前 支付会话创建(收银台)中创建的组件资源。
- 当买家完成支付并设置 notRedirectAfterComplete 为
true
时,获取特定支付结果代码释放组件资源。
// Free SDK component resources
checkoutApp.unmount();
常见问题
问:遇到 SDK_CREATEPAYMENT_PARAMETER_ERROR 时该怎么办?
答:收到此事件代码时,请检查传递的 sessionData 是否正确且完整。
问:遇到 SDK_PAYMENT_ERROR 或渲染视图错误时该怎么办?
答:检查接口初始化时的网络请求是否出现异常,如网络超时。确保创建支付会话请求的环境与 SDK 实例化时的环境一致。检查 支付会话创建(收银台)接口中的参数传递是否正确。如果接口异常持续存在,请联系我们进行进一步的故障排除。
显示支付结果
您可以使用支付组件处理需要重定向的支付方式(异步支付)和不需要的(同步支付)。
重定向支付
某些支付方式的支付过程需要离开原网页,跳转到机构页面完成支付,例如网银支付。在这种情况下,买家在完成支付后会被重定向到您在 支付会话创建(收银台)接口中提供的 paymentRedirectUrl 。您可以通过主动查询获取支付结果,并在该链接上向买家展示。
非重定向支付
对于不需要跳转的支付,支付结果将通过 onEventCallback
函数给出。这里的支付结果仅用于前端显示,最终订单状态以服务器端为准。您需要通过 onEventCallback
返回的数据自定义每个支付结果的处理流程。
以下是由 onEventCallback
返回的支付结果可能的事件代码。
事件代码 | 消息 | 解决方案 |
SDK_PAYMENT_SUCCESSFUL | 支付成功。 | 建议将 买家重定向到支付结果页面。 |
SDK_PAYMENT_PROCESSING | 支付正在处理中。 | 建议您检查在 |
SDK_PAYMENT_FAIL | 支付失败。 | 建议您检查在 |
SDK_PAYMENT_CANCEL | 买家在未提交订单的情况下退出了支付页面。 | 在有效期内,可以使用 paymentSessionData 重新调用SDK;如果已过期,需要重新请求paymentSessionData。 |
SDK_PAYMENT_ERROR | 支付状态异常。 | 建议您检查在 |
以下示例代码展示了如何处理onEventCallback
:
function onEventCallback({ code, result }) {
switch (code) {
case 'SDK_PAYMENT_SUCCESSFUL':
// Payment was successful. Redirect buyers to the payment result page.
break;
case 'SDK_PAYMENT_PROCESSING':
console.log('Check the payment result data', result);
// Payment was being processed. Guide buyers to retry the payment based on the provided information.
break;
case 'SDK_PAYMENT_FAIL':
console.log('Check the payment result data', result);
// Payment failed. Guide buyers to retry the payment based on the provided information.
break;
case 'SDK_PAYMENT_CANCEL':
// Guide buyers to retry the payment.
break;
case 'SDK_PAYMENT_ERROR':
console.log('Check the payment result data', result);
// The payment status was abnormal. Guide buyers to retry the payment based on the provided information.
break;
default:
break;
}
}
步骤 3:获取支付结果
在买家完成支付或支付超时后, Antom 会通过服务器交互将相应的支付结果发送给您,您可以通过以下方法之一获取支付结果:
- 接收异步通知
- 查询结果
接收异步通知
当支付成功或失败时,Antom会向您在 支付会话创建(收银台)接口的 paymentNotifyUrl 参数中指定的地址发送异步通知(支付通知)。收到 Antom 的通知后,您需要按照返回收到确认信息返回响应。
Antom允许您在 支付会话创建(收银台)接口的 paymentNotifyUrl 参数中指定链接。如果每个支付的地址相同,您也可以在 Antom Dashboard 中配置该地址。
以下代码展示了通知请求的示例:
{
"notifyType": "PAYMENT_RESULT",
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
},
"paymentRequestId": "paymentRequestId01",
"paymentId": "20240101123456789XXXX",
"paymentAmount": {
"value": "4200",
"currency": "SGD"
},
"paymentCreateTime": "2024-01-01T00:00:00+08:00",
"paymentTime": "2024-01-01T00:01:00+08:00"
}
如何验证通知的签名并做出响应,请参阅签名与验签。
常见问题
问:何时会发送通知?
答:这取决于支付是否完成:
- 如果支付成功完成,Antom 通常会在 3 到 5 秒内发送异步通知。对于某些支付方式,如柜台支付(OTC),通知可能会稍有延迟。
- 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。
问:异步通知会被重新发送吗?
答:是的,对于以下情况,异步通知会在 24 小时内自动重新发送:
- 如果由于网络原因未收到异步通知。
- 如果您收到来自 Antom 的异步通知,但您没有按照处理通知的示例代码格式对通知做出响应。
通知最多可以重发 8 次,或者直到收到正确的响应以终止发送。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时,15 小时。
问:在响应异步通知时,我需要添加数字签名吗?
如果您收到来自 Antom 的异步通知,您需要按照处理通知的示例代码格式返回响应,但不需要对响应进行签名。
问:我在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
- result:表示订单的支付结果。
- paymentRequestId:用于咨询、取消和对账的支付请求 ID。
- paymentId:表示由 Antom 生成的支付订单 ID,用于退款和对账。
- paymentAmount:表示支付金额。
查询结果
您可以调用 支付结果查询 接口来发起对订单结果的查询。
参数名称 | 是否必需 | 描述 |
paymentRequestId | 由商户生成的支付请求 ID。 |
完整的参数集,请参考 支付结果查询 接口文档,获取全部参数及特定支付方式的额外要求。
以下示例代码展示了如何调用 支付结果查询 接口:
public static void inquiryPayment() {
AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();
// replace with your paymentRequestId
alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");
AlipayPayQueryResponse alipayPayQueryResponse = null;
try {
alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
}
以下代码展示了请求报文的示例:
{
"paymentRequestId": "paymentRequestId01"
}
以下代码展示了响应报文的示例:
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success"
},
"paymentStatus": "SUCCESS",
"paymentRequestId": "paymentRequestId01",
"paymentId": "20240101123456789XXXX",
"paymentAmount": {
"value": "4200",
"currency": "SGD"
},
"paymentCreateTime": "2024-01-01T00:00:00+08:00",
"paymentTime": "2024-01-01T00:01:00+08:00",
"paymentMethodType": "SHOPEEPAY_SG"
}
常见问题
答:以 2 秒的间隔持续调用 支付结果查询 接口,直到获取最终的支付结果或收到异步支付结果通知为止。
问:我在通知中需要使用哪些关键参数?
答:请注意以下关键参数:
- result :表示此 支付结果查询 接口调用的结果,需要根据 paymentStatus 来判断订单状态:
SUCCESS
和FAIL
表示最终结果。PROCESSING
表示处理中。
- paymentAmount:表示支付的金额。
示例代码
前端完整示例代码:
// Step 1: Instantiate the SDK and handle the callback event.
const onEventCallback = function({ code, result }) {
switch (code) {
case 'SDK_PAYMENT_SUCCESSFUL':
// Payment was successful. Redirect buyers to the payment result page.
break;
case 'SDK_PAYMENT_PROCESSING':
console.log('Check the payment result data', result);
// Payment was being processed. Guide buyers to retry the payment based on the provided information.
break;
case 'SDK_PAYMENT_FAIL':
console.log('Check the payment result data', result);
// Payment failed. Guide buyers to retry the payment based on the provided information.
break;
case 'SDK_PAYMENT_CANCEL':
// Guide buyers to retry the payment.
break;
case 'SDK_PAYMENT_ERROR':
console.log('Check the payment result data', result);
// The payment status was abnormal. Guide buyers to retry the payment based on the provided information.
break;
default:
break;
}
}
const checkoutApp = new window.AMSCashierPayment({
environment: "sandbox",
locale: "en_US",
onLog: ({code, message}) => {},
onEventCallback: onEventCallback,
});
// Handle payment button events.
document
.querySelector("#your form id")
.addEventListener("submit", handleSubmit);
async function handleSubmit() {
// Step 2: The server calls createPaymentSession API to obtain paymentSessionData.
async function getPaymentSessionData() {
const url = "Fill in the server address";
const config = {
// Fill in the request configuration.
};
const response = await fetch(url, config);
// Obtain the value of the paymentSessionData parameter in the response.
const { paymentSessionData } = await response.json();
return paymentSessionData;
}
const paymentSessionData = await getPaymentSessionData();
// Step 3: Create rendering components.
await checkoutApp.createComponent({
sessionData: paymentSessionData,
appearance:{
showLoading: true, // Set as true by default to enable the default loading pattern.
},
});
}
事件代码
您可能会看到两种类型的事件代码:
- 状态代码: 由组件运行时生命周期中的
onEventCallback
返回。 - 错误代码: 由组件初始化阶段的
onEventCallback
或onError
返回。
类型 | 代码 | 描述 | 后续操作 |
状态代码 | SDK_START_OF_LOADING | 在创建支付组件时开始播放加载动画。 | 无需进一步操作。 |
SDK_END_OF_LOADING | 在创建支付组件时加载动画结束。 | 无需进一步操作。 | |
错误代码 | SDK_INTERNAL_ERROR | SDK 内部错误发生。 | 请联系 Antom 技术支持解决此问题。 |
SDK_CREATEPAYMENT_PARAMETER_ERROR | 传递给 AMSCashierPayment 方法的参数不正确。 | 确保参数传递正确并重新发送请求。 | |
SDK_INIT_PARAMETER_ERROR | 传递给 | 确保参数传递正确并重新发送请求。 | |
SDK_CREATECOMPONENT_ERROR | 调用 | 请联系Antom技术支持解决此问题。 | |
SDK_CALL_URL_ERROR | 支付方式客户端撤销失败。 | 请联系Antom技术支持解决此问题。 |