From 4959966222edfff188e4b512bcb42a3f8a60b17f Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 27 Oct 2016 18:42:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=85=B3=E9=97=AD=E8=AE=A2=E5=8D=95=E7=9A=84=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=20#54?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/mp/api/WxMpPayService.java | 17 +++++++++ .../mp/api/impl/WxMpPayServiceImpl.java | 34 ++++++++++++++++++ .../pay/request/WxPayOrderCloseRequest.java | 36 +++++++++++++++++++ .../pay/result/WxPayOrderCloseResult.java | 28 +++++++++++++++ .../mp/api/impl/WxMpPayServiceImplTest.java | 9 +++++ 5 files changed, 124 insertions(+) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java index 8d624e95..2fcd4cb9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java @@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback; +import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderCloseResult; import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest; import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest; import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; @@ -35,6 +36,22 @@ public interface WxMpPayService { */ WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException; + /** + *
+   * 关闭订单
+   * 应用场景
+   * 以下情况需要调用关单接口:
+   * 1. 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;
+   * 2. 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
+   * 注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。
+   * 接口地址:https://api.mch.weixin.qq.com/pay/closeorder
+   * 是否需要证书:   不需要。
+   * 
+ * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 + * @throws WxErrorException + */ + WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException; + /** * 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1) * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识" diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java index 2fc8e798..79acad73 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java @@ -8,6 +8,7 @@ import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.mp.api.WxMpPayService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback; +import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderCloseResult; import me.chanjar.weixin.mp.bean.pay.request.*; import me.chanjar.weixin.mp.bean.pay.result.*; import org.apache.commons.codec.digest.DigestUtils; @@ -210,6 +211,39 @@ public class WxMpPayServiceImpl implements WxMpPayService { return result; } + @Override + public WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException { + if (StringUtils.isBlank(outTradeNo)) { + throw new IllegalArgumentException("out_trade_no 不能为空"); + } + + XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxPayOrderCloseRequest.class); + xstream.processAnnotations(WxPayOrderCloseResult.class); + + WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); + request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); + request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); + request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); + request.setNonceStr(System.currentTimeMillis() + ""); + + String sign = this.createSign(BeanUtils.xmlBean2Map(request), + this.wxMpService.getWxMpConfigStorage().getPartnerKey()); + request.setSign(sign); + + String url = PAY_BASE_URL + "/pay/closeorder"; + + String responseContent = this.wxMpService.post(url, xstream.toXML(request)); + WxPayOrderCloseResult result = (WxPayOrderCloseResult) xstream.fromXML(responseContent); + if ("FAIL".equals(result.getResultCode())) { + throw new WxErrorException(WxError.newBuilder() + .setErrorMsg(result.getErrCode() + ":" + result.getErrCodeDes()) + .build()); + } + + return result; + } + @Override public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java new file mode 100644 index 00000000..8f26750f --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.mp.bean.pay.request; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + *
+ *  关闭订单请求对象类
+ * Created by Binary Wang on 2016-10-27.
+ * @author binarywang(Binary Wang)
+ * 
+ */ +@XStreamAlias("xml") +public class WxPayOrderCloseRequest extends WxPayBaseRequest{ + + /** + *
+   * 商户订单号
+   * out_trade_no
+   * 二选一
+   * String(32)
+   * 20150806125346
+   * 商户系统内部的订单号,当没提供transaction_id时需要传这个。
+   * 
+ */ + @XStreamAlias("out_trade_no") + private String outTradeNo; + + public String getOutTradeNo() { + return this.outTradeNo; + } + + public void setOutTradeNo(String outTradeNo) { + this.outTradeNo = outTradeNo; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java new file mode 100644 index 00000000..ccfa07bf --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java @@ -0,0 +1,28 @@ +package me.chanjar.weixin.mp.bean.pay.result; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + *
+ * 关闭订单结果对象类
+ * Created by Binary Wang on 2016-10-27.
+ * @author binarywang(Binary Wang)
+ * 
+ */ +@XStreamAlias("xml") +public class WxPayOrderCloseResult extends WxPayBaseResult { + + /** + * 业务结果描述 + */ + @XStreamAlias("result_msg") + private String resultMsg; + + public String getResultMsg() { + return this.resultMsg; + } + + public void setResultMsg(String resultMsg) { + this.resultMsg = resultMsg; + } +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java index 0f946dc3..e2febcdb 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java @@ -87,6 +87,15 @@ public class WxMpPayServiceImplTest { System.err.println(this.wxService.getPayService().queryOrder(null, "11111")); } + /** + * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#closeOrder(String)} . + * @throws WxErrorException + */ + @Test + public final void testCloseOrder() throws WxErrorException { + System.err.println(this.wxService.getPayService().closeOrder("11212121")); + } + /** * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#entPay(WxEntPayRequest, File)}. * @throws WxErrorException