国内支付宝如何支持新加坡用户支付?
结论
国内商户可以支持新加坡用户付款,但仅开通普通的境内支付宝收款还不够。
接入方式取决于用户使用的支付工具:
- 如果新加坡用户持有可以正常付款的支付宝账户,商户可接入支付宝当面付、手机网站支付或电脑网站支付等产品。
- 如果用户希望使用新加坡本地电子钱包、银行卡或新加坡元付款,通常需要申请跨境收单或 Alipay+ 相关能力,由相应的收单机构处理钱包受理、币种转换和资金结算。
- 如果商户要在新加坡的线下门店收款,需要使用适用于境外经营场景的产品,不能直接沿用中国境内门店的支付宝收款码。
接入前,应先确认商户主体、经营地区、支付场景和目标钱包,再到支付宝能力中心选择产品。页面上能查到某个 API,不等于当前商户已经获得调用权限。
为什么普通境内支付宝接口不一定适用
支付宝接口通常与商户签约的产品绑定。接口能否成功调用,除了程序本身是否正确,还取决于以下条件:
- 商户主体所在的国家或地区;
- 商品或服务的实际经营地点;
- 用户使用支付宝还是新加坡本地钱包;
- 支付发生在线上、线下还是 App 内;
- 商户签约的收单产品;
- 产品支持的交易币种和结算币种;
- 风控、实名及跨境业务资质要求。
例如,alipay.trade.precreate 常用于生成支付宝当面付二维码,但该二维码不一定能受理所有新加坡钱包。某个钱包是否可用,要以商户签约的产品、后台配置及支付宝返回结果为准。
推荐的接入路径
1. 明确用户使用什么支付工具
首先要区分两类需求。
使用支付宝付款
如果新加坡用户使用支付宝客户端,且账户具备相应的付款能力,商户可以按支付场景申请境内支付宝产品:
- PC 网站使用电脑网站支付;
- 手机浏览器使用手机网站支付;
- App 使用 App 支付;
- 线下扫码使用当面付。
使用新加坡本地支付工具付款
如果用户要使用本地电子钱包、银行卡或本地币种,应申请跨境收单或 Alipay+ 受理能力。具体支持哪些钱包、币种和结算方式,可能因商户主体和签约渠道而异,不能通过统一收款码的外观来判断。
2. 在开放平台申请对应产品
在支付宝开放平台创建应用后,按以下流程完成配置:
- 完成企业账户认证。
- 根据业务场景创建网页应用、移动应用或其他适用的应用。
- 申请对应的支付产品。
- 配置应用公钥或证书。
- 配置异步通知地址。
- 等待产品签约和应用审核通过。
- 查看产品文档,确认可用 API、网关、币种和必填参数。
如果开放平台没有向当前商户提供跨境或 Alipay+ 产品入口,应联系支付宝或具备相关资质的收单服务商,确认可用的接入方案。
3. 服务端创建支付订单
下面以 alipay.trade.precreate 为例,展示服务端生成二维码的基本结构。该接口适用于已经签约对应产品的扫码支付场景,但不表示它会自动支持所有新加坡本地钱包。
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
APP_ID,
MERCHANT_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
AlipayTradePrecreateRequest request =
new AlipayTradePrecreateRequest();
request.setNotifyUrl("https://merchant.example.com/alipay/notify");
request.setBizContent("""
{
"out_trade_no": "SG202609090001",
"total_amount": "100.00",
"subject": "商品订单",
"timeout_express": "10m"
}
""");
AlipayTradePrecreateResponse response =
alipayClient.execute(request);
if (response.isSuccess()) {
String qrCode = response.getQrCode();
System.out.println("QR Code: " + qrCode);
} else {
System.out.println("code: " + response.getCode());
System.out.println("sub_code: " + response.getSubCode());
System.out.println("sub_msg: " + response.getSubMsg());
}
APP_ID、商户私钥和支付宝公钥必须来自实际应用配置,不能写死在源码中。如果应用采用证书模式,应按对应 SDK 的证书客户端初始化方式处理,不能与普通公钥模式混用。
跨境产品使用的下单接口、请求字段和网关可能与上述示例不同。开发时应查阅商户实际签约产品的接口文档,不要直接套用境内当面付的参数。
4. 验证异步通知
支付完成后,服务端需要验签并核对订单信息,不能只根据前端跳转结果修改订单状态。
Map<String, String> params = getRequestParams(request);
boolean valid = AlipaySignature.rsaCheckV1(
params,
ALIPAY_PUBLIC_KEY,
"UTF-8",
"RSA2"
);
if (!valid) {
response.setStatus(400);
return;
}
String outTradeNo = params.get("out_trade_no");
String tradeStatus = params.get("trade_status");
String totalAmount = params.get("total_amount");
String appId = params.get("app_id");
String sellerId = params.get("seller_id");
// 还需从数据库读取订单,并核对:
// 1. out_trade_no 是否存在
// 2. total_amount 是否一致
// 3. app_id 和 seller_id 是否属于当前商户
// 4. 订单是否已经处理,避免重复入账
if ("TRADE_SUCCESS".equals(tradeStatus)
|| "TRADE_FINISHED".equals(tradeStatus)) {
markOrderPaidIdempotently(outTradeNo);
}
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().write("success");
支付宝可能重复发送异步通知,因此订单更新必须保证幂等。即使验签成功,也要继续核对金额、商户号和应用 ID,不能直接认定订单信息无误。
币种与结算需要单独确认
新加坡用户付款时看到的币种,未必与国内商户最终收到的结算币种一致。跨境交易可能涉及:
- 订单计价币种;
- 用户实际扣款币种;
- 汇率换算;
- 商户结算币种;
- 跨境手续费;
- 退款时产生的汇率差异。
不要自行添加接口文档中没有确认的 currency 参数。部分境内支付产品只接受人民币金额,跨境产品可能采用不同的字段或订单模型。具体能力应以签约产品文档和商户后台显示的信息为准。
上线前必须确认的事项
- “支付宝用户可以付款”不等于所有新加坡用户都可以付款。
- “支持 Alipay+“不等于自动支持全部合作钱包。
- 沙箱环境通常只能验证接口流程,不能证明真实的新加坡钱包一定可用。
- 支付密钥只能保存在服务端,并通过密钥管理或环境配置注入。
notify_url必须能够被支付宝从公网访问,并使用 HTTPS。- 下单、查询、退款和关单应使用同一套商户订单号体系。
- 支付结果应以服务端异步通知和主动查单为准,不能只相信客户端回调。
- 退款能力、退款币种和到账时间要按实际签约产品确认。
- 跨境收款还可能涉及商品类目、外汇结算、税务和合规审核。
接入前,最好先向支付宝或收单服务商提供商户主体、经营地点、线上或线下场景、目标支付工具、计价币种和结算币种。确认产品能够覆盖这些条件后,再按照该产品在能力中心列出的 API 进行开发。
备注:内容仅供参考。
