Merge remote-tracking branch 'origin/master'

This commit is contained in:
egzosn
2019-07-04 15:49:15 +08:00
29 changed files with 1807 additions and 361 deletions

View File

@@ -2,6 +2,7 @@ package com.egzosn.pay.ali.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.ali.bean.AliPayMessage;
import com.egzosn.pay.ali.bean.AliTransactionType;
import com.egzosn.pay.ali.bean.OrderSettle;
import com.egzosn.pay.common.api.BasePayService;
@@ -608,4 +609,14 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
return JSON.toJSONString(getBizContent(tradeNo, outTradeNo, null));
}
/**
* 创建消息
*
* @param message 支付平台返回的消息
* @return 支付消息对象
*/
@Override
public PayMessage createMessage(Map<String, Object> message) {
return AliPayMessage.create(message);
}
}

View File

@@ -0,0 +1,263 @@
package com.egzosn.pay.ali.bean;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.egzosn.pay.common.bean.PayMessage;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
/**
* 支付宝回调信息
*
* @author egan
* email egzosn@gmail.com
* date 2019/6/30.19:19
*/
public class AliPayMessage extends PayMessage {
//notify_time 通知时间 Date 是 通知的发送时间。格式为yyyy-MM-dd HH:mm:ss 2015-14-27 15:45:58
@JSONField(name = "notify_time")
private Date notifyTime;
//notify_type 通知类型 String(64) 是 通知的类型 trade_status_sync
@JSONField(name = "notify_type")
private String notifyType;
// notify_id 通知校验ID String(128) 是 通知校验ID ac05099524730693a8b330c5ecf72da9786
@JSONField(name = "notify_id")
private String notifyId;
// app_id 支付宝分配给开发者的应用Id String(32) 是 支付宝分配给开发者的应用Id 2014072300007148
@JSONField(name = "app_id")
private String appId;
// charset 编码格式 String(10) 是 编码格式如utf-8、gbk、gb2312等 utf-8
private String charset;
// version 接口版本 String(3) 是 调用的接口版本固定为1.0 1.0
private String version;
// sign_type 签名类型 String(10) 是 商户生成签名字符串所使用的签名算法类型目前支持RSA2和RSA推荐使用RSA2 RSA2
@JSONField(name = "sign_type")
private String signType;
// sign 签名 String(256) 是 请参考文末 异步返回结果的验签 601510b7970e52cc63db0f44997cf70e
private String sign;
// trade_no 支付宝交易号 String(64) 是 支付宝交易凭证号 2013112011001004330000121536
@JSONField(name = "trade_no")
private String tradeNo;
// out_trade_no 商户订单号 String(64) 是 原支付请求的商户订单号 6823789339978248
@JSONField(name = "out_trade_no")
private String outTradeNo;
// out_biz_no 商户业务号 String(64) 否 商户业务ID主要是退款通知中返回退款申请的流水号 HZRF001
@JSONField(name = "out_biz_no")
private String outBizNo;
// buyer_id 买家支付宝用户号 String(16) 否 买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字 2088102122524333
@JSONField(name = "buyer_id")
private String buyerId;
// buyer_logon_id 买家支付宝账号 String(100) 否 买家支付宝账号 15901825620
@JSONField(name = "buyer_logon_id")
private String buyerLogonId;
// seller_id 卖家支付宝用户号 String(30) 否 卖家支付宝用户号 2088101106499364
@JSONField(name = "seller_id")
private String sellerId;
// seller_email 卖家支付宝账号 String(100) 否 卖家支付宝账号 zhuzhanghu@alitest.com
@JSONField(name = "seller_email")
private String sellerEmail;
// trade_status 交易状态 String(32) 否 交易目前所处的状态,见下张表 交易状态说明 TRADE_CLOSED
@JSONField(name = "trade_status")
private String tradeStatus;
// total_amount 订单金额 Number(9,2) 否 本次交易支付的订单金额,单位为人民币(元) 20
@JSONField(name = "total_amount")
private BigDecimal totalAmount;
// receipt_amount 实收金额 Number(9,2) 否 商家在交易中实际收到的款项,单位为元 15
@JSONField(name = "receipt_amount")
private BigDecimal receiptAmount;
// invoice_amount 开票金额 Number(9,2) 否 用户在交易中支付的可开发票的金额 10.00
@JSONField(name = "invoice_amount")
private BigDecimal invoiceAmount;
// buyer_pay_amount 付款金额 Number(9,2) 否 用户在交易中支付的金额 13.88
@JSONField(name = "buyer_pay_amount")
private BigDecimal buyerPayAmount;
// point_amount 集分宝金额 Number(9,2) 否 使用集分宝支付的金额 12.00
@JSONField(name = "point_amount")
private BigDecimal pointAmount;
// refund_fee 总退款金额 Number(9,2) 否 退款通知中,返回总退款金额,单位为元,支持两位小数 2.58
@JSONField(name = "refund_fee")
private BigDecimal refundFee;
// subject 订单标题 String(256) 否 商品的标题/交易标题/订单标题/订单关键字等,是请求时对应的参数,原样通知回来 当面付交易
@JSONField(name = "subject")
private String subject;
// body 商品描述 String(400) 否 该订单的备注、描述、明细等。对应请求时的body参数原样通知回来 当面付交易内容
@JSONField(name = "body")
private String body;
// gmt_create 交易创建时间 Date 否 该笔交易创建的时间。格式为yyyy-MM-dd HH:mm:ss 2015-04-27 15:45:57
@JSONField(name = "gmt_create")
private Date gmtCreate;
// gmt_payment 交易付款时间 Date 否 该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss 2015-04-27 15:45:57
@JSONField(name = "gmt_payment")
private Date gmtPayment;
// gmt_refund 交易退款时间 Date 否 该笔交易的退款时间。格式为yyyy-MM-dd HH:mm:ss.S 2015-04-28 15:45:57.320
@JSONField(name = "gmt_refund")
private Date gmtRefund;
// gmt_close 交易结束时间 Date 否 该笔交易结束时间。格式为yyyy-MM-dd HH:mm:ss 2015-04-29 15:45:57
@JSONField(name = "gmt_close")
private Date gmtClose;
// fund_bill_list 支付金额信息 String(512) 否 支付成功的各个渠道金额信息,详见下表 资金明细信息说明 [{“amount”:“15.00”,“fundChannel”:“ALIPAYACCOUNT”}]
@JSONField(name = "fund_bill_list")
private String fundBillList;
// passback_params 回传参数 String(512) 否 公共回传参数如果请求时传递了该参数则返回给商户时会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝 merchantBizType%3d3C%26merchantBizNo%3d2016010101111
@JSONField(name = "passback_params")
private String passbackParams;
// voucher_detail_list 优惠券信息 String 否 本交易支付时所使用的所有优惠券信息,详见下表 优惠券信息说明 [{“amount”:“0.20”,“merchantContribute”:“0.00”,“name”:“一键创建券模板的券名称”,“otherContribute”:“0.20”,“type”:“ALIPAY_DISCOUNT_VOUCHER”,“memo”:“学生卡8折优惠”]
@JSONField(name = "voucher_detail_list")
private String voucherDetailList;
public Date getNotifyTime() {
return notifyTime;
}
public void setNotifyTime(Date notifyTime) {
this.notifyTime = notifyTime;
}
public String getNotifyType() {
return notifyType;
}
public void setNotifyType(String notifyType) {
this.notifyType = notifyType;
}
public String getNotifyId() {
return notifyId;
}
public void setNotifyId(String notifyId) {
this.notifyId = notifyId;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSignType() {
return signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
@Override
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getTradeNo() {
return tradeNo;
}
public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
}
@Override
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public String getOutBizNo() {
return outBizNo;
}
public void setOutBizNo(String outBizNo) {
this.outBizNo = outBizNo;
}
public String getBuyerId() {
return buyerId;
}
public void setBuyerId(String buyerId) {
this.buyerId = buyerId;
}
public String getBuyerLogonId() {
return buyerLogonId;
}
public void setBuyerLogonId(String buyerLogonId) {
this.buyerLogonId = buyerLogonId;
}
public String getSellerId() {
return sellerId;
}
public void setSellerId(String sellerId) {
this.sellerId = sellerId;
}
public String getSellerEmail() {
return sellerEmail;
}
public void setSellerEmail(String sellerEmail) {
this.sellerEmail = sellerEmail;
}
public String getTradeStatus() {
return tradeStatus;
}
public void setTradeStatus(String tradeStatus) {
this.tradeStatus = tradeStatus;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}
public BigDecimal getReceiptAmount() {
return receiptAmount;
}
public void setReceiptAmount(BigDecimal receiptAmount) {
this.receiptAmount = receiptAmount;
}
public static final AliPayMessage create(Map<String, Object> message){
AliPayMessage payMessage = new JSONObject(message).toJavaObject(AliPayMessage.class);
payMessage.setPayMessage(message);
return payMessage;
}
}

View File

@@ -17,13 +17,14 @@ import java.util.*;
/**
* 支付基础服务
*
* @author: egan
* <pre>
* <pre>
* email egzosn@gmail.com
* date 2017/3/5 20:36
* </pre>
*/
public abstract class BasePayService<PC extends PayConfigStorage> implements PayService<PC> {
public abstract class BasePayService<PC extends PayConfigStorage> implements PayService<PC> {
protected final Log LOG = LogFactory.getLog(getClass());
protected PC payConfigStorage;
@@ -38,10 +39,12 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* 支付消息拦截器
*/
protected List<PayMessageInterceptor> interceptors = new ArrayList<PayMessageInterceptor>();;
protected List<PayMessageInterceptor> interceptors = new ArrayList<PayMessageInterceptor>();
;
/**
* 设置支付配置
*
* @param payConfigStorage 支付配置
*/
@Override
@@ -54,6 +57,7 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
public PC getPayConfigStorage() {
return payConfigStorage;
}
@Override
public HttpRequestTemplate getHttpRequestTemplate() {
return requestTemplate;
@@ -61,6 +65,7 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* 设置并创建请求模版, 代理请求配置这里是否合理??,
*
* @param configStorage http请求配置
* @return 支付服务
*/
@@ -82,17 +87,18 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* Generate a Base64 encoded String from user , password
* @param user 用户名
* Generate a Base64 encoded String from user , password
*
* @param user 用户名
* @param password 密码
* @return authorizationString
*/
protected String authorizationString(String user, String password) {
String base64ClientID = null;
try {
base64ClientID = com.egzosn.pay.common.util.sign.encrypt.Base64.encode(String.format("%s:%s", user , password).getBytes("UTF-8"));
base64ClientID = com.egzosn.pay.common.util.sign.encrypt.Base64.encode(String.format("%s:%s", user, password).getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
LOG.error(e);
LOG.error(e);
}
return base64ClientID;
@@ -108,8 +114,9 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
@Override
public String createSign(String content, String characterEncoding) {
return SignUtils.valueOf(payConfigStorage.getSignType()).createSign(content, payConfigStorage.getKeyPrivate(),characterEncoding);
return SignUtils.valueOf(payConfigStorage.getSignType()).createSign(content, payConfigStorage.getKeyPrivate(), characterEncoding);
}
/**
* 创建签名
*
@@ -119,7 +126,7 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
*/
@Override
public String createSign(Map<String, Object> content, String characterEncoding) {
return SignUtils.valueOf(payConfigStorage.getSignType()).sign(content, payConfigStorage.getKeyPrivate(),characterEncoding);
return SignUtils.valueOf(payConfigStorage.getSignType()).sign(content, payConfigStorage.getKeyPrivate(), characterEncoding);
}
/**
@@ -142,20 +149,20 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* @return 获得回调的请求参数
*/
@Override
public Map<String, Object> getParameter2Map (Map<String, String[]> parameterMap, InputStream is) {
public Map<String, Object> getParameter2Map(Map<String, String[]> parameterMap, InputStream is) {
Map<String, Object> params = new TreeMap<String,Object>();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
Map<String, Object> params = new TreeMap<String, Object>();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String name = entry.getKey();
String[] values = entry.getValue();
String valueStr = "";
for (int i = 0,len = values.length; i < len; i++) {
valueStr += (i == len - 1) ? values[i] : values[i] + ",";
for (int i = 0, len = values.length; i < len; i++) {
valueStr += (i == len - 1) ? values[i] : values[i] + ",";
}
if (StringUtils.isNotEmpty(payConfigStorage.getInputCharset()) && !valueStr.matches("\\w+")){
if (StringUtils.isNotEmpty(payConfigStorage.getInputCharset()) && !valueStr.matches("\\w+")) {
try {
if(valueStr.equals(new String(valueStr.getBytes("iso8859-1"), "iso8859-1"))){
valueStr=new String(valueStr.getBytes("iso8859-1"), payConfigStorage.getInputCharset());
if (valueStr.equals(new String(valueStr.getBytes("iso8859-1"), "iso8859-1"))) {
valueStr = new String(valueStr.getBytes("iso8859-1"), payConfigStorage.getInputCharset());
}
} catch (UnsupportedEncodingException e) {
LOG.error(e);
@@ -169,11 +176,12 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* 交易查询接口,带处理器
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @return 返回查询回来的结果集
* @param callback 处理器
* @param <T> 返回类型
* @return 返回查询回来的结果集
*/
@Override
public <T> T query(String tradeNo, String outTradeNo, Callback<T> callback) {
@@ -186,26 +194,27 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方交易关闭后的结果
*/
@Override
public <T> T close(String tradeNo, String outTradeNo, Callback<T> callback) {
return callback.perform(close(tradeNo, outTradeNo));
return callback.perform(close(tradeNo, outTradeNo));
}
/**
* 交易撤销
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方交易撤销后的结果
*/
@Override
public <T> T cancel(String tradeNo, String outTradeNo, Callback<T> callback) {
return callback.perform(close(tradeNo, outTradeNo));
return callback.perform(close(tradeNo, outTradeNo));
}
/**
@@ -229,7 +238,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* @param totalAmount 总金额
* @param callback 处理器
* @param <T> 返回类型
*
* @return 处理过后的类型对象, 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@@ -243,16 +251,15 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
* @param callback 处理器
* @param <T> 返回类型
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
*/
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
return callback.perform(refund(refundOrder));
return callback.perform(refund(refundOrder));
}
@@ -263,7 +270,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
*
* @return 处理过后的类型对象,返回支付方查询退款后的结果
*/
@Override
@@ -274,13 +280,13 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* 查询退款
*
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方查询退款后的结果
*/
@Override
public <T>T refundquery(RefundOrder refundOrder, Callback<T> callback){
public <T> T refundquery(RefundOrder refundOrder, Callback<T> callback) {
return callback.perform(refundquery(refundOrder));
}
@@ -291,7 +297,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* @param billType 账单类型,具体请查看对应支付平台
* @param callback 处理器
* @param <T> 返回类型
*
* @return 返回支付方下载对账单的结果
*/
@Override
@@ -300,15 +305,15 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
}
/**
* @param tradeNoOrBillDate 支付平台订单号或者账单类型, 具体请 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @param callback 处理器
* @param <T> 返回类型
* @param tradeNoOrBillDate 支付平台订单号或者账单类型, 具体请 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方对应接口的结果
*/
@Override
public <T>T secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType, Callback<T> callback){
public <T> T secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType, Callback<T> callback) {
return callback.perform(secondaryInterface(tradeNoOrBillDate, outTradeNoBillType, transactionType));
}
@@ -317,7 +322,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
*
* @param order 转账订单
* @param callback 处理器
*
* @return 对应的转账结果
*/
@Override
@@ -330,7 +334,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* 转账
*
* @param order 转账订单
*
* @return 对应的转账结果
*/
@Override
@@ -341,27 +344,26 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
/**
* 转账查询
*
* @param outNo 商户转账订单号
* @param outNo 商户转账订单号
* @param tradeNo 支付平台转账订单号
*
* @return 对应的转账订单
*/
@Override
public Map<String, Object> transferQuery(String outNo, String tradeNo){
public Map<String, Object> transferQuery(String outNo, String tradeNo) {
return new HashMap<>(0);
}
/**
* 转账查询
*
* @param outNo 商户转账订单号
* @param tradeNo 支付平台转账订单号
* @param outNo 商户转账订单号
* @param tradeNo 支付平台转账订单号
* @param callback 处理器
* @param <T> 返回类型
* @param <T> 返回类型
* @return 对应的转账订单
*/
@Override
public <T>T transferQuery(String outNo, String tradeNo, Callback<T> callback){
public <T> T transferQuery(String outNo, String tradeNo, Callback<T> callback) {
return callback.perform(transferQuery(outNo, tradeNo));
}
@@ -382,11 +384,11 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* 获取支付消息处理器,这里用于处理具体的支付业务
* 配合{@link PayService#payBack(Map, InputStream)}进行使用
* <p>
* @return 默认使用{@link DefaultPayMessageHandler }进行实现
*
* @return 默认使用{@link DefaultPayMessageHandler }进行实现
*/
public PayMessageHandler getPayMessageHandler() {
if (null == handler){
if (null == handler) {
setPayMessageHandler(new DefaultPayMessageHandler());
}
return handler;
@@ -416,16 +418,27 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
if (LOG.isDebugEnabled()) {
LOG.debug("回调响应:" + JSON.toJSONString(data));
}
if (!verify(data)){
if (!verify(data)) {
return getPayOutMessage("fail", "失败");
}
PayMessage payMessage = new PayMessage(data);
PayMessage payMessage = this.createMessage(data);
Map<String, Object> context = new HashMap<String, Object>();
for (PayMessageInterceptor interceptor : interceptors){
if (!interceptor.intercept(payMessage, context, this)){
for (PayMessageInterceptor interceptor : interceptors) {
if (!interceptor.intercept(payMessage, context, this)) {
return successPayOutMessage(payMessage);
}
}
return getPayMessageHandler().handle(payMessage, context, this);
}
/**
* 创建消息
*
* @param message 支付平台返回的消息
* @return 支付消息对象
*/
@Override
public PayMessage createMessage(Map<String, Object> message) {
return new PayMessage(message);
}
}

View File

@@ -19,7 +19,7 @@ import java.util.Map;
* source Daniel Qian
* </pre>
*/
public interface PayMessageHandler {
public interface PayMessageHandler<M extends PayMessage, S extends PayService> {
/**
* 处理支付回调消息的处理器接口
@@ -29,9 +29,9 @@ public interface PayMessageHandler {
* @return xml,text格式的消息如果在异步规则里处理的话可以返回null
* @throws PayErrorException 支付错误异常
*/
PayOutMessage handle(PayMessage payMessage,
PayOutMessage handle(M payMessage,
Map<String, Object> context,
PayService payService
S payService
) throws PayErrorException;
}

View File

@@ -18,7 +18,7 @@ import java.util.Map;
* source Daniel Qian
* </pre>
*/
public interface PayMessageInterceptor {
public interface PayMessageInterceptor<M extends PayMessage, S extends PayService> {
/**
* 拦截微信消息
@@ -28,9 +28,9 @@ public interface PayMessageInterceptor {
* @param payService 支付服务
* @return true代表OKfalse代表不OK
*/
boolean intercept(PayMessage payMessage,
boolean intercept(M payMessage,
Map<String, Object> context,
PayService payService
S payService
) throws PayErrorException;
}

View File

@@ -2,13 +2,13 @@ package com.egzosn.pay.common.api;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.util.LogExceptionHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -17,7 +17,7 @@ import java.util.concurrent.Future;
/**
* <pre>
* 支付消息路由器通过代码化的配置把来自支付的消息交给handler处理
*
*
* 说明:
* 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
* 2. 默认情况下消息只会被处理一次,除非使用 {@link PayMessageRouterRule#next()}
@@ -39,147 +39,167 @@ import java.util.concurrent.Future;
* router.route(message);
* source chanjarster/weixin-java-tools Daniel Qian
* </pre>
* @author egan
*
* @author egan
*/
public class PayMessageRouter {
protected final Log LOG = LogFactory.getLog(PayMessageRouter.class);
/**
* 异步线程大小
*/
private static final int DEFAULT_THREAD_POOL_SIZE = 100;
/**
* 规则集
*/
private final List<PayMessageRouterRule> rules = new ArrayList<PayMessageRouterRule>();
/**
* 支付服务
*/
private final PayService payService;
/**
* 异步线程处理器
*/
private ExecutorService executorService;
/**
* 支付异常处理器
*/
private PayErrorExceptionHandler exceptionHandler;
protected final Log LOG = LogFactory.getLog(PayMessageRouter.class);
/**
* 异步线程大小
*/
private static final int DEFAULT_THREAD_POOL_SIZE = 100;
/**
* 规则集
*/
private final List<PayMessageRouterRule> rules = new ArrayList<PayMessageRouterRule>();
/**
* 支付服务
*/
private final PayService payService;
/**
* 异步线程处理器
*/
private ExecutorService executorService;
/**
* 支付异常处理器
*/
private PayErrorExceptionHandler exceptionHandler;
/**
* 根据支付服务创建路由
* @param payService 支付服务
*/
public PayMessageRouter(PayService payService) {
this.payService = payService;
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
this.exceptionHandler = new LogExceptionHandler();
}
/**
* 根据支付服务创建路由
*
* @param payService 支付服务
*/
public PayMessageRouter(PayService payService) {
this.payService = payService;
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
this.exceptionHandler = new LogExceptionHandler();
}
/**
* <pre>
* 设置自定义的 {@link ExecutorService}
* 如果不调用用该方法,默认使 Executors.newFixedThreadPool(100)
* </pre>
* @param executorService 异步线程处理器
*/
public void setExecutorService(ExecutorService executorService) {
this.executorService = executorService;
}
/**
* <pre>
* 设置自定义的 {@link ExecutorService}
* 如果不调用用该方法,默认使 Executors.newFixedThreadPool(100)
* </pre>
*
* @param executorService 异步线程处理器
*/
public void setExecutorService(ExecutorService executorService) {
this.executorService = executorService;
}
/**
* <pre>
* 设置自定义的{@link PayErrorExceptionHandler}
* 如果不调用该方法,默认使用 {@link LogExceptionHandler}
* </pre>
*
* @param exceptionHandler 异常处理器
*/
public void setExceptionHandler(PayErrorExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
/**
* <pre>
* 设置自定义的{@link PayErrorExceptionHandler}
* 如果不调用该方法,默认使用 {@link LogExceptionHandler}
* </pre>
* @param exceptionHandler 异常处理器
*/
public void setExceptionHandler(PayErrorExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
/**
* 获取所有的规则
*
* @return 规则
*/
List<PayMessageRouterRule> getRules() {
return this.rules;
}
/**
* 获取所有的规则
* @return 规则
*/
List<PayMessageRouterRule> getRules() {
return this.rules;
}
/**
* 开始一个新的Route规则
*
* @return 新的Route规则
*/
public PayMessageRouterRule rule() {
return new PayMessageRouterRule(this);
}
/**
* 开始一个新的Route规则
* @return 新的Route规则
*/
public PayMessageRouterRule rule() {
return new PayMessageRouterRule(this);
}
/**
* 处理支付消息
* @param payMessage 支付消息
* @return 支付输出结果
*/
public PayOutMessage route(final PayMessage payMessage) {
final List<PayMessageRouterRule> matchRules = new ArrayList<PayMessageRouterRule>();
// 收集匹配的规则
for (final PayMessageRouterRule rule : rules) {
if (rule.test(payMessage)) {
matchRules.add(rule);
if(!rule.isReEnter()) {
break;
/**
* 处理支付消息
*
* @param payMessage 支付消息
* @return 支付输出结果
*/
public PayOutMessage route(Map<String, Object> payMessage, PayConfigStorage storage) {
PayMessage message = payService.createMessage(payMessage);
message.setPayType(storage.getPayType());
if (null == storage.getMsgType()){
message.setMsgType(storage.getMsgType().name());
}
}
return route(message);
}
if (matchRules.isEmpty()) {
return null;
}
/**
* 处理支付消息
*
* @param payMessage 支付消息
* @return 支付输出结果
*/
public PayOutMessage route(final PayMessage payMessage) {
PayOutMessage res = null;
final List<Future> futures = new ArrayList<Future>();
for (final PayMessageRouterRule rule : matchRules) {
// 返回最后一个非异步的rule的执行结果
if(rule.isAsync()) {
futures.add(
executorService.submit(new Runnable() {
@Override
public void run() {
rule.service(payMessage, payService, exceptionHandler);
}
})
);
} else {
res = rule.service(payMessage, payService, exceptionHandler);
// 在同步操作结束session访问结束
if (LOG.isDebugEnabled()) {
LOG.debug("End session access: async=false, fromPay=" + payMessage.getFromPay());
}
}
}
if (futures.size() > 0) {
executorService.submit(new Runnable() {
@Override
public void run() {
for (Future future : futures) {
try {
future.get();
LOG.debug("End session access: async=true, fromPay=" + payMessage.getFromPay());
} catch (InterruptedException e) {
LOG.error("Error happened when wait task finish", e);
} catch (ExecutionException e) {
LOG.error("Error happened when wait task finish", e);
final List<PayMessageRouterRule> matchRules = new ArrayList<PayMessageRouterRule>();
// 收集匹配的规则
for (final PayMessageRouterRule rule : rules) {
if (rule.test(payMessage)) {
matchRules.add(rule);
if (!rule.isReEnter()) {
break;
}
}
}
}
});
if (matchRules.isEmpty()) {
return null;
}
PayOutMessage res = null;
final List<Future> futures = new ArrayList<Future>();
for (final PayMessageRouterRule rule : matchRules) {
// 返回最后一个非异步的rule的执行结果
if (rule.isAsync()) {
futures.add(
executorService.submit(new Runnable() {
@Override
public void run() {
rule.service(payMessage, payService, exceptionHandler);
}
})
);
} else {
res = rule.service(payMessage, payService, exceptionHandler);
// 在同步操作结束session访问结束
if (LOG.isDebugEnabled()) {
LOG.debug("End session access: async=false, fromPay=" + payMessage.getFromPay());
}
}
}
if (futures.size() > 0) {
executorService.submit(new Runnable() {
@Override
public void run() {
for (Future future : futures) {
try {
future.get();
LOG.debug("End session access: async=true, fromPay=" + payMessage.getFromPay());
} catch (InterruptedException e) {
LOG.error("Error happened when wait task finish", e);
} catch (ExecutionException e) {
LOG.error("Error happened when wait task finish", e);
}
}
}
});
}
return res;
}
return res;
}
}

View File

@@ -15,17 +15,17 @@ import java.util.Map;
* 支付服务
*
* @author egan
* <pre>
* email egzosn@gmail.com
* date 2016-5-18 14:09:01
*</pre>
* <pre>
* email egzosn@gmail.com
* date 2016-5-18 14:09:01
* </pre>
*/
public interface PayService<PC extends PayConfigStorage> {
/**
* 设置支付配置
*
* @param payConfigStorage 支付配置
* @return 支付服务
*/
@@ -37,6 +37,7 @@ public interface PayService<PC extends PayConfigStorage> {
* @return 支付配置
*/
PC getPayConfigStorage();
/**
* 获取http请求工具
*
@@ -46,8 +47,9 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 设置 请求工具配置 设置并创建请求模版, 代理请求配置这里是否合理??,
*
* @param configStorage http请求配置
* @return 支付服务
* @return 支付服务
*/
PayService setRequestTemplateConfigStorage(HttpConfigStorage configStorage);
@@ -72,6 +74,7 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 支付宝需要,微信是否也需要再次校验来源,进行订单查询
* 校验数据来源
*
* @param id 业务id, 数据的真实性.
* @return true通过
*/
@@ -85,14 +88,16 @@ public interface PayService<PC extends PayConfigStorage> {
* @return 订单信息
* @see PayOrder 支付订单信息
*/
Map<String, Object> orderInfo(PayOrder order);
Map<String, Object> orderInfo(PayOrder order);
/**
* 页面转跳支付, 返回对应页面重定向信息
*
* @param order 订单信息
* @return 对应页面重定向信息
*/
String toPay(PayOrder order);
/**
* 创建签名
*
@@ -123,7 +128,7 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 获取输出消息,用户返回给支付端
*
* @param code 状态
* @param code 状态
* @param message 消息
* @return 返回输出消息
*/
@@ -132,6 +137,7 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 获取成功输出消息,用户返回给支付端
* 主要用于拦截器中返回
*
* @param payMessage 支付回调消息
* @return 返回输出消息
*/
@@ -148,7 +154,6 @@ public interface PayService<PC extends PayConfigStorage> {
String buildRequest(Map<String, Object> orderInfo, MethodType method);
/**
* 获取输出二维码,用户返回给支付端,
*
@@ -163,7 +168,7 @@ public interface PayService<PC extends PayConfigStorage> {
* @param order 发起支付的订单信息
* @return 返回支付结果
*/
Map<String, Object> microPay(PayOrder order);
Map<String, Object> microPay(PayOrder order);
/**
* 交易查询接口
@@ -176,13 +181,14 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 交易查询接口,带处理器
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @return 返回查询回来的结果集
* @param callback 处理器
* @param <T> 返回类型
* @return 返回查询回来的结果集
*/
<T>T query(String tradeNo, String outTradeNo, Callback<T> callback);
<T> T query(String tradeNo, String outTradeNo, Callback<T> callback);
/**
* 交易关闭接口
@@ -199,11 +205,11 @@ public interface PayService<PC extends PayConfigStorage> {
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方交易关闭后的结果
*/
<T>T close(String tradeNo, String outTradeNo, Callback<T> callback);
<T> T close(String tradeNo, String outTradeNo, Callback<T> callback);
/**
* 交易交易撤销
@@ -219,55 +225,59 @@ public interface PayService<PC extends PayConfigStorage> {
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方交易撤销后的结果
*/
<T>T cancel(String tradeNo, String outTradeNo, Callback<T> callback);
<T> T cancel(String tradeNo, String outTradeNo, Callback<T> callback);
/**
* 申请退款接口
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder)
*/
@Deprecated
Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount);
/**
* 申请退款接口
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @param callback 处理器
* @param <T> 返回类型
* @param totalAmount 总金额
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
<T>T refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback);
<T> T refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback);
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
*/
Map<String, Object> refund(RefundOrder refundOrder);
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
*/
<T>T refund(RefundOrder refundOrder, Callback<T> callback);
<T> T refund(RefundOrder refundOrder, Callback<T> callback);
/**
* 查询退款
@@ -278,33 +288,36 @@ public interface PayService<PC extends PayConfigStorage> {
*/
@Deprecated
Map<String, Object> refundquery(String tradeNo, String outTradeNo);
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方查询退款后的结果
*/
@Deprecated
<T>T refundquery(String tradeNo, String outTradeNo, Callback<T> callback);
<T> T refundquery(String tradeNo, String outTradeNo, Callback<T> callback);
/**
* 查询退款
*
* @param refundOrder 退款订单单号信息
* @param refundOrder 退款订单单号信息
* @return 返回支付方查询退款后的结果
*/
Map<String, Object> refundquery(RefundOrder refundOrder);
/**
* 查询退款
*
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方查询退款后的结果
*/
<T>T refundquery(RefundOrder refundOrder, Callback<T> callback);
<T> T refundquery(RefundOrder refundOrder, Callback<T> callback);
/**
* 下载对账单
@@ -321,18 +334,19 @@ public interface PayService<PC extends PayConfigStorage> {
* @param billDate 账单时间:具体请查看对应支付平台
* @param billType 账单类型,具体请查看对应支付平台
* @param callback 处理器
* @param <T> 返回类型
* @param <T> 返回类型
* @return 返回支付方下载对账单的结果
*/
<T>T downloadbill(Date billDate, String billType, Callback<T> callback);
<T> T downloadbill(Date billDate, String billType, Callback<T> callback);
/**
* 通用查询接口
* @param tradeNoOrBillDate 支付平台订单号或者账单类型, 具体请
* 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
*
* @param tradeNoOrBillDate 支付平台订单号或者账单类型, 具体请
* 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @return 返回支付方对应接口的结果
*/
Map<String, Object> secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType);
@@ -340,56 +354,56 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 通用查询接口
*
* @param tradeNoOrBillDate 支付平台订单号或者账单日期, 具体请 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
*
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @param callback 处理器
* @param <T> 返回类型
* @param tradeNoOrBillDate 支付平台订单号或者账单日期, 具体请 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方对应接口的结果
*/
<T>T secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType, Callback<T> callback);
<T> T secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType, Callback<T> callback);
/**
* 转账
*
* @param order 转账订单
* @return 对应的转账结果
*/
Map<String, Object> transfer(TransferOrder order);
/**
* 转账
* @param order 转账订单
*
* @param order 转账订单
* @param callback 处理器
* @param <T> 返回类型
* @param <T> 返回类型
* @return 对应的转账结果
*/
<T>T transfer(TransferOrder order, Callback<T> callback);
<T> T transfer(TransferOrder order, Callback<T> callback);
/**
* 转账查询
*
* @param outNo 商户转账订单号
* @param outNo 商户转账订单号
* @param tradeNo 支付平台转账订单号
*
* @return 对应的转账订单
*/
Map<String, Object> transferQuery(String outNo, String tradeNo);
Map<String, Object> transferQuery(String outNo, String tradeNo);
/**
* 转账查询
*
* @param outNo 商户转账订单号
* @param tradeNo 支付平台转账订单号
* @param outNo 商户转账订单号
* @param tradeNo 支付平台转账订单号
* @param callback 处理器
* @param <T> 返回类型
* @param <T> 返回类型
* @return 对应的转账订单
*/
<T>T transferQuery(String outNo, String tradeNo, Callback<T> callback);
<T> T transferQuery(String outNo, String tradeNo, Callback<T> callback);
/**
/**
* 将请求参数或者请求流转化为 Map
*
* @param parameterMap 请求参数
@@ -400,29 +414,36 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 设置支付消息处理器,这里用于处理具体的支付业务
*
* @param handler 消息处理器
* 配合{@link com.egzosn.pay.common.api.PayService#payBack(java.util.Map, java.io.InputStream)}进行使用
*
* 默认使用{@link com.egzosn.pay.common.api.DefaultPayMessageHandler }进行实现
*
* 配合{@link com.egzosn.pay.common.api.PayService#payBack(java.util.Map, java.io.InputStream)}进行使用
* <p>
* 默认使用{@link com.egzosn.pay.common.api.DefaultPayMessageHandler }进行实现
*/
void setPayMessageHandler(PayMessageHandler handler);
/**
* 设置支付消息处理器,这里用于处理具体的支付业务
*
* @param interceptor 消息拦截器
* 配合{@link com.egzosn.pay.common.api.PayService#payBack(java.util.Map, java.io.InputStream)}进行使用
*
* 默认使用{@link com.egzosn.pay.common.api.DefaultPayMessageHandler }进行实现
*
* 配合{@link com.egzosn.pay.common.api.PayService#payBack(java.util.Map, java.io.InputStream)}进行使用
* <p>
* 默认使用{@link com.egzosn.pay.common.api.DefaultPayMessageHandler }进行实现
*/
void addPayMessageInterceptor(PayMessageInterceptor interceptor);
/**
* 获取支付请求地址
* 获取支付请求地址
*
* @param transactionType 交易类型
* @return 请求地址
*/
String getReqUrl(TransactionType transactionType);
String getReqUrl(TransactionType transactionType);
/**
* 创建消息
* @param message 支付平台返回的消息
* @return 支付消息对象
*/
PayMessage createMessage(Map<String, Object> message);
}

View File

@@ -24,12 +24,16 @@ public class PayMessage implements Serializable {
private String fromPay;
private String describe;
public PayMessage() {
}
public PayMessage(Map<String, Object> payMessage) {
this.payMessage = payMessage;
}
public PayMessage(Map<String, Object> payMessage, String payType, String msgType) {
this(payMessage);
this.payMessage = payMessage;
this.payType = payType;
this.msgType = msgType;
}
@@ -42,6 +46,10 @@ public class PayMessage implements Serializable {
this.transactionType = transactionType;
}
protected void setPayMessage(Map<String, Object> payMessage) {
this.payMessage = payMessage;
}
public String getMsgType() {
return msgType;
}

View File

@@ -2,6 +2,7 @@ package com.egzosn.pay.common.http;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.common.bean.MethodType;
import com.egzosn.pay.common.bean.result.PayException;
import com.egzosn.pay.common.exception.PayErrorException;
@@ -29,13 +30,14 @@ import static com.egzosn.pay.common.http.UriVariables.getMapToParameters;
/**
* 一个HTTP请求的客户端
*
* @author: egan
* <pre>
* <pre>
* email egzosn@gmail.com
* date 2017/3/4 17:56
* </pre>
*/
public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase implements org.apache.http.client.ResponseHandler<T>{
public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase implements org.apache.http.client.ResponseHandler<T> {
protected static final Log LOG = LogFactory.getLog(ClientHttpRequest.class);
public static final ContentType APPLICATION_FORM_URLENCODED_UTF_8 = ContentType.create("application/x-www-form-urlencoded", Consts.UTF_8);
@@ -49,7 +51,7 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
*/
private Charset defaultCharset;
/**
* 响应类型
* 响应类型
*/
private Class<T> responseType;
@@ -66,25 +68,28 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
}
/**
* 根据请求地址 请求方法,请求内容对象
* @param uri 请求地址
* @param method 请求方法
* @param request 请求内容
* 根据请求地址 请求方法,请求内容对象
*
* @param uri 请求地址
* @param method 请求方法
* @param request 请求内容
* @param defaultCharset 默认使用的响应编码
*/
public ClientHttpRequest(URI uri, MethodType method, Object request, String defaultCharset) {
this(uri, method);
this(uri, method);
setParameters(request);
if (StringUtils.isNotEmpty(defaultCharset)){
setDefaultCharset( Charset.forName(defaultCharset));
if (StringUtils.isNotEmpty(defaultCharset)) {
setDefaultCharset(Charset.forName(defaultCharset));
}
}
/**
* 根据请求地址 请求方法,请求内容对象
* @param uri 请求地址
* @param method 请求方法
* @param request 请求内容
* 根据请求地址 请求方法,请求内容对象
*
* @param uri 请求地址
* @param method 请求方法
* @param request 请求内容
* @param defaultCharset 默认使用的响应编码
*/
public ClientHttpRequest(URI uri, MethodType method, Object request, Charset defaultCharset) {
@@ -92,20 +97,24 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
setParameters(request);
setDefaultCharset(defaultCharset);
}
/**
* 根据请求地址 请求方法,请求内容对象
* @param uri 请求地址
* 根据请求地址 请求方法,请求内容对象
*
* @param uri 请求地址
* @param method 请求方法
* @param request 请求内容
*/
public ClientHttpRequest(URI uri, MethodType method, Object request) {
this(uri, method);
this(uri, method);
setParameters(request);
}
/**
* 根据请求地址 请求方法
* @param uri 请求地址
* @param method 请求方法
*
* @param uri 请求地址
* @param method 请求方法
*/
public ClientHttpRequest(URI uri, MethodType method) {
this.setURI(uri);
@@ -114,30 +123,37 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
/**
* 根据请求地址
* @param uri 请求地址
*
* @param uri 请求地址
*/
public ClientHttpRequest(URI uri) {
this.setURI(uri);
}
/**
* 根据请求地址
* @param uri 请求地址
*
* @param uri 请求地址
*/
public ClientHttpRequest(String uri) {
this.setURI(URI.create(uri));
}
/**
* 根据请求地址 请求方法
* @param uri 请求地址
* @param method 请求方法
*
* @param uri 请求地址
* @param method 请求方法
*/
public ClientHttpRequest(String uri, MethodType method) {
this.setURI(URI.create(uri));
this.method = method;
}
/**
* 根据请求地址 请求方法,请求内容对象
* @param uri 请求地址
* 根据请求地址 请求方法,请求内容对象
*
* @param uri 请求地址
* @param method 请求方法
* @param request 请求内容
*/
@@ -150,7 +166,7 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
* 设置请求方式
*
* @param method 请求方式
* {@link com.egzosn.pay.common.bean.MethodType} 请求方式
* {@link com.egzosn.pay.common.bean.MethodType} 请求方式
*/
public void setMethod(MethodType method) {
this.method = method;
@@ -158,6 +174,7 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
/**
* 获取请求方式
*
* @return 请求方式
*/
@Override
@@ -178,10 +195,11 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
/**
* 设置代理
*
* @param httpProxy http代理配置信息
* @return 当前HTTP请求的客户端
*/
public ClientHttpRequest setProxy(HttpHost httpProxy){
public ClientHttpRequest setProxy(HttpHost httpProxy) {
if (httpProxy != null) {
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
setConfig(config);
@@ -197,34 +215,34 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
* @return 当前HTTP请求的客户端
*/
public ClientHttpRequest setParameters(Object request) {
if (null == request){
if (null == request) {
return this;
}
if (request instanceof HttpHeader){
HttpHeader entity = (HttpHeader)request;
if (null != entity.getHeaders() ){
if (request instanceof HttpHeader) {
HttpHeader entity = (HttpHeader) request;
if (null != entity.getHeaders()) {
if (LOG.isDebugEnabled()) {
LOG.debug("header : " + JSON.toJSONString(entity.getHeaders()));
}
for (Header header : entity.getHeaders()){
for (Header header : entity.getHeaders()) {
addHeader(header);
}
}
}else if (request instanceof HttpStringEntity){
HttpStringEntity entity = (HttpStringEntity)request;
if (!entity.isEmpty()){
} else if (request instanceof HttpStringEntity) {
HttpStringEntity entity = (HttpStringEntity) request;
if (!entity.isEmpty()) {
setEntity(entity);
}
if (null != entity.getHeaders() ){
if (null != entity.getHeaders()) {
if (LOG.isDebugEnabled()) {
LOG.debug("header : " + JSON.toJSONString(entity.getHeaders()));
}
for (Header header : entity.getHeaders()){
for (Header header : entity.getHeaders()) {
addHeader(header);
}
}
} else if (request instanceof HttpEntity){
setEntity((HttpEntity)request);
} else if (request instanceof HttpEntity) {
setEntity((HttpEntity) request);
} else if (request instanceof Map) {
String parameters = getMapToParameters((Map) request);
if (LOG.isDebugEnabled()) {
@@ -236,7 +254,7 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
if (LOG.isDebugEnabled()) {
LOG.debug("Parameter : " + request);
}
StringEntity entity = new StringEntity((String) request, APPLICATION_FORM_URLENCODED_UTF_8);
StringEntity entity = new StringEntity((String) request, APPLICATION_FORM_URLENCODED_UTF_8);
setEntity(entity);
} else {
String body = JSON.toJSONString(request);
@@ -258,21 +276,21 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
final HttpEntity entity = response.getEntity();
String[] value = null;
if (null == entity.getContentType()){
if (null == entity.getContentType()) {
value = new String[]{"application/x-www-form-urlencoded"};
}else {
} else {
value = entity.getContentType().getValue().split(";");
}
//这里进行特殊处理,如果状态码非正常状态,但内容类型匹配至对应的结果也进行对应的响应类型转换
if (statusLine.getStatusCode() >= 300 && statusLine.getStatusCode() != 304) {
if (isJson(value[0], "") || isXml(value[0], "") ){
if (isJson(value[0], "") || isXml(value[0], "")) {
return toBean(entity, value);
}
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
if (null == responseType){
if (null == responseType) {
responseType = (Class<T>) String.class;
}
@@ -283,7 +301,8 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
/**
* 对请求进行转化至对应的可转化类型
* @param entity 响应实体
*
* @param entity 响应实体
* @param contentType 内容类型编码数组,第一个值为内容类型,第二个值为编码类型
* @return 对应的响应对象
* @throws IOException 响应类型文本转换时抛出异常
@@ -298,7 +317,7 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
//获取响应的文本内容
String result = EntityUtils.toString(entity, getDefaultCharset());
if (LOG.isDebugEnabled()){
if (LOG.isDebugEnabled()) {
LOG.debug("请求响应内容:\r\n" + result);
}
if (responseType.isAssignableFrom(String.class)) {
@@ -309,6 +328,9 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
//json类型
if (isJson(contentType[0], first)) {
try {
if (responseType.isAssignableFrom(JSONObject.class)) {
return (T)JSON.parseObject(result);
}
return JSON.parseObject(result, responseType);
} catch (JSONException e) {
throw new PayErrorException(new PayException("failure", String.format("类型转化异常,contentType: %s\n%s", entity.getContentType().getValue(), e.getMessage()), result));
@@ -317,8 +339,11 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
//xml类型
if (isXml(contentType[0], first)) {
try {
if (responseType.isAssignableFrom(JSONObject.class)) {
return (T) XML.toJSONObject(result, getDefaultCharset());
}
return XML.toJSONObject(result, getDefaultCharset()).toJavaObject(responseType);
}catch (Exception e){
} catch (Exception e) {
;
}
}
@@ -346,30 +371,34 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
/**
* 检测响应类型是否为json
*
* @param contentType 内容类型
* @param textFirst 文本第一个字符
* @param textFirst 文本第一个字符
* @return 布尔型, true为json内容类型
*/
private boolean isJson(String contentType, String textFirst){
return( ContentType.APPLICATION_JSON.getMimeType().equals(contentType) || "{[".indexOf(textFirst) >= 0 );
private boolean isJson(String contentType, String textFirst) {
return (ContentType.APPLICATION_JSON.getMimeType().equals(contentType) || "{[".indexOf(textFirst) >= 0);
}
/**
* 检测响应类型是否为文本类型
*
* @param contentType 内容类型
* @return 布尔型, true为文本内容类型
*/
private boolean isText(String contentType){
return contentType.contains("xml") || contentType.contains("json") || contentType.contains("text") || contentType.contains("form-data")|| contentType.contains("x-www-form-urlencoded");
private boolean isText(String contentType) {
return contentType.contains("xml") || contentType.contains("json") || contentType.contains("text") || contentType.contains("form-data") || contentType.contains("x-www-form-urlencoded");
}
/**
* 检测响应类型是否为xml
*
* @param contentType 内容类型
* @param textFirst 文本第一个字符
* @param textFirst 文本第一个字符
* @return 布尔型, true为xml内容类型
*/
private boolean isXml(String contentType, String textFirst){
return( ContentType.APPLICATION_XML.getMimeType().equals(contentType) || "<".indexOf(textFirst) >= 0 );
private boolean isXml(String contentType, String textFirst) {
return (ContentType.APPLICATION_XML.getMimeType().equals(contentType) || "<".indexOf(textFirst) >= 0);
}

View File

@@ -1,8 +1,11 @@
package com.egzosn.pay.common.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.util.Args;
import java.lang.ref.SoftReference;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -16,7 +19,10 @@ import java.util.*;
* </pre>
*/
public final class DateUtils {
private DateUtils() {
}
private static final Log LOG = LogFactory.getLog(DateUtils.class);
static final class DateFormatHolder {
private static final ThreadLocal<SoftReference<Map<String, SimpleDateFormat>>> THREADLOCAL_FORMATS = new ThreadLocal<SoftReference<Map<String, SimpleDateFormat>>>();
@@ -60,11 +66,28 @@ public final class DateUtils {
SimpleDateFormat formatFor = DateFormatHolder.formatFor(pattern);
return formatFor.format(date);
}
public static Date parseDate(String date, String pattern) {
Args.notNull(date, "Date");
Args.notNull(pattern, "Pattern");
SimpleDateFormat formatFor = DateFormatHolder.formatFor(pattern);
try {
return formatFor.parse(date);
} catch (ParseException e) {
LOG.error(e);
}
return null;
}
public static Date parse(String date) {
return parseDate(date, YYYY_MM_DD_HH_MM_SS);
}
public static final String format(Date date) {
return formatDate(date, YYYY_MM_DD_HH_MM_SS);
}
public static final Date parseDay(String date) {
return parseDate(date, YYYY_MM_DD);
}
public static final String formatDay(Date date) {
return formatDate(date, YYYY_MM_DD);
}

View File

@@ -80,13 +80,7 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- /spring -->
<dependency>

View File

@@ -323,8 +323,19 @@ public class PayController {
//校验
if (payResponse.getService().verify(params)) {
PayMessage message = new PayMessage(params, storage.getPayType(), storage.getMsgType().name());
PayOutMessage outMessage = payResponse.getRouter().route(message);
//方式一 或者创建PayMessage的子类AliPayMessageWxPayMessage等等
/* PayMessage message = new PayMessage(params, storage.getPayType(), storage.getMsgType().name());
PayOutMessage outMessage = payResponse.getRouter().route(message);*/
//方式二
/*PayMessage message = payResponse.getService().createMessage(params);
message.setPayType(storage.getPayType());
message.setMsgType(storage.getMsgType().name());
PayOutMessage outMessage = payResponse.getRouter().route(message);
*/
//方式三
PayOutMessage outMessage = payResponse.getRouter().route(params, storage);
return outMessage.toMessage();
}

View File

@@ -33,7 +33,7 @@ public class ApyAccountRepository {
apyAccount1.setAppid("2016080400165436");
// TODO 2017/2/9 16:20 author: egan sign_type只有单一key时public_key与private_key相等比如sign_type=MD5的情况
apyAccount1.setPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIgHnOn7LLILlKETd6BFRJ0GqgS2Y3mn1wMQmyh9zEyWlz5p1zrahRahbXAfCfSqshSNfqOmAQzSHRVjCqjsAw1jyqrXaPdKBmr90DIpIxmIyKXv4GGAkPyJ/6FTFY99uhpiq0qadD/uSzQsefWo0aTvP/65zi3eof7TcZ32oWpwIDAQAB");
apyAccount1.setPrivateKey("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKroe/8h5vC4L6T+B2WdXiVwGsMvUKgb2XsKix6VY3m2wcf6tyzpNRDCNykbIwGtaeo7FshN+qZxdXHLiIam9goYncBit/8ojfLGy2gLxO/PXfzGxYGs0KsDZ+ryVPPmE34ZZ8jiJpR0ygzCFl8pN3QJPJRGTJn5+FTT9EF/9zyZAgMBAAECgYAktngcYC35u7cQXDk+jMVyiVhWYU2ULxdSpPspgLGzrZyG1saOcTIi/XVX8Spd6+B6nmLQeF/FbU3rOeuD8U2clzul2Z2YMbJ0FYay9oVZFfp5gTEFpFRTVfzqUaZQBIjJe/xHL9kQVqc5xHlE/LVA27/Kx3dbC35Y7B4EVBDYAQJBAOhsX8ZreWLKPhXiXHTyLmNKhOHJc+0tFH7Ktise/0rNspojU7o9prOatKpNylp9v6kux7migcMRdVUWWiVe+4ECQQC8PqsuEz7B0yqirQchRg1DbHjh64bw9Kj82EN1/NzOUd53tP9tg+SO97EzsibK1F7tOcuwqsa7n2aY48mQ+y0ZAkBndA2xcRcnvOOjtAz5VO8G7R12rse181HjGfG6AeMadbKg30aeaGCyIxN1loiSfNR5xsPJwibGIBg81mUrqzqBAkB+K6rkaPXJR9XtzvdWb/N3235yPkDlw7Z4MiOVM3RzvR/VMDV7m8lXoeDde2zQyeMOMYy6ztwA6WgE1bhGOnQRAkEAouUBv1sVdSBlsexX15qphOmAevzYrpufKgJIRLFWQxroXMS7FTesj+f+FmGrpPCxIde1dqJ8lqYLTyJmbzMPYw==\n");
apyAccount1.setPrivateKey("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKroe/8h5vC4L6T+B2WdXiVwGsMvUKgb2XsKix6VY3m2wcf6tyzpNRDCNykbIwGtaeo7FshN+qZxdXHLiIam9goYncBit/8ojfLGy2gLxO/PXfzGxYGs0KsDZ+ryVPPmE34ZZ8jiJpR0ygzCFl8pN3QJPJRGTJn5+FTT9EF/9zyZAgMBAAECgYAktngcYC35u7cQXDk+jMVyiVhWYU2ULxdSpPspgLGzrZyG1saOcTIi/XVX8Spd6+B6nmLQeF/FbU3rOeuD8U2clzul2Z2YMbJ0FYay9oVZFfp5gTEFpFRTVfzqUaZQBIjJe/xHL9kQVqc5xHlE/LVA27/Kx3dbC35Y7B4EVBDYAQJBAOhsX8ZreWLKPhXiXHTyLmNKhOHJc+0tFH7Ktise/0rNspojU7o9prOatKpNylp9v6kux7migcMRdVUWWiVe+4ECQQC8PqsuEz7B0yqirQchRg1DbHjh64bw9Kj82EN1/NzOUd53tP9tg+SO97EzsibK1F7tOcuwqsa7n2aY48mQ+y0ZAkBndA2xcRcnvOOjtAz5VO8G7R12rse181HjGfG6AeMadbKg30aeaGCyIxN1loiSfNR5xsPJwibGIBg81mUrqzqBAkB+K6rkaPXJR9XtzvdWb/N3235yPkDlw7Z4MiOVM3RzvR/VMDV7m8lXoeDde2zQyeMOMYy6ztwA6WgE1bhGOnQRAkEAouUBv1sVdSBlsexX15qphOmAevzYrpufKgJIRLFWQxroXMS7FTesj+f+FmGrpPCxIde1dqJ8lqYLTyJmbzMPYw==");
apyAccount1.setNotifyUrl("http://pay.egzosn.com/payBack1.json");
// 无需同步回调可不填
apyAccount1.setReturnUrl("http://pay.egzosn.com/payBack1.json");

View File

@@ -1,5 +1,7 @@
package com.egzosn.pay.demo.service.handler;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliPayMessage;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
@@ -17,14 +19,20 @@ import java.util.Map;
*
*/
@Component
public class AliPayMessageHandler implements PayMessageHandler {
public class AliPayMessageHandler implements PayMessageHandler<AliPayMessage, AliPayService> {
/**
* 处理支付回调消息的处理器接口
*
* @param payMessage 支付消息
* @param context 上下文如果handler或interceptor之间有信息要传递可以用这个
* @param payService 支付服务
* @return xml, text格式的消息如果在异步规则里处理的话可以返回null
* @throws PayErrorException 支付错误异常
*/
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(AliPayMessage payMessage, Map<String, Object> context, AliPayService payService) throws PayErrorException {
//com.egzosn.pay.demo.entity.PayType.getPayService()#48
Object payId = payService.getPayConfigStorage().getAttach();

View File

@@ -1,12 +1,14 @@
package com.egzosn.pay.demo.service.handler;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
/**
*
* Created by ZaoSheng on 2016/6/1.
*/
public abstract class BasePayMessageHandler implements PayMessageHandler {
public abstract class BasePayMessageHandler<M extends PayMessage, S extends PayService> implements PayMessageHandler<M, S> {
//支付账户id
private Integer payId;

View File

@@ -21,7 +21,7 @@ public class FuiouPayMessageHandler extends BasePayMessageHandler {
}
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(PayMessage payMessage, Map context, PayService payService) throws PayErrorException {
//交易状态
if ("0000".equals(payMessage.getPayMessage().get("order_pay_code"))){
/////这里进行成功的处理

View File

@@ -5,6 +5,7 @@ import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.paypal.api.PayPalPayService;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
@@ -16,14 +17,14 @@ import java.util.Map;
*
*/
@Component
public class PayPalPayMessageHandler implements PayMessageHandler {
public class PayPalPayMessageHandler implements PayMessageHandler<PayMessage, PayPalPayService> {
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayPalPayService payService) throws PayErrorException {
return payService.getPayOutMessage("fail", "失败");

View File

@@ -22,7 +22,7 @@ public class PayoneerMessageHandler extends BasePayMessageHandler {
}
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(PayMessage payMessage, Map context, PayService payService) throws PayErrorException {
//交易状态
if ("0".equals(payMessage.getPayMessage().get(PayoneerPayService.CODE))) {
/////这里进行成功的处理

View File

@@ -1,10 +1,10 @@
package com.egzosn.pay.demo.service.handler;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.union.api.UnionPayService;
import com.egzosn.pay.union.bean.SDKConstants;
import com.egzosn.pay.union.bean.UnionPayMessage;
import java.util.Map;
@@ -15,7 +15,7 @@ import java.util.Map;
* create 2017 2017/11/4 0004
* </pre>
*/
public class UnionPayMessageHandler extends BasePayMessageHandler {
public class UnionPayMessageHandler extends BasePayMessageHandler<UnionPayMessage, UnionPayService> {
public UnionPayMessageHandler(Integer payId) {
@@ -23,7 +23,7 @@ public class UnionPayMessageHandler extends BasePayMessageHandler {
}
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(UnionPayMessage payMessage, Map<String, Object> context, UnionPayService payService) throws PayErrorException {
//交易状态
if (SDKConstants.OK_RESP_CODE.equals(payMessage.getPayMessage().get(SDKConstants.param_respCode))) {
/////这里进行成功的处理

View File

@@ -1,9 +1,9 @@
package com.egzosn.pay.demo.service.handler;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.wx.bean.WxPayMessage;
import java.util.Map;
@@ -11,7 +11,7 @@ import java.util.Map;
* 微信支付回调处理器
* Created by ZaoSheng on 2016/6/1.
*/
public class WxPayMessageHandler extends BasePayMessageHandler {
public class WxPayMessageHandler extends BasePayMessageHandler<WxPayMessage, PayService> {
@@ -21,7 +21,7 @@ public class WxPayMessageHandler extends BasePayMessageHandler {
}
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(WxPayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
//交易状态
if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))){
/////这里进行成功的处理

View File

@@ -2,9 +2,9 @@ package com.egzosn.pay.demo.service.handler;
import com.alibaba.fastjson.JSON;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.wx.youdian.bean.WxYoudianPayMessage;
import java.util.Map;
@@ -12,7 +12,7 @@ import java.util.Map;
* @author Fuzx
* create 2017 2017/1/24 0024
*/
public class YouDianPayMessageHandler extends BasePayMessageHandler {
public class YouDianPayMessageHandler extends BasePayMessageHandler<WxYoudianPayMessage, PayService> {
@@ -22,7 +22,7 @@ public class YouDianPayMessageHandler extends BasePayMessageHandler {
}
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public PayOutMessage handle(WxYoudianPayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
//交易状态
Map<String, Object> message = payMessage.getPayMessage();
//上下文对象中获取账单

View File

@@ -1,6 +1,8 @@
package com.egzosn.pay.demo.service.interceptor;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliPayMessage;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayMessageInterceptor;
import com.egzosn.pay.common.api.PayService;
@@ -15,7 +17,7 @@ import java.util.Map;
* email egzosn@gmail.com
* date 2017/1/18 19:28
*/
public class AliPayMessageInterceptor implements PayMessageInterceptor {
public class AliPayMessageInterceptor implements PayMessageInterceptor<AliPayMessage, AliPayService> {
/**
* 拦截支付消息
@@ -28,7 +30,7 @@ public class AliPayMessageInterceptor implements PayMessageInterceptor {
* @throws PayErrorException PayErrorException*
*/
@Override
public boolean intercept(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public boolean intercept(AliPayMessage payMessage, Map<String, Object> context, AliPayService payService) throws PayErrorException {
//这里进行拦截器处理,自行实现
String outTradeNo = payMessage.getOutTradeNo();

View File

@@ -6,6 +6,7 @@ import com.egzosn.pay.common.api.PayMessageInterceptor;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.wx.youdian.bean.WxYoudianPayMessage;
import java.util.Map;
@@ -15,7 +16,7 @@ import java.util.Map;
* email egzosn@gmail.com
* date 2017/1/18 19:28
*/
public class YoudianPayMessageInterceptor implements PayMessageInterceptor {
public class YoudianPayMessageInterceptor implements PayMessageInterceptor<WxYoudianPayMessage, PayService> {
// @Autowired
// private AmtApplyService amtApplyService;
@@ -31,7 +32,7 @@ public class YoudianPayMessageInterceptor implements PayMessageInterceptor {
* @throws PayErrorException PayErrorException
*/
@Override
public boolean intercept(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
public boolean intercept(WxYoudianPayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
//这里进行拦截器处理,自行实现

View File

@@ -17,6 +17,7 @@ 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.bean.SDKConstants;
import com.egzosn.pay.union.bean.UnionPayMessage;
import com.egzosn.pay.union.bean.UnionTransactionType;
import java.awt.image.BufferedImage;
@@ -688,6 +689,14 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
}
/**
* 创建消息
*
* @param message 支付平台返回的消息
* @return 支付消息对象
*/
@Override
public PayMessage createMessage(Map<String, Object> message) {
return UnionPayMessage.create(message);
}
}

View File

@@ -0,0 +1,354 @@
package com.egzosn.pay.union.bean;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.egzosn.pay.common.bean.PayMessage;
import java.math.BigDecimal;
import java.util.Map;
/**
* 银联回调信息
*
* @author egan
* <pre>
* email egzosn@gmail.com
* date 2019/7/3.22:07
* </pre>
*/
public class UnionPayMessage extends PayMessage {
// 查询流水号 queryId AN20..21 M-必填 消费交易的流水号,供后续查询用
private String queryId;
// 交易币种 currencyCode AN3 M-必填 默认为156
private String currencyCode;
// 交易传输时间 traceTime MMDDhhmmss M-必填
@JSONField(name = "traceTime", format = "MMDDhhmmss")
private String traceTime;
// 签名 signature ANS1..1024 M-必填
private String signature;
// 签名方法 signMethod N2 M-必填
private String signMethod;
// 清算币种 settleCurrencyCode AN3 M-必填
private String settleCurrencyCode;
// 清算金额 settleAmt N1..12 M-必填
private BigDecimal settleAmt;
// 清算日期 settleDate MMDD M-必填
@JSONField(name = "settleDate", format = "MMDD")
private String settleDate;
// 系统跟踪号 traceNo N6 M-必填
private String traceNo;
// 应答码 respCode AN2 M-必填
private String respCode;
// 应答信息 respMsg ANS1..256 M-必填
private String respMsg;
// 兑换日期 exchangeDate MMDD C-按条件必填 交易成功,交易币种和清算币种不一致的时候返回
@JSONField(name = "exchangeDate", format = "MMDD")
private String exchangeDate;
// 签名公钥证书 signPubKeyCert AN1..2048 C-按条件必填 使用RSA签名方式时必选此域填写银联签名公钥证书。
private String signPubKeyCert;
// 清算汇率 exchangeRate N8 C-按条件必填 交易成功,交易币种和清算币种不一致的时候返回
private String exchangeRate;
// 账号 accNo AN1..1024 C-按条件必填 根据商户配置返回
private String accNo;
// 支付方式 payType N4 C-按条件必填 根据商户配置返回
private String payType;
// 支付卡标识 payCardNo ANS1..19 C-按条件必填 移动支付交易时,根据商户配置返回
private String payCardNo;
// 支付卡类型 payCardType N2 C-按条件必填 根据商户配置返回
private String payCardType;
// 支付卡名称 payCardIssueName ANS1..64 C-按条件必填 移动支付交易时,根据商户配置返回
private String payCardIssueName;
// 版本号 version NS5 R-需要返回
private String version;
// 绑定标识号 bindId ANS1..128 R-需要返回 绑定支付时,根据商户配置返回
private String bindId;
// 编码方式 encoding ANS1..20 R-需要返回
private String encoding;
// 产品类型 bizType N6 R-需要返回
private String bizType;
// 订单发送时间 txnTime YYYYMMDDhhmmss R-需要返回
@JSONField(name = "txnTime", format = "YYYYMMDDhhmmss")
private String txnTime;
// 交易金额 txnAmt N1..12 R-需要返回
private BigDecimal txnAmt;
// 交易类型 txnType N2 R-需要返回
private String txnType;
// 交易子类 txnSubType N2 R-需要返回
private String txnSubType;
// 接入类型 accessType N1 R-需要返回 0商户直连接入 1收单机构接入2平台商户接入
private String accessType;
// 请求方保留域 reqReserved ANS1..1024 R-需要返回
private String reqReserved;
// 商户代码 merId AN15 R-需要返回
private String merId;
// 商户订单号 orderId AN8..40 R-需要返回 商户订单号,不能含“-”或“_”; 商户自定义,同一交易日期内不可重复; 商户代码merId、商户订单号orderId、订单发送时间txnTime三要素唯一确定一笔交易。 保留域 reserved ANS1..2048O- 选填 查看详情
private String orderId;
// 分账域 accSplitData ANS1..512O- 选填 查看详情
private String accSplitData;
public String getQueryId() {
return queryId;
}
public void setQueryId(String queryId) {
this.queryId = queryId;
}
public String getCurrencyCode() {
return currencyCode;
}
public void setCurrencyCode(String currencyCode) {
this.currencyCode = currencyCode;
}
public String getTraceTime() {
return traceTime;
}
public void setTraceTime(String traceTime) {
this.traceTime = traceTime;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getSignMethod() {
return signMethod;
}
public void setSignMethod(String signMethod) {
this.signMethod = signMethod;
}
public String getSettleCurrencyCode() {
return settleCurrencyCode;
}
public void setSettleCurrencyCode(String settleCurrencyCode) {
this.settleCurrencyCode = settleCurrencyCode;
}
public BigDecimal getSettleAmt() {
return settleAmt;
}
public void setSettleAmt(BigDecimal settleAmt) {
this.settleAmt = settleAmt;
}
public String getSettleDate() {
return settleDate;
}
public void setSettleDate(String settleDate) {
this.settleDate = settleDate;
}
public String getTraceNo() {
return traceNo;
}
public void setTraceNo(String traceNo) {
this.traceNo = traceNo;
}
public String getRespCode() {
return respCode;
}
public void setRespCode(String respCode) {
this.respCode = respCode;
}
public String getRespMsg() {
return respMsg;
}
public void setRespMsg(String respMsg) {
this.respMsg = respMsg;
}
public String getExchangeDate() {
return exchangeDate;
}
public void setExchangeDate(String exchangeDate) {
this.exchangeDate = exchangeDate;
}
public String getSignPubKeyCert() {
return signPubKeyCert;
}
public void setSignPubKeyCert(String signPubKeyCert) {
this.signPubKeyCert = signPubKeyCert;
}
public String getExchangeRate() {
return exchangeRate;
}
public void setExchangeRate(String exchangeRate) {
this.exchangeRate = exchangeRate;
}
public String getAccNo() {
return accNo;
}
public void setAccNo(String accNo) {
this.accNo = accNo;
}
@Override
public String getPayType() {
return payType;
}
@Override
public void setPayType(String payType) {
this.payType = payType;
}
public String getPayCardNo() {
return payCardNo;
}
public void setPayCardNo(String payCardNo) {
this.payCardNo = payCardNo;
}
public String getPayCardType() {
return payCardType;
}
public void setPayCardType(String payCardType) {
this.payCardType = payCardType;
}
public String getPayCardIssueName() {
return payCardIssueName;
}
public void setPayCardIssueName(String payCardIssueName) {
this.payCardIssueName = payCardIssueName;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getBindId() {
return bindId;
}
public void setBindId(String bindId) {
this.bindId = bindId;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getBizType() {
return bizType;
}
public void setBizType(String bizType) {
this.bizType = bizType;
}
public String getTxnTime() {
return txnTime;
}
public void setTxnTime(String txnTime) {
this.txnTime = txnTime;
}
public BigDecimal getTxnAmt() {
return txnAmt;
}
public void setTxnAmt(BigDecimal txnAmt) {
this.txnAmt = txnAmt;
}
public String getTxnType() {
return txnType;
}
public void setTxnType(String txnType) {
this.txnType = txnType;
}
public String getTxnSubType() {
return txnSubType;
}
public void setTxnSubType(String txnSubType) {
this.txnSubType = txnSubType;
}
public String getAccessType() {
return accessType;
}
public void setAccessType(String accessType) {
this.accessType = accessType;
}
public String getReqReserved() {
return reqReserved;
}
public void setReqReserved(String reqReserved) {
this.reqReserved = reqReserved;
}
public String getMerId() {
return merId;
}
public void setMerId(String merId) {
this.merId = merId;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getAccSplitData() {
return accSplitData;
}
public void setAccSplitData(String accSplitData) {
this.accSplitData = accSplitData;
}
public static final UnionPayMessage create(Map<String, Object> message) {
UnionPayMessage payMessage = new JSONObject(message).toJavaObject(UnionPayMessage.class);
payMessage.setPayMessage(message);
return payMessage;
}
}

View File

@@ -11,6 +11,7 @@ import com.egzosn.pay.common.util.MatrixToImageWriter;
import com.egzosn.pay.common.util.Util;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import com.egzosn.pay.wx.youdian.bean.WxYoudianPayMessage;
import com.egzosn.pay.wx.youdian.bean.YdPayError;
import com.egzosn.pay.wx.youdian.bean.YoudianTransactionType;
import java.awt.image.BufferedImage;
@@ -463,4 +464,15 @@ public class WxYouDianPayService extends BasePayService<WxYouDianPayConfigStorag
return URL + type.getMethod();
}
/**
* 创建消息
*
* @param message 支付平台返回的消息
* @return 支付消息对象
*/
@Override
public PayMessage createMessage(Map<String, Object> message) {
return WxYoudianPayMessage.create(message);
}
}

View File

@@ -0,0 +1,327 @@
package com.egzosn.pay.wx.youdian.bean;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.egzosn.pay.common.bean.PayMessage;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
/**
* 友店回调信息
*
* @author egan
* email egzosn@gmail.com
* date 2019/7/3.20:25
*/
public class WxYoudianPayMessage extends PayMessage {
// 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID企业号corpid即为此appId
@JSONField(name = "appid")
private String appid;
// 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号
@JSONField(name = "mch_id")
private String mchId;
// 设备号 device_info 否 String(32) 013467007045764 微信支付分配的终端设备号,
@JSONField(name = "device_info")
private String deviceInfo;
// 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串不长于32位
@JSONField(name = "nonce_str")
private String nonceStr;
// 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名算法
@JSONField(name = "sign")
private String sign;
// 签名类型 sign_type 否 String(32) HMAC-SHA256 签名类型目前支持HMAC-SHA256和MD5默认为MD5
@JSONField(name = "sign_type")
private String signType;
// 业务结果 result_code 是 String(16) SUCCESS SUCCESS/FAIL
@JSONField(name = "result_code")
private String resultCode;
// 错误代码 err_code 否 String(32) SYSTEMERROR 错误返回的信息描述
@JSONField(name = "err_code")
private String errCode;
// 错误代码描述 err_code_des 否 String(128) 系统错误 错误返回的信息描述
@JSONField(name = "err_code_des")
private String errCodeDes;
// 用户标识 openid 是 String(128) wxd930ea5d5a258f4f 用户在商户appid下的唯一标识
@JSONField(name = "openid")
private String openid;
// 是否关注公众账号 is_subscribe 是 String(1) Y 用户是否关注公众账号Y-关注N-未关注
@JSONField(name = "is_subscribe")
private String isSubscribe;
// 交易类型 trade_type 是 String(16) JSAPI JSAPI、NATIVE、APP
@JSONField(name = "trade_type")
private String tradeType;
// 付款银行 bank_type 是 String(16) CMC 银行类型,采用字符串类型的银行标识,银行类型见银行列表
@JSONField(name = "bank_type")
private String bankType;
// 订单金额 total_fee 是 Int 100 订单总金额,单位为分
@JSONField(name = "total_fee")
private BigDecimal totalFee;
// 应结订单金额 settlement_total_fee 否 Int 100 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
@JSONField(name = "settlement_total_fee")
private BigDecimal settlementTotalFee;
// 货币种类 fee_type 否 String(8) CNY 货币类型符合ISO4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
@JSONField(name = "fee_type")
private String feeType;
// 现金支付金额 cash_fee 是 Int 100 现金支付金额订单现金支付金额,详见支付金额
@JSONField(name = "cash_fee")
private BigDecimal cashFee;
// 现金支付货币类型 cash_fee_type 否 String(16) CNY 货币类型符合ISO4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
@JSONField(name = "cash_fee_type")
private String cashFeeType;
// 总代金券金额 coupon_fee 否 Int 10 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额
@JSONField(name = "coupon_fee")
private BigDecimal couponFee;
// 代金券使用数量 coupon_count 否 Int 1 代金券使用数量
@JSONField(name = "coupon_count")
private Integer couponCount;
// 代金券类型 coupon_type_$n 否 String CASH CASH--充值代金券 NO_CASH---非充值代金券 并且订单使用了免充值券后有返回取值CASH、NO_CASH。$n为下标,从0开始编号举例coupon_type_0
@JSONField(name = "coupon_type_$0")
private String couponType0;
// 代金券ID coupon_id_$n 否 String(20) 10000 代金券ID,$n为下标从0开始编号
@JSONField(name = "coupon_id_$0")
private String couponId0;
// 单个代金券支付金额 coupon_fee_$n 否 Int 100 单个代金券支付金额,$n为下标从0开始编号
@JSONField(name = "coupon_fee_$0")
private Integer couponFee0;
// 微信支付订单号 transaction_id 是 String(32) 1217752501201407033233368018 微信支付订单号
@JSONField(name = "transaction_id")
private String transactionId;
// 商户订单号 out_trade_no 是 String(32) 1212321211201407033568112322 商户系统内部订单号要求32个字符内只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
@JSONField(name = "out_trade_no")
private String outTradeNo;
// 商家数据包 attach 否 String(128) 123456 商家数据包,原样返回
@JSONField(name = "attach")
private String attach;
// 支付完成时间 time_end 是 String(14) 20141030133525 支付完成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
@JSONField(name = "time_end", format="yyyyMMddHHmmss")
private Date timeEnd;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public String getNonceStr() {
return nonceStr;
}
public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}
@Override
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getSignType() {
return signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getErrCode() {
return errCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
}
public String getErrCodeDes() {
return errCodeDes;
}
public void setErrCodeDes(String errCodeDes) {
this.errCodeDes = errCodeDes;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getIsSubscribe() {
return isSubscribe;
}
public void setIsSubscribe(String isSubscribe) {
this.isSubscribe = isSubscribe;
}
public String getTradeType() {
return tradeType;
}
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
public String getBankType() {
return bankType;
}
public void setBankType(String bankType) {
this.bankType = bankType;
}
@Override
public BigDecimal getTotalFee() {
return totalFee;
}
public void setTotalFee(BigDecimal totalFee) {
this.totalFee = totalFee;
}
public BigDecimal getSettlementTotalFee() {
return settlementTotalFee;
}
public void setSettlementTotalFee(BigDecimal settlementTotalFee) {
this.settlementTotalFee = settlementTotalFee;
}
public String getFeeType() {
return feeType;
}
public void setFeeType(String feeType) {
this.feeType = feeType;
}
public BigDecimal getCashFee() {
return cashFee;
}
public void setCashFee(BigDecimal cashFee) {
this.cashFee = cashFee;
}
public String getCashFeeType() {
return cashFeeType;
}
public void setCashFeeType(String cashFeeType) {
this.cashFeeType = cashFeeType;
}
public BigDecimal getCouponFee() {
return couponFee;
}
public void setCouponFee(BigDecimal couponFee) {
this.couponFee = couponFee;
}
public Integer getCouponCount() {
return couponCount;
}
public void setCouponCount(Integer couponCount) {
this.couponCount = couponCount;
}
public String getCouponType0() {
return couponType0;
}
public void setCouponType0(String couponType0) {
this.couponType0 = couponType0;
}
public String getCouponId0() {
return couponId0;
}
public void setCouponId0(String couponId0) {
this.couponId0 = couponId0;
}
public Integer getCouponFee0() {
return couponFee0;
}
public void setCouponFee0(Integer couponFee0) {
this.couponFee0 = couponFee0;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
@Override
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public Date getTimeEnd() {
return timeEnd;
}
public void setTimeEnd(Date timeEnd) {
this.timeEnd = timeEnd;
}
public static final WxYoudianPayMessage create(Map<String, Object> message) {
WxYoudianPayMessage payMessage = new JSONObject(message).toJavaObject(WxYoudianPayMessage.class);
payMessage.setPayMessage(message);
return payMessage;
}
}

View File

@@ -14,6 +14,7 @@ import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.sign.encrypt.RSA2;
import com.egzosn.pay.common.util.str.StringUtils;
import com.egzosn.pay.wx.bean.WxPayError;
import com.egzosn.pay.wx.bean.WxPayMessage;
import com.egzosn.pay.wx.bean.WxTransactionType;
import com.egzosn.pay.common.util.XML;
import com.egzosn.pay.wx.bean.WxTransferType;
@@ -753,5 +754,14 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
}
}
/**
* 创建消息
*
* @param message 支付平台返回的消息
* @return 支付消息对象
*/
@Override
public PayMessage createMessage(Map<String, Object> message) {
return WxPayMessage.create(message);
}
}

View File

@@ -0,0 +1,327 @@
package com.egzosn.pay.wx.bean;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.egzosn.pay.common.bean.PayMessage;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
/**
* 微信回调信息
*
* @author egan
* email egzosn@gmail.com
* date 2019/7/3.20:25
*/
public class WxPayMessage extends PayMessage {
// 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID企业号corpid即为此appId
@JSONField(name = "appid")
private String appid;
// 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号
@JSONField(name = "mch_id")
private String mchId;
// 设备号 device_info 否 String(32) 013467007045764 微信支付分配的终端设备号,
@JSONField(name = "device_info")
private String deviceInfo;
// 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串不长于32位
@JSONField(name = "nonce_str")
private String nonceStr;
// 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名算法
@JSONField(name = "sign")
private String sign;
// 签名类型 sign_type 否 String(32) HMAC-SHA256 签名类型目前支持HMAC-SHA256和MD5默认为MD5
@JSONField(name = "sign_type")
private String signType;
// 业务结果 result_code 是 String(16) SUCCESS SUCCESS/FAIL
@JSONField(name = "result_code")
private String resultCode;
// 错误代码 err_code 否 String(32) SYSTEMERROR 错误返回的信息描述
@JSONField(name = "err_code")
private String errCode;
// 错误代码描述 err_code_des 否 String(128) 系统错误 错误返回的信息描述
@JSONField(name = "err_code_des")
private String errCodeDes;
// 用户标识 openid 是 String(128) wxd930ea5d5a258f4f 用户在商户appid下的唯一标识
@JSONField(name = "openid")
private String openid;
// 是否关注公众账号 is_subscribe 是 String(1) Y 用户是否关注公众账号Y-关注N-未关注
@JSONField(name = "is_subscribe")
private String isSubscribe;
// 交易类型 trade_type 是 String(16) JSAPI JSAPI、NATIVE、APP
@JSONField(name = "trade_type")
private String tradeType;
// 付款银行 bank_type 是 String(16) CMC 银行类型,采用字符串类型的银行标识,银行类型见银行列表
@JSONField(name = "bank_type")
private String bankType;
// 订单金额 total_fee 是 Int 100 订单总金额,单位为分
@JSONField(name = "total_fee")
private BigDecimal totalFee;
// 应结订单金额 settlement_total_fee 否 Int 100 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
@JSONField(name = "settlement_total_fee")
private BigDecimal settlementTotalFee;
// 货币种类 fee_type 否 String(8) CNY 货币类型符合ISO4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
@JSONField(name = "fee_type")
private String feeType;
// 现金支付金额 cash_fee 是 Int 100 现金支付金额订单现金支付金额,详见支付金额
@JSONField(name = "cash_fee")
private BigDecimal cashFee;
// 现金支付货币类型 cash_fee_type 否 String(16) CNY 货币类型符合ISO4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
@JSONField(name = "cash_fee_type")
private String cashFeeType;
// 总代金券金额 coupon_fee 否 Int 10 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额
@JSONField(name = "coupon_fee")
private BigDecimal couponFee;
// 代金券使用数量 coupon_count 否 Int 1 代金券使用数量
@JSONField(name = "coupon_count")
private Integer couponCount;
// 代金券类型 coupon_type_$n 否 String CASH CASH--充值代金券 NO_CASH---非充值代金券 并且订单使用了免充值券后有返回取值CASH、NO_CASH。$n为下标,从0开始编号举例coupon_type_0
@JSONField(name = "coupon_type_$0")
private String couponType0;
// 代金券ID coupon_id_$n 否 String(20) 10000 代金券ID,$n为下标从0开始编号
@JSONField(name = "coupon_id_$0")
private String couponId0;
// 单个代金券支付金额 coupon_fee_$n 否 Int 100 单个代金券支付金额,$n为下标从0开始编号
@JSONField(name = "coupon_fee_$0")
private Integer couponFee0;
// 微信支付订单号 transaction_id 是 String(32) 1217752501201407033233368018 微信支付订单号
@JSONField(name = "transaction_id")
private String transactionId;
// 商户订单号 out_trade_no 是 String(32) 1212321211201407033568112322 商户系统内部订单号要求32个字符内只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
@JSONField(name = "out_trade_no")
private String outTradeNo;
// 商家数据包 attach 否 String(128) 123456 商家数据包,原样返回
@JSONField(name = "attach")
private String attach;
// 支付完成时间 time_end 是 String(14) 20141030133525 支付完成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
@JSONField(name = "time_end", format="yyyyMMddHHmmss")
private Date timeEnd;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public String getNonceStr() {
return nonceStr;
}
public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}
@Override
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getSignType() {
return signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getErrCode() {
return errCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
}
public String getErrCodeDes() {
return errCodeDes;
}
public void setErrCodeDes(String errCodeDes) {
this.errCodeDes = errCodeDes;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getIsSubscribe() {
return isSubscribe;
}
public void setIsSubscribe(String isSubscribe) {
this.isSubscribe = isSubscribe;
}
public String getTradeType() {
return tradeType;
}
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
public String getBankType() {
return bankType;
}
public void setBankType(String bankType) {
this.bankType = bankType;
}
@Override
public BigDecimal getTotalFee() {
return totalFee;
}
public void setTotalFee(BigDecimal totalFee) {
this.totalFee = totalFee;
}
public BigDecimal getSettlementTotalFee() {
return settlementTotalFee;
}
public void setSettlementTotalFee(BigDecimal settlementTotalFee) {
this.settlementTotalFee = settlementTotalFee;
}
public String getFeeType() {
return feeType;
}
public void setFeeType(String feeType) {
this.feeType = feeType;
}
public BigDecimal getCashFee() {
return cashFee;
}
public void setCashFee(BigDecimal cashFee) {
this.cashFee = cashFee;
}
public String getCashFeeType() {
return cashFeeType;
}
public void setCashFeeType(String cashFeeType) {
this.cashFeeType = cashFeeType;
}
public BigDecimal getCouponFee() {
return couponFee;
}
public void setCouponFee(BigDecimal couponFee) {
this.couponFee = couponFee;
}
public Integer getCouponCount() {
return couponCount;
}
public void setCouponCount(Integer couponCount) {
this.couponCount = couponCount;
}
public String getCouponType0() {
return couponType0;
}
public void setCouponType0(String couponType0) {
this.couponType0 = couponType0;
}
public String getCouponId0() {
return couponId0;
}
public void setCouponId0(String couponId0) {
this.couponId0 = couponId0;
}
public Integer getCouponFee0() {
return couponFee0;
}
public void setCouponFee0(Integer couponFee0) {
this.couponFee0 = couponFee0;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
@Override
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public Date getTimeEnd() {
return timeEnd;
}
public void setTimeEnd(Date timeEnd) {
this.timeEnd = timeEnd;
}
public static final WxPayMessage create(Map<String, Object> message) {
WxPayMessage payMessage = new JSONObject(message).toJavaObject(WxPayMessage.class);
payMessage.setPayMessage(message);
return payMessage;
}
}