Recently in the company to do a micro-letter payment access, here summed up the development of some experience
Note that I am using a micro-letter open platform payment that is related to the mobile app and not to the public account.
The main operating process of micro-credit payment
1. The user browses the app, selects the product and orders.
2. The server handles the order logic and begins to formally initiate the payment process
3. First, the background server initiates a request to the Weixin server to obtain a token.
4. Background server to get token, use and other parameters encryption, again to the Weixin server to initiate a request to obtain a pre-payment Prepayid
5. The backend server returns the Prepayid to the app client
6.app Call the micro-trust control on the phone to complete the payment process.
7.app The backend server initiates a callback request notifying the server that the transaction is complete.
After the 8.weixin server has processed all the processes, the backend server initiates a POST request, formally notifies the background server that the transaction is complete
Some points to note in the above process:
1. Each acquisition of the token is a prescription, the default is 7200s, and a maximum of 200 times a day, so it is best to put the cache in the Redis, and so on after the failure to regain
2.app-initiated callback defaults are unreliable, the background should be as far as possible (not necessarily) to the micro-trust server to initiate order inquiries, query the results of this transaction.
The notify that the 3.weixin server initiates in the background is the final barrier to ensure the transaction is completed. The backend server must return "success" upon confirmation, otherwise the Weixin server will attempt to send the request again.
Get token
This step is simple enough to send a GET request. Just configure the correct parameters.
' Get token '
def _getaccesstokenfromweixin (self) from a micro-server:
response = requests.get (self.tokenurl% ( Self.appid, Self.appsecret))
If Response.status_code =:
Text = response.text
tokeninfo = json.loads ( Text)
Try:
token = tokeninfo[' Access_token ']
expires_in = tokeninfo[' expires_in ']
self._ Writeweixintokenlog (token, self.order_no) return
token
except Keyerror: Return
None #token获取失败
return None #http请求失败
Get Prepayid
In the development of micro-credit payment process, the most cumbersome is to obtain Prepayid.
In this step we need to assemble such an argument:
{"
AppID": "WXD930EA5D5A258F4F", "
Traceid": "test_1399514976",
"Noncestr": " E7D161AC8D8A76529D39D9F5B4249CCB ",
" timestamp ": 1399514976," package ":" Bank_type=wx&body=%e6%94%af%e4%bb %98%e6%b5%8b%e8%af%
95&fee_type=1&input_charset=utf-8¬ify_url=http%3a%2f%2fweixin.qq.com &out_trade_ no=7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1 & Total_fee=1&sign=7f77b507b755b3262884291517e380f8 ",
" Sign_method ":" SHA1 "," App_signature ":" 7f77b507b755b3262884291517e380f8 "
}
Assembly Package
The first step here is to assemble the package:
"Package": "bank_type=wx&body=%e6%94%af%e4%bb%98%e6%b5%8b%e8%af%
95&fee_type=1&input_charset= Utf-8¬ify_url=http%3a%2f%2fweixin.qq.com&out_trade_ no=7240b65810859cbf2a8d9f76a638c0a3&partner= 1900000109&spbill_create_ip=196.168.1.1& Total_fee=1&sign=7f77b507b755b3262884291517e380f8 ",
The parameters required for assembly package are shown in the above code, so we need to prepare a params and then prepare the signature process as follows:
1. According to the dictionary order of key, sort the params, then concatenate them into strings, noting that these keys do not include sign
2. After the string above the concatenation Key=paternerkey, and then the entire string for MD5 signature, and then converted to uppercase, this time we got the signature
We then urlencode the value of all params and then sign=signvalue the string, then we get the package strings.
The MD5 created here are as follows:
def createmd5signature (self, signparams):
' first sort '
sortedparams = sorted (Signparams.iteritems (), key= Lambda d:d[0])
' stitching '
stringsigntemp = ' & '. Join (["%s=%s"% (Item[0], item[1)) for item in Sortedparams if it Em[0]!= ' sign ' and '!= item[1] ')
#加上财付通商户权限密钥
stringsigntemp + = ' &key=%s '% (self.partnerkey)
# Sign with MD5, and then convert to uppercase
stringsign = HASHLIB.MD5 (stringsigntemp). Hexdigest () Upper () #Upper return
Stringsign
Code to assemble package:
def getpackage (self, packageparams):
"First get the sign of the params, then params the UrlEncode, finally splicing, plus sign '"
sign = Self.createmd5signature (packageparams)
packageparams = sorted (Packageparams.iteritems (), Key=lambda d:d[0])
stringparams = "&". Join (["%s=%s"% (Item[0], urllib.quote (str (item[1))) for item in Packageparams]
Stringparams + = ' &sign=%s '% (sign) return
Stringparams
Continue assembly parameters
After we get package, we continue to assemble the parameters:
The parameters required here are:
APPID=WXD930EA5D5A258F4F
Appkey=l8lrmqqegrxst5reoub0k66cay A wpqha VSQ7GGKKXHCOASTWKSVUX1UVMVQCL xahoyd3elnbrno2dhnnzgfvg9qs473m3dtozug5er46fhugofumv8h2fvr9qkjslc5k
noncestr= E7D161AC8D8A76529D39D9F5B4249CCB
package=bank_type=wx&body=%e6%94%af%e4%bb%98%e6%b5%8b%e8%af%95 & Fee_type=1&input_charset=utf-8¬ify_url=http%3a%2f%2fweixin.qq.com&out_trade_no = 7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1&tot al_fee=1& Sign=7f77b507b755b3262884291517e380f8
timestamp=1399514976
traceid=test_1399514976
Notice there's a hole here:
Signed is the above parameters , but the final parameter does not include Appkey, after signing to remember to delete.
1. All parameters sorted in dictionary order and then spliced
2. SHA1 signature, stitching to the back of the string above
3. Note Here to remove Appkey, then add sign
The code to get the SHA1 signature is as follows:
def createsha1signature (self, params):
' first sort, then splice '
sortedparams = sorted (Params.iteritems (), Key=lambda D :d [0])
stringsigntemp = "&". Join (["%s=%s"% (Item[0], item[1)) for item in Sortedparams])
stringsign = Hashli B.SHA1 (stringsigntemp). Hexdigest () return
stringsign
And then we get this parameter:
{"
AppID": "WXD930EA5D5A258F4F", "
noncestr": "E7D161AC8D8A76529D39D9F5B4249CCB",
"package": "sign= Wxpay ";
" Partnerid ":" 1900000109 ""
Prepayid ":" 1101000000140429eb40476f8896f4c9 ",
" sign ":" 7ffecb600d7157c5aa49810d2d8f28bc2811827b ",
" timestamp ":" 1399514976 "
}
Get Prepayid
The code is as follows:
' Get pre-paid Prepayid '
def gerprepayid (self, token, requestparams):
' to json the parameters, including package, and then initiate a POST request '
data = Json.dumps (requestparams)
response = Requests.post (self.gateurl% (token), data=data)
if Response.status_code = =:
Text = response.text
Text = json.loads (text)
Errcode = text[' Errcode ']
if Errcode = 0: Return
text[' Prepayid '] return
None
The Prepayid format we get is supposed to be like this:
{"Prepayid": "1101000000140429eb40476f8896f4c9", "Errcode": 0, "errmsg": "Success"}
Sign again
This is signed again using the SHA1 signature above, obtaining the following parameters:
{"
AppID": "WXD930EA5D5A258F4F", "
noncestr": "E7D161AC8D8A76529D39D9F5B4249CCB",
"package": "sign= Wxpay ";
" Partnerid ":" 1900000109 ""
Prepayid ":" 1101000000140429eb40476f8896f4c9 ",
" sign ":" 7ffecb600d7157c5aa49810d2d8f28bc2811827b ",
" timestamp ":" 1399514976 "
}
The backend server returns the result to the app, at which point the app can initiate payment.
The process code above is:
' To receive the app request, return Prepayid ' class Weixinrequireprepaidhandler (Basictemplatehandler): ' This method is called in Ordersaddhandler ' ' @staticmethod def getprepaidresult (Order_no, Total_pay, Product_Name, client_ip): ' Encapsulates the commonly used signature algorithm ' Weixinreq Uesthandler = Weixinrequesthandler (order_no) ' Collect Order related information ' addtion = str (random.randint) #产生一个两位的数字, stitching in the order The back of a number is Out_trade_no = str (order_no) + addtion Order_price = float (total_pay) #这里必须允许浮点数, after which the converted component is converted to an int #order_p Rice = 0.01 #测试 remote_addr = client_ip #客户端的IP地址 print remote_addr current_time = Int (Time.time ()) Order_ Create_time = str (current_time) order_deadline = str (current_time + 20*60) "' Some of the arguments here are for the following use ' NONCESTR = Hash
LIB.MD5 (str (random.random ())). Hexdigest () timestamp = str (int (time.time ())) Pack = ' Sign=wxpay ' ' Get token ' Access_token = Weixinrequesthandler.getaccesstoken () logging.info ("Get token:%s"% access_token) if access_t Oken: ' Set package parameter '
Packageparams = {} packageparams[' bank_type ' = ' WX ' #支付类型 packageparams[' body ' = Product_Name #商品名称 packageparams[' fee_type '] = ' 1 ' #人民币 fen packageparams[' input_charset '] = ' GBK ' #GBK packageparams[' no Tify_url '] = config[' Notify_url '] #post异步消息通知 packageparams[' out_trade_no '] = str (out_trade_no) #订单号 Packagepa
rams[' partner '] = config[' Partnerid '] #商户号 packageparams[' total_fee '] = str (int (order_price*100)) #订单金额, Unit is divided packageparams[' spbill_create_ip '] = remote_addr #IP packageparams[' time_start ' = Order_create_time #订单生成时间 pa ckageparams[' time_expire ' = order_deadline #订单失效时间 ' Get package ' package = Weixinrequesthandler.getpackage
(Packageparams) ' Set payment parameters ' Signparams = {} signparams[' AppID '] = config[' AppID '] signparams[' appkey '] = config[' Paysig Nkey '] #delete signparams[' noncestr '] = noncestr signparams[' package '] = package signparams[' timestamp ']= Timestamp signparams[' traceid '] = ' mytraceid_001 ' ' Generate payment signature ' App_signature = weixinrequesthandler.c Reatesha1signature (signparams) ' Add additional parameters that do not participate in the signature ' signparams[' sign_method '] = ' SHA1 ' signparams[app_sig ' Nature '] = App_signature ' Remove appkey ' del signparams[' Appkey '] ' get prepayid ' Prepayid = Wei Xinrequesthandler.gerprepayid (Access_token, Signparams) if Prepayid: ' Use the received Prepayid to prepare the signature again ' pack = ' Sign=wxpay ' prepayparams = {} prepayparams[' AppID '] = config[' AppID '] prepayparams[' appkey '] = config[' Paysignkey '] prepayparams[' noncestr '] = noncestr prepayparams[' package '] = Pack Prepaypar ams[' partnerid '] = config[' Partnerid '] prepayparams[' prepayid '] = Prepayid prepayparams[' timestamp '] = Tim
Estamp ' generate signature ' sign = weixinrequesthandler.createsha1signature (prepayparams) ' Prepare output parameter '
Returnparams = {} returnparams[' status '] = 0 returnparams[' retmsg '] = ' success ' returnparams[' appid '] = config[' AppID '] returnparams[' noncestr ' = noncestr returnparams[' package ' = Pack returnparams[' Prepayid '] = P Repayid returnparams[' timestamp '] = timestamp returnparams[' sign '] = sign returnparams[' Partnerid '
] = config[' Partnerid '] returnparams[' addtion ' = addtion else: ' Prepayid get failed ' Returnparams = {} returnparams[' status ' =-1 returnparams[' retmsg '] = ' Prepayid get failed ' else: ' Token get failed ' returnparams = {} returnparams[' status ' =-1 returnparams[' retmsg '] = ' token get failed ' '
Generates JSON-formatted text and returns to the app ' return Returnparams
Background asynchronous notification
The Notify asynchronous notification sent by the micro-trust server is the final sign of the success of the payment, and this step is safe and we have to postpone it:
The deferred code is as follows:
def istenpaysign (self, params):
helper = Weixinrequesthandler ()
sign = helper.createmd5signature (params) return
params[' sign '] = = Sign
The overall process is as follows:
' Micro-server asynchronous notification sent to the background ' class Weixinappnotifyhandler (Basictemplatehandler): def Initialize (self): Self.weixinresponse Handler = Weixinresponsehandler () def post (self): ' parse parameters ' params = self.parsequerystring () ' To verify that it is Weix In server send Message ' ' verifyweixinsign = self.weixinResponseHandler.isTenpaySign (params) ' Process order ' if Verifyweixinsig N: ' order logic ' order_no = str (params[' out_trade_no ']) order_no = order_no[0:-2] print '%s paied suc Cessfully '% order_no self.saveweixinreceipt (params) updateorderspaidbyweixin (order_no) #更新订单使用状态 consum Ecouponbyorderno (order_no) #优惠券已经使用 self.write ("Success") Else:self.write ("fail") def parsequerystring (self): ' Get all the parameters in the url ' uri = Self.request.uri ' ' To parse out the query string in the URI ' parseresult = urlparse.urlparse (ur
i) query = Parseresult.query ' Parse query string ' params = Urlparse.parse_qs (query) for item in params: Params[item] = Params[iTem][0].strip () return params
Finally, a point, the user on the phone to pay the money, does not count for success, only Weixin Server received notify notify the return of the success, only to calculate the final success of the transaction, at this time, our mobile phone can receive a message from the official micro-letter.
The above is the micro-credit payment development process of data collation, follow-up continue to supplement the relevant information, thank you for your support of this site!