python的微信支付代码

from __future__ import unicode_literalsimport time
import string
import random
import hashlib
import requestsfrom .base import Map, WeixinErrortry:from flask import request
except Exception:request = Nonefrom lxml import etree__all__ = ("WeixinPayError", "WeixinPay")FAIL = "FAIL"
SUCCESS = "SUCCESS"class WeixinPayError(WeixinError):def __init__(self, msg):super(WeixinPayError, self).__init__(msg)class WeixinPay(object):PAY_HOST = "https://api.mch.weixin.qq.com"def __init__(self, app_id, mch_id, mch_key, notify_url, key=None, cert=None):self.app_id = app_idself.mch_id = mch_idself.mch_key = mch_keyself.notify_url = notify_urlself.key = keyself.cert = certself.sess = requests.Session()@propertydef timestamp(self):return str(int(time.time()))@propertydef remote_addr(self):if request is not None:return request.remote_addrreturn ""@propertydef nonce_str(self):char = string.ascii_letters + string.digitsreturn "".join(random.choice(char) for _ in range(32))def sign(self, raw):raw = [(k, str(raw[k]) if isinstance(raw[k], int) else raw[k])for k in sorted(raw.keys())]s = "&".join("=".join(kv) for kv in raw if kv[1])s += "&key={0}".format(self.mch_key)return hashlib.md5(s.encode("utf-8")).hexdigest().upper()def check(self, data):sign = data.pop("sign")return sign == self.sign(data)def to_xml(self, raw):s = ""for k, v in raw.items():s += "<{0}>{1}</{0}>".format(k, v)s = "<xml>{0}</xml>".format(s)return s.encode("utf-8")def to_dict(self, content):raw = {}root = etree.fromstring(content.encode("utf-8"),parser=etree.XMLParser(resolve_entities=False))for child in root:raw[child.tag] = child.textreturn rawdef _fetch(self, url, data, use_cert=False, appid=True):if appid:data.setdefault("appid", self.app_id)data.setdefault("mch_id", self.mch_id)data.setdefault("nonce_str", self.nonce_str)data.setdefault("sign", self.sign(data))if use_cert:resp = self.sess.post(url, data=self.to_xml(data), cert=(self.cert, self.key))else:resp = self.sess.post(url, data=self.to_xml(data))content = resp.content.decode("utf-8")if "return_code" in content:data = Map(self.to_dict(content))if data.return_code == FAIL:raise WeixinPayError(data.return_msg)if "result_code" in content and data.result_code == FAIL:raise WeixinPayError(data.err_code_des)return datareturn contentdef reply(self, msg, ok=True):code = SUCCESS if ok else FAILreturn self.to_xml(dict(return_code=code, return_msg=msg))def unified_order(self, **data):"""统一下单out_trade_no、body、total_fee、trade_type必填app_id, mchid, nonce_str自动填写spbill_create_ip 在flask框架下可以自动填写, 非flask框架需要主动传入此参数"""url = self.PAY_HOST + '/pay/unifiedorder'# 必填参数if "out_trade_no" not in data:raise WeixinPayError("缺少统一支付接口必填参数out_trade_no")if "body" not in data:raise WeixinPayError("缺少统一支付接口必填参数body")if "total_fee" not in data:raise WeixinPayError("缺少统一支付接口必填参数total_fee")if "trade_type" not in data:raise WeixinPayError("缺少统一支付接口必填参数trade_type")# 关联参数if data["trade_type"] == "JSAPI" and "openid" not in data:raise WeixinPayError("trade_type为JSAPI时,openid为必填参数")if data["trade_type"] == "NATIVE" and "product_id" not in data:raise WeixinPayError("trade_type为NATIVE时,product_id为必填参数")data.setdefault("notify_url", self.notify_url)if "spbill_create_ip" not in data:data.setdefault("spbill_create_ip", self.remote_addr)raw = self._fetch(url, data)return rawdef jsapi(self, **kwargs):"""生成给JavaScript调用的数据详细规则参考 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6"""kwargs.setdefault("trade_type", "JSAPI")raw = self.unified_order(**kwargs)package = "prepay_id={0}".format(raw["prepay_id"])nonce_str = self.nonce_strraw = dict(appId=self.app_id, timeStamp=self.timestamp,nonceStr=self.nonce_str, package=package,signType='MD5')sign = self.sign(raw)raw['paySign'] = signreturn raworder_jsapi = jsapidef order_h5(self, **kwargs):"""H5 支付详细规则参考 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1"""kwargs.setdefault('trade_type', 'MWEB')return self.unified_order(**kwargs)def order_qr(self, **kwargs):"""Native 支付(扫码支付)详细规则参考 https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1"""kwargs.setdefault('trade_type', 'NATIVE')return self.unified_order(**kwargs)def qrcode_url(self, product_id, shorten=False):params = {'appid': self.app_id,'mch_id': self.mch_id,'product_id': product_id,'time_stamp': self.timestamp,'nonce_str': self.nonce_str,}params['sign'] = self.sign(params)text = ('weixin://wxpay/bizpayurl?sign=%(sign)s&appid=%(appid)s&mch_id=%(mch_id)s''&product_id=%(product_id)s&time_stamp=%(time_stamp)s&nonce_str=%(nonce_str)s') % paramsif shorten:return self.qrcode_url_shorten(long_url=urlencode(text))return textdef qrcode_url_shorten(self, **data):url = self.PAY_HOST + '/tools/shorturl'if 'long_url' not in data:raise WechatPayError('缺少转换短链接接口必填参数long_url')return self._fetch(url, data)['short_url']def order_query(self, **data):"""订单查询out_trade_no, transaction_id至少填一个appid, mchid, nonce_str不需要填入"""url = self.PAY_HOST + '/pay/orderquery'if "out_trade_no" not in data and "transaction_id" not in data:raise WeixinPayError("订单查询接口中,out_trade_no、transaction_id至少填一个")return self._fetch(url, data)def close_order(self, out_trade_no, **data):"""关闭订单out_trade_no必填appid, mchid, nonce_str不需要填入"""url = self.PAY_HOST + '/pay/closeorder'data.setdefault("out_trade_no", out_trade_no)return self._fetch(url, data)def refund(self, **data):"""申请退款out_trade_no、transaction_id至少填一个且out_refund_no、total_fee、refund_fee、op_user_id为必填参数appid、mchid、nonce_str不需要填入"""url = self.PAY_HOST + '/secapi/pay/refund'if not self.key or not self.cert:raise WeixinPayError("退款申请接口需要双向证书")if "out_trade_no" not in data and "transaction_id" not in data:raise WeixinPayError("退款申请接口中,out_trade_no、transaction_id至少填一个")if "out_refund_no" not in data:raise WeixinPayError("退款申请接口中,缺少必填参数out_refund_no");if "total_fee" not in data:raise WeixinPayError("退款申请接口中,缺少必填参数total_fee");if "refund_fee" not in data:raise WeixinPayError("退款申请接口中,缺少必填参数refund_fee");return self._fetch(url, data, True)def refund_query(self, **data):"""查询退款提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个appid、mchid、nonce_str不需要填入"""url = self.PAY_HOST + '/pay/refundquery'if "out_refund_no" not in data and "out_trade_no" not in data \and "transaction_id" not in data and "refund_id" not in data:raise WeixinPayError("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个")return self._fetch(url, data)def download_bill(self, bill_date, bill_type="ALL", **data):"""下载对账单bill_date、bill_type为必填参数appid、mchid、nonce_str不需要填入"""url = self.PAY_HOST + '/pay/downloadbill'data.setdefault("bill_date", bill_date)data.setdefault("bill_type", bill_type)if "bill_date" not in data:raise WeixinPayError("对账单接口中,缺少必填参数bill_date")return self._fetch(url, data)def pay_individual(self, **data):"""企业付款到零钱"""url = self.PAY_HOST + '/mmpaymkttransfers/promotion/transfers'if not self.key or not self.cert:raise WeixinPayError("企业接口需要双向证书")if "partner_trade_no" not in data:raise WeixinPayError("企业付款接口中, 缺少必要的参数partner_trade_no")if "openid" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数openid")if "amount" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数amount")if "desc" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数desc")data.setdefault('check_name', 'NO_CHECK')return self._fetch_pay(url, data, True)def pay_individual_to_card(self, **data):"""企业付款到银行卡"""url = self.PAY_HOST + '/mmpaysptrans/pay_bank'if not self.key or not self.cert:raise WeixinPayError("企业接口需要双向证书")if "partner_trade_no" not in data:raise WeixinPayError("企业付款接口中, 缺少必要的参数partner_trade_no")if "enc_bank_no" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数enc_bank_no")if "enc_true_name" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数enc_true_name")if "bank_code" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数bank_code")if "amount" not in data:raise WeixinPayError("企业付款接口中,缺少必填参数amount")return self._fetch(url, data, True, False)def pay_individual_bank_query(self, **data):"""企业付款到银行卡查询"""url = self.PAY_HOST + '/mmpaysptrans/query_bank'if not self.key or not self.cert:raise WeixinPayError("企业接口需要双向证书'")if "partner_trade_no" not in data:raise WeixinPayError("企业付款接口中, 缺少必要的参数partner_trade_no")return self._fetch(url, data, True, False)def pay_individual_query(self, **data):"""企业付款到零钱查询"""url = self.PAY_HOST + '/mmpaymkttransfers/gettransferinfo'if not self.key or not self.cert:raise WeixinPayError("企业接口需要双向证书'")if "partner_trade_no" not in data:raise WeixinPayError("企业付款接口中, 缺少必要的参数partner_trade_no")return self._fetch(url, data, True)def _fetch_pay(self, url, data, use_cert=False):data.setdefault("mch_appid", self.app_id)data.setdefault("mchid", self.mch_id)data.setdefault("nonce_str", self.nonce_str)data.setdefault("sign", self.sign(data))if use_cert:resp = self.sess.post(url, data=self.to_xml(data), cert=(self.cert, self.key))else:resp = self.sess.post(url, data=self.to_xml(data))content = resp.content.decode("utf-8")if "return_code" in content:data = Map(self.to_dict(content))if data.return_code == FAIL:raise WeixinPayError(data.return_msg)if "result_code" in content and data.result_code == FAIL:raise WeixinPayError(data.err_code_des)return datareturn content

python的微信支付代码相关推荐

  1. Python实现微信支付(三种方式)

    Python实现微信支付(三种方式) 微信.支付宝二维码聚合SDK下载 点我下载 关注公众号"轻松学编程"了解更多. 如果需要python SDk源码,可以加我微信[1257309 ...

  2. Python实现微信支付(Jsapi和微信扫码)

    Python实现微信支付 一.准备环境 1.要有微信公众号,商户平台账号 https://pay.weixin.qq.com/wiki/doc/api/index.html 一.扫码支付 点击&quo ...

  3. 微信团队分享:微信支付代码重构带来的移动端软件架构上的思考

    本文原文由微信客户端高级工程师方秋枋原创发表于WeMobileDev公众号,收录时有修订和加工,感谢作者的无私分享. 1.引言 作为一个重要业务,微信支付在客户端上面临着各种问题. 其中最核心问题就是 ...

  4. ASP 生成微信支付代码

    您可以使用 ASP.NET 来生成微信支付代码.首先,您需要在微信支付官方网站上申请账号并获得 API 密钥.然后,您可以使用微信支付 API 来生成微信支付代码,进行订单的创建.支付等操作. 具体实 ...

  5. python对接微信支付_python3接入微信企业支付实现小程序提现

    最近发现某些小程序有了提现功能,原来小程序是不支持提现的,所以当初实现方法是打算让用户去关注公众号,再从公众号提现,当然前提要公众号跟小程序使用同一的unionid来标记唯一用户,既然现在支持小程序直 ...

  6. python调用微信支付_Python使用JsAPI发起微信支付 Demo

    Python使用JsAPI发起微信支付 Demo 这个是基于Django框架. 了解更多,可以关注公众号"轻松学编程" 1.公众号设置.微信商户号设置 这些都可以在官网查得到, 左 ...

  7. java微信支付代码_Java微信支付之服务号支付代码示例

    Java微信支付之服务号支付实现,网上的java微信支付sdk和Demo基本上是水的,看着头疼所以我决心自己开始写Java微信支付之公众号支付,多的不说见下面源码,为了方便使用我分别用了两个Servl ...

  8. python个人微信支付接口_Python实现微信小程序支付功能

    正文 由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 2.获取openid( ...

  9. java微信支付代码_10行代码搞定微信支付(Java版)

    原标题:10行代码搞定微信支付(Java版) 微信支付痛点 对于大多数同学来说,要开发微信支付可不简单.附上微信支付官方文档网页链接 从文档上可以看出,你需要解决很多问题,我就随便挑几个吧. xml与 ...

最新文章

  1. 如何设计一个短URL地址系统
  2. 中断函数 printf_嵌入式中断服务函数的一些特点
  3. Java高并发编程详解系列-Java线程入门
  4. arcgis api for js共享干货系列之二自定义Navigation控件样式风格
  5. 【Python第三篇】Python装饰器、生成器、迭代器
  6. SharePoint 2007和WSS 3.0 SDK 1.2 Release
  7. 使用MEAT在iOS设备上采集取证信息
  8. x86 x64 arm64的区别
  9. 证明连续随机变量形式Jensen不等式
  10. ios备忘录下载安卓版_ios8备忘录安卓版下载,ios8备忘录app软件下载安卓版 v3.0-开心路...
  11. seo软文标题写作技巧:好的标题是靠这样想出来的
  12. 家庭问题(信息学奥赛一本通 - T1362)
  13. 超详细面试准备(10分钟打遍所有初级后端开发面试)
  14. Docker入门笔记(1)
  15. Python使用psutil的电脑资源监控软件
  16. 将MindManager添加到鼠标右键新建项
  17. 漫画 | Java语言是如何诞生的?
  18. 【paper笔记】Personalized Top-N Sequential Recommendation via Convolutional Sequence Embedding
  19. 我学习从事项目经理第一个课
  20. frameSet和iframe的基本理解

热门文章

  1. excel表格显示不全的方法教程
  2. 二维码生成工具源码(C#版)
  3. win10远程桌面连接凭据怎么设置_手把手操作win10系统连接远程桌面提示你的凭据不工作的恢复步骤...
  4. ps教程之淘宝图片怎么加水印方法案例
  5. 为超透镜打一点基础吧
  6. php fsockopen http,Php 应用 fsockopen发送http请求
  7. php投影,电脑如何连投影仪?
  8. WPF的DataGrid控件样式自定义
  9. 电子商务大赛历年获奖作品_武汉商贸职业学院师生在第九届海洋文化创意设计大赛中喜获佳绩! —湖北站—中国教育在线...
  10. 【首席信息官】首席信息官如何应对重大辞职