uni.requestPayment 支付宝支付如何使用美元结算
结论
只在 uni.requestPayment 中添加 currency: "USD",支付宝支付页面不会因此显示美元。
页面显示什么币种、多少金额,取决于服务端创建并签名的支付宝订单,还会受到商户签约产品、收款地区和支付宝跨境支付能力的限制。客户端传入 currency,无法把人民币订单改成美元订单。
要让用户以美元计价,需要满足以下条件:
- 商户已经开通支持美元交易的支付宝跨境支付产品。
- 服务端通过该产品对应的支付宝接口创建订单。
- 服务端订单将交易币种明确设置为
USD。 uni.requestPayment接收的是服务端生成的完整、合法且已签名的orderInfo。
如果接入的是中国大陆支付宝 App 支付,交易币种通常按人民币处理。是否可以使用美元计价,应以商户实际签约的支付宝产品及其接口文档为准。
为什么客户端设置 currency 没有效果
支付宝支付的金额和币种不是由前端临时决定的。常见调用流程如下:
- 前端向业务服务器请求支付订单。
- 服务器调用支付宝接口,生成订单参数并完成签名。
- 服务器将
orderInfo返回给前端。 - 前端通过
uni.requestPayment拉起支付宝。 - 支付宝校验签名,再按照订单中的金额和币种显示付款页面。
因此,下面的写法无法修改已经签名的支付宝订单:
uni.requestPayment({
provider: 'alipay',
orderInfo,
currency: 'USD',
success(res) {
console.log('支付调用成功', res)
},
fail(err) {
console.error('支付调用失败', err)
}
})
如果 orderInfo 对应人民币订单,支付宝仍会显示人民币。客户端自行添加或修改币种字段,还可能导致订单参数与签名不一致。
正确的配置方式
1. 先确认商户产品是否支持美元
先在支付宝商户后台或对应的跨境支付平台确认以下信息:
- 当前签约的是境内 App 支付还是跨境支付产品;
- 交易币种是否支持
USD; - 支付页面是否支持直接显示美元;
- 最终结算币种是美元还是人民币;
- 是否需要提供额外的跨境贸易、商品或收款信息。
“交易币种”和“结算币种”不是同一个概念。例如,订单可以美元计价,但支付宝可能按照产品规则换算后,以人民币向商户结算。也有些产品要求订单只能使用人民币。具体规则取决于签约产品,无法通过前端参数更改。
2. 在服务端创建美元订单
币种应在服务端调用支付宝下单接口时设置,不能等到调用 uni.requestPayment 时再补充。
不同支付宝产品使用的接口和字段可能不同。下面的代码只用于说明处理结构,实际字段名称应以商户所签约产品的官方文档为准:
// 服务端示意代码
async function createAlipayOrder(order) {
const requestData = {
merchant_order_no: order.orderNo,
subject: order.subject,
amount: {
currency: 'USD',
value: order.amount
}
}
// 使用商户私钥签名,并调用所签约产品对应的支付宝下单接口
const alipayOrder = await alipayClient.createOrder(requestData)
return {
orderInfo: alipayOrder.orderInfo
}
}
不要直接把人民币金额当成美元金额传入。服务端应根据商品定价或明确的汇率规则计算金额,并按照接口要求,使用整数最小货币单位或规定的金额格式。
3. 前端只负责传递 orderInfo
前端收到服务端返回的数据后,直接调用支付宝支付:
async function pay() {
const [requestError, response] = await uni.request({
url: 'https://example.com/api/payment/alipay/order',
method: 'POST',
data: {
orderNo: 'ORDER_202609090001'
}
})
if (requestError) {
console.error('创建订单失败', requestError)
return
}
uni.requestPayment({
provider: 'alipay',
orderInfo: response.data.orderInfo,
success(result) {
console.log('支付宝返回支付结果', result)
},
fail(error) {
console.error('支付未完成', error)
}
})
}
前端不应修改 orderInfo 中的金额、币种、商户号或签名。
如果只能使用境内支付宝 App 支付
如果商户只开通了境内支付宝 App 支付,而且该产品只接受人民币订单,就无法通过 currency: "USD" 将支付页面改成美元。
这种情况通常有两种处理方式:
- 商品以美元定价,由服务端按照业务确定的汇率换算成人民币,再创建支付宝订单。支付页面显示人民币;
- 申请并接入支持美元计价的支付宝跨境支付产品,再按照该产品的接口重新实现服务端下单。
例如,服务端换算后创建人民币订单:
const usdPrice = 10
const exchangeRate = 7.20
const cnyAmount = (usdPrice * exchangeRate).toFixed(2)
// 使用 CNY 金额创建支付宝境内支付订单
console.log(cnyAmount) // "72.00"
页面还应向用户说明美元标价、使用的汇率和实际需要支付的人民币金额,避免用户误以为支付宝会在付款时自动按美元结算。
注意事项
- 不要让客户端决定支付金额和币种,否则会有篡改风险。
- 不能只根据
uni.requestPayment的success回调判断支付结果。业务服务器还应校验支付宝异步通知,或主动查询订单状态。 - 服务端验签后,还需要核对商户订单号、支付金额、交易币种和商户身份。
- 汇率换算、退款和对账必须采用一致的币种规则。
- 美元显示、美元扣款和美元结算是三个不同的问题,需要分别向支付宝确认。
- 不同地区、商户主体和支付宝支付产品的参数结构可能不同。如果对应的下单接口没有交易币种字段,通常表示该接口不支持商户任意指定美元,也无法通过
uni.requestPayment绕过这一限制。
备注:内容仅供参考。
