微信支付WechatPay-API-v3案例

本文深入解析微信支付V3版API的主要更新,包括采用Restful设计风格、JSON数据交互、SHA256-RSA数字签名算法等。通过具体案例演示如何获取平台证书、证书报文解密及处理敏感信息请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近微信商户给老板推送了一个支付即服务的功能,老板看到了就想要,好吧,那就搞吧,看流程挺简单的

但是是微信支付V3版API文档,里面和之前V2还是有出入的,

相较于的之前微信支付API,主要区别是:

  • 遵循统一的Restful的设计风格

  • 使用JSON作为数据交互的格式,不再使用XML

  • 使用基于非对称密钥的SHA256-RSA的数字签名算法,不再使用MD5或HMAC-SHA256

  • 不再要求HTTPS客户端证书

  • 使用AES-256-GCM,对回调中的关键信息进行加密保护

刚开始摸这个的时候一脸雾水,看了一天文档后,嗯,基本看懂了他的流程,流程我就不多说了,可以去看文档,写的还是比较详细的

https://wechatpay-api.gitbook.io/wechatpay-api-v3/

老规矩,我就直接上码吧!

下文可能会出现的参数

String keyPath = "apiclient_key.pem";// 私钥证书
String mchId = "";
String serialNo = "";//公钥证书序列号
String body = ""; // 请求报文主体,没有查询参数。
String platformCertPath = "WXapiclient_cert.pem";//微信平台证书 验证签名时需要使用

//获取公钥证书序列号
public String getSerinlNo(){
    X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream("apiclient_cert.pem 证书路径"));
    String serialNo  = certificate.getSerialNumber().toString(16).toUpperCase();
}

案例一 :获取平台证书(如果所需要的API没有涉及到敏感数据,可以不调用这个API,但我们以这个为案例)

    @Test
    public void v3Get() {
        // 获取平台证书列表
        try {
            Map<String, Object> result = WxPayApi.v3Execution(
                    RequestMethod.GET,
                    WxDomain.CHINA.toString(),
                    WxApiType.GET_CERTIFICATES.toString(),
                    mchId,
                    serialNo,
                    keyPath,
                    body
            );
            //平台证书序列号
            String serialNumber = MapUtil.getStr(result, "serialNumber");
            String body = MapUtil.getStr(result, "body");
            int status = MapUtil.getInt(result, "status");

            System.out.println("serialNumber:" + serialNumber);
            System.out.println("status:" + status);
            System.out.println(result);
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(result, platformCertPath);

            System.out.println("verifySignature:" + verifySignature + "\nbody:" + body);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

案例二:证书报文解密

    @Test
    public void aesTest() throws GeneralSecurityException {
        String associatedData = "";
        String nonce = "";
        String ciphertext = "";           
        String saveCertPath = "";
        //apikey3是V3API密钥
        AesUtil aesUtil = new AesUtil(apiKey3.getBytes(StandardCharsets.UTF_8));
        // 平台证书密文解密
        //associatedData,nonce,ciphertext这个三个是上面获取平台证书的几个参数
        String publicKey = aesUtil.decryptToString(
            associatedData.getBytes(StandardCharsets.UTF_8),
            nonce.getBytes(StandardCharsets.UTF_8),
            ciphertext
        );
        System.out.println("平台证书公钥明文:" + publicKey);
        // 保存证书
        //saveCertPath 保存平台证书的路径 例:E:/cert/WXapiclient_cert.pem
        FileWriter writer = new FileWriter(saveCertPath);
        writer.write(publicKey);
        // 获取平台证书序列号
        X509Certificate certificate = PayKit.getCertificate(new                         
        ByteArrayInputStream(publicKey.getBytes()));
        System.out.println(certificate.getSerialNumber().toString(16).toUpperCase());
    }

案例三:带敏感信息请求(就是API参数中有敏感数据需要加密的,和案例一区别就是案例三加了平台证书序列号)

    @Test
    public void test() throws Exception {
        // 带有敏感信息接口
        try {
            //V3都是用json了,所以用json封装参数,参数详情
            //https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/smartguide/chapter3_1.shtml
            JSONObject json = new JSONObject()
                    .set("corpid", "")
                    .set("store_id", 123456)
                    .set("userid", "Ta")
                    .set("name", rsaEncryptOAEP("姓名"))
                    .set("mobile", rsaEncryptOAEP("手机号"))
                    .set("qr_code", "")
                    .set("avatar", "");
            String body = JSONUtil.toJsonStr(json);

            Map<String, Object> result = WxPayApi.v3Execution(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.SMART_GUIDE_GUIDES.toString(),
                    mchId,
                    serialNo,
                    platSerialNumber,//平台证书序列号
                    keyPath,
                    body
            );
            System.out.println(result);
            System.out.println(JSONUtil.toJsonStr(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密敏感信息
     * @param data
     * @return
     * @throws Exception
     */
    private String rsaEncryptOAEP(String data) throws Exception {
        X509Certificate certificate =         
        PayKit.getCertificate(FileUtil.getInputStream(platformCertPath));
        String encrypt = PayKit.rsaEncryptOAEP(data, certificate);
        return encrypt;
    }

 

如果API中没有涉及到敏感数据,可直接ctrl+c+v案例一,改一下请求地址,然后像案例三那样用json封装参数就行了

如果API中有涉及到敏感数据,就要先调用获取平台证书列表,获取到平台证书序列号,然后再请求

案例二主要是用于保存平台证书,用来验证签名

如果接口中带有参数,可使用String.format(WxApiType.SMART_GUIDE_GUIDES_ASSIGN.toString(), "123")

也可以通过https://myssl.com/cert_decode.html把api证书拖进去查看相关信息

 

 

 

<think>嗯,用户想在Odoo 17中集成微信支付。首先,我需要回忆一下Odoo的支付模块是如何工作的。Odoo通常通过支付服务提供商(比如PayPal、Stripe)来处理支付,但微信支付可能需要自定义集成。用户提供的引用[1]提到Odoo系统通过集成微信支付APIv3实现了高效支付流程,所以可能已经有相关的模块或方法。 接下来,我需要考虑微信支付的具体集成步骤。根据引用[1],可能需要使用微信的APIv3本,所以需要查阅微信支付官方文档,确保接口正确。另外,引用[3]提到Odoo 18支持合作伙伴的首选付款方式配置,可能在Odoo 17中也有类似的功能,需要确认本差异。 用户可能需要准备微信商户平台的账号和API密钥,然后在Odoo中创建新的支付提供商。这里可能需要开发自定义模块,或者利用现有的第三方模块。引用[2]和[4]提到企业微信和OAuth2.0的集成,可能涉及到微信网页授权,但支付集成可能不同,需要区分开来。 另外,测试环节可能需要使用沙箱环境,以及处理回调URL。引用[4]提到使用微信web开发者工具进行测试,可能需要配置安全域名和授权回调页面。代码部分可能需要编写控制器来处理微信支付的通知,确保支付状态同步到Odoo订单中。 还需要注意Odoo的支付流程,比如生成支付链接、处理支付结果、更新订单状态。可能需要在Odoo中创建自定义支付方法,配置商户ID、API密钥等参数。最后,要提醒用户测试沙箱环境,并考虑使用SSL证书保证安全。 总之,步骤大概是:准备微信商户信息,安装或开发支付模块,配置支付参数,处理支付逻辑,测试。需要确保每一步都符合微信支付和Odoo的要求,同时参考现有引用中的成功案例和功能。</think>### Odoo 17 微信支付集成与配置步骤 #### 一、前期准备 1. **微信商户平台注册** - 申请微信支付商户账号(需企业资质),获取以下参数: - `商户号(MCHID)` - `APIv3密钥` - `API证书`(需下载并保存为`.pem`格式) - 在商户平台设置「API安全」中的回调地址: $$ \text{https://your-odoo-domain.com/wechatpay/notify} $$ 2. **Odoo环境准备** - 安装`payment`模块(系统默认集成支付框架) - 建议使用**Python微信支付SDK**(如`wechatpayv3`): ```bash pip install wechatpayv3 ``` #### 二、支付模块开发 1. **创建自定义支付模块** ```python # models/payment_provider.py from odoo import models, fields class WeChatPayProvider(models.Model): _inherit = &#39;payment.provider&#39; code = fields.Char(default=&#39;wechatpay&#39;) merchant_id = fields.Char(string=&#39;商户号&#39;, required=True) api_v3_key = fields.Char(string=&#39;APIv3密钥&#39;, required=True) cert_path = fields.Char(string=&#39;证书路径&#39;, help=&#39;例如: /etc/odoo/certs/apiclient_cert.pem&#39;) ``` 2. **支付请求处理逻辑** ```python # controllers/main.py from odoo import http from wechatpayv3 import WeChatPay class WeChatPayController(http.Controller): @http.route(&#39;/wechatpay/notify&#39;, type=&#39;json&#39;, auth=&#39;public&#39;) def payment_notify(self, **post): # 验证签名并处理支付结果 wxpay = WeChatPay(env[&#39;payment.provider&#39;].get_wechat_config()) result = wxpay.callback_parser(post) if result[&#39;code&#39;] == &#39;SUCCESS&#39;: self._process_payment(result[&#39;out_trade_no&#39;]) ``` #### 三、系统配置流程 1. **支付方式配置** - 进入`会计 > 配置 > 支付提供商` - 新建提供商选择**微信支付** - 填写商户号、API密钥等参数[^3] 2. **商城模块对接** - 在商城订单确认页调用支付方法: ```xml <!-- views/templates.xml --> <template id="payment_wechatpay" inherit_id="website_sale.payment"> <xpath expr="//div[@id=&#39;payment_method&#39;]" position="inside"> <t t-if="provider.code == &#39;wechatpay&#39;"> <button class="btn-primary" t-attf-data-wechatpay="{{ provider.get_jsapi_params(order) }}"/> </t> </xpath> </template> ``` #### 四、高级配置建议 1. **支付消息通知** - 配置企业微信消息推送(参考引用[2]): ```python # 支付成功后发送通知 def _send_wechat_message(self, order): enterprise_wechat_api.post_message( user_id=order.user_id.enterprise_wechat_id, content=f"订单 {order.name} 支付成功" ) ``` 2. **安全增强** - 使用Nginx配置SSL加密通信 - 启用Odoo的`auth_crypt`模块加密敏感字段
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值