支付
买家授权成功后,您可以为买家提供代扣款服务,即买家在后续的购物中,每次付款都无需输入支付信息,系统自动完成订单对应金额的扣款。
代扣支付流程有以下两个步骤:
- 发起支付
- 获取支付结果
步骤一:发起支付
如果指定的支付方式余额足够支付买家的订单,您可以调用 支付 接口,发起自动代扣。在请求中注意以下参数:
- productCode: 值为
AGREEMENT_PAYMENT
- paymentMethod.paymentMethodId: 您通过调用 申请支付令牌 接口获取到的支付令牌(accessToken)的值
- paymentExpiryTime: 如果您不指定此字段的值,则代扣请求过期时间为支付请求发送后的一分钟。如果您想限制支付请求的过期时间比一分钟更短,可以通过此字段传入对应的时长。值得注意的是,过期时间不支持比一分钟更长,另外,此字段的值需遵循 ISO 8601 标准。详情参考 支付 接口字段说明。
- paymentNotifyUrl:用于接收异步通知的地址,建议您传入。
在 支付 接口的响应中,您需要根据result.resultStatus字段的值,判断扣款是否成功:
- 值为
S
,则扣款成功。 - 值为
U
,则交易仍在处理中,您需要通过轮询 查询支付结果 接口主动查询交易状态或等待异步通知来获取交易结果。 - 值为
F
,则扣款失败。需要根据 resultCode 进行相关处理。
如果您无法收到响应,建议您使用同样的参数再次调用 支付 接口。
步骤二:获取支付结果
由于网络原因,异步通知有无法触达或延迟的可能性。为了获得准确的支付结果,您必须同时集成异步通知和支付结果查询服务。
1. 接收异步通知
除去同步回跳,您也可以通过 支付 接口中的参数 paymentNotifyUrl 设定异步通知地址,当支付完成,或者支付超时后,支付宝会利用 支付结果通知 通过该地址发送异步通知。
若您收到支付宝的异步通知,需要您在返回中按照示例代码格式返回响应。若未按要求响应异步通知,或者因为网络原因异步通知未送达,通知会在 24 小时内自动重发。通知至多重发 8 次或直至收到正确响应终止发送。发送间隔如下:0分钟,2分钟,10分钟,10分钟,1小时,2小时,6小时,15小时。
【注意】支付渠道在支付成功后会立即发送支付通知,而支付失败的情况下会在关单后发送支付通知,默认关单时间通常为交易发起后的 1 分钟。
2. 主动查询交易状态
建议您在后端通过 查询支付结果 接口主动查询交易状态,可以设置在发起pay请求之后,默认关单时间之前发起轮询。
在 查询支付结果 接口的返回中,务必依赖 paymentStatus 作为交易状态,建议您按照以下表格做后续引导:
paymentStatus | 类型 | 描述 | 采取的行动(唤起支付结果页/应用切换至前台) |
SUCCESS | 交易终态 | 支付成功。 | 显示支付成功。 |
PROCESSING | 交易中间态 | 交易尚在处理中。 | 允许买家继续支付。 |
FAIL | 交易终态 | 买家未支付或支付失败。 | 允许买家继续支付或关闭订单。 |
CANCELLED | 交易终态 | 交易被商家取消。 | 允许买家继续支付或关闭订单。 |
表 1. paymentStatus 字段取值详情
欲知交易状态的更多相关内容,请参考交易状态说明。
3. 最佳实践
为获取准确的支付结果,建议您在数据库中维护一个订单表,至少包含两个字段:订单编号和订单状态。并使用以下方式查询支付结果:
- 异步通知:监听支付宝的异步通知,收到通知后作出回应。然后检查数据库中的订单状态: 如果订单状态是INIT,根据异步通知更新订单状态。 如果订单状态不是INIT,则表示已经通过查询获得了最终支付结果,并相应地更新了订单状态。无需采取进一步操作。
- 支付查询:通过轮询的形式发起对支付结果的主动查询。在每次查询之前,您需要检查数据库中的订单状态: 如果订单状态是INIT,发起查询。如果获得最终支付结果,更新数据库中的订单状态,否则继续轮询过程。 如果订单状态不是INIT,则表示已经进行了查询过程并获得了最终支付结果并用于更新订单状态,无需采取进一步操作。
图 1. 异步通知和支付查询最佳实践