java微信支付v3系列——2.微信支付基本配置

目录

java微信支付v3系列——1.微信支付准备工作
java微信支付v3系列——2.微信支付基本配置
java微信支付v3系列——3.订单创建准备操作
java微信支付v3系列——4.创建订单的封装及使用
java微信支付v3系列——5.微信支付成功回调
java微信支付v3系列——6.微信支付查询订单API
java微信支付v3系列——7.微信支付之申请退款
java微信支付v3系列——8.微信支付之退款成功回调
java微信支付v3系列——9.微信支付之商家转账API

正文

配置商户信息、证书、密钥等。将客户端对象构建到Bean中,方便后续使用。

我们可以使用官方提供的 SDK,帮助我们完成开发。实现了请求签名的生成和应答签名的验证。

<!--  微信支付 -->
<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-apache-httpclient</artifactId>
    <version>0.4.2</version>
</dependency>

首先是application.yml,本地运行时正数序列号也就是pem文件,放置到项目根目录下,不是resource下是项目的跟目录下,或者使用绝对地址。

weixin:
  appid: wx*************eec # appid
  mch-serial-no: 5BB08B7*******7772F2*****8386A0 # 证书序列号
  private-key-path: D:\code\javaCode\pem\apiclient_key.pem # 证书路径
  mch-id: 16*****284 # 商户号
  key: G6lFcTDd***********4o6uvHbr4 # api秘钥
  domain: https://api.mch.weixin.qq.com # 微信服务器地址
  notify-domain: https://xk857.mynatapp.cc # 回调,自己的回调地址

部署到centos后,要使用绝对地址了,可以参考:

weixin:
  private-key-path: /usr/local/xxlm_apiclient_key.pem  # 证书序列号,其他的不变只是pem文件位置改变

创建配置文件

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;

@Configuration
@PropertySource("classpath:application.yml") //读取配置文件
@ConfigurationProperties(prefix = "weixin") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
public class WxPayConfig {

    // 商户号
    private String mchId;

    // 商户API证书序列号
    private String mchSerialNo;

    // 商户私钥文件
    private String privateKeyPath;

    // APIv3密钥
    private String key;

    // APPID
    private String appid;

    // 微信服务器地址
    private String domain;

    // 接收结果通知地址
    private String notifyDomain;

    /**
     * 获取商户的私钥文件
     *
     * @param filename 证书地址
     * @return 私钥文件
     */
    public PrivateKey getPrivateKey(String filename) {
        try {
            return PemUtil.loadPrivateKey(new FileInputStream(filename));
        } catch (FileNotFoundException e) {
            throw new DefaultException("私钥文件不存在");
        }
    }


    /**
     * 获取签名验证器
     */
    @Bean
    public Verifier getVerifier() {
        // 获取商户私钥
        final PrivateKey privateKey = getPrivateKey(privateKeyPath);

        // 私钥签名对象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);

        // 身份认证对象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);

        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();

        try {
            // 向证书管理器增加需要自动更新平台证书的商户信息
            certificatesManager.putMerchant(mchId, wechatPay2Credentials, key.getBytes(StandardCharsets.UTF_8));
        } catch (IOException | GeneralSecurityException | HttpCodeException e) {
            e.printStackTrace();
        }

        try {
            return certificatesManager.getVerifier(mchId);
        } catch (NotFoundException e) {
            e.printStackTrace();
            throw new DefaultException("获取签名验证器失败");
        }
    }

    /**
     * 获取微信支付的远程请求对象
     *
     * @return Http请求对象
     */
    @Bean
    public CloseableHttpClient getWxPayClient() {

        // 获取签名验证器
        Verifier verifier = getVerifier();

        // 获取商户私钥
        final PrivateKey privateKey = getPrivateKey(privateKeyPath);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, privateKey)
                .withValidator(new WechatPay2Validator(verifier));

        return builder.build();
    }
}
### 使用微信支付公钥进行验签的方法 在处理来自微信支付平台的消息时,为了确保消息的真实性和完整性,需要使用微信支付平台提供的公钥来验证签名。具体过程如下: 当接收到微信支付平台发送的数据包时,其中包含了由微信支付平台私钥生成的签名字符串。接收方(即商户端)需利用事先获取到的微信支付平台证书中的公钥对该签名进行校验。 #### C# 中实现验签逻辑 对于采用C#.NET框架的应用程序而言,在完成必要的环境配置之后,可以按照以下方式编写用于执行验签操作的函数[^2]: ```csharp using System; using System.Security.Cryptography.X509Certificates; public class WeChatPayValidator { private readonly string _platformPublicKey; // 微信支付平台公钥 public bool VerifySignature(string message, string signature){ var rsa = new RSACryptoServiceProvider(); try{ var cert = new X509Certificate2(Convert.FromBase64String(_platformPublicKey)); rsa.ImportParameters(cert.GetRSAPublicKey().ExportParameters(false)); byte[] dataBytes = Encoding.UTF8.GetBytes(message); byte[] signBytes = Convert.FromBase64String(signature); SHA256 sha256 = SHA256.Create(); byte[] hashData = sha256.ComputeHash(dataBytes); return rsa.VerifyHash(hashData, signBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } finally{ rsa.Clear(); } } } ``` 此代码片段展示了如何加载微信支付平台公钥并创建`RSA`对象实例;接着计算待验证数据的实际哈希值并与传入参数中的已知签名做对比,最终返回两者是否匹配的结果。 #### Java 中实现验签逻辑 而在基于Java语言开发的服务端应用里,则可以通过引入官方支持库或者第三方工具类来进行相同的操作。这里给出一个简单的例子说明如何调用微信支付API V3所提供的方法完成验签工作[^3]: ```java import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier; import java.security.PublicKey; // 假设已经获得了WechatPayHttpClientBuilder builder 和 AutoUpdateCertificatesVerifier verifier 的实例化对象 builder.verifier(verifier); // 获取当前使用的公钥 PublicKey publicKey = ((AutoUpdateCertificatesVerifier)verifier).getPublicKeys().values().iterator().next(); // 进行验签流程... boolean isValid = Signature.getInstance("SHA256withRSA").verify(/*...*/); ``` 上述两段代码分别演示了不同编程环境中怎样运用各自特性去达成同样的目标——通过给定的信息以及微信支付平台公开发布的公钥来确认所收到来自该平台的通知或响应的有效性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CV大魔王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值