侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python实现微信小程序支付功能

Python  /  管理员 发布于 7年前   233

正文

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

1.支付交互流程

当然具体的参数配置可以参考官方文档https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1

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

 import requests from config import APPID, SECRET class OpenidUtils(object):  def __init__(self, jscode):   self.url = "https://api.weixin.qq.com/sns/jscode2session"   self.appid = APPID # 小程序id   self.secret = SECRET # 不要跟后面支付的key搞混   self.jscode = jscode # 前端传回的动态jscode  def get_openid(self):   # url一定要拼接,不可用传参方式   url = self.url + "?appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"   r = requests.get(url)   print(r.json())   openid = r.json()['openid']   return openid

3.支付请求

# -*- coding:utf-8 -*-import requestsimport hashlibimport xmltodictimport timeimport randomimport stringimport urllib2import sysclass WX_PayToolUtil(): """ 微信支付工具 """ def __init__(self, APP_ID, MCH_ID, API_KEY, NOTIFY_URL):  self._APP_ID = APP_ID # 小程序ID  self._MCH_ID = MCH_ID # # 商户号  self._API_KEY = API_KEY  self._UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 接口链接  self._NOTIFY_URL = NOTIFY_URL # 异步通知 def generate_sign(self, param):   '''生成签名'''   stringA = ''   ks = sorted(param.keys())   # 参数排序   for k in ks:    stringA += (k + '=' + param[k] + '&')   # 拼接商户KEY   stringSignTemp = stringA + "key=" + self._API_KEY   # md5加密,也可以用其他方式   hash_md5 = hashlib.md5(stringSignTemp.encode('utf8'))   sign = hash_md5.hexdigest().upper()   return sign ''' # python2另外一种实现方法 def generate_sign(self, params):  ret = []  for k in sorted(params.keys()):   if (k != 'sign') and (k != '') and (params[k] is not None):    ret.append('%s=%s' % (k, params[k]))  params_str = '&'.join(ret)  params_str = '%(params_str)s&key=%(partner_key)s' % {'params_str': params_str, 'partner_key': key}  reload(sys)  sys.setdefaultencoding('utf8')  params_str = hashlib.md5(params_str.encode('utf-8')).hexdigest()  sign = params_str.upper()  return sign ''' def getPayUrl(self, orderid, openid, goodsPrice, **kwargs):  """向微信支付端发出请求,获取url"""  key = self._API_KEY  nonce_str = ''.join(random.sample(string.letters + string.digits, 30)) # 生成随机字符串,小于32位  params = {   'appid': self._APP_ID, # 小程序ID   'mch_id': self._MCH_ID, # 商户号   'nonce_str': nonce_str, # 随机字符串   "body": '测试订单', # 支付说明   'out_trade_no': orderid, # 生成的订单号   'total_fee': str(goodsPrice), # 标价金额   'spbill_create_ip': "127.0.0.1", # 小程序不能获取客户ip,web用socekt实现   'notify_url': self._NOTIFY_URL,   'trade_type': "JSAPI", # 支付类型   "openid": openid, # 用户id   }  # 生成签名  params['sign'] = self.generate_sign(params)  # python3一种写法  param = {'root': params}  xml = xmltodict.unparse(param)  response = requests.post(self._UFDODER_URL, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})  # xml 2 dict  msg = response.text  xmlmsg = xmltodict.parse(msg)  # 4. 获取prepay_id  if xmlmsg['xml']['return_code'] == 'SUCCESS':   if xmlmsg['xml']['result_code'] == 'SUCCESS':    prepay_id = xmlmsg['xml']['prepay_id']    # 时间戳    timeStamp = str(int(time.time()))    # 5. 五个参数    data = {     "appId": self._APP_ID,     "nonceStr": nonce_str,     "package": "prepay_id=" + prepay_id,     "signType": 'MD5',     "timeStamp": timeStamp,    }    # 6. paySign签名    paySign = self.generate_sign(data)    data["paySign"] = paySign # 加入签名    # 7. 传给前端的签名后的参数    return data  # python2一种写法  '''  request_xml_str = '<xml>'  for key, value in params.items():   if isinstance(value, str):    request_xml_str = '%s<%s><![CDATA[%s]]></%s>' % (request_xml_str, key, value, key,)   else:    request_xml_str = '%s<%s>%s</%s>' % (request_xml_str, key, value, key,)  request_xml_str = '%s</xml>' % request_xml_str  # 向微信支付发出请求,并提取回传数据  res = urllib2.Request(self._UFDODER_URL, data=request_xml_str.encode("utf-8"))  res_data = urllib2.urlopen(res)  res_read = res_data.read()  doc = xmltodict.parse(res_read)  return_code = doc['xml']['return_code']  if return_code == "SUCCESS":   result_code = doc['xml']['result_code']   if result_code == "SUCCESS":    doc = doc['xml']    data = {     "appId": self._APP_ID,     "nonceStr": nonce_str,     "package": "prepay_id=" + doc["prepay_id"],     "signType": 'MD5',     "timeStamp": str(int(time.time())),    }    # paySign签名    paySign = self.generate_sign(data)    data["paySign"] = paySign # 加入签名    return data   else:    err_des = doc['xml']['err_code_des']    return err_des   else:   fail_des = doc['xml']['return_msg']   return fail_des  '''

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

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

4.支付回调

# 统一下单回调处理import xmltodictfrom django.http import HttpResponsedef payback(request): msg = request.body.decode('utf-8') xmlmsg = xmltodict.parse(msg) return_code = xmlmsg['xml']['return_code'] if return_code == 'FAIL':  # 官方发出错误  return HttpResponse("""<xml><return_code><![CDATA[FAIL]]></return_code>       <return_msg><![CDATA[Signature_Error]]></return_msg></xml>""",       content_type='text/xml', status=200) elif return_code == 'SUCCESS':  # 拿到这次支付的订单号  out_trade_no = xmlmsg['xml']['out_trade_no']  # 根据需要处理业务逻辑  return HttpResponse("""<xml><return_code><![CDATA[SUCCESS]]></return_code>       <return_msg><![CDATA[OK]]></return_msg></xml>""",       content_type='text/xml', status=200)

当然微信回调的参数有很多详细可以参考https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8

在回调的时候可能遇到这样一个问题,支付成功以后没有调回调函数,有可能是回调地址是https然后改为http就行,遇到过这个坑,具体原因也不知道。服务器没有屏蔽https访问,https证书也没有问题,把https改为http最后就可以了。

5.安全问题

在使用的过程中商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。

我在开发过程中的解决方式是在向微信支付端发起请求的时候,把订单号,金额,签名等存入数据库,然后在回调函数那里进行校验判断。在确认跟前面订单情况一样的情况下,才进行后续一系列的操作。

最后送给大家一段祝福

#         _oo8oo_#         o8888888o#         88" . "88#         (| -_- |)#         0\ = /0#        ___/'==='\___#        .' \\|  |# '.#       / \\||| : |||# \#       / _||||| -:- |||||_ \#       | | \\\ - #/ | |#       | \_| ''\---/'' |_/ |#       \ .-\__ '-' __/-. /#      ___'. .' /--.--\ '. .'___#      ."" '< '.___\_<|>_/___.' >' "".#     | | : `- \`.:`\ _ /`:.`/ -` : | |#     \ \ `-. \_ __\ /__ _/ .-` / /#    =====`-.____`.___ \_____/ ___.`____.-`=====#         `=---=`###    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##       

总结

以上所述是小编给大家介绍的Python实现微信小程序支付功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!


  • 上一条:
    python3 批量获取对应端口服务的实例
    下一条:
    python实现切割url得到域名、协议、主机名等各个字段的例子
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客