微信小程序高级能力之一:微信支付

前言

微信支付可以说是微信开放的所有能力中最重要的一个,在小程序中涉及微信支付的场景很多,而且微信支付也是面试环节中常常会问的一个问题。
当然小程序中发起微信支付的代码非常简单,因为没什么好讲的,所以本文主要讲得是后台对接微信支付中所需要做的一些流程。(因为面试中,如果能说出后台对接微信支付过程中的几个主要的点来的话,是很加分的(o)/~)

小程序中调用微信支付

小程序中调用微信支付的代码很简单,如下:

wx.requestPayment({
    timeStamp : '', // 时间戳,必填(后台传回)
    nonceStr : '', // 随机字符串,必填(后台传回)
    package : '', // 统一下单接口返回的 prepay_id 参数值,必填(后台传回)
    signType : 'MD5', // 签名算法,非必填,(预先约定或者后台传回)
    paySign  : '', // 签名 ,必填 (后台传回)
    success:function(res){ // 成功后的回调函数
        // do something
    }
})

这就讲完了?当然没有这么简单,而且这里面有什么好讲的,面试过程中有什么好问的?
我们要讲的当然不是小程序的接口,事实上我们要讲得是后台对接微信支付过程中需要做的事情。

完整的一次微信支付所经历的流程

完整的一次微信支付所经历的的流程大概是这样子的:

①小程序请求后台提供的下单接口,申请支付参数(传递商品id,商品描述body,总金额total_fee等) ——>
②后台接收到请求参数,和原本准备好的参数进行一系列的处理,请求微信后台,获得相关支付参数,再返回给小程序端 ——>
③小程序得到支付的参数,发起支付(4个或5个,因为signType可以约定好也可以后台传回) ——>
④微信支付及其后台处理,请求我们后台预留的回调接口 ——>
⑤ 后台回调接口在接收到回调请求时,对订单进行后续处理(比如订单状态代付款改成已付款)。

参数说明

可以看到,上面流程中,1、2、5是在后台进行的,3是在小程序端进行的,4是微信方进行处理,这样就构成了1个完整的支付流程。
而在后台的1、2、5中,1、5是没有任何难度的,因此主要看流程2。

流程2主要用到的相关参数说明:
appid ---> 小程序appid
body ---> 商品描述
mch_id ---> 商户号(商户开通了微信商户时拿到的id)
nonce_str ---> 随机字符串(自己生成)
notify_url ---> 后台提供的回调接口地址,用于后续处理订单(如改变订单状态等)
openid ---> 用户的openid
out_trade_no ---> 订单号,自己生成,保证唯一即可
spbill_create_ip ---> 终端ip,其实填127.0.0.1也不会影响支付结果
total_fee ---> 总金额,单位是 分
trade_type ---> 交易类型,在小程序支付中为固定值 JSAPI
key ---> 商户自定义秘钥key,在微信商户平台中定义的

后台申请微信支付参数的过程

在上面中,我们已经了解了微信支付所需要的参数。接下来主要是讲解流程2中所需要做的事情。
在流程2中,主要分为4步:

// 1 建立数组
$arr = [
    'appid' => $appid,
    'body' => $body,
    'mch_id' => $mch_id,
    'nonce_str' => $nonce_str,
    'notify_url' => $notify_url,
    'openid' => $openid,
    'out_trade_no' => $out_trade_no,
    'spbill_create_ip' => $spbill_create_ip,
    'total_fee' => $total_fee,
    'trade_type' => 'JSAPI'
]


// 2 对数组进行遍历,按照 key=value这个格式拼接字符串,并在最后加上 key='商户自定义秘钥key',
// 然后md5该值,得到sign  示例如下:
$str = 'appid=$appid&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&openid=$openid&out_trade_no=$out_trade_no&spbill_create=$spbill_create&total_fee=$total_fee&trade_type=JSAPI&key=$key'
$sign = md5(str);




// 3 拿到sign值,加入数组中,并将数组转成xml格式,用curl中的post方式请求微信接口
https://api.mch.weixin.qq.com/pay/unifiedorder

格式如下:
<xml>
   <appid>wx2421b1c4370ec43b</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://wxpay.wxutil.com/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>


// 4 第3步接收到的也是个xml数据,将其转成数组取出prepry_id字段,假设转换成的数组是$unifiedorder

返回格式如下:
<xml>
   <return_code><![CDATA[SUCCESS]]></return_code>
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
   <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
   <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
   <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
   <result_code><![CDATA[SUCCESS]]></result_code>
   <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
   <trade_type><![CDATA[JSAPI]]></trade_type>
</xml>


新建以下数组
$newarr = [
    'appId' => $this->appid,                  // 小程序ID
    'timeStamp' => '',                        // 新生成一个时间戳
    'nonceStr' => $this->createNoncestr(),     // 随机字符串
    'package' => 'prepay_id=' . $unifiedorder['prepay_id'], // 微信后台返回的数据包
    'signType' => 'MD5'      
]

将其转成
appid=appid&timestamp=timestamp&noncestr=noncestr&package=’prepay_id=xxxx’&signtype=signtype&key=key
这种格式,再md5一次,得到paySign


然后返回给小程序端的支付参数数据是 第4步中的

timeStamp
nonceStr
package
signType
paySign


至此,已经OJBK了。

其他注意事项

spbill_create_ip 终端ip 这个字段在文档中是必填的,但其实填个127.0.0.1也没什么影响
total_fee 总金额 单位为 分
notify_url 支付成功后的回调接口,但这个接口乱填,填错,在接口中没有响应或者是返回失败的结果,其实也不影响交易结果,但还是要填正确的地址(为了避免纠纷(o)/~)
notify_url 这个接口中除了改订单状态,还可以做下订单校验什么的。(例如,我和后台曾经测试,后台返回1毛钱,实际支付2毛钱,结果 支付成功...)

参考文章: 参考文章1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容