From 40cf672715df31d9f4b4a845f2419a2549a24630 Mon Sep 17 00:00:00 2001 From: jinyu Date: Sat, 26 Mar 2016 20:51:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AD=BE=E5=90=8D=E7=B1=BB=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGE.md | 4 +- .../com/foxinmy/weixin4j/api/CashApi.java | 95 ++++------ .../com/foxinmy/weixin4j/api/CouponApi.java | 73 ++------ .../java/com/foxinmy/weixin4j/api/MchApi.java | 90 ++++++++++ .../java/com/foxinmy/weixin4j/api/PayApi.java | 164 ++++++------------ .../weixin4j/payment/PayURLConsts.java | 124 ------------- .../weixin4j/payment/WeixinPayProxy.java | 123 ++++++------- .../weixin4j/payment/mch/APPPayRequest.java | 2 +- .../payment/mch/AbstractPayRequest.java | 4 + .../weixin4j/payment/mch/JSAPIPayRequest.java | 6 +- .../payment/mch/NativePayResponse.java | 5 +- .../weixin4j/payment/mch/WAPPayRequest.java | 8 +- .../weixin4j/payment/weixin.properties | 51 ++++++ .../sign/AbstractWeixinSignature.java | 43 +++++ .../weixin4j/sign/WeixinPaymentSignature.java | 29 ++++ .../weixin4j/sign/WeixinSignature.java | 35 ++++ .../com/foxinmy/weixin4j/type/SignType.java | 3 +- .../com/foxinmy/weixin4j/util/DigestUtil.java | 84 --------- .../com/foxinmy/weixin4j/util/MapUtil.java | 7 +- .../foxinmy/weixin4j/base/test/CashTest.java | 6 +- .../foxinmy/weixin4j/base/test/PayTest.java | 44 ++--- .../foxinmy/weixin4j/mp/api/PayOldApi.java | 134 +++++++------- .../foxinmy/weixin4j/mp/api/weixin.properties | 76 ++------ .../v2 => oldpayment}/ApiResultV2.java | 2 +- .../v2 => oldpayment}/NativePayNotifyV2.java | 2 +- .../NativePayResponseV2.java | 11 +- .../{payment/v2 => oldpayment}/OrderV2.java | 2 +- .../v2 => oldpayment}/PayFeedback.java | 2 +- .../v2 => oldpayment}/PayPackageV2.java | 2 +- .../{payment/v2 => oldpayment}/PayWarn.java | 2 +- .../v2 => oldpayment}/RefundDetailV2.java | 2 +- .../v2 => oldpayment}/RefundRecordV2.java | 4 +- .../v2 => oldpayment}/RefundResultV2.java | 2 +- .../oldpayment/WeixinOldPaymentSignature.java | 70 ++++++++ .../com/foxinmy/weixin4j/mp/test/PayTest.java | 13 +- .../weixin4j/mp/test/XmlstreamTest.java | 2 +- .../dispatcher/WeixinMessageDispatcher.java | 29 ++-- .../weixin4j/socket/WeixinMessageDecoder.java | 1 + .../startup/WeixinServerBootstrap.java | 14 ++ 39 files changed, 680 insertions(+), 690 deletions(-) create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java delete mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/weixin.properties create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/AbstractWeixinSignature.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinPaymentSignature.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinSignature.java rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/ApiResultV2.java (98%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/NativePayNotifyV2.java (95%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/NativePayResponseV2.java (89%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/OrderV2.java (95%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/PayFeedback.java (98%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/PayPackageV2.java (98%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/PayWarn.java (92%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/RefundDetailV2.java (98%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/RefundRecordV2.java (94%) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/{payment/v2 => oldpayment}/RefundResultV2.java (96%) create mode 100644 weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/WeixinOldPaymentSignature.java diff --git a/CHANGE.md b/CHANGE.md index 45dcbfb7..96c2cbdc 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -651,4 +651,6 @@ + weixin4j-base:v2和v3支付改名 - + weixin4j-base:支持服务商版支付 \ No newline at end of file + + weixin4j-base:支持服务商版支付 + + + weixin4j-base:签名类接口化 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CashApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CashApi.java index 08f471e4..838af73f 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CashApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CashApi.java @@ -2,25 +2,20 @@ package com.foxinmy.weixin4j.api; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; import java.util.Map; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; -import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor; import com.foxinmy.weixin4j.model.WeixinPayAccount; -import com.foxinmy.weixin4j.payment.PayURLConsts; import com.foxinmy.weixin4j.payment.mch.CorpPayment; import com.foxinmy.weixin4j.payment.mch.CorpPaymentRecord; import com.foxinmy.weixin4j.payment.mch.CorpPaymentResult; import com.foxinmy.weixin4j.payment.mch.Redpacket; import com.foxinmy.weixin4j.payment.mch.RedpacketRecord; import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult; -import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.xml.XmlStream; @@ -36,18 +31,16 @@ import com.foxinmy.weixin4j.xml.XmlStream; * @see 企业付款 */ -public class CashApi { - - private final WeixinPayAccount weixinAccount; +public class CashApi extends MchApi { public CashApi(WeixinPayAccount weixinAccount) { - this.weixinAccount = weixinAccount; + super(weixinAccount); } /** * 发放红包 企业向微信用户个人发现金红包 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param redpacket * 红包信息 @@ -58,22 +51,19 @@ public class CashApi { * href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5">发放红包接口说明 * @throws WeixinException */ - public RedpacketSendResult sendRedpack(InputStream ca, Redpacket redpacket) - throws WeixinException { - redpacket.setSign(DigestUtil.paysignMd5(redpacket, - weixinAccount.getPaySignKey())); + public RedpacketSendResult sendRedpack(InputStream certificate, + Redpacket redpacket) throws WeixinException { + redpacket.setSign(weixinSignature.sign(redpacket)); String param = XmlStream.map2xml((JSONObject) JSON.toJSON(redpacket)); WeixinResponse response = null; try { - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - response = weixinExecutor - .post(redpacket.getTotalNum() > 1 ? PayURLConsts.MCH_REDPACK_GROUPSEND_URL - : PayURLConsts.MCH_REDPACKSEND_URL, param); + response = createSSLRequestExecutor(certificate) + .post(redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri") + : getRequestUri("redpack_send_uri"), param); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -86,7 +76,7 @@ public class CashApi { /** * 查询红包记录 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo * 商户发放红包的商户订单号 @@ -96,28 +86,21 @@ public class CashApi { * href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6">查询红包接口说明 * @throws WeixinException */ - public RedpacketRecord queryRedpack(InputStream ca, String outTradeNo) - throws WeixinException { - Map para = new HashMap(); - para.put("nonce_str", RandomUtil.generateString(16)); - para.put("mch_id", weixinAccount.getMchId()); + public RedpacketRecord queryRedpack(InputStream certificate, + String outTradeNo) throws WeixinException { + Map para = createBaseRequestMap(null); para.put("bill_type", "MCHT"); - para.put("appid", weixinAccount.getId()); para.put("mch_billno", outTradeNo); - String sign = DigestUtil - .paysignMd5(para, weixinAccount.getPaySignKey()); - para.put("sign", sign); + para.put("sign", weixinSignature.sign(para)); String param = XmlStream.map2xml(para); WeixinResponse response = null; try { - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - response = weixinExecutor.post(PayURLConsts.MCH_REDPACKQUERY_URL, - param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("redpack_query_uri"), param); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -130,7 +113,7 @@ public class CashApi { /** * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param mpPayment * 付款信息 @@ -141,27 +124,24 @@ public class CashApi { * href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款 * @throws WeixinException */ - public CorpPaymentResult corpPayment(InputStream ca, CorpPayment payment) - throws WeixinException { + public CorpPaymentResult sendCorpPayment(InputStream certificate, + CorpPayment payment) throws WeixinException { JSONObject obj = (JSONObject) JSON.toJSON(payment); obj.put("nonce_str", RandomUtil.generateString(16)); obj.put("mchid", weixinAccount.getMchId()); obj.put("sub_mch_id", weixinAccount.getSubMchId()); obj.put("mch_appid", weixinAccount.getId()); obj.put("device_info", weixinAccount.getDeviceInfo()); - String sign = DigestUtil.paysignMd5(obj, weixinAccount.getPaySignKey()); - obj.put("sign", sign); + obj.put("sign", weixinSignature.sign(obj)); String param = XmlStream.map2xml(obj); WeixinResponse response = null; try { - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - response = weixinExecutor.post(PayURLConsts.MCH_ENPAYMENT_URL, - param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("corppayment_send_uri"), param); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -178,7 +158,7 @@ public class CashApi { /** * 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo * 商户调用企业付款API时使用的商户订单号 @@ -188,26 +168,23 @@ public class CashApi { * href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询 * @throws WeixinException */ - public CorpPaymentRecord queryCorpPayment(InputStream ca, String outTradeNo) - throws WeixinException { + public CorpPaymentRecord queryCorpPayment(InputStream certificate, + String outTradeNo) throws WeixinException { JSONObject obj = new JSONObject(); obj.put("nonce_str", RandomUtil.generateString(16)); obj.put("mch_id", weixinAccount.getMchId()); obj.put("appid", weixinAccount.getId()); obj.put("partner_trade_no", outTradeNo); - String sign = DigestUtil.paysignMd5(obj, weixinAccount.getPaySignKey()); - obj.put("sign", sign); + obj.put("sign", weixinSignature.sign(obj)); String param = XmlStream.map2xml(obj); WeixinResponse response = null; try { - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - response = weixinExecutor.post(PayURLConsts.MCH_ENPAYQUERY_URL, - param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("corppayment_query_uri"), param); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CouponApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CouponApi.java index af4c0def..4ff5f8d0 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CouponApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CouponApi.java @@ -2,21 +2,15 @@ package com.foxinmy.weixin4j.api; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; import java.util.Map; import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; -import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor; import com.foxinmy.weixin4j.model.WeixinPayAccount; -import com.foxinmy.weixin4j.payment.PayURLConsts; import com.foxinmy.weixin4j.payment.coupon.CouponDetail; import com.foxinmy.weixin4j.payment.coupon.CouponResult; import com.foxinmy.weixin4j.payment.coupon.CouponStock; -import com.foxinmy.weixin4j.util.DigestUtil; -import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.xml.XmlStream; @@ -29,22 +23,17 @@ import com.foxinmy.weixin4j.xml.XmlStream; * @since JDK 1.6 * @see 代金券文档 */ -public class CouponApi { - - private final WeixinRequestExecutor weixinExecutor; - - private final WeixinPayAccount weixinAccount; +public class CouponApi extends MchApi { public CouponApi(WeixinPayAccount weixinAccount) { - this.weixinAccount = weixinAccount; - this.weixinExecutor = new WeixinRequestExecutor(); + super(weixinAccount); } /** * 发放代金券(需要证书) * - * @param ca - * 后缀为*.p12的证书文件 + * @param certificate + * 后缀为*.p12的证书文件 * @param couponStockId * 代金券批次id * @param partnerTradeNo @@ -59,10 +48,10 @@ public class CouponApi { * href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_3">发放代金券接口 * @throws WeixinException */ - public CouponResult sendCoupon(InputStream ca, String couponStockId, - String partnerTradeNo, String openId, String opUserId) - throws WeixinException { - Map map = baseMap(); + public CouponResult sendCoupon(InputStream certificate, + String couponStockId, String partnerTradeNo, String openId, + String opUserId) throws WeixinException { + Map map = createBaseRequestMap(null); map.put("coupon_stock_id", couponStockId); map.put("partner_trade_no", partnerTradeNo); map.put("openid", openId); @@ -75,19 +64,16 @@ public class CouponApi { map.put("op_user_id", opUserId); map.put("version", "1.0"); map.put("type", "XML"); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = null; try { - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - response = weixinExecutor.post(PayURLConsts.MCH_COUPONSEND_URL, - param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("coupon_send_uri"), param); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -110,13 +96,12 @@ public class CouponApi { */ public CouponStock queryCouponStock(String couponStockId) throws WeixinException { - Map map = baseMap(); + Map map = createBaseRequestMap(null); map.put("coupon_stock_id", couponStockId); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_COUPONSTOCKQUERY_URL, param); + getRequestUri("couponstock_query_uri"), param); return response.getAsObject(new TypeReference() { }); } @@ -134,33 +119,13 @@ public class CouponApi { */ public CouponDetail queryCouponDetail(String couponId) throws WeixinException { - Map map = baseMap(); + Map map = createBaseRequestMap(null); map.put("coupon_id", couponId); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_COUPONDETAILQUERY_URL, param); + getRequestUri("coupondetail_query_uri"), param); return response.getAsObject(new TypeReference() { }); } - - /** - * 接口请求基本数据 - * - * @return - */ - private Map baseMap() { - Map map = new HashMap(); - map.put("appid", weixinAccount.getId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("nonce_str", RandomUtil.generateString(16)); - if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) { - map.put("device_info", weixinAccount.getDeviceInfo()); - } - if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) { - map.put("sub_mch_id", weixinAccount.getSubMchId()); - } - return map; - } } \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java new file mode 100644 index 00000000..b29c018d --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java @@ -0,0 +1,90 @@ +package com.foxinmy.weixin4j.api; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.ResourceBundle; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; +import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor; +import com.foxinmy.weixin4j.model.WeixinPayAccount; +import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; +import com.foxinmy.weixin4j.sign.WeixinSignature; +import com.foxinmy.weixin4j.type.IdQuery; +import com.foxinmy.weixin4j.util.RandomUtil; +import com.foxinmy.weixin4j.util.StringUtil; + +/** + * 商户支付 + * + * @className MchApi + * @author jy + * @date 2016年3月26日 + * @since JDK 1.6 + * @see 商户支付平台 + */ +public class MchApi extends BaseApi { + + private final static ResourceBundle WEIXIN_BUNDLE; + + static { + WEIXIN_BUNDLE = ResourceBundle + .getBundle("com/foxinmy/weixin4j/payment/weixin"); + } + + protected final WeixinPayAccount weixinAccount; + protected final WeixinSignature weixinSignature; + + public MchApi(WeixinPayAccount weixinAccount) { + this.weixinAccount = weixinAccount; + this.weixinSignature = new WeixinPaymentSignature( + weixinAccount.getPaySignKey()); + } + + @Override + protected ResourceBundle weixinBundle() { + return WEIXIN_BUNDLE; + } + + /** + * 创建 SSL支付请求 + * + * @param certificate + * *.p12证书文件 + * @return + * @throws WeixinException + */ + protected WeixinRequestExecutor createSSLRequestExecutor( + InputStream certificate) throws WeixinException { + return new WeixinSSLRequestExecutor(weixinAccount.getCertificateKey(), + certificate); + } + + /** + * 支付接口请求基本数据 + * + * @param idQuery + * ID信息 可为空 + * @return 基础map + */ + protected Map createBaseRequestMap(IdQuery idQuery) { + Map map = new HashMap(); + map.put("appid", weixinAccount.getId()); + map.put("mch_id", weixinAccount.getMchId()); + map.put("nonce_str", RandomUtil.generateString(16)); + if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) { + map.put("device_info", weixinAccount.getDeviceInfo()); + } + if (StringUtil.isNotBlank(weixinAccount.getSubId())) { + map.put("sub_appid", weixinAccount.getSubId()); + } + if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) { + map.put("sub_mch_id", weixinAccount.getSubMchId()); + } + if (idQuery != null) { + map.put(idQuery.getType().getName(), idQuery.getId()); + } + return map; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java index cba65184..a9f54514 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java @@ -19,14 +19,11 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinPayException; -import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; -import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor; import com.foxinmy.weixin4j.http.weixin.XmlResult; import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.payment.MicroPayPackage; -import com.foxinmy.weixin4j.payment.PayURLConsts; import com.foxinmy.weixin4j.payment.mch.APPPayRequest; import com.foxinmy.weixin4j.payment.mch.ApiResult; import com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest; @@ -63,14 +60,10 @@ import com.foxinmy.weixin4j.xml.XmlStream; * @since JDK 1.6 * @see 商户平台API */ -public class PayApi { - - private final WeixinRequestExecutor weixinExecutor; - private final WeixinPayAccount weixinAccount; +public class PayApi extends MchApi { public PayApi(WeixinPayAccount weixinAccount) { - this.weixinAccount = weixinAccount; - this.weixinExecutor = new WeixinRequestExecutor(); + super(weixinAccount); } /** @@ -88,12 +81,11 @@ public class PayApi { */ public PrePay createPrePay(MchPayPackage payPackage) throws WeixinPayException { - payPackage.setSign(DigestUtil.paysignMd5(payPackage, - weixinAccount.getPaySignKey())); + payPackage.setSign(weixinSignature.sign(payPackage)); String payJsRequestXml = XmlStream.toXML(payPackage); try { WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_UNIFIEDORDER_URL, payJsRequestXml); + getRequestUri("order_create_uri"), payJsRequestXml); PrePay prePay = response.getAsObject(new TypeReference() { }); if (!prePay.getReturnCode().equalsIgnoreCase(Consts.SUCCESS)) { @@ -250,8 +242,7 @@ public class PayApi { map.put("nonceStr", RandomUtil.generateString(16)); map.put("url", url); map.put("accessToken", oauthToken); - String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true, - null)); + String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true)); map.remove("url"); map.remove("accessToken"); map.put("scope", "jsapi_address"); @@ -279,8 +270,8 @@ public class PayApi { map.put("time_stamp", timestamp); map.put("nonce_str", noncestr); map.put("product_id", productId); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - return String.format(PayURLConsts.MCH_NATIVE_URL, sign, + String sign = weixinSignature.sign(map); + return String.format(getRequestUri("native_pay_uri"), sign, weixinAccount.getId(), weixinAccount.getMchId(), productId, timestamp, noncestr); } @@ -438,15 +429,12 @@ public class PayApi { */ public Order createMicroPay(MicroPayPackage payPackage) throws WeixinException { - String sign = DigestUtil.paysignMd5(payPackage, - weixinAccount.getPaySignKey()); - payPackage.setSign(sign); + payPackage.setSign(weixinSignature.sign(payPackage)); String para = XmlStream.toXML(payPackage); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_MICROPAY_URL, para); - return response - .getAsObject(new TypeReference() { - }); + getRequestUri("micropay_uri"), para); + return response.getAsObject(new TypeReference() { + }); } /** @@ -466,13 +454,12 @@ public class PayApi { * @since V3 * @throws WeixinException */ - public Order orderQuery(IdQuery idQuery) throws WeixinException { - Map map = baseMap(idQuery); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + public Order queryOrder(IdQuery idQuery) throws WeixinException { + Map map = createBaseRequestMap(idQuery); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_ORDERQUERY_URL, param); + getRequestUri("order_query_uri"), param); return ListsuffixResultDeserializer.deserialize(response.getAsString(), Order.class); } @@ -489,7 +476,7 @@ public class PayApi { * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 *

* - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -511,12 +498,12 @@ public class PayApi { * @since V3 * @throws WeixinException */ - public RefundResult refundApply(InputStream ca, IdQuery idQuery, + public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee, double refundFee, CurrencyType refundFeeType, String opUserId) throws WeixinException { WeixinResponse response = null; try { - Map map = baseMap(idQuery); + Map map = createBaseRequestMap(idQuery); map.put("out_refund_no", outRefundNo); map.put("total_fee", DateUtil.formaFee2Fen(totalFee)); map.put("refund_fee", DateUtil.formaFee2Fen(refundFee)); @@ -528,18 +515,14 @@ public class PayApi { refundFeeType = CurrencyType.CNY; } map.put("refund_fee_type", refundFeeType.name()); - String sign = DigestUtil.paysignMd5(map, - weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - response = weixinExecutor.post(PayURLConsts.MCH_REFUNDAPPLY_URL, - param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("refund_apply_uri"), param); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -552,7 +535,7 @@ public class PayApi { /** * 退款申请(全额退款) * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -561,12 +544,12 @@ public class PayApi { * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 * @param totalFee * 订单总金额,单位为元 - * @see {@link #refundApply(InputStream, IdQuery, String, double, double,CurrencyType, String)} + * @see {@link #applyRefund(InputStream, IdQuery, String, double, double,CurrencyType, String)} */ - public RefundResult refundApply(InputStream ca, IdQuery idQuery, + public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException { - return refundApply(ca, idQuery, outRefundNo, totalFee, totalFee, null, - null); + return applyRefund(certificate, idQuery, outRefundNo, totalFee, + totalFee, null, null); } /** @@ -575,7 +558,7 @@ public class PayApi { * 如需实现相同功能请调用退款接口
调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
* - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -584,24 +567,20 @@ public class PayApi { * @since V3 * @throws WeixinException */ - public ApiResult reverseOrder(InputStream ca, IdQuery idQuery) + public ApiResult reverseOrder(InputStream certificate, IdQuery idQuery) throws WeixinException { try { - WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( - weixinAccount.getCertificateKey(), ca); - Map map = baseMap(idQuery); - String sign = DigestUtil.paysignMd5(map, - weixinAccount.getPaySignKey()); - map.put("sign", sign); + Map map = createBaseRequestMap(idQuery); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); - WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_ORDERREVERSE_URL, param); + WeixinResponse response = createSSLRequestExecutor(certificate) + .post(getRequestUri("order_reverse_uri"), param); return response.getAsObject(new TypeReference() { }); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -621,17 +600,16 @@ public class PayApi { * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_9">转换短链接API */ public String getShorturl(String url) throws WeixinException { - Map map = baseMap(null); + Map map = createBaseRequestMap(null); try { map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name())); - } catch (UnsupportedEncodingException ignore) { + } catch (UnsupportedEncodingException e) { ; } - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_SHORTURL_URL, param); + getRequestUri("longurl_convert_uri"), param); map = XmlStream.xml2map(response.getAsString()); return map.get("short_url"); } @@ -652,13 +630,12 @@ public class PayApi { * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">关闭订单API */ public ApiResult closeOrder(String outTradeNo) throws WeixinException { - Map map = baseMap(new IdQuery(outTradeNo, + Map map = createBaseRequestMap(new IdQuery(outTradeNo, IdType.TRADENO)); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_CLOSEORDER_URL, param); + getRequestUri("order_close_uri"), param); return response.getAsObject(new TypeReference() { }); } @@ -700,14 +677,13 @@ public class PayApi { if (file.exists()) { return file; } - Map map = baseMap(null); + Map map = createBaseRequestMap(null); map.put("bill_date", formatBillDate); map.put("bill_type", billType.name()); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_DOWNLOADBILL_URL, param); + getRequestUri("downloadbill_uri"), param); BufferedReader reader = null; BufferedWriter writer = null; @@ -757,13 +733,12 @@ public class PayApi { * @since V3 * @throws WeixinException */ - public RefundRecord refundQuery(IdQuery idQuery) throws WeixinException { - Map map = baseMap(idQuery); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException { + Map map = createBaseRequestMap(idQuery); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_REFUNDQUERY_URL, param); + getRequestUri("refund_query_uri"), param); return ListsuffixResultDeserializer.deserialize(response.getAsString(), RefundRecord.class); } @@ -793,18 +768,17 @@ public class PayApi { public XmlResult interfaceReport(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time, XmlResult returnXml) throws WeixinException { - Map map = baseMap(null); + Map map = createBaseRequestMap(null); map.put("interface_url", interfaceUrl); map.put("execute_time_", Integer.toString(executeTime)); map.put("out_trade_no", outTradeNo); map.put("user_ip", ip); map.put("time", DateUtil.fortmat2yyyyMMddHHmmss(time)); map.putAll((Map) JSON.toJSON(returnXml)); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_PAYREPORT_URL, param); + getRequestUri("interface_report_uri"), param); return response.getAsXmlResult(); } @@ -820,39 +794,13 @@ public class PayApi { * @throws WeixinException */ public OpenIdResult authCode2openId(String authCode) throws WeixinException { - Map map = baseMap(null); + Map map = createBaseRequestMap(null); map.put("auth_code", authCode); - String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey()); - map.put("sign", sign); + map.put("sign", weixinSignature.sign(map)); String param = XmlStream.map2xml(map); WeixinResponse response = weixinExecutor.post( - PayURLConsts.MCH_AUTHCODE_OPENID_URL, param); + getRequestUri("authcode_openid_uri"), param); return response.getAsObject(new TypeReference() { }); } - - /** - * 支付接口请求基本数据 - * - * @return - */ - private Map baseMap(IdQuery idQuery) { - Map map = new HashMap(); - map.put("appid", weixinAccount.getId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("nonce_str", RandomUtil.generateString(16)); - if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) { - map.put("device_info", weixinAccount.getDeviceInfo()); - } - if (StringUtil.isNotBlank(weixinAccount.getSubId())) { - map.put("sub_appid", weixinAccount.getSubId()); - } - if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) { - map.put("sub_mch_id", weixinAccount.getSubMchId()); - } - if (idQuery != null) { - map.put(idQuery.getType().getName(), idQuery.getId()); - } - return map; - } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java deleted file mode 100644 index c1814bae..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.foxinmy.weixin4j.payment; - - -/** - * 支付URL常量类 - * - * @className PayURLConsts - * @author jy - * @date 2014年12月3日 - * @since JDK 1.6 - * @see - */ -public final class PayURLConsts { - - private static final String MCH_BASE_URL = "https://api.mch.weixin.qq.com"; - - /** - * 商户平台下统一订单生成的url - */ - public static final String MCH_UNIFIEDORDER_URL = MCH_BASE_URL - + "/pay/unifiedorder"; - /** - * 订单查询(商户平台) - */ - public static final String MCH_ORDERQUERY_URL = MCH_BASE_URL - + "/pay/orderquery"; - /** - * 关闭订单(商户平台) - */ - public static final String MCH_CLOSEORDER_URL = MCH_BASE_URL - + "/pay/closeorder"; - /** - * 对账单下载(商户平台) - */ - public static final String MCH_DOWNLOADBILL_URL = MCH_BASE_URL - + "/pay/downloadbill"; - /** - * 退款查询(商户平台) - */ - public static final String MCH_REFUNDQUERY_URL = MCH_BASE_URL - + "/pay/refundquery"; - /** - * 退款申请(商户平台) - */ - public static final String MCH_REFUNDAPPLY_URL = MCH_BASE_URL - + "/secapi/pay/refund"; - /** - * 冲正撤销(商户平台) - */ - public static final String MCH_ORDERREVERSE_URL = MCH_BASE_URL - + "/secapi/pay/reverse"; - /** - * 被扫支付&刷卡支付(商户平台) - */ - public static final String MCH_MICROPAY_URL = MCH_BASE_URL - + "/pay/micropay"; - /** - * 接口上报(商户平台) - */ - public static final String MCH_PAYREPORT_URL = MCH_BASE_URL - + "/payitil/report"; - /** - * 发送现金红包-普通红包(商户平台) - */ - public static final String MCH_REDPACKSEND_URL = MCH_BASE_URL - + "/mmpaymkttransfers/sendredpack"; - /** - * 发送现金红包-裂变红包(商户平台) - */ - public static final String MCH_REDPACK_GROUPSEND_URL = MCH_BASE_URL - + "/mmpaymkttransfers/sendgroupredpack"; - /** - * 查询现金红包(商户平台) - */ - public static final String MCH_REDPACKQUERY_URL = MCH_BASE_URL - + "/mmpaymkttransfers/gethbinfo"; - /** - * 企业向个人付款(商户平台) - */ - public static final String MCH_ENPAYMENT_URL = MCH_BASE_URL - + "/mmpaymkttransfers/promotion/transfers"; - /** - * 企业付款查询(商户平台) - */ - public static final String MCH_ENPAYQUERY_URL = MCH_BASE_URL - + "/mmpaymkttransfers/gettransferinfo"; - /** - * 发放代金券(商户平台) - */ - public static final String MCH_COUPONSEND_URL = MCH_BASE_URL - + "/mmpaymkttransfers/send_coupon"; - /** - * 查询代金券批次信息(商户平台) - */ - public static final String MCH_COUPONSTOCKQUERY_URL = MCH_BASE_URL - + "/mmpaymkttransfers/query_coupon_stock"; - /** - * 查询代金券详细信息(商户平台) - */ - public static final String MCH_COUPONDETAILQUERY_URL = MCH_BASE_URL - + "/promotion/query_coupon"; - /** - * 长链接转换(商户平台) - */ - public static final String MCH_SHORTURL_URL = MCH_BASE_URL - + "/tools/shorturl"; - /** - * 商户平台下native支付的url(模式1) - */ - public static final String MCH_NATIVE_URL = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s"; - - /** - * WAP支付 - * - * @see WAP支付说明 - */ - public static final String MCH_WAP_URL = "weixin://wap/pay?%s"; - /** - * 授权码查询OPENID接口 - */ - public static final String MCH_AUTHCODE_OPENID_URL = MCH_BASE_URL - + "/tools/authcodetoopenid"; -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java index f5c95b83..1562fa6e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java @@ -30,6 +30,7 @@ import com.foxinmy.weixin4j.payment.mch.Redpacket; import com.foxinmy.weixin4j.payment.mch.RedpacketRecord; import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult; import com.foxinmy.weixin4j.payment.mch.RefundRecord; +import com.foxinmy.weixin4j.payment.mch.RefundResult; import com.foxinmy.weixin4j.type.BillType; import com.foxinmy.weixin4j.type.CurrencyType; import com.foxinmy.weixin4j.type.IdQuery; @@ -50,7 +51,7 @@ public class WeixinPayProxy { /** * 微信支付API:js支付、扫码支付等接口 */ - private final PayApi pay3Api; + private final PayApi payApi; /** * 代金券API */ @@ -63,7 +64,7 @@ public class WeixinPayProxy { * 配置相关 */ private final Weixin4jSettings settings; - + /** * 使用weixin4j.properties配置的支付账号信息 */ @@ -79,7 +80,7 @@ public class WeixinPayProxy { */ public WeixinPayProxy(Weixin4jSettings settings) { this.settings = settings; - this.pay3Api = new PayApi(settings.getWeixinPayAccount()); + this.payApi = new PayApi(settings.getWeixinPayAccount()); this.couponApi = new CouponApi(settings.getWeixinPayAccount()); this.cashApi = new CashApi(settings.getWeixinPayAccount()); } @@ -109,7 +110,7 @@ public class WeixinPayProxy { */ public PrePay createPrePay(MchPayPackage payPackage) throws WeixinPayException { - return pay3Api.createPrePay(payPackage); + return payApi.createPrePay(payPackage); } /** @@ -127,7 +128,7 @@ public class WeixinPayProxy { */ public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinPayException { - return pay3Api.createPayRequest(payPackage); + return payApi.createPayRequest(payPackage); } /** @@ -173,7 +174,7 @@ public class WeixinPayProxy { double totalFee, String notifyUrl, String createIp, String attach, Date timeStart, Date timeExpire, String goodsTag, String limitPay) throws WeixinPayException { - return pay3Api.createPayRequest(tradeType, openId, productId, body, + return payApi.createPayRequest(tradeType, openId, productId, body, detail, outTradeNo, totalFee, notifyUrl, createIp, attach, timeStart, timeExpire, goodsTag, limitPay); } @@ -201,7 +202,7 @@ public class WeixinPayProxy { public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createJSPayRequest(openId, body, outTradeNo, totalFee, + return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp); } @@ -226,7 +227,7 @@ public class WeixinPayProxy { * @return 编辑地址请求JSON串 */ public String createAddressRequestJSON(String url, String oauthToken) { - return pay3Api.createAddressRequestJSON(url, oauthToken); + return payApi.createAddressRequestJSON(url, oauthToken); } /** @@ -241,7 +242,7 @@ public class WeixinPayProxy { * href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一 */ public String createNativePayRequestURL(String productId) { - return pay3Api.createNativePayRequestURL(productId); + return payApi.createNativePayRequestURL(productId); } /** @@ -270,7 +271,7 @@ public class WeixinPayProxy { public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createNativePayResponse(productId, body, outTradeNo, + return payApi.createNativePayResponse(productId, body, outTradeNo, totalFee, notifyUrl, createIp); } @@ -300,7 +301,7 @@ public class WeixinPayProxy { public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createNativePayRequest(productId, body, outTradeNo, + return payApi.createNativePayRequest(productId, body, outTradeNo, totalFee, notifyUrl, createIp); } @@ -327,7 +328,7 @@ public class WeixinPayProxy { public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createAppPayRequest(body, outTradeNo, totalFee, + return payApi.createAppPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp); } @@ -354,7 +355,7 @@ public class WeixinPayProxy { public MchPayRequest createWAPPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createWAPPayRequest(body, outTradeNo, totalFee, + return payApi.createWAPPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp); } @@ -378,7 +379,7 @@ public class WeixinPayProxy { */ public Order createMicroPay(String authCode, String body, String orderNo, double orderFee, String createIp) throws WeixinException { - return pay3Api.createMicroPay(authCode, body, orderNo, orderFee, + return payApi.createMicroPay(authCode, body, orderNo, orderFee, createIp); } @@ -397,7 +398,7 @@ public class WeixinPayProxy { */ public Order createMicroPay(MicroPayPackage payPackage) throws WeixinException { - return pay3Api.createMicroPay(payPackage); + return payApi.createMicroPay(payPackage); } /** @@ -418,8 +419,8 @@ public class WeixinPayProxy { * @return 订单详情 * @throws WeixinException */ - public Order orderQuery(IdQuery idQuery) throws WeixinException { - return pay3Api.orderQuery(idQuery); + public Order queryOrder(IdQuery idQuery) throws WeixinException { + return payApi.queryOrder(idQuery); } /** @@ -434,7 +435,7 @@ public class WeixinPayProxy { * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 *

* - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -458,11 +459,11 @@ public class WeixinPayProxy { * @since V3 * @throws WeixinException */ - public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply( - InputStream ca, IdQuery idQuery, String outRefundNo, + public RefundResult applyRefund( + InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee, double refundFee, CurrencyType refundFeeType, String opUserId) throws WeixinException { - return pay3Api.refundApply(ca, idQuery, outRefundNo, totalFee, + return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee, refundFee, refundFeeType, opUserId); } @@ -471,12 +472,12 @@ public class WeixinPayProxy { * * @throws IOException * - * @see {@link #refundApply(InputStream, IdQuery, String, double, double, String,CurrencyType)} + * @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String,CurrencyType)} */ - public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply( + public RefundResult applyRefund( IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException, IOException { - return pay3Api.refundApply( + return payApi.applyRefund( new FileInputStream(settings.getCertificateFile0()), idQuery, outRefundNo, totalFee); } @@ -499,8 +500,8 @@ public class WeixinPayProxy { * @since V3 * @throws WeixinException */ - public RefundRecord refundQuery(IdQuery idQuery) throws WeixinException { - return pay3Api.refundQuery(idQuery); + public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException { + return payApi.queryRefund(idQuery); } /** @@ -524,7 +525,7 @@ public class WeixinPayProxy { */ public File downloadBill(Date billDate, BillType billType) throws WeixinException { - return pay3Api.downloadBill(billDate, billType, settings.getTmpdir0()); + return payApi.downloadBill(billDate, billType, settings.getTmpdir0()); } /** @@ -533,7 +534,7 @@ public class WeixinPayProxy { * 如需实现相同功能请调用退款接口
调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
* - * @param ca + * @param certificate * 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12) * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -543,9 +544,9 @@ public class WeixinPayProxy { * @since V3 * @throws WeixinException */ - public ApiResult reverseOrder(InputStream ca, IdQuery idQuery) + public ApiResult reverseOrder(InputStream certificate, IdQuery idQuery) throws WeixinException { - return pay3Api.reverseOrder(ca, idQuery); + return payApi.reverseOrder(certificate, idQuery); } /** @@ -560,7 +561,7 @@ public class WeixinPayProxy { */ public ApiResult reverseOrder(IdQuery idQuery) throws WeixinException, IOException { - return pay3Api.reverseOrder( + return payApi.reverseOrder( new FileInputStream(settings.getCertificateFile0()), idQuery); } @@ -581,7 +582,7 @@ public class WeixinPayProxy { * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">关闭订单API */ public ApiResult closeOrder(String outTradeNo) throws WeixinException { - return pay3Api.closeOrder(outTradeNo); + return payApi.closeOrder(outTradeNo); } /** @@ -598,7 +599,7 @@ public class WeixinPayProxy { * @throws WeixinException */ public String getPayShorturl(String url) throws WeixinException { - return pay3Api.getShorturl(url); + return payApi.getShorturl(url); } /** @@ -626,14 +627,14 @@ public class WeixinPayProxy { public XmlResult interfaceReport(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time, XmlResult returnXml) throws WeixinException { - return pay3Api.interfaceReport(interfaceUrl, executeTime, outTradeNo, + return payApi.interfaceReport(interfaceUrl, executeTime, outTradeNo, ip, time, returnXml); } /** * 发放代金券(需要证书) * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param couponStockId * 代金券批次id @@ -650,11 +651,11 @@ public class WeixinPayProxy { * href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_3">发放代金券接口 * @throws WeixinException */ - public CouponResult sendCoupon(InputStream ca, String couponStockId, - String partnerTradeNo, String openId, String opUserId) - throws WeixinException { - return couponApi.sendCoupon(ca, couponStockId, partnerTradeNo, openId, - opUserId); + public CouponResult sendCoupon(InputStream certificate, + String couponStockId, String partnerTradeNo, String openId, + String opUserId) throws WeixinException { + return couponApi.sendCoupon(certificate, couponStockId, partnerTradeNo, + openId, opUserId); } /** @@ -706,7 +707,7 @@ public class WeixinPayProxy { /** * 发放红包 企业向微信用户个人发现金红包 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param redpacket * 红包信息 @@ -718,9 +719,9 @@ public class WeixinPayProxy { * href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5">红包接口说明 * @throws WeixinException */ - public RedpacketSendResult sendRedpack(InputStream ca, Redpacket redpacket) - throws WeixinException { - return cashApi.sendRedpack(ca, redpacket); + public RedpacketSendResult sendRedpack(InputStream certificate, + Redpacket redpacket) throws WeixinException { + return cashApi.sendRedpack(certificate, redpacket); } /** @@ -737,7 +738,7 @@ public class WeixinPayProxy { /** * 查询红包记录 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo * 商户发放红包的商户订单号 @@ -748,9 +749,9 @@ public class WeixinPayProxy { * href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6">查询红包接口说明 * @throws WeixinException */ - public RedpacketRecord queryRedpack(InputStream ca, String outTradeNo) - throws WeixinException { - return cashApi.queryRedpack(ca, outTradeNo); + public RedpacketRecord queryRedpack(InputStream certificate, + String outTradeNo) throws WeixinException { + return cashApi.queryRedpack(certificate, outTradeNo); } /** @@ -769,9 +770,9 @@ public class WeixinPayProxy { /** * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 - * @param mpPayment + * @param payment * 付款信息 * @return 付款结果 * @see com.foxinmy.weixin4j.api.CashApi @@ -781,26 +782,26 @@ public class WeixinPayProxy { * href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款 * @throws WeixinException */ - public CorpPaymentResult corpPayment(InputStream ca, CorpPayment payment) - throws WeixinException { - return cashApi.corpPayment(ca, payment); + public CorpPaymentResult sendCorpPayment(InputStream certificate, + CorpPayment payment) throws WeixinException { + return cashApi.sendCorpPayment(certificate, payment); } /** * 企业付款 * - * @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#corpPayment(InputStream, CorpPayment)} + * @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#senCorpPayment(InputStream, CorpPayment)} */ - public CorpPaymentResult corpPayment(CorpPayment payment) + public CorpPaymentResult sendCorpPayment(CorpPayment payment) throws WeixinException, IOException { - return cashApi.corpPayment( + return cashApi.sendCorpPayment( new FileInputStream(settings.getCertificateFile0()), payment); } /** * 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果 * - * @param ca + * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo * 商户调用企业付款API时使用的商户订单号 @@ -811,9 +812,9 @@ public class WeixinPayProxy { * href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询 * @throws WeixinException */ - public CorpPaymentRecord queryCorpPayment(InputStream ca, String outTradeNo) - throws WeixinException { - return cashApi.queryCorpPayment(ca, outTradeNo); + public CorpPaymentRecord queryCorpPayment(InputStream certificate, + String outTradeNo) throws WeixinException { + return cashApi.queryCorpPayment(certificate, outTradeNo); } /** @@ -842,7 +843,7 @@ public class WeixinPayProxy { * @throws WeixinException */ public OpenIdResult authCode2openId(String authCode) throws WeixinException { - return pay3Api.authCode2openId(authCode); + return payApi.authCode2openId(authCode); } public final static String VERSION = "1.6.7"; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java index 881b3a24..7513d273 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java @@ -44,7 +44,7 @@ public class APPPayRequest extends AbstractPayRequest { PayRequest payRequest = toRequestObject(); String sign = DigestUtil.MD5( String.format("%s&key=%s", - MapUtil.toJoinString(payRequest, false, true, null), + MapUtil.toJoinString(payRequest, false, true), getPayAccount().getPaySignKey())).toUpperCase(); StringBuilder content = new StringBuilder(); content.append(""); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java index 5fc25553..1a975e4e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java @@ -1,15 +1,19 @@ package com.foxinmy.weixin4j.payment.mch; import com.foxinmy.weixin4j.model.WeixinPayAccount; +import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; +import com.foxinmy.weixin4j.sign.WeixinSignature; public abstract class AbstractPayRequest implements MchPayRequest { private final String prePayId; private final WeixinPayAccount payAccount; + protected final WeixinSignature weixinSignature; public AbstractPayRequest(String prePayId, WeixinPayAccount payAccount) { this.prePayId = prePayId; this.payAccount = payAccount; + this.weixinSignature = new WeixinPaymentSignature(payAccount.getPaySignKey()); } @Override diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java index c570d17b..e2921f33 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java @@ -5,7 +5,6 @@ import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.payment.PayRequest; import com.foxinmy.weixin4j.type.SignType; import com.foxinmy.weixin4j.type.TradeType; -import com.foxinmy.weixin4j.util.DigestUtil; /** * 公众号JS支付:get_brand_wcpay_request
@@ -29,7 +28,7 @@ public class JSAPIPayRequest extends AbstractPayRequest { public JSAPIPayRequest(String prePayId, WeixinPayAccount payAccount) { super(prePayId, payAccount); } - + @Override public TradeType getTradeType() { return TradeType.JSAPI; @@ -40,8 +39,7 @@ public class JSAPIPayRequest extends AbstractPayRequest { PayRequest payRequest = new PayRequest(getPayAccount().getId(), "prepay_id=" + getPrePayId()); payRequest.setSignType(SignType.MD5); - payRequest.setPaySign(DigestUtil.paysignMd5(payRequest, getPayAccount() - .getPaySignKey())); + payRequest.setPaySign(weixinSignature.sign(payRequest)); return payRequest; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NativePayResponse.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NativePayResponse.java index 20577d18..54bba89c 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NativePayResponse.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NativePayResponse.java @@ -9,7 +9,7 @@ import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.exception.WeixinPayException; import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.WeixinPayAccount; -import com.foxinmy.weixin4j.util.DigestUtil; +import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; import com.foxinmy.weixin4j.util.RandomUtil; /** @@ -67,7 +67,8 @@ public class NativePayResponse extends ApiResult { this.setAppId(weixinAccount.getId()); this.setNonceStr(RandomUtil.generateString(16)); this.prepayId = prepayId; - this.setSign(DigestUtil.paysignMd5(this, weixinAccount.getPaySignKey())); + this.setSign(new WeixinPaymentSignature(weixinAccount.getPaySignKey()) + .sign(this)); } public String getPrepayId() { diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java index 1a7514fe..692b72d6 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java @@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.payment.mch; import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.payment.PayRequest; -import com.foxinmy.weixin4j.payment.PayURLConsts; import com.foxinmy.weixin4j.type.TradeType; import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.MapUtil; @@ -46,12 +45,13 @@ public class WAPPayRequest extends AbstractPayRequest { @Override public String toRequestString() { PayRequest payRequest = toRequestObject(); - String original = MapUtil.toJoinString(payRequest, true, true, null); + String original = MapUtil.toJoinString(payRequest, true, true); String sign = DigestUtil.MD5( String.format("%s&key=%s", original, getPayAccount() .getPaySignKey())).toUpperCase(); - return String.format(PayURLConsts.MCH_WAP_URL, URLEncodingUtil - .encoding(String.format("%s&sign=%s", original, sign), + return String.format("weixin://wap/pay?%s", + URLEncodingUtil.encoding( + String.format("%s&sign=%s", original, sign), Consts.UTF_8, true)); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/weixin.properties b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/weixin.properties new file mode 100644 index 00000000..1a44e97c --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/weixin.properties @@ -0,0 +1,51 @@ +# \u5fae\u4fe1\u5546\u6237\u5e73\u53f0\u6587\u6863\u8bf4\u660e +# https://pay.weixin.qq.com/ +# https://pay.weixin.qq.com/wiki/doc/api/index.php +# ---------------------------------------------------------------------------- + +mch_base_url=https://api.mch.weixin.qq.com + +# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305 +redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack +# \u53d1\u9001\u73b0\u91d1\u88c2\u53d8\u7ea2\u5305 +groupredpack_send_uri={mch_base_url}/mmpaymkttransfers/sendgroupredpack +# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305 +redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo +# \u7edf\u4e00\u8ba2\u5355\u751f\u6210 +order_create_uri={mch_base_url}/pay/unifiedorder +# \u88ab\u626b\u652f\u4ed8 +micropay_uri={mch_base_url}/pay/micropay +# \u8ba2\u5355\u67e5\u8be2 +order_query_uri={mch_base_url}/pay/orderquery +# \u5173\u95ed\u8ba2\u5355 +order_close_uri={mch_base_url}/pay/closeorder +# \u5bf9\u8d26\u5355\u4e0b\u8f7d +downloadbill_uri={mch_base_url}/pay/downloadbill +# \u9000\u6b3e\u67e5\u8be2 +refund_query_uri={mch_base_url}/pay/refundquery +# \u9000\u6b3e\u7533\u8bf7 +refund_apply_uri={mch_base_url}/secapi/pay/refund +# \u51b2\u6b63\u64a4\u9500 +order_reverse_uri={mch_base_url}/secapi/pay/reverse +# \u957f\u94fe\u63a5\u8f6c\u6362 +longurl_convert_uri={mch_base_url}/tools/shorturl +# \u53d1\u653e\u4ee3\u91d1\u5238 +coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon +# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f +couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock +# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f +coupondetail_query_uri={mch_base_url}/promotion/query_coupon +# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305 +redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack +# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305 +redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo +# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e +corppayment_send_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers +# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2 +corppayment_query_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo +# \u63a5\u53e3\u4e0a\u62a5 +interface_report_uri={mch_base_url}/payitil/report +# \u6388\u6743\u7801\u67e5\u8be2OPENID\u63a5\u53e3 +authcode_openid_uri={mch_base_url}/tools/authcodetoopenid +# native\u652f\u4ed8url(\u6a21\u5f0f1) +native_pay_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/AbstractWeixinSignature.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/AbstractWeixinSignature.java new file mode 100644 index 00000000..a244fd86 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/AbstractWeixinSignature.java @@ -0,0 +1,43 @@ +package com.foxinmy.weixin4j.sign; + +import com.foxinmy.weixin4j.util.MapUtil; + +/** + * 微信签名 + * + * @className AbstractWeixinSignature + * @author jy + * @date 2016年3月26日 + * @since JDK 1.6 + * @see + */ +public abstract class AbstractWeixinSignature implements WeixinSignature { + /** + * 是否编码 + * + * @return + */ + public boolean encoder() { + return false; + } + + /** + * 是否转换小写 + * + * @return + */ + public boolean lowerCase() { + return false; + } + + /** + * 拼接字符串 + * + * @param obj + * @return + */ + protected StringBuilder join(Object obj) { + return new StringBuilder(MapUtil.toJoinString(obj, encoder(), + lowerCase())); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinPaymentSignature.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinPaymentSignature.java new file mode 100644 index 00000000..46387080 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinPaymentSignature.java @@ -0,0 +1,29 @@ +package com.foxinmy.weixin4j.sign; + +import com.foxinmy.weixin4j.util.DigestUtil; + +/** + * 微信支付签名实现 + * + * @className WeixinPaymentSignature + * @author jy + * @date 2016年3月26日 + * @since JDK 1.6 + * @see + */ +public class WeixinPaymentSignature extends AbstractWeixinSignature { + /** + * 支付密钥 + */ + private final String paySignKey; + + public WeixinPaymentSignature(String paySignKey) { + this.paySignKey = paySignKey; + } + + @Override + public String sign(Object obj) { + StringBuilder sb = join(obj).append("&key=").append(paySignKey); + return DigestUtil.MD5(sb.toString()).toUpperCase(); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinSignature.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinSignature.java new file mode 100644 index 00000000..c71617ca --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/sign/WeixinSignature.java @@ -0,0 +1,35 @@ +package com.foxinmy.weixin4j.sign; + + +/** + * 微信签名 + * + * @className WeixinSignature + * @author jy + * @date 2016年3月26日 + * @since JDK 1.7 + * @see + */ +public interface WeixinSignature { + /** + * 是否编码 + * + * @return + */ + public boolean encoder(); + + /** + * 是否转换小写 + * + * @return + */ + public boolean lowerCase(); + + /** + * 签名 + * + * @param obj + * @return + */ + public String sign(Object obj); +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/SignType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/SignType.java index 15aabcd9..7a458d83 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/SignType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/SignType.java @@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.type; /** * 签名类型 + * * @className SignType * @author jy * @date 2014年11月5日 @@ -9,5 +10,5 @@ package com.foxinmy.weixin4j.type; * @see */ public enum SignType { - SHA1,MD5 + SHA1, MD5, HMAC$SHA256 } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DigestUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DigestUtil.java index bb4263ed..e2bb5a34 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DigestUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DigestUtil.java @@ -1,16 +1,9 @@ package com.foxinmy.weixin4j.util; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.Map; import com.foxinmy.weixin4j.model.Consts; -import com.foxinmy.weixin4j.payment.mch.NativePayNotify; -import com.foxinmy.weixin4j.xml.XmlStream; /** * 签名工具类 @@ -66,81 +59,4 @@ public final class DigestUtil { byte[] data = StringUtil.getBytesUtf8(content); return HexUtil.encodeHexString(getDigest(Consts.MD5).digest(data)); } - - /** - * md5签名(一般用于V3.x支付接口) - * - * @param obj - * 签名对象 - * @param paySignKey - * 支付API的密钥 - * @return - */ - public static String paysignMd5(Object obj, String paySignKey) { - StringBuilder sb = new StringBuilder(); - // a--->string1 - sb.append(MapUtil.toJoinString(obj, false, false, null)); - // b---> - // 在 string1 最后拼接上 key=paternerKey 得到 stringSignTemp 字符串,并 对 - // stringSignTemp 进行 md5 运算 - // 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。 - sb.append("&key=").append(paySignKey); - return MD5(sb.toString()).toUpperCase(); - } - - /** - * sha签名(一般用于V2.x支付接口) - * - * @param obj - * 签名对象 - * @param paySignKey - * 支付API的密钥请注意排序放进去的是put("appKey", - * paySignKey) - * @return - */ - public static String paysignSha(Object obj, String paySignKey) { - Map extra = new HashMap(); - if (StringUtil.isNotBlank(paySignKey)) { - extra.put("appKey", paySignKey); - } - return SHA1(MapUtil.toJoinString(obj, false, true, extra)); - } - - /** - * package拼接签名(一般用于V2.x支付接口) - * - * @param signObj - * 签名对象 如 PayPackageV2 - * @param signKey - * 签名key - * @return - */ - public static String packageSign(Object signObj, String signKey) { - StringBuilder sb = new StringBuilder(); - // a.对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) 后, - // 使用 URL 键值 对的格式(即 key1=value1&key2=value2...)拼接成字符串 string1 - // 注意:值为空的参数不参与签名 - sb.append(MapUtil.toJoinString(signObj, false, false, null)); - // b---> - // 在 string1 最后拼接上 key=signKey 得到 stringSignTemp 字符串,并 对 - // stringSignTemp 进行 md5 运算 - // 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。 - sb.append("&key=").append(signKey); - // c---> & d----> - String sign = DigestUtil.MD5(sb.toString()).toUpperCase(); - sb.delete(0, sb.length()); - // c.对传入参数中所有键值对的 value 进行 urlencode 转码后重新拼接成字符串 string2 - sb.append(MapUtil.toJoinString(signObj, true, false, null)) - .append("&sign=").append(sign); - - return sb.toString(); - } - - public static void main(String[] args) throws FileNotFoundException { - NativePayNotify notify = XmlStream.fromXML(new FileInputStream( - new File("/Users/jy/Downloads/weixin4j.xml")), - NativePayNotify.class); - notify.setSign(null); - System.err.println(paysignMd5(notify, "GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ")); - } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MapUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MapUtil.java index 89a95eb8..0eef204d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MapUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MapUtil.java @@ -35,7 +35,7 @@ public class MapUtil { * @return */ public static String toJoinString(Object object, boolean encoder, - boolean lowerCase, Map extra) { + boolean lowerCase) { Map map = new HashMap(); JSONObject obj = null; if (object instanceof String) { @@ -46,14 +46,11 @@ public class MapUtil { for (String key : obj.keySet()) { map.put(key, obj.getString(key)); } - if (extra != null && !extra.isEmpty()) { - map.putAll(extra); - } return toJoinString(map, encoder, lowerCase); } /** - * 连接字符串 + * 拼接字符串 * * @param map * 对象 diff --git a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/CashTest.java b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/CashTest.java index 01f25a1e..1054a53d 100644 --- a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/CashTest.java +++ b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/CashTest.java @@ -43,17 +43,17 @@ public class CashTest extends PayTest { } @Test - public void mpPayment() throws WeixinException, IOException { + public void sendCorpPayment() throws WeixinException, IOException { CorpPayment payment = new CorpPayment("MP001", "ofW1gwok9vZIyle0YbA-eQe83Uk8", MPPaymentCheckNameType.NO_CHECK, "企业付款测试", 1d, "127.0.0.1"); - CorpPaymentResult result = PAY.corpPayment(new FileInputStream(caFile), + CorpPaymentResult result = PAY.sendCorpPayment(new FileInputStream(caFile), payment); System.err.println(result); } @Test - public void mchPaymentQuery() throws WeixinException, IOException { + public void queryCorpPayment() throws WeixinException, IOException { System.err.println(PAY.queryCorpPayment(new FileInputStream(caFile), "MP001")); } diff --git a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java index 1c6a76f5..94498554 100644 --- a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java +++ b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java @@ -18,10 +18,13 @@ import com.foxinmy.weixin4j.payment.mch.ApiResult; import com.foxinmy.weixin4j.payment.mch.MchPayPackage; import com.foxinmy.weixin4j.payment.mch.Order; import com.foxinmy.weixin4j.payment.mch.PrePay; +import com.foxinmy.weixin4j.payment.mch.RefundRecord; +import com.foxinmy.weixin4j.payment.mch.RefundResult; +import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; +import com.foxinmy.weixin4j.sign.WeixinSignature; import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdType; import com.foxinmy.weixin4j.type.TradeType; -import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.Weixin4jSettings; /** @@ -34,10 +37,13 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings; * @see */ public class PayTest { - protected final static WeixinPayProxy PAY; protected final static WeixinPayAccount ACCOUNT; + protected final static WeixinSignature SIGNATURE; + protected final static WeixinPayProxy PAY; + static { ACCOUNT = new WeixinPayAccount("appid", "paySignKey", "mchid"); + SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey()); PAY = new WeixinPayProxy(new Weixin4jSettings(ACCOUNT)); } /** @@ -46,35 +52,34 @@ public class PayTest { protected File caFile = new File("证书文件:*.p12"); @Test - public void orderQueryV3() throws WeixinException { - Order order = PAY.orderQuery(new IdQuery("BY2016010800025", + public void queryOrder() throws WeixinException { + Order order = PAY.queryOrder(new IdQuery("BY2016010800025", IdType.TRADENO)); System.err.println(order); String sign = order.getSign(); order.setSign(null); - String valiSign = DigestUtil.paysignMd5(order, ACCOUNT.getPaySignKey()); + String valiSign = SIGNATURE.sign(order); System.err .println(String.format("sign=%s,valiSign=%s", sign, valiSign)); Assert.assertEquals(valiSign, sign); } @Test - public void refundQueryV3() throws WeixinException { - com.foxinmy.weixin4j.payment.mch.RefundRecord record = PAY - .refundQuery(new IdQuery("TT_1427183696238", IdType.TRADENO)); + public void queryRefund() throws WeixinException { + RefundRecord record = PAY.queryRefund(new IdQuery("TT_1427183696238", + IdType.TRADENO)); System.err.println(record); // 这里的验证签名需要把details循环拼接 String sign = record.getSign(); record.setSign(null); - String valiSign = DigestUtil - .paysignMd5(record, ACCOUNT.getPaySignKey()); + String valiSign = SIGNATURE.sign(record); System.err .println(String.format("sign=%s,valiSign=%s", sign, valiSign)); Assert.assertEquals(valiSign, sign); } @Test - public void downbillV3() throws WeixinException { + public void downbill() throws WeixinException { Calendar c = Calendar.getInstance(); System.err.println(c.getTime()); c.set(Calendar.YEAR, 2015); @@ -86,24 +91,22 @@ public class PayTest { } @Test - public void refundV3() throws WeixinException, IOException { + public void refund() throws WeixinException, IOException { IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO); - com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY.refundApply( - new FileInputStream(caFile), idQuery, - "TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, null, - "10020674"); + RefundResult result = PAY.applyRefund(new FileInputStream(caFile), + idQuery, "TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, + null, "10020674"); System.err.println(result); String sign = result.getSign(); result.setSign(null); - String valiSign = DigestUtil - .paysignMd5(result, ACCOUNT.getPaySignKey()); + String valiSign = SIGNATURE.sign(result); System.err .println(String.format("sign=%s,valiSign=%s", sign, valiSign)); Assert.assertEquals(valiSign, sign); } @Test - public void nativeV3() throws WeixinException { + public void nativePay() throws WeixinException { MchPayPackage payPackageV3 = new MchPayPackage(ACCOUNT, "oyFLst1bqtuTcxK-ojF8hOGtLQao", "native测试", "T0001", 0.1d, "notify_url", "127.0.0.1", TradeType.NATIVE); @@ -123,8 +126,7 @@ public class PayTest { System.err.println(result); String sign = result.getSign(); result.setSign(null); - String valiSign = DigestUtil - .paysignMd5(result, ACCOUNT.getPaySignKey()); + String valiSign = SIGNATURE.sign(result); System.err .println(String.format("sign=%s,valiSign=%s", sign, valiSign)); Assert.assertEquals(valiSign, sign); diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/PayOldApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/PayOldApi.java index dcb3e0ce..bf5dfa1a 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/PayOldApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/PayOldApi.java @@ -34,12 +34,15 @@ import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor; import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.WeixinPayOldAccount; -import com.foxinmy.weixin4j.mp.payment.v2.OrderV2; -import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2; -import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2; -import com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2; +import com.foxinmy.weixin4j.mp.oldpayment.OrderV2; +import com.foxinmy.weixin4j.mp.oldpayment.PayPackageV2; +import com.foxinmy.weixin4j.mp.oldpayment.RefundRecordV2; +import com.foxinmy.weixin4j.mp.oldpayment.RefundResultV2; +import com.foxinmy.weixin4j.mp.oldpayment.WeixinOldPaymentSignature; import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator; import com.foxinmy.weixin4j.payment.PayRequest; +import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; +import com.foxinmy.weixin4j.sign.WeixinSignature; import com.foxinmy.weixin4j.token.FileTokenStorager; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenStorager; @@ -58,7 +61,7 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer; /** * V2老支付API * - * @className Pay2Api + * @className PayOldApi * @author jy * @date 2014年10月28日 * @since JDK 1.6 @@ -66,8 +69,10 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer; */ public class PayOldApi extends MpApi { - private final WeixinPayOldAccount payAccount; + private final WeixinPayOldAccount weixinAccount; private final TokenHolder tokenHolder; + private final WeixinSignature weixinMD5Signature; + private final WeixinOldPaymentSignature weixinOldSignature; /** * 默认使用weixin4j.properties配置信息 @@ -90,14 +95,19 @@ public class PayOldApi extends MpApi { WeixinPayOldAccount.class), tokenStorager); } - public PayOldApi(WeixinPayOldAccount payAccount, TokenStorager tokenStorager) { - this.payAccount = payAccount; + public PayOldApi(WeixinPayOldAccount weixinAccount, + TokenStorager tokenStorager) { + this.weixinAccount = weixinAccount; this.tokenHolder = new TokenHolder(new WeixinTokenCreator( - payAccount.getId(), payAccount.getSecret()), tokenStorager); + weixinAccount.getId(), weixinAccount.getSecret()), + tokenStorager); + this.weixinMD5Signature = new WeixinPaymentSignature( + weixinAccount.getPartnerKey()); + this.weixinOldSignature = new WeixinOldPaymentSignature(); } public WeixinPayOldAccount getPayAccount() { - return this.payAccount; + return this.weixinAccount; } /** @@ -162,10 +172,10 @@ public class PayOldApi extends MpApi { payPackage.setProductFee(productFee); payPackage.setGoodsTag(goodsTag); PayRequest payRequest = new PayRequest(getPayAccount().getId(), - DigestUtil.packageSign(payPackage, getPayAccount() + weixinOldSignature.sign(payPackage, getPayAccount() .getPartnerKey())); - payRequest.setPaySign(DigestUtil.paysignSha(payRequest, getPayAccount() - .getPaySignKey())); + payRequest.setPaySign(weixinOldSignature.sign(payRequest, + getPayAccount().getPaySignKey())); payRequest.setSignType(SignType.SHA1); return JSON.toJSONString(payRequest); } @@ -186,9 +196,9 @@ public class PayOldApi extends MpApi { map.put("noncestr", noncestr); map.put("productid", productId); map.put("appkey", getPayAccount().getPaySignKey()); - String sign = DigestUtil.paysignSha(map, null); - String ordernative_v2_uri = getRequestUri("ordernative_v2_uri"); - return String.format(ordernative_v2_uri, sign, getPayAccount().getId(), + String sign = weixinOldSignature.sign(map); + String nativepay_uri = getRequestUri("nativepay_old_uri"); + return String.format(nativepay_uri, sign, getPayAccount().getId(), productId, timestamp, noncestr); } @@ -198,12 +208,12 @@ public class PayOldApi extends MpApi { * @param idQuery * 订单号 * @return 订单信息 - * @see com.foxinmy.weixin4j.mp.payment.v2.OrderV2 + * @see com.foxinmy.weixin4j.mp.oldpayment.OrderV2 * @since V2 * @throws WeixinException */ - public OrderV2 orderQuery(IdQuery idQuery) throws WeixinException { - String orderquery_uri = getRequestUri("orderquery_v2_uri"); + public OrderV2 queryOrder(IdQuery idQuery) throws WeixinException { + String orderquery_uri = getRequestUri("orderquery_old_uri"); Token token = tokenHolder.getToken(); StringBuilder sb = new StringBuilder(); sb.append(idQuery.getType().getName()).append("=") @@ -221,7 +231,7 @@ public class PayOldApi extends MpApi { obj.put("appkey", getPayAccount().getPaySignKey()); obj.put("package", sb.toString()); obj.put("timestamp", timestamp); - String signature = DigestUtil.paysignSha(obj, null); + String signature = weixinOldSignature.sign(obj); obj.clear(); obj.put("appid", getPayAccount().getId()); @@ -251,7 +261,7 @@ public class PayOldApi extends MpApi { * 败后重新提交,要采用原来的 out_refund_no。总退款金额不能超过用户实际支付金额。
*

* - * @param caFile + * @param certificate * 证书文件(V2版本后缀为*.pfx) * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -268,18 +278,17 @@ public class PayOldApi extends MpApi { * 如 opUserPasswd * * @return 退款申请结果 - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2 + * @see com.foxinmy.weixin4j.mp.oldpayment.RefundResultV2 * @since V2 * @throws WeixinException */ - protected RefundResultV2 refundApply(File caFile, IdQuery idQuery, - String outRefundNo, double totalFee, double refundFee, - String opUserId, Map mopara) throws WeixinException { - String refund_uri = getRequestUri("refundapply_v2_uri"); + protected RefundResultV2 applyRefund(InputStream certificate, + IdQuery idQuery, String outRefundNo, double totalFee, + double refundFee, String opUserId, Map mopara) + throws WeixinException { + String refund_uri = getRequestUri("refundapply_old_uri"); WeixinResponse response = null; - InputStream ca = null; try { - ca = new FileInputStream(caFile); Map map = new HashMap(); map.put("input_charset", Consts.UTF_8.name()); // 版本号 @@ -298,24 +307,23 @@ public class PayOldApi extends MpApi { if (mopara != null && !mopara.isEmpty()) { map.putAll(mopara); } - String sign = DigestUtil.paysignMd5(map, getPayAccount() - .getPartnerKey()); + String sign = weixinMD5Signature.sign(map); map.put("sign", sign.toUpperCase()); SSLContext ctx = null; KeyStore ks = null; String jksPwd = ""; File jksFile = new File(String.format("%s/tenpay_cacert.jks", - caFile.getParent())); + Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir", + System.getProperty("java.io.tmpdir")))); // create jks ca if (!jksFile.exists()) { CertificateFactory cf = CertificateFactory - .getInstance(com.foxinmy.weixin4j.model.Consts.X509); + .getInstance(Consts.X509); java.security.cert.Certificate cert = cf .generateCertificate(PayOldApi.class .getResourceAsStream("cacert.pem")); - ks = KeyStore - .getInstance(com.foxinmy.weixin4j.model.Consts.JKS); + ks = KeyStore.getInstance(Consts.JKS); ks.load(null, null); ks.setCertificateEntry("tenpay", cert); FileOutputStream os = new FileOutputStream(jksFile); @@ -324,20 +332,20 @@ public class PayOldApi extends MpApi { } // load jks ca TrustManagerFactory tmf = TrustManagerFactory - .getInstance(com.foxinmy.weixin4j.model.Consts.SunX509); - ks = KeyStore.getInstance(com.foxinmy.weixin4j.model.Consts.JKS); + .getInstance(Consts.SunX509); + ks = KeyStore.getInstance(Consts.JKS); FileInputStream is = new FileInputStream(jksFile); ks.load(is, jksPwd.toCharArray()); tmf.init(ks); is.close(); // load pfx ca KeyManagerFactory kmf = KeyManagerFactory - .getInstance(com.foxinmy.weixin4j.model.Consts.SunX509); - ks = KeyStore.getInstance(com.foxinmy.weixin4j.model.Consts.PKCS12); - ks.load(ca, getPayAccount().getPartnerId().toCharArray()); + .getInstance(Consts.SunX509); + ks = KeyStore.getInstance(Consts.PKCS12); + ks.load(certificate, getPayAccount().getPartnerId().toCharArray()); kmf.init(ks, getPayAccount().getPartnerId().toCharArray()); - ctx = SSLContext.getInstance(com.foxinmy.weixin4j.model.Consts.TLS); + ctx = SSLContext.getInstance(Consts.TLS); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); @@ -349,9 +357,9 @@ public class PayOldApi extends MpApi { } catch (Exception e) { throw new WeixinException(e); } finally { - if (ca != null) { + if (certificate != null) { try { - ca.close(); + certificate.close(); } catch (IOException e) { ; } @@ -364,7 +372,7 @@ public class PayOldApi extends MpApi { /** * 退款申请 * - * @param caFile + * @param certificate * 证书文件(V2版本后缀为*.pfx) * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -379,21 +387,21 @@ public class PayOldApi extends MpApi { * 操作员帐号, 默认为商户号 * @param opUserPasswd * 操作员密码,默认为商户后台登录密码 - * @see {@link #refundApply(File, IdQuery, String, double, double, String, Map)} + * @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String, Map)} */ - public RefundResultV2 refundApply(File caFile, IdQuery idQuery, + public RefundResultV2 applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee, double refundFee, String opUserId, String opUserPasswd) throws WeixinException { Map mopara = new HashMap(); mopara.put("op_user_passwd", DigestUtil.MD5(opUserPasswd)); - return refundApply(caFile, idQuery, outRefundNo, totalFee, refundFee, - opUserId, mopara); + return applyRefund(certificate, idQuery, outRefundNo, totalFee, + refundFee, opUserId, mopara); } /** * 退款申请 * - * @param caFile + * @param certificate * 证书文件(V2版本后缀为*.pfx) * @param idQuery * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: @@ -417,10 +425,10 @@ public class PayOldApi extends MpApi { * @param refundType * 为空或者填 1:商户号余额退款;2:现金帐号 退款;3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。使用 2 或 * 3 时,需联系财 付通开通此功能 - * @see {@link #refundApply(File, IdQuery, String, double, double, String, Map)} + * @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String, Map)} * @return 退款结果 */ - public RefundResultV2 refundApply(File caFile, IdQuery idQuery, + public RefundResultV2 applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee, double refundFee, String opUserId, String opUserPasswd, String recvUserId, String reccvUserName, RefundType refundType) throws WeixinException { @@ -435,8 +443,8 @@ public class PayOldApi extends MpApi { if (refundType != null) { mopara.put("refund_type", Integer.toString(refundType.getVal())); } - return refundApply(caFile, idQuery, outRefundNo, totalFee, refundFee, - opUserId, mopara); + return applyRefund(certificate, idQuery, outRefundNo, totalFee, + refundFee, opUserId, mopara); } /** @@ -474,7 +482,7 @@ public class PayOldApi extends MpApi { if (file.exists()) { return file; } - String downloadbill_uri = getRequestUri("downloadbill_v2_uri"); + String downloadbill_uri = getRequestUri("downloadbill_old_uri"); Map map = new LinkedHashMap(); map.put("spid", getPayAccount().getPartnerId()); @@ -523,19 +531,18 @@ public class PayOldApi extends MpApi { * 四个参数必填一个,优先级为: * refund_id>out_refund_no>transaction_id>out_trade_no * @return 退款记录 - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2 - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundDetailV2 + * @see com.foxinmy.weixin4j.mp.oldpayment.RefundRecordV2 + * @see com.foxinmy.weixin4j.mp.oldpayment.RefundDetailV2 * @since V2 * @throws WeixinException */ - public RefundRecordV2 refundQuery(IdQuery idQuery) throws WeixinException { - String refundquery_uri = getRequestUri("refundquery_v2_uri"); + public RefundRecordV2 queryRefund(IdQuery idQuery) throws WeixinException { + String refundquery_uri = getRequestUri("refundquery_old_uri"); Map map = new HashMap(); map.put("input_charset", Consts.UTF_8.name()); map.put("partner", getPayAccount().getPartnerId()); map.put(idQuery.getType().getName(), idQuery.getId()); - String sign = DigestUtil.paysignMd5(map, getPayAccount() - .getPartnerKey()); + String sign = weixinMD5Signature.sign(map); map.put("sign", sign.toLowerCase()); WeixinResponse response = weixinExecutor.get(refundquery_uri, map); return ListsuffixResultDeserializer.deserialize(response.getAsString(), @@ -561,7 +568,7 @@ public class PayOldApi extends MpApi { public JsonResult deliverNotify(String openId, String transid, String outTradeNo, boolean status, String statusMsg) throws WeixinException { - String delivernotify_uri = getRequestUri("delivernotify_uri"); + String delivernotify_uri = getRequestUri("delivernotify_old_uri"); Token token = tokenHolder.getToken(); Map map = new HashMap(); @@ -573,7 +580,7 @@ public class PayOldApi extends MpApi { map.put("deliver_timestamp", DateUtil.timestamp2string()); map.put("deliver_status", status ? "1" : "0"); map.put("deliver_msg", statusMsg); - map.put("app_signature", DigestUtil.paysignSha(map, null)); + map.put("app_signature", weixinOldSignature.sign(map)); map.put("sign_method", SignType.SHA1.name().toLowerCase()); WeixinResponse response = weixinExecutor.post( @@ -594,11 +601,10 @@ public class PayOldApi extends MpApi { */ public JsonResult updateFeedback(String openId, String feedbackId) throws WeixinException { - String payfeedback_update_uri = getRequestUri("payfeedback_update_uri"); + String payfeedback_uri = getRequestUri("payfeedback_old_uri"); Token token = tokenHolder.getToken(); WeixinResponse response = weixinExecutor.get(String.format( - payfeedback_update_uri, token.getAccessToken(), openId, - feedbackId)); + payfeedback_uri, token.getAccessToken(), openId, feedbackId)); return response.getAsJsonResult(); } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties index 68c1e573..088a9da5 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties @@ -6,12 +6,10 @@ api_base_url=https://api.weixin.qq.com api_cgi_url={api_base_url}/cgi-bin mp_base_url=https://mp.weixin.qq.com/cgi-bin -mch_base_url=https://api.mch.weixin.qq.com tenpay_base_url=http://mch.tenpay.com tenpay_ssl_base_url=https://mch.tenpay.com tenpay_gw_base_url=https://gw.tenpay.com - # \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f sns_user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect #open_user_auth_uri=https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect @@ -107,7 +105,6 @@ kfsession_list_uri={api_base_url}/customservice/kfsession/getsessionlist?access_ kfsession_wait_uri={api_base_url}/customservice/kfsession/getwaitcase?access_token=%s # \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5 shorturl_uri={api_cgi_url}/shorturl?access_token=%s -p_shorturl_uri={mch_base_url}/tools/shorturl # \u8bbe\u7f6e\u5907\u6ce8\u540d updateremark_uri={api_cgi_url}/user/info/updateremark?access_token=%s # \u8bbe\u7f6e\u6a21\u677f\u6d88\u606f\u6240\u5904\u884c\u4e1a @@ -126,48 +123,26 @@ template_send_uri={api_cgi_url}/message/template/send?access_token=%s semantic_uri={api_base_url}/semantic/semproxy/search?access_token=%s # \u5fae\u4fe1\u670d\u52a1\u5730\u5740 getcallbackip_uri={api_cgi_url}/getcallbackip?access_token=%s - -# v2\u8ba2\u5355\u67e5\u8be2 -orderquery_v2_uri={api_base_url}/pay/orderquery?access_token=%s -# v2native\u652f\u4ed8 -ordernative_v2_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&nocestr=%s\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc53\udbff\udc53\udbff\udc53\udbff\udc53\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udc76\udbff\udc76\udbff\udc76\udbff\udc76\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcde\udbff\udcde\udbff\udcde\udbff\udcde\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udcdf\udbff\udcdf\udbff\udcdf\udbff\udcdf\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udc77\udbff\udc77\udbff\udc77\udbff\udc77\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc68\udbff\udc68\udbff\udc68\udbff\udc68\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd -# \u53d1\u8d27\u901a\u77e5 -delivernotify_uri={api_base_url}/pay/delivernotify?access_token=%s -# \u7ef4\u6743\u5904\u7406 -payfeedback_update_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s -# v2\u5bf9\u8d26\u5355\u4e0b\u8f7d -downloadbill_v2_uri={tenpay_base_url}/cgi-bin/mchdown_real_new.cgi -# v2\u9000\u6b3e\u67e5\u8be2 -refundquery_v2_uri={tenpay_gw_base_url}/gateway/normalrefundquery.xml -# v2\u9000\u6b3e\u7533\u8bf7 -refundapply_v2_uri={tenpay_ssl_base_url}/refundapi/gateway/refund.xml - -# \u8ba2\u5355\u67e5\u8be2 -orderquery_v3_uri={mch_base_url}/pay/orderquery -# \u5173\u95ed\u8ba2\u5355 -closeorder_uri={mch_base_url}/pay/closeorder -# \u5bf9\u8d26\u5355\u4e0b\u8f7d -downloadbill_v3_uri={mch_base_url}/pay/downloadbill -# \u9000\u6b3e\u67e5\u8be2 -refundquery_v3_uri={mch_base_url}/pay/refundquery -# \u9000\u6b3e\u7533\u8bf7 -refund_v3_uri={mch_base_url}/secapi/pay/refund -# \u51b2\u6b63\u64a4\u9500 -reverse_uri={mch_base_url}/secapi/pay/reverse -# \u88ab\u626b\u652f\u4ed8 -micropay_uri={mch_base_url}/pay/micropay -# \u63a5\u53e3\u4e0a\u62a5 -pay_report_uri={mch_base_url}/payitil/report - -# \u7edf\u4e00\u8ba2\u5355\u751f\u6210 -unifiedorder_uri={mch_base_url}/pay/unifiedorder -# native\u652f\u4ed8\u94fe\u63a5 -nativepay_v2_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s -nativepay_v3_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s - # \u6570\u636e\u7edf\u8ba1 datacube_uri={api_base_url}/datacube/%s?access_token=%s +##########################\u8001\u7248\u672c\u652f\u4ed8~start +# \u8ba2\u5355\u67e5\u8be2 +orderquery_old_uri={api_base_url}/pay/orderquery?access_token=%s +# \u53d1\u8d27\u901a\u77e5 +delivernotify_old_uri={api_base_url}/pay/delivernotify?access_token=%s +# \u7ef4\u6743\u5904\u7406 +payfeedback_old_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s +# \u5bf9\u8d26\u5355\u4e0b\u8f7d +downloadbill_old_uri={tenpay_base_url}/cgi-bin/mchdown_real_new.cgi +# \u9000\u6b3e\u67e5\u8be2 +refundquery_old_uri={tenpay_gw_base_url}/gateway/normalrefundquery.xml +# \u9000\u6b3e\u7533\u8bf7 +refundapply_old_uri={tenpay_ssl_base_url}/refundapi/gateway/refund.xml +# native\u652f\u4ed8 +nativepay_old_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s +##########################\u8001\u7248\u672c\u652f\u4ed8~end + # \u4e0a\u4f20\u6c38\u4e45\u56fe\u6587\u7d20\u6750 material_article_upload_uri={api_cgi_url}/material/add_news?access_token=%s # \u4e0a\u4f20\u6c38\u4e45\u5a92\u4f53\u7d20\u6750 @@ -183,19 +158,4 @@ material_media_count_uri={api_cgi_url}/material/get_materialcount?access_token=% # \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u5217\u8868 material_media_list_uri={api_cgi_url}/material/batchget_material?access_token=%s # \u81ea\u52a8\u56de\u590d\u89c4\u5219 -autoreply_setting_get_uri={api_cgi_url}/get_current_autoreply_info?access_token=%s - -# \u53d1\u653e\u4ee3\u91d1\u5238 -coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon -# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f -couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock -# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f -coupondetail_query_uri={mch_base_url}/promotion/query_coupon -# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305 -redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack -# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305 -redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo -# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e -mp_payment_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers -# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2 -mp_payquery_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo \ No newline at end of file +autoreply_setting_get_uri={api_cgi_url}/get_current_autoreply_info?access_token=%s \ No newline at end of file diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResultV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/ApiResultV2.java similarity index 98% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResultV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/ApiResultV2.java index a14821c7..4a8fff36 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResultV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/ApiResultV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import java.io.Serializable; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/NativePayNotifyV2.java similarity index 95% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/NativePayNotifyV2.java index 2d942dfc..3e5c4f5f 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/NativePayNotifyV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/NativePayResponseV2.java similarity index 89% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/NativePayResponseV2.java index 10b29eaf..b50499b6 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/NativePayResponseV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import java.util.HashMap; import java.util.Map; @@ -11,7 +11,6 @@ import javax.xml.bind.annotation.XmlRootElement; import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.model.WeixinPayOldAccount; import com.foxinmy.weixin4j.payment.PayRequest; -import com.foxinmy.weixin4j.util.DigestUtil; /** * V2 Native支付时的回调响应 @@ -64,10 +63,12 @@ public class NativePayResponseV2 extends PayRequest { */ public NativePayResponseV2(WeixinPayOldAccount weixinAccount, PayPackageV2 payPackage) { - super(weixinAccount.getId(), DigestUtil.packageSign(payPackage, - weixinAccount.getPartnerKey())); + super(weixinAccount.getId(), null); this.retCode = "0"; this.retMsg = "OK"; + WeixinOldPaymentSignature weixinSignature = new WeixinOldPaymentSignature(); + setPackageInfo(weixinSignature.sign(payPackage, + weixinAccount.getPartnerKey())); Map map = new HashMap(); map.put("appid", weixinAccount.getId()); map.put("appkey", weixinAccount.getPaySignKey()); @@ -76,7 +77,7 @@ public class NativePayResponseV2 extends PayRequest { map.put("package", getPackageInfo()); map.put("retcode", getRetCode()); map.put("reterrmsg", getRetMsg()); - this.setPaySign(DigestUtil.paysignSha(map, null)); + this.setPaySign(weixinSignature.sign(map)); } public String getRetCode() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/OrderV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/OrderV2.java similarity index 95% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/OrderV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/OrderV2.java index c5390681..0ea5e2ed 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/OrderV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/OrderV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import java.util.Date; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayFeedback.java similarity index 98% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayFeedback.java index 90e19da4..44d6f694 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayFeedback.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayPackageV2.java similarity index 98% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayPackageV2.java index 3d0a8537..b2102a8b 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayPackageV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import java.util.Date; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayWarn.java similarity index 92% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayWarn.java index 3d1c57dd..3abf099e 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/PayWarn.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetailV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundDetailV2.java similarity index 98% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetailV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundDetailV2.java index 7fc0fa63..ded1a8e9 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetailV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundDetailV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecordV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundRecordV2.java similarity index 94% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecordV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundRecordV2.java index 5f102719..61707bc2 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecordV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundRecordV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import java.util.List; @@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult; * @author jy * @date 2014年11月1日 * @since JDK 1.6 - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundDetailV2 + * @see com.foxinmy.weixin4j.mp.oldpayment.RefundDetailV2 */ @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResultV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundResultV2.java similarity index 96% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResultV2.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundResultV2.java index e4ba05ea..5c98f1fc 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResultV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/RefundResultV2.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.mp.payment.v2; +package com.foxinmy.weixin4j.mp.oldpayment; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/WeixinOldPaymentSignature.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/WeixinOldPaymentSignature.java new file mode 100644 index 00000000..92ab9a8d --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/oldpayment/WeixinOldPaymentSignature.java @@ -0,0 +1,70 @@ +package com.foxinmy.weixin4j.mp.oldpayment; + +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.foxinmy.weixin4j.sign.AbstractWeixinSignature; +import com.foxinmy.weixin4j.util.DigestUtil; +import com.foxinmy.weixin4j.util.MapUtil; + +/** + * 老版本支付签名 + * + * @className WeixinOldPaymentSignature + * @author jy + * @date 2016年3月26日 + * @since JDK 1.6 + * @see + */ +public class WeixinOldPaymentSignature extends AbstractWeixinSignature { + + @Override + public boolean lowerCase() { + return true; + } + + @Override + public String sign(Object obj) { + return DigestUtil.SHA1(join(obj).toString()); + } + + public String sign(Object obj, String paySignKey) { + if (obj instanceof Map) { + JSONPath.set(obj, "appKey", paySignKey); + } else { + ((JSONObject) JSON.toJSON(obj)).put("appKey", paySignKey); + } + return DigestUtil.SHA1(join(obj).toString()); + } + + /** + * package拼接签名 + * + * @param packageInfo + * package对象 + * @param partnerKey + * 签名key + * @return + */ + public String sign(PayPackageV2 packageInfo, String partnerKey) { + StringBuilder sb = new StringBuilder(); + // a.对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) 后, + // 使用 URL 键值 对的格式(即 key1=value1&key2=value2...)拼接成字符串 string1 + // 注意:值为空的参数不参与签名 + sb.append(MapUtil.toJoinString(packageInfo, false, false)); + // b---> + // 在 string1 最后拼接上 key=signKey 得到 stringSignTemp 字符串,并 对 + // stringSignTemp 进行 md5 运算 + // 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。 + sb.append("&key=").append(partnerKey); + // c---> & d----> + String sign = DigestUtil.MD5(sb.toString()).toUpperCase(); + sb.delete(0, sb.length()); + // c.对传入参数中所有键值对的 value 进行 urlencode 转码后重新拼接成字符串 string2 + sb.append(MapUtil.toJoinString(packageInfo, true, false)) + .append("&sign=").append(sign); + return sb.toString(); + } +} diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java index 6de07213..ec404d86 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java @@ -1,6 +1,8 @@ package com.foxinmy.weixin4j.mp.test; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.Calendar; import org.junit.Test; @@ -36,20 +38,21 @@ public class PayTest { @Test public void orderQueryV2() throws WeixinException { - System.err.println(PAY2.orderQuery(new IdQuery("D14110500021", + System.err.println(PAY2.queryOrder(new IdQuery("D14110500021", IdType.REFUNDNO))); } @Test - public void refundV2() throws WeixinException { + public void refundV2() throws WeixinException, IOException { IdQuery idQuery = new IdQuery("D15020300005", IdType.TRADENO); - System.err.println(PAY2.refundApply(caFile, idQuery, "1422925555037", - 16d, 16d, "1221928801", "111111", null, null, null)); + System.err.println(PAY2.applyRefund(new FileInputStream(caFile), + idQuery, "1422925555037", 16d, 16d, "1221928801", "111111", + null, null, null)); } @Test public void refundQueryV2() throws WeixinException { - System.err.println(PAY2.refundQuery(new IdQuery("D14123000004", + System.err.println(PAY2.queryRefund(new IdQuery("D14123000004", IdType.TRADENO))); } diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java index 13f83a43..15f4078c 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java @@ -6,7 +6,7 @@ import java.util.HashMap; import java.util.Map; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2; +import com.foxinmy.weixin4j.mp.oldpayment.RefundRecordV2; import com.foxinmy.weixin4j.payment.mch.Order; import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer; import com.foxinmy.weixin4j.xml.XmlStream; diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java index bfc22159..6b83bca4 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java @@ -14,10 +14,10 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; @@ -88,7 +88,7 @@ public class WeixinMessageDispatcher { /** * 消息转换 */ - private ThreadLocal, Unmarshaller>> messageUnmarshaller; + private Map, Unmarshaller> messageUnmarshaller; /** * 是否总是响应请求,如未匹配到MessageHandler时回复空白消息 */ @@ -100,12 +100,7 @@ public class WeixinMessageDispatcher { public WeixinMessageDispatcher(WeixinMessageMatcher messageMatcher) { this.messageMatcher = messageMatcher; - this.messageUnmarshaller = new ThreadLocal, Unmarshaller>>() { - @Override - protected Map, Unmarshaller> initialValue() { - return new HashMap, Unmarshaller>(); - } - }; + this.messageUnmarshaller = new ConcurrentHashMap, Unmarshaller>(); } /** @@ -125,7 +120,8 @@ public class WeixinMessageDispatcher { WeixinMessageKey messageKey = defineMessageKey(messageTransfer, request); Class targetClass = messageMatcher .match(messageKey); - WeixinMessage message = messageRead(request.getOriginalContent(), targetClass); + WeixinMessage message = messageRead(request.getOriginalContent(), + targetClass); logger.info("define '{}' matched '{}'", messageKey, targetClass); MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context, request, messageKey, message, messageTransfer.getNodeNames()); @@ -179,6 +175,7 @@ public class WeixinMessageDispatcher { */ protected void noHandlerFound(ChannelHandlerContext context, WeixinRequest request, Object message) { + logger.warn("no handler found {}", request); if (alwaysResponse) { context.write(BlankResponse.global); } else { @@ -209,13 +206,13 @@ public class WeixinMessageDispatcher { */ protected MessageHandlerExecutor getHandlerExecutor( ChannelHandlerContext context, WeixinRequest request, - WeixinMessageKey messageKey, WeixinMessage message, Set nodeNames) - throws WeixinException { + WeixinMessageKey messageKey, WeixinMessage message, + Set nodeNames) throws WeixinException { WeixinMessageHandler[] messageHandlers = getMessageHandlers(); if (messageHandlers == null) { return null; } - logger.info("resolve handlers '{}'", this.messageHandlerList); + logger.info("resolve message handlers '{}'", this.messageHandlerList); List matchedMessageHandlers = new ArrayList(); for (WeixinMessageHandler handler : messageHandlers) { if (handler.canHandle(request, message, nodeNames)) { @@ -233,7 +230,7 @@ public class WeixinMessageDispatcher { return m2.weight() - m1.weight(); } }); - logger.info("matched message handlers '{}'", matchedMessageHandlers); + logger.info("matched message handler '{}'", matchedMessageHandlers); return new MessageHandlerExecutor(context, matchedMessageHandlers.get(0), getMessageInterceptors()); } @@ -367,6 +364,8 @@ public class WeixinMessageDispatcher { .size()]); } } + logger.info("resolve message interceptors '{}'", + this.messageInterceptorList); return this.messageInterceptors; } @@ -406,12 +405,12 @@ public class WeixinMessageDispatcher { */ protected Unmarshaller getUnmarshaller(Class clazz) throws WeixinException { - Unmarshaller unmarshaller = messageUnmarshaller.get().get(clazz); + Unmarshaller unmarshaller = messageUnmarshaller.get(clazz); if (unmarshaller == null) { try { JAXBContext jaxbContext = JAXBContext.newInstance(clazz); unmarshaller = jaxbContext.createUnmarshaller(); - messageUnmarshaller.get().put(clazz, unmarshaller); + messageUnmarshaller.put(clazz, unmarshaller); } catch (JAXBException e) { throw new WeixinException(e); } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java index 3a776405..be6f0c0b 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java @@ -87,6 +87,7 @@ public class WeixinMessageDecoder extends messageContent = MessageUtil.aesDecrypt(aesToken.getWeixinId(), aesToken.getAesKey(), encryptContent); } + logger.info("read original message {}", messageContent); WeixinRequest request = new WeixinRequest(req.headers(), method, req.getUri(), encryptType, echoStr, timeStamp, nonce, signature, msgSignature, messageContent, encryptContent, diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java index 8aa41949..374c0ae0 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java @@ -233,6 +233,9 @@ public final class WeixinServerBootstrap { */ public WeixinServerBootstrap addHandler( WeixinMessageHandler... messageHandler) { + if (messageHandler == null) { + throw new IllegalArgumentException("messageHandler not be null"); + } messageHandlerList.addAll(Arrays.asList(messageHandler)); return this; } @@ -246,6 +249,9 @@ public final class WeixinServerBootstrap { */ public WeixinServerBootstrap addInterceptor( WeixinMessageInterceptor... messageInterceptor) { + if (messageInterceptor == null) { + throw new IllegalArgumentException("messageInterceptor not be null"); + } messageInterceptorList.addAll(Arrays.asList(messageInterceptor)); return this; } @@ -259,6 +265,10 @@ public final class WeixinServerBootstrap { */ public WeixinServerBootstrap handlerPackagesToScan( String... messageHandlerPackages) { + if (messageHandlerPackages == null) { + throw new IllegalArgumentException( + "messageHandlerPackages not be null"); + } messageDispatcher.setMessageHandlerPackages(messageHandlerPackages); return this; } @@ -272,6 +282,10 @@ public final class WeixinServerBootstrap { */ public WeixinServerBootstrap interceptorPackagesToScan( String... messageInterceptorPackages) { + if (messageInterceptorPackages == null) { + throw new IllegalArgumentException( + "messageInterceptorPackages not be null"); + } messageDispatcher .setMessageInterceptorPackages(messageInterceptorPackages); return this;