首页 >> 行业资讯 >>聚合支付 >> 微信扫码支付实现过程
详细内容

微信扫码支付实现过程

课程目标

    掌握二维码生成插件qrious的使用
    能够说出微信支付开发的整体思路
    能够调用微信支付接口(统一下单)生成支付二维码
    能够调用微信支付接口(查询订单)查询支付状态
    实现支付日志的生成与订单状态的修改

一. 二维码
1.1 什么是二维码

    二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。

    二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

    图示:

   

1.2 二维码的优势:

    信息容量大, 可以容纳多达1850个大写字母或2710个数字或500多个汉字
    应用范围广, 支持文字,声音,图片,指纹等等…
    容错能力强, 即使图片出现部分破损也能使用
    成本低, 容易制作

1.3 二维码的容错级别:

    L级(低) 7%的码字可以被恢复。
    M级(中) 的码字的15%可以被恢复。
    Q级(四分)的码字的25%可以被恢复。
    H级(高) 的码字的30%可以被恢复。

二. 二维码生成插件qrious:
2.1 qrious是一款基于HTML5 Canvas的纯JS二维码生成插件。通过qrious.js可以快速生成各种二维码,你可以控制二维码的尺寸颜色,还可以将生成的二维码进行Base64编码。
2.2 qrious.js二维码插件的可用配置参数如下:

    方块确定方位,黑色代表1,白色代表0

三. 微信扫码支付
3.1 介绍:

    微信扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于 PC 网站支付、实体店单品或订单支付、媒体广告支付等场景。

3.2 申请步骤:(了解)

    第一步:注册公众号(类型须为:服务号)
    请根据营业执照类型选择以下主体注册:个体工商户| 企业/公司| 政府| 媒体| 其他类型。

    第二步:认证公众号
    公众号认证后才可申请微信支付,认证费:300 元/次。

    第三步:提交资料申请微信支付
    登录公众平台,点击左侧菜单【微信支付】,开始填写资料等待审核,审核时间为 1-5个工作日内。

    第四步:开户成功,登录商户平台进行验证
    资料审核通过后,请登录联系人邮箱查收商户号和密码,并登录商户平台填写财付通备付金打的小额资金数额,完成账户验证。

    第五步:在线签署协议
    本协议为线上电子协议,签署后方可进行交易及资金结算,签署完立即生效。

四. 微信支付SDK
4.1 微信支付接口调用的整体思路:

    按 API 要求组装参数,以 XML 方式发送(POST)给微信支付接口(URL),微信支付接口也是以 XML 方式给予响应。程序根据返回的结果(其中包括支付 URL)生成二维码或判断订单状态
    简单来讲:通过URL将一些参数告诉给微信,然后接受返回值生成二维码

4.2 释义:

    appid:微信公众账号或开放平台 APP 的唯一标识
    mch_id:商户号 (配置文件中的 partner)
    partnerkey:商户密钥
    sign:数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性【每次都不同】

4.3 微信支付SDK

    微信支付提供了 SDK, 下载后打开源码,install 到本地仓库;
    导入依赖:


4.4 我们主要会用到微信支付 SDK 的以下功能:

    获取随机字符串




五. 查询状态
5.1 思路:

    前端循环调用后端
    后端循环调用微信支付查询结果,前端调用后端

5.2 交易状态类型:

    SUCCESS: 支付成功
    REFUND : 转入退款
    NOTPAY: 未支付
    CLOSED: 已关闭
    REVOKED: 已撤销
    USERPAYING: 用户支付中
    PAYERROR: 支付失败(其他原因,银行返回失败)
    支付状态机等可以查看相关文档

六. 支付日志需求
6.1 思路:

    在用户下订单时,判断如果为微信支付,就向支付日志表添加一条记录,信息包括支付总金额,订单id(多个),用户id,下单时间等信息,支付状态为0(未支付);

    生成的支付日志对象放入reids中,以用户id作为key,这样在生成支付二维码时就可以从redis中提取支付日志对象中的金额和订单号;

    当用户支付成功后,修改支付日志的支付状态为1(已支付),并记录微信传递给我们的交易流水号。根据订单id(多个)修改订单的状态为2(已付款).

七. 微信支付准备:
7.1 业务流程:

    选择商品以及相应的规格和数量后点击"加入购物车"。
    当加入购物车后跳转到购物车列表页面,对收货地址,商品添加或者删除等操作后点击"结算"
    当带着参数进入结算页的时候,首先对使用微信支付和货到付款等方式进行判断,然后跳转到相应的页面
    页面通过与微信官方交互然后自动生成二维码,用户扫码之后显示"付款成功"或者"付款失败"等.

7.2 技术分析[准备阶段]:

    微信支付功能必须为服务号才能申请微信付款功能,这个由公司完成并提供给我们相关的账户和密码;
    查看微信支付SDK文档,获取大概的流程;
    首先应该在本地仓库中配好微信支付SDK的jar包,并引入微信支付SDK的依赖

八. 支付流程图

九. 流程及代码
9.1 首先生成微信二维码:

    准备:
        通过HttpClient工具类实现对远程支付接口的调用
     
        参考文档:统一下单API

    开始:
         创建一个map集合,将需要发送给微信的数据存入map集合内
        
        通过HttpClient发送给微信
        获取XML结果后调用WXPayUtil工具类将它转为Map格式的数据
        创建一个新的Map集合,将获取的结果存入新建的map集合内 【这里的数据是要展现给前端的,所以只存一些需要展示的,不必所有都存入,否则安全性有影响】
        将集合返回

       
        建立一个生成微信二维码的方法,调用雪花算法将订单号和支付类型作为方法参数调用,将得到的map集合返回上去;

     
        建立一个本地支付的方法,指向


        建立一个本地生成二维码的方法,前端页面调用此方法进行查询后端,获取结果后得到订单编号和金额大小,同时在这里生成二维码,将订单编号和金额大小都返回到前端页面;

        pay.html:

            首先引入js相关文件,创建二维码的js文件,以及绑定初始调用ng-init生成二维码功能
            将放置二维码图片的地方
            显示订单:订单号: 显示金额:¥{{money}}元

9.2 然后,检测支付状态:

    准备:
        需求:
        当用户支付成功的时候我们应该跳转到成功页面,提示:恭喜您,付款成功啦!,支付方式:微信支付 支付金额:xxxx元
        当用户支付失败的时候我们应该跳转到失败页面,提示:支付失败,请稍后再试! 失败原因:… 提供一个重新支付按钮以及跳转到品优购首页的功能

    实现思路:
        我们可以通过HttpClient工具类实现对远程支付接口的调用
        微信接口链接:
        参考文档: 查询订单API
        思路:
            我们可以在后端建立查询状态方法,方法内通过循环查询,如果获取到结果则进行判断:
                如果结果为Null,则返回空map集合,
            前端进行循环调用查询状态方法。前端controller.js对返回的结果进行判断:
             
    开始:
       
            创建查询状态方法,接收参数订单编号
            实现查询状态方法,新建一个HashMap,然后存入公众号id,商户号id,订单号,随机字符串,以及查询订单状态的url地址;
            【URL地址是微信提供的,其他通过配置文件注入和参数接收】
            通过WXPayUtil将Map集合转为XML格式的字符串,然后通过HttpClient传入url地址发送获取状态;
            接收状态并将其转为Map集合,然后返回结果,如果获取失败则打印异常;

        1. 先定义一个实体类
        2. 循环调用Service层的查询订单状态方法并获取返回值;
        3. 对返回值进行判断,如果
        5. 线程等待每3秒执行一次

        创建查询状态方法并指向查询状态的地址和方法,传给它订单编号;

中创建查询状态方法,方法中对返回结果进行判断,
        - 如果返回结果为true,则跳转到支付成功页面
        - 如果返回结果为false,则跳转到失败页面

            将该方法在createNative生成二维码的时候进行调用,这样在二维码生成的时候就完成了查询订单状态的功能;
            因为二维码是初始化init就进行调用,所以生成二维码开始起就可以对二维码状态进行查询;

9.3再然后,我们需要加一个查询时间限制

    准备:
        需求:

            如果用户到了二维码页面一直未支付,或是关掉了支付页面,我们的代码会一直循环调用微信接口,这样会对程序造成很大的压力。所以我们要加一个时间限制或是循环次数限制,当超过时间或次数时,跳出循环。

    实现思路:

        可以在中的查询状态方法内定义一个计时器,

        在 前端中中再添加一个判断,如果成功则跳转,如果失败则进行判断,如果返回的结果是二维码超时,则重新生成二维码,否则就跳转到失败页面;

        、

9.4 再然后,支付成功页面我们应该显示金额

    准备:
        需求:现在我们支付成功页面显示的是固定的值,怎么显示真正的支付金额呢?我们这里可以使用 angularJS 的页面传参来解决
        实现思路:
            中的查询支付状态方法内,如果返回的result是true,支付成功,那么我们在跳转到支付成功页面的时候应该传入参数:$scope.money [付款金额]
    开始:
       :
        - 跳转页面传参,当支付成功后跳转到成功页面的时候传入付款金额


   
        - 用表达式显示金额:

        支付金额:¥{{getMoney()}}元

9.5 最后,我们应该添加一个支付日志的功能

    准备:
        需求:
        - 系统中无法查询到支付记录
        - 支付后订单状态没有改变
        实现思路:
            在用户下订单时,判断如果为微信支付,就想支付日志表添加一条记录,信息包括支付总金额、订单 ID(多个)、用户 ID 、下单时间等信息,支付状态为 0(未支付)
            生成的支付日志对象放入 redis 中,以用户 ID 作为 key,这样在生成支付二维码时就可以从 redis 中提取支付日志对象中的金额和订单号。
            当用户支付成功后,修改支付日志的支付状态为 1(已支付),并记录微信传递给我们的交易流水号。根据订单 ID(多个)修改订单的状态为 2(已付款)。
            分析表结构:根据需求我们应该独立建立一个订单支付日志表,它应该包含:支付订单号,创建事件,支付完成时间,支付金额,交易流水,交易状态,支付类型,订单表id串

    具体思路[解决系统中无法查询到支付记录]:
        interface:
        * 首先我们在接口中创建一个通过用户id查询redis中订单的办法。
        service:
            然后在实现类中的生成二维码方法中先获取当前用户,
            通过当前用户userid查询redis返回一个payLog日志对象,
            然后对其进行判断如果该日志不存在则返回一个【即这个值为null】
            如果该日志存在,则将日志中的订单编号和商品金额作为参数调用返回;

    具体思路[解决支付后订单状态没有改变]
            创建一个修改订单状态的方法,并传入订单编号,和交易号的的方法;


            首先要明确做的三件事情:
                修改支付日志状态
                修改关联的订单的状态
                清除缓存中的支付日志对象

            实现接口新建的修改订单状态方法
                通过日志操作类通过订单编号查询到payLog对象,然后修改payLog对象内的属性,如交易状态,交易号等
                通过日志类payLog()获取订单号列表然后查询到orderList值,
                orderList的值为"xxx,xxx,xxx",我们可以通过spilt(",")方法获取到订单号数组。
                遍历订单编号,通过订单操作类方法查询id值获得订单,如果订单存在则修改状态,并覆盖订单;
                通过redisTemplate查找删除日志id;
                在微信支付接口有成功返回状态时,调用修改状态的方法

联系方式
更多

联系电话:400-805-0125

公司名称 : 上海义国网络科技有限公司

公司地址:上海市杨浦区国顺东路800号艺术区2楼211

公司邮箱:master@forceun.com

Copyrights 2019 | All Rights Reserved