Compare commits
2 Commits
0c2fc0028e
...
25c8333466
Author | SHA1 | Date |
---|---|---|
|
25c8333466 | 3 years ago |
|
46c9e8c9a3 | 3 years ago |
5 changed files with 182 additions and 9 deletions
@ -0,0 +1,73 @@ |
|||||
|
package com.ccsens.wechatutil.payutil.wxjsapi; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.ccsens.wechatutil.bean.vo.WxPayOrders; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
import org.apache.http.client.methods.HttpPost; |
||||
|
import org.apache.http.entity.StringEntity; |
||||
|
import org.apache.http.util.EntityUtils; |
||||
|
|
||||
|
/** |
||||
|
* @author 逗 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
public class JsApiPay { |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 生成订单 返回预支付交易会话标识 |
||||
|
* @return 返回二维码访问路径(不包含前缀) |
||||
|
*/ |
||||
|
public static JSONObject transactions(WxPayOrders wxPayOrders,String serialNo,String keyFilePath,String v3Key) throws Exception { |
||||
|
HttpPost httpPost = new HttpPost(JsApiUtils.URL_TRANSACTIONS); |
||||
|
httpPost.addHeader("Accept", "application/json"); |
||||
|
httpPost.addHeader("Content-type", "application/json; charset=utf-8"); |
||||
|
|
||||
|
JSONObject params = new JSONObject(); |
||||
|
JSONObject amount = new JSONObject(); |
||||
|
JSONObject payer = new JSONObject(); |
||||
|
payer.put("openid", wxPayOrders.getPayer().getOpenid()); |
||||
|
|
||||
|
amount.put("total", wxPayOrders.getAmount().getTotal()); |
||||
|
amount.put("currency", "CNY"); |
||||
|
|
||||
|
params.put("appid", wxPayOrders.getAppid()); |
||||
|
params.put("mchid", wxPayOrders.getMchid()); |
||||
|
params.put("out_trade_no", wxPayOrders.getOut_trade_no()); |
||||
|
params.put("description", wxPayOrders.getDescription()); |
||||
|
params.put("notify_url", wxPayOrders.getNotify_url()); |
||||
|
params.put("amount", amount); |
||||
|
params.put("payer", payer); |
||||
|
|
||||
|
httpPost.setEntity(new StringEntity(params.toJSONString(), "UTF-8")); |
||||
|
CloseableHttpResponse response = (CloseableHttpResponse) JsApiUtils.getWechatPayHttpClient(wxPayOrders.getMchid(),serialNo,keyFilePath, v3Key).execute(httpPost); |
||||
|
String bodyAsString = EntityUtils.toString(response.getEntity()); |
||||
|
JSONObject respJson = JSONObject.parseObject(bodyAsString); |
||||
|
|
||||
|
Object prepayId = respJson.get("prepay_id"); |
||||
|
Object code = respJson.get("code"); |
||||
|
|
||||
|
if (code != null) { |
||||
|
throw new Exception(respJson.get("message").toString()); |
||||
|
} |
||||
|
JSONObject result = new JSONObject(); |
||||
|
//根据返回的prepay_id生成发起支付需要的参数签名返回前端
|
||||
|
|
||||
|
result.put("appId", wxPayOrders.getAppid()); |
||||
|
result.put("timeStamp", System.currentTimeMillis() / 1000); |
||||
|
result.put("nonceStr", JsApiUtils.createNonceStr()); |
||||
|
result.put("package", "prepay_id=" + prepayId); |
||||
|
result.put("signType", "RSA"); |
||||
|
|
||||
|
String message = wxPayOrders.getAppid() + "\n" |
||||
|
+ result.get("timeStamp") + "\n" |
||||
|
+ result.get("nonceStr") + "\n" |
||||
|
+ result.get("package") + "\n"; |
||||
|
String sign = JsApiUtils.wxPayReqSign(keyFilePath,message.getBytes("utf-8")); |
||||
|
result.put("paySign", sign); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
package com.ccsens.wechatutil.payutil.wxjsapi; |
||||
|
|
||||
|
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; |
||||
|
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 com.wechat.pay.contrib.apache.httpclient.util.PemUtil; |
||||
|
import org.apache.http.client.HttpClient; |
||||
|
|
||||
|
import java.io.*; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.security.*; |
||||
|
import java.util.Base64; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @author 逗 |
||||
|
*/ |
||||
|
public class JsApiUtils { |
||||
|
|
||||
|
/** |
||||
|
* 请求地址 |
||||
|
*/ |
||||
|
public static final String URL_TRANSACTIONS = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"; |
||||
|
|
||||
|
/** |
||||
|
* 根据微信平台证书获取httpclient |
||||
|
*/ |
||||
|
public static HttpClient getWechatPayHttpClient(String mchId,String serialNo,String keyFilePath,String v3Key) throws FileNotFoundException { |
||||
|
HttpClient httpClient; |
||||
|
//构造WechatPayHttpClientBuilder
|
||||
|
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() |
||||
|
.withMerchant(mchId, serialNo, getPrivateKey(keyFilePath)) |
||||
|
.withValidator(new WechatPay2Validator(getVerifier(mchId,serialNo,keyFilePath,v3Key))); |
||||
|
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
|
||||
|
httpClient = builder.build(); |
||||
|
return httpClient; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据商户证书,获取私钥 |
||||
|
*/ |
||||
|
public static PrivateKey getPrivateKey(String keyFilePath) throws FileNotFoundException { |
||||
|
return PemUtil.loadPrivateKey( |
||||
|
new FileInputStream(keyFilePath)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 自动获取微信平台证书 |
||||
|
*/ |
||||
|
public static AutoUpdateCertificatesVerifier getVerifier(String mchId,String serialNo,String keyFilePath,String v3Key) throws FileNotFoundException { |
||||
|
//不需要传入微信支付证书了
|
||||
|
return new AutoUpdateCertificatesVerifier( |
||||
|
new WechatPay2Credentials(mchId, new PrivateKeySigner(serialNo, getPrivateKey(keyFilePath))), |
||||
|
v3Key.getBytes(StandardCharsets.UTF_8)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成随机字符串 |
||||
|
*/ |
||||
|
public static String createNonceStr() { |
||||
|
return UUID.randomUUID().toString().replace("-", ""); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 依据商户证书私钥进行签名 |
||||
|
*/ |
||||
|
public static String wxPayReqSign(String keyFilePath,byte[] message) throws Exception { |
||||
|
Signature sign = Signature.getInstance("SHA256withRSA"); |
||||
|
sign.initSign(getPrivateKey(keyFilePath)); |
||||
|
sign.update(message); |
||||
|
return Base64.getEncoder().encodeToString(sign.sign()); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue