diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java index 88450403e..508bf9745 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java @@ -1,5 +1,6 @@ package cn.binarywang.wx.miniapp.bean; +import cn.binarywang.wx.miniapp.bean.xpay.WxMaXPayTeamInfo; import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; @@ -313,6 +314,110 @@ public class WxMaMessage implements Serializable { @XStreamAlias("settlement_time") private Long settlementTime; + // xpay_refund_notify 退款推送字段 + + /** + * 微信退款单号. + * xpay_refund_notify + */ + @SerializedName("WxRefundId") + @XStreamAlias("WxRefundId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String wxRefundId; + + /** + * 商户退款单号. + * xpay_refund_notify + */ + @SerializedName("MchRefundId") + @XStreamAlias("MchRefundId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mchRefundId; + + /** + * 退款单对应支付单的微信单号. + * xpay_refund_notify + */ + @SerializedName("WxOrderId") + @XStreamAlias("WxOrderId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String wxOrderId; + + /** + * 退款单对应支付单的商户单号. + * xpay_refund_notify + */ + @SerializedName("MchOrderId") + @XStreamAlias("MchOrderId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mchOrderId; + + /** + * 退款金额,单位分. + * xpay_refund_notify + */ + @SerializedName("RefundFee") + @XStreamAlias("RefundFee") + private Integer refundFee; + + /** + * 退款结果,0为成功,非0为失败. + * xpay_refund_notify + */ + @SerializedName("RetCode") + @XStreamAlias("RetCode") + private Integer retCode; + + /** + * 退款结果详情,失败时为退款失败的原因. + * xpay_refund_notify + */ + @SerializedName("RetMsg") + @XStreamAlias("RetMsg") + @XStreamConverter(value = XStreamCDataConverter.class) + private String retMsg; + + /** + * 开始退款时间,秒级时间戳. + * xpay_refund_notify + */ + @SerializedName("RefundStartTimestamp") + @XStreamAlias("RefundStartTimestamp") + private Long refundStartTimestamp; + + /** + * 结束退款时间,秒级时间戳. + * xpay_refund_notify + */ + @SerializedName("RefundSuccTimestamp") + @XStreamAlias("RefundSuccTimestamp") + private Long refundSuccTimestamp; + + /** + * 退款单的微信支付单号. + * xpay_refund_notify + */ + @SerializedName("WxpayRefundTransactionId") + @XStreamAlias("WxpayRefundTransactionId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String wxpayRefundTransactionId; + + /** + * 重试次数,从0开始,重试间隔为2 4 8 16...最多15次. + * xpay_refund_notify + */ + @SerializedName("RetryTimes") + @XStreamAlias("RetryTimes") + private Integer retryTimes; + + /** + * 拼团信息. + * xpay_goods_deliver_notify, xpay_refund_notify + */ + @SerializedName("TeamInfo") + @XStreamAlias("TeamInfo") + private WxMaXPayTeamInfo teamInfo; + /** * 不要直接使用这个字段, * 这个字段只是为了适配 SubscribeMsgPopupEvent SubscribeMsgChangeEvent SubscribeMsgSentEvent diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/xpay/WxMaXPayTeamInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/xpay/WxMaXPayTeamInfo.java new file mode 100644 index 000000000..cadf98809 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/xpay/WxMaXPayTeamInfo.java @@ -0,0 +1,48 @@ +package cn.binarywang.wx.miniapp.bean.xpay; + +import com.google.gson.annotations.SerializedName; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 虚拟支付拼团信息. + * 用于 xpay_goods_deliver_notify、xpay_refund_notify 等推送事件 + */ +@Data +@NoArgsConstructor +@XStreamAlias("TeamInfo") +public class WxMaXPayTeamInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 活动id. + */ + @SerializedName("ActivityId") + @XStreamAlias("ActivityId") + private String activityId; + + /** + * 团id. + */ + @SerializedName("TeamId") + @XStreamAlias("TeamId") + private String teamId; + + /** + * 团类型. + * 1-支付全部,拼成退款 + */ + @SerializedName("TeamType") + @XStreamAlias("TeamType") + private Integer teamType; + + /** + * 0-创团 1-参团. + */ + @SerializedName("TeamAction") + @XStreamAlias("TeamAction") + private Integer teamAction; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java index 488481c01..eed700631 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java @@ -263,6 +263,7 @@ public static final class XPayOrderStatus { public static final class XPayNotifyEvent { public static String COIN_PAY = "xpay_coin_pay_notify"; public static String GOODS_DELIVER = "xpay_goods_deliver_notify"; + public static String REFUND = "xpay_refund_notify"; } @UtilityClass diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java index bfdb912f6..00821eb63 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java @@ -1,5 +1,6 @@ package cn.binarywang.wx.miniapp.bean; +import cn.binarywang.wx.miniapp.bean.xpay.WxMaXPayTeamInfo; import me.chanjar.weixin.common.api.WxConsts; import org.testng.annotations.Test; @@ -294,38 +295,97 @@ public void testFromXmlForAllFieldsMap() { } /** - * 自定义交易组件付款通知事件测试用例 - * msgType等于event且event等于WxConsts.EventType.OPEN_PRODUCT_ORDER_PAY + * 虚拟支付退款推送事件 xpay_refund_notify 测试用例(XML格式,含TeamInfo) */ @Test - public void testFromXmlForOpenProductOrderPayEvent(){ - String xml = " \n" + - " gh_abcdefg \n" + - " oABCD \n" + - " 1642658087 \n" + - " event \n" + - " open_product_order_pay\n" + - " \n" + - " 123456\n" + - " 1234567\n" + - " 42000000123123\n" + - " 2021-12-30 22:31:00\n" + - " 10\n" + - " oNMZ-5C0SPGHUiKsTwnOXpSHzFvw\n" + - " \n" + + public void testXPayRefundNotifyFromXml() { + String xml = "\n" + + " \n" + + " \n" + + " 1700000000\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 100\n" + + " 0\n" + + " \n" + + " 1700000000\n" + + " 1700000010\n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 0\n" + + " \n" + ""; - WxMaMessage wxMessage = WxMaMessage.fromXml(xml); - assertThat(wxMessage.getMsgType()).isEqualTo("event"); - assertThat(wxMessage.getEvent()).isEqualTo(WxConsts.EventType.OPEN_PRODUCT_ORDER_PAY); - Map allFieldsMap = wxMessage.getAllFieldsMap(); - Map orderInfo = (Map) allFieldsMap.get("order_info"); - assertThat(orderInfo).isNotEmpty(); - assertThat(orderInfo) - .containsEntry("out_order_id","123456") - .containsEntry("order_id","1234567") - .containsEntry("transaction_id","42000000123123") - .containsEntry("pay_time","2021-12-30 22:31:00") - .containsEntry("amount","10") - .containsEntry("sp_openid","oNMZ-5C0SPGHUiKsTwnOXpSHzFvw"); + + WxMaMessage msg = WxMaMessage.fromXml(xml); + checkXPayRefundNotifyMessage(msg); + } + + /** + * 虚拟支付退款推送事件 xpay_refund_notify 测试用例(JSON格式,含TeamInfo) + */ + @Test + public void testXPayRefundNotifyFromJson() { + String json = "{\n" + + " \"ToUserName\": \"gh_abcdefg\",\n" + + " \"FromUserName\": \"oABCDEFG\",\n" + + " \"CreateTime\": 1700000000,\n" + + " \"MsgType\": \"event\",\n" + + " \"Event\": \"xpay_refund_notify\",\n" + + " \"OpenId\": \"oABCDEFG\",\n" + + " \"WxRefundId\": \"wx_refund_123\",\n" + + " \"MchRefundId\": \"mch_refund_456\",\n" + + " \"WxOrderId\": \"wx_order_789\",\n" + + " \"MchOrderId\": \"mch_order_101\",\n" + + " \"RefundFee\": 100,\n" + + " \"RetCode\": 0,\n" + + " \"RetMsg\": \"success\",\n" + + " \"RefundStartTimestamp\": 1700000000,\n" + + " \"RefundSuccTimestamp\": 1700000010,\n" + + " \"WxpayRefundTransactionId\": \"wxpay_refund_tx_202\",\n" + + " \"RetryTimes\": 0,\n" + + " \"TeamInfo\": {\n" + + " \"ActivityId\": \"act_001\",\n" + + " \"TeamId\": \"team_002\",\n" + + " \"TeamType\": 1,\n" + + " \"TeamAction\": 0\n" + + " }\n" + + "}"; + + WxMaMessage msg = WxMaMessage.fromJson(json); + checkXPayRefundNotifyMessage(msg); + } + + private void checkXPayRefundNotifyMessage(WxMaMessage msg) { + assertEquals(msg.getToUser(), "gh_abcdefg"); + assertEquals(msg.getFromUser(), "oABCDEFG"); + assertEquals(msg.getCreateTime(), new Integer(1700000000)); + assertEquals(msg.getMsgType(), WxConsts.XmlMsgType.EVENT); + assertEquals(msg.getEvent(), "xpay_refund_notify"); + assertEquals(msg.getWxRefundId(), "wx_refund_123"); + assertEquals(msg.getMchRefundId(), "mch_refund_456"); + assertEquals(msg.getWxOrderId(), "wx_order_789"); + assertEquals(msg.getMchOrderId(), "mch_order_101"); + assertEquals(msg.getRefundFee(), new Integer(100)); + assertEquals(msg.getRetCode(), new Integer(0)); + assertEquals(msg.getRetMsg(), "success"); + assertEquals(msg.getRefundStartTimestamp(), new Long(1700000000L)); + assertEquals(msg.getRefundSuccTimestamp(), new Long(1700000010L)); + assertEquals(msg.getWxpayRefundTransactionId(), "wxpay_refund_tx_202"); + assertEquals(msg.getRetryTimes(), new Integer(0)); + WxMaXPayTeamInfo teamInfo = msg.getTeamInfo(); + assertNotNull(teamInfo); + assertEquals(teamInfo.getActivityId(), "act_001"); + assertEquals(teamInfo.getTeamId(), "team_002"); + assertEquals(teamInfo.getTeamType(), new Integer(1)); + assertEquals(teamInfo.getTeamAction(), new Integer(0)); } }