mirror of
https://gitee.com/egzosn/pay-java-parent.git
synced 2026-06-02 05:50:29 +08:00
退款结果集统一处理
This commit is contained in:
@@ -236,7 +236,7 @@
|
||||
RefundOrder order = new RefundOrder("支付宝单号", "我方系统单号", "退款金额", "订单总金额");
|
||||
//非必填, 根据业务需求而定,可用于多次退款
|
||||
order.setRefundNo("退款单号")
|
||||
Map result = service.refund(order);
|
||||
AliRefundResult result = service.refund(order);
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.egzosn.pay.ali.api;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.egzosn.pay.ali.bean.AliPayMessage;
|
||||
import com.egzosn.pay.ali.bean.AliRefundResult;
|
||||
import com.egzosn.pay.ali.bean.AliTransactionType;
|
||||
import com.egzosn.pay.ali.bean.AliTransferType;
|
||||
import com.egzosn.pay.ali.bean.OrderSettle;
|
||||
@@ -437,7 +438,7 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public AliRefundResult refund(RefundOrder refundOrder) {
|
||||
//获取公共参数
|
||||
Map<String, Object> parameters = getPublicParameters(AliTransactionType.REFUND);
|
||||
setAppAuthToken(parameters, refundOrder.getAttrs());
|
||||
@@ -451,7 +452,9 @@ public class AliPayService extends BasePayService<AliPayConfigStorage> {
|
||||
parameters.put(BIZ_CONTENT, JSON.toJSONString(bizContent));
|
||||
//设置签名
|
||||
setSign(parameters);
|
||||
return requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class);
|
||||
final AliRefundResult refundResult = AliRefundResult.create(requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
|
||||
refundResult.setOutRequestNo(refundOrder.getRefundNo());
|
||||
return refundResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
package com.egzosn.pay.ali.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.egzosn.pay.common.bean.BaseRefundResult;
|
||||
import com.egzosn.pay.common.bean.CurType;
|
||||
import com.egzosn.pay.common.bean.DefaultCurType;
|
||||
import com.egzosn.pay.common.bean.RefundOrder;
|
||||
|
||||
/**
|
||||
* 支付宝退款结果返回
|
||||
*
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 17:53
|
||||
* </pre>
|
||||
*/
|
||||
public class AliRefundResult extends BaseRefundResult {
|
||||
|
||||
/**
|
||||
* 网关返回码,详见文档 40004
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 网关返回码描述,详见文档 Business Failed
|
||||
*/
|
||||
private String msg;
|
||||
/**
|
||||
* 业务返回码,参见具体的API接口文档 ACQ.TRADE_HAS_SUCCESS
|
||||
*/
|
||||
@JSONField(name = "sub_code")
|
||||
private String subCode;
|
||||
|
||||
/**
|
||||
* 业务返回码描述,参见具体的API接口文档 交易已被支付
|
||||
*/
|
||||
@JSONField(name = "sub_msg")
|
||||
private String subMsg;
|
||||
/**
|
||||
* 签名,详见文档
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 支付宝交易号
|
||||
*/
|
||||
@JSONField(name = "trade_no")
|
||||
private String tradeNo;
|
||||
/**
|
||||
* 商户订单号 6823789339978248
|
||||
*/
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 标识一次退款请求,同一笔交易多次退款需要保证唯一
|
||||
* <p>
|
||||
* 因支付宝退款结果中没有返回此参数,该参数从{@link RefundOrder#getRefundNo()}获取
|
||||
*/
|
||||
private String outRequestNo;
|
||||
/**
|
||||
* 用户的登录id 159****5620
|
||||
*/
|
||||
@JSONField(name = "buyer_logon_id")
|
||||
private String buyerLogonId;
|
||||
/**
|
||||
* 本次退款是否发生了资金变化 Y
|
||||
*/
|
||||
@JSONField(name = "fund_change")
|
||||
private String fundChange;
|
||||
/**
|
||||
* 退款总金额 88.88
|
||||
*/
|
||||
@JSONField(name = "refund_fee")
|
||||
private BigDecimal refundFee;
|
||||
/**
|
||||
* 退款币种信息 USD
|
||||
*/
|
||||
@JSONField(name = "refund_currency")
|
||||
private DefaultCurType refundCurrency;
|
||||
/**
|
||||
* 退款支付时间 2014-11-27 15:45:57
|
||||
*/
|
||||
@JSONField(name = "gmt_refund_pay")
|
||||
private Date gmtRefundPay;
|
||||
|
||||
/**
|
||||
* 退款使用的资金渠道。
|
||||
* 只有在签约中指定需要返回资金明细,或者入参的query_options中指定时才返回该字段信息。
|
||||
*/
|
||||
@JSONField(name = "refund_detail_item_list")
|
||||
private TradeFundBill refundDetailItemList;
|
||||
/**
|
||||
* 交易在支付时候的门店名称
|
||||
*/
|
||||
@JSONField(name = "store_name")
|
||||
private String storeName;
|
||||
/**
|
||||
* 买家在支付宝的用户id 2088101117955611
|
||||
*/
|
||||
@JSONField(name = "buyer_user_id")
|
||||
private String buyerUserId;
|
||||
/**
|
||||
* 退回的前置资产列表
|
||||
*/
|
||||
@JSONField(name = "refund_preset_paytool_list")
|
||||
private PresetPayToolInfo refundPresetPaytoolList;
|
||||
/**
|
||||
* 退款清算编号,用于清算对账使用;
|
||||
* 只在银行间联交易场景下返回该信息; 2018101610032004620239146945
|
||||
*/
|
||||
@JSONField(name = "refund_settlement_id")
|
||||
private String refundSettlementId;
|
||||
/**
|
||||
* 本次退款金额中买家退款金额 88.88
|
||||
*/
|
||||
@JSONField(name = "present_refund_buyer_amount")
|
||||
private String presentRefundBuyerAmount;
|
||||
/**
|
||||
* 本次退款金额中平台优惠退款金额 88.88
|
||||
*/
|
||||
@JSONField(name = "present_refund_discount_amount")
|
||||
private String presentRefundDiscountAmount;
|
||||
/**
|
||||
* 本次退款金额中商家优惠退款金额 88.88
|
||||
*/
|
||||
@JSONField(name = "present_refund_mdiscount_amount")
|
||||
private String presentRefundMdiscountAmount;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态码
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态提示信息
|
||||
*
|
||||
* @return 提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态码
|
||||
*
|
||||
* @return 业务结果状态码
|
||||
*/
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return subCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态提示信息
|
||||
*
|
||||
* @return 业务结果状态提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return subMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*
|
||||
* @return 退款金额
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return refundFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款币种信息
|
||||
*
|
||||
* @return 币种信息
|
||||
*/
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return refundCurrency;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付平台交易号
|
||||
* 发起支付时 支付平台(如支付宝)返回的交易订单号
|
||||
*
|
||||
* @return 支付平台交易号
|
||||
*/
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return tradeNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单号
|
||||
* 发起支付时,用户系统的订单号
|
||||
*
|
||||
* @return 支付订单号
|
||||
*/
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户退款单号
|
||||
*
|
||||
* @return 商户退款单号
|
||||
*/
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return outRequestNo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getSubCode() {
|
||||
return subCode;
|
||||
}
|
||||
|
||||
public void setSubCode(String subCode) {
|
||||
this.subCode = subCode;
|
||||
}
|
||||
|
||||
public String getSubMsg() {
|
||||
return subMsg;
|
||||
}
|
||||
|
||||
public void setSubMsg(String subMsg) {
|
||||
this.subMsg = subMsg;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public void setTradeNo(String tradeNo) {
|
||||
this.tradeNo = tradeNo;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public String getOutRequestNo() {
|
||||
return outRequestNo;
|
||||
}
|
||||
|
||||
public void setOutRequestNo(String outRequestNo) {
|
||||
this.outRequestNo = outRequestNo;
|
||||
}
|
||||
|
||||
public String getBuyerLogonId() {
|
||||
return buyerLogonId;
|
||||
}
|
||||
|
||||
public void setBuyerLogonId(String buyerLogonId) {
|
||||
this.buyerLogonId = buyerLogonId;
|
||||
}
|
||||
|
||||
public String getFundChange() {
|
||||
return fundChange;
|
||||
}
|
||||
|
||||
public void setFundChange(String fundChange) {
|
||||
this.fundChange = fundChange;
|
||||
}
|
||||
|
||||
public void setRefundFee(BigDecimal refundFee) {
|
||||
this.refundFee = refundFee;
|
||||
}
|
||||
|
||||
public void setRefundCurrency(DefaultCurType refundCurrency) {
|
||||
this.refundCurrency = refundCurrency;
|
||||
}
|
||||
|
||||
public Date getGmtRefundPay() {
|
||||
return gmtRefundPay;
|
||||
}
|
||||
|
||||
public void setGmtRefundPay(Date gmtRefundPay) {
|
||||
this.gmtRefundPay = gmtRefundPay;
|
||||
}
|
||||
|
||||
public TradeFundBill getRefundDetailItemList() {
|
||||
return refundDetailItemList;
|
||||
}
|
||||
|
||||
public void setRefundDetailItemList(TradeFundBill refundDetailItemList) {
|
||||
this.refundDetailItemList = refundDetailItemList;
|
||||
}
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName = storeName;
|
||||
}
|
||||
|
||||
public String getBuyerUserId() {
|
||||
return buyerUserId;
|
||||
}
|
||||
|
||||
public void setBuyerUserId(String buyerUserId) {
|
||||
this.buyerUserId = buyerUserId;
|
||||
}
|
||||
|
||||
public PresetPayToolInfo getRefundPresetPaytoolList() {
|
||||
return refundPresetPaytoolList;
|
||||
}
|
||||
|
||||
public void setRefundPresetPaytoolList(PresetPayToolInfo refundPresetPaytoolList) {
|
||||
this.refundPresetPaytoolList = refundPresetPaytoolList;
|
||||
}
|
||||
|
||||
public String getRefundSettlementId() {
|
||||
return refundSettlementId;
|
||||
}
|
||||
|
||||
public void setRefundSettlementId(String refundSettlementId) {
|
||||
this.refundSettlementId = refundSettlementId;
|
||||
}
|
||||
|
||||
public String getPresentRefundBuyerAmount() {
|
||||
return presentRefundBuyerAmount;
|
||||
}
|
||||
|
||||
public void setPresentRefundBuyerAmount(String presentRefundBuyerAmount) {
|
||||
this.presentRefundBuyerAmount = presentRefundBuyerAmount;
|
||||
}
|
||||
|
||||
public String getPresentRefundDiscountAmount() {
|
||||
return presentRefundDiscountAmount;
|
||||
}
|
||||
|
||||
public void setPresentRefundDiscountAmount(String presentRefundDiscountAmount) {
|
||||
this.presentRefundDiscountAmount = presentRefundDiscountAmount;
|
||||
}
|
||||
|
||||
public String getPresentRefundMdiscountAmount() {
|
||||
return presentRefundMdiscountAmount;
|
||||
}
|
||||
|
||||
public void setPresentRefundMdiscountAmount(String presentRefundMdiscountAmount) {
|
||||
this.presentRefundMdiscountAmount = presentRefundMdiscountAmount;
|
||||
}
|
||||
public static final AliRefundResult create(Map<String, Object> result){
|
||||
AliRefundResult refundResult = new JSONObject(result).toJavaObject(AliRefundResult.class);
|
||||
refundResult.setAttrs(result);
|
||||
return refundResult;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.egzosn.pay.ali.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 退回的前置资产列表
|
||||
*
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 18:58
|
||||
* </pre>
|
||||
*/
|
||||
public class PresetPayToolInfo {
|
||||
|
||||
/**
|
||||
* 必填 32前置资产金额 12.21
|
||||
*/
|
||||
private BigDecimal[] amount;
|
||||
|
||||
/**
|
||||
* 前置资产类型编码,和收单支付传入的preset_pay_tool里面的类型编码保持一致。盒马礼品卡:HEMA;抓猫猫红包:T_CAT_COUPON
|
||||
*/
|
||||
@JSONField(name = "assert_type_code")
|
||||
private String assertTypeCode;
|
||||
|
||||
public BigDecimal[] getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal[] amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getAssertTypeCode() {
|
||||
return assertTypeCode;
|
||||
}
|
||||
|
||||
public void setAssertTypeCode(String assertTypeCode) {
|
||||
this.assertTypeCode = assertTypeCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.egzosn.pay.ali.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 退款使用的资金渠道。
|
||||
* 只有在签约中指定需要返回资金明细,或者入参的query_options中指定时才返回该字段信息。
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 18:51
|
||||
* </pre>
|
||||
*/
|
||||
public class TradeFundBill {
|
||||
/**
|
||||
* 交易使用的资金渠道,详见 支付渠道列表 ALIPAYACCOUNT
|
||||
*/
|
||||
@JSONField(name = "fund_channel")
|
||||
private String fundChannel;
|
||||
/**
|
||||
* 银行卡支付时的银行代码 CEB
|
||||
*/
|
||||
@JSONField(name = "bank_code")
|
||||
private String bankCode;
|
||||
/**
|
||||
* 该支付工具类型所使用的金额 10
|
||||
*/
|
||||
private BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 渠道实际付款金额 11.21
|
||||
*/
|
||||
@JSONField(name = "real_amount")
|
||||
private BigDecimal realAmount;
|
||||
/**
|
||||
* 渠道所使用的资金类型,目前只在资金渠道(fund_channel)是银行卡渠道(BANKCARD)的情况下才返回该信息(DEBIT_CARD:借记卡,CREDIT_CARD:信用卡,MIXED_CARD:借贷合一卡) DEBIT_CARD
|
||||
*/
|
||||
@JSONField(name = "fund_type")
|
||||
private String fundType;
|
||||
|
||||
public String getFundChannel() {
|
||||
return fundChannel;
|
||||
}
|
||||
|
||||
public void setFundChannel(String fundChannel) {
|
||||
this.fundChannel = fundChannel;
|
||||
}
|
||||
|
||||
public String getBankCode() {
|
||||
return bankCode;
|
||||
}
|
||||
|
||||
public void setBankCode(String bankCode) {
|
||||
this.bankCode = bankCode;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public BigDecimal getRealAmount() {
|
||||
return realAmount;
|
||||
}
|
||||
|
||||
public void setRealAmount(BigDecimal realAmount) {
|
||||
this.realAmount = realAmount;
|
||||
}
|
||||
|
||||
public String getFundType() {
|
||||
return fundType;
|
||||
}
|
||||
|
||||
public void setFundType(String fundType) {
|
||||
this.fundType = fundType;
|
||||
}
|
||||
}
|
||||
@@ -316,7 +316,7 @@ public class BaiduPayService extends BasePayService<BaiduPayConfigStorage> {
|
||||
* @return 退款结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public BaseRefundResult refund(RefundOrder refundOrder) {
|
||||
Map<String, Object> parameters = getUseQueryPay();
|
||||
BaiduTransactionType transactionType = BaiduTransactionType.APPLY_REFUND;
|
||||
parameters.put(METHOD, transactionType.getMethod());
|
||||
@@ -329,7 +329,53 @@ public class BaiduPayService extends BasePayService<BaiduPayConfigStorage> {
|
||||
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);
|
||||
final JSONObject result = requestTemplate.getForObject(String.format("%s?%s", getReqUrl(transactionType), UriVariables.getMapToParameters(parameters)), JSONObject.class);
|
||||
return new BaseRefundResult(result) {
|
||||
@Override
|
||||
public String getCode() {
|
||||
return getAttrString(RESPONSE_STATUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ public abstract class BasePayService<PC extends PayConfigStorage> implements Pay
|
||||
@Override
|
||||
public <T> T refund(RefundOrder refundOrder, Callback<T> callback) {
|
||||
|
||||
return callback.perform(refund(refundOrder));
|
||||
return callback.perform(refund(refundOrder).getAttrs());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ public interface PayService<PC extends PayConfigStorage> {
|
||||
* @param refundOrder 退款订单信息
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
Map<String, Object> refund(RefundOrder refundOrder);
|
||||
RefundResult refund(RefundOrder refundOrder);
|
||||
|
||||
/**
|
||||
* 申请退款接口
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
package com.egzosn.pay.common.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 基础的退款结果对象
|
||||
*
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 19:29
|
||||
* </pre>
|
||||
*/
|
||||
public abstract class BaseRefundResult implements RefundResult {
|
||||
|
||||
/**
|
||||
* 属性集,支付宝退款结果
|
||||
*/
|
||||
private Map<String, Object> attrs;
|
||||
|
||||
|
||||
public BaseRefundResult() {
|
||||
}
|
||||
|
||||
public BaseRefundResult(Map<String, Object> attrs) {
|
||||
this.attrs = attrs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款结果原信息集
|
||||
*
|
||||
* @return 属性
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getAttrs() {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
public void setAttrs(Map<String, Object> attrs) {
|
||||
this.attrs = attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款结果属性值
|
||||
*
|
||||
* @param key 属性名
|
||||
* @return 属性
|
||||
*/
|
||||
@Override
|
||||
public Object getAttr(String key) {
|
||||
return attrs.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款结果属性值
|
||||
*
|
||||
* @param key 属性名
|
||||
* @return 属性值
|
||||
*/
|
||||
@Override
|
||||
public String getAttrString(String key) {
|
||||
return attrs.get(key).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款结果属性值
|
||||
*
|
||||
* @param key 属性名
|
||||
* @return 属性值
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getAttrDecimal(String key) {
|
||||
return new BigDecimal(getAttrString(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings in this map. If the
|
||||
* map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*
|
||||
* @return the number of key-value mappings in this map
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return attrs.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains no key-value mappings.
|
||||
*
|
||||
* @return <tt>true</tt> if this map contains no key-value mappings
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return attrs.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key. More formally, returns <tt>true</tt> if and only if
|
||||
* this map contains a mapping for a key <tt>k</tt> such that
|
||||
* <tt>(key==null ? k==null : key.equals(k))</tt>. (There can be
|
||||
* at most one such mapping.)
|
||||
*
|
||||
* @param key key whose presence in this map is to be tested
|
||||
* @return <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key
|
||||
* @throws ClassCastException if the key is of an inappropriate type for
|
||||
* this map
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key is null and this map
|
||||
* does not permit null keys
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return attrs.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map maps one or more keys to the
|
||||
* specified value. More formally, returns <tt>true</tt> if and only if
|
||||
* this map contains at least one mapping to a value <tt>v</tt> such that
|
||||
* <tt>(value==null ? v==null : value.equals(v))</tt>. This operation
|
||||
* will probably require time linear in the map size for most
|
||||
* implementations of the <tt>Map</tt> interface.
|
||||
*
|
||||
* @param value value whose presence in this map is to be tested
|
||||
* @return <tt>true</tt> if this map maps one or more keys to the
|
||||
* specified value
|
||||
* @throws ClassCastException if the value is of an inappropriate type for
|
||||
* this map
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified value is null and this
|
||||
* map does not permit null values
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return attrs.containsValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped,
|
||||
* or {@code null} if this map contains no mapping for the key.
|
||||
*
|
||||
* <p>More formally, if this map contains a mapping from a key
|
||||
* {@code k} to a value {@code v} such that {@code (key==null ? k==null :
|
||||
* key.equals(k))}, then this method returns {@code v}; otherwise
|
||||
* it returns {@code null}. (There can be at most one such mapping.)
|
||||
*
|
||||
* <p>If this map permits null values, then a return value of
|
||||
* {@code null} does not <i>necessarily</i> indicate that the map
|
||||
* contains no mapping for the key; it's also possible that the map
|
||||
* explicitly maps the key to {@code null}. The {@link #containsKey
|
||||
* containsKey} operation may be used to distinguish these two cases.
|
||||
*
|
||||
* @param key the key whose associated value is to be returned
|
||||
* @return the value to which the specified key is mapped, or
|
||||
* {@code null} if this map contains no mapping for the key
|
||||
* @throws ClassCastException if the key is of an inappropriate type for
|
||||
* this map
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key is null and this map
|
||||
* does not permit null keys
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return attrs.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the specified value with the specified key in this map
|
||||
* (optional operation). If the map previously contained a mapping for
|
||||
* the key, the old value is replaced by the specified value. (A map
|
||||
* <tt>m</tt> is said to contain a mapping for a key <tt>k</tt> if and only
|
||||
* if {@link #containsKey(Object) m.containsKey(k)} would return
|
||||
* <tt>true</tt>.)
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param value value to be associated with the specified key
|
||||
* @return the previous value associated with <tt>key</tt>, or
|
||||
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
|
||||
* (A <tt>null</tt> return can also indicate that the map
|
||||
* previously associated <tt>null</tt> with <tt>key</tt>,
|
||||
* if the implementation supports <tt>null</tt> values.)
|
||||
* @throws UnsupportedOperationException if the <tt>put</tt> operation
|
||||
* is not supported by this map
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* @throws NullPointerException if the specified key or value is null
|
||||
* and this map does not permit null keys or values
|
||||
* @throws IllegalArgumentException if some property of the specified key
|
||||
* or value prevents it from being stored in this map
|
||||
*/
|
||||
@Override
|
||||
public Object put(String key, Object value) {
|
||||
return attrs.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping for a key from this map if it is present
|
||||
* (optional operation). More formally, if this map contains a mapping
|
||||
* from key <tt>k</tt> to value <tt>v</tt> such that
|
||||
* <code>(key==null ? k==null : key.equals(k))</code>, that mapping
|
||||
* is removed. (The map can contain at most one such mapping.)
|
||||
*
|
||||
* <p>Returns the value to which this map previously associated the key,
|
||||
* or <tt>null</tt> if the map contained no mapping for the key.
|
||||
*
|
||||
* <p>If this map permits null values, then a return value of
|
||||
* <tt>null</tt> does not <i>necessarily</i> indicate that the map
|
||||
* contained no mapping for the key; it's also possible that the map
|
||||
* explicitly mapped the key to <tt>null</tt>.
|
||||
*
|
||||
* <p>The map will not contain a mapping for the specified key once the
|
||||
* call returns.
|
||||
*
|
||||
* @param key key whose mapping is to be removed from the map
|
||||
* @return the previous value associated with <tt>key</tt>, or
|
||||
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
|
||||
* is not supported by this map
|
||||
* @throws ClassCastException if the key is of an inappropriate type for
|
||||
* this map
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key is null and this
|
||||
* map does not permit null keys
|
||||
* (<a href="{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
return attrs.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all of the mappings from the specified map to this map
|
||||
* (optional operation). The effect of this call is equivalent to that
|
||||
* of calling {@link #put(Object, Object) put(k, v)} on this map once
|
||||
* for each mapping from key <tt>k</tt> to value <tt>v</tt> in the
|
||||
* specified map. The behavior of this operation is undefined if the
|
||||
* specified map is modified while the operation is in progress.
|
||||
*
|
||||
* @param m mappings to be stored in this map
|
||||
* @throws UnsupportedOperationException if the <tt>putAll</tt> operation
|
||||
* is not supported by this map
|
||||
* @throws ClassCastException if the class of a key or value in the
|
||||
* specified map prevents it from being stored in this map
|
||||
* @throws NullPointerException if the specified map is null, or if
|
||||
* this map does not permit null keys or values, and the
|
||||
* specified map contains null keys or values
|
||||
* @throws IllegalArgumentException if some property of a key or value in
|
||||
* the specified map prevents it from being stored in this map
|
||||
*/
|
||||
@Override
|
||||
public void putAll(Map<? extends String, ?> m) {
|
||||
attrs.putAll(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the mappings from this map (optional operation).
|
||||
* The map will be empty after this call returns.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>clear</tt> operation
|
||||
* is not supported by this map
|
||||
*/
|
||||
@Override
|
||||
public void clear() {
|
||||
attrs.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the keys contained in this map.
|
||||
* The set is backed by the map, so changes to the map are
|
||||
* reflected in the set, and vice-versa. If the map is modified
|
||||
* while an iteration over the set is in progress (except through
|
||||
* the iterator's own <tt>remove</tt> operation), the results of
|
||||
* the iteration are undefined. The set supports element removal,
|
||||
* which removes the corresponding mapping from the map, via the
|
||||
* <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
|
||||
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
|
||||
* operations. It does not support the <tt>add</tt> or <tt>addAll</tt>
|
||||
* operations.
|
||||
*
|
||||
* @return a set view of the keys contained in this map
|
||||
*/
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return attrs.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Collection} view of the values contained in this map.
|
||||
* The collection is backed by the map, so changes to the map are
|
||||
* reflected in the collection, and vice-versa. If the map is
|
||||
* modified while an iteration over the collection is in progress
|
||||
* (except through the iterator's own <tt>remove</tt> operation),
|
||||
* the results of the iteration are undefined. The collection
|
||||
* supports element removal, which removes the corresponding
|
||||
* mapping from the map, via the <tt>Iterator.remove</tt>,
|
||||
* <tt>Collection.remove</tt>, <tt>removeAll</tt>,
|
||||
* <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
|
||||
* support the <tt>add</tt> or <tt>addAll</tt> operations.
|
||||
*
|
||||
* @return a collection view of the values contained in this map
|
||||
*/
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
return attrs.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the mappings contained in this map.
|
||||
* The set is backed by the map, so changes to the map are
|
||||
* reflected in the set, and vice-versa. If the map is modified
|
||||
* while an iteration over the set is in progress (except through
|
||||
* the iterator's own <tt>remove</tt> operation, or through the
|
||||
* <tt>setValue</tt> operation on a map entry returned by the
|
||||
* iterator) the results of the iteration are undefined. The set
|
||||
* supports element removal, which removes the corresponding
|
||||
* mapping from the map, via the <tt>Iterator.remove</tt>,
|
||||
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
|
||||
* <tt>clear</tt> operations. It does not support the
|
||||
* <tt>add</tt> or <tt>addAll</tt> operations.
|
||||
*
|
||||
* @return a set view of the mappings contained in this map
|
||||
*/
|
||||
@Override
|
||||
public Set<Entry<String, Object>> entrySet() {
|
||||
return attrs.entrySet();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original egan.
|
||||
* Copyright 2017 the original egan.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.egzosn.pay.common.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -11,7 +12,7 @@ import java.util.Map;
|
||||
* date 2020/01/05 13:34
|
||||
* </pre>
|
||||
*/
|
||||
public interface Order {
|
||||
public interface Order extends Serializable {
|
||||
|
||||
/**
|
||||
* 获取订单属性 这里可用做覆盖已设置的订单信息属性,订单信息在签名前进行覆盖。
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.egzosn.pay.common.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 退款结果
|
||||
*
|
||||
* 这里继承Map为兼容方案,后续版本进行删除
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 9:55
|
||||
* </pre>
|
||||
*/
|
||||
public interface RefundResult extends Map<String, Object>, Serializable {
|
||||
/**
|
||||
* 获取退款结果原信息集
|
||||
*
|
||||
* @return 属性
|
||||
*/
|
||||
Map<String, Object> getAttrs();
|
||||
|
||||
/**
|
||||
* 获取退款结果属性值
|
||||
*
|
||||
* @param key 属性名
|
||||
* @return 属性值
|
||||
*/
|
||||
Object getAttr(String key);
|
||||
/**
|
||||
* 获取退款结果属性值
|
||||
*
|
||||
* @param key 属性名
|
||||
* @return 属性值
|
||||
*/
|
||||
String getAttrString(String key);
|
||||
/**
|
||||
* 获取退款结果属性值
|
||||
*
|
||||
* @param key 属性名
|
||||
* @return 属性值
|
||||
*/
|
||||
BigDecimal getAttrDecimal(String key);
|
||||
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态码
|
||||
* @return 状态码
|
||||
*/
|
||||
String getCode();
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态提示信息
|
||||
* @return 提示信息
|
||||
*/
|
||||
String getMsg();
|
||||
|
||||
/**
|
||||
* 返回业务结果状态码
|
||||
* @return 业务结果状态码
|
||||
*/
|
||||
String getResultCode();
|
||||
|
||||
/**
|
||||
* 返回业务结果状态提示信息
|
||||
* @return 业务结果状态提示信息
|
||||
*/
|
||||
String getResultMsg();
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
* @return 退款金额
|
||||
*/
|
||||
BigDecimal getRefundFee();
|
||||
/**
|
||||
* 退款币种信息
|
||||
* @return 币种信息
|
||||
*/
|
||||
CurType getRefundCurrency();
|
||||
|
||||
/**
|
||||
* 支付平台交易号
|
||||
* 发起支付时 支付平台(如支付宝)返回的交易订单号
|
||||
*
|
||||
* @return 支付平台交易号
|
||||
*/
|
||||
String getTradeNo();
|
||||
|
||||
/**
|
||||
* 支付订单号
|
||||
* 发起支付时,用户系统的订单号
|
||||
* @return 支付订单号
|
||||
*/
|
||||
String getOutTradeNo();
|
||||
|
||||
/**
|
||||
* 商户退款单号
|
||||
* @return 商户退款单号
|
||||
*/
|
||||
String getRefundNo();
|
||||
}
|
||||
@@ -352,9 +352,4 @@ public class XML {
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String text = "<datas><data><code>0</code><users><user><id>1</id><name>张三</name></user><user><id>2</id><name>张4</name></user></users></data></datas>";
|
||||
System.out.println( getMap2Xml(toJSONObject(text), "datas", "utf-8"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.9.10.1</version>
|
||||
<version>2.11.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,6 +4,7 @@ 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.AliRefundResult;
|
||||
import com.egzosn.pay.ali.bean.AliTransactionType;
|
||||
import com.egzosn.pay.ali.bean.AliTransferOrder;
|
||||
import com.egzosn.pay.ali.bean.AliTransferType;
|
||||
@@ -279,7 +280,7 @@ public class AliPayController {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@RequestMapping("refund")
|
||||
public Map<String, Object> refund(RefundOrder order) {
|
||||
public AliRefundResult refund(RefundOrder order) {
|
||||
return service.refund(order);
|
||||
}
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ public class PayController {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@RequestMapping("refund")
|
||||
public Map<String, Object> refund(Integer payId, RefundOrder order) {
|
||||
public RefundResult refund(Integer payId, RefundOrder order) {
|
||||
PayResponse payResponse = service.getPayResponse(payId);
|
||||
|
||||
// return payResponse.getService().refund(order.getTradeNo(), order.getOutTradeNo(), order.getRefundAmount(), order.getTotalAmount());
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.egzosn.pay.common.api.PayService;
|
||||
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.bean.RefundResult;
|
||||
import com.egzosn.pay.common.http.HttpConfigStorage;
|
||||
import com.egzosn.pay.paypal.api.PayPalConfigStorage;
|
||||
import com.egzosn.pay.paypal.api.PayPalPayService;
|
||||
@@ -86,7 +87,7 @@ public class PayPalPayController {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@RequestMapping("refund")
|
||||
public Map<String, Object> refund() {
|
||||
public RefundResult refund() {
|
||||
// TODO 这里需要 refundAmount, curType, description, tradeNo
|
||||
RefundOrder order = new RefundOrder();
|
||||
order.setCurType(DefaultCurType.USD);
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.egzosn.pay.common.util.sign.SignUtils;
|
||||
import com.egzosn.pay.demo.request.QueryOrder;
|
||||
import com.egzosn.pay.union.api.UnionPayConfigStorage;
|
||||
import com.egzosn.pay.union.api.UnionPayService;
|
||||
import com.egzosn.pay.union.bean.UnionRefundResult;
|
||||
import com.egzosn.pay.union.bean.UnionTransactionType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -266,7 +267,7 @@ public class UnionPayController {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@RequestMapping("refund")
|
||||
public Map<String, Object> refund(RefundOrder order) {
|
||||
public UnionRefundResult refund(RefundOrder order) {
|
||||
return service.refund(order);
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ public class WxPayController {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@RequestMapping("refund")
|
||||
public Map<String, Object> refund(RefundOrder order) {
|
||||
public WxRefundResult refund(RefundOrder order) {
|
||||
if("ssl 退款证书".equals(KEYSTORE)){
|
||||
throw new RuntimeException("请设置好SSL退款证书");
|
||||
}
|
||||
|
||||
@@ -9,6 +9,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 com.egzosn.pay.fuiou.bean.FuiouRefundResult;
|
||||
import com.egzosn.pay.fuiou.bean.FuiouTransactionType;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -379,7 +380,7 @@ public class FuiouPayService extends BasePayService<FuiouPayConfigStorage> {
|
||||
* @return 退款返回结果集
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public RefundResult refund(RefundOrder refundOrder) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
//商户代码
|
||||
params.put("mchnt_cd", payConfigStorage.getPid());
|
||||
@@ -394,7 +395,7 @@ public class FuiouPayService extends BasePayService<FuiouPayConfigStorage> {
|
||||
params.putAll(refundOrder.getAttrs());
|
||||
params.put("md5", createSign(SignUtils.parameters2MD5Str(params, "|"), payConfigStorage.getInputCharset()));
|
||||
JSONObject resultJson = getHttpRequestTemplate().postForObject(getReqUrl() + URL_FuiouSmpRefundGate, params, JSONObject.class);
|
||||
return resultJson;
|
||||
return FuiouRefundResult.create(resultJson);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.egzosn.pay.fuiou.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.egzosn.pay.common.bean.BaseRefundResult;
|
||||
import com.egzosn.pay.common.bean.CurType;
|
||||
|
||||
/**
|
||||
* 富友退款结果
|
||||
* @author Egan、
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 21:17
|
||||
* </pre>
|
||||
*/
|
||||
public class FuiouRefundResult extends BaseRefundResult {
|
||||
|
||||
private String originOrderId;
|
||||
/**
|
||||
* 退款状态
|
||||
* ‘0’ – 已受理
|
||||
* ‘1’ – 成功
|
||||
* ‘2’ – 失败
|
||||
*/
|
||||
@JSONField(name = "order_st")
|
||||
private String orderSt;
|
||||
/**
|
||||
* 错误代码
|
||||
* 5341表示退款成功
|
||||
*/
|
||||
@JSONField(name = "order_pay_code")
|
||||
private String orderPayCode;
|
||||
/**
|
||||
* 错误中文描述
|
||||
* 5341表示退款成功
|
||||
*/
|
||||
@JSONField(name = "order_pay_error")
|
||||
private String orderPayError;
|
||||
/**
|
||||
* 富友流水号
|
||||
* 供商户查询支付交易状态及对账用
|
||||
*/
|
||||
@JSONField(name = "fy_ssn")
|
||||
private String fySsn;
|
||||
/**
|
||||
* 保留字段
|
||||
*/
|
||||
private String resv1;
|
||||
/**
|
||||
* MD5摘要数据
|
||||
* mchnt_cd + "|" + order_st + "|" +
|
||||
* order_pay_code + "|" +
|
||||
* order_pay_error + "|" + fy_ssn + "|" +
|
||||
* resv1 + "|" + mchnt_key
|
||||
* 做MD5摘要
|
||||
* 其中mchnt_key 为32位的商户密钥,系统分配
|
||||
*/
|
||||
private String md5;
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*/
|
||||
private BigDecimal refundAmt;
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态码
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
@Override
|
||||
public String getCode() {
|
||||
return orderSt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态提示信息
|
||||
*
|
||||
* @return 提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return orderPayError;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态码
|
||||
*
|
||||
* @return 业务结果状态码
|
||||
*/
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return orderPayCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态提示信息
|
||||
*
|
||||
* @return 业务结果状态提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return orderPayError;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*
|
||||
* @return 退款金额
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款币种信息
|
||||
*
|
||||
* @return 币种信息
|
||||
*/
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付平台交易号
|
||||
* 发起支付时 支付平台(如支付宝)返回的交易订单号
|
||||
*
|
||||
* @return 支付平台交易号
|
||||
*/
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return fySsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单号
|
||||
* 发起支付时,用户系统的订单号
|
||||
*
|
||||
* @return 支付订单号
|
||||
*/
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return originOrderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户退款单号
|
||||
*
|
||||
* @return 商户退款单号
|
||||
*/
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final FuiouRefundResult create(Map<String, Object> result){
|
||||
FuiouRefundResult refundResult = new JSONObject(result).toJavaObject(FuiouRefundResult.class);
|
||||
refundResult.setAttrs(result);
|
||||
return refundResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -120,7 +120,7 @@
|
||||
//Map result = service.refund(null, "我方系统单号", null, null);
|
||||
//支付宝单号与我方系统单号二选一
|
||||
RefundOrder order = new RefundOrder(null, "我方系统单号", null, null);
|
||||
Map result = service.refund(order);
|
||||
RefundResult result = service.refund(order);
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.apache.http.Header;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -323,8 +324,53 @@ public class PayoneerPayService extends BasePayService<PayoneerConfigStorage> im
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
return close(refundOrder.getTradeNo(), refundOrder.getOutTradeNo());
|
||||
public RefundResult refund(RefundOrder refundOrder) {
|
||||
return new BaseRefundResult(close(refundOrder.getTradeNo(), refundOrder.getOutTradeNo())) {
|
||||
@Override
|
||||
public String getCode() {
|
||||
return getAttrString(CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -95,6 +95,6 @@
|
||||
order.setDescription(" description ");
|
||||
order.setTradeNo("paypal 平台的单号");
|
||||
order.setRefundAmount(new BigDecimal(0.01));
|
||||
Map result = service.refund(order);
|
||||
RefundResult result = service.refund(order);
|
||||
|
||||
```
|
||||
|
||||
@@ -249,7 +249,7 @@ public class PayPalPayService extends BasePayService<PayPalConfigStorage>{
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public RefundResult refund(RefundOrder refundOrder) {
|
||||
JSONObject request = new JSONObject();
|
||||
|
||||
if (null != refundOrder.getRefundAmount() && BigDecimal.ZERO.compareTo( refundOrder.getRefundAmount()) == -1){
|
||||
@@ -267,7 +267,52 @@ public class PayPalPayService extends BasePayService<PayPalConfigStorage>{
|
||||
HttpStringEntity httpEntity = new HttpStringEntity(request.toJSONString(), ContentType.APPLICATION_JSON);
|
||||
httpEntity.setHeaders(authHeader());
|
||||
JSONObject resp = getHttpRequestTemplate().postForObject(getReqUrl(PayPalTransactionType.REFUND), httpEntity, JSONObject.class, refundOrder.getTradeNo());
|
||||
return resp;
|
||||
return new BaseRefundResult(resp) {
|
||||
@Override
|
||||
public String getCode() {
|
||||
return getAttrString("state");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -190,6 +190,6 @@
|
||||
|
||||
RefundOrder order = new RefundOrder(null, "原交易查询流水号", "退款金额", "订单总金额");
|
||||
order.setRefundNo("退款单号")
|
||||
Map result = service.refund(order);
|
||||
UnionRefundResult result = service.refund(order);
|
||||
|
||||
```
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.egzosn.pay.common.util.sign.encrypt.RSA2;
|
||||
import com.egzosn.pay.common.util.str.StringUtils;
|
||||
import com.egzosn.pay.union.bean.SDKConstants;
|
||||
import com.egzosn.pay.union.bean.UnionPayMessage;
|
||||
import com.egzosn.pay.union.bean.UnionRefundResult;
|
||||
import com.egzosn.pay.union.bean.UnionTransactionType;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -591,7 +592,7 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
|
||||
* @param type UnionTransactionType.REFUND 或者UnionTransactionType.CONSUME_UNDO
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
public Map<String, Object> unionRefundOrConsumeUndo(RefundOrder refundOrder, UnionTransactionType type) {
|
||||
public UnionRefundResult unionRefundOrConsumeUndo(RefundOrder refundOrder, UnionTransactionType type) {
|
||||
Map<String, Object> params = this.getCommonParam();
|
||||
type.convertMap(params);
|
||||
params.put(SDKConstants.param_orderId, refundOrder.getRefundNo());
|
||||
@@ -601,12 +602,11 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
|
||||
this.setSign(params);
|
||||
String responseStr = getHttpRequestTemplate().postForObject(this.getBackTransUrl(), params, String.class);
|
||||
JSONObject response = UriVariables.getParametersToMap(responseStr);
|
||||
|
||||
if (this.verify(response)) {
|
||||
if (SDKConstants.OK_RESP_CODE.equals(response.getString(SDKConstants.param_respCode))) {
|
||||
// String origRespCode = response.getString(SDKConstants.param_origRespCode);
|
||||
//交易成功,更新商户订单状态
|
||||
//TODO
|
||||
return response;
|
||||
final UnionRefundResult refundResult = UnionRefundResult.create(response);
|
||||
if (SDKConstants.OK_RESP_CODE.equals(refundResult.getRespCode())) {
|
||||
return refundResult;
|
||||
|
||||
}
|
||||
throw new PayErrorException(new PayException(response.getString(SDKConstants.param_respCode), response.getString(SDKConstants.param_respMsg), response.toJSONString()));
|
||||
@@ -628,7 +628,7 @@ public class UnionPayService extends BasePayService<UnionPayConfigStorage> {
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public UnionRefundResult refund(RefundOrder refundOrder) {
|
||||
return unionRefundOrConsumeUndo(refundOrder, UnionTransactionType.REFUND);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
package com.egzosn.pay.union.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.egzosn.pay.common.bean.BaseRefundResult;
|
||||
import com.egzosn.pay.common.bean.CurType;
|
||||
|
||||
/**
|
||||
* 银联退款结果
|
||||
*
|
||||
* @author Egan
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 22:15
|
||||
*/
|
||||
public class UnionRefundResult extends BaseRefundResult {
|
||||
|
||||
/**
|
||||
* 二维码数据
|
||||
*/
|
||||
private String qrCode;
|
||||
/**
|
||||
* 签名
|
||||
*/
|
||||
private String signature;
|
||||
/**
|
||||
* 签名方法
|
||||
*/
|
||||
private String signMethod;
|
||||
/**
|
||||
* 应答码
|
||||
*/
|
||||
private String respCode;
|
||||
/**
|
||||
* 应答信息
|
||||
*/
|
||||
private String respMsg;
|
||||
/**
|
||||
* 签名公钥证书
|
||||
*/
|
||||
private String signPubKeyCert;
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
private String version;
|
||||
/**
|
||||
* 编码方式
|
||||
*/
|
||||
private String encoding;
|
||||
/**
|
||||
* 产品类型
|
||||
*/
|
||||
private String bizType;
|
||||
/**
|
||||
* 订单发送时间
|
||||
*/
|
||||
private String txnTime;
|
||||
|
||||
/**
|
||||
* 交易类型
|
||||
*/
|
||||
private String txnType;
|
||||
/**
|
||||
* 交易子类
|
||||
*/
|
||||
private String txnSubType;
|
||||
/**
|
||||
* 接入类型
|
||||
* 0:商户直连接入
|
||||
* 1:收单机构接入
|
||||
* 2:平台商户接入
|
||||
*/
|
||||
private String accessType;
|
||||
/**
|
||||
* 请求方保留域
|
||||
*/
|
||||
private String reqReserved;
|
||||
/**
|
||||
* 商户代码
|
||||
*/
|
||||
private String merId;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
private String orderId;
|
||||
/**
|
||||
* 保留域
|
||||
*/
|
||||
private String reserved;
|
||||
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态码
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
@Override
|
||||
public String getCode() {
|
||||
return respCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态提示信息
|
||||
*
|
||||
* @return 提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return respMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态码
|
||||
*
|
||||
* @return 业务结果状态码
|
||||
*/
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态提示信息
|
||||
*
|
||||
* @return 业务结果状态提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*
|
||||
* @return 退款金额
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款币种信息
|
||||
*
|
||||
* @return 币种信息
|
||||
*/
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付平台交易号
|
||||
* 发起支付时 支付平台(如支付宝)返回的交易订单号
|
||||
*
|
||||
* @return 支付平台交易号
|
||||
*/
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单号
|
||||
* 发起支付时,用户系统的订单号
|
||||
*
|
||||
* @return 支付订单号
|
||||
*/
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户退款单号
|
||||
*
|
||||
* @return 商户退款单号
|
||||
*/
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getQrCode() {
|
||||
return qrCode;
|
||||
}
|
||||
|
||||
public void setQrCode(String qrCode) {
|
||||
this.qrCode = qrCode;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public void setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public String getSignMethod() {
|
||||
return signMethod;
|
||||
}
|
||||
|
||||
public void setSignMethod(String signMethod) {
|
||||
this.signMethod = signMethod;
|
||||
}
|
||||
|
||||
public String getRespCode() {
|
||||
return respCode;
|
||||
}
|
||||
|
||||
public void setRespCode(String respCode) {
|
||||
this.respCode = respCode;
|
||||
}
|
||||
|
||||
public String getRespMsg() {
|
||||
return respMsg;
|
||||
}
|
||||
|
||||
public void setRespMsg(String respMsg) {
|
||||
this.respMsg = respMsg;
|
||||
}
|
||||
|
||||
public String getSignPubKeyCert() {
|
||||
return signPubKeyCert;
|
||||
}
|
||||
|
||||
public void setSignPubKeyCert(String signPubKeyCert) {
|
||||
this.signPubKeyCert = signPubKeyCert;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public String getBizType() {
|
||||
return bizType;
|
||||
}
|
||||
|
||||
public void setBizType(String bizType) {
|
||||
this.bizType = bizType;
|
||||
}
|
||||
|
||||
public String getTxnTime() {
|
||||
return txnTime;
|
||||
}
|
||||
|
||||
public void setTxnTime(String txnTime) {
|
||||
this.txnTime = txnTime;
|
||||
}
|
||||
|
||||
public String getTxnType() {
|
||||
return txnType;
|
||||
}
|
||||
|
||||
public void setTxnType(String txnType) {
|
||||
this.txnType = txnType;
|
||||
}
|
||||
|
||||
public String getTxnSubType() {
|
||||
return txnSubType;
|
||||
}
|
||||
|
||||
public void setTxnSubType(String txnSubType) {
|
||||
this.txnSubType = txnSubType;
|
||||
}
|
||||
|
||||
public String getAccessType() {
|
||||
return accessType;
|
||||
}
|
||||
|
||||
public void setAccessType(String accessType) {
|
||||
this.accessType = accessType;
|
||||
}
|
||||
|
||||
public String getReqReserved() {
|
||||
return reqReserved;
|
||||
}
|
||||
|
||||
public void setReqReserved(String reqReserved) {
|
||||
this.reqReserved = reqReserved;
|
||||
}
|
||||
|
||||
public String getMerId() {
|
||||
return merId;
|
||||
}
|
||||
|
||||
public void setMerId(String merId) {
|
||||
this.merId = merId;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public void setReserved(String reserved) {
|
||||
this.reserved = reserved;
|
||||
}
|
||||
|
||||
public static final UnionRefundResult create(Map<String, Object> result){
|
||||
UnionRefundResult refundResult = new JSONObject(result).toJavaObject(UnionRefundResult.class);
|
||||
refundResult.setAttrs(result);
|
||||
return refundResult;
|
||||
}
|
||||
}
|
||||
@@ -393,7 +393,7 @@ public class WxYouDianPayService extends BasePayService<WxYouDianPayConfigStorag
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public RefundResult refund(RefundOrder refundOrder) {
|
||||
String apbNonce = SignUtils.randomStr();
|
||||
TreeMap<String, String> data = new TreeMap<>();
|
||||
data.put("access_token", payConfigStorage.getAccessToken());
|
||||
@@ -408,8 +408,53 @@ public class WxYouDianPayService extends BasePayService<WxYouDianPayConfigStorag
|
||||
data.put("refund_fee", refundOrder.getRefundAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString());
|
||||
String sign = createSign(SignUtils.parameterText(data, "") + apbNonce, payConfigStorage.getInputCharset());
|
||||
String queryParam = SignUtils.parameterText(data) + "&apb_nonce=" + apbNonce + "&sign=" + sign;
|
||||
JSONObject jsonObject = execute(getReqUrl(YoudianTransactionType.NATIVE_STATUS) + "?" + queryParam, MethodType.GET, null);
|
||||
return jsonObject;
|
||||
JSONObject jsonObject = execute(getReqUrl(YoudianTransactionType.REFUND) + "?" + queryParam, MethodType.GET, null);
|
||||
return new BaseRefundResult() {
|
||||
@Override
|
||||
public String getCode() {
|
||||
return getAttrString("errorcode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return getAttrString("msg");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
RefundOrder order = new RefundOrder("微信单号", "我方系统单号", "退款金额", "订单总金额");
|
||||
//可用于多次退款
|
||||
order.setRefundNo("退款单号")
|
||||
Map result = service.refund(order);
|
||||
WxRefundResult result = service.refund(order);
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -488,7 +488,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> implements
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public WxRefundResult refund(RefundOrder refundOrder) {
|
||||
//获取公共参数
|
||||
Map<String, Object> parameters = getPublicParameters();
|
||||
|
||||
@@ -506,7 +506,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> implements
|
||||
parameters.putAll(refundOrder.getAttrs());
|
||||
//设置签名
|
||||
setSign(parameters);
|
||||
return requestTemplate.postForObject(getReqUrl(WxTransactionType.REFUND), XML.getMap2Xml(parameters), JSONObject.class);
|
||||
return WxRefundResult.create(requestTemplate.postForObject(getReqUrl(WxTransactionType.REFUND), XML.getMap2Xml(parameters), JSONObject.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,496 @@
|
||||
package com.egzosn.pay.wx.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.egzosn.pay.common.bean.BaseRefundResult;
|
||||
import com.egzosn.pay.common.bean.CurType;
|
||||
|
||||
/**
|
||||
* 微信退款结果
|
||||
* @author Egan
|
||||
* <pre></pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2020/8/16 21:29
|
||||
*/
|
||||
public class WxRefundResult extends BaseRefundResult {
|
||||
|
||||
/**
|
||||
* 返回状态码
|
||||
* SUCCESS/FAIL
|
||||
* 此字段是通信标识,表示接口层的请求结果,并非退款状态。
|
||||
*/
|
||||
@JSONField(name = "return_code")
|
||||
private String returnCode;
|
||||
/**
|
||||
* 返回信息
|
||||
* 当return_code为FAIL时返回信息为错误原因 ,例如
|
||||
* 签名失败
|
||||
* 参数格式校验错误
|
||||
*/
|
||||
@JSONField(name = "return_msg")
|
||||
private String returnMsg;
|
||||
/**
|
||||
* 业务结果
|
||||
* SUCCESS/FAIL
|
||||
* SUCCESS退款申请接收成功,结果通过退款查询接口查询
|
||||
* FAIL 提交业务失败
|
||||
*/
|
||||
@JSONField(name = "result_code")
|
||||
private String resultCode;
|
||||
/**
|
||||
* 错误代码
|
||||
* 名称 描述 原因 解决方案
|
||||
* SYSTEMERROR 接口返回错误 系统超时等 请不要更换商户退款单号,请使用相同参数再次调用API。
|
||||
* BIZERR_NEED_RETRY 退款业务流程错误,需要商户触发重试来解决 并发情况下,业务被拒绝,商户重试即可解决 请不要更换商户退款单号,请使用相同参数再次调用API。
|
||||
* TRADE_OVERDUE 订单已经超过退款期限 订单已经超过可退款的最大期限(支付后一年内可退款) 请选择其他方式自行退款
|
||||
* ERROR 业务错误 申请退款业务发生错误 该错误都会返回具体的错误原因,请根据实际返回做相应处理。
|
||||
* USER_ACCOUNT_ABNORMAL 退款请求失败 用户帐号注销 此状态代表退款申请失败,商户可自行处理退款。
|
||||
* INVALID_REQ_TOO_MUCH 无效请求过多 连续错误请求数过多被系统短暂屏蔽 请检查业务是否正常,确认业务正常后请在1分钟后再来重试
|
||||
* NOTENOUGH 余额不足 商户可用退款余额不足 此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。
|
||||
* INVALID_TRANSACTIONID 无效transaction_id 请求参数未按指引进行填写 请求参数错误,检查原交易号是否存在或发起支付交易接口返回失败
|
||||
* PARAM_ERROR 参数错误 请求参数未按指引进行填写 请求参数错误,请重新检查再调用退款申请
|
||||
* APPID_NOT_EXIST APPID不存在 参数中缺少APPID 请检查APPID是否正确
|
||||
* MCHID_NOT_EXIST MCHID不存在 参数中缺少MCHID 请检查MCHID是否正确
|
||||
* ORDERNOTEXIST 订单号不存在 缺少有效的订单号 请检查你的订单号是否正确且是否已支付,未支付的订单不能发起退款
|
||||
* REQUIRE_POST_METHOD 请使用post方法 未使用post传递参数 请检查请求参数是否通过post方法提交
|
||||
* SIGNERROR 签名错误 参数签名结果不正确 请检查签名参数和方法是否都符合签名算法要求
|
||||
* XML_FORMAT_ERROR XML格式错误 XML格式错误 请检查XML参数格式是否正确
|
||||
* FREQUENCY_LIMITED 频率限制 2个月之前的订单申请退款有频率限制 该笔退款未受理,请降低频率后重试
|
||||
* NOAUTH 异常IP请求不予受理 请求ip异常 如果是动态ip,请登录商户平台后台关闭ip安全配置;
|
||||
* 如果是静态ip,请确认商户平台配置的请求ip 在不在配的ip列表里
|
||||
* CERT_ERROR 证书校验错误 请检查证书是否正确,证书是否过期或作废。 请检查证书是否正确,证书是否过期或作废。
|
||||
* REFUND_FEE_MISMATCH 订单金额或退款金额与之前请求不一致,请核实后再试 订单金额或退款金额与之前请求不一致,请核实后再试 订单金额或退款金额与之前请求不一致,请核实后再试
|
||||
* INVALID_REQUEST 请求参数符合参数格式,但不符合业务规则 此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。 此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。
|
||||
*/
|
||||
@JSONField(name = "err_code")
|
||||
private String errCode;
|
||||
/**
|
||||
* 错误代码描述
|
||||
*/
|
||||
@JSONField(name = "err_code_des")
|
||||
private String errCodeDes;
|
||||
/**
|
||||
* 应用id
|
||||
* 公众账号ID
|
||||
* 微信分配的公众账号ID
|
||||
*/
|
||||
@JSONField(name = "appid")
|
||||
private String appid;
|
||||
/**
|
||||
* 商户号
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
@JSONField(name = "mch_id")
|
||||
private String mchId;
|
||||
/**
|
||||
* 随机字符串,不长于32位
|
||||
*/
|
||||
@JSONField(name = "nonce_str")
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 签名
|
||||
*/
|
||||
@JSONField(name = "sign")
|
||||
private String sign;
|
||||
/**
|
||||
* 微信订单号
|
||||
*/
|
||||
@JSONField(name = "transaction_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 商户退款单号
|
||||
*/
|
||||
@JSONField(name = "out_refund_no")
|
||||
private String outRefundNo;
|
||||
/**
|
||||
* 微信退款单号
|
||||
*/
|
||||
@JSONField(name = "refund_id")
|
||||
private String refundId;
|
||||
/**
|
||||
* 退款金额
|
||||
* 退款总金额,单位为分,可以做部分退款
|
||||
*/
|
||||
@JSONField(name = "refund_fee")
|
||||
private BigDecimal refundFee;
|
||||
/**
|
||||
* 应结退款金额
|
||||
* 去掉非充值代金券退款金额后的退款金额,退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额
|
||||
*/
|
||||
@JSONField(name = "settlement_refund_fee")
|
||||
private BigDecimal settlementRefundFee;
|
||||
/**
|
||||
* 标价金额
|
||||
* 订单总金额,单位为分,只能为整数,详见支付金额
|
||||
*/
|
||||
@JSONField(name = "total_fee")
|
||||
private BigDecimal totalFee;
|
||||
/**
|
||||
* 应结订单金额
|
||||
* 去掉非充值代金券金额后的订单总金额,应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
|
||||
*/
|
||||
@JSONField(name = "settlement_total_fee")
|
||||
private BigDecimal settlementTotalFee;
|
||||
/**
|
||||
* 标价币种
|
||||
* 订单金额货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
|
||||
*/
|
||||
@JSONField(name = "fee_type")
|
||||
private CurType feeType;
|
||||
/**
|
||||
* 现金支付金额
|
||||
* 现金支付金额,单位为分,只能为整数,详见支付金额
|
||||
*/
|
||||
@JSONField(name = "cash_fee")
|
||||
private BigDecimal cashFee;
|
||||
/**
|
||||
* 现金支付币种
|
||||
* 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
|
||||
*/
|
||||
@JSONField(name = "cash_fee_type")
|
||||
private CurType cashFeeType;
|
||||
/**
|
||||
* 现金退款金额
|
||||
* 现金退款金额,单位为分,只能为整数,详见支付金额
|
||||
*/
|
||||
@JSONField(name = "cash_refund_fee")
|
||||
private BigDecimal cashRefundFee;
|
||||
/**
|
||||
* 代金券类型
|
||||
* CASH--充值代金券
|
||||
*
|
||||
* NO_CASH---非充值代金券
|
||||
*
|
||||
* 订单使用代金券时有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_0
|
||||
* 这里只接收0的,其余请自行获取
|
||||
*/
|
||||
@JSONField(name = "coupon_type_0")
|
||||
private String couponType0;
|
||||
/**
|
||||
* 代金券退款总金额
|
||||
* 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
|
||||
*/
|
||||
@JSONField(name = "coupon_refund_fee")
|
||||
private BigDecimal couponRefundFee;
|
||||
/**
|
||||
* 单个代金券退款金额
|
||||
* 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
|
||||
* 这里只接收0的,其余请自行获取
|
||||
*/
|
||||
@JSONField(name = "coupon_refund_fee_0")
|
||||
private BigDecimal couponRefundFee0;
|
||||
@JSONField(name = "coupon_refund_count")
|
||||
/**
|
||||
* 退款代金券使用数量
|
||||
* 退款代金券使用数量
|
||||
*/
|
||||
private Integer couponRefundCount;
|
||||
/**
|
||||
* 退款代金券ID, $n为下标,从0开始编号
|
||||
* 这里只接收0的,其余请自行获取
|
||||
*/
|
||||
@JSONField(name = "coupon_refund_id_0")
|
||||
private Integer couponRefundId0;
|
||||
/**
|
||||
* 获取退款请求结果状态码
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
@Override
|
||||
public String getCode() {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款请求结果状态提示信息
|
||||
*
|
||||
* @return 提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return returnMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态码
|
||||
*
|
||||
* @return 业务结果状态码
|
||||
*/
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回业务结果状态提示信息
|
||||
*
|
||||
* @return 业务结果状态提示信息
|
||||
*/
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return errCodeDes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*
|
||||
* @return 退款金额
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return refundFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款币种信息
|
||||
*
|
||||
* @return 币种信息
|
||||
*/
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return feeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付平台交易号
|
||||
* 发起支付时 支付平台(如支付宝)返回的交易订单号
|
||||
*
|
||||
* @return 支付平台交易号
|
||||
*/
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单号
|
||||
* 发起支付时,用户系统的订单号
|
||||
*
|
||||
* @return 支付订单号
|
||||
*/
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户退款单号
|
||||
*
|
||||
* @return 商户退款单号
|
||||
*/
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return outRefundNo;
|
||||
}
|
||||
|
||||
public String getReturnCode() {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
public void setReturnCode(String returnCode) {
|
||||
this.returnCode = returnCode;
|
||||
}
|
||||
|
||||
public String getReturnMsg() {
|
||||
return returnMsg;
|
||||
}
|
||||
|
||||
public void setReturnMsg(String returnMsg) {
|
||||
this.returnMsg = returnMsg;
|
||||
}
|
||||
|
||||
public void setResultCode(String resultCode) {
|
||||
this.resultCode = resultCode;
|
||||
}
|
||||
|
||||
public String getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
public void setErrCode(String errCode) {
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
public String getErrCodeDes() {
|
||||
return errCodeDes;
|
||||
}
|
||||
|
||||
public void setErrCodeDes(String errCodeDes) {
|
||||
this.errCodeDes = errCodeDes;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public String getOutRefundNo() {
|
||||
return outRefundNo;
|
||||
}
|
||||
|
||||
public void setOutRefundNo(String outRefundNo) {
|
||||
this.outRefundNo = outRefundNo;
|
||||
}
|
||||
|
||||
public String getRefundId() {
|
||||
return refundId;
|
||||
}
|
||||
|
||||
public void setRefundId(String refundId) {
|
||||
this.refundId = refundId;
|
||||
}
|
||||
|
||||
public void setRefundFee(BigDecimal refundFee) {
|
||||
this.refundFee = refundFee;
|
||||
}
|
||||
|
||||
public BigDecimal getSettlementRefundFee() {
|
||||
return settlementRefundFee;
|
||||
}
|
||||
|
||||
public void setSettlementRefundFee(BigDecimal settlementRefundFee) {
|
||||
this.settlementRefundFee = settlementRefundFee;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
public void setTotalFee(BigDecimal totalFee) {
|
||||
this.totalFee = totalFee;
|
||||
}
|
||||
|
||||
public BigDecimal getSettlementTotalFee() {
|
||||
return settlementTotalFee;
|
||||
}
|
||||
|
||||
public void setSettlementTotalFee(BigDecimal settlementTotalFee) {
|
||||
this.settlementTotalFee = settlementTotalFee;
|
||||
}
|
||||
|
||||
public CurType getFeeType() {
|
||||
return feeType;
|
||||
}
|
||||
|
||||
public void setFeeType(CurType feeType) {
|
||||
this.feeType = feeType;
|
||||
}
|
||||
|
||||
public BigDecimal getCashFee() {
|
||||
return cashFee;
|
||||
}
|
||||
|
||||
public void setCashFee(BigDecimal cashFee) {
|
||||
this.cashFee = cashFee;
|
||||
}
|
||||
|
||||
public CurType getCashFeeType() {
|
||||
return cashFeeType;
|
||||
}
|
||||
|
||||
public void setCashFeeType(CurType cashFeeType) {
|
||||
this.cashFeeType = cashFeeType;
|
||||
}
|
||||
|
||||
public BigDecimal getCashRefundFee() {
|
||||
return cashRefundFee;
|
||||
}
|
||||
|
||||
public void setCashRefundFee(BigDecimal cashRefundFee) {
|
||||
this.cashRefundFee = cashRefundFee;
|
||||
}
|
||||
|
||||
public String getCouponType0() {
|
||||
return couponType0;
|
||||
}
|
||||
|
||||
public void setCouponType0(String couponType0) {
|
||||
this.couponType0 = couponType0;
|
||||
}
|
||||
|
||||
public BigDecimal getCouponRefundFee() {
|
||||
return couponRefundFee;
|
||||
}
|
||||
|
||||
public void setCouponRefundFee(BigDecimal couponRefundFee) {
|
||||
this.couponRefundFee = couponRefundFee;
|
||||
}
|
||||
|
||||
public BigDecimal getCouponRefundFee0() {
|
||||
return couponRefundFee0;
|
||||
}
|
||||
|
||||
public void setCouponRefundFee0(BigDecimal couponRefundFee0) {
|
||||
this.couponRefundFee0 = couponRefundFee0;
|
||||
}
|
||||
|
||||
public Integer getCouponRefundCount() {
|
||||
return couponRefundCount;
|
||||
}
|
||||
|
||||
public void setCouponRefundCount(Integer couponRefundCount) {
|
||||
this.couponRefundCount = couponRefundCount;
|
||||
}
|
||||
|
||||
public Integer getCouponRefundId0() {
|
||||
return couponRefundId0;
|
||||
}
|
||||
|
||||
public void setCouponRefundId0(Integer couponRefundId0) {
|
||||
this.couponRefundId0 = couponRefundId0;
|
||||
}
|
||||
|
||||
|
||||
public static final WxRefundResult create(Map<String, Object> result){
|
||||
WxRefundResult refundResult = new JSONObject(result).toJavaObject(WxRefundResult.class);
|
||||
refundResult.setAttrs(result);
|
||||
return refundResult;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ 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.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
@@ -300,7 +301,7 @@ public class YiJiPayService extends BasePayService<YiJiPayConfigStorage> {
|
||||
* @return 返回支付方申请退款后的结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> refund(RefundOrder refundOrder) {
|
||||
public RefundResult refund(RefundOrder refundOrder) {
|
||||
Map<String, Object> orderInfo = getPublicParameters(YiJiTransactionType.tradeRefund);
|
||||
orderInfo.put("orderNo", refundOrder.getOutTradeNo());
|
||||
orderInfo.put("outOrderNo", refundOrder.getOutTradeNo());
|
||||
@@ -308,7 +309,52 @@ public class YiJiPayService extends BasePayService<YiJiPayConfigStorage> {
|
||||
orderInfo.put("refundTime", DateUtils.formatDay(refundOrder.getOrderDate()));
|
||||
orderInfo.put("refundReason", refundOrder.getDescription());
|
||||
setSign(orderInfo);
|
||||
return getHttpRequestTemplate().postForObject(getReqUrl(YiJiTransactionType.tradeRefund), orderInfo, JSONObject.class);
|
||||
return new BaseRefundResult(getHttpRequestTemplate().postForObject(getReqUrl(YiJiTransactionType.tradeRefund), orderInfo, JSONObject.class)) {
|
||||
@Override
|
||||
public String getCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultMsg() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getRefundFee() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurType getRefundCurrency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutTradeNo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefundNo() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
5
pom.xml
5
pom.xml
@@ -67,7 +67,7 @@
|
||||
<pay.version>2.13.3-SNAPSHOT</pay.version>
|
||||
<httpmime.version>4.5.4</httpmime.version>
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<fastjson.version>1.2.58</fastjson.version>
|
||||
<fastjson.version>1.2.73</fastjson.version>
|
||||
<zxing.version>3.3.1</zxing.version>
|
||||
<junit.version>5.5.1</junit.version>
|
||||
</properties>
|
||||
@@ -92,10 +92,11 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
<version>1.2.73</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- log4j -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
|
||||
Reference in New Issue
Block a user