前言

最近由于业务需求,需要开发付款码功能,该接口底层将会聚合市面上主流钱包 APP 的付款码功能,如微信支付,支付宝支付。

ps:付款码支付别称有很多,如微信支付端支付产品为付款码支付(之前的文档叫做刷卡支付),而支付宝端产品为当面付-条支付,而有些文档会成为二维码被扫支付
下文统一使用微信的定义方式,统称为付款码支付。

可能有些同学对于付款码支付这个听起来很陌生,其实这个功能我们可能每天都在被使用。

像我们在便利店买个早饭,最后结账时,使用支付宝/微信支付付款。收银员会让我们展示支付宝/微信付款码,然后使用扫码枪获取此码,最后上送给微信/支付宝服务端完成一次扣款。

以支付宝为例,具体用户端支付流程如下:

付款码支付后台调用流程如下:

付款码支付详细版流程

微信/支付宝付款码支付调用流程大同小异,官网写的都比较清楚,这里直接用支付宝的官网的流程。

从上面的流程可以看到,付款码支付可以说是一个同步的接口,即接口同步返回扣款结果,无需通过另外异步通知获取结果。

不过这里我们需要注意,由于涉及安全风控等问题,付款码支付过程用户端可能需要输入密码确认支付,此时付款码接口将会返回等待用户支付。

接入时务必这正确判断返回信息,若返回以下结果,代表此时用户正在输入密码。

  • 微信支付: err_code=USERPAYING 或 err_code=SYSTEMERROR
  • 支付宝: code=10003 或 code=20000

微信付款码支付在以下情况需要输入密码二次确认。

支付宝官方文档暂未找到相关规则,经过测试当支付金额大于 2000 ,需要输入密码。如果有熟悉其他验密规则的同学,可以在评论区留言一下。

另外一点需要注意的是,微信/支付宝其他支付接口,支付成功之后,微信/支付宝服务端将会发送消息通知支付结果。但是付款码不一样,该接口是不会有消息通知。

所以如果付款码支付若返回等待用户输入密码,商家后台服务必须定时调用调用微信支付/支付宝查询接口,获取支付结果。

撤销支付

如果在一段时间内比如 30s,轮询查询支付结果返回都是等待用户支付,或者支付交易过程返回失败或支付系统超时,这两种情况官方文档都是建议立刻调用撤销接口撤销交易。

如果此订单用户支付失败,撤销接口将会订单关闭;如果用户支付成功,撤销接口将会订单资金退还给用户。

也就是说撤销支付接口功能上等同于关闭订单加上退款。虽然撤销也具有退款功能,但是两者存在比较大的区别:

支付类型限制

微信/支付宝撤销支付仅能撤销付款码支付类型的订单,而退款可以支持多种支付类型的订单。

退款金额

撤销接口只能是全额退款,而退款接口支持传入金额,可以全额退款,也可以部分退款。

时间限制

撤销接口时间限制比较短,比如微信支付撤销支持 7 天内的订单,而支付宝撤销接口仅支持当天的订单。

但是退款接口可以支持较长时间订单退款,比如微信支付退款支持一年内的订单,而支付宝仅支持 3 个月内订单。

基于以上区别,其他正常支付的单如需实现相同功能请调用退款接口,官方文档建议仅在异常的情况下才建议调用撤销支付接口。

另外再说一点,有些地方这个功能接口称为冲正接口,如下面工商二维码支付。

实际上提供的功能与微信/支付宝撤销类似,这里需要各家支付公司提供文档具体研究。

撤销支付相关问题

由于撤销支付,可能导致退款,也可能关闭订单,接入之前一直有些问题弄不清楚,在官方文档处也没有查询到任何资料,没办法只好实测验证相关问题。

由于规定,支付机构不能直连微信/支付宝,所以以下测试基于银联微信/支付宝通道。
银联提供的接口与直连微信/支付宝存在些许差别,但是主要功能一样。

重复撤销

通过实测,微信/支付宝撤销接口幂等实现,重复撤销返回结果一致。

不过需要注意需要正确判断撤销的返回结果。

比如微信撤销接口成功判断还需要结合 recall 字段,支付宝也有类似字段。

订单状态

微信/支付宝订单状态处理不太一致,微信订单状态比较复杂:

也就是说,付款码订单一旦被撤销成功,再次查询订单,状态将会返回为已撤销(REVOKED)

另外微信对于付款码支付订单有限制,是无法调用关闭订单接口关闭订单,所以在付款码的场景中,是不存在订单状态为 CLOSED—已关闭

接下来说下支付宝的状态,支付宝文档没要给出类似的订单状态机,我根据官方一些文档,以及一些测试结果总结出下方订单状态图。

所以支付宝的付款码订单一旦撤销成功,再次查询原单状态将会返回 TRADE_CLOSED

对账文件数据

当天产生交易之后,次日我们需要拉取微信/支付宝对账文件,逐一核对数据,防止少账,多账问题。

对账设计流程可以参考之前写过的文章:

聊聊对账系统的设计方案

微信/支付宝对账文件只会记录交易成功的订单,所以未支付的订单被撤销是不会出现在对账文件中。但是如果支付成功了,然后又被撤销成功,将会在对账文件中产生两笔记录,一笔正交易,一笔反向退款记录。

正交易与普通的退款的记录都比较好识别,一般可以使用我们上送给微信支付宝订单号。但是撤销导致退款记录,我们无法仅用一个单号识别,我们需要结合另外的字段区分判断。

微信对账文件撤销产生那笔退款,交易状态为 REVOKED,所以我们可以采用商户订单号加交易状态识别出一条记录是否为撤销产生退款记录。

上面银联订单号可以当做是微信支付宝内部产生订单号

支付宝对账文件比较麻烦,撤销产生的退款记录不能跟微信根据交易状态区分。从对账文件上看支付宝撤销产生退款与普通退款接口产生退款记录是一样的。

仔细研究对账文件可以发现一些区别,撤销导致退款记录退款批次与正交易支付宝内部订单号是一致的。而正常退款记录,退款批次号是由商户自己上送的。所以我们可以以此筛选出撤销产生的退款记录。

撤销失败

极端情况下,有可能产生多次撤销都失败的奇葩情况,那怎么办?

这种情况下就不用往系统自动处理方向考虑了,通过线下人工介入处理吧,毕竟这种概率太低了。引用知乎**@天顺**的文章中一句话:

很多时候人工保障比你动脑筋想异常中的异常如何系统自动处理来得反而高效和低成本

这句话大家仔细品,越品越有道理!

最后说一句(求点赞、转发+关注)

付款码支付接入其实比较简单,主要难点在于撤销接口引入之后对于现有的系统的改造,比如撤销成功的订单之后,是直接修改原单的成功状态到撤销状态,还是说再创建一条撤销记录?还有对账系统核对时,对端记录可能比本端多,如何核对?这些问题大家在接入之后一定结合现有系统好好思考一下。

最后,文章难免存在一些疏漏,大家如果发现,可以在评论区留言指出,谢谢支持。

如果你也在从事支付,或者正在对接支付,欢迎加我微信,一起讨论问题,一起成长~

作者:楼下小黑哥
链接:https://juejin.im/post/5e97c109e51d4546cc26ca21

微擎支付返回商户单号_扫码枪轻轻一扫,瞬间扣款,支付背后的原理原来这么简单...相关推荐

  1. 微擎支付返回商户单号_支付宝,微信,银联支付

    https://open.unionpay.com/tjweb/index 银联支付 统一支付接口 接口描述 用于线下刷卡交易.生物特征识别(例如人脸).被扫支付等后台交易. 对于被扫支付,收银员使用 ...

  2. 微擎支付返回商户单号_微信、支付宝支付动态库PayApiFun.dll说明

    微信.支付宝支付动态库PayApiFun.dll说明 PayApiFun.dll这个动态库中包含了:微信付款码支付.生成微信支付二维码扫码支付.按商户单号查询微信支付状态.关闭未支付的微信订单.支付宝 ...

  3. 微擎支付返回商户单号_一步一步教你在SpringBoot中集成微信扫码支付

    一:准备工作 使用微信支付需要先开通服务号,然后还要开通微信支付,最后还要配置一些开发参数,过程比较多. 申请服务号(企业) 开通微信支付 开发配置 具体准备工作请参考Spring Boot入门教程( ...

  4. 微擎支付返回商户单号_聚合支付系统设计(二)

    支付网关与异步通知设计 支付网关 用户下单成功后,要经过收银台发起支付流程,支付网关就是用户发起支付流程的入口地址.支付网关需要接收订单的部分数据(订单号.待支付金额.商品描述信息等)和交易数据(支付 ...

  5. 微擎支付返回商户单号_微信小程序支付流程

    微信支付之小程序支付 微信的支付方式有以下几种,不同的支付方式适用于不同的支付场景,而今天要给大家讲的就是 小程序支付 方式 说到支付功能就要涉及到金钱交易,必定是有比较严格的规范及流程,如要求小程序 ...

  6. 微擎支付返回商户单号_微信刷脸支付流程是怎么样的?

    刷脸支付用于线下消费场景. 视壮科技微信刷脸支付设备具有以下特点: 1.无需提前录入人脸,无需拿出手机,在支持微信刷脸支付的机具上,刷脸并输入手机号验证,即可完成付款使用方便. 2.使用专用 3D 活 ...

  7. 微信支付报出 商户订单号重复 错误问题

    问题描述: 使用微信支付时,在支付页面,由于用户第一次点击了取消或余额不足等原因,没有进行支付.这时,订单已经生成,订单状态为"待支付",当用户继续支付时,微信报出了"2 ...

  8. 微信提现失败:openid与商户appid不匹配;更换了openid,但商户单号未更新

    微信提现失败:openid与商户appid不匹配:更换了openid,但商户单号未更新 公众号先开发,小程序后上线(微信小程序与公众号已绑定) openid与商户appid不匹配 openid是和ap ...

  9. 小程序微信支付提示:商户订单号重复

    最近在有用户反馈,点击订单结束无反应. 去后台看了看报错, 是这个样子的 <xml><return_code><![CDATA[SUCCESS]]></ret ...

  10. 微信支付:商户订单号重复

    调微信同一下单接口,返回值中有 <result_code><![CDATA[FAIL]]></result_code> <err_code><![ ...

最新文章

  1. 基于LZ77算法的文件压缩
  2. Opportunity creation case in Firebug
  3. thinkphp3.2自定义success及error跳转页面
  4. oracle数据库物理结构包含,Oracle - 数据库物理结构
  5. python脚本 pyqt 打包成windows可执行exe文件 pyinstaller
  6. 举例说明计算机在六个方面的应用,第六章 计算机应用基础简答题答案.doc
  7. h5优秀控件_H5匠人手册:霸屏H5实战解密
  8. Javascript第四章内置函数、函数的基本用法第一课
  9. Android安全防护之旅---Android应用反调试操作的几种方案解析
  10. Vue 定义组件模板的七种方式(一般用单文件组件更好)
  11. 线程同步(互斥锁与信号量的作用与区别)
  12. Matlab linspace函数C++实现
  13. mbedtls学习4.mbedtls_RAM/ROM优化指南
  14. 个人创建微信公众号步骤
  15. 计算机如何安装无线网络适配器,无线网卡驱动怎么安装?电脑无线网卡驱动2种安装方法...
  16. Cpp多重继承会产生的问题
  17. js逆向案例-obsfuscator混淆
  18. webrtc 入门第一章 基本设备操作
  19. java项目开发实践 pdf_Java项目开发实践 覃遵跃.pdf
  20. Java笔记--08

热门文章

  1. android opengl把经纬度点用红色点显示在3d地球上,在OpenGL中使用正确的经度和纬度在全球范围内渲染点...
  2. 电脑图片格式怎么批量转换jpg?几个小妙招轻松转换
  3. python代码 将文件夹下的.png图片转换为.mat图片 批量转换为mat
  4. ngx_lua arg类型_使用模式,Arg和类型微调Drupal主题
  5. 计算机书籍排版抓图要求,计算机录入与排版
  6. 【开发模板】Vue和SpringBoot的前后端分离开发模板
  7. html生成pdf java_Java实现HTML代码生成PDF文档
  8. MATLAB之模型仿真(一)简单自由落体运动
  9. python_lintcode_52翻转字符串_128哈希函数
  10. JPEG添加EXIF