这是一个支付的示例 仅供参考 ,传参和返回要根据情况修正,支付的其他接口只需改url和传参即可
官方文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml
相较于的之前微信支付API,主要区别是:
遵循统一的Restful的设计风格
使用JSON作为数据交互的格式,不再使用XML
使用基于非对称密钥的SHA256-RSA的数字签名算法,不再使用MD5或HMAC-SHA256
不再要求HTTPS客户端证书
使用AES-256-GCM,对回调中的关键信息进行加密保护
微信官方httpClient 自动处理签名和验签(使用WechatPayHttpClientBuilder需要调用withWechatpay设置微信支付平台证书,而平台证书又只能通过调用获取平台证书接口下载。为了解开"死循环",可以跳过签名的验证)
官方客服解答: 微信支付v3版本的密钥和v2的密钥独立,更新v3的密钥不会影响到已对接的v2的支付通道,支付证书有且只有一个
<!-- 微信-->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.2</version>
</dependency>
<!-- OKHttp3依赖 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.8.1</version>
</dependency>
package com.huayun.pay.service.thrid;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import okhttp3.HttpUrl;
import java.security.Signature;
import java.util.Base64;
import java.util.UUID;
/**
* 微信小程序支付
* APIV3接口
*/
@Service("WxAppLetPayService")
public class WxAppLetPayV3Service {
// appid。
@Value("#{config['hl.appid']}")
private String appid;
// merchantId商户号。
@Value("#{config['hl.merchantId']}")
private String merchantId;
//merchantSerialNumber商户证书的证书序列号,请参考什么是证书序列号和如何查看证书序列号。
@Value("#{config['hl.merchantSerialNumber']}")
private String merchantSerialNumber;
//merchantPrivateKey字符串格式的商户私钥,也就是通过证书工具得到的apiclient_key.pem文件中的内容。
@Value("#{config['hl.merchantPrivateKey']}")
private PrivateKey merchantPrivateKey;
//wechatpayCertificates微信支付平台证书的实例列表,用于应答签名的验证。你也可以使用后面章节提到的“自动更新证书功能”。
@Value("#{config['hl.wechatpayCertificates']}")
private List<X509Certificate> wechatpayCertificates;
@Value("#{config['hl.wxurl.pay']}")
private String pay;
@Value("#{config['hl.wxurl.notifyurl']}")
private String notifyurl;
//小程序支付统一下单
public void CreateOrder(Map<String,Object> map) throws Exception{
//请求URL
HttpPost httpPost = new HttpPost(pay);
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type","application/json; charset=utf-8");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode rootNode = objectMapper.createObjectNode();
rootNode.put("mchid",merchantId)
.put("appid", appid)
.put("description", "Image形象店-深圳腾大-QQ公仔")
.put("notify_url", notifyurl)
.put("out_trade_no", "1217752501201407033233368018");
rootNode.putObject("amount")
.put("total", 1);
rootNode.putObject("payer")
.put("openid", "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o");
objectMapper.writeValue(bos, rootNode);
//签名
// httpPost.addHeader("Authorization",getToken("POST", HttpUrl.parse(pay),rootNode.toString()));
httpPost.setEntity(new StringEntity(bos.toString("UTF-8")));
CloseableHttpClient httpClient=getHttpClient();
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
//业务处理在这里
System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
} else if (statusCode == 204) {
System.out.println("success");
} else {
System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} finally {
response.close();
}
}
/**
* merchantId商户号。
* merchantSerialNumber商户证书的证书序列号,请参考什么是证书序列号和如何查看证书序列号。
* merchantPrivateKey字符串格式的商户私钥,也就是通过证书工具得到的apiclient_key.pem文件中的内容。
* wechatpayCertificates微信支付平台证书的实例列表,用于应答签名的验证。你也可以使用后面章节提到的“自动更新证书功能”。
* @return
*/
//获取httpClient
public CloseableHttpClient getHttpClient() {
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
.withWechatpay(wechatpayCertificates);
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
CloseableHttpClient httpClient = builder.build();
return httpClient;
}
//获取httpClient(不验证返回签名)
public CloseableHttpClient getHttpClientNo() {
CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
.withValidator(response -> true) // NOTE: 设置一个空的应答签名验证器,**不要**用在业务请求
.build();
return httpClient;
}
//不需要传入微信支付证书,将会自动更新
// public CloseableHttpClient getHttpClientVerifier() {
// AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
// new WechatPay2Credentials(merchantId, new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)),
// apiV3Key.getBytes("utf-8"));
// WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
// .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
// .withValidator(new WechatPay2Validator(verifier));
// CloseableHttpClient httpClient = builder.build();
// return httpClient;
// }
//获取签名请求头
// Authorization:
// public String getToken(String method, HttpUrl url, String body) throws Exception{
// String nonceStr = UUID.randomUUID().toString().replace("-","");
// long timestamp = System.currentTimeMillis() / 1000;
// String message = buildMessage(method, url, timestamp, nonceStr, body);
// String signature = sign(message.getBytes("utf-8"));
// return "mchid=\"" + merchantId + "\","
// + "nonce_str=\"" + nonceStr + "\","
// + "timestamp=\"" + timestamp + "\","
// + "serial_no=\"" + merchantSerialNumber + "\","
// + "signature=\"" + signature + "\"";
// }
//
// public String sign(byte[] message) throws Exception{
// Signature sign = Signature.getInstance("SHA256withRSA");
// sign.initSign(merchantPrivateKey);
// sign.update(message);
//
// return Base64.getEncoder().encodeToString(sign.sign());
// }
//
// public String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
// String canonicalUrl = url.encodedPath();
// if (url.encodedQuery() != null) {
// canonicalUrl += "?" + url.encodedQuery();
// }
// return method + "\n"
// + canonicalUrl + "\n"
// + timestamp + "\n"
// + nonceStr + "\n"
// + body + "\n";
// }
}