Merge branches 'develop' and 'master' of gitee.com:egzosn/pay-java-parent

This commit is contained in:
egzosn
2020-06-01 22:12:31 +08:00
59 changed files with 1939 additions and 684 deletions

5
.gitignore vendored
View File

@@ -1,3 +1,4 @@
<<<<<<< HEAD
# Compiled class file
*.class
@@ -22,3 +23,7 @@
.idea
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
target/
.idea/
*.iml

View File

@@ -1,4 +1,4 @@
全能第三方支付对接Java开发工具包.优雅的轻量级支付模块集成支付对接支付整合(微信,支付宝,银联,友店,富友,跨境支付paypal,payoneer(P卡派安盈)易极付app,扫码,网页支付刷卡付条码付刷脸付转账服务商模式、支持多种支付类型多支付账户,支付与业务完全剥离,简单几行代码即可实现支付,简单快速完成支付模块的开发,可轻松嵌入到任何系统里 目前仅是一个开发工具包即SDK只提供简单Web实现建议使用maven或gradle引用本项目即可使用本SDK提供的各种支付相关的功能
全能第三方支付对接Java开发工具包.优雅的轻量级支付模块集成支付对接支付整合(微信,支付宝,银联,友店,富友,跨境支付paypal,payoneer(P卡派安盈)易极付app,扫码,网页支付刷卡付条码付刷脸付转账红包服务商模式、支持多种支付类型多支付账户,支付与业务完全剥离,简单几行代码即可实现支付,简单快速完成支付模块的开发,可轻松嵌入到任何系统里 目前仅是一个开发工具包即SDK只提供简单Web实现建议使用maven或gradle引用本项目即可使用本SDK提供的各种支付相关的功能
### 特性

View File

@@ -113,6 +113,18 @@
Map appOrderInfo = service.orderInfo(payOrder);
/*-----------/APP-------------------*/
```
#### 小程序支付
```java
/*-----------APP-------------------*/
payOrder.setTransactionType(AliTransactionType.MINAPP);
payOrder.setOpenid("支付宝小程序授权登录成功后获取到的支付宝 user_id")
//获取小程序支付所需的信息组,直接给小程序网页端就可使用
Map appOrderInfo = service.orderInfo(payOrder);
/*-----------/APP-------------------*/
```
#### 即时到帐 WAP 网页支付

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pay-java-ali</artifactId>

View File

@@ -4,6 +4,7 @@ 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.AliTransferType;
import com.egzosn.pay.ali.bean.OrderSettle;
import com.egzosn.pay.common.api.BasePayService;
import com.egzosn.pay.common.bean.*;
@@ -15,7 +16,7 @@ import com.egzosn.pay.common.util.DateUtils;
import com.egzosn.pay.common.util.Util;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import java.math.BigDecimal;
import java.util.*;
/**
@@ -36,29 +37,37 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
* 沙箱测试环境账号
*/
private static final String DEV_REQ_URL = "https://openapi.alipaydev.com/gateway.do";
public static final String SIGN = "sign";
public static final String SUCCESS_CODE = "10000";
public static final String CODE = "code";
private static final String SIGN = "sign";
private static final String SUCCESS_CODE = "10000";
private static final String CODE = "code";
/**
* 附加参数
*/
public static final String PASSBACK_PARAMS = "passback_params";
private static final String PASSBACK_PARAMS = "passback_params";
/**
* 产品代码
*/
public static final String PRODUCT_CODE = "product_code";
private static final String PRODUCT_CODE = "product_code";
/**
* 返回地址
*/
public static final String RETURN_URL = "return_url";
private static final String RETURN_URL = "return_url";
/**
* 请求内容
*/
public static final String BIZ_CONTENT = "biz_content";
private static final String BIZ_CONTENT = "biz_content";
/**
* 应用授权概述
*/
private static final String APP_AUTH_TOKEN = "app_auth_token";
/**
* 收款方信息
*/
private static final String PAYEE_INFO = "payee_info";
/**
* 获取对应的请求地址
@@ -190,7 +199,7 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
orderInfo.put("notify_url", payConfigStorage.getNotifyUrl());
orderInfo.put("format", "json");
setAppAuthToken(orderInfo, order.getAttrs());
Map<String, Object> bizContent = new TreeMap<>();
bizContent.put("body", order.getBody());
@@ -213,6 +222,11 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
bizContent.put(PASSBACK_PARAMS, order.getAddition());
bizContent.put(PRODUCT_CODE, "QUICK_MSECURITY_PAY");
break;
case MINAPP:
bizContent.put("extend_params", order.getAddition());
bizContent.put("buyer_id", order.getOpenid());
bizContent.put(PRODUCT_CODE, "FACE_TO_FACE_PAYMENT");
break;
case BAR_CODE:
case WAVE_CODE:
case SECURITY_CODE:
@@ -223,10 +237,10 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
}
if (null != order.getExpirationTime()) {
bizContent.put("timeout_express", DateUtils.minutesRemaining(order.getExpirationTime()) + "m");
bizContent.put(order.getTransactionType() == AliTransactionType.SWEEPPAY ? "qr_code_timeout_express" : "timeout_express", DateUtils.minutesRemaining(order.getExpirationTime()) + "m");
}
bizContent.putAll(order.getAttrs());
orderInfo.put(BIZ_CONTENT, JSON.toJSONString(bizContent));
orderInfo.putAll(order.getAttr());
return preOrderHandler(orderInfo, order);
}
@@ -355,7 +369,10 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
public Map<String, Object> settle(OrderSettle order){
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.SETTLE);
parameters.put(BIZ_CONTENT, JSON.toJSONString(order.toBizContent()));
setAppAuthToken(parameters, order.getAttrs());
final Map<String, Object> bizContent = order.toBizContent();
bizContent.putAll(order.getAttrs());
parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return getHttpRequestTemplate().postForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), null, JSONObject.class);
@@ -403,21 +420,13 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
}
/**
* 申请退款接口
* 废弃
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, com.egzosn.pay.common.api.Callback)
* @deprecated 版本替代 {@link #refund(RefundOrder, com.egzosn.pay.common.api.Callback)}
* 设置支付宝授权Token
* @param parameters 参数
* @param attrs 订单属性
* @return 参数
*/
@Deprecated
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount));
private void setAppAuthToken(Map<String, Object> parameters, Map<String, Object> attrs) {
setParameters(parameters, APP_AUTH_TOKEN, (String) attrs.remove(APP_AUTH_TOKEN));
}
@@ -431,12 +440,13 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
public Map<String, Object> refund(RefundOrder refundOrder) {
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.REFUND);
setAppAuthToken(parameters, refundOrder.getAttrs());
Map<String, Object> bizContent = getBizContent(refundOrder.getTradeNo(), refundOrder.getOutTradeNo(), null);
if (!StringUtils.isEmpty(refundOrder.getRefundNo())) {
bizContent.put("out_request_no", refundOrder.getRefundNo());
}
bizContent.put("refund_amount", Util.conversionAmount(refundOrder.getRefundAmount()));
bizContent.putAll(refundOrder.getAttrs());
//设置请求参数的集合
parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent));
//设置签名
@@ -444,17 +454,7 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
return requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class);
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return secondaryInterface(tradeNo, outTradeNo, AliTransactionType.REFUNDQUERY);
}
/**
* 查询退款
@@ -464,17 +464,16 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
*/
@Override
public Map<String, Object> refundquery(RefundOrder refundOrder) {
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.REFUNDQUERY);
setAppAuthToken(parameters, refundOrder.getAttrs());
Map<String, Object> bizContent = getBizContent(refundOrder.getTradeNo(), refundOrder.getOutTradeNo(), null);
if (!StringUtils.isEmpty(refundOrder.getRefundNo())) {
bizContent.put("out_request_no", refundOrder.getRefundNo());
}
bizContent.putAll(refundOrder.getAttrs());
//设置请求参数的集合
parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class);
@@ -505,6 +504,7 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
}
/**
* @param tradeNoOrBillDate 支付平台订单号或者账单类型, 具体请
* 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
@@ -512,6 +512,7 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
* @param transactionType 交易类型
* @return 返回支付方对应接口的结果
*/
@Override
public Map<String, Object> secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType) {
@@ -528,36 +529,38 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
//获取公共参数
Map<String, Object> parameters = getPublicParameters(transactionType);
//设置请求参数的集合
parameters.put(BIZ_CONTENT, getContentToJson((String) tradeNoOrBillDate, outTradeNoBillType));
//设置签名
setSign(parameters);
return requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class);
}
/**
* 转账
* 新版转账转账
*
* @param order 转账订单
* @return 对应的转账结果
*/
@Override
public Map<String, Object> transfer(TransferOrder order) {
final TransferType transferType = order.getTransferType();
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.TRANS);
Map<String, Object> parameters = getPublicParameters(transferType);
setAppAuthToken(parameters, order.getAttrs());
Map<String, Object> bizContent = new TreeMap<String, Object>();
Map<String, Object> bizContent = new LinkedHashMap<String, Object>();
bizContent.put("out_biz_no", order.getOutNo());
//默认 支付宝登录号,支持邮箱和手机号格式。
bizContent.put("payee_type", "ALIPAY_LOGONID");
if (null != order.getTransferType()) {
bizContent.put("payee_type", order.getTransferType().getType());
}
bizContent.put("payee_account", order.getPayeeAccount());
bizContent.put("amount", Util.conversionAmount(order.getAmount()));
bizContent.put("payer_show_name", order.getPayerName());
bizContent.put("payee_real_name", order.getPayeeName());
bizContent.put("trans_amount", order.getAmount());
transferType.setAttr(bizContent, order);
setParameters(bizContent, "order_title", order);
setParameters(bizContent, "original_order_id", order);
setPayeeInfo(bizContent, order);
bizContent.put("remark", order.getRemark());
setParameters(bizContent, "business_params", order);
//设置请求参数的集合
parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent));
//设置签名
@@ -565,6 +568,24 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
return getHttpRequestTemplate().postForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), null, JSONObject.class);
}
private Map<String, Object> setPayeeInfo(Map<String, Object> bizContent, Order order){
final Object attr = order.getAttr(PAYEE_INFO);
if (attr instanceof String){
bizContent.put(PAYEE_INFO, attr);
}
if (attr instanceof TreeMap){
bizContent.put(PAYEE_INFO, attr);
}
if (attr instanceof Map){
Map<String, Object> payeeInfo = new TreeMap<String, Object>((Map)attr);
bizContent.put(PAYEE_INFO, payeeInfo);
}
return bizContent;
}
/**
* 转账查询
*
@@ -575,7 +596,7 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
@Override
public Map<String, Object> transferQuery(String outNo, String tradeNo) {
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.TRANS_QUERY);
Map<String, Object> parameters = getPublicParameters(AliTransferType.TRANS_QUERY);
Map<String, Object> bizContent = new TreeMap<String, Object>();
if (StringUtils.isEmpty(outNo)) {

View File

@@ -44,6 +44,10 @@ public enum AliTransactionType implements TransactionType {
* 声波付
*/
WAVE_CODE("alipay.trade.pay"),
/**
* 小程序
*/
MINAPP("alipay.trade.create"),
/**
* 刷脸付
*/
@@ -84,14 +88,6 @@ public enum AliTransactionType implements TransactionType {
* 下载对账单
*/
DOWNLOADBILL("alipay.data.dataservice.bill.downloadurl.query"),
/**
* 转账到支付宝
*/
TRANS("alipay.fund.trans.toaccount.transfer"),
/**
* 转账查询
*/
TRANS_QUERY("alipay.fund.trans.order.query"),
/**
* 查询刷脸结果信息
* 暂时未接入

View File

@@ -0,0 +1,153 @@
package com.egzosn.pay.ali.bean;
import com.egzosn.pay.common.bean.TransferOrder;
import java.math.BigDecimal;
import java.util.TreeMap;
/**
* 支付转账(红包)订单
*
* @author egan
* date 2020/5/18 21:08
* email egzosn@gmail.com
*/
public class AliTransferOrder extends TransferOrder {
private String identity;
private String identityType;
/**
* 商户端的唯一订单号,对于同一笔转账请求,商户需保证该订单号唯一。
*
* @return 商户端的唯一订单号
*/
public String getOutBizNo() {
return getOutNo();
}
public void setOutBizNo(String outBizNo) {
setOutNo(outBizNo);
}
/**
* 订单总金额单位为元精确到小数点后两位STD_RED_PACKET产品取值范围[0.01,100000000]
* TRANS_ACCOUNT_NO_PWD产品取值范围[0.1,100000000]
*
* @return 订单总金额
*/
public BigDecimal getTransAmount() {
return getAmount();
}
public void setTransAmount(BigDecimal transAmount) {
setAmount(transAmount);
}
/**
* 转账业务的标题,用于在支付宝用户的账单里显示
*
* @return 转账业务的标题
*/
public String getOrderTitle() {
return (String) getAttr("order_title");
}
public void setOrderTitle(String orderTitle) {
addAttr("order_title", orderTitle);
}
/**
* 描述特定的业务场景,可传的参数如下:
* DIRECT_TRANSFER单笔无密转账到支付宝/银行卡, B2C现金红包;
* PERSONAL_COLLECTIONC2C现金红包-领红包
*
* @return 描述特定的业务场景
*/
public String getBizScene() {
return (String) getAttr("biz_scene");
}
public void setBizScene(String bizScene) {
addAttr("biz_scene", bizScene);
}
/**
* 收款方信息
*
* @return 收款方信息
*/
private TreeMap<String, Object> getPayeeinfo() {
Object payeeInfo = getAttr("payee_info");
if (null != payeeInfo && payeeInfo instanceof TreeMap){
return (TreeMap<String, Object>) payeeInfo;
}
TreeMap<String, Object> payee = new TreeMap<>();
addAttr("payee_info", payee);
return payee;
}
/**
* 参与方的唯一标识
*
* @return 参与方的唯一标识
*/
public String getIdentity() {
return identity;
}
public void setIdentity(String identity) {
this.identity = identity;
getPayeeinfo().put("identity", identity);
}
/**
* 参与方的标识类型,目前支持如下类型:
* 1、ALIPAY_USER_ID 支付宝的会员ID
* 2、ALIPAY_LOGON_ID支付宝登录号支持邮箱和手机号格式
*
* @return 参与方的标识类型
*/
public String getIdentityType() {
return identityType;
}
public void setIdentityType(String identityType) {
this.identityType = identityType;
getPayeeinfo().put("identity_type", identityType);
}
/**
* 参与方真实姓名
*
* @return 参与方真实姓名
*/
public String getName() {
return getPayeeName();
}
public void setName(String name) {
setPayeeName(name);
getPayeeinfo().put("name", name);
}
/**
* 转账业务请求的扩展参数,支持传入的扩展参数如下:
* 1、sub_biz_scene 子业务场景红包业务必传取值REDPACKETC2C现金红包、B2C现金红包均需传入
* <p>
* 2、withdraw_timeliness为转账到银行卡的预期到账时间可选不传入则默认为T1取值T0表示预期T+0到账取值T1表示预期T+1到账因到账时效受银行机构处理影响支付宝无法保证一定是T0或者T1到账
*
* @return 转账业务请求的扩展参数
*/
public String getBusinessParams() {
return (String) getAttr("business_params");
}
public void setBusinessParams(String businessParams) {
addAttr("business_params", businessParams);
}
}

View File

@@ -1,26 +1,69 @@
package com.egzosn.pay.ali.bean;
import com.egzosn.pay.common.bean.TransferOrder;
import com.egzosn.pay.common.bean.TransferType;
import java.util.Map;
/**
* 收款方账户类型
* 收款方账户类型
*
* @author egan
* email egzosn@gmail.com
* date 2018/9/28.20:32
* email egzosn@gmail.com
* date 2018/9/28.20:32
*/
public enum AliTransferType implements TransferType {
/**
* 支付宝账号对应的支付宝唯一用户号。以2088开头的16位纯数字组成。
* 单笔无密转账到支付宝账户固定为
*/
ALIPAY_USERID,
TRANS_ACCOUNT_NO_PWD("alipay.fund.trans.uni.transfer", "DIRECT_TRANSFER"),
/**
* 支付宝登录号,支持邮箱和手机号格式。
* 单笔无密转账到银行卡固定为
*/
ALIPAY_LOGONID
;
TRANS_BANKCARD_NO_PWD("alipay.fund.trans.uni.transfer", "DIRECT_TRANSFER"),
/**
* 收发现金红包固定为
*/
STD_RED_PACKET("alipay.fund.trans.uni.transfer", "DIRECT_TRANSFER"),
/**
* 现金红包无线支付接口
*/
STD_RED_PACKET_APP("alipay.fund.trans.app.pay", "PERSONAL_PAY") {
/**
* 获取转账类型
*
* @return 转账类型
*/
@Override
public String getType() {
return STD_RED_PACKET.name();
}
},
/**
* 获取转账类型
* 转账查询
*/
TRANS_QUERY("alipay.fund.trans.order.query");
/**
* 接口名称
*/
private String method;
/**
* 业务场景
*/
private String bizScene;
AliTransferType(String method) {
this.method = method;
}
AliTransferType(String method, String bizScene) {
this.method = method;
this.bizScene = bizScene;
}
/**
* 获取转账类型, product_code 业务产品码
*
* @return 转账类型
*/
@@ -29,6 +72,10 @@ public enum AliTransferType implements TransferType {
return name();
}
public String getBizScene() {
return bizScene;
}
/**
* 获取接口
*
@@ -36,6 +83,20 @@ public enum AliTransferType implements TransferType {
*/
@Override
public String getMethod() {
return name();
return method;
}
/**
* 设置属性
*
* @param attr 已有属性对象
* @param order 转账订单
* @return 属性对象
*/
@Override
public Map<String, Object> setAttr(Map<String, Object> attr, TransferOrder order) {
attr.put("product_code", getType());
attr.put("biz_scene", getBizScene());
return attr;
}
}

View File

@@ -1,9 +1,11 @@
package com.egzosn.pay.ali.bean;
import com.egzosn.pay.common.bean.Order;
import com.egzosn.pay.common.util.Util;
import com.egzosn.pay.common.util.str.StringUtils;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
@@ -13,7 +15,7 @@ import java.util.TreeMap;
* email egzosn@gmail.com
* date 2019/4/28.20:29
*/
public class OrderSettle {
public class OrderSettle implements Order {
/**
* 结算请求流水号 开发者自行生成并保证唯一性
@@ -52,6 +54,11 @@ public class OrderSettle {
*/
private String operatorId;
/**
* 订单附加信息,可用于预设未提供的参数,这里会覆盖以上所有的订单信息,
*/
private Map<String, Object> attr;
public String getOutRequestNo() {
return outRequestNo;
}
@@ -158,6 +165,28 @@ public class OrderSettle {
return bizContent;
}
@Override
public Map<String, Object> getAttrs() {
if (null == attr){
attr = new HashMap<>();
}
return attr;
}
@Override
public Object getAttr(String key) {
return getAttrs().get(key);
}
/**
* 添加订单信息
* @param key key
* @param value 值
*/
@Override
public void addAttr(String key, Object value) {
getAttrs().put(key, value);
}
}

28
pay-java-baidu/pom.xml Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pay-java-baidu</artifactId>
<dependencies>
<!-- pay-java -->
<dependency>
<groupId>com.egzosn</groupId>
<artifactId>pay-java-common</artifactId>
</dependency>
<!-- /pay-java -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,53 @@
package com.egzosn.pay.baidu.api;
import com.egzosn.pay.common.api.BasePayConfigStorage;
public class BaiduPayConfigStorage extends BasePayConfigStorage {
private String appid;
private String dealId;
@Override
public String getAppid() {
return this.appid;
}
@Override
public String getPid() {
return getDealId();
}
@Override
public String getSeller() {
throw new UnsupportedOperationException("不支持");
}
public String getDealId() {
return dealId;
}
public void setDealId(String dealId) {
this.dealId = dealId;
}
public String getAppKey() {
return this.getKeyPrivate();
}
public void setAppKey(String appKey) {
setKeyPrivate(appKey);
}
@Override
public String getKeyPublic() {
return super.getKeyPrivate();
}
@Override
public void setKeyPublic(String keyPublic) {
super.setKeyPublic(keyPublic);
}
public void setAppid(String appid) {
this.appid = appid;
}
}

View File

@@ -0,0 +1,433 @@
package com.egzosn.pay.baidu.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.baidu.bean.BaiduPayOrder;
import com.egzosn.pay.baidu.bean.BaiduRefundOrder;
import com.egzosn.pay.baidu.bean.BaiduTransactionType;
import com.egzosn.pay.baidu.bean.type.AuditStatus;
import com.egzosn.pay.baidu.util.Asserts;
import com.egzosn.pay.common.api.BasePayService;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.http.UriVariables;
import com.egzosn.pay.common.util.DateUtils;
import com.egzosn.pay.common.util.Util;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class BaiduPayService extends BasePayService<BaiduPayConfigStorage> {
public static final String APP_KEY = "appKey";
public static final String APP_ID = "appId";
public static final String DEAL_ID = "dealId";
public static final String TP_ORDER_ID = "tpOrderId";
public static final String DEAL_TITLE = "dealTitle";
public static final String TOTAL_AMOUNT = "totalAmount";
public static final String SIGN_FIELDS_RANGE = "signFieldsRange";
public static final String BIZ_INFO = "bizInfo";
public static final String RSA_SIGN = "rsaSign";
public static final String ORDER_ID = "orderId";
public static final String USER_ID = "userId";
public static final String SITE_ID = "siteId";
public static final String SIGN = "sign";
public static final String METHOD = "method";
public static final String TYPE = "type";
public static final Integer RESPONSE_SUCCESS = 2;
public static final String RESPONSE_STATUS = "status";
public BaiduPayService(BaiduPayConfigStorage payConfigStorage) {
super(payConfigStorage);
}
public BaiduPayService(BaiduPayConfigStorage payConfigStorage,
HttpConfigStorage configStorage) {
super(payConfigStorage, configStorage);
}
/**
* 验证响应
*
* @param params 回调回来的参数集
* @return 结果
*/
@Override
public boolean verify(Map<String, Object> params) {
if (!RESPONSE_SUCCESS.equals(params.get(RESPONSE_STATUS))) {
return false;
}
return signVerify(params, String.valueOf(params.get(RSA_SIGN))) && verifySource(String.valueOf(params.get(TP_ORDER_ID)));
}
/**
* 验证签名
*
* @param params 参数集
* @param sign 签名原文
* @return 结果
*/
@Override
public boolean signVerify(Map<String, Object> params, String sign) {
String rsaSign = String.valueOf(params.get(RSA_SIGN));
String targetRsaSign = getRsaSign(params, RSA_SIGN);
LOG.debug("百度返回的签名: " + rsaSign + " 本地产生的签名: " + targetRsaSign);
return StringUtils.equals(rsaSign, targetRsaSign);
}
@Override
public boolean verifySource(String id) {
return true;
}
/**
* 返回创建的订单信息
*
* @param order 支付订单
* @return 结果
*/
@Override
public Map<String, Object> orderInfo(PayOrder order) {
Map<String, Object> params = getUseOrderInfoParams(order);
String rsaSign = getRsaSign(params, RSA_SIGN);
params.put(RSA_SIGN, rsaSign);
return params;
}
/**
* 获取"查询支付状态"所需参数
*
* @return 结果
*/
public Map<String, Object> getUseQueryPay() {
String appKey = payConfigStorage.getAppKey();
Map<String, Object> result = new HashMap<>();
result.put(APP_KEY, appKey);
result.put(APP_ID, payConfigStorage.getAppid());
return result;
}
/**
* 获取"创建订单"所需参数
*
* @param order 订单信息
* @return 结果
*/
private Map<String, Object> getUseOrderInfoParams(PayOrder order) {
BaiduPayOrder payOrder = (BaiduPayOrder) order;
Map<String, Object> result = new HashMap<>();
String appKey = payConfigStorage.getAppKey();
String dealId = payConfigStorage.getDealId();
result.put(APP_KEY, appKey);
result.put(TP_ORDER_ID, payOrder.getTradeNo());
result.put(DEAL_ID, dealId);
result.put(DEAL_TITLE, payOrder.getSubject());
result.put(SIGN_FIELDS_RANGE, payOrder.getSignFieldsRange());
result.put(BIZ_INFO, JSON.toJSONString(payOrder.getBizInfo()));
result.put(TOTAL_AMOUNT, String.valueOf(Util.conversionAmount(order.getPrice())));
return result;
}
/**
* 获取输出消息,用户返回给支付端
*
* @param code 状态
* @param message 消息
* @return 结果
*/
@Override
@Deprecated
public PayOutMessage getPayOutMessage(String code, String message) {
throw new UnsupportedOperationException("请使用 " + getClass().getName() + "#getPayOutMessageUseBaidu");
}
/**
* 请求业务方退款审核/响应处理
* http://smartprogram.baidu.com/docs/develop/function/tune_up_examine/
*
* @param errno 错误代码
* @param message 消息
* @param auditStatus 状态
* @param refundPayMoney 退款金额
* @return 结果
*/
public PayOutMessage getApplyRefundOutMessageUseBaidu(Integer errno,
String message,
AuditStatus auditStatus,
BigDecimal refundPayMoney) {
JSONObject data = new JSONObject();
data.put("auditStatus", auditStatus.getCode());
JSONObject calculateRes = new JSONObject();
calculateRes.put("refundPayMoney", refundPayMoney);
data.put("calculateRes", calculateRes);
return PayOutMessage.JSON()
.content("errno", errno)
.content("message", message)
.content("data", data)
.build();
}
/**
* 通知退款状态/响应处理
* http://smartprogram.baidu.com/docs/develop/function/tune_up_drawback/
*
* @param errno 错误代码
* @param message 消息
* @return 结果
*/
public PayOutMessage getRefundOutMessageUseBaidu(Integer errno,
String message) {
return PayOutMessage.JSON()
.content("errno", errno)
.content("message", message)
.content("data", "{}")
.build();
}
/**
* 支付通知/响应处理
*
* @param errno 错误代码
* @param message 消息
* @param isConsumed 是否消费
* @param isErrorOrder 错误订单
* @return 结果
*/
public PayOutMessage getPayOutMessageUseBaidu(Integer errno,
String message,
Integer isConsumed,
Integer isErrorOrder) {
Asserts.isNoNull(errno, "errno 是必填的");
Asserts.isNoNull(message, "message 是必填的");
Asserts.isNoNull(isConsumed, "isConsumed 是必填的");
JSONObject data = new JSONObject();
data.put("isConsumed", isConsumed);
if (isErrorOrder != null) {
data.put("isErrorOrder", isErrorOrder);
}
return PayOutMessage.JSON()
.content("errno", errno)
.content("message", message)
.content("data", data)
.build();
}
/**
* 支付通知/响应处理
* http://smartprogram.baidu.com/docs/develop/function/tune_up_notice/
*
* @param code 状态码
* @param message 消息
* @param isConsumed 是否消费
* @return 结果
*/
public PayOutMessage getPayOutMessageUseBaidu(Integer code,
String message,
Integer isConsumed) {
return getPayOutMessageUseBaidu(code, message, isConsumed, null);
}
/**
* 支付通知/响应处理
* http://smartprogram.baidu.com/docs/develop/function/tune_up_notice/
*
* @param payMessage 支付回调消息
* @return 结果
*/
@Override
public PayOutMessage successPayOutMessage(PayMessage payMessage) {
return getPayOutMessageUseBaidu(0, "success", 2);
}
/**
* 获取输出消息,用户返回给支付端, 针对于web端
*
* @param orderInfo 发起支付的订单信息
* @param method 请求方式 "post" "get",
* @return 结果
*/
@Override
public String buildRequest(Map<String, Object> orderInfo,
MethodType method) {
throw new UnsupportedOperationException("百度不支持PC支付");
}
/**
* 百度不支持扫码付
*
* @param order 发起支付的订单信息
* @return 结果
*/
@Override
public String getQrPay(PayOrder order) {
throw new UnsupportedOperationException("百度不支持扫码付");
}
/**
* 百度不支持刷卡付
*
* @param order 发起支付的订单信息
* @return 结果
*/
@Override
public Map<String, Object> microPay(PayOrder order) {
throw new UnsupportedOperationException("百度不支持刷卡付");
}
/**
* 查询订单
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 结果
*/
@Override
public Map<String, Object> query(String tradeNo, String outTradeNo) {
return secondaryInterface(tradeNo, outTradeNo, BaiduTransactionType.PAY_QUERY);
}
/**
* 百度不支持该操作
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 结果
*/
@Override
public Map<String, Object> close(String tradeNo, String outTradeNo) {
throw new UnsupportedOperationException("不支持该操作");
}
/**
* 退款
*
* @param refundOrder 退款订单信息
* @return 退款结果
*/
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
Map<String, Object> parameters = getUseQueryPay();
BaiduTransactionType transactionType = BaiduTransactionType.APPLY_REFUND;
parameters.put(METHOD, transactionType.getMethod());
parameters.put(ORDER_ID, refundOrder.getOutTradeNo());
parameters.put(USER_ID, refundOrder.getUserId());
setParameters(parameters, "refundType", refundOrder);
parameters.put("refundReason", refundOrder.getDescription());
parameters.put(TP_ORDER_ID, refundOrder.getTradeNo());
parameters.put("applyRefundMoney", refundOrder.getRefundAmount());
parameters.put("bizRefundBatchId", refundOrder.getRefundNo());
parameters.put(APP_KEY, payConfigStorage.getAppKey());
parameters.put(RSA_SIGN, getRsaSign(parameters, RSA_SIGN));
return requestTemplate.getForObject(String.format("%s?%s", getReqUrl(transactionType), UriVariables.getMapToParameters(parameters)), JSONObject.class);
}
/**
* 退费查询
*
* @param refundOrder 退款订单单号信息
* @return 退款查询结果
*/
@Override
public Map<String, Object> refundquery(RefundOrder refundOrder) {
Map<String, Object> parameters = getUseQueryPay();
BaiduTransactionType transactionType = BaiduTransactionType.REFUND_QUERY;
parameters.put(METHOD, transactionType.getMethod());
parameters.put(TYPE, 3);
parameters.put(ORDER_ID, refundOrder.getTradeNo());
parameters.put(USER_ID, refundOrder.getUserId());
parameters.put(APP_KEY, payConfigStorage.getAppKey());
parameters.put(RSA_SIGN, getRsaSign(parameters, RSA_SIGN));
return requestTemplate.getForObject(String.format("%s?%s", getReqUrl(transactionType), UriVariables.getMapToParameters(parameters)), JSONObject.class);
}
/**
* 下载资金账单
*
* @param billDate 账单时间日账单格式为yyyy-MM-dd
* @param accessToken 用户token
* @return 对账单
*/
@Override
public Map<String, Object> downloadbill(Date billDate, String accessToken) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("access_token", accessToken);
parameters.put("billTime", DateUtils.formatDay(billDate));
return requestTemplate.getForObject(String.format("%s?%s", getReqUrl(BaiduTransactionType.DOWNLOAD_BILL),
UriVariables.getMapToParameters(parameters)), JSONObject.class);
}
/**
* 下载订单对账单
*
* @param billDate 账单时间日账单格式为yyyy-MM-dd
* @param accessToken 用户token
* @return 账单结果
*/
public Map<String, Object> downloadOrderBill(Date billDate, String accessToken) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("access_token", accessToken);
parameters.put("billTime", DateUtils.formatDay(billDate));
return requestTemplate.getForObject(String.format("%s?%s", getReqUrl(BaiduTransactionType.DOWNLOAD_ORDER_BILL),
UriVariables.getMapToParameters(parameters)), JSONObject.class);
}
/**
* 通用查询接口
*
* @param orderId 订单id
* @param siteId 用户id
* @param transactionType 交易类型
* @return 结果
*/
@Override
public Map<String, Object> secondaryInterface(Object orderId,
String siteId,
TransactionType transactionType) {
if (!BaiduTransactionType.PAY_QUERY.equals(transactionType)) {
throw new UnsupportedOperationException("不支持该操作");
}
Map<String, Object> parameters = getUseQueryPay();
parameters.put(ORDER_ID, orderId);
parameters.put(SITE_ID, siteId);
parameters.put(SIGN, getRsaSign(parameters, SIGN));
return requestTemplate.getForObject(String.format("%s?%s", getReqUrl(transactionType), UriVariables.getMapToParameters(parameters)), JSONObject.class);
}
/**
* 获取支付请求地址
*
* @param transactionType 交易类型
* @return 请求URL
*/
@Override
public String getReqUrl(TransactionType transactionType) {
return ((BaiduTransactionType) transactionType).getUrl();
}
/**
* 签名
*
* @param params 参数
* @param ignoreKeys 忽略字段
* @return 签名结果
*/
private String getRsaSign(Map<String, Object> params, String... ignoreKeys) {
String waitSignVal = SignUtils.parameterText(params, "&", false, ignoreKeys);
return SignUtils.valueOf(payConfigStorage.getSignType()).createSign(waitSignVal, payConfigStorage.getKeyPrivate(), payConfigStorage.getInputCharset());
}
}

View File

@@ -0,0 +1,76 @@
package com.egzosn.pay.baidu.bean;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.TransactionType;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import static com.egzosn.pay.baidu.api.BaiduPayService.BIZ_INFO;
import static com.egzosn.pay.baidu.api.BaiduPayService.SIGN_FIELDS_RANGE;
public class BaiduPayOrder extends PayOrder {
/**
* 需要隐藏的支付方式
*/
private List<TransactionType> bannedChannels = Collections.emptyList();
/**
* 固定值
*/
private String signFieldsRange;
/**
* 附加信息
*/
private JSONObject bizInfo = new JSONObject();
public BaiduPayOrder(String dealTitle,
BigDecimal totalAmount,
String tpOrderId,
String signFieldsRange) {
this(dealTitle, totalAmount, tpOrderId, signFieldsRange, Collections.<TransactionType>emptyList());
}
public BaiduPayOrder(String dealTitle,
BigDecimal totalAmount,
String tpOrderId,
String signFieldsRange,
List<TransactionType> bannedChannels) {
setPrice(totalAmount);
setOutTradeNo(tpOrderId);
setSubject(dealTitle);
setSignFieldsRange(signFieldsRange);
setBannedChannels(bannedChannels);
}
public JSONObject getBizInfo() {
return bizInfo;
}
public void setBizInfo(JSONObject bizInfo) {
this.bizInfo = bizInfo;
addAttr(BIZ_INFO, bizInfo);
}
public List<TransactionType> getBannedChannels() {
return bannedChannels;
}
public void setBannedChannels(List<TransactionType> bannedChannels) {
this.bannedChannels = bannedChannels;
}
public String getSignFieldsRange() {
return signFieldsRange;
}
public void setSignFieldsRange(String signFieldsRange) {
this.signFieldsRange = signFieldsRange;
addAttr(SIGN_FIELDS_RANGE, signFieldsRange);
}
}

View File

@@ -0,0 +1,71 @@
package com.egzosn.pay.baidu.bean;
import com.egzosn.pay.common.bean.RefundOrder;
import java.math.BigDecimal;
public class BaiduRefundOrder extends RefundOrder {
/**
* 退款类型
*/
private Integer refundType;
public BaiduRefundOrder(Long orderId,
String userId,
Integer refundType,
String refundReason,
String tpOrderId) {
super();
setOutTradeNo(String.valueOf(orderId));
setUserId(userId);
setRefundType(refundType);
setDescription(refundReason);
setTradeNo(tpOrderId);
}
/**
* 退款金额,单位:分,发起部分退款时必传
*
* @return 退款金额
*/
public BigDecimal getApplyRefundMoney() {
return getRefundAmount();
}
/**
* 退款金额,单位:分,发起部分退款时必传
*
* @param applyRefundMoney 退款金额
*/
public void setApplyRefundMoney(BigDecimal applyRefundMoney) {
setRefundAmount(applyRefundMoney);
}
/**
* 业务方退款批次id退款业务流水唯一编号发起部分退款时必传
*
* @return 退款业务流水
*/
public String getBizRefundBatchId() {
return getRefundNo();
}
/**
* 业务方退款批次id退款业务流水唯一编号发起部分退款时必传
*/
public void setBizRefundBatchId(String bizRefundBatchId) {
setRefundNo(bizRefundBatchId);
}
public void setRefundType(Integer refundType) {
this.refundType = refundType;
addAttr("refundType", refundType);
}
public Integer getRefundType() {
return refundType;
}
}

View File

@@ -0,0 +1,47 @@
package com.egzosn.pay.baidu.bean;
import com.egzosn.pay.common.bean.TransactionType;
public enum BaiduTransactionType implements TransactionType {
/**
* 查询支付状态
*/
PAY_QUERY("https://dianshang.baidu.com/platform/entity/openapi/queryorderdetail", null),
/**
* 取消核销
*/
REFUND_QUERY("https://nop.nuomi.com/nop/server/rest", "nuomi.cashier.syncorderstatus"),
/**
* 下载资金账单
*/
DOWNLOAD_BILL("https://openapi.baidu.com/rest/2.0/smartapp/pay/paymentservice/capitaBill", null),
/**
* 下载订单对账单
*/
DOWNLOAD_ORDER_BILL("https://openapi.baidu.com/rest/2.0/smartapp/pay/paymentservice/orderBill", null),
/**
* 申请退款
*/
APPLY_REFUND("https://nop.nuomi.com/nop/server/rest", "nuomi.cashier.applyorderrefund");
private final String method;
private final String url;
BaiduTransactionType( String url, String method) {
this.url = url;
this.method = method;
}
@Override
public String getType() {
return this.name();
}
@Override
public String getMethod() {
return this.method;
}
public String getUrl() {
return url;
}
}

View File

@@ -0,0 +1,22 @@
package com.egzosn.pay.baidu.bean.type;
public enum AuditStatus {
SUCCESS(1, "审核通过可退款"),
FAIL(2, "审核不通过,不能退款"),
UNKNOWN(3, "审核结果不确定,待重试");
private final int code;
private final String desc;
AuditStatus(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1 @@
package com.egzosn.pay.baidu;

View File

@@ -0,0 +1,16 @@
package com.egzosn.pay.baidu.util;
public class Asserts {
public static void isNoNull(Object object, String message) {
if (object == null) {
throw new IllegalArgumentException(message);
}
}
public static void isTrue(boolean bool, String message) {
if (!bool) {
throw new IllegalArgumentException(message);
}
}
}

View File

@@ -0,0 +1,24 @@
package com.egzosn.pay.baidu.api;
import org.junit.jupiter.api.Test;
/**
* Created by hocgin on 2019/11/24.
* email: hocgin@gmail.com
*
* @author hocgin
*/
public class BaiduPayServiceTest {
@Test
public void orderInfo() {
BaiduPayConfigStorage configStorage = new BaiduPayConfigStorage();
configStorage.setAppid("APP ID");
configStorage.setAppKey("APP KEY");
configStorage.setDealId("DEAL ID");
configStorage.setKeyPublic("KEY PUBLIC");
BaiduPayService payService = new BaiduPayService(configStorage);
// payService.refund()
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

View File

@@ -14,7 +14,6 @@ import org.apache.commons.logging.LogFactory;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;
/**
@@ -126,7 +125,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
* @param characterEncoding 字符编码
* @return 签名
*/
@Override
public String createSign(Map<String, Object> content, String characterEncoding) {
return SignUtils.valueOf(payConfigStorage.getSignType()).sign(content, payConfigStorage.getKeyPrivate(), characterEncoding);
}
@@ -142,6 +140,16 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
Map orderInfo = orderInfo(order);
return buildRequest(orderInfo, MethodType.POST);
}
/**
* app支付
* @param order 订单信息
* @param <O> 预订单类型
* @return 对应app所需参数信息
*/
@Override
public <O extends PayOrder> Map<String, Object> app(O order) {
return orderInfo(order);
}
/**
* 生成二维码支付
@@ -242,24 +250,7 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
return Collections.EMPTY_MAP;
}
/**
* 退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @param callback 处理器
* @param <T> 返回类型
* @return 处理过后的类型对象, 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
@Override
public <T> T refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback) {
return callback.perform(refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount)));
}
/**
* 申请退款接口
@@ -276,19 +267,6 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @return 处理过后的类型对象,返回支付方查询退款后的结果
*/
@Override
public <T> T refundquery(String tradeNo, String outTradeNo, Callback<T> callback) {
return callback.perform(refundquery(tradeNo, outTradeNo));
}
/**
* 查询退款
@@ -467,4 +445,20 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
return orderInfo;
}
protected Map<String, Object> setParameters(Map<String, Object> parameters, String key, String value) {
if (StringUtils.isNotEmpty(value)) {
parameters.put(key, value);
}
return parameters;
}
protected Map<String, Object> setParameters(Map<String, Object> parameters, String key, Order order) {
Object attr = order.getAttr(key);
if (null != attr && !"".equals(attr)) {
parameters.put(key, attr);
}
return parameters;
}
}

View File

@@ -7,7 +7,6 @@ import com.egzosn.pay.common.http.HttpRequestTemplate;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
@@ -59,25 +58,27 @@ public interface PayService<PC extends PayConfigStorage> {
* @param params 回调回来的参数集
* @return 签名校验 true通过
*/
boolean verify(Map<String, Object> params);
boolean verify(Map<String, Object> params);
/**
* 签名校验
*
* 后面版本废弃
* @param params 参数集
* @param sign 签名原文
* @return 签名校验 true通过
*/
@Deprecated
boolean signVerify(Map<String, Object> params, String sign);
/**
* 支付宝需要,微信是否也需要再次校验来源,进行订单查询
* 校验数据来源
*
* 后面版本废弃
* @param id 业务id, 数据的真实性.
* @return true通过
*/
@Deprecated
boolean verifySource(String id);
@@ -99,6 +100,13 @@ public interface PayService<PC extends PayConfigStorage> {
* @return 对应页面重定向信息
*/
<O extends PayOrder>String toPay(O order);
/**
* app支付
* @param order 订单信息
* @param <O> 预订单类型
* @return 对应app所需参数信息
*/
<O extends PayOrder>Map<String, Object> app(O order);
/**
* 创建签名
@@ -109,14 +117,7 @@ public interface PayService<PC extends PayConfigStorage> {
*/
String createSign(String content, String characterEncoding);
/**
* 创建签名
*
* @param content 需要签名的内容
* @param characterEncoding 字符编码
* @return 签名
*/
String createSign(Map<String, Object> content, String characterEncoding);
/**
* 将请求参数或者请求流转化为 Map
@@ -243,35 +244,7 @@ public interface PayService<PC extends PayConfigStorage> {
*/
<T> T cancel(String tradeNo, String outTradeNo, Callback<T> callback);
/**
* 申请退款接口
* 废弃
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder)
*/
@Deprecated
Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount);
/**
* 申请退款接口
* 废弃
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @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);
/**
* 申请退款接口
@@ -291,27 +264,7 @@ public interface PayService<PC extends PayConfigStorage> {
*/
<T> T refund(RefundOrder refundOrder, Callback<T> callback);
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Deprecated
Map<String, Object> refundquery(String tradeNo, String outTradeNo);
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方查询退款后的结果
*/
@Deprecated
<T> T refundquery(String tradeNo, String outTradeNo, Callback<T> callback);
/**
* 查询退款
@@ -354,18 +307,19 @@ public interface PayService<PC extends PayConfigStorage> {
/**
* 通用查询接口
*
* 接下来移除此方法
* @param tradeNoOrBillDate 支付平台订单号或者账单类型, 具体请
* 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
* @return 返回支付方对应接口的结果
*/
@Deprecated
Map<String, Object> secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType);
/**
* 通用查询接口
*
* 接下来移除此方法
* @param tradeNoOrBillDate 支付平台订单号或者账单日期, 具体请 类型为{@link String }或者 {@link Date },类型须强制限制,类型不对应则抛出异常{@link PayErrorException}
* @param outTradeNoBillType 商户单号或者 账单类型
* @param transactionType 交易类型
@@ -373,6 +327,7 @@ public interface PayService<PC extends PayConfigStorage> {
* @param <T> 返回类型
* @return 返回支付方对应接口的结果
*/
@Deprecated
<T> T secondaryInterface(Object tradeNoOrBillDate, String outTradeNoBillType, TransactionType transactionType, Callback<T> callback);

View File

@@ -15,8 +15,26 @@ public interface Order {
/**
* 获取订单属性 这里可用做覆盖已设置的订单信息属性,订单信息在签名前进行覆盖。
*
* @return 属性
*/
Map<String, Object> getAttr();
Map<String, Object> getAttrs();
/**
* 获取订单属性 这里可用做覆盖已设置的订单信息属性,订单信息在签名前进行覆盖。
*
* @param key 属性名
* @return 属性
*/
Object getAttr(String key);
/**
* 添加订单信息
*
* @param key key
* @param value 值
*/
void addAttr(String key, Object value);
}

View File

@@ -1,12 +1,12 @@
package com.egzosn.pay.common.bean;
import com.egzosn.pay.common.util.str.StringUtils;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.egzosn.pay.common.util.str.StringUtils;
/**
* 支付订单信息
*
@@ -71,6 +71,7 @@ public class PayOrder implements Order {
/**
* 用户唯一标识
* 微信含 sub_openid 字段
* 支付宝 buyer_id
*/
private String openid;
/**
@@ -258,20 +259,27 @@ public class PayOrder implements Order {
}
@Override
public Map<String, Object> getAttr() {
public Map<String, Object> getAttrs() {
if (null == attr){
attr = new HashMap<>();
}
return attr;
}
@Override
public Object getAttr(String key) {
return getAttrs().get(key);
}
/**
* 添加订单信息
* @param key key
* @param value 值
*/
@Override
public void addAttr(String key, Object value) {
getAttr().put(key, value);
getAttrs().put(key, value);
}

View File

@@ -2,16 +2,19 @@ package com.egzosn.pay.common.bean;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 退款订单信息
* @author: egan
* <pre>
*
* @author egan
* <pre>
* email egzosn@gmail.com
* date 2018/1/15 21:40
* </pre>
*/
public class RefundOrder {
public class RefundOrder implements Order {
/**
* 退款单号,每次进行退款的单号,此处唯一
*/
@@ -46,6 +49,15 @@ public class RefundOrder {
* 退款说明
*/
private String description;
/**
* 退款用户
*/
private String userId;
/**
* 订单附加信息,可用于预设未提供的参数,这里会覆盖以上所有的订单信息,
*/
private Map<String, Object> attr;
public String getRefundNo() {
return refundNo;
@@ -111,6 +123,14 @@ public class RefundOrder {
this.description = description;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public RefundOrder() {
}
@@ -135,5 +155,28 @@ public class RefundOrder {
this.totalAmount = totalAmount;
}
@Override
public Map<String, Object> getAttrs() {
if (null == attr) {
attr = new HashMap<>();
}
return attr;
}
@Override
public Object getAttr(String key) {
return getAttrs().get(key);
}
/**
* 添加订单信息
*
* @param key key
* @param value 值
*/
@Override
public void addAttr(String key, Object value) {
getAttrs().put(key, value);
}
}

View File

@@ -1,16 +1,19 @@
package com.egzosn.pay.common.bean;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* 转账订单
*
* @author egan
* <pre>
* email egzosn@gmail.com
* date 2018/1/31
* </pre>
*/
public class TransferOrder {
public class TransferOrder implements Order {
/**
* 转账批次订单单号
@@ -25,12 +28,12 @@ public class TransferOrder {
/**
* 收款方账户, 用户openid,卡号等等
*/
private String payeeAccount ;
private String payeeAccount;
/**
* 转账金额
*/
private BigDecimal amount ;
private BigDecimal amount;
/**
* 付款人名称
@@ -53,11 +56,11 @@ public class TransferOrder {
/**
* 收款开户行
*/
*/
private Bank bank;
/**
* 收款开户行地址
* 收款开户行地址
*/
private String payeeBankAddress;
@@ -79,6 +82,12 @@ public class TransferOrder {
*/
private String ip;
/**
* 订单附加信息,可用于预设未提供的参数,这里会覆盖以上所有的订单信息,
*/
private Map<String, Object> attr;
public String getBatchNo() {
return batchNo;
}
@@ -190,4 +199,31 @@ public class TransferOrder {
public void setIp(String ip) {
this.ip = ip;
}
@Override
public Map<String, Object> getAttrs() {
if (null == attr) {
attr = new HashMap<>();
}
return attr;
}
@Override
public Object getAttr(String key) {
return getAttrs().get(key);
}
/**
* 添加订单信息
*
* @param key key
* @param value 值
*/
@Override
public void addAttr(String key, Object value) {
getAttrs().put(key, value);
}
}

View File

@@ -1,5 +1,7 @@
package com.egzosn.pay.common.bean;
import java.util.Map;
/**
* 转账类型
* @author egan
@@ -7,6 +9,12 @@ package com.egzosn.pay.common.bean;
* date 2018/9/28.19:45
*/
public interface TransferType extends TransactionType{
/**
* 设置属性
*
* @param attr 已有属性对象
* @param order 转账订单
* @return 属性对象
*/
Map<String, Object> setAttr(Map<String, Object> attr, TransferOrder order);
}

View File

@@ -13,7 +13,7 @@ import java.util.*;
* 日期转换运算工具
*
* @author egan
* <pre>
* <pre>
* email egzosn@gmail.com
* date 2018-11-21 16:43:20
* </pre>
@@ -23,6 +23,7 @@ public final class 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>>>();
@@ -37,7 +38,7 @@ public final class DateUtils {
THREADLOCAL_FORMATS.set(new SoftReference(formats));
}
SimpleDateFormat format = formats.get(pattern);
SimpleDateFormat format = formats.get(pattern);
if (format == null) {
format = new SimpleDateFormat(pattern);
@@ -66,6 +67,7 @@ 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");
@@ -77,9 +79,11 @@ public final class DateUtils {
}
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);
}
@@ -99,7 +103,7 @@ public final class DateUtils {
* @return 分钟数
*/
public static final long minutesRemaining(Date date) {
return (date.getTime() - System.currentTimeMillis()) / 1000 / 60;
return (date.getTime() / 1000 / 60 - System.currentTimeMillis() / 1000 / 60);
}
/**

View File

@@ -193,7 +193,20 @@ public enum SignUtils implements SignType {
* @param ignoreKey 需要忽略添加的key
* @return 去掉空值与签名参数后的新签名,拼接后字符串
*/
public static String parameterText(Map parameters, String separator, String... ignoreKey ) {
public static String parameterText(Map parameters, String separator, String... ignoreKey) {
return parameterText(parameters, separator, true, ignoreKey);
}
/**
*
* 把数组所有元素排序,并按照“参数=参数值”的模式用“@param separator”字符拼接成字符串
* @param parameters 参数
* @param separator 分隔符
* @param ignoreNullValue 需要忽略NULL值
* @param ignoreKey 需要忽略添加的key
* @return 去掉空值与签名参数后的新签名,拼接后字符串
*/
public static String parameterText(Map parameters, String separator, boolean ignoreNullValue, String... ignoreKey ) {
if(parameters == null){
return "";
}
@@ -225,7 +238,7 @@ public enum SignUtils implements SignType {
for (String k : keys) {
String valueStr = "";
Object o = parameters.get(k);
if (null == o) {
if (ignoreNullValue && null == o) {
continue;
}
if (o instanceof String[]) {

View File

@@ -3,6 +3,7 @@ package com.egzosn.pay.common.util.sign.encrypt;
import javax.crypto.Cipher;
import java.io.*;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -34,9 +35,9 @@ public class RSA{
*/
public static String sign(String content, String privateKey, String signAlgorithms, String characterEncoding) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey));
KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature.getInstance(signAlgorithms);
@@ -111,11 +112,11 @@ public class RSA{
*/
public static boolean verify(String content, String sign, String publicKey, String signAlgorithms, String characterEncoding){
try {
PublicKey pubKey = getPublicKey(publicKey, ALGORITHM);
PublicKey pubKey = getPublicKey(publicKey, ALGORITHM);
java.security.Signature signature = java.security.Signature.getInstance(signAlgorithms);
signature.initVerify(pubKey);
signature.update( content.getBytes(characterEncoding) );
return signature.verify( Base64.decode(sign) );
signature.update(content.getBytes(characterEncoding) );
return signature.verify(Base64.decode(sign) );
} catch (Exception e) {
e.printStackTrace();
}
@@ -135,8 +136,8 @@ public class RSA{
try {
java.security.Signature signature = java.security.Signature.getInstance(signAlgorithms);
signature.initVerify(publicKey);
signature.update( content.getBytes(characterEncoding) );
return signature.verify( Base64.decode(sign) );
signature.update(content.getBytes(characterEncoding) );
return signature.verify(Base64.decode(sign) );
} catch (Exception e) {
e.printStackTrace();
}
@@ -176,9 +177,9 @@ public class RSA{
* @return 解密后的字符串
* @throws Exception 解密异常
*/
public static String decrypt(String content, String privateKey, String characterEncoding) throws Exception {
PrivateKey prikey = getPrivateKey(privateKey);
Cipher cipher = Cipher.getInstance(ALGORITHM);
public static String decrypt(String content, String privateKey, String characterEncoding) throws GeneralSecurityException, IOException {
PrivateKey prikey = getPrivateKey(privateKey);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, prikey);
try(InputStream ins = new ByteArrayInputStream(Base64.decode(content)); ByteArrayOutputStream writer = new ByteArrayOutputStream();) {
@@ -204,14 +205,14 @@ public class RSA{
}
}
/**
* 得到私钥
* @param key 密钥字符串经过base64编码
* @throws Exception 加密异常
* @throws GeneralSecurityException 加密异常
* @return 私钥
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
public static PrivateKey getPrivateKey(String key) throws GeneralSecurityException {
byte[] keyBytes;
keyBytes = Base64.decode(key);
@@ -225,26 +226,30 @@ public class RSA{
* 得到公钥
* @param key 密钥字符串经过base64编码
* @param signAlgorithms 密钥类型
* @throws Exception 加密异常
* @throws GeneralSecurityException 加密异常
* @throws IOException 加密异常
* @return 公钥
*/
public static PublicKey getPublicKey(String key, String signAlgorithms) throws Exception {
return getPublicKey(new ByteArrayInputStream(key.getBytes("ISO8859-1")), signAlgorithms);
public static PublicKey getPublicKey(String key, String signAlgorithms) throws GeneralSecurityException, IOException {
try (ByteArrayInputStream is = new ByteArrayInputStream(key.getBytes("ISO8859-1"))){
return getPublicKey(is, signAlgorithms);
}
}
/**
* 得到公钥
* @param key 密钥字符串经过base64编码
* @throws Exception 加密异常
* @throws GeneralSecurityException 加密异常
* @throws IOException 加密异常
* @return 公钥
*/
public static PublicKey getPublicKey(String key) throws Exception {
public static PublicKey getPublicKey(String key) throws GeneralSecurityException, IOException {
return getPublicKey(key, ALGORITHM);
}
public static PublicKey getPublicKey(InputStream inputStream, String keyAlgorithm) throws Exception {
public static PublicKey getPublicKey(InputStream inputStream, String keyAlgorithm) throws IOException, GeneralSecurityException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));) {
StringBuilder sb = new StringBuilder();
String readLine = null;
@@ -262,14 +267,14 @@ public class RSA{
}
}
public static byte[] encrypt(byte[] plainBytes, PublicKey publicKey, int keyLength, int reserveSize, String cipherAlgorithm) throws Exception {
public static byte[] encrypt(byte[] plainBytes, PublicKey publicKey, int keyLength, int reserveSize, String cipherAlgorithm) throws IOException, GeneralSecurityException {
int keyByteSize = keyLength / 8;
int encryptBlockSize = keyByteSize - reserveSize;
int nBlock = plainBytes.length / encryptBlockSize;
if ((plainBytes.length % encryptBlockSize) != 0) {
nBlock += 1;
}
try (ByteArrayOutputStream outbuf = new ByteArrayOutputStream(nBlock * keyByteSize);) {
try (ByteArrayOutputStream outbuf = new ByteArrayOutputStream(nBlock * keyByteSize)) {
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
for (int offset = 0; offset < plainBytes.length; offset += encryptBlockSize) {
@@ -284,7 +289,7 @@ public class RSA{
return outbuf.toByteArray();
}
}
public static String encrypt(String content, String publicKey, String cipherAlgorithm, String characterEncoding ) throws Exception {
public static String encrypt(String content, String publicKey, String cipherAlgorithm, String characterEncoding ) throws IOException, GeneralSecurityException {
return Base64.encode(RSA.encrypt(content.getBytes(characterEncoding), RSA.getPublicKey(publicKey),1024, 11, cipherAlgorithm));
}

View File

@@ -1,6 +1,8 @@
package com.egzosn.pay.common.util.sign.encrypt;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -63,11 +65,11 @@ public class RSA2 {
* @return 解密后的字符串
* @throws Exception 解密异常
*/
public static String decrypt(String content, String privateKey, String characterEncoding) throws Exception {
public static String decrypt(String content, String privateKey, String characterEncoding) throws GeneralSecurityException, IOException {
return RSA.decrypt(content, privateKey, characterEncoding);
}
/**
* 得到私钥
* @param key 密钥字符串经过base64编码
@@ -79,7 +81,7 @@ public class RSA2 {
}
public static String encrypt(String content, String publicKey, String cipherAlgorithm, String characterEncoding ) throws Exception {
return Base64.encode(RSA.encrypt(content.getBytes(characterEncoding), RSA.getPublicKey(publicKey),2048, 11, cipherAlgorithm));
public static String encrypt(String content, String publicKey, String cipherAlgorithm, String characterEncoding ) throws GeneralSecurityException, IOException {
return Base64.encode(RSA.encrypt(content.getBytes(characterEncoding), RSA.getPublicKey(publicKey), 2048, 11, cipherAlgorithm));
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
@@ -90,39 +90,7 @@
</dependency>
</dependencies>
<profiles>
<profile>
<id>port8080</id>
<properties>
<port>8080</port>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>port9096</id>
<properties>
<port>9096</port>
</properties>
</profile>
<profile>
<id>local</id>
<properties>
<env>local</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>proc</id>
<properties>
<env>proc</env>
</properties>
</profile>
</profiles>
<build>
<finalName>pay-java-demo</finalName>
<plugins>
@@ -140,7 +108,7 @@
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<port>${port}</port>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>

View File

@@ -5,9 +5,11 @@ package com.egzosn.pay.demo.controller;
import com.egzosn.pay.ali.api.AliPayConfigStorage;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliTransactionType;
import com.egzosn.pay.ali.bean.AliTransferOrder;
import com.egzosn.pay.ali.bean.AliTransferType;
import com.egzosn.pay.ali.bean.OrderSettle;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.RefundOrder;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.http.UriVariables;
import com.egzosn.pay.common.util.sign.SignUtils;
@@ -17,6 +19,7 @@ import com.egzosn.pay.demo.service.interceptor.AliPayMessageInterceptor;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
@@ -109,7 +112,7 @@ public class AliPayController {
PayOrder order = new PayOrder("订单title", "摘要", new BigDecimal(0.01), UUID.randomUUID().toString().replace("-", ""));
//App支付
order.setTransactionType(AliTransactionType.APP);
data.put("orderInfo", UriVariables.getMapToParameters(service.orderInfo(order)));
data.put("orderInfo", UriVariables.getMapToParameters(service.app(order)));
return data;
}
@@ -287,8 +290,8 @@ public class AliPayController {
* @return 返回支付方查询退款后的结果
*/
@RequestMapping("refundquery")
public Map<String, Object> refundquery(QueryOrder order) {
return service.refundquery(order.getTradeNo(), order.getOutTradeNo());
public Map<String, Object> refundquery(RefundOrder order) {
return service.refundquery(order);
}
/**
@@ -303,18 +306,6 @@ public class AliPayController {
}
/**
* 通用查询接口,根据 AliTransactionType 类型进行实现,此接口不包括退款
*
* @param order 订单的请求体
* @return 返回支付方对应接口的结果
*/
@RequestMapping("secondaryInterface")
public Map<String, Object> secondaryInterface(QueryOrder order) {
TransactionType type = AliTransactionType.valueOf(order.getTransactionType());
return service.secondaryInterface(order.getTradeNoOrBillDate(), order.getOutTradeNoBillType(), type);
}
/**
* 转账
*
@@ -323,15 +314,18 @@ public class AliPayController {
* @return 对应的转账结果
*/
@RequestMapping("transfer")
public Map<String, Object> transfer(TransferOrder order) {
// order.setOutNo("转账单号");
// order.setPayeeAccount("收款方账户,支付宝登录号,支持邮箱和手机号格式");
// order.setAmount(new BigDecimal(10));
// order.setPayerName("付款方姓名, 非必填");
// order.setPayeeName("收款方真实姓名, 非必填");
// order.setRemark("转账备注, 非必填");
//收款方账户类型 ,默认值 ALIPAY_LOGONID支付宝登录号支持邮箱和手机号格式。
order.setTransferType(AliTransferType.ALIPAY_LOGONID);
public Map<String, Object> transfer(AliTransferOrder order) {
order.setOutBizNo("转账单号");
order.setTransAmount(new BigDecimal(10));
order.setOrderTitle("转账业务的标题");
order.setIdentity("参与方的唯一标识");
order.setIdentityType("参与方的标识类型,目前支持如下类型:");
order.setName("参与方真实姓名");
order.setRemark("转账备注, 非必填");
//单笔无密转账到支付宝账户
order.setTransferType(AliTransferType.TRANS_ACCOUNT_NO_PWD);
//单笔无密转账到银行卡
// order.setTransferType(AliTransferType.TRANS_BANKCARD_NO_PWD);
return service.transfer(order);
}

View File

@@ -167,14 +167,14 @@ public class PayController {
* @param price 金额
* @return 支付预订单信息
*/
@RequestMapping("getOrderInfo")
@RequestMapping("app")
public Map<String, Object> getOrderInfo(Integer payId, String transactionType, BigDecimal price) {
//获取对应的支付账户操作工具可根据账户id
PayResponse payResponse = service.getPayResponse(payId);
Map<String, Object> data = new HashMap<>();
data.put("code", 0);
PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
data.put("orderInfo", payResponse.getService().orderInfo(order));
data.put("orderInfo", payResponse.getService().app(order));
return data;
}
@@ -436,9 +436,11 @@ public class PayController {
* @return 返回支付方查询退款后的结果
*/
@RequestMapping("refundquery")
public Map<String, Object> refundquery(QueryOrder order) {
PayResponse payResponse = service.getPayResponse(order.getPayId());
return payResponse.getService().refundquery(order.getTradeNo(), order.getOutTradeNo());
public Map<String, Object> refundquery(Integer payId, RefundOrder order) {
PayResponse payResponse = service.getPayResponse(payId);
return payResponse.getService().refundquery(order);
}
/**

View File

@@ -2,7 +2,9 @@ package com.egzosn.pay.demo.controller;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.bean.DefaultCurType;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.RefundOrder;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.paypal.api.PayPalConfigStorage;
import com.egzosn.pay.paypal.api.PayPalPayService;

View File

@@ -139,7 +139,7 @@ public class UnionPayController {
//APPLE支付 苹果付
// order.setTransactionType(UnionTransactionType.APPLE);
data.put("orderInfo", service.orderInfo(order));
data.put("orderInfo", service.app(order));
return data;
}
@@ -270,16 +270,6 @@ public class UnionPayController {
return service.refund(order);
}
/**
* 查询退款
*
* @param order 订单的请求体
* @return 返回支付方查询退款后的结果
*/
@RequestMapping("refundquery")
public Map<String, Object> refundquery(QueryOrder order) {
return service.refundquery(order.getTradeNo(), order.getOutTradeNo());
}
/**
* 下载对账单

View File

@@ -2,27 +2,16 @@
package com.egzosn.pay.demo.controller;
import com.egzosn.pay.common.api.Callback;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.http.UriVariables;
import com.egzosn.pay.demo.entity.PayType;
import com.egzosn.pay.demo.request.QueryOrder;
import com.egzosn.pay.demo.service.PayResponse;
import com.egzosn.pay.demo.service.handler.AliPayMessageHandler;
import com.egzosn.pay.demo.service.handler.WxPayMessageHandler;
import com.egzosn.pay.wx.api.WxPayConfigStorage;
import com.egzosn.pay.wx.api.WxPayService;
import com.egzosn.pay.wx.bean.WxBank;
import com.egzosn.pay.wx.bean.WxTransactionType;
import com.egzosn.pay.wx.bean.WxTransferType;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import com.egzosn.pay.wx.bean.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
@@ -43,7 +32,7 @@ import java.util.UUID;
@RequestMapping("wx")
public class WxPayController {
private PayService service = null;
private WxPayService service = null;
@@ -155,7 +144,7 @@ public class WxPayController {
PayOrder order = new PayOrder("订单title", "摘要", new BigDecimal(0.01), UUID.randomUUID().toString().replace("-", ""));
//App支付
order.setTransactionType(WxTransactionType.APP);
data.put("orderInfo", service.orderInfo(order));
data.put("orderInfo", service.app(order));
return data;
}
@@ -334,8 +323,8 @@ public class WxPayController {
* @return 返回支付方查询退款后的结果
*/
@RequestMapping("refundquery")
public Map<String, Object> refundquery(QueryOrder order) {
return service.refundquery(order.getTradeNo(), order.getOutTradeNo());
public Map<String, Object> refundquery(RefundOrder order) {
return service.refundquery(order);
}
/**
@@ -350,18 +339,6 @@ public class WxPayController {
}
/**
* 通用查询接口,根据 WxTransactionType 类型进行实现,此接口不包括退款
*
* @param order 订单的请求体
* @return 返回支付方对应接口的结果
*/
@RequestMapping("secondaryInterface")
public Map<String, Object> secondaryInterface(QueryOrder order) {
TransactionType type = WxTransactionType.valueOf(order.getTransactionType());
return service.secondaryInterface(order.getTradeNoOrBillDate(), order.getOutTradeNoBillType(), type);
}
/**
@@ -428,4 +405,51 @@ public class WxPayController {
//默认查询银行卡的记录 com.egzosn.pay.wx.bean.WxTransferType#QUERY_BANK
return service.transferQuery(outNo, wxTransferType);
}
/**
* 微信发红包
* @param redpackOrder 红包订单
* @return 结果
*/
public Map<String, Object> sendredpack(RedpackOrder redpackOrder) {
redpackOrder.setTransferType(WxSendredpackType.SENDREDPACK);
return service.sendredpack(redpackOrder);
}
/**
* 发放裂变红包
* @param redpackOrder 红包订单
* @return 结果
*/
public Map<String, Object> sendgroupredpack(RedpackOrder redpackOrder) {
redpackOrder.setTransferType(WxSendredpackType.SENDGROUPREDPACK);
return service.sendredpack(redpackOrder);
}
/**
* 小程序发红包
* @param redpackOrder 红包订单
* @return 结果
*/
public Map<String, Object> sendminiprogramhb(RedpackOrder redpackOrder) {
redpackOrder.setTransferType(WxSendredpackType.SENDMINIPROGRAMHB);
return service.sendredpack(redpackOrder);
}
/**
* 查询红包记录
* 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包
* 查询红包记录API只支持查询30天内的红包订单30天之前的红包订单请登录商户平台查询。
*
* @param mchBillno 商户发放红包的商户订单号
* @return 返回查询结果
*/
public Map<String, Object> gethbinfo(String mchBillno) {
return service.gethbinfo(mchBillno);
}
}

View File

@@ -69,12 +69,12 @@
</div>
<br/>
<div>各个支付对应的<b>交易类型</b>可自行查看对应的官方文档,本项目已实现几种交易类型,对应各个支付类型的<code>com.egzosn.pay.common.bean.TransactionType</code>具体实现</div>
<div>新版支付宝(<code>com.egzosn.pay.ali.bean.AliTransactionType</code>) 即时付款=PAGE 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>
<div><b>详情请查看 com.egzosn.pay.common.bean.TransactionType对应的子类</b></div>
<br>
<br>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pay-java-fuiou</artifactId>

View File

@@ -203,7 +203,7 @@ public class FuiouPayService extends BasePayService<FuiouPayConfigStorage> {
parameters.put("rem", "");
//版本号
parameters.put("ver", "1.0.1");
parameters.putAll(order.getAttr());
parameters.putAll(order.getAttrs());
return preOrderHandler(parameters, order);
}
@@ -371,22 +371,6 @@ public class FuiouPayService extends BasePayService<FuiouPayConfigStorage> {
/**
* 申请退款接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 退款返回结果集
*/
@Override
public Map<String, Object> refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount));
}
/**
* 申请退款接口
@@ -413,20 +397,6 @@ public class FuiouPayService extends BasePayService<FuiouPayConfigStorage> {
}
/**
* 查询退款
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 空
*
*/
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return Collections.emptyMap();
}
/**
* 查询退款
*

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pay-java-payoneer</artifactId>

View File

@@ -18,8 +18,6 @@ import org.apache.http.Header;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicHeader;
import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.util.*;
/**
@@ -184,7 +182,7 @@ public class PayoneerPayService extends BasePayService<PayoneerConfigStorage> im
}
params.put("currency", order.getCurType());
params.put("description", order.getSubject());
params.putAll(order.getAttr());
params.putAll(order.getAttrs());
return preOrderHandler(params, order);
}
@@ -314,22 +312,7 @@ public class PayoneerPayService extends BasePayService<PayoneerConfigStorage> im
return secondaryInterface(tradeNo, outTradeNo, PayoneerTransactionType.CHARGE_CANCEL);
}
/**
* 申请退款接口
* 废弃
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
*
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder)
*/
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return close(tradeNo, outTradeNo);
}
/**
@@ -344,18 +327,6 @@ public class PayoneerPayService extends BasePayService<PayoneerConfigStorage> im
return close(refundOrder.getTradeNo(), refundOrder.getOutTradeNo());
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
*
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return Collections.emptyMap();
}
/**
* 查询退款

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -16,7 +16,7 @@ import com.egzosn.pay.paypal.bean.order.*;
import org.apache.http.Header;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicHeader;
import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;
@@ -239,22 +239,7 @@ public class PayPalPayService extends BasePayService<PayPalConfigStorage>{
public Map<String, Object> close(String tradeNo, String outTradeNo) {
return null;
}
/**
* 申请退款接口
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder)
* @deprecated {@link #refund(RefundOrder)}
*/
@Deprecated
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder( tradeNo, outTradeNo, refundAmount, totalAmount));
}
/**
@@ -284,18 +269,6 @@ public class PayPalPayService extends BasePayService<PayPalConfigStorage>{
JSONObject resp = getHttpRequestTemplate().postForObject(getReqUrl(PayPalTransactionType.REFUND), httpEntity, JSONObject.class, refundOrder.getTradeNo());
return resp;
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
JSONObject resp = getHttpRequestTemplate().getForObject(getReqUrl(PayPalTransactionType.REFUND_QUERY), authHeader(), JSONObject.class, tradeNo);
return resp;
}
/**
* 查询退款
@@ -305,7 +278,8 @@ public class PayPalPayService extends BasePayService<PayPalConfigStorage>{
*/
@Override
public Map<String, Object> refundquery(RefundOrder refundOrder) {
return refundquery(refundOrder.getTradeNo(), refundOrder.getOutTradeNo());
JSONObject resp = getHttpRequestTemplate().getForObject(getReqUrl(PayPalTransactionType.REFUND_QUERY), authHeader(), JSONObject.class, refundOrder.getTradeNo());
return resp;
}
@Override

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -9,7 +9,6 @@ import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.http.UriVariables;
import com.egzosn.pay.common.util.DateUtils;
import com.egzosn.pay.common.util.MatrixToImageWriter;
import com.egzosn.pay.common.util.Util;
import com.egzosn.pay.common.util.sign.CertDescriptor;
import com.egzosn.pay.common.util.sign.SignUtils;
@@ -20,11 +19,13 @@ 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;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.*;
import java.sql.Timestamp;
import java.text.DateFormat;
@@ -284,7 +285,7 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
params.put(SDKConstants.param_payTimeout, getPayTimeout(order.getExpirationTime()));
params.put("orderDesc", order.getSubject());
}
params.putAll(order.getAttr());
params.putAll(order.getAttrs());
params = preOrderHandler(params, order);
return setSign(params);
}
@@ -361,21 +362,35 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
@SuppressWarnings("unused")
PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder.build(pkixParams);
/*PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult)*/ builder.build(pkixParams);
return cert;
} catch (java.security.cert.CertPathBuilderException e) {
LOG.error("verify certificate chain fail.", e);
} catch (CertificateExpiredException e) {
LOG.error(e);
} catch (CertificateNotYetValidException e) {
LOG.error(e);
} catch (Exception e) {
} catch (GeneralSecurityException e) {
LOG.error(e);
}
return null;
}
/**
* 发送订单
*
* @param order 发起支付的订单信息
* @return 返回支付结果
*/
public JSONObject postOrder(PayOrder order) {
Map<String, Object> params = orderInfo(order);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
if (response.isEmpty()) {
throw new PayErrorException(new PayException("failure", "响应内容有误!", responseStr));
}
return response;
}
@Override
public String toPay(PayOrder order) {
@@ -397,20 +412,15 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
@Override
public String getQrPay(PayOrder order) {
order.setTransactionType(UnionTransactionType.APPLY_QR_CODE);
Map<String, Object> params = orderInfo(order);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
Map<String, Object> response = UriVariables.getParametersToMap(responseStr);
if (response.isEmpty()) {
throw new PayErrorException(new PayException("failure", "响应内容有误!", responseStr));
}
JSONObject response = postOrder(order);
if (this.verify(response)) {
if (SDKConstants.OK_RESP_CODE.equals(response.get(SDKConstants.param_respCode))) {
//成功
return (String) response.get(SDKConstants.param_qrCode);
}
throw new PayErrorException(new PayException((String) response.get(SDKConstants.param_respCode), (String) response.get(SDKConstants.param_respMsg), responseStr));
throw new PayErrorException(new PayException((String) response.get(SDKConstants.param_respCode), (String) response.get(SDKConstants.param_respMsg), response.toJSONString()));
}
throw new PayErrorException(new PayException("failure", "验证签名失败", responseStr));
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
/**
@@ -422,9 +432,8 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
@Override
public Map<String, Object> microPay(PayOrder order) {
order.setTransactionType(UnionTransactionType.CONSUME);
Map<String, Object> params = orderInfo(order);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
return UriVariables.getParametersToMap(responseStr);
JSONObject response = postOrder(order);
return response;
}
@@ -501,17 +510,14 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
/**
* 功能:将订单信息进行签名并提交请求
* 业务范围:手机控件支付产品(WAP),
* 业务范围:手机支付控件含安卓Pay
* @param order 订单信息
* @return 成功:返回支付结果 失败:返回
*/
public Map<String ,Object> sendHttpRequest(PayOrder order){
Map<String, Object> params = orderInfo(order);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
Map<String, Object> response = UriVariables.getParametersToMap(responseStr);
if (response.isEmpty()) {
throw new PayErrorException(new PayException("failure", "响应内容有误!", responseStr));
}
@Override
public Map<String, Object> app(PayOrder order){
order.setTransactionType(UnionTransactionType.APP);
JSONObject response = postOrder(order);
if (this.verify(response)) {
if (SDKConstants.OK_RESP_CODE.equals(response.get(SDKConstants.param_respCode))) {
// //成功,获取tn号
@@ -519,9 +525,9 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
// //TODO
return response;
}
throw new PayErrorException(new PayException((String) response.get(SDKConstants.param_respCode), (String) response.get(SDKConstants.param_respMsg), responseStr));
throw new PayErrorException(new PayException((String) response.get(SDKConstants.param_respCode), (String) response.get(SDKConstants.param_respMsg), response.toJSONString()));
}
throw new PayErrorException(new PayException("failure", "验证签名失败", responseStr));
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
/**
@@ -610,40 +616,12 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
return Collections.emptyMap();
}
/**
* 申请退款接口
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder)
*/
@Deprecated
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount));
}
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
return unionRefundOrConsumeUndo(refundOrder, UnionTransactionType.REFUND);
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return Collections.emptyMap();
}
/**
* 查询退款

View File

@@ -93,7 +93,7 @@ public class PayTest {
/*-----------退货交易:后台资金类交易,有同步应答和后台通知应答------------------------------*/
payOrder.setTransactionType(UnionTransactionType.REFUND);
params = service.refund("原交易查询流水号", "订单号", null,new BigDecimal("退款金额" ));
params = service.refund(new RefundOrder("原交易查询流水号", "订单号", null, new BigDecimal("退款金额" )));
/*-----------退货交易:后台资金类交易,有同步应答和后台通知应答------------------------------*/

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pay-java-wx-youdian</artifactId>

View File

@@ -7,14 +7,13 @@ import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.bean.result.PayError;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.http.HttpConfigStorage;
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;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
@@ -227,7 +226,7 @@ public class WxYouDianPayService extends BasePayService<WxYouDianPayConfigStorag
Map<String, Object> data = new TreeMap<>();
data.put("access_token", getAccessToken());
data.put("paymoney", Util.conversionAmount(order.getPrice()).toString());
data.putAll(order.getAttr());
data.putAll(order.getAttrs());
data = preOrderHandler(data, order);
String apbNonce = SignUtils.randomStr();
String sign = createSign(SignUtils.parameterText(data, "") + apbNonce, payConfigStorage.getInputCharset());
@@ -385,13 +384,14 @@ public class WxYouDianPayService extends BasePayService<WxYouDianPayConfigStorag
}
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder(tradeNo, outTradeNo,refundAmount, totalAmount));
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
*/
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
String apbNonce = SignUtils.randomStr();
@@ -413,11 +413,6 @@ public class WxYouDianPayService extends BasePayService<WxYouDianPayConfigStorag
}
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return Collections.emptyMap();
}
/**
* 查询退款
*

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pay-java-wx</artifactId>

View File

@@ -2,29 +2,25 @@ package com.egzosn.pay.wx.api;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.common.api.BasePayService;
import com.egzosn.pay.common.api.Callback;
import com.egzosn.pay.common.bean.*;
import com.egzosn.pay.common.bean.result.PayException;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.util.DateUtils;
import com.egzosn.pay.common.util.MatrixToImageWriter;
import com.egzosn.pay.common.util.Util;
import com.egzosn.pay.common.util.XML;
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;
import java.awt.image.BufferedImage;
import com.egzosn.pay.wx.bean.*;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.security.GeneralSecurityException;
import java.util.*;
import static com.egzosn.pay.wx.api.WxConst.*;
import static com.egzosn.pay.wx.bean.WxTransferType.*;
/**
@@ -32,34 +28,11 @@ import static com.egzosn.pay.wx.bean.WxTransferType.*;
*
* @author egan
* <pre>
* email egzosn@gmail.com
* date 2016-5-18 14:09:01
* </pre>
* email egzosn@gmail.com
* date 2016-5-18 14:09:01
* </pre>
*/
public class WxPayService extends BasePayService<WxPayConfigStorage> {
/**
* 微信请求地址
*/
public static final String URI = "https://api.mch.weixin.qq.com/";
/**
* 沙箱
*/
public static final String SANDBOXNEW = "sandboxnew/";
public static final String SUCCESS = "SUCCESS";
public static final String RETURN_CODE = "return_code";
public static final String SIGN = "sign";
public static final String CIPHER_ALGORITHM = "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";
public static final String FAILURE = "failure";
public static final String APPID = "appid";
private static final String HMAC_SHA256 = "HMAC-SHA256";
private static final String HMACSHA256 = "HMACSHA256";
private static final String RETURN_MSG_CODE = "return_msg";
private static final String RESULT_CODE = "result_code";
private static final String MCH_ID = "mch_id";
private static final String NONCE_STR = "nonce_str";
public class WxPayService extends BasePayService<WxPayConfigStorage> implements WxRedPackService {
/**
@@ -118,17 +91,21 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
public boolean verify(Map<String, Object> params) {
if (!(SUCCESS.equals(params.get(RETURN_CODE)) && SUCCESS.equals(params.get(RESULT_CODE)))) {
LOG.debug(String.format("微信支付异常return_code=%s,参数集=%s", params.get(RETURN_CODE), params));
if (LOG.isErrorEnabled()) {
LOG.error(String.format("微信支付异常return_code=%s,参数集=%s", params.get(RETURN_CODE), params));
}
return false;
}
if (null == params.get(SIGN)) {
LOG.debug("微信支付异常签名为空out_trade_no=" + params.get("out_trade_no"));
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("微信支付异常:签名为空!%s=%s", OUT_TRADE_NO, params.get(OUT_TRADE_NO)));
}
return false;
}
try {
return signVerify(params, (String) params.get(SIGN)) && verifySource((String) params.get("out_trade_no"));
return signVerify(params, (String) params.get(SIGN)) && verifySource((String) params.get(OUT_TRADE_NO));
} catch (PayErrorException e) {
LOG.error(e);
}
@@ -203,9 +180,9 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
// 购买支付信息
parameters.put("body", order.getSubject());
// 购买支付信息
// parameters.put("detail", order.getBody());
setParameters(parameters, "detail", order);
// 订单号
parameters.put("out_trade_no", order.getOutTradeNo());
parameters.put(OUT_TRADE_NO, order.getOutTradeNo());
parameters.put("spbill_create_ip", StringUtils.isEmpty(order.getSpbillCreateIp()) ? "192.168.1.150" : order.getSpbillCreateIp());
// 总金额单位为分
parameters.put("total_fee", Util.conversionCentAmount(order.getPrice()));
@@ -222,7 +199,13 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
}
((WxTransactionType) order.getTransactionType()).setAttribute(parameters, order);
parameters.putAll(order.getAttr());
//可覆盖参数
/* setParameters(parameters, "notify_url", order);
setParameters(parameters, "goods_tag", order);
setParameters(parameters, "limit_pay", order);
setParameters(parameters, "receipt", order);
setParameters(parameters, "product_id", order);*/
parameters.putAll(order.getAttrs());
parameters = preOrderHandler(parameters, order);
setSign(parameters);
@@ -276,7 +259,6 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
params.put("noncestr", result.get(NONCE_STR));
params.put("package", "Sign=WXPay");
}
params = preOrderHandler(params, order);
String paySign = createSign(SignUtils.parameterText(params), payConfigStorage.getInputCharset());
params.put(SIGN, paySign);
return params;
@@ -495,30 +477,6 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
return secondaryInterface(transactionId, outTradeNo, WxTransactionType.REVERSE);
}
/**
* 退款
*
* @param transactionId 微信订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
@Override
public Map<String, Object> refund(String transactionId, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder(transactionId, outTradeNo, refundAmount, totalAmount));
}
private Map<String, Object> setParameters(Map<String, Object> parameters, String key, String value) {
if (StringUtils.isNotEmpty(value)) {
parameters.put(key, value);
}
return parameters;
}
/**
* 申请退款接口
@@ -532,7 +490,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
Map<String, Object> parameters = getPublicParameters();
setParameters(parameters, "transaction_id", refundOrder.getTradeNo());
setParameters(parameters, "out_trade_no", refundOrder.getOutTradeNo());
setParameters(parameters, OUT_TRADE_NO, refundOrder.getOutTradeNo());
setParameters(parameters, "out_refund_no", refundOrder.getRefundNo());
parameters.put("total_fee", Util.conversionCentAmount(refundOrder.getTotalAmount()));
parameters.put("refund_fee", Util.conversionCentAmount(refundOrder.getRefundAmount()));
@@ -547,18 +505,6 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
}
/**
* 查询退款
*
* @param transactionId 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery(String transactionId, String outTradeNo) {
return secondaryInterface(transactionId, outTradeNo, WxTransactionType.REFUNDQUERY);
}
/**
* 查询退款
*
@@ -571,7 +517,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
//获取公共参数
Map<String, Object> parameters = getPublicParameters();
setParameters(parameters, "transaction_id", refundOrder.getTradeNo());
setParameters(parameters, "out_trade_no", refundOrder.getOutTradeNo());
setParameters(parameters, OUT_TRADE_NO, refundOrder.getOutTradeNo());
setParameters(parameters, "out_refund_no", refundOrder.getRefundNo());
//设置签名
setSign(parameters);
@@ -638,7 +584,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
//获取公共参数
Map<String, Object> parameters = getPublicParameters();
setParameters(parameters, "out_trade_no", outTradeNoBillType);
setParameters(parameters, OUT_TRADE_NO, outTradeNoBillType);
setParameters(parameters, "transaction_id", (String) transactionIdOrBillDate);
//设置签名
setSign(parameters);
@@ -651,13 +597,12 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
* @param order 转账订单
* <pre>
*
* 注意事项:
* ◆ 当返回错误码为“SYSTEMERROR”时请不要更换商户订单号一定要使用原商户订单号重试否则可能造成重复支付等资金风险。
* ◆ XML具有可扩展性因此返回参数可能会有新增而且顺序可能不完全遵循此文档规范如果在解析回包的时候发生错误请商户务必不要换单重试请商户联系客服确认付款情况。如果有新回包字段会更新到此API文档中。
* ◆ 因为错误代码字段err_code的值后续可能会增加所以商户如果遇到回包返回新的错误码请商户务必不要换单重试请商户联系客服确认付款情况。如果有新的错误码会更新到此API文档中。
* ◆ 错误代码描述字段err_code_des只供人工定位问题时做参考系统实现时请不要依赖这个字段来做自动化处理。
*
* </pre>
* 注意事项:
* ◆ 当返回错误码为“SYSTEMERROR”时请不要更换商户订单号一定要使用原商户订单号重试否则可能造成重复支付等资金风险。
* ◆ XML具有可扩展性因此返回参数可能会有新增而且顺序可能不完全遵循此文档规范如果在解析回包的时候发生错误请商户务必不要换单重试请商户联系客服确认付款情况。如果有新回包字段会更新到此API文档中。
* ◆ 因为错误代码字段err_code的值后续可能会增加所以商户如果遇到回包返回新的错误码请商户务必不要换单重试请商户联系客服确认付款情况。如果有新的错误码会更新到此API文档中。
* ◆ 错误代码描述字段err_code_des只供人工定位问题时做参考系统实现时请不要依赖这个字段来做自动化处理。
* </pre>
* @return 对应的转账结果
*/
@Override
@@ -760,7 +705,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
public String keyPublic(String content) {
try {
return RSA2.encrypt(content, payConfigStorage.getKeyPublic(), CIPHER_ALGORITHM, payConfigStorage.getInputCharset());
} catch (Exception e) {
} catch (GeneralSecurityException | IOException e) {
throw new PayErrorException(new WxPayError(FAILURE, e.getLocalizedMessage()));
}
}
@@ -775,4 +720,70 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
public PayMessage createMessage(Map<String, Object> message) {
return WxPayMessage.create(message);
}
/**
* 微信发红包
*
* @param redpackOrder 红包实体
* @return 返回发红包实体后的结果
* @author: faymanwang 1057438332@qq.com
*/
@Override
public Map<String, Object> sendredpack(RedpackOrder redpackOrder) {
Map<String, Object> parameters = new TreeMap<String, Object>();
redPackParam(redpackOrder, parameters);
if (WxSendredpackType.SENDGROUPREDPACK == redpackOrder.getTransferType()) {
//现金红包小程序红包默认传1.裂变红包取传入值且需要大于3
parameters.put("total_num", Math.max(redpackOrder.getTotalNum(), 3));
parameters.put("amt_type", "ALL_RAND");
} else if (WxSendredpackType.SENDMINIPROGRAMHB == redpackOrder.getTransferType()) {
parameters.put("notify_way", "MINI_PROGRAM_JSAPI");
}
parameters.put(SIGN, createSign(SignUtils.parameterText(parameters, "&", SIGN), payConfigStorage.getInputCharset()));
return requestTemplate.postForObject(getReqUrl(redpackOrder.getTransferType()), XML.getMap2Xml(parameters), JSONObject.class);
}
/**
* 查询红包记录
* 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包
* 查询红包记录API只支持查询30天内的红包订单30天之前的红包订单请登录商户平台查询。
*
* @param mchBillno 商户发放红包的商户订单号
* @return 返回查询结果
* @author: faymanwang 1057438332@qq.com
*/
@Override
public Map<String, Object> gethbinfo(String mchBillno) {
Map<String, Object> parameters = this.getPublicParameters();
parameters.put("mch_billno", mchBillno);
parameters.put("bill_type", "MCHT");
parameters.put(SIGN, createSign(SignUtils.parameterText(parameters, "&", SIGN), payConfigStorage.getInputCharset()));
return requestTemplate.postForObject(getReqUrl(WxSendredpackType.GETHBINFO), XML.getMap2Xml(parameters), JSONObject.class);
}
/**
* 微信红包构造参数方法
*
* @param redpackOrder 红包实体
* @param parameters 接收参数
*/
private void redPackParam(RedpackOrder redpackOrder, Map<String, Object> parameters) {
parameters.put(NONCE_STR, SignUtils.randomStr());
parameters.put(MCH_ID, payConfigStorage.getPid());
parameters.put("wxappid", payConfigStorage.getAppid());
parameters.put("send_name", redpackOrder.getSendName());
parameters.put("re_openid", redpackOrder.getReOpenid());
parameters.put("mch_billno", redpackOrder.getMchBillno());
parameters.put("total_amount", Util.conversionCentAmount(redpackOrder.getTotalAmount()));
parameters.put("total_num", 1);
parameters.put("wishing", redpackOrder.getWishing());
parameters.put("client_ip", StringUtils.isNotEmpty(redpackOrder.getIp()) ? redpackOrder.getIp() : "192.168.0.1");
parameters.put("act_name", redpackOrder.getActName());
parameters.put("remark", redpackOrder.getRemark());
if (StringUtils.isNotEmpty(redpackOrder.getSceneId())) {
parameters.put("scene_id", redpackOrder.getSceneId());
}
}
}

View File

@@ -0,0 +1,33 @@
package com.egzosn.pay.wx.api;
import com.egzosn.pay.wx.bean.RedpackOrder;
import java.util.Map;
/**
* 微信红包服务
* @author egan
* <pre>
* email egzosn@gmail.com
* date 2020/5/17 22:24
* </pre>
*/
public interface WxRedPackService {
/**
* 微信发红包
*
* @param redpackOrder 红包实体
* @return 返回发红包实体后的结果
*/
Map<String, Object> sendredpack(RedpackOrder redpackOrder);
/**
* 查询红包记录
* 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包
* 查询红包记录API只支持查询30天内的红包订单30天之前的红包订单请登录商户平台查询。
*
* @param mchBillno 商户发放红包的商户订单号
* @return 返回查询结果
*/
Map<String, Object> gethbinfo(String mchBillno);
}

View File

@@ -0,0 +1,122 @@
package com.egzosn.pay.wx.bean;
import com.egzosn.pay.common.bean.TransferOrder;
import java.math.BigDecimal;
/**
* @description: 发红包订单
* @author: 保网 faymanwang 1057438332@qq.com
* @time: 2020/5/15 12:40
*/
public class RedpackOrder extends TransferOrder {
/**
* 商户订单号每个订单号必须唯一。取值范围0~9a~zA~Z
* 接口根据商户订单号支持重入,如出现超时可再调用
* @return 商户订单号
*/
public String getMchBillno() {
return getOutNo();
}
public void setMchBillno(String mchBillno) {
setOutNo(mchBillno);
}
/**
* 商户名称:红包发送者名称
* @return 红包发送者名称
*/
public String getSendName() {
return getPayerName();
}
public void setSendName(String sendName) {
super.setPayerName(sendName);
}
/**
* 用户openid
* @return 用户openid
*/
public String getReOpenid() {
return getPayeeAccount();
}
public void setReOpenid(String reOpenid) {
super.setPayeeAccount(reOpenid);
}
/**
* 付款金额 每个红包金额必须在默认额度内默认大于1元小于200元可在产品设置中自行申请调高额度
* @return 付款金额
*/
public BigDecimal getTotalAmount() {
return getAmount();
}
public void setTotalAmount(BigDecimal totalAmount) {
super.setAmount(totalAmount);
}
/**
* 红包发放总人数
* 普通红包1
* 裂变:必须介于(包括)3到20之间
*/
public int getTotalNum() {
Object totalNum = getAttr("total_num");
return null == totalNum ? 1 : (Integer)totalNum;
}
public void setTotalNum(int totalNum) {
addAttr("total_num", totalNum);
}
/**
* 红包祝福语
*/
public String getWishing() {
return (String) getAttr("wishing");
}
public void setWishing(String wishing) {
addAttr("wishing", wishing);
}
/**
* 活动名称
*/
public String getActName() {
return (String) getAttr("act_name");
}
public void setActName(String actName) {
addAttr("act_name", actName);
}
public String getSceneId() {
return (String) getAttr("scene_id");
}
/**
* 发放红包使用场景红包金额大于200或者小于1元时必传
* PRODUCT_1:商品促销
* PRODUCT_2:抽奖
* PRODUCT_3:虚拟物品兑奖
* PRODUCT_4:企业内部福利
* PRODUCT_5:渠道分润
* PRODUCT_6:保险回馈
* PRODUCT_7:彩票派奖
* PRODUCT_8:税务刮奖
*/
public void setSceneId(String sceneId) {
addAttr("scene_id", sceneId);
}
public void setTransferType(WxSendredpackType transferType) {
super.setTransferType(transferType);
}
}

View File

@@ -0,0 +1,51 @@
package com.egzosn.pay.wx.bean;
import com.egzosn.pay.common.bean.TransferOrder;
import com.egzosn.pay.common.bean.TransferType;
import java.util.Map;
/**
* @description: 红包交易类型
* @author faymanwang
* @time: 2020/5/14 20:11
*/
public enum WxSendredpackType implements TransferType {
/**
* 现金红包-发放红包接口
*/
SENDREDPACK("mmpaymkttransfers/sendredpack"),
/**
* 现金红包-发放裂变红包
*/
SENDGROUPREDPACK("mmpaymkttransfers/sendgroupredpack"),
/**
* 现金红包-查询红包记录
*/
GETHBINFO ("mmpaymkttransfers/gethbinfo"),
/**
* 小程序
*/
SENDMINIPROGRAMHB ("mmpaymkttransfers/sendminiprogramhb")
;
WxSendredpackType(String method) {
this.method = method;
}
private String method;
@Override
public String getType() {
return this.name();
}
@Override
public String getMethod() {
return this.method;
}
@Override
public Map<String, Object> setAttr(Map<String, Object> attr, TransferOrder order) {
return attr;
}
}

View File

@@ -1,7 +1,10 @@
package com.egzosn.pay.wx.bean;
import com.egzosn.pay.common.bean.TransferOrder;
import com.egzosn.pay.common.bean.TransferType;
import java.util.Map;
/**
* 微信转账类型
* @author egan
@@ -41,4 +44,10 @@ public enum WxTransferType implements TransferType{
public String getMethod() {
return this.method;
}
@Override
public Map<String, Object> setAttr(Map<String, Object> attr, TransferOrder order) {
return attr;
}
}

View File

@@ -1,9 +1,12 @@
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.CertStoreType;
import com.egzosn.pay.common.bean.MethodType;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.wx.api.WxPayConfigStorage;
import com.egzosn.pay.wx.api.WxPayService;
import com.egzosn.pay.wx.bean.RedpackOrder;
import com.egzosn.pay.wx.bean.WxSendredpackType;
import com.egzosn.pay.wx.bean.WxTransactionType;
import java.awt.image.BufferedImage;
@@ -39,7 +42,7 @@ public class PayTest {
//是否为测试账号,沙箱环境 此处暂未实现
wxPayConfigStorage.setTest(true);
//支付服务
PayService service = new WxPayService(wxPayConfigStorage);
WxPayService service = new WxPayService(wxPayConfigStorage);
//支付订单基础信息
PayOrder payOrder = new PayOrder("订单title", "摘要", new BigDecimal(0.01) , UUID.randomUUID().toString().replace("-", ""));
/*-----------扫码付-------------------*/
@@ -84,5 +87,32 @@ public class PayTest {
/*-----------回调处理-------------------*/
HttpConfigStorage httpConfigStorage = new HttpConfigStorage();
//ssl 退款证书相关
httpConfigStorage.setKeystore("D:/work/pay/src/main/resources/certificates/1220429901_apiclient_cert.p12");
httpConfigStorage.setStorePassword("默认商户号");
//设置ssl证书对应的存储方式这里默认为文件地址
httpConfigStorage.setCertStoreType(CertStoreType.PATH);
service.setRequestTemplateConfigStorage(httpConfigStorage);
RedpackOrder redpackOrder = new RedpackOrder();
redpackOrder.setSendName("测试");
//faymanwang- opid
redpackOrder.setReOpenid("om3rxjhD1rhGrP6oLydMgLcN5n10");
//红包流水
redpackOrder.setMchBillno("red202005181");
redpackOrder.setTotalAmount(new BigDecimal(1.5));
redpackOrder.setSceneId("PRODUCT_1");
//现金红包小程序默认为1 裂变默认为3
redpackOrder.setTotalNum(4);
redpackOrder.setWishing("请勿领取");
redpackOrder.setActName("请勿领取测试红包");
redpackOrder.setRemark("测试支付-by fayman");
//设置发红包方式
redpackOrder.setTransferType(WxSendredpackType.SENDGROUPREDPACK);
Map<String, Object> sendredpack = service.sendredpack(redpackOrder);
System.out.println(sendredpack);
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>pay-java-parent</artifactId>
<groupId>com.egzosn</groupId>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -11,8 +11,6 @@ import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import com.egzosn.pay.yiji.bean.YiJiTransactionType;
import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
@@ -175,7 +173,7 @@ public class YiJiPayService extends BasePayService<YiJiPayConfigStorage> {
if (null != order.getCurType()){
orderInfo.put("currency", order.getCurType());
}
orderInfo.putAll(order.getAttr());
orderInfo.putAll(order.getAttrs());
return preOrderHandler(orderInfo, order);
}
@@ -294,24 +292,6 @@ public class YiJiPayService extends BasePayService<YiJiPayConfigStorage> {
/**
* 申请退款接口
* 废弃
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, com.egzosn.pay.common.api.Callback)
* @deprecated 版本替代 {@link #refund(RefundOrder, com.egzosn.pay.common.api.Callback)}
*/
@Deprecated
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount));
}
/**
* 申请退款接口
@@ -331,18 +311,6 @@ public class YiJiPayService extends BasePayService<YiJiPayConfigStorage> {
return getHttpRequestTemplate().postForObject(getReqUrl(YiJiTransactionType.tradeRefund), orderInfo, JSONObject.class);
}
/**
* 查询退款
*
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @return 返回支付方查询退款后的结果
*/
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return Collections.emptyMap();
}
/**
* 查询退款
*

157
pom.xml
View File

@@ -7,7 +7,7 @@
<groupId>com.egzosn</groupId>
<artifactId>pay-java-parent</artifactId>
<packaging>pom</packaging>
<version>2.13.1</version>
<version>2.13.2-SNAPSHOT</version>
<name>Pay Java - Parent</name>
<description>Pay Java Parent</description>
@@ -34,6 +34,11 @@
<email>zhangchenghui.dev@gmail.com</email>
<url>https://github.com/objcoding</url>
</developer>
<developer>
<name>hocgin</name>
<email>hocgin@gmail.com</email>
<url>https://github.com/hocgin</url>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/egzosn/pay-java-parent.git</connection>
@@ -52,17 +57,19 @@
<module>pay-java-payoneer</module>
<module>pay-java-paypal</module>
<module>pay-java-yiji</module>
<module>pay-java-baidu</module>
<module>pay-java-demo</module>
</modules>
<properties>
<pay.version>2.13.1</pay.version>
<pay.version>2.13.2-SNAPSHOT</pay.version>
<httpmime.version>4.5.4</httpmime.version>
<log4j.version>1.2.17</log4j.version>
<fastjson.version>1.2.58</fastjson.version>
<zxing.version>3.3.1</zxing.version>
<junit.version>5.5.1</junit.version>
</properties>
@@ -103,6 +110,11 @@
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
@@ -128,68 +140,85 @@
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<autoVersionSubmodules>false</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>install</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>proc</id>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<autoVersionSubmodules>false</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>install</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>