微信支付接口V3版python库

Overview

wechatpayv3

PyPI version Download count

介绍

微信支付接口V3版python库。

适用对象

wechatpayv3支持微信支付直连商户,接口说明详见 官网

特性

  1. 平台证书自动更新,无需开发者关注平台证书有效性,无需手动下载更新;
  2. 支持本地缓存平台证书,初始化时指定平台证书保存目录即可。

适配进度

微信支付V3版API接口

其中:

基础支付

JSAPI支付 已适配
APP支付 已适配
H5支付 已适配
Native支付 已适配
小程序支付 已适配
合单支付 已适配
付款码支付 待官网更新
刷脸支付 无需适配

行业方案

智慧商圈 已适配

需要的接口适配怎么办?

由于wechatpayv3包内核心的core.py已经封装了请求签名和消息验证过程,开发者无需关心web请求细节,直接根据官方文档参考以下基础支付的申请退款接口代码自行适配,测试OK的话,欢迎提交代码。 必填的参数建议加上空值检查,可选的参数默认传入None。参数类型对照参考下表:

文档声明 wechatpayv3
string string
int int
object dict: {}
array list: []
boolean bool: True, False
def refund(self,
           out_refund_no,
           amount,
           transaction_id=None,
           out_trade_no=None,
           reason=None,
           funds_account=None,
           goods_detail=None,
           notify_url=None):
    """申请退款
    :param out_refund_no: 商户退款单号,示例值:'1217752501201407033233368018'
    :param amount: 金额信息,示例值:{'refund':888, 'total':888, 'currency':'CNY'}
    :param transaction_id: 微信支付订单号,示例值:'1217752501201407033233368018'
    :param out_trade_no: 商户订单号,示例值:'1217752501201407033233368018'
    :param reason: 退款原因,示例值:'商品已售完'
    :param funds_account: 退款资金来源,示例值:'AVAILABLE'
    :param goods_detail: 退款商品,示例值:{'merchant_goods_id':'1217752501201407033233368018', 'wechatpay_goods_id':'1001', 'goods_name':'iPhone6s 16G', 'unit_price':528800, 'refund_amount':528800, 'refund_quantity':1}
    :param notify_url: 通知地址,示例值:'https://www.weixin.qq.com/wxpay/pay.php'
    """
    params = {}
    params['notify_url'] = notify_url or self._notify_url
    # 
    if out_refund_no:
        params.update({'out_refund_no': out_refund_no})
    else:
        raise Exception('out_refund_no is not assigned.')
    if amount:
        params.update({'amount': amount})
    else:
        raise Exception('amount is not assigned.')
    if transaction_id:
        params.update({'transaction_id': transaction_id})
    if out_trade_no:
        params.update({'out_trade_no': out_trade_no})
    if reason:
        params.update({'reason': reason})
    if funds_account:
        params.update({'funds_account': funds_account})
    if goods_detail:
        params.update({'goods_detail': goods_detail})
    path = '/v3/refund/domestic/refunds'
    return self._core.request(path, method=RequestType.POST, data=params)

源码

github

gitee

安装

$ pip install wechatpayv3

使用方法

准备

参考微信官方文档准备好密钥, 证书文件和配置(证书/密钥/签名介绍)

初始化

from wechatpayv3 import WeChatPay, WeChatPayType

# 微信支付商户号
MCHID = '1230000109'
# 商户证书私钥
PRIVATE_KEY = 'MIIEvwIBADANBgkqhkiG9w0BAQE...'
# 商户证书序列号
CERT_SERIAL_NO = '444F4864EA9B34415...'
# API v3密钥, https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_2.shtml
APIV3_KEY = 'MIIEvwIBADANBgkqhkiG9w0BAQE...'
# APPID
APPID = 'wxd678efh567hg6787'
# 回调地址,也可以在调用接口的时候覆盖
NOTIFY_URL = 'https://www.weixin.qq.com/wxpay/pay.php'

wxpay = WeChatPay(
    wechatpay_type=WeChatPayType.MINIPROG,
    mchid=MCHID,
    parivate_key=PRIVATE_KEY,
    cert_serial_no=CERT_SERIAL_NO,
    apiv3_key=APIV3_KEY,
    appid=APPID,
    notify_url=NOTIFY_URL)

接口

# 统一下单
def pay():
    code, message = wxpay.pay(
        description='demo-description',
        out_trade_no='demo-trade-no',
        amount={'total': 100},
        payer={'openid': 'demo-openid'})
    print('code: %s, message: %s' % (code, message))

# 订单查询
def query():
    code, message = wxpay.query(transaction_id='demo-transation-id')
    print('code: %s, message: %s' % (code, message))

# 关闭订单
def close():
    code, message = wxpay.close(out_trade_no='demo-out-trade-no')
    print('code: %s, message: %s' % (code, message))

# 申请退款
def refund():
    code, message=wxpay.refund(
        out_refund_no='demo-out-refund-no',
        amount={'refund': 100, 'total': 100, 'currency': 'CNY'},
        transaction_id='1217752501201407033233368018')
    print('code: %s, message: %s' % (code, message))

# 退款查询
def query_refund():
    code, message = wxpay.query_refund(out_refund_no='demo-out-refund-no')
    print('code: %s, message: %s' % (code, message))

# 申请交易账单
def trade_bill():
    code, message = wxpay.trade_bill(bill_date='2021-04-01')
    print('code: %s, message: %s' % (code, message))

# 申请资金流水账单
def fundflow_bill():
    code, message = wxpay.fundflow_bill(bill_date='2021-04-01')
    print('code: %s, message: %s' % (code, message))

# 下载账单
def download_bill():
    code, message = wxpay.download_bill(url='https://api.mch.weixin.qq.com/v3/billdownload/file?token=demo-token')
    print('code: %s, message: %s' % (code, message))

# 合单支付下单
def combine_pay():
    code, message = wxpay.combine_pay(
        combine_out_trade_no='demo_out_trade_no',
        sub_orders=[{'mchid':'1900000109',
                     'attach':'深圳分店',
                     'amount':{'total_amount':100,'currency':'CNY'},
                     'out_trade_no':'20150806125346',
                     'description':'腾讯充值中心-QQ会员充值',
                     'settle_info':{'profit_sharing':False, 'subsidy_amount':10}}])
    print('code: %s, message: %s' % (code, message))

# 合单订单查询
def combine_query():
    code, message = wxpay.combine_query(combine_out_trade_no='demo_out_trade_no')
    print('code: %s, message: %s' % (code, message))

# 合单订单关闭
def combine_close():
    code, message = wxpay.combine_close(
        combine_out_trade_no='demo_out_trade_no', 
        sub_orders=[{'mchid': '1900000109', 'out_trade_no': '20150806125346'}])
    print('code: %s, message: %s' % (code, message))

# 计算签名供调起支付时拼凑参数使用
# 注意事项:注意参数顺序,某个参数为空时不能省略,以空字符串''占位
def sign():
    print(wxpay.sign(['wx888','1414561699','5K8264ILTKCH16CQ2502S....','prepay_id=wx201410272009395522657....']))

# 验证并解密回调消息,把回调接口收到的headers和body传入
def decrypt_callback(headers, body):
    print(wxpay.decrypt_callback(headers, body))

# 智慧商圈积分通知
def points_notify():
    code, message = wxpay.points_notify(
        transaction_id='4200000533202000000000000000',
        openid='otPAN5xxxxxxxxrOEG6lUv_pzacc',
        earn_points=True,
        increased_points=100,
        points_update_time='2020-05-20T13:29:35.120+08:00')
    print('code: %s, message: %s' % (code, message))

# 智慧商圈积分授权查询
def user_authorization():
    code, message = wxpay.user_authorizations(openid='otPAN5xxxxxxxxrOEG6lUv_pzacc')
    print('code: %s, message: %s' % (code, message))
Comments
  • 微信支付回调函数验证签名不正确,求助!

    微信支付回调函数验证签名不正确,求助!

    你好,

    在回调地址notify_url中接受request.header和request.body,并传入wxpay.decrypt_callback函数验证签名和解密返回值,验证签名失败,但解密返回值正确。

    服务器为centos 7,已设置平台证书路径为“\cert”,运行decrypt_callback函数时,系统已下载签名并存放到该文件夹。verify(timestamp, nonce, body, signature, certificate)时可以通过该证书生成公钥文件:<cryptography.hazmat.backends.openssl.rsa._RSAPublicKey object at 0x7f0dcf7b6eb0>

    然后在public_key.verify(signature, message, PKCS1v15(), SHA256())时,验证不过去。以下为拼凑的sign_str,还请帮助看看在哪一步出现了问题,非常感谢!

    例如,验签拼凑字符串为: 1627890132 Fnqw2Aw6k1fIxb8DhPAKogL76BeSnvQ6 {"id": "3e283601-7c3d-5c04-8ebf-225474439c26", "create_time": "2021-08-02T15:42:11+08:00", "resource_type": "encrypt-resource", "event_type": "TRANSACTION.SUCCESS", "summary": "支付成功", "resource": {"original_type": "transaction", "algorithm": "AEAD_AES_256_GCM", "ciphertext": "ECIKoyOZBc9soYj7gVqD1JRzXA+0LSPcbm6lPXqIqB/iLTWk9jR6En9z6vVPHpTDKIySzFb4/A9+fViPQJYMCa8tGqwA2HzMCB52PyRTRQ7nrBLBR7lQyHMZbWDqU35tujTmu4KGuO8nplOV4Q7rm+dXFt5RN7XJwbyufTQmU1FviWfzTwe7sT4ndnf4YhY7V0z7m2AhboQXGxdpSYccHLIGFpZctL4VFE1qJ4ikHdNJNvj6RF/yTElP2ssDVHd4lKckuqZ8u7xa5jmhvxzqkJIAFsVDEHKvM4wUkmgV6B6XIeuXMvxi1JNTW33hTnNWTZphcE467Ge/l2ajJckDNKJTeRv50nY+JLm6K2I7f2kmvxHm9OYpCkHlzXWqieMrPrwQs1KbfTqxYaUYW9vOESRXAAOV7q7YfMCkvfjnyX7KQEKYIsKYHPUnpWpJbBRriAH1oY5DC0SoLmlbaCEvwiaEJg7MFwhFVQYLxwk2DsIjbFC1UUxLIs5tZvKUrWFmbQOUTzmnCv/0qU7KbVZbeaHVEFzZ8d1UG1SK/db+medh65ueEwgko9DIvdCITnXTceS3AwTdre2T", "associated_data": "transaction", "nonce": "123RUOfxtcAL"}}

    opened by carter8225 7
  • 请问“敏感信息加解密”的实现代码在哪里?

    请问“敏感信息加解密”的实现代码在哪里?

    微信支付官方文档中有“敏感信息加解密”的相关要求: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml

    “开发者应当使用微信支付平台证书中的公钥,对上送的敏感信息进行加密。这样只有拥有私钥的微信支付才能对密文进行解密,从而保证了信息的机密性。 另一方面,微信支付使用 商户证书中的公钥对下行的敏感信息进行加密。开发者应使用商户私钥对下行的敏感信息的密文进行解密。”

    大佬,请问wechatpayv3中有相关实现代码吗?找了半天没找到,请恕我愚钝。

    opened by Odyssey166 7
  • wechatpayv3也支持微信支付服务商吧?

    wechatpayv3也支持微信支付服务商吧?

    大佬,再问一个可能比较普遍的问题。wechatpayv3文档上说:”适用对象wechatpayv3支持微信支付直连商户“,然后给出了接口适配的方法。通过阅读微信支付官方文档,我发现直连商户和服务商的签名验签、加密解密过程都是一样的。API本质上貌似也没什么区别。例如,以下是服务商电商收付通的API列表: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter3_3_3.shtml

    所以我认为wechatpayv3也支持微信支付服务商,只要开发者自己适配相关接口即可。

    请问我的理解是正确的吗?

    opened by Odyssey166 3
  • 微信支付分退款接口无法使用

    微信支付分退款接口无法使用

    该接口在return refund时掉了一个self参数。因此会报如下错误: File "/usr/local/lib/python3.9/site-packages/wechatpayv3/payscore.py", line 361, in payscore_refund sharedpowerbankdocker-web_api-1 | return refund(out_refund_no=out_refund_no, amount=amount, transaction_id=transaction_id, reason=reason, sharedpowerbankdocker-web_api-1 | TypeError: refund() missing 1 required positional argument: 'self'

    opened by MacGuffinLife 2
  • 【BUG】在本地证书需要更新时,程序会因无法通过证书验证而陷入死循环

    【BUG】在本地证书需要更新时,程序会因无法通过证书验证而陷入死循环

    方法路径:wechatpayv3 > core.py > _verify_signature(self, headers, body)

    方法源码:

        def _verify_signature(self, headers, body):
            signature = headers.get('Wechatpay-Signature')
            timestamp = headers.get('Wechatpay-Timestamp')
            nonce = headers.get('Wechatpay-Nonce')
            serial_no = headers.get('Wechatpay-Serial')
            cert_found = False
            for cert in self._certificates:
                if int('0x' + serial_no, 16) == cert.serial_number:
                    cert_found = True
                    certificate = cert
                    break
            if not cert_found:
                self._update_certificates()
                for cert in self._certificates:
                    if int('0x' + serial_no, 16) == cert.serial_number:
                        cert_found = True
                        certificate = cert
                        break
                if not cert_found:
                    return False
            if not rsa_verify(timestamp, nonce, body, signature, certificate):
                return False
            return True
    

    cert_foundFalse 时,程序将会执行 _update_certificates() 方法,在此更新证书的方法中,self._certificates 中的信息仍然错误,从而导致接下来的验证依旧不能通过,进而再次执行 _update_certificates() 方法,最终产生死循环

    opened by worship76 2
  • 小程序回调方法

    小程序回调方法

    请问一下,为什么我的回调方法接收到的request.data格式不对 { "id": "EV-2018022511223320873", "create_time": "2015-05-20T13:29:35+08:00", "resource_type": "encrypt-resource", "event_type": "TRANSACTION.SUCCESS", "summary": "支付成功", "resource": { "original_type": "transaction", "algorithm": "AEAD_AES_256_GCM", "ciphertext": "", "associated_data": "", "nonce": "" } }

    我得到的是这样的 {"data":[ {"effective_time":"2022-04-15T13:46:12+08:00", "encrypt_certificate": {"algorithm":"AEAD_AES_256_GCM", "associated_data":"certificate", "ciphertext":"MpxtKsvcoF3Jmuofu/L/NjZ+aUqJ4yrQG824VT4At5WHoDyd4x2ydRAJwwy+zuvZ4MsQfGyjjNkO2xAF9G7oN3cnwJAyL0Oo4ZWcrPoMZDLqccaYJaMogun/qz6u8FHP9x5CIBi3HAQzZl+FP9MhpIEuUhj/nMl8yksTWDU9R5MFdw+0CGymglJ6P3kGDIeQACXALRLT6eL0NGQSCQwFAoQpVEwDBVRIjh6beWYOKySP8KLJasL3MH3XthYcS/rvjO0lQxLER2ByZsfBg/yM+3eQuyFJUauqWlY8iPuO8GAYalhomdPWpe2TwAqwce0ZLdKfDOvDxd96TKKGeR5+BD8Ws5+b6y8PYnkcMd+WUyv8BVGl2dHf6tno3QHuqVxm61Km2Ze+6lEKjPXNr7CMX8k1rqeMhlrVxYbUhGWrNXXL+CKOJTNnQgMRO1aU46Kx0N/x9sepKL72RpYbTzcbcRwsZ4WFw+qqd2nO4afusV7HmYsztSvxxcD8fTg19kTEhI3HMWLHf8CCyQ+uRAm7ZiCi/g6WlMT5a2JYMzx4/kKucS1PCHs+3k7OYDocxXDUhVt9YlMJGPdZLMjmQzEt3CP/8zGl4ndJmOuLZsO1xGuJNN5P/h2K+JuZ0Y5toQrR6m9zlWdhmbaxiENVDzaxn9FEyR3Tj1ioRVpFhIBvmyLhZuRr+uHX/9ZcxNqKuP+pVntu+oEnd+aUSZsNV3U+S/vF2d78cFsJMgx1k9dbyYOflmAJB6qhf4MUxumqMXhu6verAs7K9RYy3B/8D+1DLv88gxRSSZVr0iqXYped6EGe0Gfp10oy0OKWAjsXmiIQaX/d4NGnFFfi0HdvaxhFokkh/Nktam0fxl40OZGeyKgqZl/NcfirjtLpRUu3YZV1ASYdbHLe8kqn0HYnMfKUdcw//5AIT9mDTnvP+wHadHicLRQHVzPR2z4IlBGm+Rr6J0yBC9LWzxFstBv/yHq9SmcqiC6C9RVOtrHpqb2HbE4kD0TbpTcofp3KGVsMOEf+hAYob94OEUU74H6tulxI1UiTr6JQzJykxP3M1FnEqb3/JN8aDZPIAwilgE/NjySpRvedkl4apvanNI8gHOK3SYyrD+RvrHrY3LcHjpiR6V5inCXYM3tmPmNiURBoIVLRLzbb84Q11lRJCVmWfE1zU62OCckmlqDJMck58QPI75EEk5sCQbBumuICKwfDfj//uU49KtvcHLVdj3WhmQtz660x2NU80ndB5WBk2AAv/rT3zFd3zGzXeM+jBy/4623dXnDEaSXHQk4BP7FLULhIsQiM/JNP+hbkyHTDq+bbJ3JzQpZtR8aTlP5wZpwWvclDCnisi65JHeEublKe2wIKoiYo9RYsHDzsqy6FlJlSqaJMu6mC6oYsF3ZG21x2Dv+WRIsf3SaPpGLpcOkVJNtT+tdT12z1i//rbLK53DADhTN2h2djPiHkx2KiMlNxocFQXtFcJIR0zmde8UQ54sLg4SMh1An+bJitpNleeCcNZuDJIQCAkpCShztQB9lFdEbeG7bWI28sMYVVOVuSYgqanmEh5CyNteqcqG21A91uMQmmQLG3dJmD9VyTvakBf3R6Qm7rLoXXUJ+yoAVJie6Te12ALLzuyE8pwI8OfvpK+BNLXBS7W3KzENTsIkx/i/IqtgGFzRkQ9guVCwA71JHiuU3+K0KLKXjN4ynLDbk2r0ZIL9m8aBHoguyoIWtFwI76Fz3B4ZwXDX7U9N9VqNGO+UjCljrTZjRQy+FSOh1DJIXKaePEROggGSOjcD3QEE9Q1va2WW7M/uv+yHh8u/V9HnsBnTQrPK09U0BIqy+3ALEhfGgZef6L5kHUY/nWDLcRwtnSq/W0NPf16XjcgQ/29Krq3OXadQ==", "nonce":"0401acb66488"}, "expire_time":"2027-04-14T13:46:12+08:00","serial_no":"474A7CDC898039BEC0F1D6F4A0F7F8C9D8113412"} ] } 麻烦帮忙看一下,非常感谢

    opened by Warzonee 1
  • applyment_submit

    applyment_submit

    path should end with ‘/’, path = '/v3/applyment4sub/applyment/', otherwise will return 404. Also,some field should encrypt too, add logic as follows in applyment_submit function: if params.get('subject_info').get('identity_info'): id_card_info = params.get('subject_info').get('identity_info').get('id_card_info') if id_card_info is not None: id_card_info['id_card_name'] = self._core.encrypt(id_card_info['id_card_name']) id_card_info['id_card_number'] = self._core.encrypt(id_card_info['id_card_number']) cipher_data = True

    opened by realwrtoff 1
Releases(1.2.35)
Owner
chen gang
chen gang
Local community telegram bot

Бот на районе Телеграм-бот для поиска адресов и заведений в вашем районе города или в небольшом городке. Требует недели прогулок по району д

Ilya Zverev 32 Jan 19, 2022
A modular dynamical-systems model of Ethereum's validator economics.

CADLabs Ethereum Economic Model A modular dynamical-systems model of Ethereum's validator economics, based on the open-source Python library radCAD, a

CADLabs 104 Jan 03, 2023
trading strategy for freqtrade crypto bot it base on CDC-ActionZone

ft-action-zone trading strategy for freqtrade crypto bot it base on CDC-ActionZone Indicator by piriya33 Clone The Repository if you just clone this r

Miwtoo 17 Aug 13, 2022
A Happy and lightweight Python Package that Provides an API to search for articles on Google News and returns a JSON response.

A Happy and lightweight Python Package that Provides an API to search for articles on Google News and returns a JSON response.

Muhammad Abdullah 273 Dec 31, 2022
A Telegram Userbot to play Audio and Video songs / files in Telegram Voice Chats.

VC UserBot A Telegram Userbot to play Audio and Video songs / files in Telegram Voice Chats. It's made with PyTgCalls and Pyrogram Requirements Python

조던 1 Nov 29, 2021
Python wrapper for the Intercom API.

python-intercom Not officially supported Please note that this is NOT an official Intercom SDK. The third party that maintained it reached out to us t

Intercom 215 Dec 22, 2022
just another discord bot

boredbot just another discord bot made to learn python this bots main function is to cache teams meeting links and send them right before the classes

macky 3 Sep 03, 2021
A telegram bot does not allow channels to send messages to the telegram supergroup

Channel Message Handler Getting started Installation $ git clone https://github.com/AbhijithNT/GroupChannelHandler.git Change directory $ cd ChannelMe

Abhijith N T 0 Dec 26, 2021
Follow pixiv account from twitter profile

Follow pixiv account from twitter profile

Genshi 7 Apr 11, 2022
Cogs for Red-DiscordBot

Redbot cogs for Red-DiscordBot authored by Kreusada This is my repository for Red Discord-Bot. I built these cogs because these were the features that

Kreus Amredes 26 Nov 07, 2022
Generate direct m3u playlist for all the channels subscribed in the Tata Sky portal

Tata Sky IPTV Script generator A script to generate the m3u playlist containing direct streamable file (.mpd or MPEG-DASH or DASH) based on the channe

Gaurav Thakkar 250 Jan 01, 2023
Ethereum Gas Fee for the MacBook Pro touchbar (using BetterTouchTool)

Gasbar Ethereum Gas Fee for the MacBook Pro touchbar (using BetterTouchTool) Worried about Ethereum gas fees? Me too. I'd like to keep an eye on them

TSS 51 Nov 14, 2022
Automated crypto trading bot as adapted from Algovibes.

crypto-trading-bot Automated crypto trading bot as adapted from Algovibes. Pre-requisites Ensure that you have created a Binance API key before procee

Kai Koh 33 Nov 01, 2022
Open API to list Viet Nam administrative divisions

Viet Nam province API Homepage: https://provinces.open-api.vn This is online tool to let my VietnamProvinces library reach more users. VietnamProvince

Nguyễn Hồng Quân 52 Dec 05, 2022
It's a discord.py simulator.

DiscordPySimulator It's a discord.py simulator. ⚠️ Things to fix Context As you may know, discord py commands provide the context as the first paramet

Juan Sebastián 11 Oct 24, 2022
How to add reaction on message discord.py

BA / HR / RS: Python (discord.py) skripta pomocu koje dodajete reakciju na vasu poruku putem komande !v ili da se dodaje samo u nekoj odredjenoj sobi.

Seekii 3 Dec 23, 2021
Zen-Userbot - Userbot gabut With Python

Zen-Userbot Disclaimer ⚠️ PERINGATAN UNTUK ANDA ⚠️ ️ Zen-Userbot

Wahyusaputra 6 Feb 12, 2022
A Next-Gen modular Python3 Telegram-Bot with Anime Theme to it.

Hsea Robot A modular Telegram Python bot running on python3 with a sqlalchemy database and an entirely themed persona to make Cutiepii suitable for An

Wahyusaputra 1 Dec 29, 2021
ResolveURL - Fork of UrlResolver by eldorados, tknorris and jsergio123

ResolveURL Fork of UrlResolver by eldorados, tknorris and jsergio123 I am in no

gujal 60 Jan 03, 2023
A Telegram Bot written in Python for mirroring files on the Internet to your Google Drive or Telegram

Original Repo mirror-leech-telegram-bot This is a Telegram Bot written in Python for mirroring files on the Internet to your Google Drive or Telegram.

0 Jan 03, 2022