Files
shaguabijia-app-server/docs/integrations/wxpay.md
T
marco a114a0f3f2 docs(integrations/wxpay): 删 code_to_openid 行,跟齐 9d1278c 死代码清理
9d1278c 已删 wxpay.py 的 code_to_openid 函数(能力被 code_to_userinfo 覆盖),
docs 函数表里这一行没跟着删,补齐。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 20:44:46 +08:00

2.8 KiB
Raw Blame History

微信支付 V3 — 商家转账到零钱(提现)+ code 换 openidwxpay

文件:app/integrations/wxpay.py | 关联接口:wallet-withdraw · wallet-withdraw-status · wallet-bind-wechat · wallet-withdraw-info | ← 集成索引

作用

两件事:①提现——微信支付 V3「商家转账到零钱」;②绑定——微信授权 code 换 openid / 昵称头像。移植自 elderhelper,密钥懒加载(文件缺失不在 import 时炸,只在真正调用时抛 WxPayNotConfiguredError,与极光私钥同款策略)。

函数

函数 说明
create_transfer(openid, amount_fen, out_bill_no, user_name=None) 发起商家转账到零钱。返回 {status_code, data}
query_transfer(out_bill_no) 按商户单号查转账单状态
cancel_transfer(out_bill_no) 撤销转账单(仅 WAIT_USER_CONFIRM/ACCEPTED 可撤)。用户没在确认页确认就离开时调
encrypt_sensitive(plain) 用微信支付平台公钥 OAEP(SHA1) 加密敏感信息(实名)
code_to_userinfo(code) code 换 openid + 拉昵称头像,返回 {openid, nickname, avatar_url, raw}

签名机制

  • 请求签名:商户 API 私钥 RSA-SHA256/PKCS1v15,构造 V3 Authorization 头(WECHATPAY2-SHA256-RSA2048,含 mchid/nonce/timestamp/serial_no/signature)。
  • 敏感字段(实名):微信支付平台公钥 OAEP(SHA1) 加密,请求头带 Wechatpay-Serial
  • 实名传递阈值:amount_fen >= 30(沿用 elderhelper,实际以微信侧要求为准)才加密带 user_name
  • 转账接口路径:/v3/fund-app/mch-transfer/transfer-billshost https://api.mch.weixin.qq.com

配置

配置项 说明
WECHAT_APP_ID / WECHAT_APP_SECRET 微信开放平台移动应用 appid / secret(换 openid 用)
WXPAY_MCH_ID / WXPAY_MCH_SERIAL_NO 商户号 / 商户证书序列号
WXPAY_MCH_PRIVATE_KEY_PATH 商户 API 私钥 .pem 路径
WXPAY_PUBLIC_KEY_PATH / WXPAY_PUBLIC_KEY_ID 微信支付平台公钥 .pem 路径 / 公钥 ID
WXPAY_TRANSFER_SCENE_ID 转账场景 ID
WXPAY_REQUEST_TIMEOUT_SEC 请求超时

踩坑

  • userinfo 可能脱敏:微信隐私新政下 sns/userinfo 可能返回昵称「微信用户」/灰头像,nickname/avatar_url 可能为空,调用方需兜底(绑定不因此失败,openid 已拿到)。
  • cancel_transfer 是提现「轮询查单时若仍 WAIT_USER_CONFIRM」的退款依据(见 wallet-withdraw-status 的副作用)。
  • 凭证/证书未配置时所有转账类调用抛 WxPayNotConfiguredErrorapi 层翻成 503