服务端-服务端模式

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

本文介绍了如何通过服务端到服务端模式集成银行卡支付方法。这种集成方法适合对支付流程定制程度有高要求的商家。服务端到服务端集成模式要求您符合 PCI 资格。具体的 PCI 资质请和各机构确认。

以下是 Antom 的 PCI 资质要求:

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

注意:卡支付托管模式集成方案与本方案调用的接口一致,如果您没有 PCI 资质或者您不希望自己采集卡信息,请选择托管模式

用户体验

以下图示展示了首次支付和已保存的银行卡支付的用户体验。

首次支付

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

Web 用户体验

web-首次支付.png

已存卡支付

Web 用户体验

web-已存卡支付.png

支付流程

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

服务端到服务端时序图.png

  1. 买家输入卡信息并选择是否绑卡。
  2. 提交支付请求。
    买家选择支付方式并提交订单后,调用 支付 接口以获取支付链接来完成支付。
  3. 买家跳转至 3D 验证页面。
    买家跳转至 3D 验证页面完成身份核验(如遇无摩擦验证则免核验),随后返回商户支付结果页。
  4. 获取授权支付结果。
    商户服务端会接收支付平台返回的支付结果通知,并根据结果进行相应的业务处理。
  5. 请款并获取请款结果
    您需要在授权支付成功后发起请款。之后您可以通过以下两种方法之一获取请款结果
    • 异步通知:在 支付 接口中设置 paymentNotifyUrl 参数,以指定接收异步通知的地址。当支付成功或过期时,APO 会使用 请款通知 向您发送异步通知。
    • 手动查询:调用 支付结果查询 接口来查询支付请求状态。

注意若您在多机构下开通了同一个支付方式,请在 APO Dashboard 完成路由配置。若不配置,则 APO 会采取随机路由规则。

集成准备

集成 APO 服务端 SDK 资源包,并完成接口库安装和请求示例初始化。具体操作参见服务端 SDK

集成步骤

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

  1. (可选)显示支付方式
  2. 授权支付
  3. (可选)跳转至 3D 验证页面
  4. 获取授权支付结果
  5. 请款并获取请款结果

步骤 1:(可选)显示支付方式 客户端

首次支付

您可以添加您计划集成的支付方式的标识和名称,这使得买家在首次支付时可以轻松选择他们更喜欢的支付方式。您可以通过联系 APO 技术支持来获取标识和名称。

添加支付方式后的页面效果如下所示:

5.png

步骤 2:授权支付 服务端

当买家选择支付方式时,您需要收集关键订单信息,如买家的支付方式信息、订单信息、设备信息和支付金额等,并需要调用 支付 接口提交支付请求。

1. 调用支付接口

以下示例代码展示了如何调用 支付 接口:

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("tokenize", false);
     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");

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

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

2. 发起支付请求

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

参数名称

是否必需

描述

productCode

在此场景中,值设置为 CASHIER_PAYMENT

paymentRequestId

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

paymentAmount

支付金额,需按下单币种的最小单位设置,如 CNY 为分,KRW 为元。

paymentMethod

支付方式枚举值,卡支付时固定为 CARD

paymentRedirectUrl

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

paymentNotifyUrl

支付结果通知地址,可以在接口传入,也可以在 APO Dashboard 里设置一个固定值。

settlementStrategy

该笔支付的结算币种,若业务签约了多个结算币种,需在接口中指定。仅 Antom 收单机构生效。

order.buyer

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

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

order.referenceOrderId

商户端订单号。

order.orderDescription

商户端订单描述。

env.terminalType

指定买家发起交易的端类型。有效值为:

  • WEB:商户 PC 网站。
  • WAP:商户 H5 网站。
  • APP:商户 app。

env.osType

买家发起交易的环境。当买家在商户手机浏览器网站发起时,此参数值则为 ANDROID 或者 IOS

env.clientIp

买家当前的 IP。卡支付场景下,需提供买家的 IP 信息。

paymentFactor.isAuthorization支付模式。固定传 true,指定为授权请款模式。

paymentMethod.paymentMethodMetaData.cardNo

卡支付场景下,您需自行采集卡信息需传入明文卡号。

paymentMethod.paymentMethodMetaData.expiryYear

卡支付场景下,您需自行采集卡信息需传入卡有效期-年。

paymentMethod.paymentMethodMetaData.expiryMonth

卡支付场景下,您需自行采集卡信息需传入卡有效期-月。

paymentMethod.paymentMethodMetaData.cvv

在卡片支付场景中,首次支付以及后续使用新卡支付时,传入卡的 CVV 信息将有助于提高支付成功率。

paymentMethod.paymentMethodMetaData.cardholderName

卡支付场景下,请传入持卡人姓名以提升支付成功率。该参数仅支持英文字符。

paymentMethod.paymentMethodMetaData.is3DSAuthentication

表示交易验证类型是否为 3D Secure。商户需根据当前的风险和争议的考虑,设置订单是否走 3D 验证。有效值为:

  • true :此时 APO 会设置该笔交易为 3D 传递给下游收单机构。
  • false:若不设置该参数或者设置为 false,APO 会设置该笔交易为非 3D 传递给下游收单机构。但是最后会以收单机构的处理为准。

注意:有关完整参数的更多信息以及某些支付方式额外要求,请参阅 支付 接口。

以下代码展示了支付请求报文的示例:

copy
{
  "env":{
    "browserInfo":{
      "acceptHeader":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
      "javaEnabled":false,
      "javaScriptEnabled":false,
      "language":"en",
      "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
    },
    "clientIp":"172.*.*.*",
    "colorDepth":24,
    "deviceId":"d0e9ee6d-be3a-487d-b514-69495000be72",
    "deviceLanguage":"en",
    "screenHeight":723,
    "screenWidth":1536,
    "terminalType":"WEB",
    "timeZoneOffset":0
  },
  "order":{
    "buyer":{
      "buyerEmail":"ken***@gmail.com",
      "buyerName":{
        "firstName":"*******",
        "lastName":"schmitt "
      },
      "buyerPhoneNo":"7046518433",
      "buyerRegistrationTime":"2022-01-10T20:33:07+08:00",
      "referenceBuyerId":"2095667"
    },
    "goods":[
      {
        "deliveryMethodType":"PHYSICAL",
        "goodsCategory":"Bikini Sets",
        "goodsName":"V-neck Strawberry Knotted Tankini Cheeky Bikini Set",
        "goodsQuantity":"1",
        "goodsUnitAmount":{
          "currency":"USD",
          "value":"2290"
        },
        "goodsUrl":"https://m.shopcider.com/product/detail?pid=114496585",
        "referenceGoodsId":"114496585"
      },
      {
        "deliveryMethodType":"PHYSICAL",
        "goodsCategory":"3 Piece Bikini Sets",
        "goodsName":"V-neck Floral Halter Cheeky Bikini Swimsuit With Floral Cover Up Skirt",
        "goodsQuantity":"1",
        "goodsUnitAmount":{
          "currency":"USD",
          "value":"2790"
        },
        "goodsUrl":"https://m.shopcider.com/product/detail?pid=111038664",
        "referenceGoodsId":"111038664"
      },
      {
        "deliveryMethodType":"PHYSICAL",
        "goodsCategory":"3 Piece Bikini Sets",
        "goodsName":"V-neck Halter Floral Tie Side Bikini Swimsuit With Sarong",
        "goodsQuantity":"1",
        "goodsUnitAmount":{
          "currency":"USD",
          "value":"2790"
        },
        "goodsUrl":"https://m.shopcider.com/product/detail?pid=107371032",
        "referenceGoodsId":"107371032"
      },
      {
        "deliveryMethodType":"PHYSICAL",
        "goodsCategory":"One-pieces ",
        "goodsName":"Shaping Lettuce Trim Cut Out Shell Chain O-Ring One Piece Swimsuit",
        "goodsQuantity":"1",
        "goodsUnitAmount":{
          "currency":"USD",
          "value":"2490"
        },
        "goodsUrl":"https://m.shopcider.com/product/detail?pid=114267374",
        "referenceGoodsId":"114267374"
      },
      {
        "deliveryMethodType":"PHYSICAL",
        "goodsCategory":"One-pieces ",
        "goodsName":"Shaping Halter Floral Bowknot Ruched One Piece Swimsuit",
        "goodsQuantity":"1",
        "goodsUnitAmount":{
          "currency":"USD",
          "value":"1990"
        },
        "goodsUrl":"https://m.shopcider.com/product/detail?pid=107966234",
        "referenceGoodsId":"107966234"
      }],
    "orderAmount":{
      "currency":"USD",
      "value":"13184"
    },
    "orderDescription":"Shop in Cider.",
    "referenceOrderId":"8203426867",
    "shipping":{
      "shipToEmail":"ken***@gmail.com",
      "shippingAddress":{
        "address1":"*************************",
        "city":"Waxhaw",
        "region":"US",
        "state":"NC",
        "zipCode":"28173"
      },
      "shippingName":{
        "firstName":"*******",
        "lastName":"schmitt "
      },
      "shippingPhoneNo":"7046518433"
    }
  },
  "paymentAmount":{
    "currency":"USD",
    "value":"13184"
  },
  "paymentFactor":{
    "captureMode":"MANUAL",
    "isAuthorization":true
  },
  "paymentMethod":{
    "paymentMethodMetaData":{
      "billingAddress":{
        "address1":"*******************",
        "address2":"",
        "city":"waxhaw",
        "region":"US",
        "state":"NC",
        "zipCode":"28173"
      },
      "cardNo":"************8842",
      "cardholderName":{
        "firstName":"*******",
        "lastName":"schmitt "
      },
      "cvv":"***",
      "expiryMonth":"**",
      "expiryYear":"****"
    },
    "paymentMethodType":"CARD"
  },
  "paymentNotifyUrl":"https://pay.shopcider.com/pay/v2/notify/callback?platform=ALIPAY",
  "paymentRedirectUrl":"https://www.shopcider.com/payment/success?tradeNo=20250515141372578176868806656&oid=8203426867&payType=ALIPAY_CARD_DIRECT_US&ovt=e51e7e02c94340e7809f5b9a3768ffe4",
  "paymentRequestId":"20250515141372578176868806656",
  "productCode":"CASHIER_PAYMENT",
  "settlementStrategy":{
    "settlementCurrency":"USD"
  }
}

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

  • acquirerInfo收单机构单号信息,建议储存,具体原因请查看单号说明
  • result.resultStatus:授权支付的状态。
  • normalUrl: 需要跳转的 3D 验证页面。
copy
{
  "acquirerInfo":{
    "acquirerMerchantId":"2181110021840423",
    "acquirerName":"ALIPAY",
    "acquirerResultCode":"SUCCESS",
    "acquirerResultMessage":"success",
    "acquirerTransactionId":"20250514114010800100181020233302045",
    "referenceRequestId":"20250514141372220148107038720"
  },
  "authExpiryTime":"2025-05-13T23:33:01-07:00",
  "paymentAmount":{
    "currency":"USD",
    "value":"1339"
  },
  "paymentCreateTime":"2025-05-13T23:32:59-07:00",
  "paymentId":"20250514114010800100181020233302045",
  "paymentRequestId":"20250514141372220148107038720",
  "paymentResultInfo":{
    "avsResultRaw":"Y",
    "cardBrand":"VISA",
    "cardNo":"************9484",
    "cvvResultRaw":"Y",
    "networkTransactionId":"385134235816498",
    "threeDSResult":{
      "cavv":"AQAAAAAAPTYgKe8AmdDhgoYAAAA=",
      "eci":"07"
    }
  },
  "paymentTime":"2025-05-13T23:33:01-07:00",
  "result":{
    "resultCode":"SUCCESS",
    "resultMessage":"success.",
    "resultStatus":"S"
  }
}

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

result.resultStatus信息下一步操作

S

表示授权支付成功。

您可以储存 paymentId,并发起请款。

F

表示授权支付失败。

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

U

表示授权支付进行中。

  • 若返回了 normalUrl商户前端跳转到 normalUrl。
  • 若没有收到 normalUrl,则表示交易处理中,您可选择主动调用 支付结果查询 接口获取支付结果,或者等待支付结果异步通知。

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

常见问题

问:什么是 paymentId

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

问:acquirerInfo 里的信息作用是什么?应该如何消费?

答:acquirerInfo 里的信息代表是收单机构的信息,请查看单号说明文档。

问:terminalType 应该如何设置?

答:terminalType 的有效值为:

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

问:哪些交易需设置为 3D 验证?

答:您可根据订单交易的风险和争议决策是否需要设置为 3D 验证。配置 is3DSAuthentication 的有效值如下:

  • true :APO 会设置该笔交易为 3D 验证传递给下游收单机构。
  • false 或不设置该参数:APO 会设置该笔交易为非 3D 验证传递给下游收单机构。但是最后会以收单机构的处理为准。

问:设置了非 3D 验证的情况下,是直接返回授权支付结果吗?

答:是的。返回的授权结果可能包括以下情况:

  • 交易处理中:您需等待支付结果异步通知或主动调用 支付结果查询 接口查询支付结果;不可直接置为交易失败。
  • 收单机构最终决策交易类型为 3D 验证:买家将会跳转到 3D 验证页面。
  • 无响应:可能是网络超时所致。您可选择主动调用 支付结果查询 接口获取支付结果,或者等待支付结果异步通知;不可直接置为交易失败。

步骤 3:(可选)跳转至 3D 验证页面 客户端

当商户服务端拿到 APO normalUrl 后,将该 normalUrl 传递给前端,由商户前端跳转至 3D 验证页面

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

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

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

不同端会返回不同的 normalUrlAPO 会基于商户传入的 paymentMethodterminalType 决策返回不同的 normalUrl

web.png

常见问题

问:如何处理返回的 3D 验证页链接?

答:网页端 (Web/WAP) 直接跳转即可;移动端可以用网页浏览打开,但是无法保证个别发卡行需要拉起银行端应用。

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

  • 支付成功和支付失败的情况下,可能都有入口可以从支付方式端回跳到商户页面。因此,请勿将 paymentRedirectUrl 固定为 “支付成功页面”,而是以服务端返回的结果为准,避免引起买家误解。
  • 如果您从移动应用端发起交易,需设置 paymentRedirectUrl 为商户应用的 scheme 地址。

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

答:不是。您不能仅凭回跳商户页面来判断支付是否成功,且 APO 不会在 paymentRedirectUrl 拼接表示支付结果的参数信息。回跳商户结果页可能在以下情况中发生:

  • 家支付成功后,可能因网络等原因导致未能回跳至商户页。
  • 即时买家未完成支付,也可能通过支付方式端的入口回跳至商户页面。

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

1. 设置接收通知的 webhook URL

您可以选择以下两种方法中的一种来设置接受通知的 webhook URL:

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

注意

  • 若您在接口和 APO Dashboard 里都设置了 webhook URL,则以接口设置为准。
  • 若跳转 3D 验证页后买家未核实身份,APO 则需要等订单关闭后才会发送支付结果异步通知;默认关单时间以各收单机构为准。

以下代码展示了一个支付结果异步通知的请求报文示例:

copy
{
  "acquirerInfo":{
    "acquirerMerchantId":"WF_wallet_UK",
    "acquirerName":"ADYEN",
    "acquirerTransactionId":"PK6K679WDZS2K8F3",
    "referenceRequestId":"N2025021716031300000460202933868"
  },
  "acquirerReferenceNo":"PK6K679WDZS2K8F3",
  "notifyType":"PAYMENT_RESULT",
  "paymentAmount":{
    "currency":"GBP",
    "value":"1523"
  },
  "paymentCreateTime":"2025-02-16T21:48:05-08:00",
  "paymentId":"20250217164010890100111460207325722",
  "paymentRequestId":"2025021786031300001258802935146",
  "paymentResultInfo":{
    "avsResultRaw":"Y",
    "cardBin":"439654",
    "cardBrand":"VISA",
    "cardNo":"************6044",
    "cvvResultRaw":"M",
    "fingerprint":"2a1b042f23d1a0927175e4fb8893ab9be5f0ffeff54ed87b88f433671fa67cf4",
    "funding":"DEBIT",
    "issuerName":"WISE PAYMENTS LIMITED",
    "issuingCountry":"GB",
    "threeDSResult":{
      "cavv":"N/A",
      "eci":"N/A",
      "threeDSType":"INTERNAL",
      "xid":"N/A"
    }
  },
  "paymentTime":"2025-02-16T21:48:06-08:00",
  "result":{
    "resultCode":"SUCCESS",
    "resultMessage":"success.",
    "resultStatus":"S"
  }
}

您可能会收到请求报文中 result.resultStatus 参数的不同值,请您根据下表指引进行处理:

result.resultStatus

信息下一步操作

S

表示授权支付成功。

您可以储存 paymentId,并发起请款。

F

表示授权支付失败。

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

注意:部分失败场景,如参数异常等,支付 接口会同步返回 F,不会发送异步通知。您可以根据 F 状态直接关闭订单。

2. 异步通知验签

若您收到 APO 的异步通知,您需要对 APO 发送的支付通知进行验签,并按照示例代码格式返回响应,但无需对响应做加签处理。

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);
    }

}

您无需对通知结果响应做加签处理,但是对于每个通知请求均需按以下固定格式响应,与订单支付成功与否无关。

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

常见问题

问:何时会发送通知?

答:这取决于支付是否完成。如果支付完成后,在收到收单机构的通知后 APO 会立即发送异步通知

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

答:是的,对于以下情况,异步通知会在 24 小时内自动重新发送:

  • 如果由于网络原因未收到异步通知。 
  • 如果您收到来自 APO 的异步通知,但您没有按照处理通知的示例代码格式对通知做出响应。 

通知最多可以重发 8 次,或者直到收到正确的响应以终止发送。发送间隔如下:0 分钟,2 分钟,10 分钟,10 分钟,1 小时,2 小时,6 小时和 15 小时。 

问:发货依据是否可以按参数 resultStatus 的值为 S 为准?

答:不可以,需依据请款结果作为发货依据。

问:收到支付结果通知是否需要验签?

答:需要。通过验签 APO 会发送保障回调请求给您,验签时请注意拼装待验签报文时需按标准处理:<http-method> <http-uri> <client-id>.<request-time>.<request-body>,特别是针对 <request-body> 需直接取值而非解析 JSON 后拼装。

步骤 5:请款和获取请款结果

您可以通过配置 支付 接口中的 paymentFactor.captureMode 参数选择全款自动请款或全额手动请款。您可以在请款后通过异步通知或主动查询来获取请款结果。参见请款了解更多详情。

建议您保存收单机构相关信息( acquirerInfo 参数),具体原因请查看单号说明。以下代码展示了主动查询请款结果的响应报文示例:

copy
{
  "paymentResultCode":"SUCCESS",
  "paymentRequestId":"G153202503171022523041",
  "paymentResultInfo":{
    "lastFour":"1358",
    "funding":"CREDIT",
    "issuerName":"ORIENT CORPORATION",
    "expiryMonth":"**",
    "threeDSResult":{
      "cavv":"",
      "xid":"649335d6-1858-4532-8a6e-0579e1b78a2a",
      "threeDSType":"INTERNAL",
      "eci":"05",
      "threeDSVersion":"2.2.0"
    },
    "expiryYear":"**",
    "cardNo":"************1358",
    "cardBin":"428067",
    "holdName":"NIHEI SHUNSUKE",
    "issuingCountry":"JP",
    "avsResultRaw":"I",
    "fingerprint":"a28f7dd0713e2f1d4e9ccae8853f5c0abca5154a03a6559cd985eb409857579b",
    "networkTransactionId":"465076088338711",
    "cardBrand":"VISA",
    "cvvResultRaw":""
  },
  "transactions":[
    {
      "transactionType":"CAPTURE",
      "transactionStatus":"SUCCESS",
      "transactionRequestId":"G153202503171022523041",
      "transactionAmount":{
        "currency":"JPY",
        "value":"120"
      },
      "transactionTime":"2025-03-16T19:27:17-07:00",
      "acquirerInfo":{
        "referenceRequestId":"2025031719031301000600278847294",
        "acquirerTransactionId":"act_yv3fchmu3bre3l3tui5y352yby",
        "acquirerMerchantId":"pc_6cpbmm5qderubjraxrygjehf5q",
        "acquirerName":"CHECKOUT"
      },
      "transactionId":"20250317194010890100111600255676857",
      "transactionResult":{
        "resultStatus":"S",
        "resultCode":"SUCCESS",
        "resultMessage":"success"
      }
    }
  ],
  "paymentAmount":{
    "currency":"JPY",
    "value":"120"
  },
  "acquirerReferenceNo":"pay_6tmvamfcxp5ujbbfjeopyz6v7q",
  "result":{
    "resultStatus":"S",
    "resultCode":"SUCCESS",
    "resultMessage":"success."
  },
  "paymentId":"20250317194010890100111600255689113",
  "paymentResultMessage":"success.",
  "paymentTime":"2025-03-16T19:27:17-07:00",
  "acquirerInfo":{
    "referenceRequestId":"2025031719031300000600278825707",
    "acquirerTransactionId":"pay_6tmvamfcxp5ujbbfjeopyz6v7q",
    "acquirerMerchantId":"pc_6cpbmm5qderubjraxrygjehf5q",
    "acquirerName":"CHECKOUT"
  },
  "paymentStatus":"SUCCESS",
  "paymentCreateTime":"2025-03-16T19:26:42-07:00"
}

支付后操作

查询授权支付结果 服务端

除了可以通过异步通知的功能获取授权支付结果,同时也支持您通过主动查询服务来获取对应的结果。您可以调用 支付结果查询 接口,使用支付的 paymentRequestId 查询授权支付状态。

以下代码展示了如何调用 支付结果查询 接口:

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": "PAY_202506*****942875"
}

建议保存收单机构相关信息( acquirerInfo 参数),具体原因请查看单号说明。以下代码展示了响应报文的示例:

copy
{
  "paymentResultCode":"SUCCESS",
  "paymentRequestId":"G153202503171022523041",
  "paymentResultInfo":{
    "lastFour":"1358",
    "funding":"CREDIT",
    "issuerName":"ORIENT CORPORATION",
    "expiryMonth":"**",
    "threeDSResult":{
      "cavv":"",
      "xid":"649335d6-1858-4532-8a6e-0579e1b78a2a",
      "threeDSType":"INTERNAL",
      "eci":"05",
      "threeDSVersion":"2.2.0"
    },
    "expiryYear":"**",
    "cardNo":"************1358",
    "cardBin":"428067",
    "holdName":"NIHEI SHUNSUKE",
    "issuingCountry":"JP",
    "avsResultRaw":"I",
    "fingerprint":"a28f7dd0713e2f1d4e9ccae8853f5c0abca5154a03a6559cd985eb409857579b",
    "networkTransactionId":"465076088338711",
    "cardBrand":"VISA",
    "cvvResultRaw":""
  },
  "paymentAmount":{
    "currency":"JPY",
    "value":"120"
  },
  "acquirerReferenceNo":"pay_6tmvamfcxp5ujbbfjeopyz6v7q",
  "result":{
    "resultStatus":"S",
    "resultCode":"SUCCESS",
    "resultMessage":"success."
  },
  "paymentId":"20250317194010890100111600255689113",
  "paymentResultMessage":"success.",
  "paymentTime":"2025-03-16T19:27:17-07:00",
  "acquirerInfo":{
    "referenceRequestId":"2025031719031300000600278825707",
    "acquirerTransactionId":"pay_6tmvamfcxp5ujbbfjeopyz6v7q",
    "acquirerMerchantId":"pc_6cpbmm5qderubjraxrygjehf5q",
    "acquirerName":"CHECKOUT"
  },
  "paymentStatus":"SUCCESS",
  "paymentCreateTime":"2025-03-16T19:26:42-07:00"
}

您可能会收到响应报文中 paymentStatus 参数的不同值,请您根据下表指引进行处理:

paymentStatus

信息

下一步操作

SUCCESS

表示授权支付成功。

您可以发起请款。

FAIL

表示授权支付失败。

请关闭订单或更换 paymentRequestId 再次尝试。

PROCESSING

表示授权支付进行中。

您可以继续查询或在关单时间后查询。

常见问题

问:我在查询中需要使用哪些关键参数?

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

  • paymentStatus : 您需要根据此参数来判断授权支付状态。
  • paymentAmount :表示支付的金额。 

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

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

取消交易 服务端

如果需要取消某笔交易,您可以在支持的取消窗口期内通过 取消支付 接口进行操作,详情请参见取消交易

退款 服务端

若您需要了解 APO 的退款规则及如何对成功的交易发起退款,详情请参见退款

争议 服务端

若买家选择使用卡支付方式,会涉及到争议相关的集成,详情请参见争议。

对账

交易完成后,使用 APO 提供的财务报告进行对账。有关如何对账和 APO 结算规则的更多信息,请参阅对账