支付对接临时提交

This commit is contained in:
墨大叔 2024-09-09 13:53:30 +08:00
parent 6f1b8047cd
commit b5565fba21
17 changed files with 1055 additions and 79 deletions

View File

@ -0,0 +1,46 @@
package com.ruoyi.common.pay.syb.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author wjh
* 2024/9/9
*/
@Component
@ConfigurationProperties(prefix = "syb")
@Data
public class SybConfig {
// 集团ID
private String orgId;
// 商户ID
private String cusId;
// 应用ID
private String appId;
// MD5密钥
private String md5AppKey;
// Api地址
private String apiUrl;
// 签名方式
private String signType;
// 商户RSA私钥,用于向通联发起请求前进行签名
private String rsaCusPriKey;
// 通联平台RSA公钥用于请求返回或者通联通知的验签
private String rsaTlPubKey;
// 商户sm2私钥,用于向通联发起请求前进行签名
private String sm2CusPriKey;
// 通联平台sm2公钥用于请求返回或者通联通知的验签
private String sm2TlPubKey;
}

View File

@ -0,0 +1,53 @@
package com.ruoyi.common.pay.syb.service;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/syb")
public class ApiTestV2 extends BaseController {
@Autowired
private SybPayService service;
@GetMapping("/scanPay")
public AjaxResult testScanPay() throws Exception {
// TODO Auto-generated method stub
String reqsn = String.valueOf(System.currentTimeMillis());
Map<String, String> map = service.scanPay(1, reqsn, "标题", "备注", "134775931316089668", "", "", "", "");
return success(map);
}
@GetMapping("/query")
public AjaxResult testQuery(@RequestParam String trxid) throws Exception {
Map<String, String> map = service.query("", trxid);
return success(map);
}
@PostMapping("/refund")
public AjaxResult testRefund() throws Exception {
String reqsn = String.valueOf(System.currentTimeMillis());
Map<String, String> map = service.refund(1, reqsn, "", "20160712167578.2547");
return success(map);
}
@PostMapping("/cancel")
public AjaxResult testCancel() throws Exception {
String reqsn = String.valueOf(System.currentTimeMillis());
Map<String, String> map = service.cancel(1, reqsn, "112094120001088316", "");
return success(map);
}
@PostMapping("/pay")
public AjaxResult testPay() throws Exception {
String reqsn = String.valueOf(System.currentTimeMillis());
Map<String, String> map = service.pay(1, reqsn, "W01", "标题", "备注", "", "123", "https://test.allinpaygd.com/JWeb/NotifyServlet", "", "", "", "", "", "", "", "", "", "", "", "");
return success(map);
}
}

View File

@ -0,0 +1,240 @@
package com.ruoyi.common.pay.syb.service;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.pay.syb.config.SybConfig;
import com.ruoyi.common.pay.syb.util.HttpConnectionUtil;
import com.ruoyi.common.pay.syb.util.SybUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.TreeMap;
@Service
public class SybPayService {
@Autowired
private SybConfig sybConfig;
/**
*
* @param trxamt
* @param reqsn
* @param paytype
* @param body
* @param remark
* @param acct
* @param validtime
* @param notify_url
* @param limit_pay
* @param idno
* @param truename
* @param asinfo
* @param sub_appid
* @param goods_tag 单品优惠信息
* @param chnlstoreid
* @param subbranch
* @param cusip 限云闪付JS支付业务
* @param fqnum 限支付宝分期业务
* @return
* @throws Exception
*/
public Map<String,String> pay(long trxamt,String reqsn,String paytype,String body,String remark,String acct,String validtime,String notify_url,String limit_pay,
String idno,String truename,String asinfo,String sub_appid,String goods_tag,String benefitdetail,String chnlstoreid,String subbranch,String extendparams,String cusip,String fqnum) throws Exception{
HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/pay");
http.init();
TreeMap<String,String> params = new TreeMap<String,String>();
if(!SybUtil.isEmpty(sybConfig.getOrgId())) {
params.put("orgid", sybConfig.getOrgId());
}
params.put("cusid", sybConfig.getCusId());
params.put("appid", sybConfig.getAppId());
params.put("version", "11");
params.put("trxamt", String.valueOf(trxamt));
params.put("reqsn", reqsn);
params.put("paytype", paytype);
params.put("randomstr", SybUtil.getValidatecode(8));
params.put("body", body);
params.put("remark", remark);
params.put("validtime", validtime);
params.put("acct", acct);
params.put("notify_url", notify_url);
params.put("limit_pay", limit_pay);
params.put("sub_appid", sub_appid);
params.put("goods_tag", goods_tag);
params.put("benefitdetail", benefitdetail);
params.put("chnlstoreid", chnlstoreid);
params.put("subbranch", subbranch);
params.put("extendparams", extendparams);
params.put("cusip", cusip);
params.put("fqnum", fqnum);
params.put("idno", idno);
params.put("truename", truename);
params.put("asinfo", asinfo);
params.put("signtype", sybConfig.getSignType());
String appkey = "";
if(sybConfig.getSignType().equals("RSA")) {
appkey = sybConfig.getRsaCusPriKey();
} else if(sybConfig.getSignType().equals("SM2")) {
appkey = sybConfig.getSm2CusPriKey();
} else {
appkey = sybConfig.getMd5AppKey();
}
params.put("sign", SybUtil.unionSign(params,appkey,sybConfig.getSignType()));
byte[] bys = http.postParams(params, true);
String result = new String(bys,"UTF-8");
Map<String,String> map = handleResult(result);
return map;
}
public Map<String,String> cancel(long trxamt,String reqsn,String oldtrxid,String oldreqsn) throws Exception{
HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/cancel");
http.init();
TreeMap<String,String> params = new TreeMap<String,String>();
if(!SybUtil.isEmpty(sybConfig.getOrgId()))
params.put("orgid", sybConfig.getOrgId());
params.put("cusid", sybConfig.getCusId());
params.put("appid", sybConfig.getAppId());
params.put("version", "11");
params.put("trxamt", String.valueOf(trxamt));
params.put("reqsn", reqsn);
params.put("oldtrxid", oldtrxid);
params.put("oldreqsn", oldreqsn);
params.put("randomstr", SybUtil.getValidatecode(8));
params.put("signtype", sybConfig.getSignType());
String appkey = "";
if(sybConfig.getSignType().equals("RSA"))
appkey = sybConfig.getRsaCusPriKey();
else if(sybConfig.getSignType().equals("SM2"))
appkey = sybConfig.getSm2CusPriKey();
else
appkey = sybConfig.getMd5AppKey();
params.put("sign", SybUtil.unionSign(params,appkey,sybConfig.getSignType()));
byte[] bys = http.postParams(params, true);
String result = new String(bys,"UTF-8");
Map<String,String> map = handleResult(result);
return map;
}
public Map<String,String> refund(long trxamt,String reqsn,String oldtrxid,String oldreqsn) throws Exception{
HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/refund");
http.init();
TreeMap<String,String> params = new TreeMap<String,String>();
if(!SybUtil.isEmpty(sybConfig.getOrgId()))
params.put("orgid", sybConfig.getOrgId());
params.put("cusid", sybConfig.getCusId());
params.put("appid", sybConfig.getAppId());
params.put("version", "11");
params.put("trxamt", String.valueOf(trxamt));
params.put("reqsn", reqsn);
params.put("oldreqsn", oldreqsn);
params.put("oldtrxid", oldtrxid);
params.put("randomstr", SybUtil.getValidatecode(8));
params.put("signtype", sybConfig.getSignType());
String appkey = "";
if(sybConfig.getSignType().equals("RSA"))
appkey = sybConfig.getRsaCusPriKey();
else if(sybConfig.getSignType().equals("SM2"))
appkey = sybConfig.getSm2CusPriKey();
else
appkey = sybConfig.getMd5AppKey();
params.put("sign", SybUtil.unionSign(params,appkey,sybConfig.getSignType()));
byte[] bys = http.postParams(params, true);
String result = new String(bys,"UTF-8");
Map<String,String> map = handleResult(result);
return map;
}
public Map<String,String> query(String reqsn,String trxid) throws Exception{
HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/query");
http.init();
TreeMap<String,String> params = new TreeMap<String,String>();
if(!SybUtil.isEmpty(sybConfig.getOrgId()))
params.put("orgid", sybConfig.getOrgId());
params.put("cusid", sybConfig.getCusId());
params.put("appid", sybConfig.getAppId());
params.put("version", "11");
params.put("reqsn", reqsn);
params.put("trxid", trxid);
params.put("randomstr", SybUtil.getValidatecode(8));
params.put("signtype", sybConfig.getSignType());
String appkey = "";
if(sybConfig.getSignType().equals("RSA"))
appkey = sybConfig.getRsaCusPriKey();
else if(sybConfig.getSignType().equals("SM2"))
appkey = sybConfig.getSm2CusPriKey();
else
appkey = sybConfig.getMd5AppKey();
params.put("sign", SybUtil.unionSign(params,appkey,sybConfig.getSignType()));
byte[] bys = http.postParams(params, true);
String result = new String(bys,"UTF-8");
Map<String,String> map = handleResult(result);
return map;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public Map<String,String> handleResult(String result) throws Exception{
System.out.println("ret:"+result);
Map map = JSON.parseObject(result, Map.class);
if(map == null){
throw new Exception("返回数据错误");
}
if("SUCCESS".equals(map.get("retcode"))){
TreeMap tmap = new TreeMap();
tmap.putAll(map);
String appkey = "";
if(sybConfig.getSignType().equals("RSA"))
appkey = sybConfig.getRsaTlPubKey();
else if(sybConfig.getSignType().equals("SM2"))
appkey = sybConfig.getSm2TlPubKey();
else
appkey = sybConfig.getMd5AppKey();
if(SybUtil.validSign(tmap, appkey, sybConfig.getSignType())){
System.out.println("签名成功");
return map;
}else{
throw new Exception("验证签名失败");
}
}else{
throw new Exception(map.get("retmsg").toString());
}
}
public Map<String, String> scanPay(long trxamt,String reqsn,String body,String remark,String authcode,String limit_pay,String idno,String truename,String asinfo) throws Exception{
// TODO Auto-generated method stub
HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/scanqrpay");
http.init();
TreeMap<String,String> params = new TreeMap<String,String>();
if(!SybUtil.isEmpty(sybConfig.getOrgId()))
params.put("orgid", sybConfig.getOrgId());
params.put("cusid", sybConfig.getCusId());
params.put("appid", sybConfig.getAppId());
params.put("version", "11");
params.put("trxamt", String.valueOf(trxamt));
params.put("reqsn", reqsn);
params.put("randomstr", SybUtil.getValidatecode(8));
params.put("body", body);
params.put("remark", remark);
params.put("authcode", authcode);
params.put("limit_pay", limit_pay);
params.put("asinfo", asinfo);
params.put("signtype", sybConfig.getSignType());
String appkey = "";
if(sybConfig.getSignType().equals("RSA"))
appkey = sybConfig.getRsaCusPriKey();
else if(sybConfig.getSignType().equals("SM2"))
appkey = sybConfig.getSm2CusPriKey();
else
appkey = sybConfig.getMd5AppKey();
params.put("sign", SybUtil.unionSign(params,appkey,sybConfig.getSignType()));
byte[] bys = http.postParams(params, true);
String result = new String(bys,"UTF-8");
Map<String,String> map = handleResult(result);
return map;
}
}

View File

@ -0,0 +1,122 @@
package com.ruoyi.common.pay.syb.util;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;
public class HttpConnectionUtil {
private HttpURLConnection conn;
private String connectUrl;
public HttpConnectionUtil(String connectUrl){
this.connectUrl = connectUrl;
}
public void init() throws Exception{
URL url = new URL(connectUrl);
System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return urlHostName.equals(session.getPeerHost());
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
URLConnection conn = url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setReadTimeout(60000);
conn.setConnectTimeout(30000);
if (conn instanceof HttpsURLConnection){
HttpsURLConnection httpsConn = (HttpsURLConnection)conn;
httpsConn.setSSLSocketFactory(SSLUtil.getInstance().getSSLSocketFactory());
} else if (conn instanceof HttpURLConnection){
HttpURLConnection httpConn = (HttpURLConnection)conn;
} else {
throw new Exception("不是http/https协议的url");
}
this.conn = (HttpURLConnection)conn;
initDefaultPost();
}
public void destory(){
try{
if(this.conn!=null){
this.conn.disconnect();
}
}catch(Exception e){
}
}
private void initDefaultPost() throws Exception{
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
}
public byte[] postParams(Map<String, String> params,boolean readreturn) throws IOException {
StringBuilder outBuf = new StringBuilder();
boolean isNotFirst = false;
for (Map.Entry<String, String> entry: params.entrySet()){
if (isNotFirst)
outBuf.append('&');
isNotFirst = true;
outBuf
.append(entry.getKey())
.append('=')
.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
System.out.println("参数:"+outBuf.toString());
return postParams(outBuf.toString(),readreturn);
}
public byte[] postParams(String message,boolean readreturn) throws IOException {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(message.getBytes("UTF-8"));
out.close();
if(readreturn){
return readBytesFromStream(conn.getInputStream());
}else{
return null;
}
}
public byte[] postParams(byte[] message,boolean readreturn) throws IOException {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(message);
out.close();
if(readreturn){
return readBytesFromStream(conn.getInputStream());
}else{
return null;
}
}
private byte[] readBytesFromStream(InputStream is) throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int readLen;
byte[] tmpBuf = new byte[4096];
while ((readLen = is.read(tmpBuf)) > 0)
baos.write(tmpBuf, 0, readLen);
is.close();
return baos.toByteArray();
}
public HttpURLConnection getConn() {
return conn;
}
}

View File

@ -0,0 +1,53 @@
package com.ruoyi.common.pay.syb.util;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* SSL管理助手类
* @author Administrator
*
*/
public class SSLUtil implements X509TrustManager {
private SSLSocketFactory sslFactory = null;
private SSLUtil(){
}
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
/** 获取SSL Socket工厂 */
public SSLSocketFactory getSSLSocketFactory(){
return sslFactory;
}
private static SSLUtil _instance = null;
/** 获取SSL管理助手类实例 */
synchronized public static SSLUtil getInstance() throws NoSuchAlgorithmException, KeyManagementException {
if (_instance == null){
_instance = new SSLUtil();
SSLContext sc = SSLContext.getInstance("SSLv3");
sc.init(null, new TrustManager[]{new SSLUtil()}, null);
_instance.sslFactory = sc.getSocketFactory();
}
return _instance;
}
}

View File

@ -0,0 +1,133 @@
package com.ruoyi.common.pay.syb.util;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.jcajce.spec.SM2ParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
public class SmUtil {
static{
Security.addProvider(new BouncyCastleProvider());
}
/**算法常量:SM3withSM2*/
public static final String ALGORITHM_SM3SM2_BCPROV = "SM3withSM2";
private final static int SM3withSM2_RS_LEN=32;
public static void main(String[] args) throws Exception {
/**商户平台分配的appid,也是签名的certid**/
String appid = "00000156";
/**商户sm2私钥,用于向通联发起请求前进行签名**/
String cusPrivateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgjj4Rk+b0YjwO+UwXofnHf4bK+kaaY5Btkd8nMP2VimmgCgYIKoEcz1UBgi2hRANCAAQqlALW4qGC3bP1x3wo5QsKxaCMEZJ2ODTTwOQ+d8UGU7GoK/y/WMBQWf5upMnFU06p5FxGooXYYoBtldgm03hq";
/**商户sm2公钥需要配置到通联商户平台**/
String cusPubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEKpQC1uKhgt2z9cd8KOULCsWgjBGSdjg008DkPnfFBlOxqCv8v1jAUFn+bqTJxVNOqeRcRqKF2GKAbZXYJtN4ag==";
/**通联平台sm2公钥用于请求返回或者通联通知的验签**/
String tlPubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/BnA8BawehBtH0ksPyayo4pmzL/u1FQ2sZcqwOp6bjVqQX4tjo930QAvHZPJ2eez8sCz/RYghcqv4LvMq+kloQ==";
String blankStr = "请求待签名数据";
PrivateKey privkey = privKeySM2FromBase64Str(cusPrivateKey);
String sign = signSM3SM2RetBase64(privkey, appid, blankStr.getBytes("UTF-8"));//签名
System.out.println(sign);
String rspBlankStr = "返回待验签数据";//通联返回的明文
String rspSign = "AovBKQGUe0xuJ0ox7FgIIX+yB3DzbudgUsnNvJmDV0IdHZtU2Y8vdeUY1pd2vmPUf08hNgdkoz+4WP/D/ktOcA==";//通联返回的签名
PublicKey publicKey = pubKeySM2FromBase64Str(tlPubKey);
boolean isOk = verifySM3SM2(publicKey, "Allinpay", Base64.decodeBase64(rspSign), rspBlankStr.getBytes("UTF-8"));
System.out.println("验签结果:"+isOk);
}
/**签名并BASE64编码-SM3WithSM2 */
public static String signSM3SM2RetBase64(final PrivateKey privateKey,String certid,final byte[] data) throws Exception{
return Base64.encodeBase64String(signSM3SM2(privateKey, certid, data));
}
/**签名-SM3WithSM2 */
public static byte[] signSM3SM2(final PrivateKey privateKey,String certid,final byte[] data) throws Exception{
SM2ParameterSpec parameterSpec = new SM2ParameterSpec(certid.getBytes());
Signature signer = Signature.getInstance(ALGORITHM_SM3SM2_BCPROV, "BC");
signer.setParameter(parameterSpec);
signer.initSign(privateKey, new SecureRandom());
signer.update(data);
return byteAsn12BytePlain(signer.sign());
}
/** 验证签名-SM3WithSM2*/
public static boolean verifySM3SM2(final PublicKey publicKey,String certid,final byte[] signData, final byte[] srcData) throws Exception {
SM2ParameterSpec parameterSpec = new SM2ParameterSpec(certid.getBytes());
Signature verifier = Signature.getInstance(ALGORITHM_SM3SM2_BCPROV, "BC");
verifier.setParameter(parameterSpec);
verifier.initVerify(publicKey);
verifier.update(srcData);
return verifier.verify(bytePlain2ByteAsn1(signData));
}
/**从字符串读取私钥-目前支持PKCS8(keystr为BASE64格式)*/
public static PrivateKey privKeySM2FromBase64Str(String keystr) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("EC");
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(keystr)));
}
/**从字符串读取RSA公钥(keystr为BASE64格式)*/
public static PublicKey pubKeySM2FromBase64Str(String keystr) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("EC");
return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(keystr)));
}
/**
* 将普通字节数组转换为ASN1字节数组 适用于SM3withSM2验签时验签明文转换
*/
private static byte[] bytePlain2ByteAsn1(byte[] data) {
if (data.length != SM3withSM2_RS_LEN * 2) throw new RuntimeException("err data. ");
BigInteger r = new BigInteger(1, Arrays.copyOfRange(data, 0, SM3withSM2_RS_LEN));
BigInteger s = new BigInteger(1, Arrays.copyOfRange(data, SM3withSM2_RS_LEN, SM3withSM2_RS_LEN * 2));
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(r));
v.add(new ASN1Integer(s));
try {
return new DERSequence(v).getEncoded("DER");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 将ASN1字节数组转换为普通字节数组 适用于SM3withSM2签名时签名结果转换
*/
private static byte[] byteAsn12BytePlain(byte[] dataAsn1) {
ASN1Sequence seq = ASN1Sequence.getInstance(dataAsn1);
byte[] r = bigIntToFixexLengthBytes(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue());
byte[] s = bigIntToFixexLengthBytes(ASN1Integer.getInstance(seq.getObjectAt(1)).getValue());
byte[] result = new byte[SM3withSM2_RS_LEN * 2];
System.arraycopy(r, 0, result, 0, r.length);
System.arraycopy(s, 0, result, SM3withSM2_RS_LEN, s.length);
return result;
}
private static byte[] bigIntToFixexLengthBytes(BigInteger rOrS) {
byte[] rs = rOrS.toByteArray();
if (rs.length == SM3withSM2_RS_LEN) return rs;
else if (rs.length == SM3withSM2_RS_LEN + 1 && rs[0] == 0)
return Arrays.copyOfRange(rs, 1, SM3withSM2_RS_LEN + 1);
else if (rs.length < SM3withSM2_RS_LEN) {
byte[] result = new byte[SM3withSM2_RS_LEN];
Arrays.fill(result, (byte) 0);
System.arraycopy(rs, 0, result, SM3withSM2_RS_LEN - rs.length, rs.length);
return result;
} else {
throw new RuntimeException("err rs: " + Hex.toHexString(rs));
}
}
}

View File

@ -0,0 +1,212 @@
package com.ruoyi.common.pay.syb.util;
import org.apache.commons.codec.binary.Base64;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
public class SybUtil {
/**
* md5
*
* @param b
* @return
*/
public static String md5(byte[] b) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
md.update(b);
byte[] hash = md.digest();
StringBuffer outStrBuf = new StringBuffer(32);
for (int i = 0; i < hash.length; i++) {
int v = hash[i] & 0xFF;
if (v < 16) {
outStrBuf.append('0');
}
outStrBuf.append(Integer.toString(v, 16).toLowerCase());
}
return outStrBuf.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return new String(b);
}
}
/**
* 判断字符串是否为空
*
* @param s
* @return
*/
public static boolean isEmpty(String s) {
if (s == null || "".equals(s.trim()))
return true;
return false;
}
/**
* 生成随机码
*
* @param n
* @return
*/
public static String getValidatecode(int n) {
Random random = new Random();
String sRand = "";
n = n == 0 ? 4 : n;// default 4
for (int i = 0; i < n; i++) {
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
}
return sRand;
}
public static boolean validSign(TreeMap<String, String> param,
String appkey, String signType) throws Exception {
if (param != null && !param.isEmpty()) {
if (!param.containsKey("sign"))
return false;
String sign = param.remove("sign");
if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序
param.put("key", appkey);
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : param.entrySet()) {
if (entry.getValue() != null && entry.getValue().length() > 0) {
sb.append(entry.getKey()).append("=")
.append(entry.getValue()).append("&");
}
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
if ("MD5".equals(signType)) {
return sign.toLowerCase().equals(
md5(sb.toString().getBytes("UTF-8")).toLowerCase());
} else if("SM2".equals(signType)){
PublicKey publicKey = SmUtil.pubKeySM2FromBase64Str(appkey);
return SmUtil.verifySM3SM2(publicKey, "Allinpay", Base64.decodeBase64(sign), sb.toString().getBytes("UTF-8"));
}else {
return rsaVerifyPublickey(sb.toString(), sign, appkey, "UTF-8");
}
}
return false;
}
public static boolean rsaVerifyPublickey(String content, String sign,
String publicKey, String charset) throws Exception {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
Base64.decodeBase64(publicKey.getBytes()));
return rsaVerifyPublickey(content, sign, pubKey, charset);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("RSAcontent = " + content + ",sign=" + sign
+ ",charset = " + charset, e);
}
}
public static boolean rsaVerifyPublickey(String content, String sign,
PublicKey pubKey, String charset) throws Exception {
try {
java.security.Signature signature = java.security.Signature
.getInstance("SHA1WithRSA");
signature.initVerify(pubKey);
if (charset == null || "".equals(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
throw e;
}
}
public static String unionSign(TreeMap<String, String> params,String appkey,
String signType) throws Exception {
// TODO Auto-generated method stub
params.remove("sign");
if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序
params.put("key", appkey);
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() != null && entry.getValue().length() > 0) {
sb.append(entry.getKey()).append("=").append(entry.getValue())
.append("&");
}
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
String sign = "";
if ("MD5".equals(signType)) {
System.out.println(sb.toString());
sign = md5(sb.toString().getBytes("UTF-8"));// 记得是md5编码的加签
params.remove("key");
}else if("SM2".equals(signType)){
System.out.println(sb.toString());
PrivateKey privkey = SmUtil.privKeySM2FromBase64Str(appkey);
sign = SmUtil.signSM3SM2RetBase64(privkey, params.get("appid"), sb.toString().getBytes("UTF-8"));//签名
} else {
System.out.println(sb.toString());
sign = rsaSign(sb.toString(), appkey, "UTF-8");
}
return sign;
}
public static String rsaSign(String content, String privateKey,
String charset) throws Exception {
PrivateKey priKey = getPrivateKeyFromPKCS8("RSA",
Base64.decodeBase64(privateKey.getBytes()));
return rsaSign(content, priKey, charset);
}
public static String rsaSign(String content, byte[] privateKey,
String charset) throws Exception {
PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", privateKey);
return rsaSign(content, priKey, charset);
}
public static String rsaSign(String content, PrivateKey priKey,
String charset) throws Exception {
java.security.Signature signature = java.security.Signature
.getInstance("SHA1WithRSA");
signature.initSign(priKey);
if (charset == null || "".equals(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
}
public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
byte[] encodedKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
}
public static PublicKey getPublicKeyFromX509(String algorithm,
byte[] encodedKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
}
}

View File

@ -1,5 +1,8 @@
package com.ruoyi.common.pay.yst.service;
import com.ruoyi.common.pay.wx.domain.Payable;
import com.ruoyi.common.pay.yst.domain.bizRes.comsumptionApply.ChannelParamInfo;
/**
* 云商通支付服务
* @author wjh
@ -8,8 +11,7 @@ package com.ruoyi.common.pay.yst.service;
public interface YstPayService {
/**
* 调起支付
* 调起微信支付
*/
void pay() throws Exception;
ChannelParamInfo prepayWx(Payable payable);
}

View File

@ -1,10 +1,13 @@
package com.ruoyi.common.pay.yst.service.impl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.wx.domain.Payable;
import com.ruoyi.common.pay.yst.config.YstConfig;
import com.ruoyi.common.pay.yst.constants.YstApi;
import com.ruoyi.common.pay.yst.constants.YstTransCode;
import com.ruoyi.common.pay.yst.domain.BizParameter;
import com.ruoyi.common.pay.yst.domain.YstResponse;
import com.ruoyi.common.pay.yst.domain.bizRes.comsumptionApply.ChannelParamInfo;
import com.ruoyi.common.pay.yst.domain.bizRes.comsumptionApply.ConsumptionApplyRes;
import com.ruoyi.common.pay.yst.service.YstPayService;
import com.ruoyi.common.pay.yst.util.SM4Utils;
@ -20,9 +23,8 @@ import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.*;
import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;
/**
* 云商通支付
* @author wjh
* 2024/8/1
*/
@ -43,82 +45,82 @@ public class YstPayServiceImpl implements YstPayService {
*/
@Override
@GetMapping
public void pay() throws Exception {
// 支付模式
String bankCardNo= SM4Utils.encryptEcb(ystConfig.getSecretKey(), "6212261001029054530");
//微信正扫
Map<String, Object> SCAN_WEIXIN = new HashMap<>();
SCAN_WEIXIN.put("SCAN_WEIXIN","{\"limitPay\":\"no_credit\"}");
SCAN_WEIXIN.put("SCAN_WEIXIN","{\"vspCusid\":\"55058404816VQJW\"}");
public ChannelParamInfo prepayWx(Payable payable) {
try {
// 支付模式
String bankCardNo= SM4Utils.encryptEcb(ystConfig.getSecretKey(), "6212261001029054530");
//微信正扫
Map<String, Object> SCAN_WEIXIN = new HashMap<>();
SCAN_WEIXIN.put("SCAN_WEIXIN","{\"limitPay\":\"no_credit\"}");
SCAN_WEIXIN.put("SCAN_WEIXIN","{\"vspCusid\":\"55058404816VQJW\"}");
// SCAN_WEIXIN.put("SCAN_WEIXIN","{\"extendParams\":\"渠道扩展参数\"}");
// SCAN_WEIXIN.put("SCAN_WEIXIN","{\"idNo\":\"\"}");
// SCAN_WEIXIN.put("SCAN_WEIXIN","{\"name\":\"\"}");
// SCAN_WEIXIN.put("SCAN_WEIXIN","{\"cardThype\":\"\"}");
//收银宝快捷
Map<String, Object> QUICKPAY_VSP = new HashMap<>();
//收银宝快捷
Map<String, Object> QUICKPAY_VSP = new HashMap<>();
System.out.println("{\"bankCardNo\":\""+bankCardNo+"\"}");
QUICKPAY_VSP.put("QUICKPAY_VSP","{\"bankCardNo\":\""+bankCardNo+"\"}");
System.out.println("{\"bankCardNo\":\""+bankCardNo+"\"}");
QUICKPAY_VSP.put("QUICKPAY_VSP","{\"bankCardNo\":\""+bankCardNo+"\"}");
//收付通快捷
Map<String, Object> QUICKPAY_SFT = new HashMap<>();
System.out.println("{\"bankCardNo\":\""+bankCardNo+"\"}");
QUICKPAY_SFT.put("QUICKPAY_SFT","{\"bankCardNo\":\""+bankCardNo+"\"}");
//收付通快捷
Map<String, Object> QUICKPAY_SFT = new HashMap<>();
System.out.println("{\"bankCardNo\":\""+bankCardNo+"\"}");
QUICKPAY_SFT.put("QUICKPAY_SFT","{\"bankCardNo\":\""+bankCardNo+"\"}");
//银联正扫
Map<String, Object> SCAN_UNIONPAY = new HashMap<>();
SCAN_UNIONPAY.put("SCAN_UNIONPAY","{\"limitPay\":\"no_credit\"}");
//银联正扫
Map<String, Object> SCAN_UNIONPAY = new HashMap<>();
SCAN_UNIONPAY.put("SCAN_UNIONPAY","{\"limitPay\":\"no_credit\"}");
//支付宝正扫
Map<String, Object> SCAN_ALIPAY = new HashMap<>();
SCAN_ALIPAY.put("SCAN_ALIPAY","{\"limitPay\":\"no_credit\"}");
//支付宝正扫
Map<String, Object> SCAN_ALIPAY = new HashMap<>();
SCAN_ALIPAY.put("SCAN_ALIPAY","{\"limitPay\":\"no_credit\"}");
//收银宝POS
Map<String, Object> ORDER_VSPPAY = new HashMap<>();
ORDER_VSPPAY.put("ORDER_VSPPAY","{\"vspCusid\":\"6602900601500JK\"}");
//收银宝POS
Map<String, Object> ORDER_VSPPAY = new HashMap<>();
ORDER_VSPPAY.put("ORDER_VSPPAY","{\"vspCusid\":\"6602900601500JK\"}");
//付款码支付
Map<String, Object> CODEPAY_VSP = new HashMap<>();
CODEPAY_VSP.put("CODEPAY_VSP","{\"vspCusid\":\"\"}");
CODEPAY_VSP.put("CODEPAY_VSP","{\"authcode\":\"280310687633511560\"}");
//付款码支付
Map<String, Object> CODEPAY_VSP = new HashMap<>();
CODEPAY_VSP.put("CODEPAY_VSP","{\"vspCusid\":\"\"}");
CODEPAY_VSP.put("CODEPAY_VSP","{\"authcode\":\"280310687633511560\"}");
//分账规则
List sepDetail = new ArrayList();
Map<String, Object> map1 = new HashMap<>();
map1.put("signNum", "2705wxl00002");
map1.put("amount", 1);
sepDetail.add(map1);
//分账规则
List sepDetail = new ArrayList();
Map<String, Object> map1 = new HashMap<>();
map1.put("signNum", "2705wxl00002");
map1.put("amount", 1);
sepDetail.add(map1);
Map<String, Object> map2 = new HashMap<>();
map2.put("signNum", "9665wxl202400004");
map2.put("amount", 1);
Map<String, Object> map2 = new HashMap<>();
map2.put("signNum", "9665wxl202400004");
map2.put("amount", 1);
// sepDetail.add(map2);
//订单过期时间
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 720);
final Date date = calendar.getTime();
final String orderValidTime = sdf.format(date);
//订单过期时间
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 720);
final Date date = calendar.getTime();
final String orderValidTime = sdf.format(date);
// 组装参数
BizParameter bizParameter = new BizParameter();
bizParameter.addParam("signNum", "111111");//TESTWC10011
bizParameter.addParam("receiverSignNum", "2705wxl00001");
bizParameter.addParam("reqTraceNum", "wxl"+ SnowFlakeUtil.newId());//商户订单号
bizParameter.addParam("orderAmount", 3);//订单金额
bizParameter.addParam("payAmount", 2);//支付金额
bizParameter.addParam("promotionAmount", 1);//营销金额
bizParameter.addParam("couponAmount",1 );//平台抽佣金额
bizParameter.addParam("verifyType", 1);//交易验证方式-0无验证1短信验证码默认-1短信验证码
// 组装参数
BizParameter bizParameter = new BizParameter();
bizParameter.addParam("signNum", "111111");//TESTWC10011
bizParameter.addParam("receiverSignNum", "2705wxl00001");
bizParameter.addParam("reqTraceNum", "wxl"+ SnowFlakeUtil.newId());//商户订单号
bizParameter.addParam("orderAmount", 3);//订单金额
bizParameter.addParam("payAmount", 2);//支付金额
bizParameter.addParam("promotionAmount", 1);//营销金额
bizParameter.addParam("couponAmount",1 );//平台抽佣金额
bizParameter.addParam("verifyType", 1);//交易验证方式-0无验证1短信验证码默认-1短信验证码
//支付模式
bizParameter.addMapParam("payMode", SCAN_WEIXIN);//微信正扫
//支付模式
bizParameter.addMapParam("payMode", SCAN_WEIXIN);//微信正扫
// bizParameter.addMapParam("payMode", QUICKPAY_VSP);//收银宝快捷
// bizParameter.addMapParam("payMode", QUICKPAY_SFT);//收付通快捷
// bizParameter.addMapParam("payMode", SCAN_UNIONPAY);//银联正扫
@ -126,24 +128,24 @@ public class YstPayServiceImpl implements YstPayService {
// bizParameter.addMapParam("payMode", ORDER_VSPPAY);//收银宝POS
// bizParameter.addMapParam("payMode", CODEPAY_VSP);//付款码支付
bizParameter.addListParam("sepDetail", sepDetail);//分账规则
bizParameter.addParam("reqsUrl", "http://www.baidu.com");//前台通知地址
bizParameter.addParam("respUrl", "http://test.allinpay.com/open/testNotify");//后台通知地址
bizParameter.addParam("orderValidTime", orderValidTime);//订单过期时间
bizParameter.addListParam("sepDetail", sepDetail);//分账规则
bizParameter.addParam("reqsUrl", "http://www.baidu.com");//前台通知地址
bizParameter.addParam("respUrl", "http://test.allinpay.com/open/testNotify");//后台通知地址
bizParameter.addParam("orderValidTime", orderValidTime);//订单过期时间
// bizParameter.addParam("goodsType", "goodsType");//商品类型
// bizParameter.addParam("bizGoodsNo", "bizGoodsNo123456");//商户商品编号
bizParameter.addParam("goodsName", "goodsName123456");//商品名称
bizParameter.addParam("goodsDesc", "goodsDesc123456");//商品描述
bizParameter.addParam("industryCode", "111111");//行业代码
bizParameter.addParam("industryName", "222222");//行业名称
bizParameter.addParam("summary", "摘要");
bizParameter.addParam("extendParams", "{\"extend\":\"abcdefghiii\"}");
// 发送请求
YstResponse<ConsumptionApplyRes> res = ystClient.sendRequest(YstApi.TX, YstTransCode.CONSUMPTION_APPLY, bizParameter, ConsumptionApplyRes.class);
res.getBizData().getChannelParamInfo();
// 打印响应结果
log.info(res.getBizData().toString());
bizParameter.addParam("goodsName", "goodsName123456");//商品名称
bizParameter.addParam("goodsDesc", "goodsDesc123456");//商品描述
bizParameter.addParam("industryCode", "111111");//行业代码
bizParameter.addParam("industryName", "222222");//行业名称
bizParameter.addParam("summary", "摘要");
bizParameter.addParam("extendParams", "{\"extend\":\"abcdefghiii\"}");
// 发送请求
YstResponse<ConsumptionApplyRes> res = ystClient.sendRequest(YstApi.TX, YstTransCode.CONSUMPTION_APPLY, bizParameter, ConsumptionApplyRes.class);
return res.getBizData().getChannelParamInfo();
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
}

View File

@ -11,6 +11,7 @@ import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.wx.util.WxPayUtil;
import com.ruoyi.common.pay.yst.service.YstPayService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.SnowFlakeUtil;
@ -76,6 +77,9 @@ public class PayBillServiceImpl implements PayBillService
@Autowired
private PayBillConverter payBillConverter;
@Autowired
private YstPayService ystPayService;
/**
* 查询支付订单
*
@ -287,6 +291,8 @@ public class PayBillServiceImpl implements PayBillService
} else {
if (TransactionBillPayType.WECHAT.getType().equals(bill.getChannelId())) {
vo.setPayParams(wxPayService.prepayWithRequestPayment(bill));
} else if (TransactionBillPayType.YST_WX.getType().equals(bill.getChannelId())) {
vo.setPayParams(ystPayService.prepayWx(bill));
} else {
throw new ServiceException("暂不支持该支付方式");
}

View File

@ -0,0 +1,21 @@
package com.ruoyi.ss.transactionBill.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author wjh
* 2024/9/9
*/
@Data
public class BillPayDTO {
@ApiModelProperty("订单编号")
@NotNull(message = "订单编号不允许为空")
private String billNo;
@ApiModelProperty("渠道ID")
@NotNull(message = "渠道ID不允许为空")
private Long channelId;
}

View File

@ -19,7 +19,8 @@ public enum TransactionBillPayType {
WECHAT(1L, "微信支付", AccountType.WECHAT),
ALI(2L, "支付宝", AccountType.ALIPAY),
BANK(3L, "银行卡", AccountType.BANK_CARD),
BALANCE(4L, "余额支付", null)
BALANCE(4L, "余额支付", null),
YST_WX(5L, "通联微信支付", null)
;
private final Long type;

View File

@ -49,7 +49,8 @@ public class TransactionBillVO extends TransactionBill {
@JsonView(JsonViewProfile.App.class)
private Boolean isFinished;
@ApiModelProperty("套餐剩余时长(毫秒)/电量(度)")
@ApiModelProperty("套餐剩余时长(秒)/电量(度)")
@JsonView(JsonViewProfile.App.class)
private BigDecimal suitSurplus;
/**

View File

@ -4,6 +4,7 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* 启动程序
@ -11,6 +12,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
* @author ruoyi
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableConfigurationProperties
@MapperScan("com.ruoyi.**.mapper")
public class SmartSwitchApplication
{

View File

@ -331,4 +331,15 @@ public class AppTransactionBillController extends BaseController
return toAjax(transactionBillService.switchDevice(bill, open));
}
@ApiOperation("支付订单")
@PutMapping("/pay")
public AjaxResult pay(@RequestBody BillPayDTO dto) {
TransactionBillVO bill = transactionBillService.selectSmTransactionBillByBillNo(dto.getBillNo());
if (transactionBillValidator.isUser(bill, getUserId())) {
return error("这不是您的订单,无法支付");
}
RechargePayBO bo = transactionBillConverter.toRechargePayBO(bill, dto.getChannelId());
return success(transactionBillService.pay(bo));
}
}

View File

@ -81,3 +81,50 @@ yst:
private-key: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgiaZmB+feACtziE8SYjVZsaQwLNLRiyO8ebSupeoWIF2gCgYIKoEcz1UBgi2hRANCAATwEo0zq6KaB992PToWeJH52LmfS0sFovnB8/LMaoIAOTlFJtA3YgjWXKlO3KT+GqOCfCC4xE60isCr28tqy7hM
# 公钥
public-key: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEu9LNkJlyLtjJxtQWIGlcZ/hyHt5eZ7LEH1nfOiK1H9HsE1cMPu5KK5jZVTtAyc7lPMXixUMirf6A3tMbuMbgqg==
#
## 收银宝
#syb:
# # 集团ID
# orgId: ""
# # 商户ID
# cusId: 5505810078000YD
# # 应用ID
# appId: 00002811
# # MD5密钥
# md5AppKey: allinpay888
# # Api地址
# apiUrl: https://syb-test.allinpay.com/apiweb/unitorder
# # 签名方式
# signType: RSA
# # 商户RSA私钥,用于向通联发起请求前进行签名
# rsaCusPriKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCfw/st1+lYn9k5wDuIIdsKuk2Ju/lijbyL/jJVcQxfaiit5iTSeVrReoaANtl8QqJdnB0KxySCzvONR/J2xHRgh5OsVZxuuV4RHkg8tqCJB5AckeDf97T61wt7byrr/tMutFqe8Jjmvicx7c0KZrCScT7bBfxlKCcpXHkTgbnv5o4o8xiAJV3ei47oEaKcShCjMzGIwNjjBqhK2hBAA7R7z7iuOrLYQD4PATBw1SAnprRYGIecOI2HZBaiMoLvtITCwAAauGnUZ51DaUFZPkeMrMWjoi2vMaS33sFh9h3tDWr2P5XZoW8dmcKRpp92YbQckfUlnHOziyUdxmhpcEeBAgMBAAECggEAAg+ntmwyLPwG8+lIe1Wge09y/6NmsMBOXen+IT8Pn02Bz9iHwhVhuBEiGhZbEPDVImsIruJp1Kwx1TFH7gNT0wj8vTzvgzgt//+JhAsBIDNyRwQUyB7sfU337nQ9NAU6GUCnaKSG/HcYj1rXidpQTdtbKb02h+GQO8bfIwLJ8M/d7Y2EK2/9+jIAvmKSO4ZyGEVrzbgYQC0V8KCKuTx64fErYurQH/aBlhxN0GxTcxeX/y5RkUwfaW55JEhApwm+SpzhjLJJfri14bMcVT8av4yoDGnmLEPBpPnFxR1EQoBJLTtc7TS7u/51I/JJwAe/75OOPSYIQWYVnlOLDng7yQKBgQDTFNNgvwr9zwdInnQfiibUx7TJfKSJqvbEXhsIWXKBCfFyQdu3d9RLd2FgRE3vgsFx3PMaT/ILVs15jPEI/mP4tCwQdCXc+l1NoiuuabUc4UwgY290fa2S5oRrf7ltmuscrC/xCa0Iqaio5dqfZN2XaBdv97ETDvZ3ReUxGsX0HQKBgQDBw5n5Ky2gpbOG0EG79tViF+S5JlTwNzQJjm+YskauZZcFwPAAIzh1z9Kz8lodSoC1wb/rrFmr9PnAbk4Puv9NbNdoIifp9CshonQ3PJyykh/SMTn2wmrQpmIiJIjgOvUjSgyRad6ePzM3hh9bQpD9kkRg73b85eDSqHIhp5g7tQKBgC3e3riti5Pwg6KyXIXmHd4rsAwBPDh2oL23vaQo3AtSv9eWnErYjZgAz3Z+IXmlLqix3VqgePch2/FIQbE0p0EK1nCU7Q2Ckvgl/9wdOLCX/VUkhroH/cposeoyjXdWLTXD7X8yHRo+1Fov6TyuTMF0a3N3nlGH9OOimtX6/X25AoGBAIUv5o6XV22teJGaZRTGvjYHJnj+GDRmPaaz+ZGEOYF24zBZRp9RlmWkzLhURg0MQRyuaTWd6qWAZowXRiEZ8JNP1WEG2Vi/NUaRXED7sNouByF8JNOxH6r8M0g0xMEcxZPUOn9ZvmQYHSR1VOhuASvLdqUK9Ucw3DDxCEKJ6OJhAoGBAKZYojmufECdq4YL5bsHBKo9okdOxzbAguQF4D8R0y7xYOTtQlU5qKQADmfMUxQwD/m+xgGewCoqRk8fDl2CTZDE4pmOrK5LAG2ZMZoTLErX95SmR/9VQgkddfWWKwyBQ1AcxshhTjADT71EYIvq12TJfL8iAcZCqC+4DmFcaYRg
# # 通联平台RSA公钥用于请求返回或者通联通知的验签
# rsaTlPubKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYXfu4b7xgDSmEGQpQ8Sn3RzFgl5CE4gL4TbYrND4FtCYOrvbgLijkdFgIrVVWi2hUW4K0PwBsmlYhXcbR+JSmqv9zviVXZiym0lK3glJGVCN86r9EPvNTusZZPm40TOEKMVENSYaUjCxZ7JzeZDfQ4WCeQQr2xirqn6LdJjpZ5wIDAQAB
# # 商户sm2私钥,用于向通联发起请求前进行签名
# sm2CusPriKey: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgKq+zfelNxrtYkJh3zX4b3miICXYN3ki3ZTREqUXSBfSgCgYIKoEcz1UBgi2hRANCAATSXuGjTUMlEvvUwl+BEXfzzNZ8CXMKjUza8taH1mCxUPc91TFzqK1FGcQflWTWn68b+H0RLQnv/TySkL5GfDJi
# # 通联平台sm2公钥用于请求返回或者通联通知的验签
# sm2TlPubKey: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/BnA8BawehBtH0ksPyayo4pmzL/u1FQ2sZcqwOp6bjVqQX4tjo930QAvHZPJ2eez8sCz/RYghcqv4LvMq+kloQ==
# 收银宝
syb:
# 集团ID
orgId: ""
# 商户ID
cusId: 56340307399QTL2
# 应用ID
appId: "00322693"
# MD5密钥
md5AppKey: allinpay888
# Api地址
apiUrl: https://vsp.allinpay.com/apiweb/unitorder
# 签名方式
signType: RSA
# 商户RSA私钥,用于向通联发起请求前进行签名
rsaCusPriKey: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCkngbbMX1kgcp8ClMDqO3r2lHP8MIdG+lrwDXoMtxLXv/sohyvmZIGv1QKPDZhU3b+tMfjfyvpCQ53Ji885YVocThz7TP8nNnshhNzhFVIQ+LcfakuitHtmsLL0wohU6NiEOi3k9iZkSuTEHgXkJSoVv3yHicjdDfbcq/rsMhx2RLa9yffVgwJY6it9EO73phc6xHP/VrxYjwjF1EXM22HyF7mNvzSdMpl7k8IBm8r8uvuB108J+sL4yPoJqHSXkJYESA9r0vLPH6hmJ534UG/umleBxnJ3l6NplcgM7NOOVNIF8a0Cu2+l+hfW+E/oAEdNImA2H7NVQy3b0vsi0S9AgMBAAECggEAGTIJtRtcSJmX8wfGgHEm5zotWvEL2NY4khIjfhRoxM13yNFgKB1ObSN0GrPwE9HpTN9BF+gTQbHt6Z0pzj2H/34SyKWF1zRvo2S7DetzfSHM03gVQKclLeOJzJYSvxqUz3HsmIpztL90Jqh25Q5vPlvANwJX9bR4RymE1QNkDo6OjfSaXvPFK5xuQ+mHmWft2Gbh/OmVONcJ6bIguQvIgyXD3wlmH16Bh1D8trqEHfw6QzpWPF3+N9WHbuFjn/u9oO+HwmVu3s6qmYlrEfvBWzkrcyzDGmUxz9oIEx1Ruh+PS+fn5mfFvmARSe5vVd6ipFw+f4aumJd2mCQbf3J34QKBgQDixyqlMCs2xg+Rv+PmIgO7BTSNzcbmpO0o74OVnSIAJMF99M1TaQYOWoXqXKN2sS8lAUd9Kf48xuXX1lEzDsNZ2kKnLqDd0I28bapZ1hawdrcKMnot2j3gt3LIe2Mq7qjAu6qEjBgA5BC2WjpKuNT++MDE9XEnQdsu8DsT2vDTYQKBgQC51FXo93qcNnGj6JAZvax1x9X/z/jHMczBDfHOhjJwGaogael+uGLwmRCI3cKd0Hau1wp5wZ+ySyWGZsLYs2cB3jqqmRQGV8wHHLZKUCO+agft5zeyu17Rw1hRAxF57Fcrk5LzyMZXeO6ny6apxLPcLEB/phAMgs24CrqRMEMK3QKBgGxXlqognySl7x5EvM5fhcS9sePlYZcjSCJ8ezLpRSsoZECWydmFnV0SJlRXOckk0U8uk0ba3xmONJSvUU/BR9cPjTRt9HDEiFJzWiVdQK3BqaT3hKOPVmybd/0L5c7HAlxBzC9S9szGKK3V4W99alT95qqyUALfVaXRI4hS2ydBAoGAO528RfYHNtBcmsoEWM254ztOEziERltapeC0X5471izVoHp59zZuP2PLoy0Jv5leSe8hJDiS5B8plbmn7t93P2ktBwf/HZ3TDcEPVj3pia/4hUE1ZDiqTb9OuQaz95pzyL4aWe1ifDOG1PwHptU9Inhr5MfAxFK+brm6atPB3l0CgYBMnyT/eaMC2PZS9jYAOBDHGTBKMxX5ddRMcI/dZzspzDNfQ6cjWH5RiXFAU4PIU2o9LbnIJNuwjdD3NspQblwbB2/c28qW4iY08jGna7MRJ46mTQle3varn7hWcQ3LMgP7XavgPDKS/qRRv0xFA/cjbnYGFn4iQp5BxcbGCy5Gdg==
# 通联平台RSA公钥用于请求返回或者通联通知的验签
rsaTlPubKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm9OV6zH5DYH/ZnAVYHscEELdCNfNTHGuBv1nYYEY9FrOzE0/4kLl9f7Y9dkWHlc2ocDwbrFSm0Vqz0q2rJPxXUYBCQl5yW3jzuKSXif7q1yOwkFVtJXvuhf5WRy+1X5FOFoMvS7538No0RpnLzmNi3ktmiqmhpcY/1pmt20FHQQIDAQAB
# 商户sm2私钥,用于向通联发起请求前进行签名
sm2CusPriKey: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgaPcLc/a1wqUa9wpDetd0PtjbPv+ldPq8vPc7UeDmlWegCgYIKoEcz1UBgi2hRANCAASo8eWV80+/3elREuKbSukOwkP+tekaq1bsk9zrreR14RAzQrDJWrq8PBso8Ctpvew51w6aVhFubw+oDFFNLE/w
# 通联平台sm2公钥用于请求返回或者通联通知的验签
sm2TlPubKey: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBQicgWm0KAMqhO3bdqMUEDrKQvYg8cCXHhdGwq7CGE6oJDzJ1P/94HpuVdBf1KidmPxr7HOH+0DAnpeCcx9TcQ==

View File

@ -81,3 +81,27 @@ yst:
private-key: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgiaZmB+feACtziE8SYjVZsaQwLNLRiyO8ebSupeoWIF2gCgYIKoEcz1UBgi2hRANCAATwEo0zq6KaB992PToWeJH52LmfS0sFovnB8/LMaoIAOTlFJtA3YgjWXKlO3KT+GqOCfCC4xE60isCr28tqy7hM
# 公钥
public-key: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEu9LNkJlyLtjJxtQWIGlcZ/hyHt5eZ7LEH1nfOiK1H9HsE1cMPu5KK5jZVTtAyc7lPMXixUMirf6A3tMbuMbgqg==
# 收银宝
syb:
# 集团ID
orgId: ""
# 商户ID
cusId: 990581007426001
# 应用ID
appId: 00322693
# MD5密钥
md5AppKey: allinpay888
# Api地址
apiUrl: https://vsp.allinpay.com/apiweb/unitorder
# 签名方式
signType: MD5
# 商户RSA私钥,用于向通联发起请求前进行签名
rsaCusPriKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCJbvZMgWzzeok4mOu4IPDk1h2i0AjJSF0e/BPa9UHnUY2iX+FDJm0JXSSqYuJi+NVorJj3uqYS6PXUVzX2tAh3Wi99rYqKdlaTTQTNC53R5+1hnJwbEU5DRrW4vwilJ0CheOrRazx6FjIf6uUmMl/oLw6P6FLMN/ABwHqG+hIXqg5OAKODbvFcNBE3tow/lX7TrjFwt6KBRPsq/mGYjcN6jL0fcviI3vYRkNtejBYJwRHVTquOdm7OQeLnltHTMY0EpcVkc1G23GLgVQRLENmREerezUfwqE7l8MZn2jNKYG/w1EBOXCNLHD8IizizzBuxnGCj4xYgGpYjasPuMjRAgMBAAECggEALuaesqF67yzXW4G1QxHJwv1daYXKQLM/mbw3GXibRfOgepxMyf95QiOqPaPnqZq5mH5tSeMYGSJsuh9Vpm+dyBCMtRdcemMRttbftaPtdbM/ycJo8u+06UtZKIA9GL1+EJX3ofB7DxVqHUV6VbNzOfnCfu/QLzHnW6RVuhBz1MddTgctTe6XA8lZ9k9t1ZNGPo1F4Y8VFoFm62ltCEkm1gAnT0rEYGCaL39aeEBihA30qC9inGGjRSXOilSDfNIiXNahr7+3PmopbmKuCqKCooMy4dBIRVnq1gyUvXZJq3CKTBOhh/ibEghcF+dGVNxKEqC7QVdMBE9URLY8gE+H4QKBgQDrLylrxwoeSsYcF8mNzsCkJkBdJ9Fex0t5GczWjcRo1OwQL9rsT7c5tQpOUE3r72JnUMONYUKRXjtMl2iL1fveuPK0igy6pjI/cxXhrCHfDTwMJ6E89L1JOCx1j+PD4wJDgp/o2700rVbKOFpb2rzwuGKaLM6nANmGtODkVUWoQwKBgQDTVMDrjcZZRNkM6904H3llezl96nF0zd/Onli555IMVAuA0g5Pi52hu1Wq/4Dzv00TGOm5h13/rvyiwwEyYVBmZeTKxO6lOIE5+jZ3veaamNc/cbCroFA9PJrck0GsY7beDQzv6hNGcGbSWq/p7klfbDjtrjF685qXQKzi0pMTWwKBgQCNMilaDYtjmFzMLPPS8VfytQxbYTZwApKrR/QUs9RBY+O97B0xVsKYILrpPYkqpvObN3/P955xi/NqDlSz72ph0wPTpDX0MSdltIBklmVXdqigW4KQCBdESDdY9WQ3DKklQt0ifhpf79l1WtPU5cQdeXWpPlFrLjVqjFmgfBlv5QKBgF+Ha2HPh77osVj28dwh1iV6i2WQ6dKMEcR7rc3zkQCDqWOFELUCfrISVcpjjy4f5r5gP57/Qw2GU2tbzRmyBb8UBlVmqh4Dqd7EbYS5UhnGR17FjMA4Sq0zzSkyY7iCprI/of59iFMKEmC6X9TWQ1KgQCeo23Mh1VrUAJLT72oLAoGBAKe8Os5vpkrfp2uvH0HjK48vzWWwaMFHvEkN8aTTeUJLVHr4brKVnLoJOmefq79HxWnIoZNp1smG43hycumF8EEusbNpPCBsIAnnpZAis7JE3h4g0iL6HrNWD+t2vkziOfCv9cY6MSNAR5lcjY9irhpP5SiXwaXQlhLH7IJ91rgw
# 通联平台RSA公钥用于请求返回或者通联通知的验签
rsaTlPubKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYXfu4b7xgDSmEGQpQ8Sn3RzFgl5CE4gL4TbYrND4FtCYOrvbgLijkdFgIrVVWi2hUW4K0PwBsmlYhXcbR+JSmqv9zviVXZiym0lK3glJGVCN86r9EPvNTusZZPm40TOEKMVENSYaUjCxZ7JzeZDfQ4WCeQQr2xirqn6LdJjpZ5wIDAQAB
# 商户sm2私钥,用于向通联发起请求前进行签名
sm2CusPriKey: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgaPNmMtsLKr2gYFRW59CQkYEmV6cAtuBO9sYaep9gBoCgCgYIKoEcz1UBgi2hRANCAAQHogtPxFVVxIS6csg5e5I2EuCSnDnwq67PyKAil+Z9vT2QemLe022Y+iPvVXsvBRwN46yl+2naTe8q2QKuj+u+
# 通联平台sm2公钥用于请求返回或者通联通知的验签
sm2TlPubKey: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/BnA8BawehBtH0ksPyayo4pmzL/u1FQ2sZcqwOp6bjVqQX4tjo930QAvHZPJ2eez8sCz/RYghcqv4LvMq+kloQ==