Java实现微信扫码支付V3(NATIVE方式)[全网最简单]
前期了解准备
微信商户账号
地址为https://pay.weixin.qq.com 用来开通微信支付能力,没有商户号是无法使用微信支付的。而且后续申请的公众号 appid 和移动应用、小程序的 appid 都要同微信商户帐号进行绑定。
微信开放平台账号
地址为https://open.weixin.qq.com 用来开发第三方平台、移动应用、公众平台、网站应用的开发。后续申请的微信公众号服务号、移动应用 appid 需要绑定到开放平台中。
微信公众平台服务号
通过https://mp.weixin.qq.com申请, 切记是服务号,不是订阅号,也不是个人号!服务号才是企业开发用的。申请认证完毕后需要同微信商户帐号和微信开放平台帐号进行绑定。
下面是为了获取开发中需要的参数:标识商户身份的信息、商户的证书和私钥、微信支付的证书、微信支付API的URL
-
1.获取商户号
微信商户平台:https://pay.weixin.qq.com/ 步骤:申请成为商户 => 提交资料 => 签署协议 => 获取商户号
-
2.获取AppID
微信公众平台:https://mp.weixin.qq.com/ 步骤:注册服务号 => 服务号认证 => 获取APPID => 绑定商户号
-
3.申请商户证书
步骤:登录商户平台 => 选择 账户中心 => 安全中心 => API安全 => 申请API证书 包括商户证书和商户私钥
-
4.获取微信的证书
可以预先下载,也可以通过编程的方式获取。
-
5.获取APIv3秘钥(在微信支付回调通知和商户获取平台证书使用APIv3密钥)
步骤:登录商户平台 => 选择 账户中心 => 安全中心 => API安全 => 设置APIv3密钥
1.引入依赖
1 2 3 4 5 6 | <!--wechatpay-sdk--> <dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-apache-httpclient</artifactId> <version> 0.4 . 5 </version> </dependency> |
2.添加yml
pay:
wechat:
appId: xxxxx
appSecret: xxxx
mchId: xxx
#商户私钥路径
keyPath: Dcerts/apiclient_key.pem
#三个证书路径
certPath: certs/apiclient_cert.pem
certP12Path: certs/apiclient_cert.p12
platformCertPath: certs/platformCert.pem
#apiv2秘钥
apiKey: xx
#apiv3秘钥
apiKey3: xxx
#可外网访问域名
domain: http://energy.free.idcfengye.com/
#商户证书序列号
serialnumber: xxxx
3.添加配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | package com.legendenergy.config; 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.util.PemUtil; import org.apache.http.impl.client.CloseableHttpClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import java.io.*; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; @Configuration public class WechatpayConfig { @Value ( "${pay.wechat.mchId}" ) private String merchantId; @Value ( "${pay.wechat.apiKey3}" ) private String apiV3Key; @Value ( "${pay.wechat.serialnumber}" ) private String merchantSerialNumber; @Value ( "${pay.wechat.keyPath}" ) private String privateKey; /** * 给容器中加入WechatPay的HttpClient,虽然它是WechatPay的, * 但可以用它给任何外部发请求,因为它只对发给WechatPay的请求做处理而不对发给别的的请求做处理. * * @return */ @Bean public CloseableHttpClient closeableHttpClient() throws IOException { //获取商户私钥方法一 //String key = FileUtil.readUtf8String(privateKey); //PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(key); // 获取商户私钥 下面三行代码通过流获取私钥可以避免打jar包到服务器后找不到私钥文件 Resource[] resources = new PathMatchingResourcePatternResolver().getResources(privateKey); InputStream inputStream = resources[ 0 ].getInputStream(); PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(inputStream); //微信证书校验器 Verifier verifier = null ; try { //获取证书管理器实例 CertificatesManager certificatesManager = CertificatesManager.getInstance(); //向证书管理器增加需要自动更新平台证书的商户信息(默认时间间隔:24小时) certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId, new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8)); //从证书管理器中获取verifier verifier = certificatesManager.getVerifier(merchantId); } catch (Exception e) { new RuntimeException( "微信证书校验器配置失败" ); } WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey) .withValidator( new WechatPay2Validator(verifier)); CloseableHttpClient httpClient = builder.build(); return httpClient; } /** * 和上面相比只是不需要验证签名了 * @return */ // @Bean // public CloseableHttpClient httpClientWithNoSign(){ // //私钥 // PrivateKey merchantPrivateKey=PemUtil.loadPrivateKey(privateKey); // //微信证书校验器 // Verifier verifier=null; // try{ // //获取证书管理器实例 // CertificatesManager certificatesManager=CertificatesManager.getInstance(); // //向证书管理器增加需要自动更新平台证书的商户信息(默认时间间隔:24小时) // certificatesManager.putMerchant(merchantId,new WechatPay2Credentials(merchantId,new PrivateKeySigner(merchantSerialNumber,merchantPrivateKey)),apiV3Key.getBytes(StandardCharsets.UTF_8)); // //从证书管理器中获取verifier // verifier=certificatesManager.getVerifier(merchantId); // } // catch(Exception e){ // new RuntimeException("微信证书校验器配置失败"); // } // WechatPayHttpClientBuilder builder=WechatPayHttpClientBuilder.create() // .withMerchant(merchantId,merchantSerialNumber,merchantPrivateKey) // .withValidator(response->true); // CloseableHttpClient httpClient=builder.build(); // return httpClient; // } } |
4.添加API常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class WechatPayApi { /** * 微信支付主机地址 */ public static final String HOST = "https://api.mch.weixin.qq.com" ; /** * Native下单 */ public static final String NATIVE_ORDER = HOST+ "/v3/pay/transactions/native" ; /** * Native订单状态查询, 根据商户订单号查询 */ public static final String NATIVE_QUERY = HOST+ "/v3/pay/transactions/out-trade-no/%s?mchid=%s" ; /** * 关闭订单接口 */ public static final String NATIVE_CLOSE_ORDER = HOST+ "/v3/pay/transactions/out-trade-no/%s/close" ; /** * 申请退款接口 */ public static final String NATIVE_REFUND_ORDER = HOST+ "/v3/refund/domestic/refunds" ; /** * 退款状态查询接口 */ public static final String NATIVE_REFUND_QUERY = HOST+ "/v3/refund/domestic/refunds/%s" ; } |
5.测试查询订单接口
1 2 3 4 5 6 7 8 | String url = String.format(WechatPayApi.NATIVE_QUERY, tradeNo, merchantId);<br> HttpGet httpGet = new HttpGet(url); httpGet.setHeader( "Accept" , "application/json" ); CloseableHttpResponse response = wxPayClient.execute(httpGet); String bodyString = EntityUtils.toString(response.getEntity()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 200 ) { //模拟微信支付回调成功后的操作 } |
https://blog.csdn.net/u012488804/article/details/113378063 微信回调密文解析但是明文不解析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程