Skip to content

Commit 852017f

Browse files
author
Liu Kai
committed
增加微信退款接口以及修改几个卡券相关的接口
1. 增加微信退款接口 2. 增加取得卡券详情接口 3. 修改取卡券签名接口的说明 4. 将卡券核销接口的返回值由Void改为String Change-Id: I2bac2d090871a4988f7279a9794eca5722451cdd Signed-off-by: Liu Kai <[email protected]>
1 parent b5986cf commit 852017f

File tree

3 files changed

+391
-6
lines changed

3 files changed

+391
-6
lines changed

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,20 @@ public interface WxMpService {
761761
*/
762762
WxMpPayCallback getJSSDKCallbackData(String xmlData);
763763

764+
/**
765+
* 微信支付-申请退款
766+
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
767+
* @param parameters 需要传入的退款参数的Map。以下几项为参数的必须项:<br/>
768+
* <li/> transaction_id
769+
* <li/> out_trade_no (仅在上述transaction_id为空时是必须项)
770+
* <li/> out_refund_no
771+
* <li/> total_fee
772+
* <li/> refund_fee
773+
* @return 退款操作结果
774+
* @throws WxErrorException
775+
*/
776+
public WxMpPayRefundResult refundPay(Map<String, String> parameters) throws WxErrorException;
777+
764778
/**
765779
* <pre>
766780
* 计算Map键值对是否和签名相符,
@@ -812,6 +826,7 @@ public interface WxMpService {
812826
*
813827
* @param optionalSignParam 参与签名的参数数组。
814828
* 可以为下列字段:app_id, card_id, card_type, code, openid, location_id
829+
* </br>注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空
815830
* @return 卡券Api签名对象
816831
*/
817832
public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws
@@ -839,10 +854,12 @@ public WxMpCardResult queryCardCode(String cardId, String code, boolean checkCon
839854
/**
840855
* 卡券Code核销。核销失败会抛出异常
841856
* @param code 单张卡券的唯一标准
842-
* @return
843-
* @throws WxErrorException
844-
*/
845-
public void consumeCardCode(String code) throws WxErrorException;
857+
* @param cardId 当自定义Code卡券时需要传入card_id
858+
* @return 调用返回的JSON字符串。
859+
* <br>可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。
860+
* @throws WxErrorException
861+
*/
862+
public String consumeCardCode(String code, String cardId) throws WxErrorException;
846863

847864
/**
848865
* 卡券Mark接口。
@@ -856,4 +873,15 @@ public WxMpCardResult queryCardCode(String cardId, String code, boolean checkCon
856873
*/
857874
public void markCardCode(String code, String cardId, String openId, boolean isMark) throws
858875
WxErrorException;
876+
877+
/**
878+
* 查看卡券详情接口
879+
* 详见 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
880+
* @param cardId 卡券的ID
881+
* @return 返回的卡券详情JSON字符串
882+
* <br> [注] 由于返回的JSON格式过于复杂,难以定义其对应格式的Bean并且难以维护,因此只返回String格式的JSON串。
883+
* <br> 可由 com.google.gson.JsonParser#parse 等方法直接取JSON串中的某个字段。
884+
* @throws WxErrorException
885+
*/
886+
public String getCardDetail(String cardId) throws WxErrorException;
859887
}

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import me.chanjar.weixin.mp.bean.result.WxMpMaterialVideoInfoResult;
5757
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
5858
import me.chanjar.weixin.mp.bean.result.WxMpPayCallback;
59+
import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult;
5960
import me.chanjar.weixin.mp.bean.result.WxMpPayResult;
6061
import me.chanjar.weixin.mp.bean.result.WxMpPrepayIdResult;
6162
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
@@ -97,6 +98,7 @@
9798
import com.google.gson.JsonArray;
9899
import com.google.gson.JsonElement;
99100
import com.google.gson.JsonObject;
101+
import com.google.gson.JsonParser;
100102
import com.google.gson.internal.Streams;
101103
import com.google.gson.reflect.TypeToken;
102104
import com.google.gson.stream.JsonReader;
@@ -971,6 +973,54 @@ public WxMpPayCallback getJSSDKCallbackData(String xmlData) {
971973
return new WxMpPayCallback();
972974
}
973975

976+
@Override
977+
public WxMpPayRefundResult refundPay(Map<String, String> parameters) throws WxErrorException {
978+
SortedMap<String, String> refundParams = new TreeMap<String, String>(parameters);
979+
refundParams.put("appid", wxMpConfigStorage.getAppId());
980+
refundParams.put("mch_id", wxMpConfigStorage.getPartnerId());
981+
refundParams.put("nonceStr", System.currentTimeMillis() + "");
982+
refundParams.put("op_user_id", wxMpConfigStorage.getPartnerId());
983+
String sign = WxCryptUtil.createSign(refundParams, wxMpConfigStorage.getPartnerKey());
984+
refundParams.put("sign", sign);
985+
986+
StringBuilder request = new StringBuilder("<xml>");
987+
for (Entry<String, String> para : refundParams.entrySet()) {
988+
request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey()));
989+
}
990+
request.append("</xml>");
991+
992+
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
993+
if (httpProxy != null) {
994+
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
995+
httpPost.setConfig(config);
996+
}
997+
998+
StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8);
999+
httpPost.setEntity(entity);
1000+
try(
1001+
CloseableHttpResponse response = getHttpclient().execute(httpPost)) {
1002+
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
1003+
XStream xstream = XStreamInitializer.getInstance();
1004+
xstream.processAnnotations(WxRedpackResult.class);
1005+
WxMpPayRefundResult wxMpPayRefundResult = (WxMpPayRefundResult) xstream.fromXML(responseContent);
1006+
1007+
if ("FAIL".equals(wxMpPayRefundResult.getResultCode())) {
1008+
WxError error = new WxError();
1009+
error.setErrorCode(-1);
1010+
error.setErrorMsg(wxMpPayRefundResult.getErrCodeDes());
1011+
throw new WxErrorException(error);
1012+
}
1013+
1014+
return wxMpPayRefundResult;
1015+
} catch (IOException e) {
1016+
log.error(MessageFormatter.format("The exception was happened when sending refund '{}'.", request.toString()).getMessage(), e);
1017+
WxError error = new WxError();
1018+
error.setErrorCode(-1);
1019+
error.setErrorMsg("incorrect response.");
1020+
throw new WxErrorException(error);
1021+
}
1022+
}
1023+
9741024
@Override
9751025
public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature) {
9761026
return signature.equals(WxCryptUtil.createSign(kvm, wxMpConfigStorage.getPartnerKey()));
@@ -1074,6 +1124,7 @@ public String getCardApiTicket(boolean forceRefresh) throws WxErrorException {
10741124
*
10751125
* @param optionalSignParam 参与签名的参数数组。
10761126
* 可以为下列字段:app_id, card_id, card_type, code, openid, location_id
1127+
* </br>注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空
10771128
* @return 卡券Api签名对象
10781129
*/
10791130
@Override
@@ -1148,11 +1199,17 @@ public WxMpCardResult queryCardCode(String cardId, String code, boolean checkCon
11481199
* @throws WxErrorException
11491200
*/
11501201
@Override
1151-
public void consumeCardCode(String code) throws WxErrorException {
1202+
public String consumeCardCode(String code, String cardId) throws WxErrorException {
11521203
String url = "https://api.weixin.qq.com/card/code/consume";
11531204
JsonObject param = new JsonObject();
11541205
param.addProperty("code", code);
1155-
post(url, param.toString());
1206+
1207+
if (cardId != null && !"".equals(cardId)) {
1208+
param.addProperty("card_id", cardId);
1209+
}
1210+
1211+
String responseContent = post(url, param.toString());
1212+
return responseContent;
11561213
}
11571214

11581215
/**
@@ -1183,4 +1240,26 @@ public void markCardCode(String code, String cardId, String openId, boolean isMa
11831240
log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg());
11841241
}
11851242
}
1243+
1244+
@Override
1245+
public String getCardDetail(String cardId) throws WxErrorException {
1246+
String url = "https://api.weixin.qq.com/card/get";
1247+
JsonObject param = new JsonObject();
1248+
param.addProperty("card_id", cardId);
1249+
String responseContent = post(url, param.toString());
1250+
1251+
// 判断返回值
1252+
JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject();
1253+
String errcode = json.get("errcode").getAsString();
1254+
if (!"0".equals(errcode)) {
1255+
String errmsg = json.get("errmsg").getAsString();
1256+
WxError error = new WxError();
1257+
error.setErrorCode(Integer.valueOf(errcode));
1258+
error.setErrorMsg(errmsg);
1259+
throw new WxErrorException(error);
1260+
}
1261+
1262+
return responseContent;
1263+
}
1264+
11861265
}

0 commit comments

Comments
 (0)