|
@@ -0,0 +1,251 @@
|
|
|
+package com.chelvc.cloud.vehicle.server.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.chelvc.cloud.vehicle.server.dao.OmsOrderMapper;
|
|
|
+import com.chelvc.cloud.vehicle.server.entity.OmsOrder;
|
|
|
+import com.chelvc.cloud.vehicle.server.service.PayService;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.BufferedInputStream;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.security.KeyStore;
|
|
|
+import java.security.PrivateKey;
|
|
|
+import java.security.PublicKey;
|
|
|
+import java.security.Signature;
|
|
|
+import java.security.cert.CertificateFactory;
|
|
|
+import java.security.cert.X509Certificate;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
|
|
+public class PayServiceImpl implements PayService {
|
|
|
+
|
|
|
+ private final OmsOrderMapper omsOrderMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void orderPay(Long orderId) {
|
|
|
+ LambdaQueryWrapper<OmsOrder> wrapper = Wrappers.lambdaQuery();
|
|
|
+ wrapper.eq(OmsOrder::getId, orderId);
|
|
|
+ wrapper.eq(OmsOrder::getStatus, 0);
|
|
|
+ OmsOrder omsOrder = omsOrderMapper.selectOne(wrapper);
|
|
|
+ if(omsOrder == null){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ sb.append("merchantAcctId=").append("1001292117101").append("&");
|
|
|
+ sb.append("version=").append("v2.0").append("&");
|
|
|
+ sb.append("language=").append("1").append("&");
|
|
|
+ sb.append("signType=").append("4").append("&");
|
|
|
+ sb.append("payType=").append("21").append("&");
|
|
|
+ sb.append("bankId=").append("QTYH").append("&");
|
|
|
+ sb.append("orderId=").append("KQ20220609155005").append("&");
|
|
|
+ sb.append("orderTime=").append("20220609155005").append("&");
|
|
|
+ sb.append("orderAmount=").append("1").append("&");
|
|
|
+ sb.append("bindCard=").append("6222027781").append("&");
|
|
|
+ sb.append("bindMobile=").append("1662653").append("&");
|
|
|
+ sb.append("dealId=").append("104964327").append("&");
|
|
|
+ sb.append("bankDealId=").append("9841654761026121342").append("&");
|
|
|
+ sb.append("dealTime=").append("20220609155546").append("&");
|
|
|
+ sb.append("payAmount=").append("1").append("&");
|
|
|
+ sb.append("fee=").append("0").append("&");
|
|
|
+ sb.append("payResult=").append("10");
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ sb.append("merchantAcctId=").append("1001292117101").append("&");
|
|
|
+ sb.append("version=").append("v2.0").append("&");
|
|
|
+ sb.append("language=").append("1").append("&");
|
|
|
+ sb.append("signType=").append("4").append("&");
|
|
|
+ sb.append("payType=").append("21").append("&");
|
|
|
+ sb.append("bankId=").append("QTYH").append("&");
|
|
|
+ sb.append("orderId=").append("KQ20220609155005").append("&");
|
|
|
+ sb.append("orderTime=").append("20220609155005").append("&");
|
|
|
+ sb.append("orderAmount=").append("1").append("&");
|
|
|
+ sb.append("bindCard=").append("6222027781").append("&");
|
|
|
+ sb.append("bindMobile=").append("1662653").append("&");
|
|
|
+ sb.append("dealId=").append("104964327").append("&");
|
|
|
+ sb.append("bankDealId=").append("9841654761026121342").append("&");
|
|
|
+ sb.append("dealTime=").append("20220609155546").append("&");
|
|
|
+ sb.append("payAmount=").append("1").append("&");
|
|
|
+ sb.append("fee=").append("0").append("&");
|
|
|
+ sb.append("payResult=").append("10");
|
|
|
+ String base64 = "";
|
|
|
+ String SignMsgVal="merchantAcctId=1001292117101&version=v2.0&language=1&signType=4&payType=21&bankId=QTYH&orderId=KQ20220609155005&orderTime=20220609155005&orderAmount=1&bindCard=6222027781&bindMobile=1662653&dealId=104964327&bankDealId=9841654761026121342&dealTime=20220609155546&payAmount=1&fee=0&payResult=10";
|
|
|
+
|
|
|
+ //人民币网关账号,该账号为11位人民币网关商户编号+01,该参数必填。
|
|
|
+ String merchantAcctId = "1001295168301";
|
|
|
+ //编码方式,1代表 UTF-8; 2 代表 GBK; 3代表 GB2312 默认为1,该参数必填。
|
|
|
+ String inputCharset = "1";
|
|
|
+ //接收支付结果的页面地址,该参数一般置为空即可。
|
|
|
+ String pageUrl = "";
|
|
|
+ //服务器接收支付结果的后台地址,该参数务必填写,不能为空。
|
|
|
+ String bgUrl = "http://www.99bill.com/";
|
|
|
+ //网关版本,固定值:mobile1.0,该参数必填。
|
|
|
+ String version = "mobile1.0";
|
|
|
+ //移动网关版本 phone代表手机版移动网关,pad代表平板移动网关,默认为phone
|
|
|
+ String mobileGateway="";
|
|
|
+ //语言种类,1代表中文显示,2代表英文显示。默认为1,该参数必填。
|
|
|
+ String language = "1";
|
|
|
+ //签名类型,该值为4,代表PKI加密方式,该参数必填。
|
|
|
+ String signType = "4";
|
|
|
+ //支付人姓名,可以为空。
|
|
|
+ String payerName= "";
|
|
|
+ //支付人联系类型,1 代表电子邮件方式;2 代表手机联系方式。可以为空。
|
|
|
+ String payerContactType = "";
|
|
|
+ //支付人联系方式,与payerContactType设置对应,payerContactType为1,则填写邮箱地址;payerContactType为2,则填写手机号码。可以为空。
|
|
|
+ String payerContact = "";
|
|
|
+ //指定付款人,可以为空
|
|
|
+ String payerIdType = "";
|
|
|
+ //付款人标识,可以为空
|
|
|
+ String payerId = "";
|
|
|
+ //付款人IP,可以为空
|
|
|
+ String payerIP = "";
|
|
|
+ //商家的终端ip,支持Ipv4和Ipv6
|
|
|
+ String terminalIp = "192.168.1.1";
|
|
|
+ //网络交易平台简称,英文或中文字符串,除微信支付宝支付外其他交易方式必传
|
|
|
+ String tdpformName = "";
|
|
|
+ //商户订单号,以下采用时间来定义订单号,商户可以根据自己订单号的定义规则来定义该值,不能为空。
|
|
|
+ String orderId = "KQ"+new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
|
|
|
+ //订单金额,金额以“分”为单位,商户测试以1分测试即可,切勿以大金额测试。该参数必填。
|
|
|
+ String orderAmount = "1";
|
|
|
+ //订单提交时间,格式:yyyyMMddHHmmss,如:20071117020101,不能为空。
|
|
|
+ String orderTime = new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
|
|
|
+ //String orderTime = "20220224145101";
|
|
|
+ //快钱时间戳,格式:yyyyMMddHHmmss,如:20071117020101, 可以为空
|
|
|
+ String orderTimestamp= "";//new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());;
|
|
|
+ //商品名称,可以为空。
|
|
|
+ String productName= "测试商品";
|
|
|
+ //商品数量,可以为空。
|
|
|
+ String productNum = "1";
|
|
|
+ //商品代码,可以为空。
|
|
|
+ String productId = "";
|
|
|
+ //商品描述,可以为空。
|
|
|
+ String productDesc = "";
|
|
|
+ //扩展字段1,商户可以传递自己需要的参数,支付完快钱会原值返回,可以为空。
|
|
|
+ String ext1 = "";
|
|
|
+ //扩展自段2,商户可以传递自己需要的参数,支付完快钱会原值返回,可以为空。
|
|
|
+ String ext2 = "";
|
|
|
+ //支付方式,一般为00,代表所有的支付方式。微信小程序26-3
|
|
|
+ String payType = "26-3";
|
|
|
+ //银行代码,如果payType为00,该值可以为空
|
|
|
+ String bankId = "";
|
|
|
+ //同一订单禁止重复提交标志,实物购物车填1,虚拟产品用0。1代表只能提交一次,0代表在支付不成功情况下可以再提交。可为空。
|
|
|
+ String redoFlag = "0";
|
|
|
+ //快钱合作伙伴的帐户号,即商户编号,可为空。
|
|
|
+ String pid = "";
|
|
|
+ //订单超时时间(秒),可为空。
|
|
|
+ String orderTimeOut = "";
|
|
|
+ //聚合支付参数
|
|
|
+ String aggregatePay="26-3:[appId=wx44377c7a02caaac9,openId=oxr7946y03Ui9LjsR4zGFi8OssbY,limitPay=0]";
|
|
|
+
|
|
|
+ //signMsg 签名字符串 不可空,生成加密签名串
|
|
|
+ String signMsgVal = "";
|
|
|
+ signMsgVal = appendParam(signMsgVal, "inputCharset", inputCharset);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "pageUrl", pageUrl);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "bgUrl", bgUrl);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "version", version);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "language", language);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "signType", signType);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "merchantAcctId",merchantAcctId);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payerName", payerName);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payerContactType",payerContactType);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payerContact", payerContact);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payerIdType", payerIdType);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payerId", payerId);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payerIP", payerIP);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "orderId", orderId);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "orderAmount", orderAmount);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "orderTime", orderTime);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "orderTimestamp", orderTimestamp);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "productName", productName);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "productNum", productNum);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "productId", productId);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "productDesc", productDesc);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "ext1", ext1);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "ext2", ext2);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "payType", payType);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "bankId", bankId);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "redoFlag", redoFlag);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "pid", pid);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "orderTimeOut", orderTimeOut);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "mobileGateway", mobileGateway);
|
|
|
+ signMsgVal = appendParam(signMsgVal, "aggregatePay", aggregatePay);
|
|
|
+
|
|
|
+ try {
|
|
|
+ System.out.println(signMsgVal);
|
|
|
+ KeyStore ks = KeyStore.getInstance("PKCS12");
|
|
|
+
|
|
|
+ //读取密钥仓库(相对路径)
|
|
|
+ String file = Objects.requireNonNull(PayServiceImpl.class.getClassLoader().getResource("payUtils/10012951683.pfx")).getPath().replaceAll("%20", " ");
|
|
|
+ System.out.println(file);
|
|
|
+
|
|
|
+ FileInputStream ksfis = new FileInputStream(file);
|
|
|
+ //InputStream inputStream = PayServiceImpl.class.getClassLoader().getResourceAsStream("payUtils/10012951683.pfx");
|
|
|
+ BufferedInputStream ksbufin = new BufferedInputStream(ksfis);
|
|
|
+ //证书密码
|
|
|
+ char[] keyPwd = "123456".toCharArray();
|
|
|
+ ks.load(ksbufin, keyPwd);
|
|
|
+
|
|
|
+ //证书别名 20190802.3300000002967055(10012155863)、20190801.3300000002925831(10012921171)
|
|
|
+ PrivateKey priK = (PrivateKey) ks.getKey("test-alias", keyPwd); //老别名:test-alias
|
|
|
+ //签名算法
|
|
|
+ Signature signature = Signature.getInstance("SHA256withRSA"); //SHA256withRSA,SHA1withRSA
|
|
|
+ signature.initSign(priK);
|
|
|
+ //signature.update(SignMsgVal.getBytes(StandardCharsets.UTF_8));
|
|
|
+ signature.update(signMsgVal.getBytes(StandardCharsets.UTF_8));
|
|
|
+ sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
|
|
|
+ base64 = encoder.encode(signature.sign());
|
|
|
+
|
|
|
+ } catch(FileNotFoundException e){
|
|
|
+ System.out.println("123");
|
|
|
+ }catch (Exception ex) {
|
|
|
+ ex.printStackTrace();
|
|
|
+ }
|
|
|
+ System.out.println("test = "+base64);
|
|
|
+ String signMsg="Yku7O/TyRnCErbGwvo/EQxgNLgR61YJ9WQrxpD0I6HxIumGVRxQo4eQ/hn5CS57xM2GnJ7qtkWM3J/g9CRcK22S7EJ4E1zK2HuqYiScaFLolHWNszGe7kOPk3PovTFl4nGYUSW8vMzZEZgRTMdHNSpmib57o6Mrjq0+6xA1gSBBRqpaL6SO4IBfB6yldWHpkJN0RJlKlkGGRJjMEpLJPn8lTGPcOfJuNxmMq+qjbvdLyoxn7v0vK8bAPFT45bCdvGG+0HwUCYxtPPhFReZMXP/yJYEZ/TODSMlPhGM1dZXXbnZ5Sc4KJSWNB9CKgyKWcycMbfTlsraWtpsCwOr8k0g==";
|
|
|
+ try {
|
|
|
+ //快钱公钥
|
|
|
+ //String file = Pkipair.class.getResource("99bill.RSA.cer").toURI().getPath();
|
|
|
+ String file = Objects.requireNonNull(PayServiceImpl.class.getClassLoader().getResource("payUtils/CFCA_sandbox.cer")).toURI().getPath();
|
|
|
+ //System.out.println(file);
|
|
|
+ FileInputStream inStream = new FileInputStream(file);
|
|
|
+
|
|
|
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
|
|
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
|
|
|
+
|
|
|
+ PublicKey pk = cert.getPublicKey();
|
|
|
+ //验签算法
|
|
|
+ Signature signature = Signature.getInstance("SHA256withRSA");//SHA256withRSA,SHA1withRSA
|
|
|
+ signature.initVerify(pk);
|
|
|
+ signature.update(signMsgVal.getBytes());
|
|
|
+
|
|
|
+ sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
|
|
|
+ //System.out.println(new String(decoder.decodeBuffer(msg)));
|
|
|
+ boolean flag = signature.verify(decoder.decodeBuffer(base64));
|
|
|
+ System.out.println(flag);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ //System.out.println("no");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String appendParam(String returns, String paramId, String paramValue) {
|
|
|
+ if (!Objects.equals(returns, "")) {
|
|
|
+ if (!Objects.equals(paramValue, "")) {
|
|
|
+ returns += "&" + paramId + "=" + paramValue;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!Objects.equals(paramValue, "")) {
|
|
|
+ returns = paramId + "=" + paramValue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return returns;
|
|
|
+ }
|
|
|
+}
|