From 866b37c54bb8675d25723c0545bca73d50b4cae4 Mon Sep 17 00:00:00 2001 From: jinyu Date: Tue, 24 May 2016 10:23:53 +0800 Subject: [PATCH] fixed #65 --- .../com/foxinmy/weixin4j/api/CashApi.java | 76 +++-- .../com/foxinmy/weixin4j/api/CustomsApi.java | 8 +- .../http/factory/Netty4HttpClient.java | 9 +- .../http/factory/Netty4HttpResponse.java | 4 +- .../com/foxinmy/weixin4j/model/Button.java | 20 +- .../weixin4j/payment/WeixinPayProxy.java | 300 ++++++++++-------- .../payment/mch/CorpPaymentResult.java | 6 +- .../com/foxinmy/weixin4j/tuple/MpArticle.java | 2 +- .../com/foxinmy/weixin4j/type/ButtonType.java | 8 +- .../foxinmy/weixin4j/mp/api/HelperApi.java | 52 ++- .../test/{HelpTest.java => HelperTest.java} | 11 +- .../socket/WeixinResponseEncoder.java | 2 +- .../com/foxinmy/weixin4j/util/HttpUtil.java | 20 +- 13 files changed, 292 insertions(+), 226 deletions(-) rename weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/{HelpTest.java => HelperTest.java} (76%) 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 ad19ed52..21d02674 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 @@ -27,7 +27,7 @@ import com.foxinmy.weixin4j.xml.XmlStream; /** * 现金API - * + * * @className CashApi * @author jinyu(foxinmy@gmail.com) * @date 2015年3月28日 @@ -47,7 +47,7 @@ public class CashApi extends MchApi { /** * 发放红包 企业向微信用户个人发现金红包 - * + * * @param certificate * 后缀为*.p12的证书文件 * @param redpacket @@ -63,7 +63,8 @@ public class CashApi extends MchApi { * 发放裂变红包接口 * @throws WeixinException */ - public RedpacketSendResult sendRedpack(InputStream certificate, Redpacket redpacket) throws WeixinException { + public RedpacketSendResult sendRedpack(InputStream certificate, + Redpacket redpacket) throws WeixinException { redpacket.declareWeixinPayAccount(weixinAccount); JSONObject obj = (JSONObject) JSON.toJSON(redpacket); obj.put("wxappid", obj.remove("appid")); @@ -71,8 +72,9 @@ public class CashApi extends MchApi { String param = XmlStream.map2xml(obj); WeixinResponse response = null; try { - response = createSSLRequestExecutor(certificate).post(redpacket.getTotalNum() > 1 - ? getRequestUri("groupredpack_send_uri") : getRequestUri("redpack_send_uri"), param); + response = createSSLRequestExecutor(certificate) + .post(redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri") + : getRequestUri("redpack_send_uri"), param); } finally { if (certificate != null) { try { @@ -82,14 +84,15 @@ public class CashApi extends MchApi { } } } - String text = response.getAsString().replaceFirst("", "").replaceFirst("", - ""); + String text = response.getAsString() + .replaceFirst("", "") + .replaceFirst("", ""); return XmlStream.fromXML(text, RedpacketSendResult.class); } /** * 查询红包记录 - * + * * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo @@ -104,7 +107,8 @@ public class CashApi extends MchApi { * 查询裂变红包接口 * @throws WeixinException */ - public RedpacketRecord queryRedpack(InputStream certificate, String outTradeNo) throws WeixinException { + public RedpacketRecord queryRedpack(InputStream certificate, + String outTradeNo) throws WeixinException { Map para = createBaseRequestMap(null); para.put("bill_type", "MCHT"); para.put("mch_billno", outTradeNo); @@ -112,7 +116,8 @@ public class CashApi extends MchApi { String param = XmlStream.map2xml(para); WeixinResponse response = null; try { - response = createSSLRequestExecutor(certificate).post(getRequestUri("redpack_query_uri"), param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("redpack_query_uri"), param); } finally { if (certificate != null) { try { @@ -128,7 +133,16 @@ public class CashApi extends MchApi { /** * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 - * + *

+ * 接口调用规则: + *

+ *

  • 给同一个实名用户付款,单笔单日限额2W/2W + *
  • 给同一个非实名用户付款,单笔单日限额2000/2000 + *
  • 一个商户同一日付款总额限额100W + *
  • 单笔最小金额默认为1元 + *
  • 每个用户每天最多可付款10次,可以在商户平台--API安全进行设置 + *
  • 给同一个用户付款时间间隔不得低于15秒 + * * @param certificate * 后缀为*.p12的证书文件 * @param payment @@ -141,7 +155,8 @@ public class CashApi extends MchApi { * 企业付款接口 * @throws WeixinException */ - public CorpPaymentResult sendCorpPayment(InputStream certificate, CorpPayment payment) throws WeixinException { + public CorpPaymentResult sendCorpPayment(InputStream certificate, + CorpPayment payment) throws WeixinException { payment.declareWeixinPayAccount(weixinAccount); JSONObject obj = (JSONObject) JSON.toJSON(payment); obj.put("mchid", obj.remove("mch_id")); @@ -150,7 +165,8 @@ public class CashApi extends MchApi { String param = XmlStream.map2xml(obj); WeixinResponse response = null; try { - response = createSSLRequestExecutor(certificate).post(getRequestUri("corppayment_send_uri"), param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("corppayment_send_uri"), param); } finally { if (certificate != null) { try { @@ -160,15 +176,17 @@ public class CashApi extends MchApi { } } } - String text = response.getAsString().replaceFirst("", "") - .replaceFirst("", "").replaceFirst("", "") + String text = response.getAsString() + .replaceFirst("", "") + .replaceFirst("", "") + .replaceFirst("", "") .replaceFirst("", ""); return XmlStream.fromXML(text, CorpPaymentResult.class); } /** * 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果 - * + * * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo @@ -180,7 +198,8 @@ public class CashApi extends MchApi { * 企业付款查询接口 * @throws WeixinException */ - public CorpPaymentRecord queryCorpPayment(InputStream certificate, 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()); @@ -190,7 +209,8 @@ public class CashApi extends MchApi { String param = XmlStream.map2xml(obj); WeixinResponse response = null; try { - response = createSSLRequestExecutor(certificate).post(getRequestUri("corppayment_query_uri"), param); + response = createSSLRequestExecutor(certificate).post( + getRequestUri("corppayment_query_uri"), param); } finally { if (certificate != null) { try { @@ -206,7 +226,7 @@ public class CashApi extends MchApi { /** * 查询结算资金 - * + * * @param status * 是否结算 * @param pageable @@ -222,8 +242,8 @@ public class CashApi extends MchApi { * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7"> * 查询结算资金接口 */ - public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end) - throws WeixinException { + public SettlementRecord querySettlement(boolean status, Pageable pageable, + Date start, Date end) throws WeixinException { JSONObject obj = new JSONObject(); obj.put("nonce_str", RandomUtil.generateString(16)); obj.put("mch_id", weixinAccount.getMchId()); @@ -239,14 +259,15 @@ public class CashApi extends MchApi { } obj.put("sign", weixinSignature.sign(obj)); String param = XmlStream.map2xml(obj); - WeixinResponse response = weixinExecutor.post(getRequestUri("settlement_query_uri"), param); + WeixinResponse response = weixinExecutor.post( + getRequestUri("settlement_query_uri"), param); return response.getAsObject(new TypeReference() { }); } /** * 查询汇率 - * + * * @param currencyType * 外币币种 * @param date @@ -257,7 +278,8 @@ public class CashApi extends MchApi { * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8"> * 查询汇率接口 */ - public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException { + public double queryExchageRate(CurrencyType currencyType, Date date) + throws WeixinException { if (date == null) { date = new Date(); } @@ -269,8 +291,10 @@ public class CashApi extends MchApi { obj.put("date", DateUtil.fortmat2yyyyMMdd(date)); obj.put("sign", weixinSignature.sign(obj)); String param = XmlStream.map2xml(obj); - WeixinResponse response = weixinExecutor.post(getRequestUri("exchagerate_query_uri"), param); - BigDecimal rate = new BigDecimal(XmlStream.xml2map(response.getAsString()).get("rate")); + WeixinResponse response = weixinExecutor.post( + getRequestUri("exchagerate_query_uri"), param); + BigDecimal rate = new BigDecimal(XmlStream.xml2map( + response.getAsString()).get("rate")); return rate.divide(new BigDecimal(100000000d)).doubleValue(); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CustomsApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CustomsApi.java index da89b622..b273c0fb 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CustomsApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/CustomsApi.java @@ -16,11 +16,11 @@ import com.foxinmy.weixin4j.xml.XmlStream; /** * 报关接口 - * + * * @className CustomsApi * @author jinyu(foxinmy@gmail.com) * @date 2016年3月67日 - * @since JDK 1.7 + * @since JDK 1.6 * @see */ public class CustomsApi extends MchApi { @@ -31,7 +31,7 @@ public class CustomsApi extends MchApi { /** * 订单附加信息提交 - * + * * @param customsOrder * 附加订单信息 * @return 报关结果 @@ -56,7 +56,7 @@ public class CustomsApi extends MchApi { /** * 订单附加信息查询 - * + * * @param idQuery * out_trade_no,transaction_id,sub_order_no,sub_order_id四选一 * @param customsCity diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java index a5874c14..acafa0dc 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java @@ -37,12 +37,13 @@ import com.foxinmy.weixin4j.http.HttpParams; import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.HttpResponse; import com.foxinmy.weixin4j.http.entity.HttpEntity; +import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.util.SettableFuture; import com.foxinmy.weixin4j.util.StringUtil; /** * Netty 4.x - * + * * @className Netty4HttpClient * @author jinyu(foxinmy@gmail.com) * @date 2015年8月30日 @@ -183,11 +184,11 @@ public class Netty4HttpClient extends AbstractHttpClient { if (!headers.containsKey(HttpHeaders.USER_AGENT)) { headers.set(HttpHeaders.USER_AGENT, "netty/httpclient"); } - for (Entry> header : headers - .entrySet()) { + for (Entry> header : headers.entrySet()) { uriRequest.headers().set(header.getKey(), header.getValue()); } - uriRequest.headers().set(HttpHeaders.ACCEPT_CHARSET, "utf-8"); + uriRequest.headers().set(HttpHeaders.ACCEPT_CHARSET, + Consts.UTF_8.displayName()); uriRequest.headers().set(HttpHeaders.CONNECTION, io.netty.handler.codec.http.HttpHeaders.Values.CLOSE); return uriRequest; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpResponse.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpResponse.java index b63c329f..9ff25ff4 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpResponse.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpResponse.java @@ -12,8 +12,8 @@ import com.foxinmy.weixin4j.http.HttpStatus; import com.foxinmy.weixin4j.http.HttpVersion; /** - * Netty Respone::Requires Netty 4.x or higher - * + * Netty Response::Requires Netty 4.x or higher + * * @className Netty4HttpResponse * @author jinyu(foxinmy@gmail.com) * @date 2015年8月30日 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java index 1d3fa133..1fcc3b75 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java @@ -19,7 +19,6 @@ import com.foxinmy.weixin4j.type.ButtonType; * @author jinyu(foxinmy@gmail.com) * @date 2014年4月5日 * @since JDK 1.6 - * @see com.foxinmy.weixin4j.type.ButtonType */ public class Button implements Serializable { @@ -37,18 +36,13 @@ public class Button implements Serializable { */ private ButtonType type; /** - * 菜单KEY值,根据type的类型而定,用于消息接口推送,不超过128字节. - *

    - * 官网上设置的自定义菜单:
    Text:保存文字到value; Img、voice:保存mediaID到value; - * Video:保存视频下载链接到value;
    News:保存图文消息到news_info; View:保存链接到url。
    - *

    - * 使用API设置的自定义菜单:
    - * click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album - * 、
    - * pic_weixin、location_select:保存为key;view:保存为url;media_id、view_limited - * :保存为media_id - *

    - *

    + * 菜单KEY值,根据type的类型而定

    通过公众平台设置的自定义菜单:
  • text:保存文字;
  • + * img、voice:保存媒体ID;
  • video:保存视频URL;
  • + * news:保存图文消息:List#com.foxinmy.weixin4j.tuple.MpArticle#;
  • view:保存链接URL; + *

    使用API设置的自定义菜单:

  • + * click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、 + * pic_weixin、location_select:保存key;
  • view:保存链接URL;
  • + * media_id、view_limited:保存媒体ID */ private Serializable content; /** 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 43db2c3f..7fb2a1a2 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 @@ -45,7 +45,7 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings; /** * 微信支付接口实现 - * + * * @className WeixinPayProxy * @author jinyu(foxinmy@gmail.com) * @date 2015年1月3日 @@ -98,7 +98,7 @@ public class WeixinPayProxy { /** * 获取微信商户支付信息 - * + * * @return */ public WeixinPayAccount getPayAccount() { @@ -109,7 +109,7 @@ public class WeixinPayProxy { * 统一下单接口
    * 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI * 、APP等不同场景生成交易串调起支付。 - * + * * @param payPackage * 包含订单信息的对象 * @see com.foxinmy.weixin4j.api.PayApi @@ -126,7 +126,7 @@ public class WeixinPayProxy { /** * 创建支付请求对象 - * + * * @param payPackage * 支付详情 * @return 支付请求对象 @@ -138,13 +138,14 @@ public class WeixinPayProxy { * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付 * @throws WeixinException */ - public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException { + public MchPayRequest createPayRequest(MchPayPackage payPackage) + throws WeixinException { return payApi.createPayRequest(payPackage); } /** * 创建支付请求对象【完整参数】 - * + * * @param body * 商品描述 必填项 * @param detail @@ -184,17 +185,20 @@ public class WeixinPayProxy { * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付 * @throws WeixinException */ - public MchPayRequest createPayRequest(String body, String detail, String outTradeNo, double totalFee, - String notifyUrl, String createIp, TradeType tradeType, String openId, String productId, String attach, - Date timeStart, Date timeExpire, String goodsTag, String limitPay, String subOpenId) + public MchPayRequest createPayRequest(String body, String detail, + String outTradeNo, double totalFee, String notifyUrl, + String createIp, TradeType tradeType, String openId, + String productId, String attach, Date timeStart, Date timeExpire, + String goodsTag, String limitPay, String subOpenId) throws WeixinException { - return payApi.createPayRequest(body, detail, outTradeNo, totalFee, notifyUrl, createIp, tradeType, openId, - productId, attach, timeStart, timeExpire, goodsTag, limitPay, subOpenId); + return payApi.createPayRequest(body, detail, outTradeNo, totalFee, + notifyUrl, createIp, tradeType, openId, productId, attach, + timeStart, timeExpire, goodsTag, limitPay, subOpenId); } /** * 创建JSAPI支付请求对象 - * + * * @param openId * 用户ID * @param body @@ -214,27 +218,24 @@ public class WeixinPayProxy { * @return JSAPI支付对象 * @throws WeixinException */ - public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee, - String notifyUrl, String createIp, String attach) throws WeixinException { - return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach); + public MchPayRequest createJSPayRequest(String openId, String body, + String outTradeNo, double totalFee, String notifyUrl, + String createIp, String attach) throws WeixinException { + return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee, + notifyUrl, createIp, attach); } /** *

    * 生成编辑地址请求 *

    - * - * err_msg edit_address:ok获取编辑收货地址成功
    - * edit_address:fail获取编辑收货地址失败
    - * userName 收货人姓名
    - * telNumber 收货人电话
    - * addressPostalCode 邮编
    - * proviceFirstStageName 国标收货地址第一级地址
    - * addressCitySecondStageName 国标收货地址第二级地址
    - * addressCountiesThirdStageName 国标收货地址第三级地址
    - * addressDetailInfo 详细收货地址信息
    - * nationalCode 收货地址国家码
    - * + * + * err_msg edit_address:ok获取编辑收货地址成功
    edit_address:fail获取编辑收货地址失败
    + * userName 收货人姓名
    telNumber 收货人电话
    addressPostalCode 邮编
    + * proviceFirstStageName 国标收货地址第一级地址
    addressCitySecondStageName + * 国标收货地址第二级地址
    addressCountiesThirdStageName 国标收货地址第三级地址
    + * addressDetailInfo 详细收货地址信息
    nationalCode 收货地址国家码
    + * * @param url * 当前访问页的URL * @param oauthToken @@ -251,7 +252,7 @@ public class WeixinPayProxy { /** * 创建Native支付(扫码支付)链接【模式一】 - * + * * @param productId * 与订单ID等价 * @return 支付链接 @@ -269,7 +270,7 @@ public class WeixinPayProxy { /** * 创建Native支付(扫码支付)回调对象【模式一】 - * + * * @param productId * 商品ID * @param body @@ -295,14 +296,16 @@ public class WeixinPayProxy { * * @throws WeixinException */ - public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee, - String notifyUrl, String createIp, String attach) throws WeixinException { - return payApi.createNativePayResponse(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach); + public NativePayResponse createNativePayResponse(String productId, + String body, String outTradeNo, double totalFee, String notifyUrl, + String createIp, String attach) throws WeixinException { + return payApi.createNativePayResponse(productId, body, outTradeNo, + totalFee, notifyUrl, createIp, attach); } /** * 创建Native支付(扫码支付)链接【模式二】 - * + * * @param productId * 商品ID * @param body @@ -328,14 +331,16 @@ public class WeixinPayProxy { * * @throws WeixinException */ - public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee, - String notifyUrl, String createIp, String attach) throws WeixinException { - return payApi.createNativePayRequest(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach); + public MchPayRequest createNativePayRequest(String productId, String body, + String outTradeNo, double totalFee, String notifyUrl, + String createIp, String attach) throws WeixinException { + return payApi.createNativePayRequest(productId, body, outTradeNo, + totalFee, notifyUrl, createIp, attach); } /** * 创建APP支付请求对象 - * + * * @param body * 商品描述 * @param outTradeNo @@ -356,14 +361,16 @@ public class WeixinPayProxy { * APP支付 * @throws WeixinException */ - public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl, - String createIp, String attach) throws WeixinException { - return payApi.createAppPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach); + public MchPayRequest createAppPayRequest(String body, String outTradeNo, + double totalFee, String notifyUrl, String createIp, String attach) + throws WeixinException { + return payApi.createAppPayRequest(body, outTradeNo, totalFee, + notifyUrl, createIp, attach); } /** * 创建WAP支付请求对象 - * + * * @param body * 商品描述 * @param outTradeNo @@ -384,14 +391,16 @@ public class WeixinPayProxy { * * @throws WeixinException */ - public MchPayRequest createWAPPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl, - String createIp, String attach) throws WeixinException { - return payApi.createWAPPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach); + public MchPayRequest createWAPPayRequest(String body, String outTradeNo, + double totalFee, String notifyUrl, String createIp, String attach) + throws WeixinException { + return payApi.createWAPPayRequest(body, outTradeNo, totalFee, + notifyUrl, createIp, attach); } /** * 提交被扫支付 - * + * * @param authCode * 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息 * @param body @@ -413,20 +422,20 @@ public class WeixinPayProxy { * 提交被扫支付API * @throws WeixinException */ - public MchPayRequest createMICROPayRequest(String authCode, String body, String outTradeNo, double totalFee, - String createIp, String attach) throws WeixinException { - return payApi.createMICROPayRequest(authCode, body, outTradeNo, totalFee, createIp, attach); + public MchPayRequest createMICROPayRequest(String authCode, String body, + String outTradeNo, double totalFee, String createIp, String attach) + throws WeixinException { + return payApi.createMICROPayRequest(authCode, body, outTradeNo, + totalFee, createIp, attach); } /** * 订单查询 *

    - * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
    - * 调用支付接口后,返回系统错误或未知交易状态情况;
    - * 调用被扫支付API,返回USERPAYING的状态;
    - * 调用关单或撤销接口API之前,需确认支付状态; + * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
    调用支付接口后,返回系统错误或未知交易状态情况;
    + * 调用被扫支付API,返回USERPAYING的状态;
    调用关单或撤销接口API之前,需确认支付状态; *

    - * + * * @param idQuery * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: * transaction_id> out_trade_no @@ -454,7 +463,7 @@ public class WeixinPayProxy { * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交 * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 *

    - * + * * @param certificate * 后缀为*.p12的证书文件 * @param idQuery @@ -470,7 +479,7 @@ public class WeixinPayProxy { * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY * @param opUserId * 操作员帐号, 默认为商户号 - * + * * @return 退款申请结果 * @see com.foxinmy.weixin4j.payment.mch.RefundResult * @see com.foxinmy.weixin4j.api.PayApi @@ -480,21 +489,25 @@ public class WeixinPayProxy { * @since V3 * @throws WeixinException */ - public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee, - double refundFee, CurrencyType refundFeeType, String opUserId) throws WeixinException { - return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee, refundFee, refundFeeType, opUserId); + public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, + String outRefundNo, double totalFee, double refundFee, + CurrencyType refundFeeType, String opUserId) throws WeixinException { + return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee, + refundFee, refundFeeType, opUserId); } /** * 退款申请(全额退款) - * + * * @throws IOException - * + * * @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String,CurrencyType)} */ - public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) - throws WeixinException, IOException { - return payApi.applyRefund(new FileInputStream(settings.getCertificateFile0()), idQuery, outRefundNo, totalFee); + public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, + double totalFee) throws WeixinException, IOException { + return payApi.applyRefund( + new FileInputStream(settings.getCertificateFile0()), idQuery, + outRefundNo, totalFee); } /** @@ -502,7 +515,7 @@ public class WeixinPayProxy { *

    * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 *

    - * + * * @param idQuery * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id * 四个参数必填一个,优先级为: @@ -526,7 +539,7 @@ public class WeixinPayProxy { * REVOKED;
    * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
    * 3.对账单中涉及金额的字段单位为“元”。
    - * + * * @param billDate * 下载对账单的日期 * @param billType @@ -540,18 +553,17 @@ public class WeixinPayProxy { * 下载对账单API * @throws WeixinException */ - public File downloadBill(Date billDate, BillType billType) throws WeixinException { + public File downloadBill(Date billDate, BillType billType) + throws WeixinException { return payApi.downloadBill(billDate, billType, settings.getTmpdir0()); } /** - * 冲正订单(需要证书)
    - * 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
    - * 接口逻辑:支 付失败的关单,支付成功的撤销支付
    - * 7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口
    - * 调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销 - *
    - * + * 冲正订单(需要证书)
    当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
    接口逻辑:支 + * 付失败的关单,支付成功的撤销支付
    7天以内的单可撤销,其他正常支付的单 + * 如需实现相同功能请调用退款接口
    调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
    + * * @param certificate * 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12) * @param idQuery @@ -562,13 +574,14 @@ public class WeixinPayProxy { * @since V3 * @throws WeixinException */ - public MerchantResult reverseOrder(InputStream certificate, IdQuery idQuery) throws WeixinException { + public MerchantResult reverseOrder(InputStream certificate, IdQuery idQuery) + throws WeixinException { return payApi.reverseOrder(certificate, idQuery); } /** * 冲正撤销 - * + * * @param idQuery * transaction_id、out_trade_no 二选一 * @return 撤销结果 @@ -576,8 +589,10 @@ public class WeixinPayProxy { * @throws WeixinException * @throws IOException */ - public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException, IOException { - return payApi.reverseOrder(new FileInputStream(settings.getCertificateFile0()), idQuery); + public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException, + IOException { + return payApi.reverseOrder( + new FileInputStream(settings.getCertificateFile0()), idQuery); } /** @@ -586,7 +601,7 @@ public class WeixinPayProxy { * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续 * ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 *

    - * + * * @param outTradeNo * 商户系统内部的订单号 * @return 执行结果 @@ -604,7 +619,7 @@ public class WeixinPayProxy { /** * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量 * ,提升扫描速度和精确度。 - * + * * @param url * 具有native标识的支付URL * @return 转换后的短链接 @@ -621,7 +636,7 @@ public class WeixinPayProxy { /** * 接口上报 - * + * * @param interfaceUrl * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q * q.com/pay/unifiedorder @@ -642,14 +657,16 @@ public class WeixinPayProxy { * 接口测试上报API * @throws WeixinException */ - public XmlResult interfaceReport(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time, - XmlResult returnXml) throws WeixinException { - return payApi.interfaceReport(interfaceUrl, executeTime, outTradeNo, ip, time, returnXml); + public XmlResult interfaceReport(String interfaceUrl, int executeTime, + String outTradeNo, String ip, Date time, XmlResult returnXml) + throws WeixinException { + return payApi.interfaceReport(interfaceUrl, executeTime, outTradeNo, + ip, time, returnXml); } /** * 发放代金券(需要证书) - * + * * @param certificate * 后缀为*.p12的证书文件 * @param couponStockId @@ -668,25 +685,28 @@ public class WeixinPayProxy { * 发放代金券接口 * @throws WeixinException */ - public CouponResult sendCoupon(InputStream certificate, String couponStockId, String partnerTradeNo, String openId, + public CouponResult sendCoupon(InputStream certificate, + String couponStockId, String partnerTradeNo, String openId, String opUserId) throws WeixinException { - return couponApi.sendCoupon(certificate, couponStockId, partnerTradeNo, openId, opUserId); + return couponApi.sendCoupon(certificate, couponStockId, partnerTradeNo, + openId, opUserId); } /** * 发放代金券 - * + * * @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendCoupon(InputStream, String, String, String, String)} */ - public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, String openId) - throws WeixinException, IOException { - return couponApi.sendCoupon(new FileInputStream(settings.getCertificateFile0()), couponStockId, partnerTradeNo, - openId, null); + public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, + String openId) throws WeixinException, IOException { + return couponApi.sendCoupon( + new FileInputStream(settings.getCertificateFile0()), + couponStockId, partnerTradeNo, openId, null); } /** * 查询代金券批次 - * + * * @param couponStockId * 代金券批次ID * @return 代金券批次信息 @@ -697,13 +717,14 @@ public class WeixinPayProxy { * 查询代金券批次信息接口 * @throws WeixinException */ - public CouponStock queryCouponStock(String couponStockId) throws WeixinException { + public CouponStock queryCouponStock(String couponStockId) + throws WeixinException { return couponApi.queryCouponStock(couponStockId); } /** * 查询代金券详细 - * + * * @param couponId * 代金券ID * @return 代金券详细信息 @@ -714,13 +735,14 @@ public class WeixinPayProxy { * 查询代金券详细信息接口 * @throws WeixinException */ - public CouponDetail queryCouponDetail(String couponId) throws WeixinException { + public CouponDetail queryCouponDetail(String couponId) + throws WeixinException { return couponApi.queryCouponDetail(couponId); } /** * 发放红包 企业向微信用户个人发现金红包 - * + * * @param certificate * 后缀为*.p12的证书文件 * @param redpacket @@ -737,22 +759,25 @@ public class WeixinPayProxy { * 发放裂变红包接口 * @throws WeixinException */ - public RedpacketSendResult sendRedpack(InputStream certificate, Redpacket redpacket) throws WeixinException { + public RedpacketSendResult sendRedpack(InputStream certificate, + Redpacket redpacket) throws WeixinException { return cashApi.sendRedpack(certificate, redpacket); } /** * 发放红包 - * + * * @see {@link #sendRedpack(InputStream, Redpacket)} */ - public RedpacketSendResult sendRedpack(Redpacket redpacket) throws WeixinException, IOException { - return cashApi.sendRedpack(new FileInputStream(settings.getCertificateFile0()), redpacket); + public RedpacketSendResult sendRedpack(Redpacket redpacket) + throws WeixinException, IOException { + return cashApi.sendRedpack( + new FileInputStream(settings.getCertificateFile0()), redpacket); } /** * 查询红包记录 - * + * * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo @@ -768,22 +793,36 @@ public class WeixinPayProxy { * 查询裂变红包接口 * @throws WeixinException */ - public RedpacketRecord queryRedpack(InputStream certificate, String outTradeNo) throws WeixinException { + public RedpacketRecord queryRedpack(InputStream certificate, + String outTradeNo) throws WeixinException { return cashApi.queryRedpack(certificate, outTradeNo); } /** * 查询红包 - * + * * @see {@link #queryRedpack(InputStream,String)} */ - public RedpacketRecord queryRedpack(String outTradeNo) throws WeixinException, IOException { - return cashApi.queryRedpack(new FileInputStream(settings.getCertificateFile0()), outTradeNo); + public RedpacketRecord queryRedpack(String outTradeNo) + throws WeixinException, IOException { + return cashApi + .queryRedpack( + new FileInputStream(settings.getCertificateFile0()), + outTradeNo); } /** * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 - * + *

    + * 接口调用规则: + *

    + *

  • 给同一个实名用户付款,单笔单日限额2W/2W + *
  • 给同一个非实名用户付款,单笔单日限额2000/2000 + *
  • 一个商户同一日付款总额限额100W + *
  • 单笔最小金额默认为1元 + *
  • 每个用户每天最多可付款10次,可以在商户平台--API安全进行设置 + *
  • 给同一个用户付款时间间隔不得低于15秒 + * * @param certificate * 后缀为*.p12的证书文件 * @param payment @@ -797,22 +836,25 @@ public class WeixinPayProxy { * 企业付款接口 * @throws WeixinException */ - public CorpPaymentResult sendCorpPayment(InputStream certificate, CorpPayment payment) throws WeixinException { + public CorpPaymentResult sendCorpPayment(InputStream certificate, + CorpPayment payment) throws WeixinException { return cashApi.sendCorpPayment(certificate, payment); } /** * 企业付款 - * + * * @see {@link #sendCorpPayment(InputStream, CorpPayment)} */ - public CorpPaymentResult sendCorpPayment(CorpPayment payment) throws WeixinException, IOException { - return cashApi.sendCorpPayment(new FileInputStream(settings.getCertificateFile0()), payment); + public CorpPaymentResult sendCorpPayment(CorpPayment payment) + throws WeixinException, IOException { + return cashApi.sendCorpPayment( + new FileInputStream(settings.getCertificateFile0()), payment); } /** * 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果 - * + * * @param certificate * 后缀为*.p12的证书文件 * @param outTradeNo @@ -825,22 +867,27 @@ public class WeixinPayProxy { * 企业付款查询接口 * @throws WeixinException */ - public CorpPaymentRecord queryCorpPayment(InputStream certificate, String outTradeNo) throws WeixinException { + public CorpPaymentRecord queryCorpPayment(InputStream certificate, + String outTradeNo) throws WeixinException { return cashApi.queryCorpPayment(certificate, outTradeNo); } /** * 企业付款查询 - * + * * @see {@link #CorpPaymentRecord(InputStream, String)} */ - public CorpPaymentRecord queryCorpPayment(String outTradeNo) throws WeixinException, IOException { - return cashApi.queryCorpPayment(new FileInputStream(settings.getCertificateFile0()), outTradeNo); + public CorpPaymentRecord queryCorpPayment(String outTradeNo) + throws WeixinException, IOException { + return cashApi + .queryCorpPayment( + new FileInputStream(settings.getCertificateFile0()), + outTradeNo); } /** * 授权码查询OPENID - * + * * @param authCode * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 * @return 查询结果 @@ -857,7 +904,7 @@ public class WeixinPayProxy { /** * 查询结算资金 - * + * * @param status * 是否结算 * @param pageable @@ -874,14 +921,14 @@ public class WeixinPayProxy { * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7"> * 查询结算资金接口 */ - public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end) - throws WeixinException { + public SettlementRecord querySettlement(boolean status, Pageable pageable, + Date start, Date end) throws WeixinException { return cashApi.querySettlement(status, pageable, start, end); } /** * 查询汇率 - * + * * @param currencyType * 外币币种 * @param date @@ -893,13 +940,14 @@ public class WeixinPayProxy { * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8"> * 查询汇率接口 */ - public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException { + public double queryExchageRate(CurrencyType currencyType, Date date) + throws WeixinException { return cashApi.queryExchageRate(currencyType, date); } /** * 订单附加信息提交 - * + * * @param customsOrder * 附加订单信息 * @return 报关结果 @@ -911,13 +959,14 @@ public class WeixinPayProxy { * 附加订单信息提交接口 * @throws WeixinException */ - public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) throws WeixinException { + public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) + throws WeixinException { return customsApi.declareCustomsOrder(customsOrder); } /** * 订单附加信息查询 - * + * * @param idQuery * out_trade_no,transaction_id,sub_order_no,sub_order_id四选一 * @param customsCity @@ -930,7 +979,8 @@ public class WeixinPayProxy { * 附加订单信息查询接口 * @throws WeixinException */ - public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery, CustomsCity customsCity) throws WeixinException { + public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery, + CustomsCity customsCity) throws WeixinException { return customsApi.queryCustomsOrder(idQuery, customsCity); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/CorpPaymentResult.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/CorpPaymentResult.java index 96d698a4..3f7c58af 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/CorpPaymentResult.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/CorpPaymentResult.java @@ -9,7 +9,7 @@ import com.alibaba.fastjson.annotation.JSONField; /** * 企业付款结果 - * + * * @className CorpPaymentResult * @author jinyu(foxinmy@gmail.com) * @date 2015年4月1日 @@ -44,7 +44,7 @@ public class CorpPaymentResult extends MerchantResult { protected CorpPaymentResult() { // jaxb required } - + public String getTransactionId() { return transactionId; } @@ -61,6 +61,6 @@ public class CorpPaymentResult extends MerchantResult { public String toString() { return "CorpPaymentResult [transactionId=" + transactionId + ", outTradeNo=" + outTradeNo + ", paymentTime=" + paymentTime - + "]"; + + ", " + super.toString() + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java index 24e896e1..06b3f9ef 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java @@ -7,7 +7,7 @@ import com.alibaba.fastjson.annotation.JSONField; /** * 群发消息图文(消息内容存储在微信后台) - * + * * @author jinyu(foxinmy@gmail.com) * @date 2014年4月26日 * @since JDK 1.6 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/ButtonType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/ButtonType.java index 4428c258..b8420d28 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/ButtonType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/ButtonType.java @@ -6,7 +6,7 @@ package com.foxinmy.weixin4j.type; * ,旧版本微信用户点击后将没有回应 * ,开发者也不能正常接收到事件推送。media_id和view_limited,是专门给第三方平台旗下未微信认证(具体而言,是资质认证未通过)的订阅号准备的事件类型 * ,它们是没有事件推送的,能力相对受限,其他类型的公众号不必使用。 - * + * * @className ButtonType * @author jinyu(foxinmy@gmail.com) * @date 2014年9月30日 @@ -62,5 +62,9 @@ public enum ButtonType { * 跳转图文消息URL:用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL, * 永久素材类型只支持图文消息。 请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。 */ - view_limited; + view_limited, + /** + * 以下类型请勿使用,在公众平台设置的按钮类型,如果尝试使用API方式创建菜单则会出错。 + */ + popups,text,img,voice,video,news; } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java index 190683f9..d42d076e 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java @@ -19,10 +19,11 @@ import com.foxinmy.weixin4j.mp.model.SemQuery; import com.foxinmy.weixin4j.mp.model.SemResult; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.tuple.MpArticle; +import com.foxinmy.weixin4j.type.ButtonType; /** * 辅助相关API - * + * * @className HelperApi * @author jinyu(foxinmy@gmail.com) * @date 2014年9月26日 @@ -39,7 +40,7 @@ public class HelperApi extends MpApi { /** * 长链接转短链接 - * + * * @param url * 待转换的链接 * @return 短链接 @@ -62,7 +63,7 @@ public class HelperApi extends MpApi { /** * 语义理解 - * + * * @param semQuery * 语义理解协议 * @return 语义理解结果 @@ -84,7 +85,7 @@ public class HelperApi extends MpApi { /** * 获取微信服务器IP地址 - * + * * @return IP地址 * @see 获取IP地址 @@ -93,8 +94,8 @@ public class HelperApi extends MpApi { public List getWechatServerIp() throws WeixinException { String getcallbackip_uri = getRequestUri("getcallbackip_uri"); Token token = tokenHolder.getToken(); - WeixinResponse response = weixinExecutor.post(String.format(getcallbackip_uri, - token.getAccessToken())); + WeixinResponse response = weixinExecutor.post(String.format( + getcallbackip_uri, token.getAccessToken())); return JSON.parseArray(response.getAsJson().getString("ip_list"), String.class); } @@ -102,7 +103,7 @@ public class HelperApi extends MpApi { /** * 获取公众号当前使用的自定义菜单的配置,如果公众号是通过API调用设置的菜单,则返回菜单的开发配置, * 而如果公众号是在公众平台官网通过网站功能发布菜单,则本接口返回运营者设置的菜单配置。 - * + * * @return 菜单集合 * @see {@link MenuApi#getMenu()} * @see buttonList = new ArrayList