自建收银台

自建收银台可助力您的网站快速开启在线收款功能,适用于自己维护收银台列表的商户。您可以在自有页面展示商品信息以及对应的支付方式,买家支付时,跳转到 Antom 全球商家账户的支付页面进行支付。本文将介绍如何集成桌面端的支付方案。

用户体验

下图展示了买家在商户页面中的一般操作流程:

image.png

支付流程

每种支付方式的支付流程由以下步骤组成:

yuque_diagram (21).png

  1. 买家进入结账页面
  2. 创建支付请求
    • 买家下单后,商户服务端根据支付方式、金额、币种、商品等交易信息调用 pay(单笔支付)接口以发起支付请求并获取 normalUrl
  1. 处理 Antom 支付页面 URL
    • 商户服务端获取 normalUrl 后,将该 normalUrl 传递给前端,由商户前端跳转至支付页面。
  1. 获取支付结果
    • 买家完成支付后,商户端通过异步通知或者 inquiryPayment 接口获取支付结果。 您需要在 pay(单笔支付)接口中设置paymentNotifyUrl 参数以接收异步通知,如果支付成功或者支付过期,Antom 会通过 notifyPayment 发送通知。

集成准备

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

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

集成步骤

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

  1. 创建支付请求并获取重定向 URL
  2. 处理 Antom 支付页面 URL
  3. 获取支付结果

步骤 1: 创建支付请求 服务端

调用 pay(单笔支付)接口发起支付请求,通过响应返回的 normalUrl 参数获取重定向 URL。

以下是请求参数重点字段:

字段类型

字段名

是否必需?

描述

基本字段

paymentRequestId

商户生成的专属 ID。
paymentAmount

支付金额,以支付货币的最小单位设置。

paymentRedirectUrl

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

paymentNotifyUrl

支付结果通知地址,可通过接口指定或在门户上设置固定值。

paymentMethod.paymentMethodType

支付方法选项中包含的支付方法类型。 对于此集成,固定值为 ANTOM_BIZ_ACCOUNT

订单字段

order.orderAmount

直接向客户提供服务或商品的商家的订单金额。

order.referenceOrderId

商户系统中用于识别订单的唯一编号。

order.goods

货物信息,包括订单中货物的 ID、名称、价格和数量。需注意:

  • 在机票场景下,goodsName 的值必须格式化为 “机票-日期-航班号-出发-到达”。 订单含多件商品时,每个产品的信息必须采用此格式,用逗号分隔,同时需同步录入所有商品信息。
  • 在酒店场景下,goodsName 的值必须格式化为 “住宿时间 (20250101-20250102),酒店名称”。订单含多件商品时,每个产品的信息必须采用此格式,用逗号分隔,同时需同步录入所有商品信息。
  • orderAmount paymentAmount 的值等于所有 goods 的金额之和。 当一个订单中涉及多个产品时,请参考以下公式: goodsUnitAmount No.1 * goodsQuantity No.1 +goodsUnitAmount No.2 * goodsQuantity No.2 =orderAmount /paymentAmount。
  • goods 字段中, referenceGoodsIdgoodsNamegoodsUnitAmount goodsQuantity 四个字段为必填项。
order.buyer

包括买家的 ID、姓名、电话号码和电子邮件的买家信息。传入该参数时,必须同时传入 referenceBuyerId buyerName.fullName

order.transit

行程信息,包括出行方式、行程段和乘客信息。若为机票场景下的交易,此字段为必填项。当 transit 信息为必填项,则 transitType legs.departureTimelegs.departureAddress.citylegs.arrivalAddress.city legs.carrierNo 字段为必传。

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

以下代码为调用 pay(单笔支付)接口以发起支付请求的示例:

copy
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setClientId(CLIENT_ID);
alipayPayRequest.setPath("/ams/api/v1/payments/pay");
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);

// 替换为您的 paymentRequestId
alipayPayRequest.setPaymentRequestId("paymentRequestId01");

// 设置 amount
Amount amount = new Amount();
amount.setCurrency("USD");
amount.setValue("100");
alipayPayRequest.setPaymentAmount(amount);

// 设置 paymentMethod
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setPaymentMethodType("ANTOM_BIZ_ACCOUNT");
alipayPayRequest.setPaymentMethod(paymentMethod);

// 设置 order 信息
Order order = new Order();
order.setReferenceOrderId("referenceOrderId01");
order.setOrderDescription("antom test order");
order.setOrderAmount(amount);
alipayPayRequest.setOrder(order);

//设置 env 信息
Env env = new Env();
env.setTerminalType(TerminalType.WEB);
alipayPayRequest.setEnv(env);

// 替换为您的 notifyUrl
alipayPayRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");

// 替换为您的 redirectUrl
alipayPayRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");

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

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

普通支付

copy
{
    "order": {
        "transit": {
            "transitType": "FLIGHT",
            "legs": [
            {
                "departureTime": "2024-11-27T12:01:01+08:00",
                 "departureAddress": {
                        "city": "SZX" //需要符合IATA三位码
                    },
                    "arrivalAddress": {
                        "city": "HKG" //需要符合IATA三位码
                    },
                "carrierNo": "111"
            }
            ]
        },
        "orderAmount": {
            "currency": "CNY",
            "value": "1000"
        },
        "orderDescription": "Cappuccino #grande (Mika's coffee shop)",
        "referenceOrderId": "ORDER_2022111414171****",
        "buyer": {
            "referenceBuyerId": "test1234****",
            "buyerName": {
                "fullName": "Dehua Skr Liu"
            }
        },
        "goods": [
        {
            "referenceGoodsId": "GoodsId-32078",
            "goodsUnitAmount": {
                "currency": "CNY",
                "value": "1000"
            },
            "goodsQuantity": "1",
            "goodsName": "机票-日期-航班号-出发-到达"
        }
        ],
    },
    "env": {
        "terminalType": "WEB"  
    },
    "paymentAmount": {
        "currency": "CNY",
        "value": "1000"
    },
    "paymentMethod": {
        "paymentMethodType": "ANTOM_BIZ_ACCOUNT"
    },
    "settlementStrategy": {
        "settlementCurrency": "CNY"
    },
    "paymentNotifyUrl": "https://www.alipay.com/notify",
    "paymentRedirectUrl": "https://www.alipay.com",
    "paymentRequestId": "PAY_2022111414171****",
    "productCode": "CASHIER_PAYMENT"
}

以下为响应代码示例,其中包含以下参数:

  • result.resultCode:结果代码。返回值为 PAYMENT_IN_PROCESS 时,表示支付已处理。
  • paymentId:由 Antom 分配的用于标识支付的专属 ID。
  • normalUrl:用于跳转至 WAP(仅支持 PC)或默认浏览器/内嵌 WebView 的网页 URL。 当result.resultCode的值为PAYMENT_IN_PROCESS时,返回此参数。
copy
{
    "normalUrl": "https://iexpfront-sea-global.alipay.com/payments/method/checkout/?requestId=9UKjko5EB7eoj6mq8DFLqhh%2BZ5MeSCNC%2BzOFP0%2FeNuU%3D&merchantId=1885rqVlcNMm2A5j%2F7KP%2F6pYOnqCDwjJbaGFvFMKHvVNng%3D",
    "paymentActionForm": "{\"method\":\"GET\",\"paymentActionFormType\":\"RedirectActionForm\",\"redirectUrl\":\"https://iexpfront-sea-global.alipay.com/payments/method/checkout/?requestId=9UKjko5EB7eoj6mq8DFLqhh%2BZ5MeSCNC%2BzOFP0%2FeNuU%3D&merchantId=1885rqVlcNMm2A5j%2F7KP%2F6pYOnqCDwjJbaGFvFMKHvVNng%3D\"}",
    "paymentAmount": {
        "currency": "HKD",
        "value": "1000"
    },
    "paymentCreateTime": "2024-05-27T02:27:13-07:00",
    "paymentId": "20240527194010800100188420225534863",
    "paymentRequestId": "101520240527410134510924020002",
    "redirectActionForm": {
        "method": "GET",
        "redirectUrl": "https://iexpfront-sea-global.alipay.com/payments/method/checkout/?requestId=9UKjko5EB7eoj6mq8DFLqhh%2BZ5MeSCNC%2BzOFP0%2FeNuU%3D&merchantId=1885rqVlcNMm2A5j%2F7KP%2F6pYOnqCDwjJbaGFvFMKHvVNng%3D"
    },
    "result": {
        "resultCode": "PAYMENT_IN_PROCESS",
        "resultMessage": "payment in process",
        "resultStatus": "U"
    }
}

以下为响应代码中 result.resultStatus 字段可能返回的值,您可以根据指引进行处理:

result.resultStatus

信息

后续操作

F

下单失败。

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

U

未知问题。

请根据以下情况处理:

  • 如果返回 PAYMENT_IN_PROCESS,则会跳转到支付链接 (normalUrl)。
  • 如果返回其他错误码,请关闭当前交易或重新更换 paymentRequestId 再次下单。

注意:如果您未收到响应报文,可能是网络超时所致。建议关闭当前交易或重新更换 paymentRequestId 再次下单。

步骤 2:处理 Antom 支付页面URL 客户端

商户服务端获取 normalUrl 后,将该 normalUrl 传递给前端,由商户前端跳转至支付页面。 

获取 normalUrl 后,您需要在浏览器将页面重定向至 Antom 支付页面,或在新标签页打开。

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

下图为跳转的 Antom 支付页面的渲染页面:

image.png

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

买家完成支付或支付超时时,您可通过 Antom 的异步通知获取结果,或主动查询支付状态。

接收异步通知

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

  • 在每笔请求中设置:您可以通过 pay(单笔支付)接口中的 paymentNotifyUrl 字段传入该笔订单的接收异步通知 URL,适用于每个订单有单独通知 URL 的商户。
  • 不在请求中设置:您则可以 Antom Dashboard开发者 > 通知地址 中设置 webhook URL,适用于对于所有订单统一一个通知 URL 的商户。具体操作请参见通知地址

支付通知中涉及以下关键参数:

字段名

是否必需?

描述

paymentRequestId

商户发起支付的唯一 ID。该 ID 与 pay(单笔支付)接口请求中使用的值一致。

paymentId

Antom 为识别支付而分配的支付 ID。

paymentAmount表示支付金额。

actualPaymentAmount

买家支付的金额。该金额与 paymentAmount 的值一致。

paymentMethodType

支付方式选项中包含的支付方式类型。
result.resultCode结果代码。 SUCCESS的返回值表示支付成功。

有关完整参数的更多信息,请参阅 notifyPayment

以下代码显示了请求报文的示例:

copy
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "paymentCreateTime": "2024-05-27T02:27:13-07:00",
  "paymentId": "20240527194010800100188420225534863",
  "paymentRequestId": "101520240527410134510924020002",
  "paymentResultInfo": {},
  "paymentTime": "2024-05-27T02:27:27-07:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

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

result.resultStatus

信息

后续操作

S

支付成功。

存储 paymentId 用于后续的取消交易和退款。

F

支付失败。

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

当您收到 Antom 的异步通知,需要您在返回中按照示例代码格式返回响应,但无需做加签处理。您需要对 Antom 发送的支付通知进行验签,关于如何验证通知的签名并做出响应,请参阅处理通知

无论订单是否支付成功,每个通知请求均需按以下固定格式响应。否则,Antom 会重新发送异步通知。

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

查询结果

Antom 提供发送异步通知的功能,同时也支持主动查询支付结果。调用 inquiryPayment 接口,通过以下参数查询支付结果:

参数名称

是否必需?

描述

paymentRequestId

商户生成的支付请求 ID。

以下示例代码展示了如何调用 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": "101520240527410134510924020002"
}

以下为响应的代码示例:

copy
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "paymentId": "20240527194010800100188420225534863",
  "paymentMethodType": "ANTOM_BIZ_ACCOUNT",
  "paymentRedirectUrl": "https://xxx.com/bgt_launch_app_callback.html?browser_callback_new=1&chTransId=SO000124052709420662253642020002",
  "paymentRequestId": "101520240527410134510924020002",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success",
  "paymentStatus": "SUCCESS",
  "paymentTime": "2024-05-27T02:27:27-07:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

通过 result 字段返回接口调用结果。订单状态需要根据 paymentStatus 来判断:

  • SUCCESS:支付成功。
  • FAIL:支付失败,关闭订单或更换 paymentRequestId 再次发起支付。
  • PROCESSING:支付进行中,继续查询或关单时间后再查询。

支付后

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

取消交易

下单后您可以在一定时间窗口期内通过使用 cancel 接口主动关闭某笔交易,支付成功后可在 T+1日的 00:15(UTC+8:00)之前取消(T 为交易日)。具体操作参见取消交易

退款

在支付成功后,您可以通过调用 refund 接口对成功支付的交易发起退款。具体操作参见退款

对账

交易完成后,您可以使用 Antom 提供的财务报告进行对账。请参阅对账了解关于如何对账和 Antom 结算规则的更多信息。

最佳实践

Antom 为您提供支付结果展示、支付失败重试、接口超时时间设置等最佳实践方案,请参阅最佳实践了解详情。