JAVA开发微信支付-公众号支付/微信浏览器支付(JSAPI)

支付场景随处可见,上篇文章我已经介绍过支付宝支付的相关知识以及代码,今天我们来介绍一下微信支付的相关业务场景以及集成的相关步骤。

1.获取微信支付四大参数

要想集成微信支付,得先申请两个账号

①微信公众已认证的服务号,并且需要开通微信支付该能(必须是企业才有资格申请,请你找你家产品去申请吧),②微信商户平台账号;这两个账号一个不能少。此处已默认你已有上两个账号

此处是账号模板,请参考:

    微信公众平台:账户:con*******om 登录密码 ******

    公众APPID:wx15*********a8

    APPSECEPT : c210***************892d7

    微信商户平台:账户:149**********6742 登录密码:******

    商户ID:14******42

    API密钥:5d5************b35b

其中比较不好找的是商户的API密钥:在商户平台的账户中心下:需要用户自行下载证书及安装,(略)

至此我们需要的APPID(appid),APPSECEPT(appsecret),商户ID(mch_id),API密钥(paternerKey),四个重要参数已拿到,括号中是我们代码所用的变量名称请提前熟悉。

2:平台配置

(1).配置支付目录:商户平台:

配置此目录是代码中“微信支付”所在页面的地址,可以是目录不一定是全路径-如http://www.wangtao.com/order/-----此一级域名需要ICP备案。

点击添加

(2).配置授权域名:微信公众平台:

    支付过程需要获取用户openid,必须经过网页授权配置才可以,要不然获取不到openid。

点击设置,按说明设置

3.开发流程:

微信支付原理(说白了就是调用官方文档的“统一下单”接口,之后将微信服务器返回的参数做个加工后,返回到前台(JSP页面),就OK了。咱们要做的就是想方设法的凑齐统一下单的所有参数“而已”,“而已”,“而已”,这个而已也就是最大的挑战)。所有参数解释请参考:官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

    咱们只考虑必填参数,其他参数可以就看你的了。

    先来看看所有参数:

其中的必填参数有:

1.        appid APPID (已有)

2.        mch_id 商户ID (已有)

3.        nonce_str 随机字符串

4.        sign 签名

5.        body 所支付的名称

6.        out_trade_no 咱们自己所提供的订单号,需要唯一

7.        total_fee 支付金额

8.        spbill_create_ip IP地址

9.        notify_url 回调地址

10.       trade_type 支付类型

11.       openid 支付人的微信公众号对应的唯一标识

    只要把这11个凑齐就齐活,现在咱们从第3个开始一个一个的获取;在这之前先从官网把公众号支付的sdk下载下来,如图

主要是用其中的WXPayUtil工具类中的一些方法。当然其他的类我看不懂,要是看懂了,就不至于这么费劲了。

好了开始咱们的取值之旅了:

1.        appid APPID (已有)

2.        mch_id 商户ID (已有)

3.        nonce_str 随机字符串用WXPayUtil中的generateNonceStr()即可,就是生成UUID的方法;

4.        sign 签名 用WXPayUtil中的generateSignature(finalMap<String, String> data, String key)方法,data是将除了sign外,其他10个参数放到map中,key是四大配置参数中的API秘钥(paternerKey)(这里不要着急管它,最后处理它);

5.        body 所支付的名称

6.        out_trade_no 自己后台生成的订单号,只要保证唯一就好:如“2018013000001”

7.        total_fee 支付金额 单位:分,为了测试此值给1,表示支付1分钱

8.        spbill_create_ip IP地址 网上很多ip的方法,自己找,此处测试给“127.0.0.1”

9.        notify_url 回调地址:这是微信支付成功后,微信那边会带着一大堆参数(XML格式)请求这个地址多次,这个地址做我们业务处理如:修改订单状态,赠送积分等。Ps:支付还没成功还想这么远干嘛,最后再说。地址要公网可以访问。

10.    trade_type 支付类型 咱们是公众号支付此处给“JSAPI”

11.    openid 支付人的微信公众号对应的唯一标识,每个人的openid在不同的公众号是不一样的,这11个参数里,最费劲的就是他了,其他的几乎都已经解决,现在开发得到这个参数。

    获得openid的部分内容应该不属于微信支付的范畴,属于微信公众号网页授权的东西,详情请参考微信网页授权:

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

获得openid步骤:

第一步:用户同意授权,获取code

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

注意:1. redirect_uri参数:授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理。

2. scope:用snsapi_base 。

通过此链接可以获取code,可以在一个空页面设置一个a标签,链接至其redirect_uri的地址。点击a标签,即可链接到redirect_uri的地址,并携带code。

<a href="https://open.weixin.qq.com/connect/oauth2/authorize?

appid=wx15c*********&redirect_uri=http%3a%2f%2fwww.***.com%2fpay.jsp&response_type=code&

scope=snsapi_base#wechat_redirect">去支付页面pay.jsp并携带code</a>

第二步:通过code换取网页授权access_token(其实微信支付就没有必要获取access_token,咱们只要其中openid,不是要用户信息,此步结果已经就含有咱们需要的openid了)

获取code后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

上一步的code有了,对于此链接的参数就容易了。可是在页面上如何处理是个问题,我是在pay.jsp页面加载完成后将获取code当做参数传异步到后台,在后台中用http相关类发送get请求(可以自行网上查找)。返回的JSON结果为:

{ "access_token":"ACCESS_TOKEN",

"expires_in":7200,

"refresh_token":"REFRESH_TOKEN",

"openid":"OPENID",//就是它,只要这个值

"scope":"SCOPE" }

好了,access_token是有了,不过咱们不关心它,咱们关心的是openid,有了它一就回到咱们“统一下单”接口里,所有的参数已经就位就等发送了。在回顾下11个必填参数:

1.        appid APPID (已有)

2.        mch_id 商户ID (已有)

3.        nonce_str 随机字符串用WXPayUtil中的generateNonceStr()即可,就是生成UUID的方法;

4.        sign 签名 用WXPayUtil中的publicstatic String generateSignature(final Map data, Stringkey)方法,data是将除了sign外,其他10个参数放到map中,key是四大配置参数中的API秘钥(paternerKey)(此时可以处理它了,不过其他10个参数都有了,它就easy了,先new一个map,依次put其他10个参数,就可以用generateSignature方法了,得到了sign后,不要忘记再将sign put到只有10个参数的map中,这样才能凑齐最后的第11个参数。准备召唤神龙吧。);

5.        body 所支付的名称

6.        out_trade_no 自己后台生成的订单号,只要保证唯一就好:如“2018013000001”

7.        total_fee 支付金额 单位:分,为了测试此值给1,表示支付1分钱

8.        spbill_create_ip IP地址 网上很多ip的方法,自己找,此处测试给“127.0.0.1”

9.        notify_url 回调地址:这是微信支付成功后,微信那边会带着一大堆参数(XML格式)请求这个地址多次,这个地址做我们业务处理如:修改订单状态,赠送积分等。Ps:支付还没成功还想这么远干嘛,最后再说。地址要公网可以访问。

10.    trade_type 支付类型 咱们是公众号支付此处给“JSAPI”

11.    openid (已有)

好了,准备工作完成,开始发送POST请求吧,上面提到网上找到的get请求的方法,此处用到post请求的方法,请求微信"统一下单接口https://api.mch.weixin.qq.com/pay/unifiedorder。发送前先用WXPayUtil工具类中的public static String mapToXml(Map<String,String> data)方法将有11个参数的map转成XML格式。发送后会返回String类型的返回值,如果你够幸运的话应该会得到XML的字符串:

<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>

先用WXPayUtil类中的public static Map xmlToMap(String strXML)方法,将刚才返回的XML格式的字符串转成map(为了方便取值)。map.get(“prepay_id”)就得到了prepay_id的值(比如得到的是:“wx2018…250…9981…666”),记住它,先保留此值。

看看前台都需要接收哪些值吧。

6个参数,咱们还是一个一个分析:

1.        appId:四大参数之一的APPID;

2.        timestamp:时间戳(newDate()即可)

3.        nonceStr:随机字符串,再次用WXPayUtil中的generateNonceStr()即可;

4.        package:就tm是它用到了prepay_id,但是还不是直接取值,还非要固定格式的,值的格式例如:”prepay_id= wx2018…250…9981…666”

5.        signType:写MD5就好

6.        paySign:又来了还是签名算法 ,按照上面的方法,用WXPayUtil中的publicstatic String generateSignature(final Map data, Stringkey)方法,data是将除了paySign外,其他5个参数放到map中,key是四大配置参数中的API秘钥(paternerKey),得到了paySign后,不要忘记再将paySign put到只有5个参数的map中,这样才能凑齐最后的第6个参数。);

注意:此处有个小bug,很多人会被坑的很惨,不注意就掉坑里,我是掉进去了,就是最关键的第4个参数package,眼熟不眼熟,这tm是JAVA的关键字,不能用来当变量名。

所有的参数有了,返回给前端的方法有很多,简易用springMVC的@ResponseBody注解,即可将这个有6个参数的map按json格式传给前端。好了,后台工作完成。

    前端的工作就容易多了,格式比较固定因为是微信固定格式,所以直接贴出我的代码,你只要更换触发支付的事件和异步的地址即可.

前端简单来说:1.一个空jsp页面上有个a标签,用来获取code,并跳转到pay.jsp(上面提到过)。

                        2.pay.jsp中需要异步到后台需要带code参数,pay.jsp中页面的地址上带着code,想获取code的方法很多,抛砖引引玉:(定义一个按钮,按钮上绑定一个code的属性值是页面链接的code的值,用EL表达式取的参数值,点击按钮触发点击事件)。

                        3.接收后台传过来值,调用固定方法。

Pay.jsp中内容只有一个”微信支付”的按钮,和js的代码,以下是js内容(获取code方法可以修改),其它内容不要修改

<!—pay.jsp中点击”微信支付”按钮执行pay()方法>

<input id="code"type="button" value="微信支付"onclick="pay()" code="${param.code }"/>

如果觉得对你有帮助,可以搜索公众号  ‘蛋皮皮’   关注作者支持一下,每天会不定时回复留言(有任何问题都可以留言哦)。

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