多笔退款退款接口实现

This commit is contained in:
egan
2018-01-15 23:00:41 +08:00
parent 8f5f3e8eaa
commit 87ab7f1a5d
11 changed files with 378 additions and 49 deletions

View File

@@ -165,17 +165,21 @@
#### 申请退款接口
```java
Map result = service.refund("支付宝单号", "我方系统单号", "退款金额", "订单总金额");
//过时方法
//Map result = service.refund("支付宝单号", "我方系统单号", "退款金额", "订单总金额");
//支付宝单号与我方系统单号二选一
RefundOrder order = new RefundOrder("支付宝单号", "我方系统单号", "退款金额", "订单总金额");
//非必填, 根据业务需求而定,可用于多次退款
order.setRefundNo("退款单号")
Map result = service.refund(order);
```
#### 查询退款
```java
Map result = service.refundquery("支付宝单号", "我方系统单号");
```
#### 下载对账单

View File

@@ -13,6 +13,7 @@ import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.http.UriVariables;
import com.egzosn.pay.common.util.MatrixToImageWriter;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.awt.image.BufferedImage;
@@ -367,13 +368,15 @@ public class AliPayService extends BasePayService {
}
/**
* 申请退款接口
*
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
@@ -386,7 +389,7 @@ public class AliPayService extends BasePayService {
}
/**
* 申请退款接口
*
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
@@ -394,19 +397,54 @@ public class AliPayService extends BasePayService {
* @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 refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount), callback);
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
*/
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
return refund(refundOrder, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
*/
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.REFUND);
Map<String, Object> bizContent = getBizContent(tradeNo, outTradeNo, null);
bizContent.put("refund_amount", refundAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
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", refundOrder.getRefundAmount());
//设置请求参数的集合
parameters.put("biz_content", JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}
/**
* 查询退款

View File

@@ -12,6 +12,7 @@ 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.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.awt.image.BufferedImage;
@@ -408,13 +409,15 @@ public class AliPayService extends BasePayService {
}
/**
* 申请退款接口
*
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
@@ -427,7 +430,7 @@ public class AliPayService extends BasePayService {
}
/**
* 申请退款接口
*
* 废弃
* @param tradeNo 支付平台订单号
* @param outTradeNo 商户单号
* @param refundAmount 退款金额
@@ -435,14 +438,49 @@ public class AliPayService extends BasePayService {
* @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 refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount), callback);
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
*/
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
return refund(refundOrder, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
*/
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
//获取公共参数
Map<String, Object> parameters = getPublicParameters(AliTransactionType.REFUND);
Map<String, Object> bizContent = getBizContent(tradeNo, outTradeNo, null);
bizContent.put("refund_amount", refundAmount);
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", refundOrder.getRefundAmount());
//设置请求参数的集合
parameters.put("biz_content", JSON.toJSONString(bizContent));
//设置签名

View File

@@ -198,17 +198,19 @@ public interface PayService {
/**
* 申请退款接口
*
* 废弃
* @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 退款金额
@@ -216,9 +218,28 @@ public interface PayService {
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
<T>T refund(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback);
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
*/
Map<String, Object> refund(RefundOrder refundOrder);
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @return 返回支付方申请退款后的结果
*/
<T>T refund(RefundOrder refundOrder, Callback<T> callback);
/**
* 查询退款
*

View File

@@ -0,0 +1,112 @@
package com.egzosn.pay.common.bean;
import java.math.BigDecimal;
import java.util.Date;
/**
* 退款订单信息
* @author: egan
* <pre>
* email egzosn@gmail.com
* date 2018/1/15 21:40
* </pre>
*/
public class RefundOrder {
/**
* 退款单号,每次进行退款的单号,此处唯一
*/
private String refundNo;
/**
* 支付平台订单号,交易号
*/
private String tradeNo;
/**
* 商户单号
*/
private String outTradeNo;
/**
* 退款金额
*/
private BigDecimal refundAmount;
/**
* 订单总金额
*/
private BigDecimal totalAmount;
/**
* 交易日期
*/
private Date orderDate;
public String getRefundNo() {
return refundNo;
}
public void setRefundNo(String refundNo) {
this.refundNo = refundNo;
}
public String getTradeNo() {
return tradeNo;
}
public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
}
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public BigDecimal getRefundAmount() {
return refundAmount;
}
public void setRefundAmount(BigDecimal refundAmount) {
this.refundAmount = refundAmount;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public RefundOrder() {
}
public RefundOrder(String refundNo, String tradeNo, BigDecimal refundAmount) {
this.refundNo = refundNo;
this.tradeNo = tradeNo;
this.refundAmount = refundAmount;
}
public RefundOrder(String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
this.tradeNo = tradeNo;
this.outTradeNo = outTradeNo;
this.refundAmount = refundAmount;
this.totalAmount = totalAmount;
}
public RefundOrder(String refundNo, String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
this.refundNo = refundNo;
this.tradeNo = tradeNo;
this.outTradeNo = outTradeNo;
this.refundAmount = refundAmount;
this.totalAmount = totalAmount;
}
}

View File

@@ -358,19 +358,12 @@ public class FuiouPayService extends BasePayService {
*/
@Override
public Map<String, Object> refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
Map<String ,Object> params = new HashMap<>();
params.put("mchnt_cd",payConfigStorage.getPid());//商户代码
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
params.put("origin_order_date",df.format(new Date()));//原交易日期
params.put("origin_order_id",tradeNo);//原订单号
params.put("refund_amt",refundAmount.multiply(new BigDecimal(100)).setScale( 0, BigDecimal.ROUND_HALF_UP).intValue());//退款金额
params.put("rem","");//备注
params.put("md5",createSign(SignUtils.parameters2MD5Str(params,"|"),payConfigStorage.getInputCharset()));
JSONObject resultJson = getHttpRequestTemplate().postForObject(getReqUrl() + URL_FuiouSmpRefundGate,params,JSONObject.class);
//5341标识退款成功
return resultJson;
return refund(tradeNo, outTradeNo, refundAmount, totalAmount, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
/**
@@ -385,9 +378,51 @@ public class FuiouPayService extends BasePayService {
*/
@Override
public <T> T refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback) {
return null;
return refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount), callback);
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 退款返回结果集
*/
@Override
public Map<String, Object> refund (RefundOrder refundOrder) {
return refund(refundOrder, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @param callback 处理器
* @return 空
*/
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
Map<String ,Object> params = new HashMap<>();
params.put("mchnt_cd",payConfigStorage.getPid());//商户代码
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
params.put("origin_order_date",refundOrder.getOrderDate());//原交易日期
params.put("origin_order_id",refundOrder.getTradeNo());//原订单号
params.put("refund_amt",refundOrder.getRefundAmount().multiply(new BigDecimal(100)).setScale( 0, BigDecimal.ROUND_HALF_UP).intValue());//退款金额
params.put("rem","");//备注
params.put("md5",createSign(SignUtils.parameters2MD5Str(params,"|"),payConfigStorage.getInputCharset()));
JSONObject resultJson = getHttpRequestTemplate().postForObject(getReqUrl() + URL_FuiouSmpRefundGate,params,JSONObject.class);
//5341标识退款成功
return callback.perform(params);
}
/**
* 查询退款
* @param tradeNo 支付平台订单号

View File

@@ -477,17 +477,28 @@ public class UnionPayService extends BasePayService {
/**
* 消费撤销/退货接口
* @param origQryId 原交易查询流水号.
* @param orderId 单号
* @param totalAmount 金额
* @param orderId 退款单号
* @param refundAmount 退款金额
* @param type UnionTransactionType.REFUND 或者UnionTransactionType.CONSUME_UNDO
* @return 返回支付方申请退款后的结果
*/
public Map<String, Object> unionRefundOrConsumeUndo (String origQryId, String orderId, BigDecimal totalAmount,UnionTransactionType type) {
public Map<String, Object> unionRefundOrConsumeUndo (String origQryId, String orderId, BigDecimal refundAmount,UnionTransactionType type) {
return unionRefundOrConsumeUndo(new RefundOrder(orderId, origQryId,refundAmount ), type);
}
/**
* 消费撤销/退货接口
* @param refundOrder 退款订单信息
* @param type UnionTransactionType.REFUND 或者UnionTransactionType.CONSUME_UNDO
* @return 返回支付方申请退款后的结果
*/
public Map<String, Object> unionRefundOrConsumeUndo (RefundOrder refundOrder,UnionTransactionType type) {
Map<String ,Object> params = this.getCommonParam();
type.convertMap(params);
params.put(SDKConstants.param_orderId,orderId);
params.put(SDKConstants.param_txnAmt, totalAmount);
params.put(SDKConstants.param_origQryId, origQryId);
params.put(SDKConstants.param_orderId, refundOrder.getRefundNo());
params.put(SDKConstants.param_txnAmt, refundOrder.getRefundAmount());
params.put(SDKConstants.param_origQryId, refundOrder.getTradeNo());
this.setSign(params);
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(),params,String.class);
JSONObject response = UriVariables.getParametersToMap(responseStr);
@@ -500,10 +511,8 @@ public class UnionPayService extends BasePayService {
}
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
}
throw new PayErrorException(new PayException("failure", "验证签名失败", response.toJSONString()));
}
/**
* 交易关闭接口
@@ -538,10 +547,17 @@ public class UnionPayService extends BasePayService {
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder)
*/
@Deprecated
@Override
public Map<String, Object> refund (String tradeNo, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
return unionRefundOrConsumeUndo(tradeNo, outTradeNo, totalAmount, UnionTransactionType.REFUND);
return refund(tradeNo, outTradeNo, refundAmount, totalAmount, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
@@ -555,10 +571,28 @@ public class UnionPayService extends BasePayService {
* @param totalAmount 总金额
* @param callback 处理器
* @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(unionRefundOrConsumeUndo(tradeNo, outTradeNo, totalAmount, UnionTransactionType.REFUND));
return refund(new RefundOrder(tradeNo, outTradeNo, refundAmount, totalAmount), callback);
}
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
return refund(refundOrder, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
return callback.perform(unionRefundOrConsumeUndo(refundOrder, UnionTransactionType.REFUND));
}
/**

View File

@@ -69,7 +69,7 @@ public class PayTest {
/*-----------消费(被扫场景)------------------------------*/
// /*-----------消费撤销------------------------------*/
params = service.unionRefundOrConsumeUndo("原交易查询流水", "订单", new BigDecimal("退款金额" ),UnionTransactionType.CONSUME_UNDO);
params = service.unionRefundOrConsumeUndo(new RefundOrder( "订单", "原交易查询流水", new BigDecimal("退款金额" )),UnionTransactionType.CONSUME_UNDO);
// /*-----------消费撤销------------------------------*/
/*-----------交易状态查询交易:只有同步应答------------------------------*/

View File

@@ -412,6 +412,16 @@ public class WxYouDianPayService extends BasePayService {
return null;
}
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
return null;
}
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
return null;
}
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return null;

View File

@@ -158,8 +158,13 @@
#### 申请退款接口
```java
Map result = service.refund("微信单号", "我方系统单号", "退款金额", "订单总金额");
//过时方法
//Map result = service.refund("微信单号", "我方系统单号", "退款金额", "订单总金额");
//微信单号与我方系统单号二选一
RefundOrder order = new RefundOrder("微信单号", "我方系统单号", "退款金额", "订单总金额");
//可用于多次退款
order.setRefundNo("退款单号")
Map result = service.refund(order);
```

View File

@@ -438,7 +438,9 @@ public class WxPayService extends BasePayService {
* @param refundAmount 退款金额
* @param totalAmount 总金额
* @return 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
@Override
public Map<String, Object> refund(String transactionId, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount) {
@@ -460,21 +462,51 @@ public class WxPayService extends BasePayService {
* @param callback 处理器
* @param <T> 返回类型
* @return 处理过后的类型对象, 返回支付方申请退款后的结果
* @see #refund(RefundOrder, Callback)
*/
@Deprecated
@Override
public <T> T refund(String transactionId, String outTradeNo, BigDecimal refundAmount, BigDecimal totalAmount, Callback<T> callback) {
return refund(new RefundOrder(transactionId, outTradeNo, refundAmount, totalAmount), callback);
}
/**
* 申请退款接口
*
* @param refundOrder 退款订单信息
* @return 返回支付方申请退款后的结果
*/
@Override
public Map<String, Object> refund(RefundOrder refundOrder) {
return refund(refundOrder, new Callback<Map<String, Object>>() {
@Override
public Map<String, Object> perform(Map<String, Object> map) {
return map;
}
});
}
/**
* 退款
*
* @param refundOrder 退款订单信息
* @param callback 处理器
* @param <T> 返回类型
* @return 处理过后的类型对象, 返回支付方申请退款后的结果
*/
@Override
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
//获取公共参数
Map<String, Object> parameters = getPublicParameters();
if (null != transactionId) {
parameters.put("transaction_id", transactionId);
parameters.put("out_refund_no", transactionId);
if (null != refundOrder.getTradeNo()) {
parameters.put("transaction_id", refundOrder.getTradeNo());
} else {
parameters.put("out_trade_no", outTradeNo);
parameters.put("out_refund_no", outTradeNo);
parameters.put("out_trade_no", refundOrder.getOutTradeNo());
}
parameters.put("total_fee", totalAmount.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
parameters.put("refund_fee", refundAmount.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
parameters.put("out_refund_no", refundOrder.getRefundNo());
parameters.put("total_fee", refundOrder.getTotalAmount().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
parameters.put("refund_fee", refundOrder.getRefundAmount().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue());
parameters.put("op_user_id", payConfigStorage.getPid());
//设置签名