银联支付优化

This commit is contained in:
egzosn
2017-12-19 19:02:02 +08:00
parent 7b148a65ae
commit d88db792bc
10 changed files with 218 additions and 510 deletions

View File

@@ -220,40 +220,6 @@ public class AliPayService extends BasePayService {
/**
* 将请求参数或者请求流转化为 Map
* @param parameterMap 请求参数
* @param is 请求流
* @return 获得回调的请求参数
*/
@Override
public Map<String, Object> getParameter2Map(Map<String, String[]> parameterMap, InputStream is) {
Map<String, Object> params = new TreeMap<String, Object>();
for (Iterator iter = parameterMap.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = parameterMap.get(name);
String valueStr = "";
for (int i = 0,len = values.length; i < len; i++) {
valueStr += (i == len - 1) ? values[i] : values[i] + ",";
}
//乱码解决这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
if (!valueStr.matches("\\w+")){
try {
if(valueStr.equals(new String(valueStr.getBytes("iso8859-1"), "iso8859-1"))){
valueStr=new String(valueStr.getBytes("iso8859-1"), payConfigStorage.getInputCharset());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
params.put(name, valueStr);
}
return params;
}
/**
* 获取输出消息,用户返回给支付端
* @param code 状态

View File

@@ -4,7 +4,11 @@ import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.http.HttpRequestTemplate;
import com.egzosn.pay.common.util.sign.SignUtils;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
/**
* 支付基础服务
@@ -27,6 +31,7 @@ public abstract class BasePayService implements PayService {
* 设置支付配置
* @param payConfigStorage 支付配置
*/
@Override
public BasePayService setPayConfigStorage(PayConfigStorage payConfigStorage) {
this.payConfigStorage = payConfigStorage;
return this;
@@ -85,6 +90,37 @@ public abstract class BasePayService implements PayService {
return SignUtils.valueOf(payConfigStorage.getSignType()).sign(content, payConfigStorage.getKeyPrivate(),characterEncoding);
}
/**
* 将请求参数或者请求流转化为 Map
*
* @param parameterMap 请求参数
* @param is 请求流
* @return 获得回调的请求参数
*/
@Override
public Map<String, Object> getParameter2Map (Map<String, String[]> parameterMap, InputStream is) {
Map<String, Object> params = new TreeMap<String,Object>();
for (Iterator iter = parameterMap.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = parameterMap.get(name);
String valueStr = "";
for (int i = 0,len = values.length; i < len; i++) {
valueStr += (i == len - 1) ? values[i] : values[i] + ",";
}
if (!valueStr.matches("\\w+")){
try {
if(valueStr.equals(new String(valueStr.getBytes("iso8859-1"), "iso8859-1"))){
valueStr=new String(valueStr.getBytes("iso8859-1"), payConfigStorage.getInputCharset());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
params.put(name, valueStr);
}
return params;
}
}

View File

@@ -63,7 +63,7 @@ public interface PayService {
* 签名校验
*
* @param params 参数集
* @param sign 签名
* @param sign 签名原文
* @return 签名校验 true通过
*/
boolean signVerify(Map<String, Object> params, String sign);

View File

@@ -84,9 +84,10 @@ public class ApyAccountRepository {
ApyAccount apyAccount4 = new ApyAccount();
apyAccount4.setPayId(4);
apyAccount4.setPartner("777290058110048");
// apyAccount4.setAppid("777290058110097");
apyAccount4.setPublicKey("D:\\certs\\acp_test_middle.cer;D:\\certs\\acp_test_root.cer");
apyAccount4.setPrivateKey("D:\\certs\\acp_test_sign.pfx;000000");
//公钥,验签证书链格式: 中级证书路径;根证书路径
apyAccount4.setPublicKey("D:/certs/acp_test_middle.cer;D:/certs/acp_test_root.cer");
//私钥, 私钥证书格式: 私钥证书路径;私钥证书对应的密码
apyAccount4.setPrivateKey("D:/certs/acp_test_sign.pfx;000000");
apyAccount4.setNotifyUrl("http://b1234780541.eicp.net/payBack4.json");
// 无需同步回调可不填 app填这个就可以
apyAccount4.setReturnUrl("http://b1234780541.eicp.net/payBack4.json");

View File

@@ -11,7 +11,7 @@ import com.egzosn.pay.fuiou.api.FuiouPayService;
import com.egzosn.pay.fuiou.bean.FuiouTransactionType;
import com.egzosn.pay.union.api.UnionPayConfigStorage;
import com.egzosn.pay.union.api.UnionPayService;
import com.egzosn.pay.union.enums.UnionTransactionType;
import com.egzosn.pay.union.bean.UnionTransactionType;
import com.egzosn.pay.wx.api.WxPayConfigStorage;
import com.egzosn.pay.wx.api.WxPayService;
import com.egzosn.pay.wx.bean.WxTransactionType;

View File

@@ -17,9 +17,20 @@
<br>
应用id<input type="text" name="appid">
<br>
支付平台公钥(签名校验使用)<input type="text" name="publicKey"><b>支付公钥sign_type只有单一key时public_key与private_key相等比如sign_type=MD5(友店支付除外)的情况</b>
支付平台公钥(签名校验使用)<input type="text" name="publicKey">
<br>
<b>支付公钥sign_type只有单一key时public_key与private_key相等比如sign_type=MD5(友店支付除外)的情况
<br>
<span style="color: red">银联:验签证书链格式: 中级证书路径;根证书路径</span>
</b>
<br>
应用私钥(生成签名使用)<input type="text" name="privateKey">
<b>
<br>
<span style="color: red">银联, 私钥证书格式: 私钥证书路径;私钥证书对应的密码</span>
</b>
<br>
异步回调地址<input type="text" name="notifyUrl"><b>友店支付用不到此参数,在友店管理端进行配置</b>
<br>
@@ -62,6 +73,7 @@
<div>旧版支付宝(<code>com.egzosn.pay.ali.before.bean.AliTransactionType</code>) 即时付款=DIRECT 移动支付=APP 手机网站支付=WAP</div>
<div>新版支付宝(<code>com.egzosn.pay.ali.bean.AliTransactionType</code>) 即时付款=DIRECT app支付=APP 手机网站支付=WAP , 扫码付=SWEEPPAY, 条码付=BAR_CODE, 声波付=WAVE_CODE </div>
<div>微信(<code>com.egzosn.pay.wx.bean.WxTransactionType</code>) 公众号支付=JSAPI 移动支付=APP 扫码付=NATIVE</div>
<div>银联(<code>com.egzosn.pay.union.bean.UnionTransactionType</code>):苹果支付=APPLE手机控件=APPWAP支付=WAP网关支付=WEB无跳转支付=NO_JUMPB2B支付=B2B申码(主扫场景)=APPLY_QR_CODE消费(被扫场景)=CONSUME</div>
<div>友店微信(<code>com.egzosn.pay.wx.youdian.bean.YoudianTransactionType</code>) 扫码付=NATIVE</div>
<div>富友(<code>com.egzosn.pay.fuiou.bean.FuiouTransactionType</code>) B2BB2C</div>

View File

@@ -5,6 +5,7 @@ import com.egzosn.pay.common.api.BasePayService;
import com.egzosn.pay.common.api.Callback;
import com.egzosn.pay.common.api.PayConfigStorage;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.bean.outbuilder.PayTextOutMessage;
import com.egzosn.pay.common.bean.result.PayException;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.http.HttpConfigStorage;
@@ -13,17 +14,14 @@ import com.egzosn.pay.common.util.MatrixToImageWriter;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.sign.encrypt.RSA;
import com.egzosn.pay.common.util.sign.encrypt.RSA2;
import com.egzosn.pay.common.util.str.StringUtils;
import com.egzosn.pay.union.enums.UnionTransactionType;
import com.egzosn.pay.union.request.UnionQueryOrder;
import com.egzosn.pay.union.sdk.SDKConstants;
import com.egzosn.pay.union.bean.UnionTransactionType;
import com.egzosn.pay.union.bean.SDKConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.cert.*;
import java.text.DateFormat;
@@ -36,8 +34,7 @@ import java.util.*;
* @create 2017 2017/11/5 0005
*/
public class UnionPayService extends BasePayService {
//日志
protected static final Log log = LogFactory.getLog(UnionPayService.class);
private static final Log log = LogFactory.getLog(UnionPayService.class);
/**
* 测试域名
*/
@@ -73,15 +70,32 @@ public class UnionPayService extends BasePayService {
super(payConfigStorage, configStorage);
}
public String getFrontTransUrl () {
return String.format(FRONT_TRANS_URL,payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
public String getBackTransUrl () {
return String.format(BACK_TRANS_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
public String getSingleQueryUrl () {
return String.format(SINGLE_QUERY_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
public String getFileTransUrl () {
return String.format(FILE_TRANS_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
/**
* 银联全渠道系统产品参数除了encoding自行选择外其他不需修改
*
* @return 返回参数集合
*/
private Map<String ,Object> getCommonParam(){
Map<String ,Object> params = new TreeMap<>();
UnionPayConfigStorage configStorage = (UnionPayConfigStorage)payConfigStorage;
private Map<String, Object> getCommonParam() {
Map<String, Object> params = new TreeMap<>();
UnionPayConfigStorage configStorage = (UnionPayConfigStorage) payConfigStorage;
//银联接口版本
params.put(SDKConstants.param_version, configStorage.getVersion());
//编码方式
@@ -106,41 +120,46 @@ public class UnionPayService extends BasePayService {
* 回调校验
*
* @param result 回调回来的参数集
*
* @return 签名校验 true通过
*/
@Override
public boolean verify (Map<String, Object> result) {
if(result != null){
if(this.vailSign(result)){
String respCode = result.get("respCode").toString();
if(("00").equals(respCode)){
public boolean verify(Map<String, Object> result) {
//成功,获取tn号
//String tn = resmap.get("tn");
//TODO
return true;
}else{
//其他应答码为失败请排查原因或做失败处理
//TODO
}
}else{
// 校验失败
}
}else{
if (null == result || result.get(SDKConstants.param_signature) == null) {
log.debug("银联支付验签异常params" + result);
return false;
}
return false;
return this.signVerify(result, (String) result.get(SDKConstants.param_signature));
}
/**
* 签名校验
*
* @param params 参数集
* @param sign 签名
* @param sign 签名原文
* @return 签名校验 true通过
*/
@Override
public boolean signVerify (Map<String, Object> params, String sign) {
return false;
SignUtils signUtils = SignUtils.valueOf(payConfigStorage.getSignType());
String data = SignUtils.parameterText(params, "&", "signature");
switch (signUtils){
case RSA:
data = SignUtils.SHA1.createSign(data,"", payConfigStorage.getInputCharset());
return RSA.verify(data, sign, verifyCertificate(genCertificateByStr((String)params.get(SDKConstants.param_signPubKeyCert))).getPublicKey(), payConfigStorage.getInputCharset());
case RSA2:
data = SignUtils.SHA256.createSign(data,"", payConfigStorage.getInputCharset());
return RSA2.verify(data, sign, verifyCertificate(genCertificateByStr((String)params.get(SDKConstants.param_signPubKeyCert))).getPublicKey(), payConfigStorage.getInputCharset());
case SHA1:
case SHA256:
case SM3:
String before = signUtils.createSign(payConfigStorage.getKeyPublic(),"",payConfigStorage.getInputCharset());
return signUtils.verify(data, sign, "&" + before, payConfigStorage.getInputCharset());
default:
return false;
}
}
/**
@@ -247,42 +266,13 @@ public class UnionPayService extends BasePayService {
return parameters;
}
/**
* 验证数据合法性
* @param resData 请求参数
* @return 请求参数
*/
private boolean vailSign(Map<String, Object> resData){
SignUtils signUtils = SignUtils.valueOf(payConfigStorage.getSignType());
//签名原文
String stringSign = resData.get(SDKConstants.param_signature).toString();
String data = SignUtils.parameterText(resData, "&", "signature");
switch (signUtils){
case RSA:
data = SignUtils.SHA1.createSign(data,"", payConfigStorage.getInputCharset());
return RSA.verify(data, stringSign, payConfigStorage.getCertDescriptor().getPublicCert().getPublicKey(), payConfigStorage.getInputCharset());
case RSA2:
data = SignUtils.SHA256.createSign(data,"", payConfigStorage.getInputCharset());
X509Certificate cert = genCertificateByStr(resData.get(SDKConstants.param_signPubKeyCert).toString());
/*验证证书链*/
verifyCertificate(cert);
return RSA2.verify(data, stringSign,cert.getPublicKey(), payConfigStorage.getInputCharset());
// return RSA2.verify(data, stringSign, payConfigStorage.getCertDescriptor().getPublicCert().getPublicKey(), payConfigStorage.getInputCharset());
case SHA1:
case SHA256:
case SM3:
String before = signUtils.createSign(payConfigStorage.getKeyPublic(),"",payConfigStorage.getInputCharset());
return signUtils.verify(data, stringSign, "&"+before, payConfigStorage.getInputCharset());
default:
return false;
}
}
/**
* 验证证书链
* @param cert
* @param cert 需要验证的证书
*/
private void verifyCertificate (X509Certificate cert) {
private X509Certificate verifyCertificate (X509Certificate cert) {
try {
cert.checkValidity();//验证有效期
X509Certificate middleCert = payConfigStorage.getCertDescriptor().getPublicCert();
@@ -312,6 +302,7 @@ public class UnionPayService extends BasePayService {
@SuppressWarnings("unused")
PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder
.build(pkixParams);
return cert;
} catch (java.security.cert.CertPathBuilderException e) {
log.error("verify certificate chain fail.", e);
} catch (CertificateExpiredException e) {
@@ -321,6 +312,7 @@ public class UnionPayService extends BasePayService {
} catch (Exception e) {
log.error(e);
}
return null;
}
/**
* 获取输出二维码,用户返回给支付端,
@@ -336,8 +328,8 @@ public class UnionPayService extends BasePayService {
if(response.isEmpty()){
throw new PayErrorException(new PayException("failure", "响应内容有误!",responseStr));
}
if(this.vailSign(response)){
if("00".equals(response.get(SDKConstants.param_respCode))){
if(this.verify(response)){
if(SDKConstants.OK_RESP_CODE.equals(response.get(SDKConstants.param_respCode))){
//成功,获取tn号
return MatrixToImageWriter.writeInfoToJpgBuff((String)response.get(SDKConstants.param_qrCode));
}
@@ -360,72 +352,6 @@ public class UnionPayService extends BasePayService {
}
/**
* 交易查询接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回查询回来的结果集,支付方原值返回
*/
@Override
public Map<String, Object> query (String tradeNo, String outTradeNo) {
Map<String ,Object > params = orderInfo(new PayOrder("交易查询","摘要",null,outTradeNo,UnionTransactionType.QUERY));
String responseStr = getHttpRequestTemplate().postForObject(this.getSingleQueryUrl(),params,String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if(this.vailSign(response)){
if("00".equals(response.getString(SDKConstants.param_respCode))){
String origRespCode = response.getString(SDKConstants.param_origRespCode);
if(("00").equals(origRespCode)){
//交易成功,更新商户订单状态
//TODO
return response;
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
}
/**
* 消费撤销/退货接口
*
* @return 返回支付方申请退款后的结果
*/
public Map<String, Object> unionRefundOrConsumeUndo (UnionQueryOrder queryOrder,UnionTransactionType type) {
Map<String ,Object> params = this.getCommonParam();
type.convertMap(params);
params.put(SDKConstants.param_orderId,queryOrder.getOrderId());
params.put(SDKConstants.param_txnAmt,queryOrder.getTxnAmt());
if(StringUtils.isNotBlank(queryOrder.getOrigQryId())) {
params.put(SDKConstants.param_origQryId, queryOrder.getOrigQryId());
}
if(StringUtils.isNotBlank(queryOrder.getOrigOrderId())){
params.put(SDKConstants.param_origOrderId,queryOrder.getOrigOrderId());
}
if(StringUtils.isNotBlank(queryOrder.getOrigTxnTime())) {
params.put(SDKConstants.param_origTxnTime, queryOrder.getOrigOrderId());
}
this.setSign(params);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(),params,String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if(this.vailSign(response)){
if("00".equals(response.getString(SDKConstants.param_respCode))){
String origRespCode = response.getString(SDKConstants.param_origRespCode);
//交易成功,更新商户订单状态
//TODO
return response;
}else{
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
}else{
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
}
/**
* 将字符串转换为X509Certificate对象.
*
@@ -445,41 +371,6 @@ public class UnionPayService extends BasePayService {
return x509Cert;
}
/**
* 将请求参数或者请求流转化为 Map
*
* @param parameterMap 请求参数
* @param is 请求流
* @return 获得回调的请求参数
*/
@Override
public Map<String, Object> getParameter2Map (Map<String, String[]> parameterMap, InputStream is) {
Map<String, Object> params = new TreeMap<String,Object>();
for (Iterator iter = parameterMap.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = parameterMap.get(name);
String valueStr = "";
for (int i = 0,len = values.length; i < len; i++) {
valueStr += (i == len - 1) ? values[i]
: values[i] + ",";
}
//乱码解决这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
if (!valueStr.matches("\\w+")){
try {
if(valueStr.equals(new String(valueStr.getBytes("iso8859-1"), "iso8859-1"))){
valueStr=new String(valueStr.getBytes("iso8859-1"), payConfigStorage.getInputCharset());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
params.put(name, valueStr);
}
return params;
}
/**
* 获取输出消息,用户返回给支付端
*
@@ -489,7 +380,7 @@ public class UnionPayService extends BasePayService {
*/
@Override
public PayOutMessage getPayOutMessage (String code, String message) {
return null;
return PayTextOutMessage.TEXT().content(code.toLowerCase()).build();
}
/**
@@ -501,23 +392,23 @@ public class UnionPayService extends BasePayService {
*/
@Override
public PayOutMessage successPayOutMessage (PayMessage payMessage) {
return null;
return getPayOutMessage("ok", null);
}
/**
* 获取输出消息,用户返回给支付端, 针对于web端
*
* @param ` 发起支付的订单信息
* @param method 请求方式 "post" "get",
* @param ` 发起支付的订单信息
* @param method 请求方式 "post" "get",
*
* @return 获取输出消息,用户返回给支付端, 针对于web端
* @see MethodType 请求类型
*/
@Override
public String buildRequest (Map<String, Object> orderInfo, MethodType method) {
public String buildRequest(Map<String, Object> orderInfo, MethodType method) {
StringBuffer sf = new StringBuffer();
sf.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset="+payConfigStorage.getInputCharset()+"\"/></head><body>");
sf.append("<form id = \"pay_form\" action=\"" + getFrontTransUrl()
+ "\" method=\"post\">");
sf.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + payConfigStorage.getInputCharset() + "\"/></head><body>");
sf.append("<form id = \"pay_form\" action=\"" + getFrontTransUrl() + "\" method=\"post\">");
if (null != orderInfo && 0 != orderInfo.size()) {
Set<Map.Entry<String, Object>> set = orderInfo.entrySet();
Iterator<Map.Entry<String, Object>> it = set.iterator();
@@ -525,8 +416,7 @@ public class UnionPayService extends BasePayService {
Map.Entry<String, Object> ey = it.next();
String key = ey.getKey();
Object value = ey.getValue();
sf.append("<input type=\"hidden\" name=\"" + key + "\" id=\""
+ key + "\" value=\"" + value + "\"/>");
sf.append("<input type=\"hidden\" name=\"" + key + "\" id=\"" + key + "\" value=\"" + value + "\"/>");
}
}
sf.append("</form>");
@@ -545,13 +435,81 @@ public class UnionPayService extends BasePayService {
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
*
* @return 返回查询回来的结果集
*/
@Override
public <T> T query (String tradeNo, String outTradeNo, Callback<T> callback) {
return null;
public <T> T query(String tradeNo, String outTradeNo, Callback<T> callback) {
Map<String, Object> params = orderInfo(new PayOrder("交易查询", "摘要", null, outTradeNo, UnionTransactionType.QUERY));
String responseStr = getHttpRequestTemplate().postForObject(this.getSingleQueryUrl(), params, String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if (this.verify(response)) {
if (SDKConstants.OK_RESP_CODE.equals(response.getString(SDKConstants.param_respCode))) {
String origRespCode = response.getString(SDKConstants.param_origRespCode);
if ((SDKConstants.OK_RESP_CODE).equals(origRespCode)) {
//交易成功,更新商户订单状态
//TODO
return callback.perform(response);
}
}
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
/**
* 交易查询接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
*
* @return 返回查询回来的结果集,支付方原值返回
*/
@Override
public Map<String, Object> query(String tradeNo, String outTradeNo) {
return query(tradeNo, outTradeNo, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
/**
* 消费撤销/退货接口
* @param origQryId
* @param orderId
* @param totalAmount
* @param type
* @return 返回支付方申请退款后的结果
*/
public Map<String, Object> unionRefundOrConsumeUndo (String origQryId, String orderId, BigDecimal totalAmount,UnionTransactionType type) {
Map<String ,Object> params = this.getCommonParam();
type.convertMap(params);
params.put(SDKConstants.param_orderId,orderId);
params.put(SDKConstants.param_txnAmt, totalAmount);
params.put(SDKConstants.param_origQryId, origQryId);
this.setSign(params);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(),params,String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if(this.verify(response)){
if(SDKConstants.OK_RESP_CODE.equals(response.getString(SDKConstants.param_respCode))){
String origRespCode = response.getString(SDKConstants.param_origRespCode);
//交易成功,更新商户订单状态
//TODO
return response;
}
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
/**
* 交易关闭接口
*
@@ -588,7 +546,7 @@ public class UnionPayService extends BasePayService {
*/
@Override
public Map<String, Object> refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return null;
return unionRefundOrConsumeUndo(tradeNo, outTradeNo, totalAmount, UnionTransactionType.REFUND);
}
@@ -605,7 +563,7 @@ public class UnionPayService extends BasePayService {
*/
@Override
public <T> T refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback) {
return null;
return callback.perform(unionRefundOrConsumeUndo(tradeNo, outTradeNo, totalAmount, UnionTransactionType.REFUND));
}
/**
@@ -641,44 +599,16 @@ public class UnionPayService extends BasePayService {
* @return 返回fileContent 请自行将数据落地
*/
@Override
public Object downloadbill (Date billDate, String billType) {
Map<String ,Object > params = this.getCommonParam();
UnionTransactionType.FILE_TRANSFER.convertMap(params);
DateFormat df = new SimpleDateFormat("MMDD");
params.put(SDKConstants.param_settleDate,df.format(new Date()));
params.put(SDKConstants.param_fileType,billType);
this.setSign(params);
String responseStr = getHttpRequestTemplate().postForObject(this.getFileTransUrl(),params,String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if(this.vailSign(response)){
if("00".equals(response.get(SDKConstants.param_respCode))){
public String downloadbill (Date billDate, String billType) {
return downloadbill(billDate, billType, new Callback<String>() {
@Override
public String perform(Map<String, Object> response) {
return response.get(SDKConstants.param_fileContent).toString();
}else{
throw new PayErrorException(new PayException(response.get(SDKConstants.param_respCode).toString(), response.get(SDKConstants.param_respMsg).toString(), response.toString()));
}
}else{
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toString()));
}
});
}
/**
* 将parameterMap对应的key存放至params
* @param parameterMap 请求参数
* @param params 转化的对象
* @param key 需要取值的key
* @return params
*/
public Map<String, Object> conversion(Map<String, String[]> parameterMap, Map<String, Object> params ,String key){
String[] values = parameterMap.get(key);
String valueStr = "";
for (int i = 0,len = values.length; i < len; i++) {
valueStr += (i == len - 1) ? values[i] : values[i] + ",";
}
params.put(key, valueStr);
return params;
}
/**
* 下载对账单
*
@@ -689,7 +619,23 @@ public class UnionPayService extends BasePayService {
*/
@Override
public <T> T downloadbill (Date billDate, String billType, Callback<T> callback) {
return null;
Map<String ,Object > params = this.getCommonParam();
UnionTransactionType.FILE_TRANSFER.convertMap(params);
DateFormat df = new SimpleDateFormat("MMDD");
params.put(SDKConstants.param_settleDate,df.format(new Date()));
params.put(SDKConstants.param_fileType,billType);
this.setSign(params);
String responseStr = getHttpRequestTemplate().postForObject(this.getFileTransUrl(),params,String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if(this.verify(response)){
if(SDKConstants.OK_RESP_CODE.equals(response.get(SDKConstants.param_respCode))){
return callback.perform(response);
}
throw new PayErrorException(new PayException(response.get(SDKConstants.param_respCode).toString(), response.get(SDKConstants.param_respMsg).toString(), response.toString()));
}
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toString()));
}
/**
@@ -706,51 +652,6 @@ public class UnionPayService extends BasePayService {
return null;
}
public String getFrontTransUrl () {
return String.format(FRONT_TRANS_URL,payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
public String getBackTransUrl () {
return String.format(BACK_TRANS_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
public String getSingleQueryUrl () {
return String.format(SINGLE_QUERY_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
//
// public String getBatchTransUrl () {
// return payConfigStorage.isTest() ? String.format(BATCH_TRANS_URL,TEST_BASE_DOMAIN):String.format(BATCH_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
public String getFileTransUrl () {
return String.format(FILE_TRANS_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN);
}
// public String getAppTransUrl () {
// return payConfigStorage.isTest() ? String.format(APP_TRANS_URL,TEST_BASE_DOMAIN):String.format(APP_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
//
// public String getCardTransUrl () {
// return payConfigStorage.isTest() ? String.format(CARD_TRANS_URL,TEST_BASE_DOMAIN):String.format(CARD_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
//
// public String getJfFrontTransUrl () {
// return payConfigStorage.isTest() ? String.format(JF_FRONT_TRANS_URL,TEST_BASE_DOMAIN):String.format(JF_FRONT_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
//
// public String getJfBackTransUrl () {
// return payConfigStorage.isTest() ? String.format(JF_BACK_TRANS_URL,TEST_BASE_DOMAIN):String.format(JF_BACK_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
//
// public String getJfSingleQueryUrl () {
// return payConfigStorage.isTest() ? String.format(JF_SINGLE_QUERY_URL,TEST_BASE_DOMAIN):String.format(JF_SINGLE_QUERY_URL,RELEASE_BASE_DOMAIN);
// }
//
// public String getJfAppTransUrl () {
// return payConfigStorage.isTest() ? String.format(JF_APP_TRANS_URL,TEST_BASE_DOMAIN):String.format(JF_APP_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
//
// public String getJfCardTransUrl () {
// return payConfigStorage.isTest() ? String.format(JF_CARD_TRANS_URL,TEST_BASE_DOMAIN):String.format(JF_CARD_TRANS_URL,RELEASE_BASE_DOMAIN);
// }
}

View File

@@ -12,7 +12,7 @@
* xshu 2014-05-28 MPI插件包常量定义
* =============================================================================
*/
package com.egzosn.pay.union.sdk;
package com.egzosn.pay.union.bean;
/**
*
@@ -23,134 +23,9 @@ package com.egzosn.pay.union.sdk;
*/
public class SDKConstants {
public final static String COLUMN_DEFAULT = "-";
public final static String KEY_DELIMITER = "#";
/** memeber variable: blank. */
public static final String BLANK = "";
/** member variabel: space. */
public static final String SPACE = " ";
/** memeber variable: unline. */
public static final String UNLINE = "_";
/** memeber varibale: star. */
public static final String STAR = "*";
/** memeber variable: line. */
public static final String LINE = "-";
/** memeber variable: add. */
public static final String ADD = "+";
/** memeber variable: colon. */
public final static String COLON = "|";
/** memeber variable: point. */
public final static String POINT = ".";
/** memeber variable: comma. */
public final static String COMMA = ",";
/** memeber variable: slash. */
public final static String SLASH = "/";
/** memeber variable: div. */
public final static String DIV = "/";
/** memeber variable: left . */
public final static String LB = "(";
/** memeber variable: right. */
public final static String RB = ")";
/** memeber variable: rmb. */
public final static String CUR_RMB = "RMB";
/** memeber variable: .page size */
public static final int PAGE_SIZE = 10;
/** memeber variable: String ONE. */
public static final String ONE = "1";
/** memeber variable: String ZERO. */
public static final String ZERO = "0";
/** memeber variable: number six. */
public static final int NUM_SIX = 6;
/** memeber variable: equal mark. */
public static final String EQUAL = "=";
/** memeber variable: operation ne. */
public static final String NE = "!=";
/** memeber variable: operation le. */
public static final String LE = "<=";
/** memeber variable: operation ge. */
public static final String GE = ">=";
/** memeber variable: operation lt. */
public static final String LT = "<";
/** memeber variable: operation gt. */
public static final String GT = ">";
/** memeber variable: list separator. */
public static final String SEP = "./";
/** memeber variable: Y. */
public static final String Y = "Y";
/** memeber variable: AMPERSAND. */
public static final String AMPERSAND = "&";
/** memeber variable: SQL_LIKE_TAG. */
public static final String SQL_LIKE_TAG = "%";
/** memeber variable: @. */
public static final String MAIL = "@";
/** memeber variable: number zero. */
public static final int NZERO = 0;
public static final String LEFT_BRACE = "{";
public static final String RIGHT_BRACE = "}";
/** memeber variable: string true. */
public static final String TRUE_STRING = "true";
/** memeber variable: string false. */
public static final String FALSE_STRING = "false";
/** memeber variable: forward success. */
public static final String SUCCESS = "success";
/** memeber variable: forward fail. */
public static final String FAIL = "fail";
/** memeber variable: global forward success. */
public static final String GLOBAL_SUCCESS = "$success";
/** memeber variable: global forward fail. */
public static final String GLOBAL_FAIL = "$fail";
public static final String UTF_8_ENCODING = "UTF-8";
public static final String GBK_ENCODING = "GBK";
public static final String CONTENT_TYPE = "Content-type";
public static final String APP_XML_TYPE = "application/xml;charset=utf-8";
public static final String APP_FORM_TYPE = "application/x-www-form-urlencoded;charset=";
public static final String VERSION_1_0_0 = "1.0.0";
public static final String VERSION_5_0_0 = "5.0.0";
public static final String VERSION_5_0_1 = "5.0.1";
public static final String VERSION_5_1_0 = "5.1.0";
public static final String SIGNMETHOD_RSA = "01";
public static final String SIGNMETHOD_SHA256 = "11";
public static final String SIGNMETHOD_SM3 = "12";
public static final String OK_RESP_CODE = "00";
public static final String UNIONPAY_CNNAME = "中国银联股份有限公司";
public static final String CERTTYPE_01 = "01";// 敏感信息加密公钥
public static final String CERTTYPE_02 = "02";// 磁道加密公钥
/******************************************** 5.0报文接口定义 ********************************************/
/** 版本号. */

View File

@@ -1,7 +1,6 @@
package com.egzosn.pay.union.enums;
package com.egzosn.pay.union.bean;
import com.egzosn.pay.common.bean.TransactionType;
import com.egzosn.pay.union.sdk.SDKConstants;
import java.util.Map;

View File

@@ -1,82 +0,0 @@
package com.egzosn.pay.union.request;
/**
* @author Actinia
* @email hayesfu@qq.com
* <pre>
create 2017 2017/11/4 0004
* </pre>
*/
public class UnionQueryOrder {
private Integer payId;
/**
* 支付平台订单号
*/
private String orderId;
/**
* 金额
*/
private String txnAmt;
/**
* 原交易查询流水号
*/
private String origQryId;
/**
* 原交易商户订单号
*/
private String origOrderId;
/**
* 原交易商户发送交易时间:
*/
private String origTxnTime;
public Integer getPayId() {
return payId;
}
public void setPayId(Integer payId) {
this.payId = payId;
}
public String getOrderId () {
return orderId;
}
public void setOrderId (String orderId) {
this.orderId = orderId;
}
public String getTxnAmt () {
return txnAmt;
}
public void setTxnAmt (String txnAmt) {
this.txnAmt = txnAmt;
}
public String getOrigQryId () {
return origQryId;
}
public void setOrigQryId (String origQryId) {
this.origQryId = origQryId;
}
public String getOrigOrderId () {
return origOrderId;
}
public void setOrigOrderId (String origOrderId) {
this.origOrderId = origOrderId;
}
public String getOrigTxnTime () {
return origTxnTime;
}
public void setOrigTxnTime (String origTxnTime) {
this.origTxnTime = origTxnTime;
}
}