服务端-服务端模式

单笔支付服务为网站和应用程序提供全方位的支付解决方案,支持桌面端、移动端等多场景无缝对接。通过一次集成即可快速接入多种在线支付方式,包括电子钱包、网银转账和卡支付等,有效降低技术门槛。买家可以根据个人偏好选择最便捷安全的支付方式,享受更优质的支付体验。

本文为您介绍如何通过服务端-服务端模式集成银行卡支付方式,适合对支付流程定制程度有高要求的商户。服务端到服务端集成模式要求您符合 PCI 资格,请根据您的业务需求提供相关材料完成验证:

有关 PCI DSS 合规要求的更多信息,请参阅 PCI DSS 标准

注意:本方案由您自行采集买家的卡信息,需要您具备 PCI 资质,请确保您已按照要求完成 PCI 验证。

用户体验

以下图片展示了买家进行首次支付或绑卡支付的用户体验:

首次支付

在首次支付时,可以引导买家勾选存储卡信息,在后续的支付中可用于绑卡支付、订阅支付、自动充值等场景,为买家提供更快捷的支付体验,同时大幅提升买家的支付意愿。

卡支付服务端对服务端web.png

绑卡支付

买家直接选择已存卡进行支付,无需重新填写支付信息。

卡支付服务端对服务端web-存卡.png

订单生命周期

卡支付订单主要包含以下阶段:

  • 授权:买家使用银行卡完成支付后,其资金将处于冻结状态。买家下单至完成授权期间,您都可以在窗口期内对订单发起撤销
  • 请款:通过请款将买家的冻结资金转移到您的账户。Antom 默认自动为您请款,具体信息请参阅请款。请款完成后,若有需要,您可以在窗口期内发起退款
  • 拒付:若买家向发卡行发起拒付或调单查询,您需要根据情况处理争议流程,具体信息请参阅争议

生命周期.png

支付流程

对于使用服务端-服务端模式的卡支付,支付流程包括以下步骤:

端对端flow-cn.png

  1. 买家输入卡信息并选择是否绑卡。
  2. 提交支付请求。
    买家输入卡信息提交支付后,您需调用 pay(单笔支付)接口以获取支付推进链接来完成支付。
  3. (可选)买家跳转至 3DS 认证页面。
    买家跳转至 3DS 认证页面完成身份核验(如遇无摩擦流程则免核验),随后返回商户结果页。
  4. 获取授权支付结果。
    商户服务端接收 Antom 返回的授权支付结果通知,并根据结果进行相应的业务处理。
  5. 获取请款结果
    您可以通过以下两种方法之一获取请款结果

集成准备

在您开始集成前,请阅读集成指南接口概述文档,了解服务端接口的集成步骤及调用接口的注意事项,并确保已完成以下预配置:

  • 已获得 client ID。
  • 已完成密钥配置。
  • 已完成异步通知接收地址的配置。
  • 集成服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK

集成步骤

请按照以下步骤开始集成:

  1. 授权支付
  2. (可选)跳转至 3DS 认证页面
  3. 获取授权支付结果
  4. 获取请款结果

步骤 1:授权支付 服务端

买家提交支付后,您需要采集买家的卡信息、订单信息、设备信息和支付金额等关键信息,并调用 pay(单笔支付)接口提交支付请求。

以下是发起支付请求的重点参数:

类型

参数名称

是否必需

描述

基础参数

productCode

在此场景中,该参数的值固定为 CASHIER_PAYMENT

paymentRequestId

商家为识别支付请求而分配的专属 ID,每次发起支付都要有一个新的 ID。

paymentAmount

支付金额,应根据订单货币的最小单位设置,例如,CNY 为分,KRW 为元。

paymentMethod.paymentMethodType

支付方式枚举值,卡支付场景下固定为 CARD

paymentRedirectUrl

商户端支付结果页,需根据服务端结果展示,非固定成功页面。

paymentNotifyUrl

支付结果通知地址,可通过接口传递,也可通过 Antom Dashboard 设置为固定值。若两者都设置,则接口传递的值优先。

settlementStrategy

支付请求的结算策略。若业务签约了多个结算币种,则需在接口中指定 settlementCurrency 参数。

paymentFactor.isAuthorization

支付模式。卡支付场景固定传 true,指定为授权请款模式。

订单参数

order.buyer

商户端买家信息。至少需要提供以下三者其中一个信息:

  • order.buyer.referenceBuyerId
  • order.buyer.buyerPhoneNo
  • order.buyer.buyerEmail

order.referenceOrderId

商户端订单号。

order.orderDescription

商户端订单描述。

设备参数

env.terminalType

商户服务适用的终端类型。有效值为:

  • WEB:客户端终端类型为网站,通过 PC 浏览器打开。
  • WAP:客户端终端类型为 H5 页面,通过移动浏览器打开。
  • APP:客户端终端类型为移动应用。

env.osType

买家发起交易的操作系统类型。有效值为:

  • IOS:表示操作系统为 iOS。
  • ANDROID:表示操作系统为 Android。

注意:当 env.terminalType WAPAPP 时,请指定此参数。

env.clientIp

买家的 IP 地址,卡支付场景下需要提供此信息。

卡支付信息参数(具体请参考卡支付特性

paymentMethod.paymentMethodMetaData.cardNo

银行卡号。卡支付场景下,您自行采集卡信息需传入此参数。

paymentMethod.paymentMethodMetaData.expiryYear

银行卡的过期年份。卡支付场景下,自行采集卡信息需传入此参数。

paymentMethod.paymentMethodMetaData.expiryMonth

银行卡的过期月份。卡支付场景下,自行采集卡信息需传入此参数。

paymentMethod.paymentMethodMetaData.cvv

卡验证码(CVV)。在卡支付场景中,首次支付以及后续支付使用新卡支付时建议传入卡的 CVV 信息,有助于提高支付成功率。对于 token 支付,建议无需再次采集 CVV 信息,更多内容请参阅 Antom Tokenization

paymentMethod.paymentMethodMetaData.cardholderName

持卡人姓名。卡支付场景下,自行采集卡信息需传入此参数以提升支付成功率。该参数仅支持英文字符。

paymentMethod.paymentMethodMetaData.is3DSAuthentication

您需要根据当前交易的风险和拒付情况,决定交易是否进行 3DS 认证。有效值为:

  • true:指交易发起 3DS 认证。
  • false:指交易不进行 3DS 认证。如果此参数为空或未传递,默认为此值。

以上参数是发起支付请求的基本参数,完整参数和特定支付方式的额外要求请参考 pay(单笔支付)接口。

以下示例代码展示了如何调用 pay(单笔支付)接口:

copy
public static void payByCardServer2Server() {
    AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
    alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);

    // 替换为您的 paymentRequestId
    String paymentRequestId = UUID.randomUUID().toString();
    alipayPayRequest.setPaymentRequestId(paymentRequestId);

    // 设置金额
    Amount amount = Amount.builder().currency("SGD").value("4200").build();
    alipayPayRequest.setPaymentAmount(amount);

    // 设置支付方式
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("CARD").build();
    alipayPayRequest.setPaymentMethod(paymentMethod);

    // 卡信息
    Map<String, Object> paymentMethodMetaData = new HashMap<String, Object>();
    paymentMethodMetaData.put("cardNo", "40************68");
    paymentMethodMetaData.put("cvv", "123");
    paymentMethodMetaData.put("expiryMonth", "12");
    paymentMethodMetaData.put("expiryYear", "99");
    paymentMethodMetaData.put("tokenizeMode", "ENABLED");

    JSONObject cardholderName = new JSONObject();
    cardholderName.put("firstName", "John");
    cardholderName.put("lastName", "Doe");
    paymentMethodMetaData.put("cardholderName", cardholderName);
    paymentMethod.setPaymentMethodMetaData(paymentMethodMetaData);

    // 替换为您的 orderId
    String orderId = UUID.randomUUID().toString();

    // 设置买家信息
    Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

    // 设置订单信息
    Order order = Order.builder().referenceOrderId(orderId)
    .orderDescription("antom testing order").orderAmount(amount).buyer(buyer).build();
    alipayPayRequest.setOrder(order);

    // 设置环境信息
    Env env = Env.builder().terminalType(TerminalType.WEB).clientIp("1.2.3.4").build();
    alipayPayRequest.setEnv(env);

    // 设置授权请款模式
    PaymentFactor paymentFactor = PaymentFactor.builder().isAuthorization(true).build();
    alipayPayRequest.setPaymentFactor(paymentFactor);

    // 替换为您的通知地址
    alipayPayRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");

    // 替换为您的跳转 URL
    alipayPayRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");

    // 支付
    AlipayPayResponse alipayPayResponse = null;
    try {
        alipayPayResponse = CLIENT.execute(alipayPayRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // 处理错误信息
    }
}

以下代码展示了一个请求报文的示例:

copy
{
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "productCode": "CASHIER_PAYMENT",
  "paymentNotifyUrl": "https://www.yourNotifyUrl.com",
  "paymentRequestId": "PAY_20**********38",
  "paymentRedirectUrl": "https://www.yourMerchantWeb.com",
  "paymentFactor": {
    "isAuthorization": true
  },
  "paymentMethod": {
    "paymentMethodMetaData": {
      "cvv": "682",
      "cardholderName": {
        "firstName": "Tom",
        "lastName": "Jerry"
      },
      "expiryMonth": "11",
      "expiryYear": "28",
      "cardNo": "************0849",
      "is3DSAuthentication": true
    },
    "paymentMethodType": "CARD"
  },
  "paymentAmount": {
    "currency": "EUR",
    "value": "7000"
  },
  "order": {
    "orderAmount": {
      "currency": "EUR",
      "value": "30000"
    },
    "orderDescription": "********ga",
    "referenceOrderId": "ORDER_20**********38",
    "buyer": {
      "buyerEmail": "gaga@gaga.com"
    }
  },
  "env": {
    "clientIp": "1.1.1.1",
    "osType": "IOS",
    "terminalType": "WAP"
  }
}

以下代码展示了发起支付后可能返回的响应报文示例,其中包含以下重点参数:

  • result.resultStatus:授权支付的状态。
  • normalUrl:需要跳转的 3DS 认证页面链接。
copy
{
    "normalUrl": "https://pay.xxxx.com/customer-verification?sessionid=103*****KGdFf",
    "paymentActionForm": "{\"method\":\"POST\",\"paymentActionFormType\":\"RedirectActionForm\",\"redirectUrl\":\"https://pay.xxxx.com/customer-verification?sessionid=103*****KGdFf\"}",
    "paymentAmount": {
        "currency": "EUR",
        "value": "7000"
    },
    "paymentCreateTime": "2024-10-11T22:57:16-07:00",
    "paymentId": "2024101216********216220539",
    "paymentRequestId": "PAY_20**********38",
    "paymentResultInfo": {
        "avsResultRaw": "",
        "cardBrand": "VISA",
        "cardNo": "************0849",
        "cvvResultRaw": "",
        "threeDSResult": {
            "cavv": "",
            "eci": "",
            "threeDSVersion": "2.2.0"
        }
    },
    "redirectActionForm": {
        "method": "POST",
        "redirectUrl": "https://pay.xxxx.com/customer-verification?sessionid=103*****KGdFf"
    },
    "result": {
        "resultCode": "PAYMENT_IN_PROCESS",
        "resultMessage": "paymentinprocess",
        "resultStatus": "U"
    }
}

下表展示了响应报文中 result.resultStatus 字段可能返回的值,请您根据指引进行处理:

result.resultStatus

信息

后续操作

S

授权支付成功。

可以发起请款,并储存 paymentId 用于请款或退款操作。

F

授权支付失败。

请关闭当前交易或更换 paymentRequestId 重新下单。

U

交易处理中。

  • 若返回了 normalUrl,表示需要进行 3DS 认证,商户前端跳转到 normalUrl,同时储存 paymentId 用于后续的请款或退款操作。
  • 若没有收到 normalUrl,则表示交易处理中,您可选择主动调用 inquiryPayment 接口获取支付结果,或者等待支付结果异步通知,同时储存 paymentId 用于后续的请款或退款操作。

注意:如果您未收到响应报文,可能是网络超时所致。您可选择主动调用 inquiryPayment 接口获取支付结果,或者等待支付结果异步通知。

常见问题

问:paymentId 的作用是什么?应该如何消费?

答:如果您需要存储相应的订单号以备后续退款和对账,可以指定 paymentId

问:terminalType 应该如何设置?

答:terminalType 的有效值为:

  • WEB:如果买家在 PC 端发起交易,需要将 terminalType 指定为 WEB
  • WAP:如果买家在移动浏览器上发起交易,需要将 terminalType 指定为 WAP。添加 osType 参数,并根据买家的操作系统类型设置相应的参数 ANDROIDIOS
  • APP:如果买家在移动应用内发起交易,需要将 terminalType 指定为 APP

问:哪些交易需要设置为 3DS 交易?

答:若您购买了 Antom Shield,Antom 将基于实时风控模型、交易特征及历史数据,智能决策每笔交易是否需要进行 3DS 认证;若您自身具备完善的风控能力,您可根据订单风险、拒付率以及区域合规要求自行决策是否需触发 3DS 认证。flow.png

问:如果我不设置 is3DSAuthentication 参数,Antom 会为我决策是否发起 3DS 交易吗?

答:不会。如果您未设置 is3DSAuthentication 参数,则默认发起非 3DS 交易,此时存在盗卡、拒付等风险。只有您采购 Antom Shield 服务后,Antom 风控模型才会为您决策是否使用 3DS 验证,此时您无需设置 is3DSAuthentication 参数。

(可选)步骤 2:跳转至 3DS 认证页面 客户端

商户服务端通过 pay(单笔支付)响应获取到 3DS 认证页面链接normalUrl)后,需要将该链接传递给前端,由商户前端跳转至3DS 认证页面。

注意:如果 pay(单笔支付)接口直接返回参数 result.resultStatus 的值为 SF,则无需进行此步骤,因授权支付阶段已到终态。

获取 normalUrl 后,您需要在浏览器将页面重定向至 3DS 认证页面,或在新标签页打开。

copy
if (serverResponse.normalUrl != null) {
  window.open(serverResponse.normalUrl, '_blank');
}

Antom 服务端会基于您传入的 paymentMethodterminalType 返回不同的 normalUrl 用于进行 3DS 认证,例如 H5 页面 https://centinelapi.cardinalcommerce.com/V2/Cruise/StepUp,这个页面在处理过程中可能会发生重定向。

以下图片展示了 Web 和 App 端重定向至 3DS 认证页面的用户体验:

normalUrl-web.png

常见问题

问:如何处理返回的 3DS 认证链接?

答:接收到 3DS 认证链接后,请根据您的客户端类型按以下方式处理:

  • 网页端(Web/WAP):直接引导买家跳转至该链接地址。
  • 应用程序(App):建议在应用内使用 WebView 组件加载该链接。

绝大多数发卡行的 3DS 认证流程为 H5 页面完成,但少数银行可能需拉起其官方应用进行认证。

问:支付结果页内容如何展示?

答:支付结果页必须根据服务端返回的结果进行渲染。切勿将 paymentRedirectUrl 固定为 “支付成功页面”,因为无论支付成功与否,都可能从支付方式回跳到商户页面。

问:回跳商户结果页是否代表支付成功?

答:不能仅凭回跳商户页面来判定支付成功,主要原因如下:

  • 买家支付成功后,可能因网络等原因导致未能回跳至商户结果页;即使买家未完成支付,也可能通过支付方式端的入口回跳至商户结果页。
  • 为防范参数篡改等安全风险,Antom 不会在 paymentRedirectUrl 中拼接任何支付结果参数。

问:Antom 返回的 3DS 跳转链接是固定域名吗?
答:不是固定域名。由于卡支付 3DS 认证会跳转至全球不同发卡行的页面,其域名各不相同,因此无法预置统一白名单。请避免在 WebView 中设置跳转的白名单


问:是否可以使用 iframe 加载卡支付的 3DS 跳转链接?

答:由于部分发卡行的安全策略与兼容性问题,不建议您通过 iframe 加载 3DS 跳转链接。

步骤 3:获取授权支付结果 服务端

买家完成授权支付或授权失败后, Antom 会通过服务器交互将相应的授权支付结果发送给您,您可以通过以下方法之一获取授权支付结果:

  • 接收来自 Antom 的异步通知
  • 主动查询支付结果

接收异步通知

按照以下步骤接收并处理来自 Antom 的异步通知:

  1. 设置接收通知的 webhook URL

完成授权或授权失败时,Antom 会向您设置的 webhook URL 发送异步通知,您可以选择以下两种方法之一来设置接收通知的 webhook URL(若两者都设置,则以接口请求中指定的 URL 优先):

  • 若您的每个订单都有单独的通知 URL,建议您在每笔请求中设置 webhook URL。您可以在 pay(单笔支付)接口请求的 paymentNotifyUrl 参数传入该笔订单的异步通知接收 URL。
  • 若您的所有订单有统一的通知 URL,您可以在 Antom Dashboard > 开发者 > 通知地址 中设置 webhook URL。具体操作请参阅通知地址

注意

  • 若跳转 3DS 认证页面后买家未完成身份验证,则需要等待订单关闭后 Antom 才会发送授权支付结果异步通知,默认关单时间为 14 分钟。
  • 部分失败场景如参数异常等,pay(单笔支付)接口会在响应中同步返回 F,此时 Antom 不会发送异步通知。您可根据 F 状态直接关闭订单。

以下是异步通知请求体的代码示例:

copy
{
    "actualPaymentAmount": {
        "currency": "EUR",
        "value": "7000"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "EUR",
        "value": "7000"
    },
    "paymentCreateTime": "2024-10-08T20:34:29-07:00",
    "paymentId": "20*********************96",
    "paymentRequestId": "PAY_20**********38",
    "paymentResultInfo": {
        "avsResultRaw": "",
        "cardBrand": "MASTERCARD",
        "cardNo": "41************54",
        "cvvResultRaw": "",
        "funding": "CREDIT",
        "issuingCountry": "CN",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "paymentTime": "2024-10-08T20:34:33-07:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

下表展示了授权支付结果的异步通知中 result.resultStatus 参数可能返回的值,请您根据指引进行处理:

result.resultStatus

信息

后续操作

S

授权支付成功。

可以发起请款,并储存 paymentId 用于请款或退款操作。

F

授权支付失败。

请关闭当前交易或更换 paymentRequestId 重新下单。

  1. 异步通知验签

当您收到 Antom 的异步通知,您需要按照返回收到确认信息的格式返回响应,但无需做加签处理。

您需要按照以下方法对 Antom 发送的支付通知进行验签:

copy
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 会重新发送异步通知。

copy
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}

常见问题

问:什么时候会发送异步通知?

答:这取决于授权支付是否完成:

  • 如果支付成功完成,Antom 通常会在 3 到 5 秒内向您发送异步通知。
  • 如果支付未完成,Antom 需要先关闭订单,然后发送异步通知。不同支付方式关闭订单所需的时间会有所不同,通常默认为 14 分钟。

问:Antom 会重新发送异步通知吗?

答:会。对于以下情况,异步通知将在 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> 部分,必须使用其原始的、未经任何处理的字符串值进行拼装。

问:是否可以依据异步通知中 resultStatus 的值为 S 来判断发货?

答:不可以。卡支付方式分为授权-请款两个阶段,异步通知中 resultStatus 的值仅代表授权结果,需根据请款结果来决策发货。

主动查询结果

除了通过异步通知获取授权支付结果,您还可以调用 inquiryPayment 接口主动查询授权支付结果,使用支付中的 paymentRequestId 查询支付状态。

以下代码展示了如何调用 inquiryPayment 接口:

copy
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();
        // 处理错误情况
    }
}

以下代码展示了一个请求报文的示例:

copy
{
  "paymentRequestId": "paymentRequestId01"
}

以下代码展示了一个响应报文的示例:

copy
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "authExpiryTime": "2024-12-17T21:56:56-08:00",
    "cardInfo": {
        "cardBrand": "VISA",
        "funding": "CREDIT",
        "issuingCountry": "US"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "paymentId": "20************56",
    "paymentMethodType": "CARD",
    "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultCode": "SUCCESS",
    "paymentResultInfo": {
        "avsResultRaw": "M",
        "cardBrand": "VISA",
        "cardNo": "************9954",
        "cvvResultRaw": "U",
        "funding": "CREDIT",
        "issuingCountry": "US",
        "networkTransactionId": "12********ew",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2024-12-10T21:56:57-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

下表展示了授权支付结果查询响应中 paymentStatus 字段可能返回的值,请您根据指引进行处理:

paymentStatus

信息

后续操作

SUCCESS

授权支付成功。

可发起请款。

FAIL

授权支付失败。

建议关闭订单或更换 paymentRequestId 重新发起支付。

PROCESSING

处理中。

建议继续查询或在关单时间后再次查询确认最终状态。

常见问题

问:我在查询授权支付结果时需要注意哪些关键参数?

答:请注意以下关键参数:

  • paymentStatus: 您需要根据此参数来判断授权支付状态。
  • paymentAmount:表示支付的金额,可用于金额核对。
  • result:仅表示本次 inquiryPayment 接口的调用结果。订单的授权结果需根据 paymentStatus 的值进行判断,SUCCESSFAIL 表示支付终态结果,PROCESSING 表示处理中。

问:建议发起查询的频率是多久?

答:推荐以轮询的形式发起查询,间隔 2 秒。从发起 pay(单笔支付)接口请求后立即发起轮询,直到查询到最终的支付结果或收到支付结果异步通知为止。

步骤 4:获取请款结果 服务端

授权支付成功后,Antom 默认自动为您请款,同时支持您手动发起请款。请款后,您可以通过异步通知或主动查询来获取请款结果,您需要根据请款结果来决定是否发货。具体操作请参阅请款

支付后操作

完成支付后,您可对交易进行以下支付后的操作:

取消交易 服务端

在卡支付场景中,Antom 支持以下三种情况下的撤销操作:

  • 由 Antom 为您自动请款时,对于授权通知成功但请款通知失败的交易,Antom 会在 7 天后发起撤销;您也可以主动发起撤销,避免买家资金被冻结 7 天。
  • 由您手动请款时,对于授权成功的订单,若您判断无需发起请款,则可以调用 cancel 接口,释放买家的冻结资金。
  • 对于未完成授权的交易,为避免重复扣费,您可调用 cancel 接口取消交易。

请参阅取消交易了解更多内容。

常见问题

问:订单请款成功后,是否还能发起撤销?

答:不能。订单一旦请款成功,无法再进行撤销。如需处理该订单资金,请发起退款。具体流程请参考订单生命周期

问:订单授权支付成功后若不请款,会自动撤销吗?

答:会的。订单授权成功后,最晚在 7 天内需要发起请款,否则 Antom 将自动撤销该订单以解冻资金,无需您额外调用 cancel 接口。同时,为避免买家资金被冻结 7 天,建议您主动调用 cancel 接口为买家提前释放资金。

退款 服务端

不同支付方式的退款能力各有差异,若您需要了解 Antom 的退款规则及如何对成功的交易发起退款,请参阅退款

争议 服务端

当某笔交易发生争议时,Antom 为您提供争议处理相关服务。更多信息请参阅争议运营手册

最佳实践

以下最佳实践有助于您优化集成流程,提升开发效率:

支付方式特性

本章节为您介绍在集成不同卡品牌时需要注意的参数。同时,服务端-服务端模式支持以下卡支付特性,点击了解不同特性的具体信息及使用方法:

国际卡

以下表格展示了在使用 Visa、MastercardAmerican Express、Cartes Bancaires、Diners、Discover、JCB、UnionPay 等国际卡支付时需要注意的参数:

参数名称

描述

备注

paymentMethod.paymentMethodMetaData.cardNo

明文卡号。由商户端采集的买家卡号信息。

必传

paymentMethod.paymentMethodMetaData.expiryYear

卡有效期(年)。请使用两位数字格式传入,例如:2024 年应传入 24

必传

paymentMethod.paymentMethodMetaData.expiryMonth

卡有效期(月)。请使用两位数字格式传入,例如:9 月应传入 09

必传

paymentMethod.paymentMethodMetaData.cvv

卡安全码(CVV)。

首次支付建议传递,COF 场景不建议传递。

paymentMethod.paymentMethodMetaData.cardholderName

持卡人姓名。仅支持英文姓名。

必传

paymentMethod.paymentMethodMetaData.billingAddress

与持卡人卡账户关联的账单地址。

必传若发卡国为 USCAUK,建议传递该参数)

本地卡

以下表格展示了使用国家地区的本地卡品牌支付时需要注意的参数:

参数名称

描述

是否必需

韩国卡

巴西卡

智利卡

墨西哥卡

秘鲁卡

土耳其卡

paymentMethod.paymentMethodMetaData.cardNo

明文卡号。由商户端采集的买家卡号信息。

paymentMethod.paymentMethodMetaData.expiryYear

卡有效期(年)。请使用两位数字格式传入,例如:2024 年应传入 24

paymentMethod.paymentMethodMetaData.expiryMonth

卡有效期(月)。请使用两位数字格式传入,例如:9 月应传入 09

paymentMethod.paymentMethodMetaData.cvv

卡安全码(CVV)。

paymentMethod.paymentMethodMetaData.cardholderName

持卡人姓名。仅支持英文姓名。

建议传入

建议传入

建议传入

paymentMethod.paymentMethodMetaData.dateOfBirth

持卡人的出生日期,格式为 YYYY-MM-DD

是(韩国个人卡必传)

paymentMethod.paymentMethodMetaData.cardPasswordDigest

卡支付密码的前两位数字。

paymentMethod.paymentMethodMetaData.businessNo

10 位数字的公司卡商业号码。

是(韩国公司卡必传)

paymentMethod.paymentMethodMetaData.cpf

巴西个人纳税人税号。

跨境场景必传;本对本非必传

paymentMethod.paymentMethodMetaData.payerEmail

付款人的电子邮箱地址。