专栏名称: python
隔天更新python文章,我希望用我的努力换来劳动的成果帮助更多的人掌握一门技术,因此我要更加努力。
目录
相关文章推荐
Python爱好者社区  ·  史上最强!PINN杀疯了 ·  昨天  
Python爱好者社区  ·  英伟达憾失DeepSeek关键人才?美国放走 ... ·  昨天  
Python爱好者社区  ·  1885页的Python完全版电子书 ·  3 天前  
Python爱好者社区  ·  多模态,杀疯了 ·  2 天前  
Python开发者  ·  o3-mini 碾压 DeepSeek ... ·  6 天前  
51好读  ›  专栏  ›  python

微信二次开发案例,python制作微信支付小程序!

python  · 公众号  · Python  · 2019-11-15 15:07

正文


私信小编007即可自动获取大量python视频教程以及各类PDF和源码案例!

由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程。当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程。

1.支付交互流程


当然具体的参数配置可以参考官方文档

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1

2.获取openid(微信用户标识)

 1 import requests 2 3 from config import APPID, SECRET 4 5 6 class OpenidUtils(object): 7 8 def __init__(self, jscode): 9 self.url = "https://api.weixin.qq.com/sns/jscode2session"10 self.appid = APPID # 小程序id11 self.secret = SECRET # 不要跟后面支付的key搞混12 self.jscode = jscode # 前端传回的动态jscode1314 def get_openid(self):15 # url一定要拼接,不可用传参方式16 url = self.url + "?appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"17 r = requests.get(url)18 print(r.json())19 openid = r.json()['openid']2021 return openid



3.支付请求

 1 # -*- coding:utf-8 -*- 2 import requests 3 import hashlib 4 import xmltodict 5 import time 6 import random 7 import string 8 import urllib2 9 import sys 10 11 12 class WX_PayToolUtil(): 13 """ 微信支付工具 """ 14 15 def __init__(self, APP_ID, MCH_ID, API_KEY, NOTIFY_URL): 16 self._APP_ID = APP_ID # 小程序ID 17 self._MCH_ID = MCH_ID # # 商户号 18 self._API_KEY = API_KEY 19 self._UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 接口链接 20 self._NOTIFY_URL = NOTIFY_URL # 异步通知 21 22 def generate_sign(self, param): 23 '''生成签名''' 24 stringA = '' 25 ks = sorted(param.keys()) 26 # 参数排序 27 for k in ks: 28 stringA += (k + '=' + param[k] + '&') 29 # 拼接商户KEY 30 stringSignTemp = stringA + "key=" + self._API_KEY 31




    
 # md5加密,也可以用其他方式 32 hash_md5 = hashlib.md5(stringSignTemp.encode('utf8')) 33 sign = hash_md5.hexdigest().upper() 34 return sign 35 36 ''' 37 # python2另外一种实现方法 38 def generate_sign(self, params): 39 ret = [] 40 for k in sorted(params.keys()): 41 if (k != 'sign') and (k != '') and (params[k] is not None): 42 ret.append('%s=%s' % (k, params[k])) 43 params_str = '&'.join(ret) 44 params_str = '%(params_str)s&key=%(partner_key)s' % {'params_str': params_str, 'partner_key': key} 45 46 reload(sys) 47 sys.setdefaultencoding('utf8') 48 49 params_str = hashlib.md5(params_str.encode('utf-8')).hexdigest() 50 sign = params_str.upper() 51 return sign 52 ''' 53 54 def getPayUrl(self, orderid, openid, goodsPrice, **kwargs): 55 """向微信支付端发出请求,获取url""" 56 key = self._API_KEY 57 nonce_str = ''.join(random.sample(string.letters + string.digits, 30)) # 生成随机字符串,小于32位 58 params = { 59 'appid': self._APP_ID, # 小程序ID 60 'mch_id': self._MCH_ID, # 商户号 61 'nonce_str': nonce_str, # 随机字符串 62 "body": '测试订单', # 支付说明 63 'out_trade_no': orderid, # 生成的订单号 64 'total_fee': str(goodsPrice), # 标价金额 65 'spbill_create_ip': "127.0.0.1", # 小程序不能获取客户ip,web用socekt实现 66 'notify_url': self._NOTIFY_URL, 67 'trade_type': "JSAPI", # 支付类型 68 "openid": openid, # 用户id 69 } 70 # 生成签名 71 params['sign'] = self.generate_sign(params) 72 73 # python3一种写法 74 param = {'root': params} 75 xml = xmltodict.unparse(param) 76 response = requests.post(self._UFDODER_URL, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'}) 77 # xml 2 dict 78 msg = response.text 79 xmlmsg = xmltodict.parse(msg) 80 # 4. 获取prepay_id 81 if xmlmsg['xml']['return_code'] == 'SUCCESS': 82 if xmlmsg['xml']['result_code'] == 'SUCCESS': 83 prepay_id = xmlmsg['xml']['prepay_id'] 84 # 时间戳 85 timeStamp = str(int(time.time())) 86 # 5. 五个参数 87 data = { 88 "appId": self._APP_ID, 89 "nonceStr": nonce_str, 90 "package": "prepay_id=" + prepay_id, 91 "signType": 'MD5', 92 "timeStamp": timeStamp, 93 } 94 # 6. paySign签名 95 paySign = self.generate_sign(data) 96 data["paySign"] = paySign # 加入签名 97 # 7. 传给前端的签名后的参数 98 return data 99100 # python2一种写法101 '''102 request_xml_str = ''103 for key, value in params.items():104 if isinstance(value, str):105 request_xml_str = '%s%s>' % (request_xml_str, key, value, key,)106 else:107 request_xml_str = '%s%s%s>' % (request_xml_str, key, value, key,)108 request_xml_str = '%s' % request_xml_str109110 # 向微信支付发出请求,并提取回传数据111 res = urllib2.Request(self._UFDODER_URL, data=request_xml_str.encode("utf-8"))112 res_data = urllib2.urlopen(res)113 res_read = res_data.read()114 doc = xmltodict.parse(res_read)115 return_code = doc['xml']['return_code']116 if return_code == "SUCCESS":117 result_code = doc['xml']['result_code']118 if result_code == "SUCCESS":119 doc = doc['xml']120 data = {121 "appId": self._APP_ID,122 "nonceStr": nonce_str,123 "package": "prepay_id=" + doc["prepay_id"],124 "signType": 'MD5',125 "timeStamp": str(int(time.time())),126 }127 # paySign签名128 paySign = self.generate_sign(data)129 data["paySign"] = paySign # 加入签名130 return data131 else:132 err_des = doc['xml']['err_code_des']133 return err_des134 else:135 fail_des = doc['xml']['return_msg']136 return fail_des137 '''


当然你可能会遇到的错误有签名错误,一般的情况是你的appSecret和商户号的API密钥两个弄错了,当然如果不是还有可能是其他问题,解决方案链接 https://www.cnblogs.com/wanghuijie/p/wxpay_sign_error.html

其他的支付方式获取用户的ip地址可以通过 socket.gethostbyname(socket.gethostname()) 方法来获取。

4.支付回调

微信二次开发案例,python制作微信支付小程序!




    
由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程。当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程。
1.支付交互流程
微信二次开发案例,python制作微信支付小程序!当然具体的参数配置可以参考官方文档
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1
2.获取openid(微信用户标识)
1 import requests 2 3 from config import APPID, SECRET 4 5 6 class OpenidUtils(object): 7 8 def __init__(self, jscode): 9 self.url = "https://api.weixin.qq.com/sns/jscode2session"10 self.appid = APPID # 小程序id11 self.secret = SECRET # 不要跟后面支付的key搞混12 self.jscode = jscode # 前端传回的动态jscode13 14 def get_openid(self):15 # url一定要拼接,不可用传参方式16 url = self.url + "?appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"17 r = requests.get(url)18 print(r.json())19 openid = r.json()['openid']20 21 return openid微信二次开发案例,python制作微信支付小程序!3.支付请求
1 # -*- coding:utf-8 -*- 2 import requests 3 import hashlib 4 import xmltodict 5 import time 6 import random 7 import string 8 import urllib2 9 import sys 10 11 12 class WX_PayToolUtil(): 13 """ 微信支付工具 """ 14 15 def __init__(self, APP_ID, MCH_ID, API_KEY, NOTIFY_URL): 16 self._APP_ID = APP_ID # 小程序ID 17 self._MCH_ID = MCH_ID # # 商户号 18 self._API_KEY = API_KEY 19 self._UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 接口链接 20 self._NOTIFY_URL = NOTIFY_URL # 异步通知 21 22 def generate_sign(self, param): 23 '''生成签名''' 24 stringA = '' 25 ks = sorted(param.keys()) 26 # 参数排序 27 for k in ks: 28 stringA += (k + '=' + param[k] + '&') 29 # 拼接商户KEY 30 stringSignTemp = stringA + "key=" + self._API_KEY 31 # md5加密,也可以用其他方式 32 hash_md5 = hashlib.md5(stringSignTemp.encode('utf8')) 33 sign = hash_md5.hexdigest().upper() 34 return sign 35 36 ''' 37 # python2另外一种实现方法 38 def generate_sign(self, params): 39 ret = [] 40 for k in sorted(params.keys()): 41 if (k != 'sign') and (k != '') and (params[k] is not None): 42 ret.append('%s=%s' % (k, params[k])) 43 params_str = '&'.join(ret) 44 params_str = '%(params_str)s&key=%(partner_key)s' % {'params_str': params_str, 'partner_key': key} 45 46 reload(sys) 47 sys.setdefaultencoding('utf8') 48 49 params_str = hashlib.md5(params_str.encode('utf-8')).hexdigest() 50 sign = params_str.upper() 51 return sign 52 ''' 53 54 def getPayUrl(self, orderid, openid, goodsPrice, **kwargs): 55 """向微信支付端发出请求,获取url""" 56 key = self._API_KEY 57 nonce_str = ''.join(random.sample(string.letters + string.digits, 30)) # 生成随机字符串,小于32位 58 params = { 59 'appid': self._APP_ID, # 小程序ID 60 'mch_id': self._MCH_ID, # 商户号 61 'nonce_str': nonce_str, # 随机字符串 62 "body": '测试订单', # 支付说明 63 'out_trade_no': orderid, # 生成的订单号 64 'total_fee': str(goodsPrice), # 标价金额 65 'spbill_create_ip': "127.0.0.1", # 小程序不能获取客户ip,web用socekt实现 66 'notify_url': self._NOTIFY_URL, 67 'trade_type': "JSAPI", # 支付类型 68 "openid": openid, # 用户id 69 } 70 # 生成签名 71 params['sign'] = self.generate_sign(params) 72 73 # python3一种写法 74 param = {'root': params} 75 xml = xmltodict.unparse(param) 76 response = requests.post(self._UFDODER_URL, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'}) 77 # xml 2 dict 78 msg = response.text 79 xmlmsg = xmltodict.parse(msg) 80 # 4. 获取prepay_id 81 if xmlmsg['xml']['return_code'] == 'SUCCESS': 82 if xmlmsg['xml']['result_code'] == 'SUCCESS': 83 prepay_id = xmlmsg['xml']['prepay_id'] 84 # 时间戳 85 timeStamp = str(int(time.time())) 86 # 5. 五个参数 87 data = { 88 "appId": self._APP_ID, 89 "nonceStr": nonce_str, 90 "package": "prepay_id=" + prepay_id, 91 "signType": 'MD5', 92 "timeStamp": timeStamp, 93 } 94 # 6. paySign签名 95 paySign = self.generate_sign(data) 96 data["paySign"] = paySign # 加入签名 97 # 7. 传给前端的签名后的参数 98 return data 99 100 # python2一种写法101 '''102 request_xml_str = ''103 for key, value in params.items():104 if isinstance(value, str):105 request_xml_str = '%s%s>' % (request_xml_str, key, value, key,)106 else:107 request_xml_str = '%s%s%s>' % (request_xml_str, key, value, key,)108 request_xml_str = '%s' % request_xml_str109 110 # 向微信支付发出请求,并提取回传数据111 res = urllib2.Request(self._UFDODER_URL, data=request_xml_str.encode("utf-8"))112 res_data = urllib2.urlopen(res)113 res_read = res_data.read()114 doc = xmltodict.parse(res_read)115 return_code = doc['xml']['return_code']116 if return_code == "SUCCESS":117 result_code = doc['xml']['result_code']118 if result_code == "SUCCESS":119 doc = doc['xml']120 data = {121 "appId": self._APP_ID,122 "nonceStr": nonce_str,123 "package": "prepay_id=" + doc["prepay_id"],124 "signType": 'MD5',125 "timeStamp": str(int(time.time())),126






请到「今天看啥」查看全文