Skip to content

Commit

Permalink
支持新版商家转账功能
Browse files Browse the repository at this point in the history
  • Loading branch information
minibear2021 committed Jan 15, 2025
1 parent 3266b74 commit 8d6f2cc
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 4 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pip install wechatpayv3

根据[Q&A](docs/Q&A.md)第一条判断当前账户所使用的模式(微信支付平台证书模式 或 微信支付平台公钥模式)。

参考微信官方文档准备好商户证书私钥、商户证书序列号、APIv3密钥, 如果使用微信支付公钥模式,还需要准备好微信支付平台公钥和微信支付公钥ID,这些参数配置方法请参考官方文档。
参考微信官方文档准备好商户证书私钥、商户证书序列号、APIv3密钥, 如果使用微信支付平台公钥模式,还需要准备好微信支付平台公钥和微信支付公钥ID,这些参数配置方法请参考官方文档。

- **商户 API 证书私钥:PRIVATE_KEY**。商户申请商户 API 证书时,会生成商户私钥,并保存在本地证书文件夹的文件 apiclient_key.pem 中。
> :warning: 不要把私钥文件暴露在公共场合,如上传到 Github,写在客户端代码等。
Expand All @@ -53,8 +53,8 @@ pip install wechatpayv3

在2024年09月后申请开通的微信支付可能[无法使用接口下载平台证书](docs/Q&A.md#下载平台证书时解析失败),这种情况下,需要从微信支付后台的“API安全”菜单中下载/复制以下两项,使用公钥模式初始化WechatPay。

- **微信支付公钥:PUBLIC_KEY**,微信支付后台“API安全-微信支付公钥”菜单中下载的微信支付公钥。
- **微信支付公钥ID:PUBLIC_KEY_ID**,微信支付后台“API安全-微信支付公钥”菜单中复制的微信支付公钥ID,形如:PUB_KEY_ID_1234567890...。
- **微信支付平台公钥:PUBLIC_KEY**,微信支付后台“API安全-微信支付公钥”菜单中下载的微信支付公钥。
- **微信支付平台公钥ID:PUBLIC_KEY_ID**,微信支付后台“API安全-微信支付公钥”菜单中复制的微信支付公钥ID,形如:PUB_KEY_ID_1234567890...。


### 一个最小的后端
Expand Down
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [1.3.7] - 2025-01-15

### Added

- 支持新版商家转账功能

## [1.3.6] - 2024-12-23

### Fixed
Expand Down
5 changes: 5 additions & 0 deletions docs/apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@
| 资金应用 | 商家转账到零钱 | 查询转账电子回单| transfer_query_bill_receipt |||
| 资金应用 | 商家转账到零钱 | 转账明细电子回单受理| transfer_detail_receipt |||
| 资金应用 | 商家转账到零钱 | 查询转账明细电子回单受理结果| transfer_query_receipt |||
| 资金应用 | 商家转账 | 发起转账 | mch_transfer_bills | 是 | 否
| 资金应用 | 商家转账 | 撤销转账 | mch_transfer_bills_cancel | 是 | 否
| 资金应用 | 商家转账 | 查询转账单 | mch_transfer_bills_query | 是 | 否
| 资金应用 | 商家转账 | 申请电子回单 | mch_transfer_elecsign | 是 | 否
| 资金应用 | 商家转账 | 查询电子回单 | mch_transfer_elecsign_query | 是 | 否
| 资金应用 | 分账 | 请求分账 | profitsharing_order |||
| 资金应用 | 分账 | 查询分账结果| profitsharing_order_query |||
| 资金应用 | 分账 | 请求分账回退| profitsharing_return|||
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name="wechatpayv3",
version="1.3.6",
version="1.3.7",
author="minibear",
description="微信支付 API v3 Python SDK(python sdk for wechatpay v3)",
long_description=long_description,
Expand Down
3 changes: 3 additions & 0 deletions wechatpayv3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,6 @@ def decrypt(self, ciphtext):
transfer_query_out_batch_no,
transfer_query_out_detail_no,
transfer_query_receipt)
from .mchtransfer import (mch_transfer_bills, mch_transfer_bills_cancel,
mch_transfer_bills_query, mch_transfer_elecsign,
mch_transfer_elecsign_query)
104 changes: 104 additions & 0 deletions wechatpayv3/mchtransfer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-

from .type import RequestType

def mch_transfer_bills(self, out_bill_no, transfer_scene_id, openid, transfer_amount, transfer_remark, user_name=None, user_recv_perception=None, transfer_scene_report_infos=[], appid=None, notify_url=None):
"""发起转账
:param out_bill_no: 商户单号,商户系统内部的商家单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,示例值:'plfk2020042013'
:param transfer_scene_id: 转账场景ID,示例值:'1001'
:param openid: 收款用户OpenID,商户AppID下,某用户的OpenID,示例值:'o-MYE42l80oelYMDE34nYD456Xoy'
:param transfer_amount: 转账金额,单位为“分”,示例值: 1000
:param transfer_remark: 转账备注,用户收款时可见该备注信息,最多允许32个字符,示例值:'2020年4月报销'
:param user_name: 收款用户姓名,转账金额 >= 2,000元时,该笔明细必须填写。若商户传入收款用户姓名,微信支付会校验收款用户与输入姓名是否一致,并提供电子回单,示例值:'张三'
:param user_recv_perception: 用户收款时感知到的收款原因,将根据转账场景自动展示默认内容。如有其他展示需求,可在本字段传入。示例值: '现金奖励'
:param transfer_scene_report_infos: 转账场景报备信息,示例值: [{'info_type':'奖励说明', 'info_content':'注册会员抽奖'}]
:param appid: 应用ID,可不填,默认传入初始化时的appid,示例值:'wx1234567890abcdef'
:param notify_url: 通知地址,异步接收微信支付结果通知的回调地址,示例值:'https://www.weixin.qq.com/wxpay/pay.php'
"""
params={}
if out_bill_no:
params.update({'out_bill_no':out_bill_no})
else:
raise Exception('out_batch_no is not assigned')
if transfer_scene_id:
params.update({'transfer_scene_id':transfer_scene_id})
else:
raise Exception('transfer_scene_id is not assigned')
if openid:
params.update({'openid':openid})
else:
raise Exception('openid is not assigned')
if transfer_amount:
params.update({'transfer_amount':transfer_amount})
else:
raise Exception('transfer_amount is not assigned')
if transfer_remark:
params.update({'transfer_remark':transfer_remark})
else:
raise Exception('transfer_remark is not assigned')
cipher_data = False
if user_name:
params.update({'user_name':self._core.encrypt(user_name)})
cipher_data = True
if transfer_amount >= 200000 and not user_name:
raise Exception('user_name is not assigned')
if user_recv_perception:
params.update({'user_recv_perception':user_recv_perception})
if transfer_scene_report_infos:
params.update({'transfer_scene_report_infos':transfer_scene_report_infos})
params.update({'appid': appid or self._appid})
params.update({'notify_url': notify_url or self._notify_url})
path = '/v3/fund-app/mch-transfer/transfer-bills'
return self._core.request(path, method=RequestType.POST, data=params, cipher_data=cipher_data)

def mch_transfer_bills_cancel(self, out_bill_no):
"""撤销转账
:param out_bill_no: 商户单号,商户系统内部的商家单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,示例值:'plfk2020042013'
"""
if out_bill_no:
path = f'/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{out_bill_no}/cancel'
else:
raise Exception('out_bill_no is not assigned')
return self._core.request(path)

def mch_transfer_bills_query(self, out_bill_no=None, transfer_bill_no=None):
"""查询转账单
:param out_bill_no: 商户单号,商户系统内部的商家单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,示例值:'plfk2020042013'
:param transfer_bill_no: 微信转账单号,微信商家转账系统返回的唯一标识,示例值: '1330000071100999991182020050700019480001'
"""
if not (out_bill_no or transfer_bill_no):
raise Exception('out_bill_no or transfer_bill_no is not assigned')
if out_bill_no:
path = f'/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{out_bill_no}'
else:
path = f'/v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no/{transfer_bill_no}'
return self._core.request(path)

def mch_transfer_elecsign(self, out_bill_no=None, transfer_bill_no=None):
"""申请电子回单
:param out_bill_no: 商户单号,商户系统内部的商家单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,示例值:'plfk2020042013'
:param transfer_bill_no: 微信转账单号,微信商家转账系统返回的唯一标识,示例值: '1330000071100999991182020050700019480001'
"""
if not (out_bill_no or transfer_bill_no):
raise Exception('out_bill_no or transfer_bill_no is not assigned')
params = {}
if out_bill_no:
params.update({'out_bill_no':out_bill_no})
path = '/v3/fund-app/mch-transfer/elecsign/out-bill-no'
else:
params.update({'transfer_bill_no':transfer_bill_no})
path = '/v3/fund-app/mch-transfer/elecsign/transfer-bill-no'
return self._core.request(path, method=RequestType.POST, data=params)

def mch_transfer_elecsign_query(self, out_bill_no=None, transfer_bill_no=None):
"""查询电子回单
:param out_bill_no: 商户单号,商户系统内部的商家单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,示例值:'plfk2020042013'
:param transfer_bill_no: 微信转账单号,微信商家转账系统返回的唯一标识,示例值: '1330000071100999991182020050700019480001'
"""
if not (out_bill_no or transfer_bill_no):
raise Exception('out_bill_no or transfer_bill_no is not assigned')
if out_bill_no:
path = f'/v3/fund-app/mch-transfer/elecsign/out-bill-no/{out_bill_no}'
else:
path = f'/v3/fund-app/mch-transfer/elecsign/transfer-bill-no/{transfer_bill_no}'
return self._core.request(path)

0 comments on commit 8d6f2cc

Please sign in to comment.