Detailed description of WeChat payment development process and payment process

Source: Internet
Author: User

Detailed description of payment development process and payment process

I recently made a payment transfer in the company. Here I will summarize some development experiences.

Note: I am using the payment on the open platform, which is related to the mobile app, but not the public account.

Main procedure of payment

1. the user browses the app, selects the product, and then places an order.

2. The server processes the order logic and starts the formal payment process.

3. The background server initiates a request to the weixin server to obtain a token.

4. The background server obtains the token, encrypts it with other parameters, and then initiates a request to the weixin server again to obtain a pre-paid prepayid

5. The background server returns the prepayid to the app client.

6. The app calls the controls on the mobile phone to complete the payment process.

7. The app initiates a callback request to the backend server to notify the server that the transaction is complete.

8. After the weixin server processes all the processes, it initiates a post request to the backend server to officially notify the backend server that the transaction has been completed.

Notes for the above process:

1. Each token obtained has a validity period. The default value is 7200 s, and a maximum of 200 tokens can be obtained every day. Therefore, it is best to cache the token in redis and re-obtain the token after it expires.

2. The callback initiated by the app is unreliable by default. The background should initiate an order query to the server as much as possible (not required) to query the result of this transaction.

3. The weixin server initiates transaction Y to the background, which is the final barrier to ensure Transaction completion. The backend server must return "success" after confirmation; otherwise, the weixin server will try to resend the request.

Get token

This step is very simple, just send a get request. You only need to configure the correct parameters.

'''Get token''' from the server def _ getAccessTokenFromWeixin (self): response = requests. get (self. tokenUrl % (self. appId, self. appSecret) if response. status_code = 200: 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 failed t KeyError: return None # failed to get token return None # failed http Request

Get prepayid

In the development process of payment, the most tedious thing is to get the prepayid.

In this step, we need to assemble such a parameter:

{"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&notify_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"} 

Package assembly

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&notify_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 package assembly are shown in the code above. Therefore, we need to prepare a params and a signature. The signature process is as follows:

1. Sort params in the Lexicographic Order of keys and splice them into strings. Note that these keys do not include the sign

2. After the above string, splice the key = paternerKey, then perform the md5 Signature on the entire string, and then convert it to uppercase. Then we get the signature.

Then, we transcode the values of all params and splice the values with sign = signValue to obtain the package string.

MD5 has been created as follows:

Def createMD5Signature (self, signParams): ''' sort ''' sortedParams = sorted (signParams. iteritems (), key = lambda d: d [0]) ''' splice ''' stringSignTemp = "&". join (["% s = % s" % (item [0], item [1]) for item in sortedParams if item [0]! = 'Sign' and ''! = Item [1]) # Add the accesskey stringSignTemp + = '& key = % s' % (self. partnerKey) # use MD5 to sign and convert it to uppercase stringSign = hashlib. md5 (stringSignTemp ). hexdigest (). upper () # Upper return stringSign

Package assembly code:

Def getPackage (self, packageParams): ''' first obtain the params sign, then urlencode the params, and then splice it with 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 obtaining the package, we will continue to assemble the parameters:

The required parameters are as follows:

appid=wxd930ea5d5a258f4fappkey=L8LrMqqeGRxST5reouB0K66CaY A WpqhA Vsq7ggKkxHCOastWksvuX1uvmvQcl xaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5Knoncestr=e7d161ac8d8a76529d39d9f5b4249ccbpackage=bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%95 &fee_type=1&input_charset=UTF-8&notify_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=7F77B507B755B3262884291517E380F8timestamp=1399514976 

Traceid = test_1399514976

Note:

The above parameters are involved in the signature, but the appKey is not included in the final parameters. Remember to delete the signature.

1. All parameters are sorted alphabetically and then spliced

2. Sign sha1 and splice it to the end of the above string

3. Delete the appKey and add the sign

The code for getting the sha1 signature is as follows:

Def createSHA1Signature (self, params): ''' first sort and then splice ''' sortedParams = sorted (params. iteritems (), key = lambda d: d [0]) stringSignTemp = "&". join (["% s = % s" % (item [0], item [1]) for item in sortedParams]) stringSign = hashlib. sha1 (stringSignTemp ). hexdigest () return stringSign

Then we get the following parameters:

{"appid":"wxd930ea5d5a258f4f", "noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb", "package":"Sign=WXpay";"partnerid":"1900000109" "prepayid":"1101000000140429eb40476f8896f4c9", "sign":"7ffecb600d7157c5aa49810d2d8f28bc2811827b", "timestamp":"1399514976"}

Get prepayid

The Code is as follows:

'''Get prepayid ''' def gerPrepayId (self, token, requestParams): ''' json parameters, including package, then initiate the post request '''data = json. dumps (requestParams) response = requests. post (self. response URL % (token), data = data) if response. status_code = 200: text = response. text = json. loads (text) errcode = text ['errcode'] if errcode = 0: return text ['prepayid'] return None

The prepayid format we obtain should be as follows:

{"Prepayid": "110000000140429eb40476f8896f4c9", "errcode": 0, "errmsg": "Success "}

Sign again

Here we use the sha1 signature method to re-sign and obtain the following parameters:

{"appid":"wxd930ea5d5a258f4f", "noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb", "package":"Sign=WXpay";"partnerid":"1900000109" "prepayid":"1101000000140429eb40476f8896f4c9", "sign":"7ffecb600d7157c5aa49810d2d8f28bc2811827b", "timestamp":"1399514976"}

The background server returns the result to the app, and the app can initiate a payment.

The above process code is:

'''Receives app requests and returns prepayid''' class WeixinRequirePrePaidHandler (BasicTemplateHandler): '''. This method is called ''' @ staticdef method getPrePaidResult (order_no, total_pay, product_name, client_ip): ''' encapsulates common signature algorithms ''' weixinRequestHandler = WeixinRequestHandler (order_no) '''collect order information ''' addtion = str (random. randint (10,100) # generate a two-digit number and splice it to the end of the order number out_trade_no = str (order_no) + addtion order_price = float (total_pay) # floating point numbers must be allowed here, convert the converted component to int # order_price = 0.01 # test remote_addr = client_ip # print remote_addr current_time = int (time. time () order_create_time = str (current_time) order_deadline = str (current_time + 20*60) ''' some parameters here are used for '''noncestr = hashlib. 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_token: '''set package parameter ''' packageParams = {} packageParams ['Bank _ type'] = 'wx '# payment type packageParams ['body'] = product_name # product name packageParams ['prop _ type'] = '1' # RMB fen packageParams ['input _ charset'] = 'gbk' # GBK packageParams ['prop Y _ url'] = config [' Y _ url'] # post Asynchronous Message notification packageParams ['out _ trade_no '] = str (out_trade_no) # Order No. packageParams ['passer'] = config ['aterid'] # merchant No. packageParams ['total _ upload'] = str (int (order_price * 100) # order amount, the Unit is packageParams ['spbill _ create_ip'] = remote_addr # IP packageParams ['time _ start'] = order_create_time # order generation time packageParams ['time _ expire '] = order_deadline # order expiration time ''' get package ''' package = weixinRequestHandler. getPackage (packageParams) '''set the payment parameter ''' signParams = {} signParams ['appid '] = config ['appid'] signParams ['appkey'] = config ['paysignkey'] # delete signParams ['noncestr'] = noncestr signParams ['package'] = package signParams ['timestamp'] = timestamp signParams ['traceid'] = 'mytraceid _ 00 '''' generate the payment signature ''' app_signature = weixinRequestHandler. createSHA1Signature (signParams) ''' added the parameter '''signparams ['sign _ method'] = 'sha1' signParams ['app _ signature'] = app_signature ''' to remove the appKey. '''del signParams ['appkey'] ''' get prepayid ''' prepayid = weixinRequestHandler. gerPrepayId (access_token, signParams) if prepayid: ''' use the obtained prepayid to re-Prepare the signature ''' pack = 'sign = wxpay' prepayParams = {} prepayParams ['appid '] = config ['appid'] prepayParams [' appkey'] = config ['paysignkey'] prepayParams ['noncestr'] = noncestr prepayParams ['package'] = pack prepayParams ['ererid'] = config ['ererid'] prepayParams ['prepayid'] = prepayid prepayParams ['timestamp'] = timestamp' ''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'] = prepayid returnParams ['timestamp'] = timestamp signature [' sign '] = sign returnParams ['ererid'] = config ['ererid'] returnParams ['addtion'] = addtion else: '''prepayid acquisition failed ''' returnParams = {} returnParams ['status'] =-1 returnParams ['retmsg'] = 'prepayid acquisition failed 'else: '''token retrieval failed ''' returnParams = {} returnParams ['status'] =-1 returnParams ['retmsg'] = 'token retrieval failed ''' generate json format text, then return to the app''' return returnParams

Background asynchronous notification

The asynchronous notification sent by the server is the final sign of successful payment. This step is safe and we must extend the signature:

The extension code is as follows:

def isTenpaySign(self, params):    helper = WeixinRequestHandler()    sign = helper.createMD5Signature(params)    return params[‘sign‘] == sign

The overall process is as follows:

'''Asynchronous notification sent by the server to the backend ''' class weixinapppolicyhandler (BasicTemplateHandler): def initialize (self): self. weixinResponseHandler = WeixinResponseHandler () def post (self): ''' resolution parameter ''' params = self. parseQueryString () ''' verify whether the message is sent back by the weixin server ''' verifyWeixinSign = self. weixinResponseHandler. isTenpaySign (params) ''' process the order ''' if verifyWeixinSign: ''' order logic ''' order_no = str (params ['out _ trade_no ']) order_no = order_no [0:-2] print '% s paied successfully' % order_no self. saveweixinreceept (params) updateOrdersPaidByWeixin (order_no) # update the order Usage Status consumeCouponByOrderNo (order_no) # The coupon has used self. write ("success") else: self. write ("fail") def parseQueryString (self): ''' get all parameters in the url ''' uri = self. request. uri ''' parses the query string ''' parseResult = urlparse In the URI. urlparse (uri) query = parseResult. query ''' parses the query string ''' params = urlparse. parse_qs (query) for item in params: params [item] = params [item] [0]. strip () return params

The last note is that the payment on the mobile phone is not counted as successful. Only when the weixin server receives the success returned by the notify y notification will the transaction be successful, at this time, our mobile phone can receive an official message.

The above are the materials for the payment development process. We will continue to add relevant materials in the future. Thank you for your support for this site!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.