Alipay, China's leading third-party online payment solutionAlipay, China's leading third-party online payment solution

SDK 参考

回调数据

回调函数可以返回多种类型的数据或值,例如事件码和与支付相关的信息。本文向您介绍通过回调函数返回的事件码、卡支付信息以及风控信息。

事件码

回调函数事件码在不同时机通过不同回调函数返回,主要包括以下三种:

  • 状态码
  • 错误码
  • 支付结果码

状态码

在组件运行生命周期内,通过 onEventCallback 回调函数返回,可根据具体事件进行后续处理。

  • SDK_START_OF_LOADING配置 showLoading 为 false 时,使用自定义动画,您可在这个时机渲染并展示自定义加载动画。
  • SDK_END_OF_LOADING配置 showLoading 为 false 时,使用自定义动画,您可在这个时机结束自定义加载动画。
  • SDK_CALL_URL_ERROR此事件码代表以下事件信息中的一种情况:
    • 跳转到商户页面失败。
    • 跳转到 3D 验证页面失败。
    • 调用 支付会话创建 请求时,paymentRedirectUrl 参数未传入或未正确传入。

Web/WAP 场景下通常不会出现跳转异常,如果出现异常建议您校验重定向链接。App 场景下,如果频繁出现跳转异常,请联系 Antom 技术支持,排查跳转或唤端问题。

  • SDK_CALL_URL_SUCCESS跳转支付方式/商户页面成功。
  • SDK_DUPLICATE_SUBMISSION_BEHAVIOR表单重复提交。您可以设置提示,避免用户重复点击提交。
  • SDK_FORM_VERIFICATION_FAILED提交表单后校验不通过。SDK 会在要素收集页面展示表单错误码,用户可以重新提交支付。
  • SDK_PAYMENT_AUTHORIZATION_SUCCESSFUL支付流程已完成。如果配置了支付后不跳转的方法,建议继续监听相应的支付事件码以处理后续流程。否则,可以忽略此事件码并跳转到您的支付结果页面。
  • SDK_PAYMENT_CHALLENGE触发3D验证,发卡行需要与买家进行进一步交互才能验证支付。无需处理,SDK 会自动跳转到验证页面。

错误码

在组件初始化阶段,通过 onEventCallbackonError 回调函数返回,可根据具体事件进行后续处理。

  • SDK_INTERNAL_ERROR:SDK 内部错误。请联系 Antom 技术支持。
  • SDK_CREATEPAYMENT_PARAMETER_ERRORcreateComponent 函数传入参数异常。请检查参数是否正确并重新初始化组件。
  • SDK_INIT_PARAMETER_ERRORAMSCashierPayment 函数传入参数异常。请检查参数是否正确并重新实例化 SDK。
  • SDK_CREATECOMPONENT_ERROR:组件初始化异常。请联系 Antom 技术支持。
  • SDK_SUBMIT_NETWORK_ERROR因网络原因,接口调用失败。在 submit 函数提交中可能会出现。请尝试再次提交。

支付结果码

在支付流程结束时,通过 onEventCallback 回调函数返回,可根据具体事件进行后续处理。

  • SDK_PAYMENT_SUCCESSFUL :表示支付成功。首次支付时买家需手动取消 SDK,银行卡令牌支付模式下 SDK会自动关闭。建议跳转到支付结果页面。
  • SDK_PAYMENT_PROCESSING表示支付处理中。建议您的服务端查询支付状态或等待支付结果通知
  • SDK_PAYMENT_FAIL表示支付失败。建议您根据 paymentResultCode 错误码提示信息进行处理,并引导用户重新支付。
  • SDK_PAYMENT_ERROR表示支付状态异常。建议您的服务端查询支付状态或等待支付结果通知。

支付失败或异常说明

以下表格为支付失败或异常时的支付结果信息以及对应的处理建议,您可以根据收到的支付结果码作进一步处理。

paymentResultCode

paymentResultMessage

建议

ACCESS_DENIED

访问被拒绝。

无权限。请联系 Antom 技术支持了解具体原因。

CURRENCY_NOT_SUPPORT

不支持该货币。

币种不支持。请联系 Antom 技术支持了解具体原因。

FRAUD_REJECT

由于风险控制,交易无法进一步处理。如果买家已为交易付款,交易将被退款。

如下情况请联系 Antom 技术支持

  • 您需要申诉。
  • 买家两周内未收到退款。

INVALID_CARD

无效卡。可能是信用卡号无法识别,没有对应的发卡行,或者卡号格式错误。

建议换卡重试。

INVALID_EXPIRY_DATE_FORMAT

expiryYear 或者 expiryMonth 格式错误。

卡有效期格式错误。建议检查卡有效期的填写格式。

ISSUER_REJECTS_TRANSACTION

发卡行拒绝交易。

建议换卡重试或联系发卡行。

INVALID_MERCHANT_STATUS

由于存在限制,商户状态异常。

请联系 Antom 技术支持以获取具体原因。

MERCHANT_KYB_NOT_QUALIFIED

由于商户的 KYB 状态,支付失败。商户可能未完成 KYB,或者 KYB 状态不适用于此交易。

请联系 Antom 技术支持以获取具体原因。

NO_PAY_OPTIONS

没有可用的支付选项。

币种不受支持。请检查支付方式是否支持该币种,或者支付方式和币种是否与合同一致。如有问题,请联系 Antom 技术支持以获取具体原因。

ORDER_IS_CLOSED

您发起的请求具有与已关闭交易相同 的 paymentRequestId

订单关闭。请发起新的请求并重试。

PAYMENT_AMOUNT_EXCEED_LIMIT

支付金额超过了合同或支付方式允许的最大金额。

金额超出限制。请检查支付金额是否超出限制,或尝试使用较低的金额重试。请联系 Antom 技术支持获取具体的支付限额信息。

PAYMENT_COUNT_EXCEED_LIMIT

支付次数超过了支付方式规定的最大限制。

使用次数超出限制。请联系 Antom 技术支持获取具体的支付限额信息。

PAYMENT_NOT_QUALIFIED

商户不具备支付资格,可能是因为未注册、未签订自动扣款协议或被禁止支付。

商户无权限。具体原因请联系 Antom 技术支持。

PROCESS_FAIL

发生常见的业务失败。

支付失败。获取 Antom 技术支持前请勿重试。

RISK_REJECT

由于风险控制,交易无法进一步处理。如果用户已为交易付款,交易将被退款。

风控拒绝。如果买家在两周内未收到退款,请联系 Antom 技术支持。

SUSPECTED_CARD

该卡疑似存在欺诈行为。例如,卡片可能被盗或受到限制。

风控拒绝。建议换卡重试或联系发卡行。

SUSPECTED_RISK

由于怀疑存在安全问题,无法进一步处理该交易。您可以在一个工作日后重试该交易。如果交易不安全但用户已付款,则该交易将被退款。

风控拒绝。如下情况下请联系 Antom 技术支持

  • 您需要申诉。
  • 买家两周内未收到退款。

USER_AMOUNT_EXCEED_LIMIT

支付金额超过了用户的支付限额。

金额超过限制。请用小于或等于您账户中的可用余额的金额重新发起支付,或联系 Antom 技术支持。

USER_BALANCE_NOT_ENOUGH

用户在相应支付方式中的余额不足,无法完成支付。

用户余额不足,请充值或选择其他支付方式。

USER_KYC_NOT_QUALIFIED

由于用户的 KYC 状态,支付失败。用户可能未完成 KYC 认证,或者 KYC 状态不满足此交易要求(例如,支付金额或产品信息的限制)。

请用户先完成 KYC 认证。

USER_PAYMENT_VERIFICATION_FAILED

用户在支付方式方面受到限制,无法进行支付。 

用户未完成验证,具体原因请联系 Antom 技术支持。

USER_STATUS_ABNORMAL

用户支付方式端的状态异常。

用户状态异常,具体原因请联系 Antom 技术支持。

PAYMENT_IN_PROCESS

支付正在处理中。

支付处理中。

UNKNOWN_EXCEPTION

由于未知原因,接口调用失败。

未知异常,具体原因请联系 Anotm 技术支持。

CARD_NOT_SUPPORTED

用于交易的卡不支持。

卡不支持,请换卡重试。

INVALID_EXPIRATION_DATE

paymentMethodMetaData.expiryYear 或者 paymentMethodMetaData.expiryDate 的值无效。

银行卡的有效期不正确。建议检查银行卡的有效期是否填写正确。

INVALID_CARD_NUMBER

用于交易的卡号无效。

卡号不正确。建议换卡重试。如果重试后仍有问题,请联系 Antom 技术支持以获取具体原因。

银行卡支付

在卡支付场景下,当支付流程达到成功或失败的最终状态时,您可以在调用 onEventCallback 函数后在响应中收到 cardPaymentResultInfo 参数。 请参阅下表了解 cardPaymentResultInfo 的子参数信息:

注意如果支付流程完成,用户被重定向到跳转链接,您将不会收到 cardPaymentResultInfo 参数

参数

描述

cardNo

可选 字符串 (32)

脱敏卡号,仅显示部分卡号,可用于向用户展示。

支付 接口中参数 paymentMethodType 的值为 CARD 且商户没有 PCI 资质时返回此参数。

cardBrand

可选 字符串 (256)

卡品牌,可用于向用户展示。

支付 接口中参数 paymentMethodType 的值为 CARD 时返回此参数。

cardBin

可选 字符串 (32)

卡号前六位。

lastFour

可选 字符串 (4)

卡号后四位。

issuerName

可选 字符串 (256)

发卡行。

发行国家

可选 字符串 (2)

发卡国家。此参数的值为两个字母的国家/地区代码,遵循 ISO 3166 国家/地区代码标准。

支付 接口中字段 paymentMethodType 的值为 CARD 时返回此参数。

资金来源

可选 字符串 (32)

卡片的资助类型。有效值包括:

  • CREDIT: 表示信用卡。
  • DEBIT: 表示借记卡。
  • PREPAID: 表示预付卡。
  • CHARGE: 表示充值卡。
  • DEFERRED_DEBIT: 表示延期借记卡。

当以下所有条件满足时,此参数将返回:

  • 参数 paymentMethodType 的值为 CARD.
  • 参数 cardNo 的值有效。
  • 信息在Antom的卡片数据库中可用。

avsResultRaw

可选 字符串 (128)

原始 AVS 结果。请参阅 AVS 结果代码查看有效值。  

当发卡行将此信息传递给 Antom 时将返回此参数。

cvvResultRaw

可选 字符串 (128)

原始卡验证值 (CVV)、卡安全码 (CSC) 或卡验证码 (CVC) 结果。请参阅 CVV 结果代码查看有效值。

当发卡行将此信息传递给 Antom 时将返回此参数。

holdName

可选 字符串 (32)

持卡人姓名。

指纹

可选 字符串 (256)

此特定卡号的唯一标识。您可以使用此参数检查两个已注册的客户是否使用相同的卡号。

过期月份

可选 字符串 (2)

银行卡的过期月份。传入表示月份的两位数字。例如,如果过期月份是二月,此参数的值为 02

在满足以下所有条件时指定此参数:

  • 您已获得PCI资格。
  • paymentMethodType 的值为 CARD
  • 您在支付过程中收集此信息。

过期年份

可选 字符串 (2)

银行卡的到期年份。输入年份的最后两位数字。例如,如果到期年份是2025,此参数的值为 25

在满足以下所有条件时指定此参数:

  • 您已获得PCI资格。
  • paymentMethodType 的值为 CARD。 
  • 您在支付过程中收集此信息。

返回的卡片信息的示例代码:

copy
{
    "result": {
        "resultCode": "SUCCESS",
        "resultStatus": "S",
        "resultMessage": "Success"
    },
    "paymentStatus": "SUCCESS",
    "paymentResultCode": "SUCCESS",
    "paymentResultMessage": "success",
    "cardPaymentResultInfo": {
        "avsResultRaw": "4",
        "cardBin": "409280",
        "cardBrand": "VISA",
        "cardNo": "************8888",
        "cvvResultRaw": "1",
        "expiryMonth": "02",
        "expiryYear": "27",
        "fingerprint": "",
        "funding": "DEBIT",
        "holdName": "Tom Jay",
        "issuerName": "BANCO ITAUCARD, S.A.",
        "issuingCountry": "BR",
        "lastFour": "0000"
    }
}

风控信息

在卡支付场景下,当支付流程达到成功或失败的最终状态并且您与 Antom 签署了风控服务时,您可以在调用 onEventCallback 函数后在响应中收到 popRiskDecisionResultInfo 参数。 请参阅下表了解 popRiskDecisionResultInfo 的子参数信息:

注意:如果支付流程完成后用户被重定向,您将不会收到 popRiskDecisionResultInfo 参数。

参数

描述

riskDecision

可选 字符串 (16)

Antom 的风险管理决策。有效值为:

ACCEPT:表示 Antom 建议您接受付款。

REJECT:表示 Antom 建议您拒绝付款。

当您与 Antom 签署风控服务时返回该参数。

riskAuthDecision

可选 字符串 (16)

Antom 推荐的身份验证方法。有效值为:

3D:建议对此交易进行 3D 身份验证。

NON_3D:建议对此交易进行非 3D 验证。

当您与 Antom 签署风控服务时返回此参数。

返回的风控信息示例代码:

copy
{
    "result": {
        "resultCode": "SUCCESS",
        "resultStatus": "S",
        "resultMessage": "Success"
    },
    "paymentStatus": "SUCCESS",
    "paymentResultCode": "SUCCESS",
    "paymentResultMessage": "success",
    "popRiskDecisionResultInfo": {
        "riskDecision": "ACCEPT",
        "riskAuthDecision": "NON_3D"
    }
}

客户端 SDK 完整示例代码

以下代码示例说明了集成过程中的关键步骤。代码中不包括调用 支付会话创建 接口的步骤示例,需要您自行处理服务端接口的调用。

Web/WAP 端集成代码示例

您可以在桌面浏览器或移动浏览器上集成 Antom 客户端 SDK。以下是两种集成方法的示例代码:

  • 使用 npm 集成 SDK 资源包  
  • 使用 CDN 资源集成 SDK 资源包
copy
import { AMSCashierPayment } from "@alipay/ams-checkout";
// Step 1: Instantiate the SDK and handle the callback event.
const onEventCallback = function({ code, result }) {
  switch (code) {
    case code:
      'SDK_PAYMENT_SUCCESSFUL';
      // Payment was successful. Redirect users to the payment result page.
      break;
    case code:
      'SDK_PAYMENT_PROCESSING';
      console.log('Check the payment result data', result);
      // Payment was being processed. Guide users to retry the payment based on the provided information.
      break;
    case code:
      'SDK_PAYMENT_FAIL';
      console.log('Check the payment result data', result);
      // Payment failed. Guide users to retry the payment based on the provided information.
      break;
    case code:
      'SDK_PAYMENT_CANCEL';
      // Guide the user to retry the payment.
      break;
    case code:
      'SDK_PAYMENT_ERROR';
      console.log('Check the payment result data', result);
      // The payment status was abnormal. Guide users to retry the payment based on the provided information.
      break;
    case code:
      'SDK_END_OF_LOADING';
      // End the custom loading animation.
      break;
    default:
      break;
  }
}
const checkoutApp = new 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.
  // Best practice
  await checkoutApp.createComponent({ 
    sessionData: paymentSessionData, 
    appearance:{
      showLoading: true, // Set as true by default to enable the default loading pattern.
    },
  });
}

Android 端集成代码示例

以下示例代码展示了如何在 Android 设备上集成客户端 SDK。

copy
AMSCashierPaymentConfiguration configuration = new AMSCashierPaymentConfiguration();
configuration.setLocale(new Locale("en", "US"));
// When the showLoading parameter is set to true (default value), use the internal loading page. When false, the merchant can customize the loading animation through the event in onPaymentEventCallback.
configuration.setOption("showLoading", "true");
// Set the sandbox environment instead of the online production environment.
configuration.setOption("sandbox", "true");
// Configure whether the payment button is rendered by the SDK component.
configuration.setOption("showSubmitButton", "true");
// Set up checkout callback monitoring.
configuration.setOnCheckoutListener(new OnCheckoutListener() {
    @Override
    public void onEventCallback(String eventCode, AMSEventResult eventResult) {
        Log.e(TAG, "onEventCallback eventCode=" + eventCode + " eventResult=" + eventResult.toString());
      
        if (!TextUtils.isEmpty(eventCode)) {
            if ("SDK_PAYMENT_SUCCESSFUL".equals(eventCode)) {
                // Payment was successful. Suggest redirecting to the payment result page.
            } else if ("SDK_PAYMENT_PROCESSING".equals(eventCode)) {
                // Payment is being processed. We suggest that your server check the payment status or wait for the payment result notification.
            } else if ("SDK_PAYMENT_FAIL".equals(eventCode)) {
                // Payment failed. We suggest that you follow the paymentResultCode error code prompt and guide the user to pay it again.
            }else if ("SDK_PAYMENT_CANCEL".equals(eventCode)) {
                // The buyer did not click to pay and closed the payment window. The SDK can be re-called with paymentSessionData within the validity period. If it has expired, paymentSessionData needs to be requested again.
            } else if ("SDK_PAYMENT_ERROR".equals(eventCode)) {
                // The payment status was abnormal. We suggest that your server check the payment status or wait for the payment result notification.
            }
        }
    }
});
// Create the AMSCashierPayment instantiation.
AMSCashierPayment checkout = new AMSCashierPayment.Builder(activity, configuration).build();

checkout.mountComponent(activity, sessionData);

checkout.onDestroy();

iOS 端集成代码示例

以下示例代码展示了如何在 iOS 设备上集成客户端 SDK。

copy
#import <AMSComponent/AMSComponent-Swift.h>

AMSCashierPaymentConfiguration *componentConfig = [AMSCashierPaymentConfiguration new];
componentConfig.locale = @"en_US";
// Set sandbox environment instead of online production environment
NSDictionary *options = @{@"showLoading": @"true", @"sandbox": @"true"};
componentConfig.options = options;

[[AMSCashierPayment shared] initConfiguration:componentConfig];

[AMSCashierPayment shared].paymentDelegate = self;
[AMSCashierPayment shared].loggerDelegate = self;
[[AMSCashierPayment shared] createComponent:paymentSessionData];

NSString *dataString = @"{\"billingAddress\":{\"zipCode\":\"310000\",\"region\":\"CN\"}}";
[[AMSCashierPayment shared] submit: dataString];

#pragma AMSPaymentProtocol
- (void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult
{
    if ([eventCode isEqualToString:@"SDK_PAYMENT_SUCCESSFUL"]) {
        // Payment was successful. Suggest redirecting to the payment result page.
    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_PROCESSING"]) {
        // Payment is being processed. It is recommended that your server check the payment status or wait for the payment result notification.

    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_FAIL"]) {
        // Payment failed. We suggest that you follow the paymentResultCode error code prompt and guide the user to pay it again.

    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_CANCEL"]) {
        // The buyer did not click to pay and closed the payment window. The SDK can be re-called with paymentSessionData within the validity period. If it has expired, paymentSessionData needs to be requested again.

    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_ERROR"]) {
        // The payment status was abnormal. It is recommended that your server check the payment status or wait for the payment result notification.
    }
    NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}

#pragma AMSLogProtocol
- (void)logWithName:(NSString *)name parameter:(NSDictionary<NSString *,id> *)parameter
{
   NSLog(@"name%@ parameter%@", name, parameter);
}