记得上下班打卡 | git大法好,push需谨慎

Commit cfc26285 authored by 胡佳晨's avatar 胡佳晨

Merge branch 'master' into dev_qrCode_wechat

parents 4a0164c8 f65081e2
......@@ -44,7 +44,7 @@ public class AdamMemberOrderParam implements Serializable {
@Pattern(regexp = LnsRegex.Valid.TRIPLE_PF_FOR_PAY_TERMINAL, message = "支付终端类型无效")
@NotBlank(message = "支付终端不能为空")
private String deviceFrom;
@ApiModelProperty(position = 20, required = true, value = "支付方式", allowableValues = "alipay,wepay")
@ApiModelProperty(position = 20, required = true, value = "支付方式", allowableValues = "alipay,wepay,douyinpay,unionpay")
@Pattern(regexp = LnsRegex.Valid.TRIPLE_PF_FOR_PAY, message = "支付方式无效")
@NotBlank(message = "支付方式不能为空")
private String payType;
......
......@@ -20,6 +20,8 @@ public class AdamMemberOrderResult implements Serializable, Cloneable {
private String showUrl;
@ApiModelProperty(value = "支付成功跳转URL")
private String returnUrl;
@ApiModelProperty(value = "支付方式")
private String payType;
private static final AdamMemberOrderResult obj = new AdamMemberOrderResult();
......
......@@ -13,16 +13,22 @@ public class DragonConstant {
public static final String REFUND_TYPE_WEB_ALIPAY="WEBALIPAY";//,"电脑网页内支付宝即时到账支付"),
public static final String REFUND_TYPE_WEB_WEPAY="WEBWEPAY";//,"电脑网页内微信二维码支付,用户打开微信扫码支付"),
public static final String REFUND_TYPE_JS_WEPAY="JSWEPAY";//,"微信内网页、微信公众号"),
public static final String REFUND_TYPE_WAP_UNION="WAPUNIONPAY";//,"微信内网页、微信公众号"),
public static final String REFUND_TYPE_APP_UNION="APPUNIONPAY";//,"微信内网页、微信公众号"),
public static final String REFUND_TYPE_APPLET_DOUYIN="APPLETDOUYINPAY";//,"applet 抖音支付"),
public static final String REFUND_TYPE_APPLET_WEPAY="APPLETWEPAY";//,"微信小程序");
public static final String REFUND_REDIS_KET="dragon:refund:refundCode:";// 订单号对应回调地址
public static final String ORDERCODE_REDIS_KET="dragon:refund:orderCode:";// 退款订单号对应 支付订单号
public static final String REDIS_KET_PAY_CODE="dragon:pay:code:";// 支付流水号
public enum PayChannelEnum{
ALIPAY("alipay","支付宝"),
WEPAY ("wepay","微信"),
APPLEPAY ("applepay","applepay"),
UNIONPAY("unionpay","云闪付"),
DOUYINPAY ("douyinpay","抖音"),
CLOUDPAY("cloudpay","云闪付");
private String code;
private String message;
......@@ -37,7 +43,7 @@ public class DragonConstant {
}
public enum DeviceFromEnum{
WEB("web",""),WAP("wap","")
WEB("web",""),WAP("wap",""),WAPPAGE("wappage","")
,APP("app",""),JS("js",""),APPLET("applet","");
private String code;
private String message;
......@@ -175,7 +181,10 @@ public class DragonConstant {
PAYMENT_TYPE_WEB_ALIPAY("WEBALIPAY","alipay","web","电脑网页内支付宝即时到账支付"),
PAYMENT_TYPE_WEB_WEPAY("WEBWEPAY","wepay","web","电脑网页内微信二维码支付,用户打开微信扫码支付"),
PAYMENT_TYPE_JS_WEPAY("JSWEPAY","wepay","js","微信内网页、微信公众号"),
PAYMENT_TYPE_APPLET_WEPAY("APPLETWEPAY","wepay","applet","微信小程序");
PAYMENT_TYPE_APPLET_WEPAY("APPLETWEPAY","wepay","applet","微信小程序"),
PAYMENT_TYPE_APPLET_DOUYINPAY("APPLETDOUYINPAY","douyinpay","applet","抖音小程序"),
PAYMENT_TYPE_WAP_UNIONPAY("WAPUNIONPAY","unionpay","wap","银联wap支付"),
PAYMENT_TYPE_APP_UNIONPAY("APPUNIONPAY","unionpay","wap","银联wap支付");
private String code;
private String message;
......
......@@ -27,8 +27,16 @@ public enum DragonErrorCodeEnum {
TRADE_ALIPAY_QUERY_ERROR("PAY0010010","支付宝订单查询失败!"),
TRADE_UNIONPAY_QUERY_ERROR("PAY0040002","银联订单查询失败,因缓存消失,查询不到订单导致!"),
TRADE_WEPAY_SIGN_ERROR("PAY0020001","微信签名异常!"),
TRADE_DOUYINPAY_SIGN_ERROR("PAY0030001","抖音签名异常!"),
TRADE_DOUYINPAY_QUERY_ERROR("PAY0030002","抖音查询支付订单异常!"),
TRADE_UNIONPAY_SIGN_ERROR("PAY0040001","银联签名异常!"),
TRADE_WEPAY_QUERY_ERROR("PAY0020002","微信订单查询失败!");
private String code;
......
......@@ -36,6 +36,8 @@ public class DragonPayBaseRespDto implements Serializable {
private PayData payData;
private String payType;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class PayData{
......@@ -63,5 +65,9 @@ public class DragonPayBaseRespDto implements Serializable {
private String redirectUrl;
private String orderStr;
private String orderId;
private String orderToken;
}
}
......@@ -22,6 +22,12 @@ public interface IDragonOrderRefundsService {
String wePayRefundCallBack(HttpServletRequest request , HttpServletResponse response);
String unionRefundCallBack(HttpServletRequest request , HttpServletResponse response);
String aliPayRefundCodeStatus(String outTradeNo ,String tradeNo ,String outBizNo,String callBackUrl);
String douYinPayRefundCallBack(HttpServletRequest request , HttpServletResponse response);
String douYinPayRefundCodeStatus(String outRefundNo);
}
......@@ -23,4 +23,22 @@ public class PayDataVo implements Serializable {
private String signType;
private String redirectUrl;
private String orderStr;
private String orderId;
private String orderToken;
public String getOrderToken() {
return orderToken==null?"":orderToken;
}
public void setOrderToken(String orderToken) {
this.orderToken = orderToken==null?"":orderToken;
}
public String getOrderId() {
return orderId==null?"":orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId==null?"":orderId;
}
}
......@@ -13,6 +13,7 @@ public class PayInnerResultVo implements Serializable,Cloneable {
private String orderCode;
private Integer status;
private String orderId;
private String payType;
private String showUrl;
private String returnUrl;
private BigDecimal price;
......
......@@ -48,6 +48,7 @@ public class SweetConstant {
public static final String REDIS_KEY_SWEET_INTEGRAL_ACTIVITY_TOTAL_PRIZE_NUM = "sweet:integralActivity:totalPrizeNum:activityId:";
public static final String REDIS_KEY_SWEET_INTEGRAL_ACTIVITY_DRAW_BLACK = "sweet:integralActivity:drawBlack";
public static final String REDIS_KEY_SWEET_INTEGRAL_ACTIVITY_DRAW_WHITE = "sweet:integralActivity:drawWhite";
public static final String REDIS_KEY_SWEET_SEND_COUPON = "sweet:integralActivity:coupon:send:";
// 答题活动
public final static String REDIS_KEY_SWEET_ANSWER_PHONE = "sweet:answer:phone:";
// 城市投票活动
......
......@@ -95,6 +95,10 @@
field: 'nickname',
title: '用户昵称'
},
{
field: 'mobile',
title: '用户账号'
},
{
field: 'receivingName',
title: '收货人姓名'
......
......@@ -79,7 +79,7 @@ public class LnsRegex {
/**
* 支持的支付方式
*/
public static final String TRIPLE_PF_FOR_PAY = "\\b(alipay|wepay)\\b";
public static final String TRIPLE_PF_FOR_PAY = "\\b(alipay|wepay|douyinpay|unionpay)\\b";
/* ======================================================================= | */
......
......@@ -14,8 +14,8 @@ liquidnet:
blacklist_grace_period: 5
mysql:
urlHostAndPort: 39.107.71.112:3308
username: testmall
password: zhengzai!mYT
username: root
password: Zhengzai@rd2U#
rabbitmq:
host: rabbitmq.zhengzai.tv
port: 5672
......
......@@ -34,4 +34,11 @@ liquidnet:
merchantId: 1551961491
appId: wx3498304dda39c5a1
partnerKey: itIuO65O9yKmemOu3S8g1S4orqvCGwXK
unionpay:
merchantId: 821690048160PQY
gateway-url: https://gateway.95516.com
refund-url: https://gateway.95516.com/
certs-path: /data/certs/dragon/unionpay/test
certs-prefix: acp_test
pfx-pwd: '520360'
......@@ -33,4 +33,11 @@ liquidnet:
gataway-url: https://openapi.alipay.com/gateway.do
merchantId: 1551961491
appId: wx3498304dda39c5a1
partnerKey: itIuO65O9yKmemOu3S8g1S4orqvCGwXK
\ No newline at end of file
partnerKey: itIuO65O9yKmemOu3S8g1S4orqvCGwXK
unionpay:
merchantId: 821690048160PQY
gateway-url: https://gateway.95516.com
refund-url: https://gateway.95516.com
certs-path: /data/certs/dragon/unionpay/test
certs-prefix: acp_test
pfx-pwd: '520360'
\ No newline at end of file
......@@ -97,4 +97,49 @@ global-auth:
# - ${liquidnet.info.context}/**
# -----------------------------------------------------------
# -----------------------------------------------------------
\ No newline at end of file
# -----------------------------------------------------------
# ---------------------以下为银联支付--------------------------------------
##交易请求地址
acpsdk:
## 消费接口
frontTransUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/frontTransReq.do
## app 消费接口
appTransUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/appTransReq.do
## 交易状态查询
backTransUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/backTransReq.do
## 交易状态查询:app用的路径
singleQueryUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/queryTrans.do
## 退款路径 (https://gateway.95516.com/gateway/api/backTransReq.do)
refundUrl: ${liquidnet.dragon.unionpay.refund-url}/gateway/api/backTransReq.do
########################################################################
########################################################################
# 报文版本号,固定5.1.0,请勿改动
version: 5.1.0
# 签名方式,证书方式固定01,请勿改动
signMethod: '01'
# 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。
ifValidateCNName: false
# 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
ifValidateRemoteCert: false
#后台通知地址,填写接收银联后台通知的地址,必须外网能访问
#backUrl: http://222.222.222.222:8080/ACPSample_AppServer/backRcvResponse
#前台通知地址,填写处理银联前台通知的地址,必须外网能访问
#frontUrl: http://localhost:8080/ACPSample_AppServer/frontRcvResponse
#########################入网测试环境签名证书配置 ################################
# 多证书的情况证书路径为代码指定,可不对此块做配置。
# 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
# windows样例:
signCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_sign.pfx
# 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
signCertPwd: ${liquidnet.dragon.unionpay.pfx-pwd}
# 签名证书类型,固定不需要修改
signCertType: PKCS12
##########################加密证书配置################################
# 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
encryptCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_enc.cer
##########################验签证书配置################################
# 验签中级证书路径(银联提供)
middleCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_middle.cer
# 验签根证书路径(银联提供)
rootCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_root.cer
\ No newline at end of file
......@@ -36,4 +36,10 @@ liquidnet:
merchantId: 1551961491
appId: wx3498304dda39c5a1
partnerKey: itIuO65O9yKmemOu3S8g1S4orqvCGwXK
unionpay:
merchantId: 821690048160PQY
gateway-url: https://gateway.95516.com
refund-url: https://gateway.95516.com/
certs-path: /data/certs/dragon/unionpay/test
certs-prefix: acp_prod
pfx-pwd: '520360'
......@@ -35,4 +35,11 @@ liquidnet:
gataway-url: https://openapi.alipay.com/gateway.do
merchantId: 1551961491
appId: wx3498304dda39c5a1
partnerKey: itIuO65O9yKmemOu3S8g1S4orqvCGwXK
\ No newline at end of file
partnerKey: itIuO65O9yKmemOu3S8g1S4orqvCGwXK
unionpay:
merchantId: 821690048160PQY
gateway-url: https://gateway.95516.com
refund-url: https://gateway.95516.com
certs-path: /data/certs/dragon/unionpay/test
certs-prefix: acp_test
pfx-pwd: '520360'
\ No newline at end of file
......@@ -104,4 +104,50 @@ global-auth:
# - ${liquidnet.info.context}/**
# -----------------------------------------------------------
# -----------------------------------------------------------
\ No newline at end of file
# -----------------------------------------------------------
# -----------------------------------------------------------
# ---------------------以下为银联支付--------------------------------------
##交易请求地址
acpsdk:
## 消费接口
frontTransUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/frontTransReq.do
## app 消费接口
appTransUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/appTransReq.do
## 交易状态查询
backTransUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/backTransReq.do
## 交易状态查询:app用的路径
singleQueryUrl: ${liquidnet.dragon.unionpay.gateway-url}/gateway/api/queryTrans.do
## 退款路径 (https://gateway.95516.com/gateway/api/backTransReq.do)
refundUrl: ${liquidnet.dragon.unionpay.refund-url}/gateway/api/backTransReq.do
########################################################################
########################################################################
# 报文版本号,固定5.1.0,请勿改动
version: 5.1.0
# 签名方式,证书方式固定01,请勿改动
signMethod: '01'
# 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。
ifValidateCNName: false
# 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
ifValidateRemoteCert: false
#后台通知地址,填写接收银联后台通知的地址,必须外网能访问
#backUrl: http://222.222.222.222:8080/ACPSample_AppServer/backRcvResponse
#前台通知地址,填写处理银联前台通知的地址,必须外网能访问
#frontUrl: http://localhost:8080/ACPSample_AppServer/frontRcvResponse
#########################入网测试环境签名证书配置 ################################
# 多证书的情况证书路径为代码指定,可不对此块做配置。
# 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
# windows样例:
signCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_sign.pfx
# 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
signCertPwd: ${liquidnet.dragon.unionpay.pfx-pwd}
# 签名证书类型,固定不需要修改
signCertType: PKCS12
##########################加密证书配置################################
# 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
encryptCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_enc.cer
##########################验签证书配置################################
# 验签中级证书路径(银联提供)
middleCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_middle.cer
# 验签根证书路径(银联提供)
rootCertPath: ${liquidnet.dragon.unionpay.certs-path}/${liquidnet.dragon.unionpay.certs-prefix}_root.cer
\ No newline at end of file
......@@ -18,7 +18,7 @@
FROM candy_coupon cc
LEFT JOIN candy_coupon_rule ccr ON cc.coupon_id = ccr.coupon_id
<where>
cc.state = 1 AND ccr.state = 1
cc.state = 1
<if test="couType != null">
AND cc.cou_type=#{couType,jdbcType=SMALLINT}
</if>
......@@ -29,7 +29,7 @@
AND cc.busi_type = #{busiType,jdbcType=SMALLINT}
</if>
<if test="keyword != null and keyword != ''">
AND INSTR(CONCAT(cc.title, cc.notice, ccr.busi_name), #{keyword,jdbcType=VARCHAR})
AND INSTR(CONCAT(cc.title, ifnull(cc.notice,''), ifnull(ccr.busi_name,'')), #{keyword,jdbcType=VARCHAR})
</if>
</where>
</select>
......
......@@ -120,6 +120,14 @@ public class AdamMemberOrderServiceImpl implements IAdamMemberOrderService {
payParam.add("productId", param.getProductId());
break;
}
if (param.getPayType().equals("douyinpay")) {
payParam.add("showUrl", param.getShowUrl());
payParam.add("returnUrl", param.getReturnUrl() + orderNo);
}
if (param.getPayType().equals("unionpay")) {
payParam.add("returnUrl", param.getReturnUrl() + orderNo);
}
payParam.add("createDate", nowStr);
payParam.add("expireTime", "5");// 过期时间,单位分钟,默认5
......@@ -189,6 +197,7 @@ public class AdamMemberOrderServiceImpl implements IAdamMemberOrderService {
result.setOrderNo(memberOrderVo.getOrderNo());
result.setShowUrl(param.getShowUrl());
result.setReturnUrl(param.getReturnUrl());
result.setPayType(param.getPayType());
return ResponseDto.success(result);
}
......
......@@ -61,7 +61,7 @@ public class CandyCouponServiceImpl implements ICandyCouponService {
for (CandyUserCouponBasicDto dtoItem : dtoList) {
CandyCouponVo baseVo = CouponBaseUtil.getBaseCouponUserVo(dtoItem);
if(baseVo==null){
if (baseVo == null) {
continue;
}
if (type == 1) {
......@@ -124,7 +124,7 @@ public class CandyCouponServiceImpl implements ICandyCouponService {
continue;
}
CandyCouponVo baseVo = CouponBaseUtil.getBaseCouponUserVo(dtoItem);
if(baseVo==null){
if (baseVo == null) {
continue;
}
if (dtoItem.getExclusive().equals(1)) { //会员券
......@@ -153,7 +153,7 @@ public class CandyCouponServiceImpl implements ICandyCouponService {
for (CandyUserCouponBasicDto dtoItem : dtoList) {
CandyCouponVo baseVo = CouponBaseUtil.getPerformanceCouponUserVo(dtoItem, priceTotal, performanceId, timeId, ticketId);
if (type == 1) {
if (baseVo.getState().equals(3) || dtoItem.getState().equals(5)) {
if (baseVo.getState().equals(3) || dtoItem.getState().equals(5) || baseVo.getState().equals(21)) {
continue;
}
} else if (type == 2) {
......@@ -222,7 +222,7 @@ public class CandyCouponServiceImpl implements ICandyCouponService {
for (CandyUserCouponBasicDto dtoItem : dtoList) {
CandyCouponVo baseVo = CouponBaseUtil.getGoodCouponUserVo(dtoItem, priceTotal, goodId, dtoList.size());
if (type == 1) {
if (baseVo.getState().equals(3) || dtoItem.getState().equals(5)) {
if (baseVo.getState().equals(3) || dtoItem.getState().equals(5) || baseVo.getState().equals(21)) {
continue;
}
} else if (type == 2) {
......@@ -544,7 +544,7 @@ public class CandyCouponServiceImpl implements ICandyCouponService {
for (CandyUserCouponBasicDto dtoItem : dtoList) {
if (uCouponIdList.contains(dtoItem.getUcouponId())) {
CandyCouponVo baseVo = CouponBaseUtil.getBaseCouponUserVo(dtoItem);
if(baseVo==null){
if (baseVo == null) {
continue;
}
vo.add(baseVo);
......
-----BEGIN CERTIFICATE-----
MIIEPzCCAyegAwIBAgIFEDl2NhIwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMC
Q04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTEwHhcNMjAwOTExMDI0MzI2WhcN
MjUwOTExMDI0MzI2WjBzMQswCQYDVQQGEwJDTjESMBAGA1UEChMJQ0ZDQSBPQ0Ex
MQ0wCwYDVQQLEwRZQ0NBMRUwEwYDVQQLEwxJbmRpdmlkdWFsLTExKjAoBgNVBAMM
IVlDQ0FA5rWL6K+V5L2/55SoQDAwMDQwMDAwOlNJR05AMTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALUwYYpqUXZyDAu0gX5d8XkiUfFxdCan/VyLa6Cz
KH38cjX0QZIShn/O6Cw2hn2WurP/r3LdopLRzTHI0vIDJpQY/0Y135QHRFZHkAH0
omRTfAZ/atePnRF7VW766LGhR5n05h1nITDHlzCZYPSumpDPpVcJj4y30+G3A5Ou
1VVAsuLi48XtGIKwRX6gMXI+P75RwHSmPt5/pHlEPT6wUbmF0HBoF2gRBpYZwiSK
51Z52XUVEk96reolFFLu/9qyL767/v2izd5YuN9i7oSXNw1gDYcLnAuww6V6BUnK
Kq4KUG6H3Lz3WyXbEay72f12A5pnHWDjLEOwJ2SG1VVMLN8CAwEAAaOB9DCB8TAf
BgNVHSMEGDAWgBTPcJ1h6518Lrj3ywJA9wmd/jN0gDBIBgNVHSAEQTA/MD0GCGCB
HIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMv
dXMtMTQuaHRtMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly91Y3JsLmNmY2EuY29t
LmNuL1JTQS9jcmw3NTM3Ni5jcmwwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSwaOVL
eW+I7Pm7C8lXu94+MTXAzjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQw
DQYJKoZIhvcNAQEFBQADggEBADhYan/FCZWzD0BS+KvZivpp498eWRqzXjH2QkBv
IDYv2+Ntue66WxECMW7i9+RZVjyMeYbFkoxVEcg0cE/mcHOnqd1mTBpeb62NRbWR
OuquWHxcdIHJ/TjGX8+NwtpAKsn/IvTdEBz+EOOzmXuxNqNxV3Gg7Ay3YavWZzci
h9GEAQ11WKAjaNqq+XO6dDwBSVEQEkvHqf1DeqCZ9wl58I4MvUmAI7wKfnoonquu
1wCNMxnkHYS5EAk1Zb0nsprjz771+YZI6ai/I2ehn8hyUR46TYmPMn0WyaXkmEO7
ig055dazyfvMinsHmKyLa/yJvQMlZIWtsKzaNG4ikdA+ELQ=
-----END CERTIFICATE-----
\ No newline at end of file
-----BEGIN CERTIFICATE-----
MIIDzjCCAragAwIBAgIKGNDz/H99Hd/CxjANBgkqhkiG9w0BAQUFADBZMQswCQYD
VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODMwMDMx
NDMzWhcNMzEwNTExMDMxNDMzWjBYMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp
bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRcwFQYDVQQDEw5D
RkNBIFRFU1QgT0NBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALiL
J/BrdvHSbXNfLIMTwUg9tDtVjMRGXOl6aZnu9IpxjI5SMUJ4hVwgJnmbTokxs6GF
IXKsCLSm5H1jHLI22ysc/ltByEybLWj5jjJuC9+Uknbl3/Ls1RBG6MogUCqZckuo
hKrf5DmlV3C/jVLxGn3pUeanvmqVUi4TKpXxgm5QqKSPF8VtQY4qCpNcQwwZqbMr
D+IfJtfpGAeVrP+Kg6i1t65seeEnVSaLhqpRUDU0PTblOuUv3OhiKJWA3cYWxUrg
7U7SIHNJLSEUWmjy4mKty+g7Cnjzt29F9qXFb6oB2mR8yt4GHCilw1Rc5RBXY63H
eTuOwdtGE3M2p7Q++OECAwEAAaOBmDCBlTAfBgNVHSMEGDAWgBR03sWNCn0QGqpp
g1tNIc6Gm8xxODAMBgNVHRMEBTADAQH/MDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6
Ly8yMTAuNzQuNDIuMy90ZXN0cmNhL1JTQS9jcmwxLmNybDALBgNVHQ8EBAMCAQYw
HQYDVR0OBBYEFM9wnWHrnXwuuPfLAkD3CZ3+M3SAMA0GCSqGSIb3DQEBBQUAA4IB
AQC0JOazrbkk0XMxMMeBCc3lgBId1RjQLgWUZ7zaUISpPstGIrE5A9aB6Ppq0Sxl
pt2gkFhPEKUqgOFN1CzCDEbP3n4H0chqK1DOMrgTCD8ID5UW+ECTYNe35rZ+1JiF
lOPEhFL3pv6XSkiKTfDnjum8+wFwUBGlfoWK1Hcx0P2Hk1jcZZKwGTx1IAkesF83
pufhxHE2Ur7W4d4tfp+eC7XXcA91pdd+VUrAfkj9eKHcDEYZz66HvHzmt6rtJVBa
pwrtCi9pW3rcm8c/1jSnEETZIaokai0fD7260h/LkD/GrNCibSWxFj1CqyP9Y5Yv
cj6aA5LnUcJYeNkrQ3V4XvVc
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIKUhN+zB19hbc65jANBgkqhkiG9w0BAQUFADBZMQswCQYD
VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODI5MDUw
MTI5WhcNMzIwODI5MDUwMTI5WjBZMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp
bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRgwFgYDVQQDEw9D
RkNBIFRFU1QgQ1MgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
rMJGruH6rOBPFxUI7T1ybydSRRtOM1xvkVjQNX0qmYir8feE6Tb0ctgtKR7a20DI
YCj9kZ5ANBQqjRcj3Soq9XH3cirqhYHJ723OKyTpS0RPQ0N6vtVt3P5JQ+ztjWHd
qIbbTOQ6O024TGTiqi6uHgMuz9/OVur81X3a5YVkK7jFeZ9o8cTcvQxD853/1sgZ
QcmR9aUSw0RXH4XFLTrn7n4QSfWKiNotlD8Ag5gS1pH9ONUb6nGkMn3gh1xfJqjm
ONMSknPXTGiNpXtqvYi8oIvByVCbUDO59IwPP1r1SYyE3P8Nr7DdQRu0KQSdXLoG
iugSR3fn+toObVAQmplDAgMBAAGjXTBbMB8GA1UdIwQYMBaAFHTexY0KfRAaqmmD
W00hzoabzHE4MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBR0
3sWNCn0QGqppg1tNIc6Gm8xxODANBgkqhkiG9w0BAQUFAAOCAQEAM0eTkM35D4hj
RlGC63wY0h++wVPUvOrObqAVBbzEEQ7ScBienmeY8Q6lWMUTXM9ALibZklpJPcJv
3ntht7LL6ztd4wdX7E9RzZCQnRvbL9A/BU3NxWdeSpCg/OyPod5oCKP+6Uc7kApi
F9OtYNWnt3l2Zp/NiedzEQD8H4qEWQLAq+0dFo5BkfVhb/jPcktndpfPOuH1IMhP
tVcvo6jpFHw4U/nP2Jv59osIE97KJz/SPt2JAYnZOlIDqWwp9/Afvt0/MDr8y0PK
Q9c6eqIzBx7a9LpUTUl5u1jS+xSDZ/KF2lXnjwaFp7jICLWEMlBstCoogi7KwH9A
LpJP7/dj9g==
-----END CERTIFICATE-----
##############SDK配置文件(证书方式签名)################
# 说明:
# 1. 使用时请将此文件复制到src文件夹下替换原来的acp_sdk.properties。
# 2. 具体配置项请根据注释修改。
#
################################################
##########################入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址)#############################
##交易请求地址
acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do
acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do
acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do
acpsdk.batchTransUrl=https://gateway.test.95516.com/gateway/api/batchTrans.do
acpsdk.fileTransUrl=https://filedownload.test.95516.com/
acpsdk.appTransUrl=https://gateway.test.95516.com/gateway/api/appTransReq.do
acpsdk.cardTransUrl=https://gateway.test.95516.com/gateway/api/cardTransReq.do
#以下缴费产品使用,其余产品用不到
acpsdk.jfFrontTransUrl=https://gateway.test.95516.com/jiaofei/api/frontTransReq.do
acpsdk.jfBackTransUrl=https://gateway.test.95516.com/jiaofei/api/backTransReq.do
acpsdk.jfSingleQueryUrl=https://gateway.test.95516.com/jiaofei/api/queryTrans.do
acpsdk.jfCardTransUrl=https://gateway.test.95516.com/jiaofei/api/cardTransReq.do
acpsdk.jfAppTransUrl=https://gateway.test.95516.com/jiaofei/api/appTransReq.do
########################################################################
# 报文版本号,固定5.1.0,请勿改动
acpsdk.version=5.1.0
# 签名方式,证书方式固定01,请勿改动
acpsdk.signMethod=01
# 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。
acpsdk.ifValidateCNName=false
# 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
acpsdk.ifValidateRemoteCert=false
#后台通知地址,填写接收银联后台通知的地址,必须外网能访问
acpsdk.backUrl=http://222.222.222.222:8080/ACPSample_AppServer/backRcvResponse
#前台通知地址,填写处理银联前台通知的地址,必须外网能访问
acpsdk.frontUrl=http://localhost:8080/ACPSample_AppServer/frontRcvResponse
#########################入网测试环境签名证书配置 ################################
# 多证书的情况证书路径为代码指定,可不对此块做配置。
# 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
# windows样例:
acpsdk.signCert.path=D:/certs/acp_test_sign.pfx
# linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明)
#acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp_test_sign.pfx
# 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
acpsdk.signCert.pwd=000000
# 签名证书类型,固定不需要修改
acpsdk.signCert.type=PKCS12
##########################加密证书配置################################
# 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
acpsdk.encryptCert.path=d:/certs/acp_test_enc.cer
##########################验签证书配置################################
# 验签中级证书路径(银联提供)
acpsdk.middleCert.path=D:/certs/acp_test_middle.cer
# 验签根证书路径(银联提供)
acpsdk.rootCert.path=D:/certs/acp_test_root.cer
-----BEGIN CERTIFICATE-----
MIIEGjCCAwKgAwIBAgIFEgg4VmIwDQYJKoZIhvcNAQEFBQAwITELMAkGA1UEBhMC
Q04xEjAQBgNVBAoTCUNGQ0EgT0NBMTAeFw0xODExMzAwNzUxNDBaFw0yNDAxMDIw
OTA3MThaMIGFMQswCQYDVQQGEwJjbjESMBAGA1UEChMJQ0ZDQSBPQ0ExMRYwFAYD
VQQLEw1Mb2NhbCBSQSBPQ0ExMRQwEgYDVQQLEwtFbnRlcnByaXNlczE0MDIGA1UE
AxQrMDQxQFoxMjAwMDQwMDAwOlNJR05AMDAwNDAwMDA6U0lHTkAwMDAwMDAwMjCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN3BsX/kyJ2BRh2IW4GyYfFs
4g5RcIEPhzGfo0IztDeqM8cfwRGqklavYHuZfFG6XPb1N/p1rXQlwyBJ6UQwgnVu
ACyWa9+Cqf664XNp+vIVx9grqor9lzrJK6jTPrd57AJNuhpFGAW0dRAjfF5ZAdpZ
56gYiWFgp2zTIXGjXoA0MHqYKBGMMYdFSZ3EkRhsJ0jyJeaBep2VmsFDtODliW0X
5T+cSgPn1+zzlHwu1svmBYxh3ZpEY3hEwR8KQwja5d5b0kUZ5eCepg9OyB8y+K6P
5VxCN8YHwVsXFYz1rpEmjGp2qObO2A+vyJaaCdtB3AeppsGLwGCIXQ/t5wyjOqEC
AwEAAaOB8zCB8DAfBgNVHSMEGDAWgBTR2+mIguXdGo9MqgCMvnzyqxv22TBIBgNV
HSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2Zj
YS5jb20uY24vdXMvdXMtMTQuaHRtMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9j
cmwuY2ZjYS5jb20uY24vUlNBL2NybDE3ODgwLmNybDALBgNVHQ8EBAMCA+gwHQYD
VR0OBBYEFAIndZ83GnekyNLXDbnxhC6+p4aCMB0GA1UdJQQWMBQGCCsGAQUFBwMC
BggrBgEFBQcDBDANBgkqhkiG9w0BAQUFAAOCAQEASJTBgXZUnzJ7PVv9Ro4LvVtY
G/8UOyB7d6TPnWkOGsPghVJujwiSpGmzI3wCCqWbQI23sOBuwkRFCZdK11bc01Wb
bsapui647RfG0zCAd86ggn5eoe41lZRgIVc1PN/te9JtKcdHkAS9n1PUkD64lPVn
WEMOcUXukW1emQG9WXauQ8+MVWUtQPW3mmNz2pWsrLk4jk9bppCwkY0lT6KRUXWp
1xfxXF57wOoNR11wx7WQv1zHJok4oJTrM9lQuVLCwFNr7Pmg0JeEZMF7M7fGaBDi
ecJB+qLudeVOIpFijW6AQfZaLawlT6eco5/UclK95gnCSct1/BgMOe9UMYPG+w==
-----END CERTIFICATE-----
\ No newline at end of file
-----BEGIN CERTIFICATE-----
MIIDgzCCAmugAwIBAgIFEAAAABkwDQYJKoZIhvcNAQEFBQAwIjELMAkGA1UEBhMC
Q04xEzARBgNVBAoTCkNGQ0EgQ1MgQ0EwHhcNMTEwNTIwMTc0MTI0WhcNMzEwNTE1
MTc0MTI0WjAhMQswCQYDVQQGEwJDTjESMBAGA1UEChMJQ0ZDQSBPQ0ExMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApR8eQ7of5iMfk2hlgGC9Z0jcpiFs
f6ligck4WoLNgEiYg7jWL0jKkcxxlTt79maSEHRWHbdYCIQ0gq/xdIY6EUbIJ4Wd
J46dTHBOL+OVE93P3Qd422WiDMTkYsH3Mb2BcTKK/1B4jPNCL0eqCDmJrYgBiAo8
FZqm9zHmDNZHwRF/5NsyoqwuZBbTiU+JVZqrxZRtQY2k74H+umQXBNoxxHlsi0QQ
itqrhuLczY21Q0IsAAYkAuok1amDdTvNBNeP2c0lKs6N8tOfCDzi6Xz+VxMs7nJj
6sz5GCR1d1rRQDh59DfmxKlWVzAiSDIdAfBAbICLE0NQNAhYulwUSJS1wQIDAQAB
o4HAMIG9MB8GA1UdIwQYMBaAFFhpydXdFLMToHE8fAONA+Y9D44BMAwGA1UdEwQF
MAMBAf8wYAYDVR0fBFkwVzBVoFOgUaRPME0xCzAJBgNVBAYTAkNOMRMwEQYDVQQK
EwpDRkNBIENTIENBMQwwCgYDVQQLEwNDUkwxDDAKBgNVBAsTA1JTQTENMAsGA1UE
AxMEY3JsMTALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFNHb6YiC5d0aj0yqAIy+fPKr
G/bZMA0GCSqGSIb3DQEBBQUAA4IBAQAhsQGgMpueLi4lVn+TmU8MN7sO+T9/fg1S
KPKedwPZ4arpRC2etLtQ1YC4xK8LdZcQVC3cCJ3MXeBLPJS0fVOtMI10LIhasYyy
U1Zj3OSwPSBbHXwMiaTdphDMG3ZowZ7x/4OL/QS90+Zp8zfCxt9uPWPKS6QR81oa
nkrXhPJ13zBMhbP8ZpakhSfMqYG8z9l41ujmI92NahrFivl/qQrIVP6A+8KsS45d
0MVnkM2ggqDDi42KZ05zkpwpLdGOSfZ+V54GqfhjgtYxkd5I3vAGNad0hWPuIQ59
H2HILbGHI45vG7803rh5CsyqvaW1KUD4i2sLkgs9vI432PyPJVBi
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDHzCCAgegAwIBAgIEGCVShDANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJD
TjETMBEGA1UEChMKQ0ZDQSBDUyBDQTAeFw0xMTA1MjAxNTI3MDVaFw00MTA1MTIx
NTI3MDVaMCIxCzAJBgNVBAYTAkNOMRMwEQYDVQQKEwpDRkNBIENTIENBMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAshVScIOG1yHCTl2FSU1XHONBWXcS
tlJr79ZeOZ8GkH+YFG0U60iaveoYBb4B7gAcc/pprxHEhgVr8uRBjlOAfp9vLrRX
1dJH00j93T7DXVRchGVjD/4x3zyjKLuNekeiBcA+7ry0m3FCHGSj31Kocw4kfrUc
+BsDz4gIXJtsu617/AO4bvA+a+nBfxhwnIRNItsCLkO6qJfGIzeGMO+IYJ1s4XzL
XCsrXM4ofUj6jblh5Cqo7ZwFRa0dV5lmgOz8xBYzvn/t+8HoIlwRq7zAbw1I8IpC
VYcaE4+aPBK47hY9o9q9+JAqKbYQQwjLW4MSv4GNCKCVHQCeHD0QLoxtQwIDAQAB
o10wWzAfBgNVHSMEGDAWgBRYacnV3RSzE6BxPHwDjQPmPQ+OATAMBgNVHRMEBTAD
AQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUWGnJ1d0UsxOgcTx8A40D5j0PjgEw
DQYJKoZIhvcNAQEFBQADggEBAGXTChXGscLtYcWtYF8v9OLdvzEWXclSAbyPI15S
PYVrTleGMfUWraszz9CUrypuoYiWTnhr8ldOZ5HmR1IYIcs/XFQztTruAyCbAnMQ
s2il3WqEZ1N5N5AG9PeAg/EYoLxJ9+lHpNa9fLjMK9x9IzDu6/qtkdDN6NuJgqTX
6gk8RpSl8PSaxxhmyum6t1adm5S7fj2IlbWdjHcRUQEBn5l7/MNaleGh1q7+5fc3
sLIC+udfA42SLYrDCAQGJ8UK5ec37hKSKQxT1WXJnSgP5hcYd+Jmb3AeXz7PoR7t
8TsDYnMum7OHLlLlxm+wmZ1ew+SCTlz1nwhPaDqWOIZmSXc=
-----END CERTIFICATE-----
##############SDK配置文件(证书方式签名)################
# 说明:
# 1. 使用时请将此文件复制到src文件夹下替换原来的acp_sdk.properties。
# 2. 具体配置项请根据注释修改。
#
################################################
##########################入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址)#############################
##交易请求地址
acpsdk.frontTransUrl=https://gateway.95516.com/gateway/api/frontTransReq.do
acpsdk.backTransUrl=https://gateway.95516.com/gateway/api/backTransReq.do
acpsdk.singleQueryUrl=https://gateway.95516.com/gateway/api/queryTrans.do
acpsdk.batchTransUrl=https://gateway.95516.com/gateway/api/batchTrans.do
acpsdk.fileTransUrl=https://filedownload.95516.com/
acpsdk.appTransUrl=https://gateway.95516.com/gateway/api/appTransReq.do
acpsdk.cardTransUrl=https://gateway.95516.com/gateway/api/cardTransReq.do
#以下缴费产品使用,其余产品用不到
acpsdk.jfFrontTransUrl=https://gateway.95516.com/jiaofei/api/frontTransReq.do
acpsdk.jfBackTransUrl=https://gateway.95516.com/jiaofei/api/backTransReq.do
acpsdk.jfSingleQueryUrl=https://gateway.95516.com/jiaofei/api/queryTrans.do
acpsdk.jfCardTransUrl=https://gateway.95516.com/jiaofei/api/cardTransReq.do
acpsdk.jfAppTransUrl=https://gateway.95516.com/jiaofei/api/appTransReq.do
########################################################################
# 报文版本号,固定5.1.0,请勿改动
acpsdk.version=5.1.0
# 签名方式,证书方式固定01,请勿改动
acpsdk.signMethod=01
# 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
acpsdk.ifValidateRemoteCert=true
#后台通知地址,填写接收银联后台通知的地址,必须外网能访问
acpsdk.backUrl=http://222.222.222.222:8080/ACPSample_AppServer/backRcvResponse
#前台通知地址,填写处理银联前台通知的地址,必须外网能访问
acpsdk.frontUrl=http://localhost:8080/ACPSample_AppServer/frontRcvResponse
#########################入网测试环境签名证书配置 ################################
# 多证书的情况证书路径为代码指定,可不对此块做配置。
# 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
# windows样例:
acpsdk.signCert.path=D:/certs/从cfca获取到的私钥证书.pfx
# linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明)
#acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/从cfca获取到的私钥证书.pfx
# 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
acpsdk.signCert.pwd=000000
# 签名证书类型,固定不需要修改
acpsdk.signCert.type=PKCS12
##########################加密证书配置################################
# 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
acpsdk.encryptCert.path=d:/certs/acp_prod_enc.cer
##########################验签证书配置################################
# 验签中级证书路径(银联提供)
acpsdk.middleCert.path=D:/certs/acp_prod_middle.cer
# 验签根证书路径(银联提供)
acpsdk.rootCert.path=D:/certs/acp_prod_root.cer
......@@ -4,7 +4,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.core.env.Environment;
......@@ -14,6 +16,7 @@ import java.util.Arrays;
@Slf4j
@EnableFeignClients
@SpringBootApplication(scanBasePackages = {"com.liquidnet"})
@EnableConfigurationProperties
public class ServiceDragonApplication implements CommandLineRunner {
@Autowired
private Environment environment;
......
......@@ -91,6 +91,7 @@ public abstract class AbstractAlipayStrategy implements IAlipayStrategy {
*/
protected DragonPayBaseRespDto buildCommonRespDto(DragonPayBaseReqDto dragonPayBaseReqDto){
DragonPayBaseRespDto respDto = new DragonPayBaseRespDto();
respDto.setPayType(dragonPayBaseReqDto.getPayType());
respDto.setCode(dragonPayBaseReqDto.getCode());
respDto.setOrderCode(dragonPayBaseReqDto.getOrderCode());
DragonPayBaseRespDto.PayData payData = new DragonPayBaseRespDto.PayData();
......
package com.liquidnet.service.dragon.channel.douyinpay.biz;
import com.alibaba.fastjson.JSON;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.service.dragon.utils.PayDouYinpayUtils;
import com.liquidnet.service.dragon.utils.PayWepayUtils;
import com.liquidnet.service.dragon.utils.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* @author zhangfuxin
* @Description:
* @date 2021/11/12 上午11:15
*/
@Slf4j
@Component
public class DouYinPayBiz {
@Value("${liquidnet.dragon.wepay.merchantId}")
private String merchantId;
/**
* @author zhangfuxin
* @Description:抖音订单查询 实现
* @date 2021/11/12 上午11:27
*/
public Map<String, Object> tradeQuery(String outOrderNo, String appid) {
Map<String, Object> respMap =CollectionUtil.mapStringObject();
log.info("DouYinPayBiz.tradeQuery-->> request out_order_no:{} appid:{} ",outOrderNo,appid);
SortedMap<String, Object> parameters = new TreeMap<>();
parameters.put("app_id", appid);
parameters.put("out_order_no", outOrderNo);
//生成签名
String sign = PayDouYinpayUtils.getInstance().createSign(parameters);
parameters.put("sign", sign);
//map转string
String data = JSON.toJSONString(parameters);
log.info("抖音订单查询请求参数:{}",data);
try {
HttpPost httpost = new HttpPost("https://developer.toutiao.com/api/apps/ecpay/v1/query_order");
httpost.setEntity(new StringEntity(data, "UTF-8"));
CloseableHttpClient httpClient = PayDouYinpayUtils.getInstance().getHttpClient();
CloseableHttpResponse response = httpClient.execute(httpost);
HttpEntity entity = response.getEntity();
//接受到返回信息
String json = EntityUtils.toString(response.getEntity(), "UTF-8");
log.info("抖音订单查询接口返回:{}",json);
EntityUtils.consume(entity);
respMap=JSON.parseObject(json, HashMap.class);
}catch (Exception e){
log.error(e.getMessage());
}
return respMap;
}
}
package com.liquidnet.service.dragon.channel.douyinpay.constant;
/**
* @author zhangfuxin
* @Description: 抖音枚举
* @date 2021/11/9 下午3:37
*/
public class DouYinpayConstant {
public enum DouYinTradeStateEnum {
SUCCESS("0","成功");
private String code;
private String message;
DouYinTradeStateEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
}
}
package com.liquidnet.service.dragon.channel.douyinpay.strategy;
import com.liquidnet.service.dragon.channel.wepay.strategy.IWepayStrategy;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhangfuxin
* @Description:
* @date 2021/11/9 下午4:09
*/
@Component
public class DouYinayStrategyContext {
private final Map<String, IDouYinpayStrategy> handlerMap = new HashMap<>();
public IDouYinpayStrategy getStrategy(String type) {
return handlerMap.get(type);
}
public void putStrategy(String code, IDouYinpayStrategy strategy) {
handlerMap.put(code, strategy);
}
}
package com.liquidnet.service.dragon.channel.douyinpay.strategy;
import com.liquidnet.service.dragon.channel.douyinpay.strategy.annotation.StrategyDouYinPayHandler;
import com.liquidnet.service.dragon.channel.wepay.strategy.IWepayStrategy;
import com.liquidnet.service.dragon.channel.wepay.strategy.WepayStrategyContext;
import com.liquidnet.service.dragon.channel.wepay.strategy.annotation.StrategyWepayHandler;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author zhangfuxin
* @Description:
* @date 2021/11/9 下午4:12
*/
@Component
public class DouYinpayStrategyListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
Map<String, Object> beans = event.getApplicationContext().getBeansWithAnnotation(StrategyDouYinPayHandler.class);
DouYinayStrategyContext strategyContext = event.getApplicationContext().getBean(DouYinayStrategyContext.class);
beans.forEach((name, bean) -> {
StrategyDouYinPayHandler typeHandler = bean.getClass().getAnnotation(StrategyDouYinPayHandler.class);
strategyContext.putStrategy(typeHandler.value().getCode(), (IDouYinpayStrategy) bean);
});
}
}
\ No newline at end of file
package com.liquidnet.service.dragon.channel.douyinpay.strategy;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
/**
* @author zhangfuxin
* @Description: 抖音支付接口
* @date 2021/11/9 下午1:42
*/
public interface IDouYinpayStrategy {
/**
* @author zhangfuxin
* @Description: 预支付
* @date 2021/11/9 下午1:44
*/
ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto);
DragonPayOrderQueryRespDto checkOrderStatus(String code);
}
package com.liquidnet.service.dragon.channel.douyinpay.strategy.annotation;
import com.liquidnet.service.dragon.constant.DragonConstant;
import java.lang.annotation.*;
/**
* @author zhangfuxin
* @Description: 抖音标记
* @date 2021/11/9 下午1:40
*/
@Documented
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface StrategyDouYinPayHandler {
DragonConstant.DeviceFromEnum value();
}
package com.liquidnet.service.dragon.channel.douyinpay.strategy.impl;
import com.alibaba.fastjson.JSON;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.biz.DragonServiceCommonBiz;
import com.liquidnet.service.dragon.channel.douyinpay.biz.DouYinPayBiz;
import com.liquidnet.service.dragon.channel.douyinpay.constant.DouYinpayConstant;
import com.liquidnet.service.dragon.channel.douyinpay.strategy.IDouYinpayStrategy;
import com.liquidnet.service.dragon.channel.strategy.biz.DragonPayBiz;
import com.liquidnet.service.dragon.channel.wepay.biz.WepayBiz;
import com.liquidnet.service.dragon.channel.wepay.constant.WepayConstant;
import com.liquidnet.service.dragon.channel.wepay.resp.WepayPayRespDto;
import com.liquidnet.service.dragon.channel.wepay.strategy.IWepayStrategy;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.constant.DragonErrorCodeEnum;
import com.liquidnet.service.dragon.dto.DragonOrdersDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
import com.liquidnet.service.dragon.utils.DataUtils;
import com.liquidnet.service.dragon.utils.PayDouYinpayUtils;
import com.liquidnet.service.dragon.utils.PayWepayUtils;
import com.liquidnet.service.dragon.utils.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import springfox.documentation.spring.web.json.Json;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* @author zhangfuxin
* @Description: 抖音支付的抽象类
* @date 2021/11/9 下午1:41
*/
@Slf4j
public abstract class AbstractDouYinPayStrategy implements IDouYinpayStrategy {
// 订单过期时间(秒); 最小 15 分钟,最大两天
private int valid_time=60*60*24*2;
@Autowired
private DouYinPayBiz douYinPayBiz;
@Autowired
private DataUtils dataUtils;
@Autowired
private DragonServiceCommonBiz dragonServiceCommonBiz;
@Autowired
private DragonPayBiz dragonPayBiz;
@Override
public ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto) {
long startTimeTotal = System.currentTimeMillis();
long startTime = System.currentTimeMillis();
try {
//构造请求参数
SortedMap<String, Object> commonParams = this.buildRequestParamMap(dragonPayBaseReqDto);
//追加请求参数
SortedMap<String, Object> parameters = this.appendRequestParam(commonParams,dragonPayBaseReqDto);
//生成签名
String sign = PayDouYinpayUtils.getInstance().createSign(parameters);
parameters.put("sign", sign);
//map转string
String data = JSON.toJSONString(parameters);
log.info("dragonPay:douYinPay:"+dragonPayBaseReqDto.getDeviceFrom()+" request jsondata: {} ",data);
HttpPost httpost = new HttpPost(this.getRequestUrl());
httpost.setEntity(new StringEntity(data, "UTF-8"));
startTime = System.currentTimeMillis();
CloseableHttpClient httpClient = PayDouYinpayUtils.getInstance().getHttpClient();
log.info("douYinPay-->request--> getHttpClient耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
startTime = System.currentTimeMillis();
CloseableHttpResponse response = httpClient.execute(httpost);
log.info("douYinPay-->request--> execute耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
HttpEntity entity = response.getEntity();
//接收到返回信息
String json = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
log.info("dragonPay:douYinPay:"+dragonPayBaseReqDto.getDeviceFrom()+" response jsonStr: {} ",json);
//拼接返回参数
DragonPayBaseRespDto respDto = buildCommonRespDto(dragonPayBaseReqDto);
Map result=JSON.parseObject(json, HashMap.class);
if(DouYinpayConstant.DouYinTradeStateEnum.SUCCESS.getCode().equals(result.get("err_no").toString())){
//成功
respDto = this.buildResponseDto(respDto,result);
//支付订单持久化
dragonServiceCommonBiz.buildPayOrders(dragonPayBaseReqDto,respDto);
log.info("douYinpay-->dragonPay--> 耗时:{}",(System.currentTimeMillis() - startTimeTotal)+"毫秒");
return ResponseDto.success(respDto);
}else {
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_PARAM_ERROR.getCode(),DragonErrorCodeEnum.TRADE_PARAM_ERROR.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 构造公共返回参数
* @param dragonPayBaseReqDto
* @return
*/
protected DragonPayBaseRespDto buildCommonRespDto(DragonPayBaseReqDto dragonPayBaseReqDto){
DragonPayBaseRespDto respDto = new DragonPayBaseRespDto();
respDto.setCode(dragonPayBaseReqDto.getCode());
respDto.setOrderCode(dragonPayBaseReqDto.getOrderCode());
DragonPayBaseRespDto.PayData payData = new DragonPayBaseRespDto.PayData();
respDto.setPayData(payData);
return respDto;
}
/**
* 构造请求参数
* @return
*/
protected SortedMap<String, Object> buildRequestParamMap(DragonPayBaseReqDto dragonPayBaseReqDto){
SortedMap<String, Object> parameters = new TreeMap<>();
parameters.put("total_amount", dragonPayBaseReqDto.getPrice().multiply(BigDecimal.valueOf(100L)).intValue());
//商品描述; 长度限制 128 字节,不超过 42 个汉字
parameters.put("subject", dragonPayBaseReqDto.getName());
//商品详情
parameters.put("body", dragonPayBaseReqDto.getDetail());
//开发者侧的订单号, 同一小程序下不可重复
parameters.put("out_order_no", dragonPayBaseReqDto.getCode());
parameters.put("notify_url", this.getNotifyUrl());
//订单过期时间(秒); 最小 15 分钟,最大两天
parameters.put("valid_time",Integer.parseInt(dragonPayBaseReqDto.getExpireTime())*60);
return parameters;
};
/**
* 追加请求参数
* @param requestMap
* @return
*/
abstract SortedMap<String, Object> appendRequestParam(SortedMap<String, Object> requestMap,DragonPayBaseReqDto dragonPayBaseReqDto);
/**
* 构造返回参数
*/
abstract DragonPayBaseRespDto buildResponseDto(DragonPayBaseRespDto payBaseRespDto,Map result);
/**
* 获取请求url
* @return
*/
protected abstract String getRequestUrl();
/**
* 设置notifyUrl
*/
protected abstract String getNotifyUrl();
@Override
public DragonPayOrderQueryRespDto checkOrderStatus(String code) {
DragonOrdersDto ordersDto = dataUtils.getPayOrderByCode(code);
Map<String, Object> resultMaps = douYinPayBiz.tradeQuery(code,this.getAppid());
DragonPayOrderQueryRespDto respDto = dragonPayBiz.buildPayOrderQueryRespDto(ordersDto);
Map<String, Object> resultMap= (Map<String, Object>) resultMaps.get("payment_info");
Object orderStatus = resultMap.get("order_status");
/* // 查询失败
if (null == orderStatus || "FAIL".equals(orderStatus)) {
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_DOUYINPAY_QUERY_ERROR.getCode(),DragonErrorCodeEnum.TRADE_DOUYINPAY_QUERY_ERROR.getMessage());
}*/
// 当trade_state为SUCCESS时才返回result_code
if ("SUCCESS".equals(orderStatus)) {
respDto.setStatus(Integer.valueOf(DragonConstant.PayStatusEnum.STATUS_PAID.getCode()));
}else {
respDto.setStatus(Integer.valueOf(DragonConstant.PayStatusEnum.STATUS_PAY_FAIL.getCode()));
}
return respDto;
}
protected abstract String getAppid();
}
package com.liquidnet.service.dragon.channel.douyinpay.strategy.impl;
import com.liquidnet.service.dragon.channel.douyinpay.strategy.annotation.StrategyDouYinPayHandler;
import com.liquidnet.service.dragon.channel.wepay.resp.WepayPayRespDto;
import com.liquidnet.service.dragon.channel.wepay.strategy.annotation.StrategyWepayHandler;
import com.liquidnet.service.dragon.channel.wepay.strategy.impl.AbstractWepayStrategy;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.utils.PayDouYinpayUtils;
import com.liquidnet.service.dragon.utils.PayWepayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* @author zhangfuxin
* @Description: 抖音小程序支付实现
* @date 2021/11/9 下午1:45
*/
@Slf4j
@Component
@StrategyDouYinPayHandler(DragonConstant.DeviceFromEnum.APPLET)
public class DouYinPayStrategyAppletImpl extends AbstractDouYinPayStrategy {
@Value("${liquidnet.dragon.url}")
private String notifyUrl;
@Override
SortedMap<String, Object> appendRequestParam(SortedMap<String, Object> requestMap, DragonPayBaseReqDto dragonPayBaseReqDto) {
requestMap.put("app_id", PayDouYinpayUtils.getInstance().getAPP_ID());
return requestMap;
}
@Override
DragonPayBaseRespDto buildResponseDto(DragonPayBaseRespDto payBaseRespDto, Map result) {
Map data= (Map) result.get("data");
payBaseRespDto.getPayData().setOrderId(data.get("order_id").toString());
payBaseRespDto.getPayData().setOrderToken(data.get("order_token").toString());
return payBaseRespDto;
}
@Override
protected String getRequestUrl() {
return "https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
}
@Override
protected String getNotifyUrl() {
return notifyUrl + "/notify/douyinpay/applet";
}
@Override
protected String getAppid() {
return PayDouYinpayUtils.getInstance().getAPP_ID();
}
}
package com.liquidnet.service.dragon.channel.strategy.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.biz.DragonServiceCommonBiz;
import com.liquidnet.service.dragon.channel.douyinpay.strategy.DouYinayStrategyContext;
import com.liquidnet.service.dragon.channel.strategy.annotation.StrategyPayChannelHandler;
import com.liquidnet.service.dragon.channel.strategy.biz.DragonPayBiz;
import com.liquidnet.service.dragon.channel.wepay.constant.WepayConstant;
import com.liquidnet.service.dragon.channel.wepay.strategy.WepayStrategyContext;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.constant.DragonErrorCodeEnum;
import com.liquidnet.service.dragon.dto.DragonOrdersDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
import com.liquidnet.service.dragon.utils.DataUtils;
import com.liquidnet.service.dragon.utils.PayDouYinpayUtils;
import com.liquidnet.service.dragon.utils.PayWepayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhangfuxin
* @Description: 抖音
* @date 2021/11/9 上午11:47
*/
@Slf4j
@Component
@StrategyPayChannelHandler(DragonConstant.PayChannelEnum.DOUYINPAY)
public class PayChannelStrategyDouYinImpl extends AbstractPayChannelStrategyImpl {
@Autowired
private DouYinayStrategyContext douYinayStrategyContext;
@Autowired
private DataUtils dataUtils;
@Autowired
private DragonServiceCommonBiz dragonServiceCommonBiz;
@Autowired
private DragonPayBiz dragonPayBiz;
@Override
public ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto) {
return douYinayStrategyContext.getStrategy(dragonPayBaseReqDto.getDeviceFrom()).dragonPay(dragonPayBaseReqDto);
}
@Override
public String dragonNotify(HttpServletRequest request,String payType,String deviceFrom) {
JSONObject jsonObject=PayDouYinpayUtils.getJsonObject(request);
try {
log.info("dragonNotify-->douYinPay json : {}", JSON.toJSONString(jsonObject));
log.info("接收到{}支付结果{}", payType, JSON.toJSONString(jsonObject));
if(!jsonObject.getString("type").equals("payment")){
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_PARAM_ERROR.getCode(),DragonErrorCodeEnum.TRADE_PARAM_ERROR.getMessage());
}
JSONObject msg=jsonObject.getJSONObject("msg");
// Map msg= (Map) map.get("msg");
String code =msg.get("cp_orderno").toString();
//持久化通知记录
dragonServiceCommonBiz.createDragonOrderLogs(code,dragonPayBiz.getPaymentType(payType,deviceFrom),JSON.toJSONString(jsonObject));
// 根据银行订单号获取支付信息
DragonOrdersDto dragonOrdersDto = dataUtils.getPayOrderByCode(code);
if (dragonOrdersDto == null) {
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_ERROR_NOT_EXISTS.getCode(),DragonErrorCodeEnum.TRADE_ERROR_NOT_EXISTS.getMessage());
}
if (DragonConstant.PayStatusEnum.STATUS_PAID.getCode().equals(dragonOrdersDto.getStatus())) {
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_ERROR_HAS_PAID.getCode(),DragonErrorCodeEnum.TRADE_ERROR_HAS_PAID.getMessage());
}
String sign = jsonObject.get("msg_signature").toString();
boolean notifyResult = false;
if (PayDouYinpayUtils.getInstance().notifySign( sign,jsonObject)) {// 根据配置信息验证签名
//抖音回调 就代表成功了
this.completeSuccessOrder(dragonOrdersDto,null, LocalDateTime.now(), JSON.toJSONString(jsonObject));
/*if (WepayConstant.WeixinTradeStateEnum.SUCCESS.getCode().equals(notifyMap.get("result_code"))) {// 业务结果
// 成功
notifyResult = this.completeSuccessOrder(dragonOrdersDto, notifyMap.get("transaction_id"), timeEnd, notifyMap.toString());
} else {
notifyResult = this.completeFailOrder(dragonOrdersDto, notifyMap.toString());
}
if(notifyResult){
returnStr = "<xml>\n" + " <return_code><![CDATA[SUCCESS]]></return_code>\n" + " <return_msg><![CDATA[OK]]></return_msg>\n" + "</xml>";
}*/
return "{\"err_no\": 0,\"err_tips\": \"success\"}";
} else {
log.error("touyin notify fail code:{} msg:{} ",DragonErrorCodeEnum.TRADE_DOUYINPAY_SIGN_ERROR.getCode(),DragonErrorCodeEnum.TRADE_DOUYINPAY_SIGN_ERROR.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
@Override
public DragonPayOrderQueryRespDto checkOrderStatus(String code) {
DragonOrdersDto ordersDto = dataUtils.getPayOrderByCode(code);
DragonPayOrderQueryRespDto respDto = douYinayStrategyContext.getStrategy(DragonConstant.PayTypeEnum.getEnumByCode(ordersDto.getPaymentType()).getDeviceFrom()).checkOrderStatus(code);
return respDto;
}
}
package com.liquidnet.service.dragon.channel.strategy.impl;
import com.alibaba.fastjson.JSON;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.biz.DragonServiceCommonBiz;
import com.liquidnet.service.dragon.channel.alipay.constant.AlipayConstant;
import com.liquidnet.service.dragon.channel.strategy.annotation.StrategyPayChannelHandler;
import com.liquidnet.service.dragon.channel.strategy.biz.DragonPayBiz;
import com.liquidnet.service.dragon.channel.unionpay.biz.UnionpayBiz;
import com.liquidnet.service.dragon.channel.unionpay.constant.UnionpayConstant;
import com.liquidnet.service.dragon.channel.unionpay.sdk.AcpService;
import com.liquidnet.service.dragon.channel.unionpay.sdk.SDKConstants;
import com.liquidnet.service.dragon.channel.unionpay.strategy.UnionpayStrategyContext;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.constant.DragonErrorCodeEnum;
import com.liquidnet.service.dragon.dto.DragonOrdersDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
import com.liquidnet.service.dragon.service.impl.DragonOrderRefundsServiceImpl;
import com.liquidnet.service.dragon.utils.DataUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: PayChannelStrategyUnionpayImpl
* @Package com.liquidnet.service.dragon.channel.strategy.impl
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/11/08 18:06
*/
@Slf4j
@Component
@StrategyPayChannelHandler(DragonConstant.PayChannelEnum.UNIONPAY)
public class PayChannelStrategyUnionpayImpl extends AbstractPayChannelStrategyImpl {
@Autowired
private UnionpayStrategyContext unionpayStrategyContext;
@Autowired
private DataUtils dataUtils;
@Autowired
private UnionpayBiz unionpayBiz;
@Autowired
private DragonPayBiz dragonPayBiz;
@Autowired
private DragonServiceCommonBiz dragonServiceCommonBiz;
@Autowired
private DragonOrderRefundsServiceImpl dragonOrderRefundsService;
@Autowired
private AcpService acpService;
@Override
public ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto) {
return unionpayStrategyContext.getStrategy(dragonPayBaseReqDto.getDeviceFrom()).dragonPay(dragonPayBaseReqDto);
}
@Override
public String dragonNotify(HttpServletRequest request,String payType,String deviceFrom) {
log.info("unionpay-->notify-->begin payType:{} deviceFrom:{}",payType,deviceFrom);
try {
String encoding = request.getParameter(SDKConstants.param_encoding);
Map<String , String> notifyMap = unionpayBiz.parseNotifyMsg(request);
log.info("dragonNotify-->unionpay json : {}", JSON.toJSONString(notifyMap));
log.info("接收到{}支付结果{}", payType, notifyMap);
//商户订单号
String code =notifyMap.get("orderId"); //获取后台通知的数据
//持久化通知记录
dragonServiceCommonBiz.createDragonOrderLogs(code,dragonPayBiz.getPaymentType(payType,deviceFrom),JSON.toJSONString(notifyMap));
// 根据银行订单号获取支付信息
DragonOrdersDto dragonOrdersDto = dataUtils.getPayOrderByCode(code);
if (dragonOrdersDto == null) {
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_ERROR_NOT_EXISTS.getCode(),DragonErrorCodeEnum.TRADE_ERROR_NOT_EXISTS.getMessage());
}
if (DragonConstant.PayStatusEnum.STATUS_PAID.getCode().equals(dragonOrdersDto.getStatus())) {
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_ERROR_HAS_PAID.getCode(),DragonErrorCodeEnum.TRADE_ERROR_HAS_PAID.getMessage());
}
boolean notifyResult = false;
//1、验证签名
if (acpService.validate(notifyMap, encoding)) {
//判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。
//因发现00 是成功 a6为有缺陷的成功,所以如果是a6则要再查一下
boolean result=false;
if(notifyMap.get("respCode").equals("A6")){
//此处需要发起查询接口,要看下最终状态,等查询接口完毕后再写
result=true;
}else if (notifyMap.get("respCode").equals("00")){
result =true;
}else{
result =false;
}
if(result){
notifyResult = this.completeSuccessOrder(dragonOrdersDto, notifyMap.get("queryId"), LocalDateTime.now(), notifyMap.toString());
}else{
notifyResult = this.completeFailOrder(dragonOrdersDto, notifyMap.toString());
}
}else{
log.error("unionPay notify fail code:{} msg:{} ",DragonErrorCodeEnum.TRADE_UNIONPAY_SIGN_ERROR.getCode(),DragonErrorCodeEnum.TRADE_UNIONPAY_SIGN_ERROR.getMessage());
}
}catch (Exception e){
e.printStackTrace();
}
return "ok";
}
@Override
public DragonPayOrderQueryRespDto checkOrderStatus(String code) {
// 查看是哪个deviceForm 的支付
DragonOrdersDto ordersDto = dataUtils.getPayOrderByCode(code);
DragonPayOrderQueryRespDto respDto = unionpayStrategyContext.getStrategy(DragonConstant.PayTypeEnum.getEnumByCode(ordersDto.getPaymentType()).getDeviceFrom()).checkOrderStatus(code);
/* if(null==ordersDto){
throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_UNIONPAY_QUERY_ERROR.getCode(),DragonErrorCodeEnum.TRADE_UNIONPAY_QUERY_ERROR.getMessage());
}
DragonPayOrderQueryRespDto respDto = dragonPayBiz.buildPayOrderQueryRespDto(ordersDto);
*/
return respDto;
}
}
package com.liquidnet.service.dragon.channel.unionpay.constant;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: UnionpayConstant
* @Package com.liquidnet.service.dragon.channel.unionpay.constant
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/11/8 18:12
*/
public class UnionpayConstant {
//默认配置的是UTF-8
public static String encoding = "UTF-8";
public enum UnionTradeStateEnum {
TRADE_CLOSED ("TRADE_CLOSED","交易关闭"),
TRADE_FINISHED ("TRADE_FINISHED","支付完成"),
TRADE_DEFECTIVENESS_SUCCESS ("A6","有缺陷的成功"),
TRADE_SUCCESS ("00","支付成功"),
WAIT_BUYER_PAY ("WAIT_BUYER_PAY","交易创建"),
FAIL("01","支付失败");
private String code;
private String message;
UnionTradeStateEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
}
}
package com.liquidnet.service.dragon.channel.unionpay.req;
import lombok.Data;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: UnionpayBaseReq
* @Package com.liquidnet.service.dragon.channel.unionpay.req
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/11/10 11:20
*/
@Data
public class UnionpayBaseReq {
/***银联全渠道系统,产品参数***/
private String version;
private String encoding;
private String signMethod;
private String txnType;
private String txnSubType;
private String bizType;
private String channelType;
/***商户接入参数***/
private String merId;
private String accessType;
private String orderId;
private String txnTime;
private String txnAmt;
private String currencyCode;
private String backUrl;
/***app支付接入***/
private String accType; //
/***wap支付接入***/
private String riskRateInfo;
private String frontUrl;
private String payTimeout;
}
package com.liquidnet.service.dragon.channel.unionpay.req;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import java.io.Serializable;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: UnionpayTradePayReq
* @Package com.liquidnet.service.dragon.channel.unionpay.req
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/7/9 17:50
*/
@Data
public class UnionpayTradePayReq extends UnionpayBaseReq implements Serializable, Cloneable{
private static final long serialVersionUID = -5827961038383330701L;
@Override
public String toString(){
return JSON.toJSONString(this);
}
private static final UnionpayTradePayReq obj = new UnionpayTradePayReq();
public static UnionpayTradePayReq getNew() {
try {
return (UnionpayTradePayReq) obj.clone();
} catch (CloneNotSupportedException e) {
return new UnionpayTradePayReq();
}
}
}
package com.liquidnet.service.dragon.channel.unionpay.sdk;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.security.PublicKey;
import java.util.Map;
/**
* @ClassName Acp6Service
* @Description 全渠道6.0接口服务类,接入商户集成请可以直接参考使用本类中的方法
* @date 2020/03
*/
@Slf4j
public class Acp6Service {
@Autowired
private SDKConfig sdkConfig;
@Autowired
private CertUtil certUtil;
@Autowired
private SDKUtil sdkUtil;
/**
* 请求报文签名(使用配置文件中配置的私钥证书或者对称密钥签名)<br>
* 功能:对请求报文进行签名,并计算赋值certid,signature字段并返回<br>
* @param reqData 请求报文map<br>
* @param encoding 上送请求报文域encoding字段的值<br>
* @return 签名后的map对象<br>
*/
public Map<String, String> sign(Map<String, String> reqData,String encoding) {
return signByCertInfo(reqData, sdkConfig.getSignCertPath(), sdkConfig.getSignCertPwd(), encoding);
}
/**
* 多证书签名(通过传入私钥证书路径和密码签名)<br>
* 功能:如果有多个商户号接入银联,每个商户号对应不同的证书可以使用此方法:传入私钥证书和密码(并且在acp_sdk.properties中 配置 acpsdk.singleMode=false)<br>
* @param reqData 请求报文map<br>
* @param certPath 签名私钥文件(带路径)<br>
* @param certPwd 签名私钥密码<br>
* @param encoding 上送请求报文域encoding字段的值<br>
* @return 签名后的map对象<br>
*/
public Map<String, String> signByCertInfo(Map<String, String> reqData, String certPath,
String certPwd, String encoding) {
Map<String, String> data = SDKUtil.filterBlank(reqData);
if (SDKUtil.isEmpty(encoding)) {
encoding = "UTF-8";
}
if (SDKUtil.isEmpty(certPath) || SDKUtil.isEmpty(certPwd)) {
log.error("CertPath or CertPwd is empty");
return data;
}
try {
data.put(SDKConstants.param_certId, certUtil.getCertIdByKeyStoreMap(certPath, certPwd));
data.put(SDKConstants.param_signature, sdkUtil.signRsa2(data, certPath, certPwd, encoding));
return data;
} catch (Exception e) {
log.error("Sign Error", e);
return data;
}
}
/**
* 验证签名<br>
* @param data 返回报文数据<br>
* @param encoding 上送请求报文域encoding字段的值<br>
* @return true 通过 false 未通过<br>
*/
public boolean validate(Map<String, String> data, String encoding) {
log.info("验签处理开始");
if (SDKUtil.isEmpty(encoding)) {
encoding = "UTF-8";
}
String certId = data.get(SDKConstants.param_certId);
log.info("对返回报文串验签使用的验签公钥序列号:[" + certId + "]");
PublicKey verifyKey = certUtil.getValidatePublicKey(certId);
if(verifyKey == null) {
log.error("未找到此序列号证书。");
return false;
}
try {
boolean result = SDKUtil.verifyRsa2(data, verifyKey, encoding);
log.info("验签" + (result ? "成功" : "失败") + "。");
return result;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 获取应答报文中的加密公钥证书,并存储到本地,备份原始证书,并自动替换证书<br>
* 更新成功则返回1,无更新返回0,失败异常返回-1<br>
* @return
*/
public int updateEncryptCert(String strCert, String certType) {
return sdkUtil.updateEncryptCert(strCert, certType);
}
/**
* 密码加密并做base64<br>
* @param accNo 卡号<br>
* @param pin 密码<br>
* @param encoding<br>
* @return 加密的内容<br>
*/
public String encryptPin(String accNo, String pin, String encoding) {
byte[] pinblock = SecureUtil.pinblock(accNo, pin);
return Base64.encodeBase64String(SecureUtil.encrypt(certUtil.getPinEncryptCert().pubKey, pinblock));
}
// /**
// * 密码加密并做base64<br>
// * @param accNo 卡号<br>
// * @param pin 密码<br>
// * @param encoding<br>
// * @return 加密的内容<br>
// */
// public String encryptPin(String pin, String encoding) {
// byte[] pinblock = SecureUtil.pinblock(pin);
// return Base64.encodeBase64String(SecureUtil.encrypt(CertUtil.getPinEncryptCert().pubKey, pinblock));
// }
/**
* 敏感信息加密并做base64(卡号,手机号,cvn2,有效期)<br>
* @param data 送 phoneNo,cvn2,有效期<br>
* @param encoding<br>
* @return 加密的密文<br>
*/
public String encryptData(String data, String encoding) {
return this.encryptData(data, encoding);
}
/**
* @param data 明文<br>
* @return 加密的密文<br>
*/
public String encryptData(byte[] data) {
try {
return Base64.encodeBase64String(SecureUtil.encrypt(certUtil.getEncryptCert().pubKey, data));
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
/**
* @param data 明文<br>
* @return 加密的密文<br>
*/
public String tripleDesEncryptECBPKCS5Padding(byte[] key, byte[] data) {
try {
return Base64.encodeBase64String(SecureUtil.tripleDesEncryptECBPKCS5Padding(key, SecureUtil.rightPadZero(data, 8)));
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
/**
* 敏感信息解密,使用配置文件acp_sdk.properties解密<br>
* @param base64EncryptedInfo 加密信息<br>
* @param encoding<br>
* @return 解密后的明文<br>
*/
public String decryptData(String base64EncryptedInfo, String encoding) {
return this.decryptData(base64EncryptedInfo, encoding);
}
/**
* 敏感信息解密,通过传入的私钥解密<br>
* @param base64EncryptedInfo 加密信息<br>
* @param certPath 私钥文件(带全路径)<br>
* @param certPwd 私钥密码<br>
* @param encoding<br>
* @return
*/
public String decryptData(String base64EncryptedInfo, String certPath,
String certPwd, String encoding) {
return this.decryptData(base64EncryptedInfo, certPath, certPwd, encoding);
}
/**
* 获取敏感信息加密证书的物理序列号<br>
* @return
*/
public String getEncryptCertId(){
return certUtil.getEncryptCert().certId;
}
/**
* 获取敏感信息加密证书的物理序列号<br>
* @return
*/
public String getPinEncryptCertId(){
return certUtil.getPinEncryptCert().certId;
}
/**
* 功能:后台交易提交请求报文并接收同步应答报文<br>
* @param reqData 请求报文<br>
* @param reqUrl 请求地址<br>
* @param encoding<br>
* @return 应答http 200返回true ,其他false<br>
*/
public Map<String,String> post(Map<String, String> reqData, String reqUrl,String encoding) {
if(reqData == null || reqUrl == null) {
log.error("null input");
return null;
}
log.info("请求银联地址:" + reqUrl + ",请求参数:" + reqData.toString());
if(reqUrl.startsWith("https://") && !sdkConfig.isIfValidateRemoteCert()) {
reqUrl = "u" + reqUrl;
}
try{
byte[] respBytes = HttpsUtil.post(reqUrl, SDKUtil.createLinkString(reqData, false, true, encoding).getBytes(encoding));
if(respBytes == null) {
log.error("post失败");
return null;
}
Map<String,String> result = SDKUtil.parseQString(new String(respBytes, encoding), encoding);
log.info("应答参数:" + result);
return result;
} catch (Exception e) {
log.error("post失败:" + e.getMessage(), e);
return null;
}
}
/**
* 功能:后台交易提交请求报文并接收同步应答报文<br>
* @param reqData 请求报文<br>
* @param reqUrl 请求地址<br>
* @param encoding<br>
* @return 应答http 200返回true ,其他false<br>
*/
public String postNotice(Map<String, String> reqData, String reqUrl,String encoding) {
if(reqData == null || reqUrl == null) {
log.error("null input");
return null;
}
log.info("请求银联地址:" + reqUrl + ",请求参数:" + reqData.toString());
if(reqUrl.startsWith("https://") && !sdkConfig.isIfValidateRemoteCert()) {
reqUrl = "u" + reqUrl;
}
try{
byte[] respBytes = HttpsUtil.post(reqUrl, SDKUtil.createLinkString(reqData, false, true, encoding).getBytes(encoding));
if(respBytes == null) {
log.error("post失败");
return null;
}
String result = new String(respBytes, encoding);
log.info("应答体:" + result);
return result;
} catch (Exception e) {
log.error("post失败:" + e.getMessage(), e);
return null;
}
}
/**
* 对字符串做base64<br>
* @param rawStr<br>
* @param encoding<br>
* @return<br>
* @throws IOException
*/
public String base64Encode(String rawStr, String encoding){
return AcpService.base64Encode(rawStr, encoding);
}
/**
* 对字符串做base64<br>
* @param base64Str<br>
* @param encoding<br>
* @return<br>
* @throws IOException
*/
public String base64Decode(String base64Str, String encoding){
return AcpService.base64Decode(base64Str, encoding);
}
}
/**
*
* Licensed Property to China UnionPay Co., Ltd.
*
* (C) Copyright of China UnionPay Co., Ltd. 2010
* All Rights Reserved.
*
*
* Modification History:
* =============================================================================
* Author Date Description
* ------------ ---------- ---------------------------------------------------
* xshu 2014-05-28 MPI基本参数工具类
* =============================================================================
*/
package com.liquidnet.service.dragon.channel.unionpay.sdk;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.Properties;
/**
*
* @ClassName SDKConfig
* @Description acpsdk配置文件acp_sdk.properties配置信息类
* @date 2016-7-22 下午4:04:55
*/
@Slf4j
@Component
@ConfigurationProperties(prefix = "acpsdk")
@Data
public class SDKConfig {
/** 前台请求URL. */
private String frontTransUrl;
/** 后台请求URL. */
private String backTransUrl;
// 退款路径
private String refundUrl;
/** 二维码统一下单请求URL. */
private String orderRequestUrl;
/** 单笔查询 */
private String singleQueryUrl;
/** 批量查询 */
private String batchQueryUrl;
/** 批量交易 */
private String batchTransUrl;
/** 文件传输 */
private String fileTransUrl;
/** 签名证书路径. */
private String signCertPath;
/** 签名证书密码. */
private String signCertPwd;
/** 签名证书类型. */
private String signCertType;
/** 加密公钥证书路径. */
private String encryptCertPath;
/** 验证签名公钥证书目录. */
private String validateCertDir;
/** 按照商户代码读取指定签名证书目录. */
private String signCertDir;
// /** 磁道加密证书路径. */
// private String encryptTrackCertPath;
/** 磁道加密公钥模数. */
private String encryptTrackKeyModulus;
/** 磁道加密公钥指数. */
private String encryptTrackKeyExponent;
/** 6.0.0统一支付产品加密pin公钥证书路径. */
private String pinEncryptCertPath;
/** 有卡交易. */
private String cardRequestUrl;
/** app交易 */
private String appTransUrl;
/** 证书使用模式(单证书/多证书) */
private String singleMode;
/** 安全密钥(SHA256和SM3计算时使用) */
private String secureKey;
/** 中级证书路径 */
private String middleCertPath;
/** 根证书路径 */
private String rootCertPath;
/** 是否验证验签证书CN,除了false都验 */
private boolean ifValidateCNName = true;
/** 是否验证https证书,默认都不验 */
private boolean ifValidateRemoteCert = false;
/** signMethod,没配按01吧 */
private String signMethod = "01";
/** version,没配按5.0.0 */
private String version = "5.0.0";
/** frontUrl */
private String frontUrl;
/** backUrl */
private String backUrl;
/** frontFailUrl */
private String frontFailUrl;
/*缴费相关地址*/
private String jfFrontRequestUrl;
private String jfBackRequestUrl;
private String jfSingleQueryUrl;
private String jfCardRequestUrl;
private String jfAppRequestUrl;
//二维码
private String qrcBackTransUrl;
private String qrcB2cIssBackTransUrl;
private String qrcB2cMerBackTransUrl;
private String qrcB2cMerBackSynTransUrl;
//综合认证
private String zhrzFrontRequestUrl;
private String zhrzBackRequestUrl;
private String zhrzSingleQueryUrl;
private String zhrzCardRequestUrl;
private String zhrzAppRequestUrl;
private String zhrzFaceRequestUrl;
/** acp6 */
private String transUrl;
/** 配置文件中的前台URL常量. */
public static final String SDK_FRONT_URL = "acpsdk.frontTransUrl";
/** 配置文件中的后台URL常量. */
public static final String SDK_BACK_URL = "acpsdk.backTransUrl";
/** 配置文件中的统一下单URL常量. */
public static final String SDK_ORDER_URL = "acpsdk.orderTransUrl";
/** 配置文件中的单笔交易查询URL常量. */
public static final String SDK_SIGNQ_URL = "acpsdk.singleQueryUrl";
/** 配置文件中的批量交易查询URL常量. */
public static final String SDK_BATQ_URL = "acpsdk.batchQueryUrl";
/** 配置文件中的批量交易URL常量. */
public static final String SDK_BATTRANS_URL = "acpsdk.batchTransUrl";
/** 配置文件中的文件类交易URL常量. */
public static final String SDK_FILETRANS_URL = "acpsdk.fileTransUrl";
/** 配置文件中的有卡交易URL常量. */
public static final String SDK_CARD_URL = "acpsdk.cardTransUrl";
/** 配置文件中的app交易URL常量. */
public static final String SDK_APP_URL = "acpsdk.appTransUrl";
/** 以下缴费产品使用,其余产品用不到,无视即可 */
// 前台请求地址
public static final String JF_SDK_FRONT_TRANS_URL= "acpsdk.jfFrontTransUrl";
// 后台请求地址
public static final String JF_SDK_BACK_TRANS_URL="acpsdk.jfBackTransUrl";
// 单笔查询请求地址
public static final String JF_SDK_SINGLE_QUERY_URL="acpsdk.jfSingleQueryUrl";
// 有卡交易地址
public static final String JF_SDK_CARD_TRANS_URL="acpsdk.jfCardTransUrl";
// App交易地址
public static final String JF_SDK_APP_TRANS_URL="acpsdk.jfAppTransUrl";
// 人到人
public static final String QRC_BACK_TRANS_URL="acpsdk.qrcBackTransUrl";
// 人到人
public static final String QRC_B2C_ISS_BACK_TRANS_URL="acpsdk.qrcB2cIssBackTransUrl";
// 人到人
public static final String QRC_B2C_MER_BACK_TRANS_URL="acpsdk.qrcB2cMerBackTransUrl";
public static final String QRC_B2C_MER_BACK_SYN_TRANS_URL="acpsdk.qrcB2cMerBackSynTransUrl";
/** 以下综合认证产品使用,其余产品用不到,无视即可 */
// 前台请求地址
public static final String ZHRZ_SDK_FRONT_TRANS_URL= "acpsdk.zhrzFrontTransUrl";
// 后台请求地址
public static final String ZHRZ_SDK_BACK_TRANS_URL="acpsdk.zhrzBackTransUrl";
// 单笔查询请求地址
public static final String ZHRZ_SDK_SINGLE_QUERY_URL="acpsdk.zhrzSingleQueryUrl";
// 有卡交易地址
public static final String ZHRZ_SDK_CARD_TRANS_URL="acpsdk.zhrzCardTransUrl";
// App交易地址
public static final String ZHRZ_SDK_APP_TRANS_URL="acpsdk.zhrzAppTransUrl";
// 图片识别交易地址
public static final String ZHRZ_SDK_FACE_TRANS_URL="acpsdk.zhrzFaceTransUrl";
// acp6
public static final String TRANS_URL="acpsdk.transUrl";
/** 配置文件中签名证书路径常量. */
public static final String SDK_SIGNCERT_PATH = "acpsdk.signCert.path";
/** 配置文件中签名证书密码常量. */
public static final String SDK_SIGNCERT_PWD = "acpsdk.signCert.pwd";
/** 配置文件中签名证书类型常量. */
public static final String SDK_SIGNCERT_TYPE = "acpsdk.signCert.type";
/** 配置文件中加密证书路径常量. */
public static final String SDK_ENCRYPTCERT_PATH = "acpsdk.encryptCert.path";
// /** 配置文件中磁道加密证书路径常量. */
// public static final String SDK_ENCRYPTTRACKCERT_PATH = "acpsdk.encryptTrackCert.path";
/** 配置文件中5.0.0有卡产品磁道加密公钥模数常量. */
public static final String SDK_ENCRYPTTRACKKEY_MODULUS = "acpsdk.encryptTrackKey.modulus";
/** 配置文件中5.0.0有卡产品磁道加密公钥指数常量. */
public static final String SDK_ENCRYPTTRACKKEY_EXPONENT = "acpsdk.encryptTrackKey.exponent";
/** 配置文件中验证签名证书目录常量. */
public static final String SDK_VALIDATECERT_DIR = "acpsdk.validateCert.dir";
/** 配置文件中6.0.0统一支付产品加密pin证书路径常量. */
public static final String SDK_PINENCRYPTCERT_PATH = "acpsdk.pinEncryptCert.path";
/** 配置文件中是否加密cvn2常量. */
public static final String SDK_CVN_ENC = "acpsdk.cvn2.enc";
/** 配置文件中是否加密cvn2有效期常量. */
public static final String SDK_DATE_ENC = "acpsdk.date.enc";
/** 配置文件中是否加密卡号常量. */
public static final String SDK_PAN_ENC = "acpsdk.pan.enc";
/** 配置文件中证书使用模式 */
public static final String SDK_SINGLEMODE = "acpsdk.singleMode";
/** 配置文件中安全密钥 */
public static final String SDK_SECURITYKEY = "acpsdk.secureKey";
/** 配置文件中根证书路径常量 */
public static final String SDK_ROOTCERT_PATH = "acpsdk.rootCert.path";
/** 配置文件中根证书路径常量 */
public static final String SDK_MIDDLECERT_PATH = "acpsdk.middleCert.path";
/** 配置是否需要验证验签证书CN,除了false之外的值都当true处理 */
public static final String SDK_IF_VALIDATE_CN_NAME = "acpsdk.ifValidateCNName";
/** 配置是否需要验证https证书,除了true之外的值都当false处理 */
public static final String SDK_IF_VALIDATE_REMOTE_CERT = "acpsdk.ifValidateRemoteCert";
/** signmethod */
public static final String SDK_SIGN_METHOD ="acpsdk.signMethod";
/** version */
public static final String SDK_VERSION = "acpsdk.version";
/** 后台通知地址 */
public static final String SDK_BACKURL = "acpsdk.backUrl";
/** 前台通知地址 */
public static final String SDK_FRONTURL = "acpsdk.frontUrl";
/** 前台失败通知地址 */
public static final String SDK_FRONT_FAIL_URL = "acpsdk.frontFailUrl";
}
【哪个sdk新就用哪个哦】【不完全向下兼容注意】
2020/9/29:
增加应答只需要关心200的post。
2020/6/23:
规范大改了,请参考最新规范进行修改。
1. 应答新增returnMsg,调整了应答码和交易状态相关字段。具体的值见规范。
目前使用的:
1)returnCode:代表此次交易请求的业务结果,查询交易表示查询操作的业务结果,具体交易结果,以交易应答码、交易状态码为准。
2)respCode:交易结果应答码。
3)xxxStatus:各类交易的状态
① transferStatus-转账状态,仅转账交易出现
② billStatus-账单状态,仅缴费交易用
③ entryStatus-入账状态,入账状态查询用
④ transStatus-消费/预授权交易的状态,仅消费和预授权查询和通知用
已删除的:resultCode、transCode、transMsg。
2. 应答新增merTransIndex,查询接口会原样应答,但目前并没有往发卡或者二维码的付款方送,大概没别的作用。
3. 应答新增preAuthId,没什么用,如果需要收单手工帮你处理预授权进行撤销或完成时可用提供他们,可方便他们处理。卡号+商户号+preAuthId在预授权超时或结束(完成或撤销)前是唯一的。
4. 新增respCode、transStatus取值TRANS_PRE_AUTH_COMPLETED,表示已被预授权完成。
5. 查询应答新增transStatus字段表示被查询的原交易的状态。
6. respCode和respMsg下沉到bizContent中.
7. traceNo和traceTime替换成清算主键settleKey,settleKey在收单和发卡的清算文件内是唯一的,可用于和收单对账,以及找银联和发卡查交易。
8. merCertId、cupCertId改为certId。
9. accessId:填写商户号。
10. accessType填写0。
11. 订单号、交易时间、商户代码从公共参数下沉到bizContent中。
12. 增加入账状态状态查询接口。
13. 转账交易termId从必填M改成可选O。
14. 两方转账也返回transferStatus。
2020/4/29:
6.0接口地址修正最终版,注意获取地址方式改getTransUrl,配置文件增加acpsdk.transUrl=https://gateway.test.95516.com/api/trans.do。
2020/4/4:
不完全向下兼容,注意对应修改,修改后的样例可参考assets/sdk测试类.
修改后:
全渠道5.0、5.1用AcpService。
全渠道6.0用Acp6Service。
二维码用QrcService。。
LogUtil删除,请改成直接调log4j或slf4j打印。
原二维码DemoBase中:
DemoBase.getAddnCond->QrcService.getKVBase64Field
DemoBase.formInfoBase64->QrcService.getKVBase64Field
DemoBase.getPayeeInfo->QrcService.getKVBase64Field
DemoBase.getPayeeInfoWithEncrpyt->QrcService.getKVEncBase64Field
DemoBase.getPayerInfo->QrcService.getKVBase64Field
DemoBase.getPayerInfoWithEncrpyt->QrcService.getKVEncBase64Field
\ No newline at end of file
package com.liquidnet.service.dragon.channel.unionpay.strategy;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: Test
* @Package com.liquidnet.service.dragon.channel.strategy
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/7/10 14:27
*/
public interface IUnionpayStrategy {
ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto);
DragonPayOrderQueryRespDto checkOrderStatus(String code);
}
package com.liquidnet.service.dragon.channel.unionpay.strategy;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: Test
* @Package com.liquidnet.service.dragon.channel.strategy
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/7/10 14:27
*/
@Component
public class UnionpayStrategyContext {
private final Map<String, IUnionpayStrategy> handlerMap = new HashMap<>();
public IUnionpayStrategy getStrategy(String type) {
return handlerMap.get(type);
}
public void putStrategy(String code, IUnionpayStrategy strategy) {
handlerMap.put(code, strategy);
}
}
package com.liquidnet.service.dragon.channel.unionpay.strategy;
import com.liquidnet.service.dragon.channel.unionpay.strategy.annotation.StrategyUnionpayHandler;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: Test
* @Package com.liquidnet.service.dragon.channel.strategy
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/7/10 14:27
*/
@Component
public class UnionpayStrategyListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
Map<String, Object> beans = event.getApplicationContext().getBeansWithAnnotation(StrategyUnionpayHandler.class);
UnionpayStrategyContext strategyContext = event.getApplicationContext().getBean(UnionpayStrategyContext.class);
beans.forEach((name, bean) -> {
StrategyUnionpayHandler typeHandler = bean.getClass().getAnnotation(StrategyUnionpayHandler.class);
strategyContext.putStrategy(typeHandler.value().getCode(), (IUnionpayStrategy) bean);
});
}
}
\ No newline at end of file
......@@ -133,6 +133,7 @@ public abstract class AbstractWepayStrategy implements IWepayStrategy {
DragonPayBaseRespDto respDto = new DragonPayBaseRespDto();
respDto.setCode(dragonPayBaseReqDto.getCode());
respDto.setOrderCode(dragonPayBaseReqDto.getOrderCode());
respDto.setPayType(dragonPayBaseReqDto.getPayType());
DragonPayBaseRespDto.PayData payData = new DragonPayBaseRespDto.PayData();
payData.setAppId(respWepayDto.getAppid());
payData.setNonceStr(nonceStr);
......
......@@ -91,6 +91,7 @@ public abstract class AbstractAlipayStrategy implements IAlipayStrategy {
*/
protected DragonPayBaseRespDto buildCommonRespDto(DragonPayBaseReqDto dragonPayBaseReqDto){
DragonPayBaseRespDto respDto = new DragonPayBaseRespDto();
respDto.setPayType(dragonPayBaseReqDto.getPayType());
respDto.setCode(dragonPayBaseReqDto.getCode());
respDto.setOrderCode(dragonPayBaseReqDto.getOrderCode());
DragonPayBaseRespDto.PayData payData = new DragonPayBaseRespDto.PayData();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment