Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

微信支付 V3 (wx-pay)

Feature: wx-pay-h5 / wx-pay-native / wx-pay-app / wx-pay-mini / wx-pay-js

📖 官方文档:https://pay.weixin.qq.com/doc/v3/merchant/4012791832\(产品介绍)

基于微信支付 V3 API,使用 RSA-SHA256 签名,统一支持五种支付方式。

产品概述

支付方式Feature场景预下单返回调起方式
H5 支付wx-pay-h5手机浏览器网页h5_url前端重定向到 h5_url
Native 支付wx-pay-nativePC 端扫码code_url将 code_url 转换为二维码
APP 支付wx-pay-app商户 APP 内prepay_idAPP 端调起微信 SDK
小程序支付wx-pay-mini微信小程序内prepay_idwx.requestPayment
JSAPI 支付wx-pay-js微信内置浏览器prepay_idWeixinJSBridge.invoke

📖 H5 产品介绍 | Native 产品介绍 | APP 产品介绍 | 小程序/JSAPI 产品介绍

配置

三种支付方式共用一个 [wx_pay] 配置段:

[wx_pay]
mch_id = ""                          # 商户号
app_id = ""                          # 应用 ID (AppID)
api_v3_key = ""                      # API v3 密钥 (32 字节)
private_key = """                    # 商户 API 私钥 (PEM 格式)
-----BEGIN PRIVATE KEY...
...
-----END PRIVATE KEY...
"""
serial_no = ""                       # 商户证书序列号
notify_url = ""                      # 支付回调完整 URL (发给微信)
# callback_path = "wx/pay/notify"    # 回调路由路径, 默认 wx/pay/notify
# refund_notify_url = ""             # 退款回调完整 URL (可选, 默认使用 notify_url)
# platform_cert = """                # 微信支付平台证书公钥 (PEM 格式, 用于验签回调)
# """

使用方法

1. 预下单

📖 H5下单 | Native下单 | APP下单

H5 支付wx-pay-h5):

#![allow(unused)]
fn main() {
let result = state.wx_pay.prepay_h5(
    "ORDER_20260603_001",     // 商户订单号
    "测试商品",                // 商品描述
    100,                      // 金额 (分)
    "123.123.123.123",        // 用户终端 IP
    "Wap",                    // 场景类型 (Wap/IOS/Android)
    "https://example.com",    // 场景 URL
).await?;
println!("h5_url: {}", result.h5_url);  // 前端重定向到此 URL
}

Native 支付wx-pay-native):

#![allow(unused)]
fn main() {
let result = state.wx_pay.prepay_native(
    "ORDER_20260603_001",     // 商户订单号
    "测试商品",                // 商品描述
    100,                      // 金额 (分)
).await?;
println!("code_url: {}", result.code_url);  // 转换为二维码展示
}

APP 支付wx-pay-app):

#![allow(unused)]
fn main() {
let result = state.wx_pay.prepay_app(
    "ORDER_20260603_001",     // 商户订单号
    "测试商品",                // 商品描述
    100,                      // 金额 (分)
).await?;
println!("prepay_id: {}", result.prepay_id);  // APP 端调起微信 SDK
}

小程序支付wx-pay-mini):

#![allow(unused)]
fn main() {
let result = state.wx_pay.prepay_mini(
    "ORDER_20260603_001",     // 商户订单号
    "测试商品",                // 商品描述
    100,                      // 金额 (分)
    "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o", // 用户 openid
).await?;
println!("prepay_id: {}", result.prepay_id);  // wx.requestPayment 调起支付
}

JSAPI 支付wx-pay-js):

#![allow(unused)]
fn main() {
let result = state.wx_pay.prepay_js(
    "ORDER_20260603_001",     // 商户订单号
    "测试商品",                // 商品描述
    100,                      // 金额 (分)
    "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o", // 用户 openid
).await?;
println!("prepay_id: {}", result.prepay_id);  // WeixinJSBridge.invoke 调起支付
}

2. 查询订单

📖 商户订单号查询 | 微信支付订单号查询

#![allow(unused)]
fn main() {
let order = state.wx_pay.query_by_out_trade_no("ORDER_20260603_001").await?;
println!("交易状态: {}", order.trade_state);

let order = state.wx_pay.query_by_transaction_id("4200001234202606030000000000").await?;
}

3. 关闭订单

📖 关闭订单 API 文档

#![allow(unused)]
fn main() {
state.wx_pay.close_order("ORDER_20260603_001").await?;
}

4. 申请退款

📖 退款申请 API 文档

#![allow(unused)]
fn main() {
let refund = state.wx_pay.refund(
    "REFUND_20260603_001",
    "ORDER_20260603_001",
    100, 100,
    Some("用户申请退款"),
).await?;
}

5. 查询退款

📖 查询单笔退款

#![allow(unused)]
fn main() {
let refund = state.wx_pay.query_refund("REFUND_20260603_001").await?;
}

6. 发起异常退款

📖 发起异常退款

#![allow(unused)]
fn main() {
let refund = state.wx_pay.apply_abnormal_refund(
    "5000000001202606030000000000",
    "REFUND_20260603_001",
    "USER_BANK_CARD",
).await?;
}

7. 申请交易账单

📖 申请交易账单

#![allow(unused)]
fn main() {
let bill = state.wx_pay.apply_trade_bill("2026-06-02", Some("ALL")).await?;
}

8. 申请资金账单

📖 申请资金账单

#![allow(unused)]
fn main() {
let bill = state.wx_pay.apply_fund_flow_bill("2026-06-02", Some("BASIC")).await?;
}

9. 下载账单文件

📖 下载账单

#![allow(unused)]
fn main() {
let csv_content = state.wx_pay.download_bill(&bill.download_url).await?;
std::fs::write("bill.csv", &csv_content)?;
}

10. 处理回调通知

📖 支付成功回调通知 | 退款结果回调通知

AFaster::run() 自动注册回调路由,用户只需注册业务回调:

#![allow(unused)]
fn main() {
use afaster::wx_pay::WxPayNotifyResult;

let app = AFaster::new("config.toml".to_string()).await.unwrap()
    .with_wx_pay(|wp| {
        wp.with_pay_success_callback(|state, notify| async move {
            println!("支付成功: {} - {} 分", notify.out_trade_no,
                notify.amount.as_ref().map(|a| a.total).unwrap_or(0));
            Ok(WxPayNotifyResult::success())
        })
        .with_refund_callback(|state, notify| async move {
            println!("退款: {} - {}", notify.out_refund_no, notify.refund_status);
            Ok(WxPayNotifyResult::success())
        })
    });
}

回调处理流程:

  1. 微信 POST 到 notify_url
  2. 框架自动验签(如配置了 platform_cert
  3. event_type 分发:
    • TRANSACTION.SUCCESSpay_success_callback
    • REFUND.SUCCESS / REFUND.ABNORMAL / REFUND.CLOSEDrefund_callback
  4. 未注册回调时静默返回成功,避免微信重试

支付流程

📖 H5调起支付 | Native调起支付 | APP调起支付

商户 → 调用 prepay_xxx() → 获取 h5_url / code_url / prepay_id
    ↓
用户确认支付(重定向/扫码/SDK 调起)
    ↓
微信回调 notify_url → 后端解密通知 → 处理业务逻辑

错误码

错误码说明
40901签名验证失败
40902微信 API 业务错误
40903回调通知解密失败
40904回调通知验签失败
40905配置缺少必要字段
50901私钥加载失败
50902签名生成失败
50903请求失败
50904预下单请求失败
50905预下单响应解析失败
50907查询订单响应解析失败
50910退款响应解析失败
50911支付通知解析失败
50912退款通知解析失败
50913证书解析失败
50914账单响应解析失败

与虚拟支付的区别

维度wx-paywx-virtual-pay
场景H5/PC/APP微信小程序内
API 版本V3 (RSA-SHA256)V2 (HMAC-SHA256)
签名方式商户私钥 RSA 签名appKey HMAC 签名
回调加密AEAD_AES_256_GCMAES-256-CBC
支付方式h5_url / code_url / prepay_id小程序 SDK 调起