热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

这篇文章主要介绍了Python实现微信小程序支付功能,本文通过实例代码,流程图给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

正文

由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用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 requests
import hashlib
import xmltodict
import time
import random
import string
import urllib2
import sys
class 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 = ''
  for key, value in params.items():
   if isinstance(value, str):
    request_xml_str = '%s<%s>' % (request_xml_str, key, value, key,)
   else:
    request_xml_str = '%s<%s>%s' % (request_xml_str, key, value, key,)
  request_xml_str = '%s' % 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://www.jb51.net/article/166176.htm 。

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

4.支付回调

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

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

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

5.安全问题

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

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

最后送给大家一段祝福

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

总结

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


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 小程序自动授权和手动接入的方式及操作步骤
    本文介绍了小程序支持的两种接入方式:自动授权和手动接入,并详细说明了它们的操作步骤。同时还介绍了如何在两种方式之间切换,以及手动接入后如何下载代码包和提交审核。 ... [详细]
  • 手把手教你使用GraphPad Prism和Excel绘制回归分析结果的森林图
    本文介绍了使用GraphPad Prism和Excel绘制回归分析结果的森林图的方法。通过展示森林图,可以更加直观地将回归分析结果可视化。GraphPad Prism是一款专门为医学专业人士设计的绘图软件,同时也兼顾统计分析的功能,操作便捷,可以帮助科研人员轻松绘制出高质量的专业图形。文章以一篇发表在JACC杂志上的研究为例,利用其中的多因素回归分析结果来绘制森林图。通过本文的指导,读者可以学会如何使用GraphPad Prism和Excel绘制回归分析结果的森林图。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • 微信答题小程序的设计与实现详解
    本文详细介绍了如何设计和实现一个微信答题小程序,包括题库的设计和题目的呈现。通过抽取题目编号和使用全局变量记录当前题目的信息,实现了题目的刷新和显示。同时,还介绍了题目的展示方式和容器的创建。本文适合零基础的小白学习微信答题小程序的开发。 ... [详细]
  • 微信小程序导航跟随的实现方法
    本文介绍了在微信小程序中实现导航跟随的方法。通过设置导航的position属性和绑定滚动事件,可以实现页面向下滚动到导航位置时,导航固定在页面最上方;页面向上滚动到导航位置时,导航恢复到原始位置;点击导航可以平滑跳转到相应位置。代码示例也给出了具体实现方法。 ... [详细]
author-avatar
muc4093631
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有