@@ -0,0 +1,61 @@ | |||
package com.github.binarywang.wxpay.bean.result; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
/** | |||
* <pre> | |||
* 退款代金券信息. | |||
* Created by BinaryWang on 2018/4/21. | |||
* </pre> | |||
* | |||
* @author Binary Wang | |||
*/ | |||
@Data | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
public class WxPayRefundCouponInfo { | |||
/** | |||
* <pre> | |||
* 字段名:退款代金券ID. | |||
* 变量名:coupon_refund_id_$n_$m | |||
* 是否必填:否 | |||
* 类型:String(20) | |||
* 示例值:10000 | |||
* 描述:退款代金券ID, $n为下标,$m为下标,从0开始编号 | |||
* </pre> | |||
*/ | |||
@XStreamAlias("coupon_refund_id") | |||
private String couponRefundId; | |||
/** | |||
* <pre> | |||
* 字段名:单个退款代金券支付金额. | |||
* 变量名:coupon_refund_fee_$n_$m | |||
* 是否必填:否 | |||
* 类型:Int | |||
* 示例值:100 | |||
* 描述:单个退款代金券支付金额, $n为下标,$m为下标,从0开始编号 | |||
* </pre> | |||
*/ | |||
@XStreamAlias("coupon_refund_fee") | |||
private Integer couponRefundFee; | |||
/** | |||
* <pre> | |||
* 字段名:代金券类型. | |||
* 变量名:coupon_type_$n_$m | |||
* 是否必填:否 | |||
* 类型:String(8) | |||
* 示例值:CASH | |||
* 描述:CASH--充值代金券 , NO_CASH---非充值代金券。 | |||
* 开通免充值券功能,并且订单使用了优惠券后有返回(取值:CASH、NO_CASH)。 | |||
* $n为下标,$m为下标,从0开始编号,举例:coupon_type_$0_$1 | |||
* </pre> | |||
*/ | |||
@XStreamAlias("coupon_type") | |||
private String couponType; | |||
} |
@@ -151,10 +151,10 @@ public class WxPayRefundQueryResult extends BaseWxPayResult { | |||
continue; | |||
} | |||
List<RefundRecord.RefundCoupon> coupons = Lists.newArrayList(); | |||
List<WxPayRefundCouponInfo> coupons = Lists.newArrayList(); | |||
for (int j = 0; j < refundRecord.getCouponRefundCount(); j++) { | |||
coupons.add( | |||
new RefundRecord.RefundCoupon( | |||
new WxPayRefundCouponInfo( | |||
this.getXmlValue("xml/coupon_refund_id_" + i + "_" + j), | |||
this.getXmlValueAsInt("xml/coupon_refund_fee_" + i + "_" + j), | |||
this.getXmlValue("xml/coupon_type_" + i + "_" + j) | |||
@@ -277,7 +277,7 @@ public class WxPayRefundQueryResult extends BaseWxPayResult { | |||
@XStreamAlias("coupon_refund_count") | |||
private Integer couponRefundCount; | |||
private List<RefundCoupon> refundCoupons; | |||
private List<WxPayRefundCouponInfo> refundCoupons; | |||
/** | |||
* <pre> | |||
@@ -323,54 +323,6 @@ public class WxPayRefundQueryResult extends BaseWxPayResult { | |||
@XStreamAlias("refund_success_time") | |||
private String refundSuccessTime; | |||
@Data | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
public static class RefundCoupon { | |||
/** | |||
* <pre> | |||
* 字段名:退款代金券ID. | |||
* 变量名:coupon_refund_id_$n_$m | |||
* 是否必填:否 | |||
* 类型:String(20) | |||
* 示例值:10000 | |||
* 描述:退款代金券ID, $n为下标,$m为下标,从0开始编号 | |||
* </pre> | |||
*/ | |||
@XStreamAlias("coupon_refund_id") | |||
private String couponRefundId; | |||
/** | |||
* <pre> | |||
* 字段名:单个退款代金券支付金额. | |||
* 变量名:coupon_refund_fee_$n_$m | |||
* 是否必填:否 | |||
* 类型:Int | |||
* 示例值:100 | |||
* 描述:单个退款代金券支付金额, $n为下标,$m为下标,从0开始编号 | |||
* </pre> | |||
*/ | |||
@XStreamAlias("coupon_refund_fee") | |||
private Integer couponRefundFee; | |||
/** | |||
* <pre> | |||
* 字段名:代金券类型. | |||
* 变量名:coupon_type_$n_$m | |||
* 是否必填:否 | |||
* 类型:String(8) | |||
* 示例值:CASH | |||
* 描述:CASH--充值代金券 , NO_CASH---非充值代金券。 | |||
* 开通免充值券功能,并且订单使用了优惠券后有返回(取值:CASH、NO_CASH)。 | |||
* $n为下标,$m为下标,从0开始编号,举例:coupon_type_$0_$1 | |||
* </pre> | |||
*/ | |||
@XStreamAlias("coupon_type") | |||
private String couponType; | |||
} | |||
} | |||
} | |||
@@ -1,67 +1,122 @@ | |||
package com.github.binarywang.wxpay.bean.result; | |||
import com.google.common.collect.Lists; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import lombok.Data; | |||
import lombok.EqualsAndHashCode; | |||
import lombok.NoArgsConstructor; | |||
import java.io.Serializable; | |||
import java.util.List; | |||
/** | |||
* <pre> | |||
* 微信支付-申请退款返回结果 | |||
* 微信支付-申请退款返回结果. | |||
* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 | |||
* </pre> | |||
* | |||
* @author liukaitj | |||
* @author liukaitj & Binary Wang | |||
*/ | |||
@Data | |||
@EqualsAndHashCode(callSuper = true) | |||
@NoArgsConstructor | |||
@XStreamAlias("xml") | |||
public class WxPayRefundResult extends BaseWxPayResult implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
@XStreamAlias("device_info") | |||
private String deviceInfo; | |||
private static final long serialVersionUID = -3392333879907788033L; | |||
/** | |||
* 微信订单号. | |||
*/ | |||
@XStreamAlias("transaction_id") | |||
private String transactionId; | |||
/** | |||
* 商户订单号. | |||
*/ | |||
@XStreamAlias("out_trade_no") | |||
private String outTradeNo; | |||
/** | |||
* 商户退款单号. | |||
*/ | |||
@XStreamAlias("out_refund_no") | |||
private String outRefundNo; | |||
/** | |||
* 微信退款单号. | |||
*/ | |||
@XStreamAlias("refund_id") | |||
private String refundId; | |||
@XStreamAlias("refund_channel") | |||
private String refundChannel; | |||
/** | |||
* 退款金额. | |||
*/ | |||
@XStreamAlias("refund_fee") | |||
private String refundFee; | |||
private Integer refundFee; | |||
/** | |||
* 应结退款金额. | |||
*/ | |||
@XStreamAlias("settlement_refund_fee") | |||
private Integer settlementRefundFee; | |||
/** | |||
* 标价金额. | |||
*/ | |||
@XStreamAlias("total_fee") | |||
private String totalFee; | |||
private Integer totalFee; | |||
/** | |||
* 应结订单金额. | |||
*/ | |||
@XStreamAlias("settlement_total_fee") | |||
private Integer settlementTotalFee; | |||
/** | |||
* 标价币种. | |||
*/ | |||
@XStreamAlias("fee_type") | |||
private String feeType; | |||
/** | |||
* 现金支付金额. | |||
*/ | |||
@XStreamAlias("cash_fee") | |||
private String cashFee; | |||
private Integer cashFee; | |||
/** | |||
* 现金支付币种. | |||
*/ | |||
@XStreamAlias("cash_fee_type") | |||
private String cashFeeType; | |||
/** | |||
* 现金退款金额. | |||
*/ | |||
@XStreamAlias("cash_refund_fee") | |||
private String cashRefundFee; | |||
@XStreamAlias("coupon_refund_fee") | |||
private String couponRefundFee; | |||
/** | |||
* 退款代金券使用数量. | |||
*/ | |||
@XStreamAlias("coupon_refund_count") | |||
private String couponRefundCount; | |||
@XStreamAlias("coupon_refund_id") | |||
private String couponRefundId; | |||
private Integer couponRefundCount; | |||
private List<WxPayRefundCouponInfo> refundCoupons; | |||
/** | |||
* 组装生成退款代金券信息. | |||
*/ | |||
public void composeRefundCoupons() { | |||
List<WxPayRefundCouponInfo> coupons = Lists.newArrayList(); | |||
for (int i = 0; i < this.getCouponRefundCount(); i++) { | |||
coupons.add( | |||
new WxPayRefundCouponInfo( | |||
this.getXmlValue("xml/coupon_refund_id_" + i), | |||
this.getXmlValueAsInt("xml/coupon_refund_fee_" + i), | |||
this.getXmlValue("xml/coupon_type_" + i) | |||
) | |||
); | |||
} | |||
this.setRefundCoupons(coupons); | |||
} | |||
} |
@@ -131,6 +131,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||
String url = this.getPayBaseUrl() + "/secapi/pay/refund"; | |||
String responseContent = this.post(url, request.toXML(), true); | |||
WxPayRefundResult result = BaseWxPayResult.fromXML(responseContent, WxPayRefundResult.class); | |||
result.composeRefundCoupons(); | |||
result.checkResult(this, request.getSignType(), true); | |||
return result; | |||
} | |||
@@ -0,0 +1,51 @@ | |||
package com.github.binarywang.wxpay.bean.result; | |||
import org.testng.annotations.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
/** | |||
* <pre> | |||
* Created by BinaryWang on 2018/4/22. | |||
* </pre> | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class WxPayRefundResultTest { | |||
@Test | |||
public void testComposeRefundCoupons() { | |||
/* | |||
该xml字符串来自于官方文档示例,稍加改造,加上代金卷 | |||
refund_channel 是个什么鬼,官方文档只字不提 | |||
*/ | |||
String xmlString = "<xml>\n" + | |||
" <return_code><![CDATA[SUCCESS]]></return_code>\n" + | |||
" <return_msg><![CDATA[OK]]></return_msg>\n" + | |||
" <appid><![CDATA[wx2421b1c4370ec43b]]></appid>\n" + | |||
" <mch_id><![CDATA[10000100]]></mch_id>\n" + | |||
" <nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>\n" + | |||
" <sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>\n" + | |||
" <result_code><![CDATA[SUCCESS]]></result_code>\n" + | |||
" <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>\n" + | |||
" <out_trade_no><![CDATA[1415757673]]></out_trade_no>\n" + | |||
" <out_refund_no><![CDATA[1415701182]]></out_refund_no>\n" + | |||
" <refund_id><![CDATA[2008450740201411110000174436]]></refund_id>\n" + | |||
" <refund_channel><![CDATA[]]></refund_channel>\n" + | |||
" <coupon_refund_fee>1</coupon_refund_fee>\n" + | |||
" <coupon_refund_count>1</coupon_refund_count>\n" + | |||
" <coupon_refund_id_0>123</coupon_refund_id_0>\n" + | |||
" <coupon_refund_fee_0>1</coupon_refund_fee_0>\n" + | |||
" <coupon_type_0><![CDATA[CASH]]></coupon_type_0>\n" + | |||
" <refund_fee>2</refund_fee> \n" + | |||
"</xml>"; | |||
WxPayRefundResult result = WxPayRefundResult.fromXML(xmlString, WxPayRefundResult.class); | |||
result.composeRefundCoupons(); | |||
assertThat(result.getRefundCoupons()).isNotEmpty(); | |||
assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123"); | |||
assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH"); | |||
assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1); | |||
} | |||
} |