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

SDK 参考信息

回调数据

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

事件码

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

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

状态码

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

  • SDK_START_OF_LOADING:配置 showLoadingfalse 时,使用自定义动画,您可在这个时机渲染并展示自定义加载动画。
  • SDK_END_OF_LOADING:配置 showLoadingfalse 时,使用自定义动画,您可在这个时机结束自定义加载动画。
  • SDK_PAYMENT_CANCEL:表示用户取消支付,即用户未提交订单退出支付页面。可使用有效期内的 paymentSessionData 重新调用 SDK。如已过期,需要重新发起 支付会话创建 请求。
  • SDK_CALL_URL_ERROR:此事件码代表以下事件信息中的一种情况:
    • 跳转商户页面失败。
    • 转支付方式 App 或页面失败。
    • 调用 支付会话创建 请求时 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_PAYMENT_FAIL:表示支付失败。建议您根据 paymentResultCode 错误码提示信息进行处理,并引导重新支付。
  • SDK_PAYMENT_PROCESSING:表示支付处理中。建议您的服务端查询支付状态或等待支付结果通知,同时可询问用户是否完成,如果用户未完成支付,可以引导重新支付。
  • SDK_PAYMENT_ERROR:表示支付状态异常。建议您的服务端查询支付状态或等待支付结果通知。
  • SDK_PAYMENT_RETRY:支付失败后重试。 在开启失败可重试的情况下,引导用户修改信息后再支付。

支付失败或异常说明

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

支付结果码(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 验证异常,先完成 KYC 认证。

USER_PAYMENT_VERIFICATION_FAILED

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

用户验证失败。请联系 Antom 技术支持了解具体原因。

USER_STATUS_ABNORMAL

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

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

PAYMENT_IN_PROCESS

支付正在处理中。

支付处理中。

UNKNOWN_EXCEPTION

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

未知异常。请联系 Antom 技术支持了解具体原因。

CARD_NOT_SUPPORTED

用于交易的卡不支持。

卡不支持。请换卡重试。

INVALID_EXPIRATION_DATE

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

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

INVALID_CARD_NUMBER

用于交易的卡号无效。

卡号不正确。建议换卡重试。如重试后还有问题,请联系 Antom 技术支持了解具体原因。

卡支付信息

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

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

参数名称

是否必需

说明

cardNo

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

当 pay 接口中字段 paymentMethodType 的值为 CARD 且商户没有 PCI 资质时返回此参数。

cardBrand

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

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

cardBin

卡号前 6 位。

lastFour

卡号后 4 位。

issuerName

发卡行。

issuingCountry

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

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

funding

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

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

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

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

avsResultRaw

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

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

cvvResultRaw

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

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

holdName

持卡人姓名

fingerprint

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

expiryMonth

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

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

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

expiryYear

银行卡的到期年份。输入年份的最后两位数字。例如,如果到期年份是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

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

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

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

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

riskAuthDecision

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"
    }
}

集成关键步骤代码示例

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

Web/WAP 端集成代码示例

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

  • 使用 npm 集成 SDK 资源包  
  • 使用 CDN 资源集成 SDK 资源包
copy
13:57import { AMSCashierPayment } from "@alipay/ams-checkout";
// 步骤一:实例化SDK,并处理好事件回调
const onEventCallback = function({ code, result }) {
  switch (code) {
    case 'SDK_PAYMENT_SUCCESSFUL':
      // 支付成功。建议您重定向到支付结果页。
      break;
    case 'SDK_PAYMENT_PROCESSING':
      console.log('可检查支付结果数据', result);
      // 支付处理中。建议您通过服务端查询支付状态或等待支付结果通知,同时可询问用户是否完成,如果未完成,可以引导用户重新支付。
      break;
    case 'SDK_PAYMENT_FAIL':
      console.log('可检查支付结果数据', result);
      // 支付失败。建议您查阅文末参考信息服务端事件码表格中的处理建议,并引导用户重新支付。
      break;
    case 'SDK_PAYMENT_CANCEL':
      // 用户在未提交订单状态下退出支付页面。可以用在有效期内的 paymentSessionData 重新调用SDK。如已过期,需要重新请求 paymentSessionData。
      break;
    case 'SDK_PAYMENT_ERROR':
      console.log('可检查支付结果数据', result);
      // 支付状态异常。建议您通过服务端查询支付状态或等待支付结果通知,或引导用户重新支付。
      break;
    case 'SDK_END_OF_LOADING':
      // 建议您结束自定义加载动画
      break;
    default:
      break;
  }
}
const checkoutApp = new AMSCashierPayment({
  environment: "sandbox",
  locale: "en_US",
  onLog: ({code, message}) => {},
  onEventCallback: onEventCallback,
});
// 处理卡支付按钮事件
document
  .querySelector("#你的表单id")
  .addEventListener("submit", handleSubmit);

async function handleSubmit() {
  // 步骤二:服务端调用支付会话创建接口,获取paymentSessionData
  async function getPaymentSessionData() {
    const url = "填写服务端地址";
    const config = {
      // 填写请求配置
    };
    const response = await fetch(url, config);
    // 获取响应中的paymentSessionData参数值
    const { paymentSessionData } = await response.json();
    return paymentSessionData;
  }
  const paymentSessionData = await getPaymentSessionData();

  // 步骤三:创建渲染卡组件
  // 最佳实践
  await checkoutApp.createComponent({ 
    sessionData: paymentSessionData, 
    appearance:{
      showLoading: true, // 默认为true,表示展示初始化加载动画
    },
  });
}

Android 端集成代码示例

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

copy
AMSCashierPaymentConfiguration configuration = new AMSCashierPaymentConfiguration();
configuration.setLocale(new Locale("en", "US"));
// 设置showLoading参数为true(默认值)时使用内部loading页面,false时商户可通过onPaymentEventCallback中的事件自定义loading动画
configuration.setOption("showLoading", "true");
// 设置沙箱环境,不设置为线上正式环境
configuration.setOption("sandbox", "true");
// 配置是否由SDK组件渲染支付按钮
configuration.setOption("showSubmitButton", "true");
// 设置收银台回调监听
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)) {
                // 支付成功。建议您重定向到支付结果页
            } else if ("SDK_PAYMENT_PROCESSING".equals(eventCode)) {
                // 支付处理中。建议您的服务端查询支付状态或等待支付结果通知
            } else if ("SDK_PAYMENT_FAIL".equals(eventCode)) {
                // 支付失败。建议您根据 paymentResultCode 错误码提示信息,并重新引导支付
            }else if ("SDK_PAYMENT_CANCEL".equals(eventCode)) {
                // 买家未点击支付并关闭支付窗口。可以用在有效期内的 paymentSessionData 重新调用SDK。如已过期,需要重新请求 paymentSessionData
            } else if ("SDK_PAYMENT_ERROR".equals(eventCode)) {
                // 支付状态异常。建议您的服务端查询支付状态或等待支付结果通知
            }
        }
    }
});
// 创建AMSCashierPayment实例化
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";
// sandbox变更设置沙箱环境,不设置为线上正式环境
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"]) {
        // 支付成功。建议您重定向到支付结果页
    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_PROCESSING"]) {
        // 支付处理中。建议您的服务端查询支付状态或等待支付结果通知

    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_FAIL"]) {
        // 支付失败。建议您根据 paymentResultCode 错误码提示信息,并重新引导支付

    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_CANCEL"]) {
        // 买家未点击支付并关闭支付窗口。可以用在有效期内的 paymentSessionData 重新调用SDK。如已过期,需要重新请求 paymentSessionData

    } else if ([eventCode isEqualToString:@"SDK_PAYMENT_ERROR"]) {
        // 支付状态异常。建议您的服务端查询支付状态或等待支付结果通知
    }
    NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}

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