Commit 7ad697ba authored by licc's avatar licc

微信支付接口

parent c4e4a6b2
......@@ -17,5 +17,5 @@ public class PayPageDto {
/**
* 支付金额 :金额不能为0
*/
private String price;
private Integer total;
}
package cn.wisenergy.service.app;
import cn.wisenergy.common.utils.R;
import cn.wisenergy.model.dto.PayPageDto;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
/**
* @author 86187
*/
public interface PayService {
/**
* 微行支付接口
* @param payPageDto 入参
* @return
*/
R<String> wxPay(PayPageDto payPageDto) throws UnsupportedEncodingException, NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException;
}
package cn.wisenergy.service.app.impl;
import cn.wisenergy.common.utils.R;
import cn.wisenergy.model.dto.PayPageDto;
import cn.wisenergy.service.app.PayService;
import cn.wisenergy.service.util.SignDemo;
import cn.wisenergy.service.util.SignUtil;
import cn.wisenergy.service.wxpay.WxCommon;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* @author 86187
*/
@Service
@Slf4j
public class PayServiceImpl implements PayService {
@Autowired
private RestTemplate restTemplate;
@Override
public R<String> wxPay(PayPageDto payPageDto) throws UnsupportedEncodingException, NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException {
if (null == payPageDto || null == payPageDto.getTotal()) {
return R.error("入参不能为空!");
}
final HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = UUID.randomUUID().toString().replace("-", "");
String url = "v3/pay/transactions/native";
String method = "POST";
String tradeNo = "21" + System.currentTimeMillis();
HttpUrl httpurl = HttpUrl.parse(WxCommon.WX_PAY_URL);
//构造签名参数
JSONObject jsonObject = new JSONObject();
jsonObject.put("appid", WxCommon.APP_ID);
jsonObject.put("mchid", WxCommon.MCHID);
jsonObject.put("timestamp", timestamp);
jsonObject.put("nonce_str", nonceStr);
jsonObject.put("url", url);
jsonObject.put("method", method);
jsonObject.put("description", "充值");
jsonObject.put("out_trade_no", tradeNo);
jsonObject.put("notify_url", WxCommon.NOTIFY_URL);
jsonObject.put("amount", payPageDto);
String sign = SignDemo.getToken(method, httpurl, jsonObject.toJSONString(),nonceStr,timestamp);
headers.add("Wechatpay-Signature", sign);
HttpEntity<JSONObject> formEntity = new HttpEntity<>(jsonObject, headers);
ResponseEntity<JSONObject> responseEntity = this.restTemplate.postForEntity(WxCommon.WX_PAY_URL, formEntity, JSONObject.class);
return R.ok(Objects.requireNonNull(responseEntity.getBody()).toJSONString());
}
}
package cn.wisenergy.service.util;
import cn.wisenergy.model.dto.PayPageDto;
import cn.wisenergy.service.wxpay.WxCommon;
import com.alibaba.fastjson.JSONObject;
import okhttp3.HttpUrl;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.UUID;
/**
* @author 86187
*/
public class SignDemo {
public static String getToken(String method, HttpUrl url, String body,String nonceStr,long timestamp) throws UnsupportedEncodingException, SignatureException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
String message = buildMessage(method, url, timestamp, nonceStr, body);
String signature = sign(message.getBytes("utf-8"));
return "mchid=\"" + WxCommon.MCHID + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "timestamp=\"" + timestamp + "\","
+ "serial_no=\"" + WxCommon.SERIAL_NO + "\","
+ "signature=\"" + signature + "\"";
}
public static String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, InvalidKeySpecException {
Signature sign = Signature.getInstance("SHA256withRSA");
KeyFactory factory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = factory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(WxCommon.SECRET_KEY)));
sign.initSign(privateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
public static 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";
}
// public static void main(String[] args) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, UnsupportedEncodingException, InvalidKeySpecException {
// String method = "POST";
// HttpUrl httpurl = HttpUrl.parse("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
// long timestamp = System.currentTimeMillis() / 1000;
// String nonceStr = UUID.randomUUID().toString().replace("-", "");
// String url = "v3/pay/transactions/native";
// String tradeNo = "21" + System.currentTimeMillis();
// PayPageDto payPageDto = new PayPageDto();
// payPageDto.setTotal(100);
//
// //构造签名body
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("appid", WxCommon.APP_ID);
// jsonObject.put("mchid", WxCommon.MCHID);
// jsonObject.put("timestamp", timestamp);
// jsonObject.put("nonce_str", nonceStr);
// jsonObject.put("url", url);
// jsonObject.put("method", method);
// jsonObject.put("description", "充值");
// jsonObject.put("out_trade_no", tradeNo);
// jsonObject.put("notify_url", WxCommon.NOTIFY_URL);
// jsonObject.put("amount", payPageDto);
// String sign = getToken(method, httpurl, jsonObject.toJSONString());
// System.out.println("签名:" + sign);
// }
}
package cn.wisenergy.service.util;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Map;
/**
* @author 86187
*/
public class SignUtil {
public static String genSignature(String secretKey, Map<String, Object> params) throws UnsupportedEncodingException {
//secretKey为商户平台设置的密钥key
if (secretKey == null || params == null || params.size() == 0) {
return "";
}
// 1. 参数名按照ASCII码表升序排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 2. 按照排序拼接参数名与参数值
StringBuffer paramBuffer = new StringBuffer();
for (String key : keys) {
paramBuffer.append("&" + key).append(params.get(key) == null ? "" : "=" + params.get(key));
}
// 3. 将secretKey拼接到最后
paramBuffer = paramBuffer.append("&key=" + secretKey);
String pa = paramBuffer.substring(1);
// 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。
return DigestUtils.md5Hex(pa.getBytes("UTF-8")).toUpperCase();
}
}
package cn.wisenergy.service.wxpay;
/**
*@ Description: 微信支付公共参数
*@ Author : 86187
*@ Date : 2021/2/5 15:04
* @author 86187
*/
public class WxCommon {
public static final String APP_ID = "wx7d8f4502a2bfa865";
public static final String MCHID = "1606042985";
public static final String NOTIFY_URL = "http://www.baodu.com";
public static final String WX_PAY_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";
public static final String SECRET_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDhGq+iGQueP8EU" +
"3qj0T0Otnha0XboVcgmeDkgbe08H54WiF9d3R4aLAo+wAkAj/R7nRw2yWeaaMEgb" +
"ZvUz03IioVKwLhaMVEtwE5sNFCMGDDh9jGjm66j+BYgVk02P5hUAcYLcJYeo9iHA" +
"cFQ1YA4r64OLD0/JWqGjpHmKJ9F3YhZjBO8ETm6grnIJyqt9ABCPBQF7fRS/ZcbC" +
"J8PUoEZA1eGi60FEgzeJ2stjzXZ6629INnRQanNuPegcH26oSQmph+z33bLUhXDb" +
"lt6exClPKucU5FZoh69dMsD1RLqNeBTUG8JCvvEWnBH3RaHKRsv/nezQHS+5euw3" +
"AJnTNPl5AgMBAAECggEAR9PsFx1Gx8gwJCioYMyqG8xGEmeV6SHqT7Te7WX7YdpO" +
"mdphtn3sQI8gqlkNfm5WXhYeGLr3Clw9pgDEXTUrRkGT0QPjzgNXzvtyjknOoy9j" +
"FyymjIjF88hwE/Jc3X3dVbbiurx+/TsMqgst05pC62DLKKRKIUX6Le1dmuf5vs3E" +
"gjDZR+Z86H8jNm0Qg5OXwbUs7uIaMKun6QUGqk0YfdeIQdMXerKp48HLSI+j+bMS" +
"pkE5wt4MSk3G90qHzxLgO7N2FuUFJunl8t0jrDIg7eG8qDPT2rO7tFP8zvikJbGz" +
"zNfI9l6CIXnPXFJtoAFRt8XBG4sNF5ncSdJbDTpXAQKBgQDySdXYOkMCHxFSKAG/" +
"pCyFwCMozfvKL2HShS/lVc7wwVG/yvPeqpKFvq7+xob6R20rbJEzgSBSlOwpol9s" +
"f+fuduUPSzLK/Dz+yL6o3CrX18g2SSgZSMbqN1KDmoF7D3GO81AmdBs/FQkg8wAa" +
"oWSI8K5QUuw0nfMMWZZ4bS7VLQKBgQDt1+TpC3euInhakwrYDnGqRy7W3YEuILDN" +
"Adp+IujN0sKKIH6dx9hZxSbqEE/t4uev3Pga9P8e+91h9rIc38b3Xw2Xn2iN/bSa" +
"dk7ThAu9leiJG9bs1gN7mT8Gq8kV/RKM8npAjht2dlx61T3Eb80WSf8sC3BWJ2TE" +
"M88jjuT8/QKBgCOPqL5i1sDx9GXdj1wkaZB8Ae0URpeHWtE+UShU7tmxViFTVXXi" +
"DT1qHl8wnlEPuLs95RXtJuRYDU2TEnRnVZBPjREwlVTrrrwqlKlOH0+s0Sr+k88a" +
"Om/YDNlaDRUV0DIODj6GnhUlLkDSyboe5BWhVcReV2Llp+2xHH+ybsRFAoGBAK6C" +
"2Cy+A0Q7en9KoIxCnNfJfu6ce+oyhkcFcyFVz+clGyRqDz0Jow7K/3CCI4NyF3kL" +
"8uckmARN3PPCJJHXB4/9qGV1yytT2a3z3IaJvmuOkJ35VUtVBB0uJfZpGRQPKgtM" +
"5rJzEmdrFRPzXmzBc4NFK/tPMU+le+QR94wpjo6pAoGBAOmilsvFp4UcuAeOt50q" +
"4FC2ApgHw4f95nCi/rtUbuC9AwiFD8nBGZTLFO1lxoms52uJ9RWYLBpY4JmWo1VG" +
"IaU0+nKTljLCQZNHqA87bkG4lQIKsZjNJ47PW1iUdNtXJ58aw/qnj2ldIGIcZQQY" +
"52pD2/10mSJy5oxiqdMccmbs";
/**
* 证书序列号
*/
public static final String SERIAL_NO = "5A886697B1EA67984766E953683E04D2DC96482C";
/**
* 认证类型
*/
public static final String SCHEMA = "WECHATPAY2-SHA256-RSA2048";
}
......@@ -3,6 +3,7 @@ package cn.wisenergy.web.admin.controller.app;
import cn.wisenergy.common.utils.R;
import cn.wisenergy.model.dto.PayPageDto;
import cn.wisenergy.model.dto.PayQueryDto;
import cn.wisenergy.service.app.PayService;
import cn.wisenergy.service.common.Common;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
......@@ -15,6 +16,7 @@ import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -23,7 +25,11 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
/**
* @author 86187
......@@ -38,12 +44,15 @@ import java.util.UUID;
public class PayController {
private static final String CHARSET = "UTF-8";
@Autowired
private PayService payService;
@ApiOperation(value = "PC支付宝-支付接口", notes = "PC支付宝-支付接口", httpMethod = "POST")
@ApiImplicitParam(name = "payPageDto", value = "参数", dataType = "PayPageDto")
@PostMapping("/page")
public R<String> doPost(@RequestBody PayPageDto payPageDto, HttpServletRequest request, HttpServletResponse httpResponse) throws IOException, AlipayApiException {
if (null == payPageDto || StringUtils.isBlank(payPageDto.getPrice())) {
if (null == payPageDto || null == payPageDto.getTotal()) {
return R.error("人参不能为空!");
}
......@@ -58,7 +67,7 @@ public class PayController {
alipayRequest.setBizContent("{" +
"\"out_trade_no\":\"" + tradeNo + "\"," +
"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
"\"total_amount\":" + payPageDto.getPrice() + "," +
"\"total_amount\":" + payPageDto.getTotal() + "," +
"\"subject\":\"充值\"," +
"\"body\":\"充值\"," +
"\"time_expire\":\"2021-01-30 10:05:01\"," +
......@@ -178,4 +187,12 @@ public class PayController {
System.out.println(response.getBody());
return R.ok(response.getBody());
}
@ApiOperation(value = "微行支付-统一下单", notes = "微行支付-统一下单", httpMethod = "POST")
@ApiImplicitParam(name = "payPageDto", value = "支付入参", dataType = "PayPageDto")
@PostMapping("/wxPay")
public R<String> wxPay(@RequestBody PayPageDto payPageDto) throws AlipayApiException, UnsupportedEncodingException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
return payService.wxPay(payPageDto);
}
}
......@@ -62,8 +62,3 @@ camera:
appKey: 23756916
appSecret: TDrCbqQXe9XSt7SimYDO
path: /artemis
wxpay:
appId: # appid
mchId: # 商户号
mchKey: # 秘钥
notifyUrl: http://127.0.0.1:8080/wxPay/wxPayNotice #微信支付回调地址
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment