支付宝小程序如何获取用户可用的支付宝官方券
结论
支付宝小程序通常无法在付款前查询用户账户中”当前可用的全部支付宝官方优惠券”。因此,小程序不能只根据用户持有的优惠券,直接在商品页把 100 元商品显示为”仅需支付 90 元”。
支付宝官方券能否使用、是否可以叠加以及最终抵扣多少,通常由支付宝收银台结合用户、商品、商户、活动规则和支付方式实时判断。小程序应展示商品的实际售价,优惠金额以支付宝收银台显示的结果为准。
目前,支付宝没有向普通小程序开放通用接口,用于查询某个用户持有的全部支付宝官方券并提前计算支付金额。
为什么不能直接查询
支付宝官方券属于用户账户和平台营销资产,涉及用户隐私及营销规则。即使用户持有一张面额 10 元的券,也不代表购买任何 100 元商品时都能抵扣 10 元。优惠券还可能受以下条件限制:
- 仅限指定商户、门店或商品;
- 要求达到最低消费金额;
- 仅支持指定支付方式;
- 存在有效期、地域或用户资格限制;
- 不允许与其他优惠叠加;
- 可能要等用户进入收银台后,才能完成实时核销判断。
所以,不能直接用”商品价格减去券面额”来计算用户的应付金额。
推荐处理方式
1. 商品页展示商品售价
商品原价为 100 元时,建议展示:
商品价格:¥100.00
支付宝优惠以收银台实际展示为准
只有当优惠由商户自己的系统确定,并且能够确认用户符合使用条件时,才适合在商品页显示明确的优惠后价格。
2. 服务端创建支付宝交易
支付订单必须由服务端创建。以下代码仅演示基本流程,实际使用的接口名称和参数应以小程序当前接入的支付宝支付产品文档为准。
// 服务端示意代码
const order = {
out_trade_no: "ORDER_202609090001",
total_amount: "100.00",
subject: "商品名称",
buyer_id: userId
};
// 调用支付宝小程序支付对应的服务端交易创建接口
const result = await createAlipayTrade(order);
// 将支付宝返回的交易凭证传给小程序
return {
tradeNO: result.trade_no
};
不要在小程序前端自行生成订单金额或签名,也不要因为推测用户可能持有优惠券,就把 total_amount 从 100.00 改为 90.00。
3. 小程序唤起支付宝收银台
my.tradePay({
tradeNO: tradeNO,
success: (result) => {
// 前端结果仅用于页面交互
// 最终支付状态和金额应由服务端确认
console.log(result);
},
fail: (error) => {
console.error(error);
}
});
用户进入收银台后,支付宝会根据当时的活动规则,判断是否展示或使用符合条件的官方优惠。
4. 服务端确认最终支付结果
支付完成后,应通过支付宝异步通知或交易查询接口确认以下信息:
- 交易是否支付成功;
- 商户订单号是否一致;
- 交易金额是否符合预期;
- 实际付款、优惠及商户实收相关字段。
不同支付产品返回的金额字段可能不同,应以当前接口文档和实际响应为准,不要假设响应中一定存在某个”官方券抵扣金额”字段。
function handleAlipayNotify(params) {
const verified = verifyAlipaySignature(params);
if (!verified) {
throw new Error("Invalid Alipay signature");
}
if (params.out_trade_no !== expectedOrderNo) {
throw new Error("Unexpected order number");
}
if (params.total_amount !== "100.00") {
throw new Error("Unexpected order amount");
}
// 更新订单前还应检查交易状态,并保证通知处理具有幂等性
markOrderAsPaid(params.out_trade_no);
}
如果是商户自己发行的券
商户自有优惠券和支付宝官方券不是同一类资产。
如果优惠券由商户创建并承担优惠成本,通常可以在商户自己的会员或营销系统中记录领券情况、适用范围和核销状态,并在创建支付宝订单前计算优惠:
const originalAmount = 100.00;
const merchantDiscount = 10.00;
const payableAmount = originalAmount - merchantDiscount;
if (payableAmount < 0) {
throw new Error("Invalid payable amount");
}
这种情况下可以显示”优惠后 ¥90.00”,但服务端必须先验证该券属于当前用户、满足使用条件,而且尚未核销。
如果使用支付宝开放平台提供的商家券、营销券或券核销能力,也只能查询和处理相应产品授权范围内的券,不能借此查询用户账户中的全部支付宝官方券。具体可以使用哪些接口,取决于商户签约的营销产品、应用权限和券类型,需要在支付宝开放平台控制台及对应产品文档中确认。
注意事项
- 不要把”用户持有 10 元券”理解为”本次订单一定减 10 元”。
- 不要通过抓取、模拟或解析支付宝卡包页面来获取用户的优惠券信息。
- 商品页可以显示”最高可优惠”或”收银台可用优惠”等提示,但必须有真实的活动依据,避免承诺无法兑现的到手价。
- 支付结果必须以服务端验签后的异步通知或主动查询结果为准,不能只依赖小程序端回调。
- 对账时应区分订单金额、用户实际支付金额、平台补贴、商户优惠和商户实收金额。具体字段以所接支付产品的官方文档为准。
备注:内容仅供参考。
