mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 18:46:10 +08:00 
			
		
		
		
	增加微信退款接口以及修改几个卡券相关的接口
1. 增加微信退款接口 2. 增加取得卡券详情接口 3. 修改取卡券签名接口的说明 4. 将卡券核销接口的返回值由Void改为String Change-Id: I2bac2d090871a4988f7279a9794eca5722451cdd Signed-off-by: Liu Kai <liukai@tinkers.com.cn>
This commit is contained in:
		| @ -761,6 +761,20 @@ public interface WxMpService { | ||||
|      */ | ||||
|     WxMpPayCallback getJSSDKCallbackData(String xmlData); | ||||
|      | ||||
|     /** | ||||
|      * 微信支付-申请退款 | ||||
|      * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 | ||||
|      * @param parameters 需要传入的退款参数的Map。以下几项为参数的必须项:<br/> | ||||
|      *        <li/> transaction_id | ||||
|      *        <li/> out_trade_no (仅在上述transaction_id为空时是必须项) | ||||
|      *        <li/> out_refund_no | ||||
|      *        <li/> total_fee | ||||
|      *        <li/> refund_fee | ||||
|      * @return 退款操作结果 | ||||
|      * @throws WxErrorException  | ||||
|      */ | ||||
|     public WxMpPayRefundResult refundPay(Map<String, String> parameters) throws WxErrorException; | ||||
|      | ||||
|     /** | ||||
|      * <pre> | ||||
|      * 计算Map键值对是否和签名相符, | ||||
| @ -812,6 +826,7 @@ public interface WxMpService { | ||||
|    * | ||||
|    * @param optionalSignParam 参与签名的参数数组。 | ||||
|    *                  可以为下列字段:app_id, card_id, card_type, code, openid, location_id | ||||
|    *                  </br>注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 | ||||
|    * @return 卡券Api签名对象 | ||||
|    */ | ||||
|   public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws | ||||
| @ -839,10 +854,12 @@ public interface WxMpService { | ||||
|    /** | ||||
|    * 卡券Code核销。核销失败会抛出异常 | ||||
|    * @param code 单张卡券的唯一标准 | ||||
|     * @return | ||||
|     * @throws WxErrorException | ||||
|     */ | ||||
|   public void consumeCardCode(String code) throws WxErrorException; | ||||
|    * @param cardId 当自定义Code卡券时需要传入card_id | ||||
|    * @return 调用返回的JSON字符串。 | ||||
|    *         <br>可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   public String consumeCardCode(String code, String cardId) throws WxErrorException; | ||||
|  | ||||
|     /** | ||||
|      * 卡券Mark接口。 | ||||
| @ -856,4 +873,15 @@ public interface WxMpService { | ||||
|      */ | ||||
|   public void markCardCode(String code, String cardId, String openId, boolean isMark) throws | ||||
|       WxErrorException; | ||||
|    | ||||
|   /** | ||||
|    * 查看卡券详情接口 | ||||
|    * 详见 https://mp.weixin.qq.com/wiki/14/8dd77aeaee85f922db5f8aa6386d385e.html#.E6.9F.A5.E7.9C.8B.E5.8D.A1.E5.88.B8.E8.AF.A6.E6.83.85 | ||||
|    * @param cardId 卡券的ID | ||||
|    * @return 返回的卡券详情JSON字符串 | ||||
|    *         <br> [注] 由于返回的JSON格式过于复杂,难以定义其对应格式的Bean并且难以维护,因此只返回String格式的JSON串。 | ||||
|    *         <br> 可由 com.google.gson.JsonParser#parse 等方法直接取JSON串中的某个字段。 | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   public String getCardDetail(String cardId) throws WxErrorException; | ||||
| } | ||||
|  | ||||
| @ -56,6 +56,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpMaterialUploadResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpMaterialVideoInfoResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpPayResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpPrepayIdResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; | ||||
| @ -97,6 +98,7 @@ import org.slf4j.helpers.MessageFormatter; | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonElement; | ||||
| import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | ||||
| import com.google.gson.internal.Streams; | ||||
| import com.google.gson.reflect.TypeToken; | ||||
| import com.google.gson.stream.JsonReader; | ||||
| @ -971,6 +973,54 @@ public class WxMpServiceImpl implements WxMpService { | ||||
|     return new WxMpPayCallback(); | ||||
|   } | ||||
|    | ||||
|   @Override | ||||
|   public WxMpPayRefundResult refundPay(Map<String, String> parameters) throws WxErrorException { | ||||
|     SortedMap<String, String> refundParams = new TreeMap<String, String>(parameters); | ||||
|     refundParams.put("appid", wxMpConfigStorage.getAppId()); | ||||
|     refundParams.put("mch_id", wxMpConfigStorage.getPartnerId()); | ||||
|     refundParams.put("nonceStr", System.currentTimeMillis() + ""); | ||||
|     refundParams.put("op_user_id", wxMpConfigStorage.getPartnerId()); | ||||
|     String sign = WxCryptUtil.createSign(refundParams, wxMpConfigStorage.getPartnerKey()); | ||||
|     refundParams.put("sign", sign); | ||||
|  | ||||
|     StringBuilder request = new StringBuilder("<xml>"); | ||||
|     for (Entry<String, String> para : refundParams.entrySet()) { | ||||
|       request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey())); | ||||
|     } | ||||
|     request.append("</xml>"); | ||||
|      | ||||
|     HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund"); | ||||
|     if (httpProxy != null) { | ||||
|       RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | ||||
|       httpPost.setConfig(config); | ||||
|     } | ||||
|      | ||||
|     StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8); | ||||
|     httpPost.setEntity(entity); | ||||
|     try( | ||||
|       CloseableHttpResponse response = getHttpclient().execute(httpPost)) { | ||||
|       String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | ||||
|       XStream xstream = XStreamInitializer.getInstance(); | ||||
|       xstream.processAnnotations(WxRedpackResult.class); | ||||
|       WxMpPayRefundResult wxMpPayRefundResult = (WxMpPayRefundResult) xstream.fromXML(responseContent); | ||||
|        | ||||
|       if ("FAIL".equals(wxMpPayRefundResult.getResultCode())) { | ||||
|     	  WxError error = new WxError(); | ||||
|     	  error.setErrorCode(-1); | ||||
|     	  error.setErrorMsg(wxMpPayRefundResult.getErrCodeDes()); | ||||
|     	  throw new WxErrorException(error); | ||||
|       } | ||||
|        | ||||
|       return wxMpPayRefundResult; | ||||
|     } catch (IOException e) { | ||||
|       log.error(MessageFormatter.format("The exception was happened when sending refund '{}'.", request.toString()).getMessage(), e); | ||||
|       WxError error = new WxError(); | ||||
|       error.setErrorCode(-1); | ||||
|       error.setErrorMsg("incorrect response."); | ||||
|       throw new WxErrorException(error); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   @Override | ||||
|   public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature) { | ||||
| 	  return signature.equals(WxCryptUtil.createSign(kvm, wxMpConfigStorage.getPartnerKey())); | ||||
| @ -1074,6 +1124,7 @@ public class WxMpServiceImpl implements WxMpService { | ||||
|    * | ||||
|    * @param optionalSignParam 参与签名的参数数组。 | ||||
|    *                  可以为下列字段:app_id, card_id, card_type, code, openid, location_id | ||||
|    *                  </br>注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 | ||||
|    * @return 卡券Api签名对象 | ||||
|    */ | ||||
|   @Override | ||||
| @ -1148,11 +1199,17 @@ public class WxMpServiceImpl implements WxMpService { | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   @Override | ||||
|   public void consumeCardCode(String code) throws WxErrorException { | ||||
|   public String consumeCardCode(String code, String cardId) throws WxErrorException { | ||||
|     String url = "https://api.weixin.qq.com/card/code/consume"; | ||||
|     JsonObject param = new JsonObject(); | ||||
|     param.addProperty("code", code); | ||||
|     post(url, param.toString()); | ||||
|      | ||||
|     if (cardId != null && !"".equals(cardId)) { | ||||
|     	param.addProperty("card_id", cardId); | ||||
|     } | ||||
|      | ||||
|     String responseContent = post(url, param.toString()); | ||||
|     return responseContent; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
| @ -1183,4 +1240,26 @@ public class WxMpServiceImpl implements WxMpService { | ||||
|       log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public String getCardDetail(String cardId) throws WxErrorException { | ||||
|     String url = "https://api.weixin.qq.com/card/get"; | ||||
|     JsonObject param = new JsonObject(); | ||||
|     param.addProperty("card_id", cardId); | ||||
|     String responseContent = post(url, param.toString()); | ||||
|      | ||||
|     // 判断返回值 | ||||
|     JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject(); | ||||
|     String errcode = json.get("errcode").getAsString(); | ||||
|     if (!"0".equals(errcode)) { | ||||
|       String errmsg = json.get("errmsg").getAsString(); | ||||
|       WxError error = new WxError(); | ||||
|       error.setErrorCode(Integer.valueOf(errcode)); | ||||
|       error.setErrorMsg(errmsg); | ||||
|       throw new WxErrorException(error); | ||||
|     } | ||||
|      | ||||
|     return responseContent; | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,278 @@ | ||||
| package me.chanjar.weixin.mp.bean.result; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
|  | ||||
| /** | ||||
|  * 微信支付-申请退款返回结果 | ||||
|  * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 | ||||
|  * @author liukaitj | ||||
|  * | ||||
|  */ | ||||
| @XStreamAlias("xml") | ||||
| public class WxMpPayRefundResult implements Serializable { | ||||
|  | ||||
|   private static final long serialVersionUID = 1L; | ||||
|  | ||||
|   @XStreamAlias("return_code") | ||||
|   private String returnCode; | ||||
|    | ||||
|   @XStreamAlias("return_msg") | ||||
|   private String returnMsg; | ||||
|    | ||||
|   @XStreamAlias("result_code") | ||||
|   private String resultCode; | ||||
|    | ||||
|   @XStreamAlias("err_code") | ||||
|   private String errCode; | ||||
|    | ||||
|   @XStreamAlias("err_code_des") | ||||
|   private String errCodeDes; | ||||
|    | ||||
|   @XStreamAlias("appid") | ||||
|   private String appid; | ||||
|    | ||||
|   @XStreamAlias("mch_id") | ||||
|   private String mchId; | ||||
|    | ||||
|   @XStreamAlias("device_info") | ||||
|   private String deviceInfo; | ||||
|    | ||||
|   @XStreamAlias("nonce_str") | ||||
|   private String nonceStr; | ||||
|    | ||||
|   @XStreamAlias("sign") | ||||
|   private String sign; | ||||
|    | ||||
|   @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; | ||||
|    | ||||
|   @XStreamAlias("total_fee") | ||||
|   private String totalFee; | ||||
|    | ||||
|   @XStreamAlias("fee_type") | ||||
|   private String feeType; | ||||
|    | ||||
|   @XStreamAlias("cash_fee") | ||||
|   private String cashFee; | ||||
|    | ||||
|   @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; | ||||
|  | ||||
|   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 String getResultCode() { | ||||
|     return resultCode; | ||||
|   } | ||||
|    | ||||
|   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 getDeviceInfo() { | ||||
|     return deviceInfo; | ||||
|   } | ||||
|    | ||||
|   public void setDeviceInfo(String deviceInfo) { | ||||
|     this.deviceInfo = deviceInfo; | ||||
|   } | ||||
|    | ||||
|   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 String getOutTradeNo() { | ||||
|     return outTradeNo; | ||||
|   } | ||||
|    | ||||
|   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 String getRefundChannel() { | ||||
|     return refundChannel; | ||||
|   } | ||||
|    | ||||
|   public void setRefundChannel(String refundChannel) { | ||||
|     this.refundChannel = refundChannel; | ||||
|   } | ||||
|    | ||||
|   public String getRefundFee() { | ||||
|     return refundFee; | ||||
|   } | ||||
|    | ||||
|   public void setRefundFee(String refundFee) { | ||||
|     this.refundFee = refundFee; | ||||
|   } | ||||
|    | ||||
|   public String getTotalFee() { | ||||
|     return totalFee; | ||||
|   } | ||||
|    | ||||
|   public void setTotalFee(String totalFee) { | ||||
|     this.totalFee = totalFee; | ||||
|   } | ||||
|    | ||||
|   public String getFeeType() { | ||||
|     return feeType; | ||||
|   } | ||||
|    | ||||
|   public void setFeeType(String feeType) { | ||||
|     this.feeType = feeType; | ||||
|   } | ||||
|    | ||||
|   public String getCashFee() { | ||||
|     return cashFee; | ||||
|   } | ||||
|    | ||||
|   public void setCashFee(String cashFee) { | ||||
|     this.cashFee = cashFee; | ||||
|   } | ||||
|    | ||||
|   public String getCashRefundfee() { | ||||
|     return cashRefundfee; | ||||
|   } | ||||
|    | ||||
|   public void setCashRefundfee(String cashRefundfee) { | ||||
|     this.cashRefundfee = cashRefundfee; | ||||
|   } | ||||
|    | ||||
|   public String getCouponRefundFee() { | ||||
|     return couponRefundFee; | ||||
|   } | ||||
|    | ||||
|   public void setCouponRefundFee(String couponRefundFee) { | ||||
|     this.couponRefundFee = couponRefundFee; | ||||
|   } | ||||
|    | ||||
|   public String getCouponRefundCount() { | ||||
|     return couponRefundCount; | ||||
|   } | ||||
|    | ||||
|   public void setCouponRefundCount(String couponRefundCount) { | ||||
|     this.couponRefundCount = couponRefundCount; | ||||
|   } | ||||
|    | ||||
|   public String getCouponRefundId() { | ||||
|     return couponRefundId; | ||||
|   } | ||||
|    | ||||
|   public void setCouponRefundId(String couponRefundId) { | ||||
|     this.couponRefundId = couponRefundId; | ||||
|   } | ||||
|    | ||||
|   @Override | ||||
|   public String toString() { | ||||
|     return "[" + | ||||
|       "return_code:" + returnCode + ";" + | ||||
|       "return_msg" + returnMsg + ";"; | ||||
|   } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Liu Kai
					Liu Kai