【微信公众号开发】八、微信JS发起支付

介绍微信公众号支付流程和实现方法。

【微信公众号开发】八、微信JS发起支付

By img Microanswer Create at:Jul 5, 2019, 11:08:29 AM 

Tags: 微信支付 js支付 微信付款

介绍微信公众号支付流程和实现方法。


重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

目录

本系列博文还包含了下面的博客:

  1. 【微信公众号开发】一、运作及配置流程简介
  2. 【微信公众号开发】二、解析微信请求及响应消息
  3. 【微信公众号开发】三、解析微信事件XML数据消息及响应
  4. 【微信公众号开发】四、公众号按钮设置及自己的微信按钮编辑器
  5. 【微信公众号开发】五、微信网页授权获取用户openId
  6. 【微信公众号开发】六、微信JS的使用
  7. 【微信公众号开发】七、微信JS需要注意的坑
  8. 【微信公众号开发】八、微信JS发起支付(本文)

对于微信JS支付,如果你之前没有对接过相关开发,你可能理解起来有一点困难。为了明白这些开发起了什么作用,必须要先弄清楚微信支付的业务流程,才能理解开发的目的。

一、支付业务流程

就和我们在商店里面购物一样,我们先要有一个商品,然后拿着这个商品去支付。而在互联网上,我们先要有订单,然后支付是为这个订单进行支付。常常自己的业务系统里面有一个自己的订单系统,当我们要为自己的订单系统中某订单进行支付时,微信可不知道我们自己的订单系统是如何运转的,所以要在微信中使用微信进行支付,必须要先创建一个微信系统里面的订单,创建微信系统里面的订单时,是支持指定一部分自定义数据的,如果把这个自定义数据填写为自己的订单系统里面的标识符,这样就可根据这个自定义数据确定我们自己的订单是否支付了。

通常来说,创建一个微信系统中的订单,这个操作称之为:“统一下单”。然后我们支付时其实就是在为这个下好的单进行支付。下面来开一张业务流程图:

支付业务流程

现在你大体上知道了业务流程,所以开发起来疑问就会少很多。虽然流程看起来的却简单了,但实际上总是会遇到各种问题。这张图忽略了一个很重要的元素,那就是“商户”这个概念,下面我们来说说商户。

1、商户

微信公众号实际上是不具备收款功能的,支持收款的是微信商户,而微信商户上可以绑定多个微信公众号,在这些公众号里面进行的所有支付,钱其实最终都跑到商户上去了。所以,如果你要做支付功能,先要必须由一个商户,才能继续下去,单纯一个公众号想用微信支付是不行的。创建和管理商户你都可以到微信官方商户地址去了解详细信息。

二、开始开发

通过上述流程图,你可知道,要支付前,先要进行统一下单,而统一下单这个操作是需要比较高的权限的,通常都是在后台调用微信的下单接口,而不会直接在前端进行统一下单。意味着我们需要将这个统一下单接口在我们自己的后台系统里封装一遍,暴露给自己的业务前端调用。

1、统一下单

由于支付最终是把钱支付到商户里面的,因此统一下单接口的参数和格式都和微信其他的接口(比如设置微信菜单接口)不太一样。

接口地址:

统一下单接口地址:"https://api.mch.weixin.qq.com/pay/unifiedorder"

请求方式

POST

请求参数

统一下单接口的参数是一个xml数据,不是json数据了,所以不能用平时常用的请求了。这是一个示列请求参数:

<xml>
   <appid>wx242*****c43b</appid>
   <attach>支付测试</attach>
   <body>JSAPI支付测试</body>
   <mch_id>10000100</mch_id>
   <detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail>
   <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
   <notify_url>http://xxxxx/pub_v2/pay/notify.v2.php</notify_url>
   <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
   <out_trade_no>1415659990</out_trade_no>
   <spbill_create_ip>14.23.150.211</spbill_create_ip>
   <total_fee>1</total_fee>
   <trade_type>JSAPI</trade_type>
   <sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>

此接口的参数较多,建议到这里查看详细的参数说明。

2、封装支付参数

当你下单完成后,你就可以在前端调起支付方法引导用户进行支付了。不过为了安全着想,可不是简单的随便一调用,支付界面就弹出来了。

要成功调起支付弹窗,需要一些加密参数,这些参数来自于上一步下单成功的微信订单。当你下单成功后,你需要把这些字段封装好并返还给前端:

timestamp: 后端生成一个当前时间戳(单位[秒])。
nonceStr: 随机字符串,32位及以内的长度。
package:一段描述信息,格式:prepay_id=****。其中****表示统一下单成功得到的 prepay_id 值
signType: 加签格式
paySign: 加签结果

前端通过 wx.chooseWXPay 方法,传入以上参数才可以正常进行支付。而对于以上参数,需要通过后端把值全部计算出来。后端的大致实现流程就像这样(下面是伪代码):

// 第一步、统一下单:
orderResult = post("https://api.mch.weixin.qq.com/pay/unifiedorder", "<xml>....</xml>");

// 第二步、根据下单结果封装前端需要的参数
timestamp = System.now();
nonceStr  = String.randomStr();
package   = "prepay_id=" + orderResult.prepay_id;
signType  = "MD5";

// 生成签名,这个签名使用MD5进行,待签名的各个参数必须按参数名的 ASCII 严格排序。
// 这里涉及了一些更多的参数:
// appId: 公众号的appId
// timeStamp: 就是 上面的时间戳,不过要特别小心,这里的S是大写的,不能是小写的。
// key:是公众号绑定的商户里面的key值。
paySign   = MD5("appId=" + appId + "&nonceStr=" + noncestr + "&package=" + packagestr + "&signType=" + singType + "&timeStamp=" + timestamp + "&key=" + key).toUpperCase();

// 第三步、将封装好的数据返回给前端
response.write({
    timestamp: timestamp,
    nonceStr: nonceStr,
    "package": package,
    signType: signType,
    paySign: paySign
});

3、js发起支付及注意

当前端顺利的拿到统一下单返回并封装好的支付参数时,就可以发起支付了。

wx.chooseWXPay({
    timestamp: timestamp,
    nonceStr: nonceStr,
    "package": package,
    signType: signType,
    paySign: paySign
});

要特别注意,由于支付对安全级别要求比较高,如果这里没有弹出支付窗口,还有必要检查一下商户后台,支付网页所在的目录必须配置到商户后端的支付目录里面,否则也是无法支付的。而对于配置方法,传统html页面十分简单,你的网页在哪个目录,你就配置你对应的目录就好了,而如果你是单页面应用,就应该根据不同路由模式填写了,如果是history模式,则和传统配置相同,如果是hash模式:

  1. 对于页面https://www.microanswer.cn/#/product如果要进行支付,则你应该配置:https://www.microanswer.cn/#/
  2. 对于页面https://www.microanswer.cn/index.html#/product如果要进行支付,则你应该配置: https://www.microanswer.cn/index.html#/
  3. 如果你的页面里有些url即有index.html,有些又只有一个单独的#,那你就干脆把: https://www.microanswer.cn/https://www.microanswer.cn/#/https://www.microanswer.cn/index.html#/全部配上去。

注意以上域名仅做示列,自己配置时要根据自己的域名来。

三、总结

微信支付其实理解了流程后不难开发,只要保证:统一下单正确、支付参数封装正确、公账号绑定的商户正确、商户后台支付目录配置正确基本上就不会出现问题了。

Full text complete, Reproduction please indicate the source. Help you? Not as good as one:
Comment(Comments need to be logged in. You are not logged in.)
You need to log in before you can comment.

Comments (3 Comments)