Skip to content

Commit 94208bb

Browse files
committed
修改union的customInfo放入方式
1 parent 9857967 commit 94208bb

File tree

7 files changed

+295
-340
lines changed

7 files changed

+295
-340
lines changed

Pay-Demo/.idea/workspace.xml

Lines changed: 122 additions & 252 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Pay-Demo/src/main/java/cn/mrdear/pay/alipay/AliPayConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public final class AliPayConfig {
5050
* 成功标识
5151
*/
5252
public static final String SUCCESS_REQUEST = "TRADE_SUCCESS";
53+
/**
54+
* 交易关闭回调(当该笔订单全部退款完毕,则交易关闭)
55+
*/
56+
public static final String TRADE_CLOSED = "TRADE_CLOSED";
5357
/**
5458
* 支付宝请求客户端入口
5559
*/

Pay-Demo/src/main/java/cn/mrdear/pay/alipay/AlipayTrade.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ public boolean tradeRefundRequest(Map<String, ?> sParaTemp) throws AlipayApiExce
7373
public boolean verifyNotify(HttpServletRequest request) throws AlipayApiException {
7474
Map<String,String> paranMap = SignUtil.request2Map(request);
7575
logger.debug("支付宝回调参数:"+paranMap.toString());
76-
//"TRADE_CLOSED".equals(paranMap.get("trade_status"),交易关闭不验签
7776
boolean isVerify = false;
78-
if (AliPayConfig.SUCCESS_REQUEST.equals(paranMap.get("trade_status"))) {
77+
if (AliPayConfig.SUCCESS_REQUEST.equals(paranMap.get("trade_status")) || AliPayConfig.TRADE_CLOSED.equals(paranMap.get("trade_status"))) {
7978
isVerify = AlipaySignature.rsaCheckV1(paranMap, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.CHARSET); //调用SDK验证签名
8079
}
8180
logger.debug("支付宝验签结果"+isVerify);
Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package cn.mrdear.pay.unionpay;
22

33

4-
import org.apache.commons.lang3.StringUtils;
54
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
76

8-
import java.io.IOException;
9-
import java.text.SimpleDateFormat;
107
import java.util.Date;
118
import java.util.HashMap;
129
import java.util.Map;
1310

1411
import cn.mrdear.pay.unionpay.sdk.AcpService;
1512
import cn.mrdear.pay.unionpay.sdk.SDKConfig;
16-
import cn.mrdear.pay.unionpay.sdk.SecureUtil;
13+
import cn.mrdear.pay.util.DateUtil;
1714

1815
/**
1916
* @author Niu Li
@@ -37,25 +34,17 @@ public UnionPayClient(HashMap<String, String> commonMap) {
3734
* @param paramMap 要传送的参数
3835
* @return 生成的form表单
3936
*/
40-
public String tokenOpen(Map<String, String> paramMap){
37+
public String tokenOpen(Map<String, String> paramMap,Map<String, String> customerInfo){
4138
paramMap.putAll(commonMap);
42-
paramMap.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
39+
paramMap.put("txnTime", DateUtil.formatDate(new Date(),DateUtil.YMDHMS));
4340
paramMap.put("txnType", "79");
4441
paramMap.put("txnSubType", "00");
4542
paramMap.put("frontUrl", UnionPayConfig.FRONTURL);
4643
paramMap.put("backUrl", UnionPayConfig.TOKEN_BACKURL);
4744
paramMap.put("tokenPayData", UnionPayConfig.TOKENPAYDATA);
48-
try {
49-
if (paramMap.get("customerInfo") != null
50-
&& !StringUtils.isEmpty(paramMap.get("customerInfo"))) {
51-
paramMap.put("customerInfo", new String(
52-
SecureUtil.base64Encode(
53-
paramMap.get("customerInfo").getBytes(
54-
UnionPayConfig.ENCODING_UTF8))));
55-
}
56-
} catch (IOException e) {
57-
e.printStackTrace();
58-
}
45+
paramMap.put("customerInfo",AcpService.getCustomerInfo(customerInfo,paramMap.get("accNo"),UnionPayConfig.ENCODING_UTF8));
46+
//是否加密取决于商户是否开通了隐私加密权限
47+
// paramMap.put("customerInfo",AcpService.getCustomerInfoWithEncrypt(customerInfo,paramMap.get("accNo"),UnionPayConfig.ENCODING_UTF8));
5948
Map<String, String> reqData = AcpService.sign(paramMap,UnionPayConfig.ENCODING_UTF8); //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。
6049
String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl(); //获取请求银联的前台地址:对应属性文件acp_sdk.properties文件中的acpsdk.frontTransUrl
6150
String html = AcpService.createAutoFormHtml(requestFrontUrl,reqData,UnionPayConfig.ENCODING_UTF8); //生成自动跳转的Html表单
@@ -68,21 +57,13 @@ public String tokenOpen(Map<String, String> paramMap){
6857
* @param paramMap 要传送的参数
6958
* @return 请求返回的结果
7059
*/
71-
public Map<String, String> msgSend(Map<String, String> paramMap){
60+
public Map<String, String> msgSend(Map<String, String> paramMap,Map<String, String> customerInfo){
7261
paramMap.putAll(commonMap);
7362
paramMap.put("txnType", "77");
74-
paramMap.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
75-
try {
76-
if (paramMap.get("customerInfo") != null
77-
&& !StringUtils.isEmpty(paramMap.get("customerInfo"))) {
78-
paramMap.put("customerInfo", new String(
79-
SecureUtil.base64Encode(
80-
paramMap.get("customerInfo").getBytes(
81-
UnionPayConfig.ENCODING_UTF8))));
82-
}
83-
} catch (IOException e) {
84-
e.printStackTrace();
85-
}
63+
paramMap.put("txnTime", DateUtil.formatDate(new Date(),DateUtil.YMDHMS));
64+
paramMap.put("customerInfo",AcpService.getCustomerInfo(customerInfo,paramMap.get("accNo"),UnionPayConfig.ENCODING_UTF8));
65+
//是否加密取决于商户是否开通了隐私加密权限
66+
// paramMap.put("customerInfo",AcpService.getCustomerInfoWithEncrypt(customerInfo,paramMap.get("accNo"),UnionPayConfig.ENCODING_UTF8));
8667
Map<String, String> reqData = AcpService.sign(paramMap,UnionPayConfig.ENCODING_UTF8); //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。
8768
String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl(); //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的 acpsdk.backTransUrl
8869
Map<String, String> rspData = AcpService.post(reqData,requestBackUrl,UnionPayConfig.ENCODING_UTF8);
@@ -95,24 +76,16 @@ public Map<String, String> msgSend(Map<String, String> paramMap){
9576
* @param paramMap 需要传送的参数
9677
* @return 请求结果,消费结果返回异步通知
9778
*/
98-
public Map<String,String> consume(Map<String, String> paramMap){
79+
public Map<String,String> consume(Map<String, String> paramMap,Map<String, String> customerInfo){
9980
paramMap.putAll(commonMap);
10081
paramMap.put("txnType", "01");
10182
paramMap.put("frontUrl", UnionPayConfig.FRONTURL);
10283
paramMap.put("backUrl", UnionPayConfig.CONSUME_BACKURL);
10384
paramMap.put("customerIp", "127.0.0.1");
104-
paramMap.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
105-
try {
106-
if (paramMap.get("customerInfo") != null
107-
&& !StringUtils.isEmpty(paramMap.get("customerInfo"))) {
108-
paramMap.put("customerInfo", new String(
109-
SecureUtil.base64Encode(
110-
paramMap.get("customerInfo").getBytes(
111-
UnionPayConfig.ENCODING_UTF8))));
112-
}
113-
} catch (IOException e) {
114-
e.printStackTrace();
115-
}
85+
paramMap.put("txnTime", DateUtil.formatDate(new Date(),DateUtil.YMDHMS));
86+
paramMap.put("customerInfo",AcpService.getCustomerInfo(customerInfo,paramMap.get("accNo"),UnionPayConfig.ENCODING_UTF8));
87+
//是否加密取决于商户是否开通了隐私加密权限
88+
// paramMap.put("customerInfo",AcpService.getCustomerInfoWithEncrypt(customerInfo,paramMap.get("accNo"),UnionPayConfig.ENCODING_UTF8));
11689
Map<String, String> reqData = AcpService.sign(paramMap,UnionPayConfig.ENCODING_UTF8); //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。
11790
String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl(); //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的 acpsdk.backTransUrl
11891
Map<String, String> rspData = AcpService.post(reqData,requestBackUrl,UnionPayConfig.ENCODING_UTF8); //发送请求报文并接受同步应答(默认连接超时时间30秒,读取返回结果超时时间30秒);这里调用signData之后,调用submitUrl之前不能对submitFromData中的键值对做任何修改,如果修改会导致验签不通过
@@ -131,20 +104,11 @@ public Map<String,String> refund(Map<String, String> paramMap){
131104
paramMap.put("txnSubType", "00");
132105
paramMap.put("frontUrl", UnionPayConfig.FRONTURL);
133106
paramMap.put("backUrl", UnionPayConfig.REFUND_BACKURL);
134-
paramMap.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
107+
paramMap.put("txnTime", DateUtil.formatDate(new Date(),DateUtil.YMDHMS));
135108
Map<String, String> reqData = AcpService.sign(paramMap,UnionPayConfig.ENCODING_UTF8);
136109
String url = SDKConfig.getConfig().getBackRequestUrl();
137110
Map<String, String> rspData = AcpService.post(reqData, url,UnionPayConfig.ENCODING_UTF8);
138111
logger.debug("银行卡退款结果:"+rspData.toString());
139112
return rspData;
140113
}
141-
142-
143-
/**
144-
* 获取当前消费时间
145-
* @return yyyyMMddHHmmss格式时间
146-
*/
147-
public static String getCurrentTime() {
148-
return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
149-
}
150114
}

Pay-Demo/src/main/java/cn/mrdear/pay/unionpay/UnionPayTrade.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,26 @@ public class UnionPayTrade {
2525
* @param paramMap 请求参数
2626
* @return 请求返回结果
2727
*/
28-
public String tokenOpen(Map<String, String> paramMap){
29-
return UnionPayConfig.getInstance().tokenOpen(paramMap);
28+
public String tokenOpen(Map<String, String> paramMap,Map<String, String> customerInfo){
29+
return UnionPayConfig.getInstance().tokenOpen(paramMap,customerInfo);
3030
}
3131

3232
/**
3333
* 发送短信
3434
* @param paramMap 请求参数
3535
* @return 返回结果
3636
*/
37-
public Map<String,String> msg(Map<String, String> paramMap){
38-
return UnionPayConfig.getInstance().msgSend(paramMap);
37+
public Map<String,String> msg(Map<String, String> paramMap,Map<String, String> customerInfo){
38+
return UnionPayConfig.getInstance().msgSend(paramMap,customerInfo);
3939
}
4040

4141
/**
4242
* 消费
4343
* @param paramMap 请求参数
4444
* @return 请求结果
4545
*/
46-
public Map<String,String> consume(Map<String, String> paramMap){
47-
return UnionPayConfig.getInstance().consume(paramMap);
46+
public Map<String,String> consume(Map<String, String> paramMap,Map<String, String> customerInfo){
47+
return UnionPayConfig.getInstance().consume(paramMap,customerInfo);
4848
}
4949

5050
/**
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package cn.mrdear.pay.util;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import java.text.ParseException;
7+
import java.text.SimpleDateFormat;
8+
import java.util.Calendar;
9+
import java.util.Date;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
/**
14+
* 日期工具类(使用了ThreadLocal获取SimpleDateFormat,其他方法可以直接拷贝common-lang)
15+
* @author Niu Li
16+
* @date 2016/11/19
17+
*/
18+
public class DateUtil {
19+
20+
private static Map<String,ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();
21+
22+
private static Logger logger = LoggerFactory.getLogger(DateUtil.class);
23+
24+
public final static String MDHMSS = "MMddHHmmssSSS";
25+
public final static String YMDHMS = "yyyyMMddHHmmss";
26+
public final static String YMDHMS_ = "yyyy-MM-dd HH:mm:ss";
27+
public final static String YMD = "yyyyMMdd";
28+
public final static String YMD_ = "yyyy-MM-dd";
29+
public final static String HMS = "HHmmss";
30+
31+
/**
32+
* 根据map中的key得到对应线程的sdf实例
33+
* @param pattern map中的key
34+
* @return 该实例
35+
*/
36+
private static SimpleDateFormat getSdf(final String pattern){
37+
ThreadLocal<SimpleDateFormat> sdfThread = sdfMap.get(pattern);
38+
if (sdfThread == null){
39+
//双重检验,防止sdfMap被多次put进去值
40+
synchronized (DateUtil.class){
41+
sdfThread = sdfMap.get(pattern);
42+
if (sdfThread == null){
43+
logger.debug("put new sdf of pattern " + pattern + " to map");
44+
sdfThread = new ThreadLocal<SimpleDateFormat>(){
45+
@Override
46+
protected SimpleDateFormat initialValue() {
47+
logger.debug("thread: " + Thread.currentThread() + " init pattern: " + pattern);
48+
return new SimpleDateFormat(pattern);
49+
}
50+
};
51+
sdfMap.put(pattern,sdfThread);
52+
}
53+
}
54+
}
55+
return sdfThread.get();
56+
}
57+
58+
/**
59+
* 按照指定pattern解析日期
60+
* @param date 要解析的date
61+
* @param pattern 指定格式
62+
* @return 解析后date实例
63+
*/
64+
public static Date parseDate(String date,String pattern){
65+
if(date == null) {
66+
throw new IllegalArgumentException("The date must not be null");
67+
}
68+
try {
69+
return getSdf(pattern).parse(date);
70+
} catch (ParseException e) {
71+
e.printStackTrace();
72+
logger.error("解析的格式不支持:"+pattern);
73+
}
74+
return null;
75+
}
76+
/**
77+
* 按照指定pattern格式化日期
78+
* @param date 要格式化的date
79+
* @param pattern 指定格式
80+
* @return 解析后格式
81+
*/
82+
public static String formatDate(Date date,String pattern){
83+
if (date == null){
84+
throw new IllegalArgumentException("The date must not be null");
85+
}else {
86+
return getSdf(pattern).format(date);
87+
}
88+
}
89+
90+
/**
91+
* 给指定时间添加指定期限
92+
* @param date 该时间
93+
* @param calendarField 要添加的日历上的字段 参考Calendar的静态常量
94+
* @param amount 添加期限
95+
* @return 完成后实例
96+
*/
97+
public static Date add(Date date, int calendarField, int amount) {
98+
if(date == null) {
99+
throw new IllegalArgumentException("The date must not be null");
100+
} else {
101+
Calendar c = Calendar.getInstance();
102+
c.setTime(date);
103+
c.add(calendarField, amount);
104+
return c.getTime();
105+
}
106+
}
107+
108+
109+
}

Pay-Demo/src/test/java/cn/mrdear/pay/unionpay/UnionPayTradeTest.java

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ public void loadSDK(){
2626
@Test
2727
public void testTokenOpen(){
2828
UnionPayTrade unionPayTrade = new UnionPayTrade();
29-
Map<String,String> customerInfoMap = new HashMap<String,String>();
30-
customerInfoMap.put("accNo", "6222021304008026228");
31-
customerInfoMap.put("customerInfo", "{}");
32-
customerInfoMap.put("orderId", System.currentTimeMillis()+"");
33-
unionPayTrade.tokenOpen(customerInfoMap);
29+
Map<String,String> paramMap = new HashMap<String,String>();
30+
paramMap.put("accNo", "6222021304008026228");
31+
Map<String,String> customerInfo = new HashMap<String,String>();
32+
customerInfo.put("certifTp", "01"); //证件类型
33+
customerInfo.put("certifId", "341126197709218366"); //证件号码
34+
customerInfo.put("customerNm", "全渠道"); //姓名
35+
customerInfo.put("phoneNo", "13552535506"); //手机号
36+
paramMap.put("orderId", System.currentTimeMillis()+"");
37+
unionPayTrade.tokenOpen(paramMap,customerInfo);
3438
}
3539

3640
/**
@@ -39,16 +43,20 @@ public void testTokenOpen(){
3943
@Test
4044
public void testSmsCode(){
4145
UnionPayTrade unionPayTrade = new UnionPayTrade();
42-
Map<String,String> customerInfoMap = new HashMap<String,String>();
43-
customerInfoMap.put("currencyCode", "156");
44-
customerInfoMap.put("txnAmt", "1");
45-
customerInfoMap.put("tokenPayData", "{token=6235240xxxx17620679&trId=62000000016&tokenLevel=40&tokenBegin=20161030154742&tokenEnd=20211029154742&tokenType=01}");
46-
customerInfoMap.put("customerInfo", "{}");
46+
Map<String,String> paramMap = new HashMap<String,String>();
47+
paramMap.put("currencyCode", "156");
48+
paramMap.put("txnAmt", "1");
49+
paramMap.put("tokenPayData", "{token=6235240xxxx17620679&trId=62000000016&tokenLevel=40&tokenBegin=20161030154742&tokenEnd=20211029154742&tokenType=01}");
50+
Map<String,String> customerInfo = new HashMap<String,String>();
51+
customerInfo.put("certifTp", "01"); //证件类型
52+
customerInfo.put("certifId", "341126197709218366"); //证件号码
53+
customerInfo.put("customerNm", "全渠道"); //姓名
54+
customerInfo.put("phoneNo", "13552535506"); //手机号
4755
String value = System.currentTimeMillis() + "";
4856
System.out.println(value);//商户订单
49-
customerInfoMap.put("orderId", value);
50-
customerInfoMap.put("txnSubType", "02");// 用于区分发送短信的类型:00——开通短信02——消费短信04——预授权451342
51-
unionPayTrade.msg(customerInfoMap);
57+
paramMap.put("orderId", value);
58+
paramMap.put("txnSubType", "02");// 用于区分发送短信的类型:00——开通短信02——消费短信04——预授权451342
59+
unionPayTrade.msg(paramMap,customerInfo);
5260
}
5361

5462
/**
@@ -57,24 +65,25 @@ public void testSmsCode(){
5765
@Test
5866
public void testConsume(){
5967
UnionPayTrade unionPayTrade = new UnionPayTrade();
60-
Map<String,String> customerInfoMap = new HashMap<String,String>();
61-
customerInfoMap.put("currencyCode", "156");
62-
customerInfoMap.put("txnAmt", "200");
63-
customerInfoMap.put("tokenPayData", "{token=6235xxxx000217620679&trId=62000000016&tokenLevel=40&tokenBegin=20161030154742&tokenEnd=20211029154742&tokenType=01}");
64-
customerInfoMap.put("customerInfo", "{smsCode=451342}");
65-
customerInfoMap.put("orderId", "1477903831526");
66-
customerInfoMap.put("txnSubType", "01");//01:自助消费,通过地址的方式区分前台消费和后台消费(含无跳转 支付)03:分期付款
67-
unionPayTrade.consume(customerInfoMap);
68+
Map<String,String> paramMap = new HashMap<String,String>();
69+
paramMap.put("currencyCode", "156");
70+
paramMap.put("txnAmt", "200");
71+
paramMap.put("tokenPayData", "{token=6235xxxx000217620679&trId=62000000016&tokenLevel=40&tokenBegin=20161030154742&tokenEnd=20211029154742&tokenType=01}");
72+
Map<String,String> customerInfo = new HashMap<String,String>();
73+
customerInfo.put("smsCode", "13552535506"); //手机号
74+
paramMap.put("orderId", "1477903831526");
75+
paramMap.put("txnSubType", "01");//01:自助消费,通过地址的方式区分前台消费和后台消费(含无跳转 支付)03:分期付款
76+
unionPayTrade.consume(paramMap,customerInfo);
6877
}
6978

7079
@Test
7180
public void testRefund(){
7281
UnionPayTrade unionPayTrade = new UnionPayTrade();
73-
Map<String, String> customerInfoMap = new HashMap<>();
74-
customerInfoMap.put("orderId",System.currentTimeMillis()+"");
75-
customerInfoMap.put("origQryId","201610312015598471058");
76-
customerInfoMap.put("txnAmt","112555");
77-
customerInfoMap.put("txnSubType", "00");
78-
unionPayTrade.refund(customerInfoMap);
82+
Map<String, String> paramMap = new HashMap<>();
83+
paramMap.put("orderId",System.currentTimeMillis()+"");
84+
paramMap.put("origQryId","201610312015598471058");
85+
paramMap.put("txnAmt","112555");
86+
paramMap.put("txnSubType", "00");
87+
unionPayTrade.refund(paramMap);
7988
}
8089
}

0 commit comments

Comments
 (0)