15 changed files with 981 additions and 6 deletions
-
3cereshop-app/src/main/java/com/shop/cereshop/app/pay/PayFactory.java
-
6cereshop-app/src/main/java/com/shop/cereshop/app/pay/xs/service/XsPayService.java
-
228cereshop-app/src/main/java/com/shop/cereshop/app/pay/xs/service/impl/XsPayServiceImpl.java
-
134cereshop-app/src/main/java/com/shop/cereshop/app/pay/xs/utils/CommonUtils.java
-
60cereshop-app/src/main/java/com/shop/cereshop/app/pay/xs/utils/HttpUtils.java
-
67cereshop-app/src/main/java/com/shop/cereshop/app/pay/xs/utils/MD5Utils.java
-
291cereshop-app/src/main/java/com/shop/cereshop/app/pay/xs/utils/RSAUtils.java
-
49cereshop-app/src/main/java/com/shop/cereshop/app/service/order/impl/CereShopOrderServiceImpl.java
-
5cereshop-app/src/main/resources/application-app-dev.yml
-
10cereshop-app/src/main/resources/application.yml
-
4cereshop-business/src/main/java/com/shop/cereshop/business/pay/xs/service/XsPayService.java
-
23cereshop-commons/src/main/java/com/shop/cereshop/commons/config/PayConfig.java
-
104cereshop-commons/src/main/java/com/shop/cereshop/commons/config/XspayConfig.java
-
1cereshop-commons/src/main/java/com/shop/cereshop/commons/constant/IntegerEnum.java
-
2cereshop-commons/src/main/java/com/shop/cereshop/commons/utils/PayUtil.java
@ -0,0 +1,6 @@ |
|||||
|
package com.shop.cereshop.app.pay.xs.service; |
||||
|
|
||||
|
import com.shop.cereshop.app.pay.PayService; |
||||
|
|
||||
|
public interface XsPayService extends PayService { |
||||
|
} |
@ -0,0 +1,228 @@ |
|||||
|
package com.shop.cereshop.app.pay.xs.service.impl; |
||||
|
|
||||
|
import cn.hutool.core.util.StrUtil; |
||||
|
import com.alibaba.fastjson.JSONArray; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.alibaba.fastjson.TypeReference; |
||||
|
import com.shop.cereshop.app.pay.xs.service.XsPayService; |
||||
|
import com.shop.cereshop.app.pay.xs.utils.CommonUtils; |
||||
|
import com.shop.cereshop.app.pay.xs.utils.HttpUtils; |
||||
|
import com.shop.cereshop.commons.config.XspayConfig; |
||||
|
import com.shop.cereshop.commons.exception.CoBusinessException; |
||||
|
import com.sun.javafx.fxml.builder.URLBuilder; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.http.client.utils.URIBuilder; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.net.URI; |
||||
|
import java.net.URL; |
||||
|
import java.util.Base64; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.LinkedHashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Service(value = "xsPayService") |
||||
|
@Slf4j(topic = "XsPayServiceImpl") |
||||
|
public class XsPayServiceImpl implements XsPayService { |
||||
|
|
||||
|
//支付申请服务代码 serCode |
||||
|
private static final String PAY_SER_CODE = "101005"; |
||||
|
|
||||
|
@Override |
||||
|
public Map<String, String> gotoPay(String orderFormid, BigDecimal money, String openid, String ip, Integer type, Integer huabeiPeriod) throws CoBusinessException, Exception { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Map<String, String> refund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws CoBusinessException, Exception { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Map<String, String> orderRefund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws CoBusinessException, Exception { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Map<String, String> refundBond(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws CoBusinessException, Exception { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getCollectionCode(String orderFormid, BigDecimal money, String ip, String tradeType) throws CoBusinessException, Exception { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
//获取二维码 |
||||
|
@Override |
||||
|
public String getOrderCollectionCode(String orderFormid, BigDecimal money, String ip, String tradeType) throws CoBusinessException, Exception { |
||||
|
//构建请求参数 |
||||
|
Map<String, String> headMap = CommonUtils.buildHeadMap(PAY_SER_CODE); |
||||
|
|
||||
|
Map<String, Object> contentMap = buildPayContentMap(); |
||||
|
|
||||
|
//head+content做md5并根据加签方式加密 |
||||
|
String msg = CommonUtils.getRequestMsg(headMap,contentMap); |
||||
|
log.info("【" + PAY_SER_CODE + "】接口-请求报文:msg="+msg); |
||||
|
|
||||
|
String respMsg = HttpUtils.httpPost(XspayConfig.URL,msg); |
||||
|
//若响应respMsg为空时联系新生工作人员,此处因时收银台模式,前端页面提交方式,当时错误时,错误信息会重定向到其他页面展示 |
||||
|
log.info("【" + PAY_SER_CODE + "】接口-响应报文:" + respMsg); |
||||
|
|
||||
|
if(StrUtil.isNotBlank(respMsg)){ |
||||
|
try { |
||||
|
//解析响应报文并验签 |
||||
|
CommonUtils.verifySignRespMsg(PAY_SER_CODE,respMsg); |
||||
|
HashMap<String,String> responseMap = JSONObject.parseObject(respMsg,new TypeReference<HashMap<String,String>>(){}); |
||||
|
String resMsg = responseMap.get("msg"); |
||||
|
String responeMsg = new String(Base64.getDecoder().decode(resMsg)); |
||||
|
JSONObject jsonObject = JSONObject.parseObject(responeMsg); |
||||
|
String qrCodeUrl = jsonObject.getJSONObject("content").getJSONObject("payInfo").getString("qrCodeUrl"); |
||||
|
qrCodeUrl = new URIBuilder(qrCodeUrl).getQueryParams().get(0).getValue(); |
||||
|
return qrCodeUrl; |
||||
|
} catch (CoBusinessException e) { |
||||
|
throw e; |
||||
|
} catch (Exception e) { |
||||
|
//支付方式为B2C、B2B、H5,成功响应时respMsg为html页面代码 |
||||
|
if(respMsg.contains("toNativePayIndexForm")){ |
||||
|
log.info("【" + PAY_SER_CODE + "】接口-响应报文-HTML代码无需验签"); |
||||
|
}else{ |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
throw new CoBusinessException("10000","获取支付二维码出错"); |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 构建content请求参数 |
||||
|
* @return |
||||
|
*/ |
||||
|
private static Map<String,Object> buildPayContentMap(){ |
||||
|
// 设置请求正文 contentMap有序,顺序按照文档从上到下,为空字段可不传该字段 |
||||
|
Map<String, Object> contentMap = new LinkedHashMap<>(); |
||||
|
//商户订单号 |
||||
|
contentMap.put("merOrderId", System.currentTimeMillis()+""); |
||||
|
//商户名称 请根据实际情况替换 |
||||
|
contentMap.put("displayName", "成美国际"); |
||||
|
//商品名称 请根据实际情况替换 |
||||
|
contentMap.put("goodsName", "商品名称"); |
||||
|
//商品数量 请根据实际情况替换 |
||||
|
contentMap.put("goodsCount", 1); |
||||
|
//商品类别 请根据实际情况替换 |
||||
|
contentMap.put("goodsType", "01"); |
||||
|
//订单金额单位分 |
||||
|
contentMap.put("orderAmount", 100); |
||||
|
//订单币种 CNY:人民币 |
||||
|
contentMap.put("orderCurrencyCode", "CNY"); |
||||
|
//贸易类型 0004-货物贸易 |
||||
|
contentMap.put("tradeType", "0002"); |
||||
|
//支付方式 |
||||
|
contentMap.put("payType", "4"); |
||||
|
//机构代码 |
||||
|
contentMap.put("orgCode", "WECHATPAY"); |
||||
|
//payerAccount |
||||
|
contentMap.put("payerAccount", "omCqSs9K_z2sgvgGeIzEi5gjyL6k"); |
||||
|
//交易币种 CNY:人民币 |
||||
|
contentMap.put("payCurrencyCode", "CNY"); |
||||
|
//结算币种 CNY:人民币 |
||||
|
contentMap.put("settleCurrencyCode", "CNY"); |
||||
|
//分账标识 0:不分账 1:实时分账 2:延时分账 |
||||
|
contentMap.put("shareFlag", "0"); |
||||
|
//分账订单信息 shangFlag=1时必填 |
||||
|
JSONArray jsonArray = buildSubMerchantOrderDetails(); |
||||
|
contentMap.put("subMerchantOrderDetails", JSONArray.toJSONString(jsonArray)); |
||||
|
//回调地址 |
||||
|
contentMap.put("returnUrl", "http://lcoalhost:8080/gatewayTest/notify"); |
||||
|
//通知地址 |
||||
|
contentMap.put("noticeUrl", "http://lcoalhost:8080/gatewayTest/notify"); |
||||
|
//平台ID |
||||
|
contentMap.put("platformId",""); |
||||
|
//商户用户号 请根据实际情况选择填写 |
||||
|
contentMap.put("customerId", "U00001"); |
||||
|
//商户用户类型 请根据实际情况选择填写 |
||||
|
contentMap.put("customerType", "1"); |
||||
|
//商户用户姓名 请根据实际情况选择填写 |
||||
|
contentMap.put("customerName", "潘孝河"); |
||||
|
//商户用户证件号 请根据实际情况选择填写 |
||||
|
contentMap.put("customerIdNo", "460004198911216054"); |
||||
|
//商户用户手机号 请根据实际情况选择填写 |
||||
|
contentMap.put("customerTel", "13700418358"); |
||||
|
//商户用户银行卡号 |
||||
|
contentMap.put("bankCardNo", ""); |
||||
|
//商户用户银行卡类型 |
||||
|
contentMap.put("bankCardType", ""); |
||||
|
//有效期 |
||||
|
contentMap.put("expireData", ""); |
||||
|
//信用卡安全码 |
||||
|
contentMap.put("cvn", ""); |
||||
|
//备注 |
||||
|
contentMap.put("remark", ""); |
||||
|
//保留字段1 |
||||
|
contentMap.put("reserve1", ""); |
||||
|
//保留字段2 若要指定使用某条公众号/小程序appid时,可填写appid或对应备案号 |
||||
|
contentMap.put("reserve2", ""); |
||||
|
//预下单标识 |
||||
|
contentMap.put("preOrderFlag", ""); |
||||
|
return contentMap; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建分账明细 |
||||
|
* @return |
||||
|
*/ |
||||
|
private static JSONArray buildSubMerchantOrderDetails(){ |
||||
|
JSONArray jsonArray = new JSONArray(); |
||||
|
// //子订单1 |
||||
|
// JSONObject subOrder1 = new JSONObject(); |
||||
|
// subOrder1.put("subOrderId","sub20201001"); |
||||
|
// subOrder1.put("subOrderAmount",50); |
||||
|
// //子订单1 明细1 |
||||
|
// JSONArray detailArray1 = new JSONArray(); |
||||
|
// JSONObject detail1 = new JSONObject(); |
||||
|
// detail1.put("shareDetailId","sub20201001sd00001"); |
||||
|
// detail1.put("shareParId","1000000037901581"); |
||||
|
// detail1.put("shareAmount",20); |
||||
|
// detail1.put("settleCurCode","CNY"); |
||||
|
// detailArray1.add(detail1); |
||||
|
// //子订单1 明细2 |
||||
|
// JSONObject detail2 = new JSONObject(); |
||||
|
// detail2.put("shareDetailId","sub20201001sd00002"); |
||||
|
// detail2.put("shareParId","1000000037901520"); |
||||
|
// detail2.put("shareAmount",30); |
||||
|
// detail2.put("settleCurCode","CNY"); |
||||
|
// detailArray1.add(detail2); |
||||
|
// subOrder1.put("shareDetail",detailArray1); |
||||
|
// jsonArray.add(subOrder1); |
||||
|
// |
||||
|
// //子订单2 |
||||
|
// JSONObject subOrder2 = new JSONObject(); |
||||
|
// subOrder2.put("subOrderId","sub20201002"); |
||||
|
// subOrder2.put("subOrderAmount",50); |
||||
|
// //子订单2 明细1 |
||||
|
// JSONArray detailArray2 = new JSONArray(); |
||||
|
// JSONObject detail3 = new JSONObject(); |
||||
|
// detail3.put("shareDetailId","sub20201002sd00001"); |
||||
|
// detail3.put("shareParId","1000000037901485"); |
||||
|
// detail3.put("shareAmount",20); |
||||
|
// detail3.put("settleCurCode","CNY"); |
||||
|
// detailArray2.add(detail3); |
||||
|
// //子订单2 明细2 |
||||
|
// JSONObject detail4 = new JSONObject(); |
||||
|
// detail4.put("shareDetailId","sub20201002sd00002"); |
||||
|
// detail4.put("shareParId","1000000037901484"); |
||||
|
// detail4.put("shareAmount",30); |
||||
|
// detail4.put("settleCurCode","CNY"); |
||||
|
// detailArray2.add(detail4); |
||||
|
// subOrder2.put("shareDetail",detailArray2); |
||||
|
// |
||||
|
// jsonArray.add(subOrder2); |
||||
|
|
||||
|
return jsonArray; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,134 @@ |
|||||
|
package com.shop.cereshop.app.pay.xs.utils; |
||||
|
|
||||
|
import cn.hutool.core.util.StrUtil; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.alibaba.fastjson.parser.Feature; |
||||
|
import com.alibaba.fastjson.serializer.SerializerFeature; |
||||
|
import com.shop.cereshop.commons.config.XspayConfig; |
||||
|
import com.shop.cereshop.commons.exception.CoBusinessException; |
||||
|
|
||||
|
import java.text.SimpleDateFormat; |
||||
|
import java.util.Base64; |
||||
|
import java.util.Date; |
||||
|
import java.util.LinkedHashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 商户号密钥等信息自行替换 |
||||
|
*/ |
||||
|
public class CommonUtils { |
||||
|
|
||||
|
public static final SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMdd"); |
||||
|
public static final SimpleDateFormat formatTime = new SimpleDateFormat("HHmmss"); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 构建head请求参数 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static Map<String,String> buildHeadMap(String serCode){ |
||||
|
Map<String, String> headMap = new LinkedHashMap<>(); |
||||
|
headMap.put("serCode", serCode); |
||||
|
headMap.put("merCode", XspayConfig.MER_CODE); |
||||
|
//orderId每次请求不可重复,为请求序列号 |
||||
|
headMap.put("orderId", System.currentTimeMillis() + ""); |
||||
|
headMap.put("merDate", CommonUtils.formatDate.format(new Date())); |
||||
|
headMap.put("merTime", CommonUtils.formatTime.format(new Date())); |
||||
|
headMap.put("versionNo", "2.0"); |
||||
|
headMap.put("signType", XspayConfig.SIGN_TYPE); |
||||
|
return headMap; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建请求参数msg |
||||
|
* @param headMap |
||||
|
* @param contentMap |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String getRequestMsg(Map<String, String> headMap, Map<String, Object> contentMap) throws Exception { |
||||
|
//生成加签源串 空值不参与加签 |
||||
|
Map<String, Object> signMap = new LinkedHashMap<String, Object>(); |
||||
|
signMap.put("head", headMap); |
||||
|
signMap.put("content", contentMap); |
||||
|
//json字符串 |
||||
|
String jsonString = JSONObject.toJSONString(signMap); |
||||
|
System.out.println("【" + headMap.get("serCode") + "】接口-请求报文-JSON源串:"+jsonString); |
||||
|
//对json字符串md5得到加签源串 |
||||
|
String signData = MD5Utils.md5Hex(jsonString,XspayConfig.DEFAULT_CHARSET); |
||||
|
System.out.println("【" + headMap.get("serCode") + "】接口-请求报文-JSON源串MD5:"+signData); |
||||
|
String signMsg = null; |
||||
|
//加签 |
||||
|
if (StrUtil.equals(XspayConfig.SIGN_TYPE,"1")) {//RSA |
||||
|
signMsg = RSAUtils.encryptByPrivateKey(signData, XspayConfig.RSA_PRIVATE_KEY); |
||||
|
} else if (StrUtil.equals(XspayConfig.SIGN_TYPE,"2")) {//MD5 |
||||
|
signMsg = MD5Utils.md5Hex(signData + XspayConfig.RSA_PRIVATE_KEY,XspayConfig.DEFAULT_CHARSET); |
||||
|
} |
||||
|
signMap.put("sign",signMsg); |
||||
|
String postJsonStr = JSONObject.toJSONString(signMap); |
||||
|
//base64得到msg |
||||
|
String msg = new String(Base64.getEncoder().encode(postJsonStr.getBytes(XspayConfig.DEFAULT_CHARSET))); |
||||
|
return msg; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 响应报文 |
||||
|
*/ |
||||
|
public static void verifySignRespMsg(String serCode, String respMsg) throws Exception { |
||||
|
Map<String,String> responseMap = JSONObject.parseObject(respMsg,Map.class); |
||||
|
String error = responseMap.get("error"); |
||||
|
String errorMsg = responseMap.get("errMsg"); |
||||
|
if(StrUtil.isNotBlank(error) && StrUtil.isNotBlank(errorMsg) && !StrUtil.equals(error, "0") && !StrUtil.equals(error, "0000") && !StrUtil.equals(error, "0001")){ |
||||
|
throw new CoBusinessException(error, errorMsg); |
||||
|
} |
||||
|
//得到响应msg |
||||
|
String resMsg = responseMap.get("msg"); |
||||
|
System.out.println("【" + serCode + "】接口-响应报文-msg:" + new String(Base64.getDecoder().decode(resMsg))); |
||||
|
if(StrUtil.isNotBlank(resMsg)){ |
||||
|
//解析响应msg并验签 |
||||
|
boolean verifyFlag = verifySignature(resMsg); |
||||
|
if(verifyFlag){ |
||||
|
System.out.println("【" + serCode + "】接口-响应报文-验签结果:"+verifyFlag); |
||||
|
}else { |
||||
|
throw new CoBusinessException("10000","支付接口验签失败"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 响应msg报文验签 |
||||
|
* @param msg |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
private static boolean verifySignature(String msg) throws Exception { |
||||
|
//base64 decode |
||||
|
String msgStr = new String(Base64.getDecoder().decode(msg)); |
||||
|
//LinkedHashMap json字符串转map时保持字段顺序不变 |
||||
|
LinkedHashMap<String,String> headContentMap = JSONObject.parseObject(msgStr,LinkedHashMap.class, Feature.OrderedField); |
||||
|
|
||||
|
String resSign = headContentMap.get("sign"); |
||||
|
headContentMap.remove("sign"); |
||||
|
|
||||
|
//headContentMap 转为json字符串时保留字段值为null的字段 |
||||
|
SerializerFeature[] serializerFeatures = new SerializerFeature[]{SerializerFeature.WriteMapNullValue}; |
||||
|
//获取json字符串 不包含sign字段 |
||||
|
String headContentJson = JSONObject.toJSONString(headContentMap,serializerFeatures); |
||||
|
System.out.println("json:" + headContentJson); |
||||
|
//json字符串md5得到加签源串 |
||||
|
String md5Hex = MD5Utils.md5Hex(headContentJson,"UTF-8"); |
||||
|
|
||||
|
//响应结果验签 |
||||
|
boolean verifyFlag = false; |
||||
|
if (StrUtil.equals(XspayConfig.SIGN_TYPE,"1")) {//RSA |
||||
|
if(md5Hex.equals(RSAUtils.decryptByPublicKey(resSign,XspayConfig.NEWPAY_PUBLIC_KEY))){ |
||||
|
verifyFlag = true; |
||||
|
} |
||||
|
} else if (StrUtil.equals(XspayConfig.SIGN_TYPE,"2")) {//MD5 |
||||
|
String mac = MD5Utils.md5Hex(md5Hex + XspayConfig.NEWPAY_PUBLIC_KEY,"UTF-8"); |
||||
|
if(mac.equals(resSign)){ |
||||
|
verifyFlag = true; |
||||
|
} |
||||
|
} |
||||
|
return verifyFlag; |
||||
|
} |
||||
|
} |
@ -0,0 +1,60 @@ |
|||||
|
package com.shop.cereshop.app.pay.xs.utils; |
||||
|
|
||||
|
import org.apache.http.HttpEntity; |
||||
|
import org.apache.http.NameValuePair; |
||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
|
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
import org.apache.http.client.methods.HttpPost; |
||||
|
import org.apache.http.entity.ContentType; |
||||
|
import org.apache.http.entity.mime.HttpMultipartMode; |
||||
|
import org.apache.http.entity.mime.MultipartEntityBuilder; |
||||
|
import org.apache.http.impl.client.CloseableHttpClient; |
||||
|
import org.apache.http.impl.client.HttpClients; |
||||
|
import org.apache.http.message.BasicNameValuePair; |
||||
|
import org.apache.http.util.EntityUtils; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.io.FileInputStream; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
public class HttpUtils { |
||||
|
|
||||
|
public static String httpPost(String url,String msg) throws Exception { |
||||
|
//发送请求 |
||||
|
CloseableHttpClient httpclient = HttpClients.createDefault(); |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
//此处设值防止新生将该次请求当成手机端请求 |
||||
|
httpPost.setHeader("User-Agent","Mozilla/5.0(Windows NT 6.1;Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0"); |
||||
|
List<NameValuePair> params=new ArrayList<NameValuePair>(); |
||||
|
params.add(new BasicNameValuePair("msg",msg)); |
||||
|
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,"UTF-8"); |
||||
|
httpPost.setEntity(entity); |
||||
|
CloseableHttpResponse response = httpclient.execute(httpPost); |
||||
|
HttpEntity responseEntity = response.getEntity(); |
||||
|
String responseStr = EntityUtils.toString(responseEntity, "UTF-8"); |
||||
|
return responseStr; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static String httpPostFile(String url,String msg,File attachedFile) throws Exception { |
||||
|
//发送请求 |
||||
|
CloseableHttpClient httpclient = HttpClients.createDefault(); |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
//设置请求参数 |
||||
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532); |
||||
|
builder.addTextBody("msg", msg, ContentType.TEXT_PLAIN); |
||||
|
//把文件加到HTTP的post请求中 |
||||
|
if(attachedFile != null) { |
||||
|
builder.addBinaryBody("attachedFile", new FileInputStream(attachedFile), ContentType.APPLICATION_OCTET_STREAM, attachedFile.getName()); |
||||
|
} |
||||
|
HttpEntity multipart = builder.build(); |
||||
|
|
||||
|
httpPost.setEntity(multipart); |
||||
|
CloseableHttpResponse response = httpclient.execute(httpPost); |
||||
|
HttpEntity responseEntity = response.getEntity(); |
||||
|
String responseStr = EntityUtils.toString(responseEntity, "UTF-8"); |
||||
|
return responseStr; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,67 @@ |
|||||
|
package com.shop.cereshop.app.pay.xs.utils; |
||||
|
|
||||
|
import java.io.UnsupportedEncodingException; |
||||
|
import java.security.MessageDigest; |
||||
|
import java.security.NoSuchAlgorithmException; |
||||
|
|
||||
|
/** |
||||
|
* Static functions to simplifiy common {@link MessageDigest} tasks. This |
||||
|
* class is thread safe. |
||||
|
* |
||||
|
* g |
||||
|
* |
||||
|
*/ |
||||
|
public class MD5Utils { |
||||
|
|
||||
|
private MD5Utils() { |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns a MessageDigest for the given <code>algorithm</code>. |
||||
|
* |
||||
|
* The MessageDigest algorithm name. |
||||
|
* @return An MD5 digest instance. |
||||
|
* @throws RuntimeException |
||||
|
* when a {@link NoSuchAlgorithmException} is |
||||
|
* caught |
||||
|
*/ |
||||
|
|
||||
|
static MessageDigest getDigest() { |
||||
|
try { |
||||
|
return MessageDigest.getInstance("MD5"); |
||||
|
} catch (NoSuchAlgorithmException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Calculates the MD5 digest and returns the value as a 32 character hex |
||||
|
* string. |
||||
|
* |
||||
|
* @param data |
||||
|
* Data to digest |
||||
|
* @return MD5 digest as a hex string |
||||
|
* @throws UnsupportedEncodingException |
||||
|
*/ |
||||
|
public static String md5Hex(String data,String charset) throws UnsupportedEncodingException { |
||||
|
getDigest().digest(data.getBytes(charset)); |
||||
|
return byteArrayToHex(getDigest().digest(data.getBytes(charset))); |
||||
|
} |
||||
|
|
||||
|
//下面这个函数用于将字节数组换成成16进制的字符串 |
||||
|
public static String byteArrayToHex(byte[] byteArray) { |
||||
|
// 首先初始化一个字符数组,用来存放每个16进制字符 |
||||
|
char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'a','b','c','d','e','f' }; |
||||
|
// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)) |
||||
|
char[] resultCharArray =new char[byteArray.length * 2]; |
||||
|
// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去 |
||||
|
int index = 0; |
||||
|
for (byte b : byteArray) { |
||||
|
resultCharArray[index++] = hexDigits[b>>> 4 & 0xf]; |
||||
|
resultCharArray[index++] = hexDigits[b& 0xf]; |
||||
|
} |
||||
|
// 字符数组组合成字符串返回 |
||||
|
return new String(resultCharArray); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,291 @@ |
|||||
|
package com.shop.cereshop.app.pay.xs.utils; |
||||
|
|
||||
|
import javax.crypto.Cipher; |
||||
|
import java.io.ByteArrayOutputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.math.BigInteger; |
||||
|
import java.security.*; |
||||
|
import java.security.spec.PKCS8EncodedKeySpec; |
||||
|
import java.security.spec.X509EncodedKeySpec; |
||||
|
import java.util.Base64; |
||||
|
|
||||
|
public class RSAUtils { |
||||
|
|
||||
|
public static final String ALGORITHM = "RSA"; |
||||
|
|
||||
|
public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; |
||||
|
|
||||
|
/** |
||||
|
* RSA最大加密明文大小 |
||||
|
*/ |
||||
|
private static final int MAX_ENCRYPT_BLOCK = 117; |
||||
|
|
||||
|
/** |
||||
|
* RSA最大解密密文大小 |
||||
|
*/ |
||||
|
private static final int MAX_DECRYPT_BLOCK = 128; |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 公钥解密 |
||||
|
* </p> |
||||
|
* |
||||
|
* @param encryptedData |
||||
|
* 已加密数据 |
||||
|
* @param publicKey |
||||
|
* 公钥(十六进制编码) |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { |
||||
|
// byte[] keyBytes = HexUtil.toByteArray(privateKey); |
||||
|
byte[] keyBytes = Base64.getDecoder().decode(publicKey);// 修改base64编码 |
||||
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); |
||||
|
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); |
||||
|
Key publicK = keyFactory.generatePublic(x509KeySpec); |
||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
|
cipher.init(Cipher.DECRYPT_MODE, publicK); |
||||
|
int inputLen = encryptedData.length; |
||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
|
int offSet = 0; |
||||
|
byte[] cache; |
||||
|
int i = 0; |
||||
|
// 对数据分段解密 |
||||
|
while (inputLen - offSet > 0) { |
||||
|
if (inputLen - offSet > MAX_DECRYPT_BLOCK) { |
||||
|
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); |
||||
|
} else { |
||||
|
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); |
||||
|
} |
||||
|
out.write(cache, 0, cache.length); |
||||
|
i++; |
||||
|
offSet = i * MAX_DECRYPT_BLOCK; |
||||
|
} |
||||
|
byte[] decryptedData = out.toByteArray(); |
||||
|
out.close(); |
||||
|
return decryptedData; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 公钥加密 |
||||
|
* </p> |
||||
|
* |
||||
|
* @param data |
||||
|
* 源数据 |
||||
|
* @param publicKey |
||||
|
* 公钥(十六进制编码) |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { |
||||
|
// byte[] keyBytes = HexUtil.toByteArray(privateKey); |
||||
|
byte[] keyBytes = Base64.getDecoder().decode(publicKey);// 修改base64编码 |
||||
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); |
||||
|
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); |
||||
|
Key publicK = keyFactory.generatePublic(x509KeySpec); |
||||
|
// 对数据加密 |
||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicK); |
||||
|
int inputLen = data.length; |
||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
|
int offSet = 0; |
||||
|
byte[] cache; |
||||
|
int i = 0; |
||||
|
// 对数据分段加密 |
||||
|
while (inputLen - offSet > 0) { |
||||
|
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { |
||||
|
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); |
||||
|
} else { |
||||
|
cache = cipher.doFinal(data, offSet, inputLen - offSet); |
||||
|
} |
||||
|
out.write(cache, 0, cache.length); |
||||
|
i++; |
||||
|
offSet = i * MAX_ENCRYPT_BLOCK; |
||||
|
} |
||||
|
byte[] encryptedData = out.toByteArray(); |
||||
|
out.close(); |
||||
|
return encryptedData; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 私钥加密 |
||||
|
* </p> |
||||
|
* |
||||
|
* @param data |
||||
|
* 源数据 |
||||
|
* @param privateKey |
||||
|
* 私钥(十六进制编码) |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { |
||||
|
byte[] keyBytes = Base64.getDecoder().decode(privateKey);// 修改base64编码 |
||||
|
|
||||
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); |
||||
|
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); |
||||
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); |
||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
|
cipher.init(Cipher.ENCRYPT_MODE, privateK); |
||||
|
int inputLen = data.length; |
||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
|
int offSet = 0; |
||||
|
byte[] cache; |
||||
|
int i = 0; |
||||
|
// 对数据分段加密 |
||||
|
while (inputLen - offSet > 0) { |
||||
|
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { |
||||
|
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); |
||||
|
} else { |
||||
|
cache = cipher.doFinal(data, offSet, inputLen - offSet); |
||||
|
} |
||||
|
out.write(cache, 0, cache.length); |
||||
|
i++; |
||||
|
offSet = i * MAX_ENCRYPT_BLOCK; |
||||
|
} |
||||
|
byte[] encryptedData = out.toByteArray(); |
||||
|
out.close(); |
||||
|
return encryptedData; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 公钥解密 |
||||
|
* </p> |
||||
|
* |
||||
|
* @param encryptedData |
||||
|
* 已加密数据 |
||||
|
* @param publicKey |
||||
|
* 公钥 |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static String decryptByPublicKey(String encryptedData, String publicKey) throws Exception { |
||||
|
return new String(decryptByPublicKey(Base64.getDecoder().decode(encryptedData), publicKey)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 公钥加密,返回十六进制编码的密文 |
||||
|
* </p> |
||||
|
* |
||||
|
* @param data |
||||
|
* 源数据 |
||||
|
* @param publicKey |
||||
|
* 公钥(十六进制编码) |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static String encryptByPublicKey(String data, String publicKey) throws Exception { |
||||
|
return new String(Base64.getEncoder().encode(encryptByPublicKey(data.getBytes(), publicKey))); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 私钥加密,返回十六进制编码的密文 |
||||
|
* </p> |
||||
|
* |
||||
|
* @param data |
||||
|
* 源数据 |
||||
|
* @param privateKey |
||||
|
* 私钥(十六进制编码) |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static String encryptByPrivateKey(String data, String privateKey) throws Exception { |
||||
|
return new String(Base64.getEncoder().encode(encryptByPrivateKey(data.getBytes(), privateKey))); |
||||
|
} |
||||
|
|
||||
|
public static String signByPrivate(String content, PrivateKey privateKey, String input_charset) throws Exception { |
||||
|
if (privateKey == null) { |
||||
|
throw new Exception("加密私钥为空, 请设置"); |
||||
|
} |
||||
|
Signature signature = Signature.getInstance(SIGN_ALGORITHMS); |
||||
|
signature.initSign(privateKey); |
||||
|
signature.update(content.getBytes(input_charset)); |
||||
|
return new String(Base64.getEncoder().encode(signature.sign())); |
||||
|
} |
||||
|
|
||||
|
public static String signByPrivate(String content, String privateKey, String input_charset) throws Exception { |
||||
|
if (privateKey == null) { |
||||
|
throw new Exception("加密私钥为空, 请设置"); |
||||
|
} |
||||
|
PrivateKey privateKeyInfo = getPrivateKey(privateKey); |
||||
|
return signByPrivate(content, privateKeyInfo, input_charset); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* RSA验签名检查 |
||||
|
* |
||||
|
* @param content |
||||
|
* 待签名数据 |
||||
|
* @param sign |
||||
|
* 签名值 |
||||
|
* @param publicKey |
||||
|
* 支付宝公钥 |
||||
|
* @param input_charset |
||||
|
* 编码格式 |
||||
|
* @return 布尔值 |
||||
|
*/ |
||||
|
public static boolean verify(String content, String sign, String publicKey, String input_charset) { |
||||
|
try { |
||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); |
||||
|
byte[] encodedKey = Base64.getDecoder().decode(publicKey); |
||||
|
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); |
||||
|
return verify(content, sign, pubKey, input_charset); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return false; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public static boolean verify(String content, String sign, PublicKey publicKey, String inputCharset) { |
||||
|
try { |
||||
|
Signature signature = Signature.getInstance(SIGN_ALGORITHMS); |
||||
|
signature.initVerify(publicKey); |
||||
|
signature.update(content.getBytes(inputCharset)); |
||||
|
boolean bverify = signature.verify(Base64.getDecoder().decode(sign)); |
||||
|
return bverify; |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 得到私钥 |
||||
|
* |
||||
|
* @param key |
||||
|
* 密钥字符串(经过base64编码) |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static PrivateKey getPrivateKey(String key) throws Exception { |
||||
|
byte[] keyBytes = buildPKCS8Key(key); |
||||
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); |
||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); |
||||
|
PrivateKey privateKey = keyFactory.generatePrivate(keySpec); |
||||
|
return privateKey; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private static byte[] buildPKCS8Key(String privateKey) throws IOException { |
||||
|
if (privateKey.contains("-----BEGIN PRIVATE KEY-----")) { |
||||
|
return Base64.getDecoder().decode(privateKey.replaceAll("-----\\w+ PRIVATE KEY-----", "")); |
||||
|
} else if (privateKey.contains("-----BEGIN RSA PRIVATE KEY-----")) { |
||||
|
final byte[] innerKey = Base64.getDecoder().decode(privateKey.replaceAll("-----\\w+ RSA PRIVATE KEY-----", "")); |
||||
|
final byte[] result = new byte[innerKey.length + 26]; |
||||
|
System.arraycopy(Base64.getDecoder().decode("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKY="), 0, result, 0, 26); |
||||
|
System.arraycopy(BigInteger.valueOf(result.length - 4).toByteArray(), 0, result, 2, 2); |
||||
|
System.arraycopy(BigInteger.valueOf(innerKey.length).toByteArray(), 0, result, 24, 2); |
||||
|
System.arraycopy(innerKey, 0, result, 26, innerKey.length); |
||||
|
return result; |
||||
|
} else { |
||||
|
return Base64.getDecoder().decode(privateKey); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
package com.shop.cereshop.business.pay.xs.service; |
||||
|
|
||||
|
public class XsPayService { |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
/* |
||||
|
* Copyright (C) 2017-2021 |
||||
|
* All rights reserved, Designed By 深圳中科鑫智科技有限公司 |
||||
|
* Copyright authorization contact 18814114118 |
||||
|
*/ |
||||
|
package com.shop.cereshop.commons.config; |
||||
|
|
||||
|
import com.shop.cereshop.commons.constant.IntegerEnum; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
public class PayConfig { |
||||
|
|
||||
|
// 应用appid |
||||
|
public static int paymentMode = IntegerEnum.ORDER_PAY_XS.getCode(); |
||||
|
|
||||
|
@Value("${pay.paymentMode:4}") |
||||
|
public void setPaymentMode(int paymentMode) { |
||||
|
this.paymentMode = paymentMode; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,104 @@ |
|||||
|
/* |
||||
|
* Copyright (C) 2017-2021 |
||||
|
* All rights reserved, Designed By 深圳中科鑫智科技有限公司 |
||||
|
* Copyright authorization contact 18814114118 |
||||
|
*/ |
||||
|
package com.shop.cereshop.commons.config; |
||||
|
|
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
public class XspayConfig { |
||||
|
|
||||
|
// 请求网关地址 |
||||
|
public static String URL = "https://openapi.alipay.com/gateway.do"; |
||||
|
|
||||
|
/** |
||||
|
* 商户会员号 merCode |
||||
|
*/ |
||||
|
public static String MER_CODE = "10000000381"; |
||||
|
|
||||
|
/** |
||||
|
* 1-RSA |
||||
|
* 2-MD5 |
||||
|
*/ |
||||
|
public static String SIGN_TYPE = "1"; |
||||
|
|
||||
|
/** |
||||
|
* 1-RSA方式时:RSA_PRIVATE_KEY 对应 private.key |
||||
|
* 2-MD5方式时:RSA_PRIVATE_KEY 对应 10000000379_md5Key.txt |
||||
|
*/ |
||||
|
public static String RSA_PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKE9sbL2OrnqbkftH4LLPzAKYBA14MvRBUGUUQOxoAPKi3alRPn53xokZOlYKLHdEAFNkF9dIHjkJn20q5n7JRdhkeCsTQh14BZaKVNrmF5KrjdDWlGwch3Id9w+tPCkflcchSxjknVi9cRdB15mv75fEQ+4eynPPzh+8Qiz0gilAgMBAAECgYBE3mz/21vJ/O+NmSJUYytiAYx2YAzcATMVh5vyz/NgqypWStDjVG6OY+0WHamEDr+/TrnTgZtVB13JY1nIMxTr8gLAuVEhnZ4+GTaNXzJucO1hpIR2dwZy/wS276Nth3T9oZgEvVAC4q9HdzToYtcKVAnGOnWsPDLgQRYg5OQ7IQJBANHfH+TRvGOFGf4oF7X+21iyhAJrSaiDsV+eqpvdyyBwXYSwH7K/hX/c05tIZd1O8A747yP8V3pV8dc8sDD2T6cCQQDErkPZ+Z/IUKK9H66rk/kANxXvJ2nRrAujFuPAAtnpSknd3xaXnLiM9sDZMQlwpLR1OVKolGq29XQgcIE8Ws7TAkBOe541t6k3nkLGJMAZMyFb3gY30V9OQVFHbNJoT1zy2JJgWGzCL5UA59fKLhzJ0gc70iO71VXxTcqOrwdEiBfpAkAHs2MIt9NfvniAuyrVoPeQ4JdFQ9/Ky9ewzQahz/rEPZpiy4dQ7Fv1ePvYBSl/dZNzO4lW/GipPTcMxhrpSAztAkB4S07Qm8axuTyU+mSzWtSExMmXVRVIc2YL4pbSnSL/WC4r0nlDnysYOvPRatoGt5ld6IVlHiMcg4xYtqrc8RDZ"; |
||||
|
|
||||
|
/** |
||||
|
* 1-RSA方式时:NEWPAY_PUBLIC_KEY 对应 newPay.key |
||||
|
* 2-MD5方式时:NEWPAY_PUBLIC_KEY 对应 10000000379_md5Key.txt |
||||
|
*/ |
||||
|
//public static final String NEWPAY_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeI5OuApDmQr56dQzOMTH/EPWsXCeZzzq4b1/W9V3a0+kGRFLp3AiprnjbsVrzb4CUq/djLvf0mzda5YWNx74mCAQmJTXdXLF4iQhtUdTyYPC4ucoVC1QFd+K+U1xUW7avjWg3OZZzGpT7q60CPbkJqJ7XMcXxKyNYPoT4dG8qkQIDAQAB"; |
||||
|
public static String NEWPAY_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWtXOAopSduv3gKqHCU4QqYbLYddJkH/rovNYEIFpfjwhzzI7L8zpIrM0rocAAfcu933hP31uySQfGQsBHekPGoGyomLPHr77l5A2pPfKFHeZAlm39whCcquOw69tt4XlkS9uS+I4eKTGzwxfHUzg8nkGxMjArPdLtSUzuVfP75wIDAQAB"; |
||||
|
|
||||
|
/** |
||||
|
* 编码 UTF-8 |
||||
|
*/ |
||||
|
public static final String DEFAULT_CHARSET = "UTF-8"; |
||||
|
|
||||
|
|
||||
|
// // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址 |
||||
|
// public static String REDIRECT_URL; |
||||
|
// |
||||
|
// // 退款回调地址 |
||||
|
// public static String REFUND_NOTIFY_URL; |
||||
|
// |
||||
|
// // 支付成功后端回调地址 |
||||
|
// public static String APP_NOTIFY_URL; |
||||
|
// |
||||
|
// // 平台活动保证金支付成功回调地址 |
||||
|
// public static String BOND_NOTIFY_URL; |
||||
|
|
||||
|
@Value("${xspay.url:}") |
||||
|
public void setUrl(String url) { |
||||
|
this.URL = url; |
||||
|
} |
||||
|
|
||||
|
@Value("${xspay.mer_code:}") |
||||
|
public void setMerCode(String merCode) { |
||||
|
this.MER_CODE = merCode; |
||||
|
} |
||||
|
|
||||
|
@Value("${xspay.sign_type:}") |
||||
|
public void setSignType(String signType) { |
||||
|
this.SIGN_TYPE = signType; |
||||
|
} |
||||
|
|
||||
|
@Value("${xspay.rsa_private_key:}") |
||||
|
public void setRsaPrivateKey(String rsaPrivateKey) { |
||||
|
this.RSA_PRIVATE_KEY = rsaPrivateKey; |
||||
|
} |
||||
|
|
||||
|
@Value("${xspay.newpay_public_key:}") |
||||
|
public void setNewpayPublicKey(String newpayPublicKey) { |
||||
|
this.NEWPAY_PUBLIC_KEY = newpayPublicKey; |
||||
|
} |
||||
|
|
||||
|
// @Value("${alipay.redirect_url}") |
||||
|
// public void setRedirectUrl(String redirectUrl) { |
||||
|
// this.REDIRECT_URL = redirectUrl; |
||||
|
// } |
||||
|
// |
||||
|
// @Value("${alipay.refund_notifyurl}") |
||||
|
// public void setRefundNotifyUrl(String refundNotifyUrl) { |
||||
|
// this.REFUND_NOTIFY_URL = refundNotifyUrl; |
||||
|
// } |
||||
|
// |
||||
|
// @Value("${alipay.app_notifyurl}") |
||||
|
// public void setAppNotifyUrl(String appNotifyUrl) { |
||||
|
// this.APP_NOTIFY_URL = appNotifyUrl; |
||||
|
// } |
||||
|
// |
||||
|
// @Value("${alipay.bond_notifyurl}") |
||||
|
// public void setBondNotifyUrl(String bondNotifyUrl) { |
||||
|
// this.BOND_NOTIFY_URL = bondNotifyUrl; |
||||
|
// } |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue