Business Process
The WeChat official website is very detailed and has pictures. I'll say it again.
The user clicks a payment button-->{Backend push processing}-->The user sees an interface for entering a password, including the amount and other information-->After the user enters the password, a The page where the payment is successful (this part of the process is completed by WeChat itself, we don’t have to do anything) --> Return to the system’s own page (you can’t let the user keep looking at a page where the payment is completed. After spending money, it’s correct It hurts, jump quickly~ I regret it after a while, how to apply for a refund. The poor engineer still has to develop the refund function)
Development process
1) Obtain user authorization (this It doesn’t matter whether I do it or not, I haven’t done it yet anyway)
2) Call the unified ordering interface to get the prepayment ID
3) H5 calls up the built-in JS of WeChat payment
4) After the payment is completed, the processing of the WeChat callback URL
Looking at the long paragraph of text, are you very unhappy? I forgot where I saw this sentence. One picture instead thousands of words. (The red part in the picture is what we need to do. There doesn’t seem to be much
The main part of this article begins (If you want to see the code directly, You may not be able to understand the code after pasting it. It does not mean that the code is difficult, various separations, and various classes are not straightforward. If you understand it, you may not be able to debug the last signature error, or $get_brand_wcpay_request:fail.$. key0 I still have to be obedient about the parameters.) I’m a little confused about learning English recently. If you don’t understand the meaning, you can skip it. I’ll tell you about it later in the article. Joke.
1. Generate a unified ordering interface and obtain prepay_id.
Required parameters==Name==Where to find them:
WeChat official gave a parameter Detailed description of https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 Some parameters, if you still don’t know where to find them, please continue reading
appid ==Application ID==Log in to the WeChat official account backend - development - basic configuration
mch_id == WeChat payment merchant number == Log in to the WeChat payment backend and you will see
device_info ==Equipment number==Terminal device number (store number or cash register device ID), Note: Please enter "WEB"
#body==Product description==Product or payment order briefly when paying on PC web page or official account Description (I don’t know what the hell it is, it doesn’t matter, just pass a string casually, and pass an English string casually. You will get full marks for your wise decision at this time. If it is Chinese, you may encounter no clue The signature error is serious, and the person starts to doubt his life)
trade_type==Transaction type==The values are as follows: JSAPI, NATIVE, APP. The JSAPI we use here. As the title has said, it is WeChat public account payment.
ps: JSAPI--official account payment, NATIVE--native scan code payment, APP--app payment, the parameters for the unified order interface trade_type can be found here MICROPAY--payment by card, payment by card is available. Separate payment interface, does not call the unified ordering interface
nonce_str==random string==random string, no longer than 32 characters
ps: Friends may name the nonce , I am very surprised, are all the people on the WeChat team Doubi? I checked the encyclopedia and found that random numbers are also represented by nonce. (Curious babies can check the meaning of nonce in the Cambridge dictionary). With my unremitting efforts,
I discovered this. nonce ==number used once. Suddenly enlightened.
notify_url==Notification address==Receive the WeChat payment asynchronous notification callback address. The notification url must be a directly accessible url and cannot carry parameters. (Here, what’s a good name? Just name it casually, it won’t be used for a while anyway)
out_trade_no==Merchant order number==Order number within the merchant system, within 32 characters, can be Contains letters (Every time I read the official explanation on WeChat, I get more confused. Is there any? It doesn’t matter, I will just send 1.)
total_fee==Total amount==Total amount of order , the unit is cents (for the company's project testing, you have to pay for it yourself, and 1 cent is money. ps: At this time, I always think of a classmate who said that fly legs are also meat)
openid ==User ID==trade_type=JSAPI, this parameter must be passed, the user's unique ID under the merchant's appid.
The most important thing is that important characters always appear at the end.
sign==signature==official signature algorithm. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3. I don’t understand it, I don’t quite understand it. Do you think you understand it? It doesn’t matter. If you don’t encounter a few signature errors, do you have the nerve to say that you have done WeChat payment development?
said that this sign has a more important parameter. Parameters involved in the signature. Anyway, it took me a long time to find it. (The WeChat payment applied for by the company operation, when I asked her to ask for it, his expression looked like this.
key==key setting path: WeChat merchant platform (pay.weixin.qq.com)- ->Account Settings-->API Security-->Key Settings
Here:
There are instructions on how to find it online. I'm too lazy to look for it. I just thought of a string myself, then encrypted it into a 32-bit string using MD5, and reset it.
This key value is used when generating a sign signature, so it must be saved.
I see that others use a lot to generate signatures (sign). Anyway, I used the sign generated by the parameters given above. (This above refers to my blog, not WeChat. In order to reduce Misunderstanding, post the parameters I used to generate the sign signature)
The parameters I used to generate the sign signature
After preparing the above parameters, Encapsulated into XML
The format is as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xml> <appid>wxb1427ebebexxxxxx</appid> XXX费用 <device_info>WEB</device_info> <mch_id>132186xxxx</mch_id> <nonce_str>6AED000AF86A084F9CB0264161E29DD3</nonce_str> <notify_url>https://一个域名/api/wechatPay/jsapiPayNotify</notify_url> <openid>oo8WUt0taCqjt552htW1vw-xxxxx</openid> <out_trade_no>1</out_trade_no> <sign>各种排序+key生成的那个sign</sign> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type></xml>
Call the unified order address of WeChat: https://api.mch.weixin.qq.com/pay/unifiedorder
Witness a miraculous moment. If the above parameters are magically correct, you will receive the XML string returned by WeChat with the following format
<xml> <return_code></return_code> <return_msg></return_msg> <appid></appid> <mch_id></mch_id> <device_info></device_info> <nonce_str></nonce_str> <sign></sign> <result_code></result_code> <prepay_id></prepay_id> <trade_type></trade_type></xml>
What we need is this product
prepay_id 获取到这货之后,第一步骤已经结束了,可以去喝个茶,吃个冰棍,小庆祝一下。 2、H5调起微信支付的内置JS
The parameters returned from the background to the front desk should include the following items:
appId==This is unchanged==Never change
timeStamp==Timestamp==Rules: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2. After reading it, I still look confused. It doesn’t matter, we have the tool class. Who knows, just call it directly
nonceStr == Anyway, I used the same random string as the signature just now. Theoretically, it shouldn't matter if you don't use it. Diligent friends can try
package==Order details extended string==prepay_id parameter value returned by the unified order interface, submission format such as: prepay_id=** *(You guessed it right. The prepay_id we got after so much effort was used here. When I used it for the first time, I kept using the order ID to request, and then the information WeChat gave me was that the request parameters were wrong and missing. Parameter $key0$. Don’t tell me, it’s just me.)
signType==Signature method==Signature algorithm, temporarily supports MD5
paySign==Signature==This signature is required. Regenerate, in the background. Use the above 4 parameters + a key (never change). (The timestamp when I generated the signature and the timestamp sent back to the front desk are the same timeStamp. Does it work if they are different? There is no verification)
Code to generate paySign
NB: When generating prepay_id, the appid is a lowercase i. When generating paySign, the appId is an uppercase I
So far, if everything goes well, you will see a page like this.
But if, you didn’t see this. Instead, it prompts that the directory is not authorized, or the test account is not in the whitelist. I think this is the correct way to open this blog.
WeChat public account background, WeChat payment, there is a payment authorization directory in the development configuration, test authorization directory,
Payment authorization directory: during development, put it first. (Grandpa Deng Xiaoping once said when dealing with Sino-Japanese relations, we should put aside problems that we cannot solve.)
Test authorization directory: This is what we need to fill in. You need an address that can be accessed from the outside world. IP can also be used (it can be tested personally). If your IP cannot be accessed from the external network, ask an operation and maintenance classmate to solve it. It is recommended to configure a domain name accessible from the external network for testing.
Test whitelist: This does not explain
Enter the password, and then you will see the result like this. (This doesn’t require us to do anything)
I’m so excited, go get something to eat quickly and suppress your inner excitement.
Remaining, we still have two things to do. Let’s talk about the simple ones first.
3. After the payment is successful, jump back to a certain page in your system
function onBridgeReady(){ WeixinJSBridge.invoke ( 'getBrandWCPayRequest', { "appId" : appId, //公众号名称,由商户传入 "timeStamp":timeStamp, //时间戳,自1970年以来的秒数 "nonceStr" : nonceStr, //随机串 "package" : Package, "signType" :signType, //微信签名方式: "paySign" : paySign //微信签名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ) { window.location.replace("index.html"); } } ); }
In the above code, the red part can be modified to the page you want to go to. Are you curious about what replacement is? Move here and take a look: http://www.php.cn/
4, the last part. fighting
This part has the following 3 small steps
1) Parse the passed flow information and verify the correctness of the information contained in the flow by re-signing. It is to determine whether this information is sent by WeChat
2) If return_code and result_code are both SUCCESS, handle the merchant's own business logic. It’s just the payment status of the order and some other information.
3)告诉微信,我收到你的返回值了。不用在发了。
关于以上三点的解释。微信官方是这么说的
//支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL, //验证签名,并回应微信。 //对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败, //微信会通过一定的策略(如30分钟共8次)定期重新发起通知, //尽可能提高通知的成功率,但微信不保证通知最终能成功。 //商户自行增加处理流程, //例如:更新订单状态 //例如:数据库操作 //例如:推送支付完成信息
还记得我们在第一步生成预支付id(prepay_id时的那个notify_url吗。如果不记得了,请往上翻。如果当时只是随便写了一个,那么这会需要去改一改了。)
一个能访问的到的action.同样地址需要外网能访问的到。没有试ip好不好使。开发这部分功能的时候,运维同学已经配置了测试域名。好开心啊,终于不用在纠结于一些交互配置了。
和支付宝不同,微信返回的是流。和支付宝不同,微信返回的是流。和支付宝不同,微信返回的是流。重要的事情说三遍
解析之后,得到的格式是这样子的
<xml><appid><![CDATA[wxb1427ebebeeaxxxx]]></appid> <bank_type><![CDATA[CFT]]></bank_type> <cash_fee><![CDATA[1]]></cash_fee> <device_info><![CDATA[WEB]]></device_info> <fee_type><![CDATA[CNY]]></fee_type> <is_subscribe><![CDATA[Y]]></is_subscribe> <mch_id><![CDATA[132186xxxx]]></mch_id> <nonce_str><![CDATA[07FC15C9D169EE48573EDD749D25945D]]></nonce_str> <openid><![CDATA[oo8WUt0taCqjt552htW1vw-xxxxx]]></openid> <out_trade_no><![CDATA[你的订单编号]]></out_trade_no> <result_code><![CDATA[SUCCESS]]></result_code> <return_code><![CDATA[SUCCESS]]></return_code> <sign><![CDATA[E69940B3EDC437CB5A181210D523806E]]></sign> <time_end><![CDATA[20160621134204]]></time_end> <total_fee>1</total_fee> <trade_type><![CDATA[JSAPI]]></trade_type> <transaction_id><![CDATA[400386200120160621763973xxxx]]></transaction_id> </xml>
对以上第一点和第三点做个解释。
再次吐槽一下。微信真的很喜欢用签名啊。整个过程,3遍签名。也是醉了。
1)我们看到上述微信返回的xml中含有很多字段。使用上述xml中,处sign意外的值+key,进行签名。你没有看错。包含result_code和return_code。
微信的官方对于签名有解释。
原谅我真的好久不学语文了。真的没理解这句话,是用微信回调函数中传的参数,进行重新签名。傻傻的,还在想,用第二次签名是的参数进行签名,时间戳怎么办,要不要存在数据库里面。
将获得的签名与xml中的sign对比,如果相同,证明是微信返回的通知。如果不同,你的通知地址可能被黑客破解了。要不要告诉老板呢,告诉老板了,我怎么解决呢。
2)商户逻辑处理,不解释
3)告诉微信,我收到了你的通知,不需要在发送了。
怎么告诉微信呢。我翻遍了微信的文档,也没有找到回复微信通知这个url。
经人知道,再一次的刷新了认知观。用response.
我是这么写的
response.getWriter().write(xml);
这个xml就是微信给你的那个流转化的字符串。
xml中的return_code要是SUCCESS或者FAIL
别问我怎么知道的。官方的demo里面写的
if($notify->checkSign() == FALSE){ $notify->setReturnParameter("return_code","FAIL");//返回状态码 $notify->setReturnParameter("return_msg","签名失败");//返回信息 }else{ $notify->setReturnParameter("return_code","SUCCESS");//设置返回码 } $returnXml = $notify->returnXml();
按照这个写法,返回的数据。在没有收到微信的通知。
之前在测试的时候,返回字符串之后,在没有收到微信的通知,这两天偶然查日志,发现,微信在一直的,通知,不一定是8次。从打印的日志看
有4次,6次。突然,好晕啊。有明白的朋友,还请多多指教
--------------------------------------------------------------
微信公众号支付--JSAPI的开发思路和一下参数的具体解释,全部完成了。具体代码。等我从公司项目里面抽出来。在整理。
还有一个坑:我们在第一步的时候,body传的是英文,如果传中文,直接能用的赶紧感谢一下上苍,返回参数错误的,应该是正常吧。
我的对象和xml转化是用的Java的JAXBContext。很好用的赶脚。赶脚比XMLStream好用。
更多The whole process of WeChat public account payment development相关文章请关注PHP中文网!