【微信支付】公众号支付

一.公众号支付介绍

公众号支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

◆ 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付

◆ 用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付

◆ 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

二.支付账户

商户在微信公众平台(申请扫码支付、公众号支付)或开放平台(申请APP支付)按照相应提示,申请相应微信支付模式。微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息,如图2.1所示。

图2.1 微信审核通过邮件模板

2.1中的参数说明如2.2图所示:

图2.2 账户参数说明

我写微信公众号支付时,使用了mch_id、APPID、key三个参数。

三.接口规则

1.协议规则


传输方式 :为保证交易安全性,采用HTTPS传输

提交方式 :采用POST方法提交

数据格式 :提交和返回数据都为XML格式,根节点名为xml

字符编码 :统一采用UTF-8字符编码

签名算法 :MD5,后续会兼容SHA1、SHA256、HMAC等。

签名要求 :请求和接收数据均需要校验签名

证书要求 :调用申请退款、撤销订单接口需要商户证书

判断逻辑 :先判断协议字段返回,再判断业务返回,最后判断交易状态

2.参数规定


1、交易金额(重要)

交易金额默认为人民币交易,接口中参数支付金额单位为【分】,参数值不能带小数。对账单中的交易金额单位为【元】。

外币交易的支付金额精确到币种的最小单位,参数值不能带小数点。

2、交易类型

JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里

MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口

3、货币类型

货币类型的取值列表:

CNY:人民币

4、时间

标准北京时间,时区为东八区;如果商户的系统时间为非标准北京时间。参数值必须根据商户系统所在时区先换算成标准北京时间,例如商户所在地为0时区的伦敦,当地时间为2014年11月11日0时0分0秒,换算成北京时间为2014年11月11日8时0分0秒。

标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。

5、时间戳(重要)

标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。

6、商户订单号

商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_、竖线|、星号*这些英文半角字符的组合,请勿使用汉字或全角等特殊字符。微信支付要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生成订单号)。重新发起一笔支付要使用原订单号,避免重复支付;已支付过或已调用关单、撤销(请见后文的API列表)的订单号不能重新发起支付。

等等。。。

3.安全规范-算法(重要)  (微信支付接口签名校验工具


1、签名算法

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

◆ 参数名ASCII码从小到大排序(字典序);

◆ 如果参数的值为空不参与签名;

◆ 参数名区分大小写;

◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

◆ key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

举例如下:

图3.1 传送参数

第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:

图3.2 ASCII字典序排序

第二步:拼接API密钥:

图3.3 拼接密钥

最终得到最终发送的数据:

图3.4 发送的数据

2、生成随机数算法

微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。我们推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串。

四.实践(重要)

1.统一下单

◆ 两个必传参数 :goodsId(商品id)  openid(用户标识)

◆ 生成订单号封装成对象,并插入到订单表中

图4.1 订单数据表

◆ 请求下单时微信必须传递的参数

图 4.2.1 微信下单参数介绍
图 4.2.2 微信下单参数介绍

◆ 请求数据先插入表wxpay_request以便查询

图 4.3 请求记录表

◆ 正式下单 

WXPay wxPay =new WXPay(wxPayConfig);

Map resp = wxPay.unifiedOrder(order);

上两行是微信公众号支付的核心(重要)

其中WXPayConfig这个接口需要我们自己来实现

图 4.4 WXPayConfig接口

上图中的5个抽象方法是需要我们自己创建MyConfig类来实现的

其中的getCertStream()可直接返回null即可,但是getWXPayDomain()此方法实现不能返回null,否则会报如下错误:

图 4.5 微信支付内部源码

getWXPayDomain()方法返回的是一个IWXPayDomain接口,我们创建一个WXPayDomain类来实现这个接口,其中IWXPayDomain中的信息如下图:

图 4.6   IWXPayDomain接口

其中report(String s, long l, Exception e)实现但是不做处理,getDomain方法返回

new DomainInfo(WXPayConstants.DOMAIN_API, true);即可

此时,万事具备,只欠下单操作了:

WXPay wxPay =new WXPay(wxPayConfig);

Map resp = wxPay.unifiedOrder(order);

在这个我说明一下在这里栽的坑。下单的时候,微信那边是要穿spbill_create_ip这个参数的,

这个参数微信给的解释是:

APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。

我在本地测试时,获取本地IP一直报错,后来不得已,将这个参数写死,就可以了,最后写完整个功能之后将写死的放开,在测试环境上毫无问题,自豪感爆棚。。。哈哈。。

下单成功之后,返回结果如下图所示:

图 4.6 微信下单返回

赶紧将微信返回的数据保存到数据库wxpay_response

图 4.7 下单成功存库

如果微信返回的return_code为SUCCESS,说明下单成功,如果这里没有成功就不要往后写了,赶紧回过头看看。。返回成功继续下面的操作。。

签名

图 4.8 微信签名

按照微信介绍的来,记住timeStamp时间戳要以分为单位传递

String.valueOf(System.currentTimeMillis() /1000);

signType:MD5

nonceStr:WXPayUtil.generateNonceStr()

String sign = WXPayUtil.generateSignature(param, key); (重要)

上面一句话生成签名,大功告成。。

◆ 微信内H5调起支付

图 4.9 前端调微信支付所需参数

将上一步生成的数据,以接口的方式返回给前端,前端调起微信支付即可。。

2.支付回调

◆  我们在下单的时候已经将notify_url通知地址传递给了微信端,微信会回调过来

StringwxpayResult(@Context HttpServletRequest request, @Context HttpServletResponse response);

通过这样的方式接口微信端的回调即可。。

Map notifyMap = WXPayUtil.xmlToMap(resultXml);

将微信返回的数据解析成Map类型数据来做处理

1>通过微信返回的out_trade_no(订单号)查询我们内部订单是否存在

2>状态是否时未支付,如果以支付直接返回即可

3>(重要)签名认证

WXPay.isPayResultNotifySignatureValid(Map reqData)

4>将微信返回的数据保存到wxpay_result表中

图 4.10  微信支付回调表

5>微信所有的处理就完了,下面就是你们自己的业务逻辑处理了。。。

很高心和大家一起学习,当然我也是有大佬帮助过的,后期我会更新一些工作中碰到的问题,希望和大家一起进步。。

所有的委屈,都是因为自己能力不够!! 

                                                                                        - 2018.08.23 20:44

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

推荐阅读更多精彩内容