微信支付接口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
D-Ticket is a discord bot for ticket system

D-Ticket Discord Bot D-Ticket is a discord bot for ticket management system. This is not final product is currently being in development stay connecte

DeViL 1 Jan 06, 2022
Written in Python, freezed into stand-alone executable with PyInstaller. This app will make sure you stay in New World without getting kicked for inactivity.

New World - AFK Written in Python, freezed into stand-alone executable with PyInstaller. This app will make sure you stay in New World without getting

Rodney 5 Oct 31, 2021
A simple Discord Mass-Ban that's still working with Member Scraper.

Mass-Ban [!] This was made for education / you can use for revenge. Please don't skid it. [!] If you want to use it, please use member scraper before

WoahThatsHot 1 Nov 20, 2021
Quickly edit your slack posts.

Lightning Edit Quickly edit your Slack posts. Heavily inspired by @KhushrajRathod's LightningDelete. Usage: Note: Before anything, be sure to head ove

Cole Wilson 14 Nov 19, 2021
Unofficial Python API client for Notion.so

notion-py Unofficial Python 3 client for Notion.so API v3. Object-oriented interface (mapping database tables to Python classes/attributes) Automatic

Jamie Alexandre 3.9k Jan 03, 2023
Example of Telegram local API and aiogram 3.x

Telegram Local Full example of Telegram local application. Contains Telegram Bot API Local Telegram Bot API server based on aiogram Bot API Server ima

Oleg A. 9 Sep 16, 2022
Louis Manager Bot With Python

✨ Natsuki ✨ Are You Okay Baby I'm Natsuki Unmaintained. The new repo of @TheNatsukiBot is public. ⚡ (It is no longer based on this source code. The co

Team MasterXBots 1 Nov 07, 2021
A Bot to Track Kernel Upstreams from kernel.org and Post it on Telegram Channel

Channel Kernel Tracker is the channel where the bot will be sending the updates in. Introduction This is a Telegram Bot to Track Kernel Upstreams kern

Kartikeya Hegde 3 Oct 05, 2021
Image-Bot-Discord - This Is a discord bot that shows the specific image you search from Google

Advanced Discord.py Image Bot CREDITS Made by RLX and Mathiscool README by Milrato Installation Guide in .env Adjust the TOKEN python main.py to start

RLX 3 Jan 16, 2022
ESOLinuxAddonManager - Very simple addon manager for Elder Scrolls Online running on Linux.

ESOLinuxAddonManager Very simple addon manager for Elder Scrolls Online running on Linux. Well, more a downloader for now. Currently it's quite ugly b

Akseli 25 Aug 28, 2022
Cookiecutter templates for Serverless applications using AWS SAM and the Rust programming language.

Cookiecutter SAM template for Lambda functions in Rust This is a Cookiecutter template to create a serverless application based on the Serverless Appl

AWS Samples 24 Nov 11, 2022
0-1 knapsack with an additional constraint of maximum number of items used

extended_knapsack 0-1 knapsack with an additional constraint of maximum number of items used. Usage pip3 install extended_knapsack from extended_knaps

Lion Ralfs 1 Jan 06, 2022
Discord bot for Ukrfans Discord server

Ukrfans Discord Bot Discord bot for Ukrfans Discord server. 💡 Prerequisites Python ⚙️ Build & Run Create an .env file in the root directory and add t

3 Jun 24, 2022
iCloudPy is a simple iCloud webservices wrapper library written in Python

iCloudPy 🤟 Please star this repository if you end up using the library. It will help me continue supporting this product. 🙏 iCloudPy is a simple iCl

Mandar Patil 49 Dec 26, 2022
A telegram bot providing recon and research functions for bug bounty research

Bug Bounty Bot A telegram bot with commands to simplify bug bounty tasks Installation Use Road Map Installation BugBountyBot is open-source so you can

Tyler Butler 1 Oct 23, 2021
A python API wrapper for temp-mail.org

temp-mail Python API Wrapper for temp-mail.ru service. Temp-mail is a service which lets you use anonymous emails for free. You can view full API spec

Denis Veselov 91 Nov 19, 2022
Scheduled Block Checker for Cardano Stakepool Operators

ScheduledBlocks Scheduled Block Checker for Cardano Stakepool Operators Lightweight and Portable Scheduled Blocks Checker for Current Epoch. No cardan

SNAKE (Cardano Stakepool) 4 Oct 18, 2022
A Code that can make your Discord Account 24/7!

Online-Forever Make your Discord Account Online 24/7! A Code written in Python that helps you to keep your account 24/7. The main.py is the main file.

Phantom 556 Dec 29, 2022
arweave-nft-uploader is a Python tool to improve the experience of uploading NFTs to the Arweave storage for use with the Metaplex Candy Machine.

arweave-nft-uploader arweave-nft-uploader is a Python tool to improve the experience of uploading NFTs to the Arweave storage for use with the Metaple

0xEnrico 84 Dec 26, 2022
WIOpy - Walmart Affiliate API Python wrapper

WalmartIO Python Wrapper - WIOpy A python wrapper for the Walmart io API. Only s

6 Nov 14, 2022