This commit is contained in:
jinyu 2016-05-24 10:23:53 +08:00
parent 816a4ec0ef
commit 866b37c54b
13 changed files with 292 additions and 226 deletions

View File

@ -27,7 +27,7 @@ import com.foxinmy.weixin4j.xml.XmlStream;
/** /**
* 现金API * 现金API
* *
* @className CashApi * @className CashApi
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年3月28日 * @date 2015年3月28日
@ -47,7 +47,7 @@ public class CashApi extends MchApi {
/** /**
* 发放红包 企业向微信用户个人发现金红包 * 发放红包 企业向微信用户个人发现金红包
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param redpacket * @param redpacket
@ -63,7 +63,8 @@ public class CashApi extends MchApi {
* 发放裂变红包接口</a> * 发放裂变红包接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public RedpacketSendResult sendRedpack(InputStream certificate, Redpacket redpacket) throws WeixinException { public RedpacketSendResult sendRedpack(InputStream certificate,
Redpacket redpacket) throws WeixinException {
redpacket.declareWeixinPayAccount(weixinAccount); redpacket.declareWeixinPayAccount(weixinAccount);
JSONObject obj = (JSONObject) JSON.toJSON(redpacket); JSONObject obj = (JSONObject) JSON.toJSON(redpacket);
obj.put("wxappid", obj.remove("appid")); obj.put("wxappid", obj.remove("appid"));
@ -71,8 +72,9 @@ public class CashApi extends MchApi {
String param = XmlStream.map2xml(obj); String param = XmlStream.map2xml(obj);
WeixinResponse response = null; WeixinResponse response = null;
try { try {
response = createSSLRequestExecutor(certificate).post(redpacket.getTotalNum() > 1 response = createSSLRequestExecutor(certificate)
? getRequestUri("groupredpack_send_uri") : getRequestUri("redpack_send_uri"), param); .post(redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri")
: getRequestUri("redpack_send_uri"), param);
} finally { } finally {
if (certificate != null) { if (certificate != null) {
try { try {
@ -82,14 +84,15 @@ public class CashApi extends MchApi {
} }
} }
} }
String text = response.getAsString().replaceFirst("<wxappid>", "<appid>").replaceFirst("</wxappid>", String text = response.getAsString()
"</appid>"); .replaceFirst("<wxappid>", "<appid>")
.replaceFirst("</wxappid>", "</appid>");
return XmlStream.fromXML(text, RedpacketSendResult.class); return XmlStream.fromXML(text, RedpacketSendResult.class);
} }
/** /**
* 查询红包记录 * 查询红包记录
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param outTradeNo * @param outTradeNo
@ -104,7 +107,8 @@ public class CashApi extends MchApi {
* 查询裂变红包接口</a> * 查询裂变红包接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public RedpacketRecord queryRedpack(InputStream certificate, String outTradeNo) throws WeixinException { public RedpacketRecord queryRedpack(InputStream certificate,
String outTradeNo) throws WeixinException {
Map<String, String> para = createBaseRequestMap(null); Map<String, String> para = createBaseRequestMap(null);
para.put("bill_type", "MCHT"); para.put("bill_type", "MCHT");
para.put("mch_billno", outTradeNo); para.put("mch_billno", outTradeNo);
@ -112,7 +116,8 @@ public class CashApi extends MchApi {
String param = XmlStream.map2xml(para); String param = XmlStream.map2xml(para);
WeixinResponse response = null; WeixinResponse response = null;
try { try {
response = createSSLRequestExecutor(certificate).post(getRequestUri("redpack_query_uri"), param); response = createSSLRequestExecutor(certificate).post(
getRequestUri("redpack_query_uri"), param);
} finally { } finally {
if (certificate != null) { if (certificate != null) {
try { try {
@ -128,7 +133,16 @@ public class CashApi extends MchApi {
/** /**
* 企业付款 实现企业向个人付款针对部分有开发能力的商户 提供通过API完成企业付款的功能 比如目前的保险行业向客户退保给付理赔 * 企业付款 实现企业向个人付款针对部分有开发能力的商户 提供通过API完成企业付款的功能 比如目前的保险行业向客户退保给付理赔
* * <p>
* 接口调用规则
* <p>
* <li>给同一个实名用户付款单笔单日限额2W/2W
* <li>给同一个非实名用户付款单笔单日限额2000/2000
* <li>一个商户同一日付款总额限额100W
* <li>单笔最小金额默认为1元
* <li>每个用户每天最多可付款10次可以在商户平台--API安全进行设置
* <li>给同一个用户付款时间间隔不得低于15秒
*
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param payment * @param payment
@ -141,7 +155,8 @@ public class CashApi extends MchApi {
* 企业付款接口</a> * 企业付款接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CorpPaymentResult sendCorpPayment(InputStream certificate, CorpPayment payment) throws WeixinException { public CorpPaymentResult sendCorpPayment(InputStream certificate,
CorpPayment payment) throws WeixinException {
payment.declareWeixinPayAccount(weixinAccount); payment.declareWeixinPayAccount(weixinAccount);
JSONObject obj = (JSONObject) JSON.toJSON(payment); JSONObject obj = (JSONObject) JSON.toJSON(payment);
obj.put("mchid", obj.remove("mch_id")); obj.put("mchid", obj.remove("mch_id"));
@ -150,7 +165,8 @@ public class CashApi extends MchApi {
String param = XmlStream.map2xml(obj); String param = XmlStream.map2xml(obj);
WeixinResponse response = null; WeixinResponse response = null;
try { try {
response = createSSLRequestExecutor(certificate).post(getRequestUri("corppayment_send_uri"), param); response = createSSLRequestExecutor(certificate).post(
getRequestUri("corppayment_send_uri"), param);
} finally { } finally {
if (certificate != null) { if (certificate != null) {
try { try {
@ -160,15 +176,17 @@ public class CashApi extends MchApi {
} }
} }
} }
String text = response.getAsString().replaceFirst("<mch_appid>", "<appid>") String text = response.getAsString()
.replaceFirst("</mch_appid>", "</appid>").replaceFirst("<mchid>", "<mch_id>") .replaceFirst("<mch_appid>", "<appid>")
.replaceFirst("</mch_appid>", "</appid>")
.replaceFirst("<mchid>", "<mch_id>")
.replaceFirst("</mchid>", "</mch_id>"); .replaceFirst("</mchid>", "</mch_id>");
return XmlStream.fromXML(text, CorpPaymentResult.class); return XmlStream.fromXML(text, CorpPaymentResult.class);
} }
/** /**
* 企业付款查询 用于商户的企业付款操作进行结果查询返回付款操作详细结果 * 企业付款查询 用于商户的企业付款操作进行结果查询返回付款操作详细结果
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param outTradeNo * @param outTradeNo
@ -180,7 +198,8 @@ public class CashApi extends MchApi {
* 企业付款查询接口</a> * 企业付款查询接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CorpPaymentRecord queryCorpPayment(InputStream certificate, String outTradeNo) throws WeixinException { public CorpPaymentRecord queryCorpPayment(InputStream certificate,
String outTradeNo) throws WeixinException {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("nonce_str", RandomUtil.generateString(16)); obj.put("nonce_str", RandomUtil.generateString(16));
obj.put("mch_id", weixinAccount.getMchId()); obj.put("mch_id", weixinAccount.getMchId());
@ -190,7 +209,8 @@ public class CashApi extends MchApi {
String param = XmlStream.map2xml(obj); String param = XmlStream.map2xml(obj);
WeixinResponse response = null; WeixinResponse response = null;
try { try {
response = createSSLRequestExecutor(certificate).post(getRequestUri("corppayment_query_uri"), param); response = createSSLRequestExecutor(certificate).post(
getRequestUri("corppayment_query_uri"), param);
} finally { } finally {
if (certificate != null) { if (certificate != null) {
try { try {
@ -206,7 +226,7 @@ public class CashApi extends MchApi {
/** /**
* 查询结算资金 * 查询结算资金
* *
* @param status * @param status
* 是否结算 * 是否结算
* @param pageable * @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"> * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7">
* 查询结算资金接口</a> * 查询结算资金接口</a>
*/ */
public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end) public SettlementRecord querySettlement(boolean status, Pageable pageable,
throws WeixinException { Date start, Date end) throws WeixinException {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("nonce_str", RandomUtil.generateString(16)); obj.put("nonce_str", RandomUtil.generateString(16));
obj.put("mch_id", weixinAccount.getMchId()); obj.put("mch_id", weixinAccount.getMchId());
@ -239,14 +259,15 @@ public class CashApi extends MchApi {
} }
obj.put("sign", weixinSignature.sign(obj)); obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(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<SettlementRecord>() { return response.getAsObject(new TypeReference<SettlementRecord>() {
}); });
} }
/** /**
* 查询汇率 * 查询汇率
* *
* @param currencyType * @param currencyType
* 外币币种 * 外币币种
* @param date * @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"> * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8">
* 查询汇率接口</a> * 查询汇率接口</a>
*/ */
public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException { public double queryExchageRate(CurrencyType currencyType, Date date)
throws WeixinException {
if (date == null) { if (date == null) {
date = new Date(); date = new Date();
} }
@ -269,8 +291,10 @@ public class CashApi extends MchApi {
obj.put("date", DateUtil.fortmat2yyyyMMdd(date)); obj.put("date", DateUtil.fortmat2yyyyMMdd(date));
obj.put("sign", weixinSignature.sign(obj)); obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(obj); String param = XmlStream.map2xml(obj);
WeixinResponse response = weixinExecutor.post(getRequestUri("exchagerate_query_uri"), param); WeixinResponse response = weixinExecutor.post(
BigDecimal rate = new BigDecimal(XmlStream.xml2map(response.getAsString()).get("rate")); getRequestUri("exchagerate_query_uri"), param);
BigDecimal rate = new BigDecimal(XmlStream.xml2map(
response.getAsString()).get("rate"));
return rate.divide(new BigDecimal(100000000d)).doubleValue(); return rate.divide(new BigDecimal(100000000d)).doubleValue();
} }
} }

View File

@ -16,11 +16,11 @@ import com.foxinmy.weixin4j.xml.XmlStream;
/** /**
* 报关接口 * 报关接口
* *
* @className CustomsApi * @className CustomsApi
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2016年3月67日 * @date 2016年3月67日
* @since JDK 1.7 * @since JDK 1.6
* @see * @see
*/ */
public class CustomsApi extends MchApi { public class CustomsApi extends MchApi {
@ -31,7 +31,7 @@ public class CustomsApi extends MchApi {
/** /**
* 订单附加信息提交 * 订单附加信息提交
* *
* @param customsOrder * @param customsOrder
* 附加订单信息 * 附加订单信息
* @return 报关结果 * @return 报关结果
@ -56,7 +56,7 @@ public class CustomsApi extends MchApi {
/** /**
* 订单附加信息查询 * 订单附加信息查询
* *
* @param idQuery * @param idQuery
* out_trade_no,transaction_id,sub_order_no,sub_order_id四选一 * out_trade_no,transaction_id,sub_order_no,sub_order_id四选一
* @param customsCity * @param customsCity

View File

@ -37,12 +37,13 @@ import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse; import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.entity.HttpEntity; import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.SettableFuture; import com.foxinmy.weixin4j.util.SettableFuture;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
/** /**
* Netty 4.x * Netty 4.x
* *
* @className Netty4HttpClient * @className Netty4HttpClient
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年8月30日 * @date 2015年8月30日
@ -183,11 +184,11 @@ public class Netty4HttpClient extends AbstractHttpClient {
if (!headers.containsKey(HttpHeaders.USER_AGENT)) { if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "netty/httpclient"); headers.set(HttpHeaders.USER_AGENT, "netty/httpclient");
} }
for (Entry<String, List<String>> header : headers for (Entry<String, List<String>> header : headers.entrySet()) {
.entrySet()) {
uriRequest.headers().set(header.getKey(), header.getValue()); 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, uriRequest.headers().set(HttpHeaders.CONNECTION,
io.netty.handler.codec.http.HttpHeaders.Values.CLOSE); io.netty.handler.codec.http.HttpHeaders.Values.CLOSE);
return uriRequest; return uriRequest;

View File

@ -12,8 +12,8 @@ import com.foxinmy.weixin4j.http.HttpStatus;
import com.foxinmy.weixin4j.http.HttpVersion; import com.foxinmy.weixin4j.http.HttpVersion;
/** /**
* Netty Respone::Requires Netty 4.x or higher * Netty Response::Requires Netty 4.x or higher
* *
* @className Netty4HttpResponse * @className Netty4HttpResponse
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年8月30日 * @date 2015年8月30日

View File

@ -19,7 +19,6 @@ import com.foxinmy.weixin4j.type.ButtonType;
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年4月5日 * @date 2014年4月5日
* @since JDK 1.6 * @since JDK 1.6
* @see com.foxinmy.weixin4j.type.ButtonType
*/ */
public class Button implements Serializable { public class Button implements Serializable {
@ -37,18 +36,13 @@ public class Button implements Serializable {
*/ */
private ButtonType type; private ButtonType type;
/** /**
* 菜单KEY值,根据type的类型而定,用于消息接口推送,不超过128字节. * 菜单KEY值,根据type的类型而定</p> 通过公众平台设置的自定义菜单</br> <li>text:保存文字 <li>
* <p> * imgvoice保存媒体ID <li>video保存视频URL <li>
* 官网上设置的自定义菜单</br> Text:保存文字到value Imgvoice保存mediaID到value * news保存图文消息:List#com.foxinmy.weixin4j.tuple.MpArticle# <li>view保存链接URL
* Video保存视频下载链接到value</br> News保存图文消息到news_info View保存链接到url</br> * <p>使用API设置的自定义菜单</p> <li>
* <p> * clickscancode_pushscancode_waitmsgpic_sysphotopic_photo_or_album
* 使用API设置的自定义菜单</br> * pic_weixinlocation_select保存key <li>view保存链接URL; <li>
* clickscancode_pushscancode_waitmsgpic_sysphotopic_photo_or_album * media_idview_limited保存媒体ID
* </br>
* pic_weixinlocation_select保存为keyview保存为url;media_idview_limited
* 保存为media_id
* </p>
* </p>
*/ */
private Serializable content; private Serializable content;
/** /**

View File

@ -45,7 +45,7 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings;
/** /**
* 微信支付接口实现 * 微信支付接口实现
* *
* @className WeixinPayProxy * @className WeixinPayProxy
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年1月3日 * @date 2015年1月3日
@ -98,7 +98,7 @@ public class WeixinPayProxy {
/** /**
* 获取微信商户支付信息 * 获取微信商户支付信息
* *
* @return * @return
*/ */
public WeixinPayAccount getPayAccount() { public WeixinPayAccount getPayAccount() {
@ -109,7 +109,7 @@ public class WeixinPayProxy {
* 统一下单接口</br> * 统一下单接口</br>
* 除被扫支付场景以外商户系统先调用该接口在微信支付服务后台生成预支付交易单返回正确的预支付交易回话标识后再按扫码JSAPI * 除被扫支付场景以外商户系统先调用该接口在微信支付服务后台生成预支付交易单返回正确的预支付交易回话标识后再按扫码JSAPI
* APP等不同场景生成交易串调起支付 * APP等不同场景生成交易串调起支付
* *
* @param payPackage * @param payPackage
* 包含订单信息的对象 * 包含订单信息的对象
* @see com.foxinmy.weixin4j.api.PayApi * @see com.foxinmy.weixin4j.api.PayApi
@ -126,7 +126,7 @@ public class WeixinPayProxy {
/** /**
* 创建支付请求对象 * 创建支付请求对象
* *
* @param payPackage * @param payPackage
* 支付详情 * 支付详情
* @return 支付请求对象 * @return 支付请求对象
@ -138,13 +138,14 @@ public class WeixinPayProxy {
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付 * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException { public MchPayRequest createPayRequest(MchPayPackage payPackage)
throws WeixinException {
return payApi.createPayRequest(payPackage); return payApi.createPayRequest(payPackage);
} }
/** /**
* 创建支付请求对象完整参数 * 创建支付请求对象完整参数
* *
* @param body * @param body
* 商品描述 <font color="red">必填项</font> * 商品描述 <font color="red">必填项</font>
* @param detail * @param detail
@ -184,17 +185,20 @@ public class WeixinPayProxy {
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付 * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createPayRequest(String body, String detail, String outTradeNo, double totalFee, public MchPayRequest createPayRequest(String body, String detail,
String notifyUrl, String createIp, TradeType tradeType, String openId, String productId, String attach, String outTradeNo, double totalFee, String notifyUrl,
Date timeStart, Date timeExpire, String goodsTag, String limitPay, String subOpenId) String createIp, TradeType tradeType, String openId,
String productId, String attach, Date timeStart, Date timeExpire,
String goodsTag, String limitPay, String subOpenId)
throws WeixinException { throws WeixinException {
return payApi.createPayRequest(body, detail, outTradeNo, totalFee, notifyUrl, createIp, tradeType, openId, return payApi.createPayRequest(body, detail, outTradeNo, totalFee,
productId, attach, timeStart, timeExpire, goodsTag, limitPay, subOpenId); notifyUrl, createIp, tradeType, openId, productId, attach,
timeStart, timeExpire, goodsTag, limitPay, subOpenId);
} }
/** /**
* 创建JSAPI支付请求对象 * 创建JSAPI支付请求对象
* *
* @param openId * @param openId
* 用户ID * 用户ID
* @param body * @param body
@ -214,27 +218,24 @@ public class WeixinPayProxy {
* @return JSAPI支付对象 * @return JSAPI支付对象
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee, public MchPayRequest createJSPayRequest(String openId, String body,
String notifyUrl, String createIp, String attach) throws WeixinException { String outTradeNo, double totalFee, String notifyUrl,
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach); String createIp, String attach) throws WeixinException {
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
} }
/** /**
* <p> * <p>
* 生成编辑地址请求 * 生成编辑地址请求
* </p> * </p>
* *
* err_msg edit_address:ok获取编辑收货地址成功</br> * err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br>
* edit_address:fail获取编辑收货地址失败</br> * userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br>
* userName 收货人姓名</br> * proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName
* telNumber 收货人电话</br> * 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressPostalCode 邮编</br> * addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br>
* proviceFirstStageName 国标收货地址第一级地址</br> *
* addressCitySecondStageName 国标收货地址第二级地址</br>
* addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br>
* nationalCode 收货地址国家码</br>
*
* @param url * @param url
* 当前访问页的URL * 当前访问页的URL
* @param oauthToken * @param oauthToken
@ -251,7 +252,7 @@ public class WeixinPayProxy {
/** /**
* 创建Native支付(扫码支付)链接模式一 * 创建Native支付(扫码支付)链接模式一
* *
* @param productId * @param productId
* 与订单ID等价 * 与订单ID等价
* @return 支付链接 * @return 支付链接
@ -269,7 +270,7 @@ public class WeixinPayProxy {
/** /**
* 创建Native支付(扫码支付)回调对象模式一 * 创建Native支付(扫码支付)回调对象模式一
* *
* @param productId * @param productId
* 商品ID * 商品ID
* @param body * @param body
@ -295,14 +296,16 @@ public class WeixinPayProxy {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee, public NativePayResponse createNativePayResponse(String productId,
String notifyUrl, String createIp, String attach) throws WeixinException { String body, String outTradeNo, double totalFee, String notifyUrl,
return payApi.createNativePayResponse(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach); String createIp, String attach) throws WeixinException {
return payApi.createNativePayResponse(productId, body, outTradeNo,
totalFee, notifyUrl, createIp, attach);
} }
/** /**
* 创建Native支付(扫码支付)链接模式二 * 创建Native支付(扫码支付)链接模式二
* *
* @param productId * @param productId
* 商品ID * 商品ID
* @param body * @param body
@ -328,14 +331,16 @@ public class WeixinPayProxy {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee, public MchPayRequest createNativePayRequest(String productId, String body,
String notifyUrl, String createIp, String attach) throws WeixinException { String outTradeNo, double totalFee, String notifyUrl,
return payApi.createNativePayRequest(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach); String createIp, String attach) throws WeixinException {
return payApi.createNativePayRequest(productId, body, outTradeNo,
totalFee, notifyUrl, createIp, attach);
} }
/** /**
* 创建APP支付请求对象 * 创建APP支付请求对象
* *
* @param body * @param body
* 商品描述 * 商品描述
* @param outTradeNo * @param outTradeNo
@ -356,14 +361,16 @@ public class WeixinPayProxy {
* APP支付</a> * APP支付</a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl, public MchPayRequest createAppPayRequest(String body, String outTradeNo,
String createIp, String attach) throws WeixinException { double totalFee, String notifyUrl, String createIp, String attach)
return payApi.createAppPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach); throws WeixinException {
return payApi.createAppPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
} }
/** /**
* 创建WAP支付请求对象 * 创建WAP支付请求对象
* *
* @param body * @param body
* 商品描述 * 商品描述
* @param outTradeNo * @param outTradeNo
@ -384,14 +391,16 @@ public class WeixinPayProxy {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createWAPPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl, public MchPayRequest createWAPPayRequest(String body, String outTradeNo,
String createIp, String attach) throws WeixinException { double totalFee, String notifyUrl, String createIp, String attach)
return payApi.createWAPPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach); throws WeixinException {
return payApi.createWAPPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
} }
/** /**
* 提交被扫支付 * 提交被扫支付
* *
* @param authCode * @param authCode
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息 * 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
* @param body * @param body
@ -413,20 +422,20 @@ public class WeixinPayProxy {
* 提交被扫支付API</a> * 提交被扫支付API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createMICROPayRequest(String authCode, String body, String outTradeNo, double totalFee, public MchPayRequest createMICROPayRequest(String authCode, String body,
String createIp, String attach) throws WeixinException { String outTradeNo, double totalFee, String createIp, String attach)
return payApi.createMICROPayRequest(authCode, body, outTradeNo, totalFee, createIp, attach); throws WeixinException {
return payApi.createMICROPayRequest(authCode, body, outTradeNo,
totalFee, createIp, attach);
} }
/** /**
* 订单查询 * 订单查询
* <p> * <p>
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> * 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用支付接口后返回系统错误或未知交易状态情况</br> * 调用被扫支付API返回USERPAYING的状态</br> 调用关单或撤销接口API之前需确认支付状态
* 调用被扫支付API返回USERPAYING的状态</br>
* 调用关单或撤销接口API之前需确认支付状态
* </P> * </P>
* *
* @param idQuery * @param idQuery
* 商户系统内部的订单号, transaction_idout_trade_no 选一,如果同时存在优先级: * 商户系统内部的订单号, transaction_idout_trade_no 选一,如果同时存在优先级:
* transaction_id> out_trade_no * transaction_id> out_trade_no
@ -454,7 +463,7 @@ public class WeixinPayProxy {
* 2.微信支付退款支持单笔交易分多次退款多次退款需要提交原支付订单的商户订单号和设置不同的退款单号一笔退款失败后重新提交 * 2.微信支付退款支持单笔交易分多次退款多次退款需要提交原支付订单的商户订单号和设置不同的退款单号一笔退款失败后重新提交
* 要采用原来的退款单号总退款金额不能超过用户实际支付金额 * 要采用原来的退款单号总退款金额不能超过用户实际支付金额
* </p> * </p>
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param idQuery * @param idQuery
@ -470,7 +479,7 @@ public class WeixinPayProxy {
* 货币类型符合ISO 4217标准的三位字母代码默认人民币CNY * 货币类型符合ISO 4217标准的三位字母代码默认人民币CNY
* @param opUserId * @param opUserId
* 操作员帐号, 默认为商户号 * 操作员帐号, 默认为商户号
* *
* @return 退款申请结果 * @return 退款申请结果
* @see com.foxinmy.weixin4j.payment.mch.RefundResult * @see com.foxinmy.weixin4j.payment.mch.RefundResult
* @see com.foxinmy.weixin4j.api.PayApi * @see com.foxinmy.weixin4j.api.PayApi
@ -480,21 +489,25 @@ public class WeixinPayProxy {
* @since V3 * @since V3
* @throws WeixinException * @throws WeixinException
*/ */
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee, public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
double refundFee, CurrencyType refundFeeType, String opUserId) throws WeixinException { String outRefundNo, double totalFee, double refundFee,
return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee, refundFee, refundFeeType, opUserId); CurrencyType refundFeeType, String opUserId) throws WeixinException {
return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee,
refundFee, refundFeeType, opUserId);
} }
/** /**
* 退款申请(全额退款) * 退款申请(全额退款)
* *
* @throws IOException * @throws IOException
* *
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String,CurrencyType)} * @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String,CurrencyType)}
*/ */
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
throws WeixinException, IOException { double totalFee) throws WeixinException, IOException {
return payApi.applyRefund(new FileInputStream(settings.getCertificateFile0()), idQuery, outRefundNo, totalFee); return payApi.applyRefund(
new FileInputStream(settings.getCertificateFile0()), idQuery,
outRefundNo, totalFee);
} }
/** /**
@ -502,7 +515,7 @@ public class WeixinPayProxy {
* <p> * <p>
* 提交退款申请后通过调用该接口查询退款状态退款有一定延时用零钱支付的退款20分钟内到账银行卡支付的退款3个工作日后重新查询退款状态 * 提交退款申请后通过调用该接口查询退款状态退款有一定延时用零钱支付的退款20分钟内到账银行卡支付的退款3个工作日后重新查询退款状态
* </p> * </p>
* *
* @param idQuery * @param idQuery
* 单号 refund_idout_refund_no out_trade_no transaction_id * 单号 refund_idout_refund_no out_trade_no transaction_id
* 四个参数必填一个,优先级为: * 四个参数必填一个,优先级为:
@ -526,7 +539,7 @@ public class WeixinPayProxy {
* REVOKED;<br> * REVOKED;<br>
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br> * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
* 3.对账单中涉及金额的字段单位为<br> * 3.对账单中涉及金额的字段单位为<br>
* *
* @param billDate * @param billDate
* 下载对账单的日期 * 下载对账单的日期
* @param billType * @param billType
@ -540,18 +553,17 @@ public class WeixinPayProxy {
* 下载对账单API</a> * 下载对账单API</a>
* @throws WeixinException * @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()); return payApi.downloadBill(billDate, billType, settings.getTmpdir0());
} }
/** /**
* 冲正订单(需要证书)</br> * 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:
* 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> * 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
* 接口逻辑: 付失败的关单,支付成功的撤销支付</br> * 如需实现相同功能请调用退款接口</font></br> <font
* <font color="red">7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口</font></br> * color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font> </br>
* <font color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font> *
* </br>
*
* @param certificate * @param certificate
* 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12) * 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12)
* @param idQuery * @param idQuery
@ -562,13 +574,14 @@ public class WeixinPayProxy {
* @since V3 * @since V3
* @throws WeixinException * @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); return payApi.reverseOrder(certificate, idQuery);
} }
/** /**
* 冲正撤销 * 冲正撤销
* *
* @param idQuery * @param idQuery
* transaction_idout_trade_no 二选一 * transaction_idout_trade_no 二选一
* @return 撤销结果 * @return 撤销结果
@ -576,8 +589,10 @@ public class WeixinPayProxy {
* @throws WeixinException * @throws WeixinException
* @throws IOException * @throws IOException
*/ */
public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException, IOException { public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException,
return payApi.reverseOrder(new FileInputStream(settings.getCertificateFile0()), idQuery); IOException {
return payApi.reverseOrder(
new FileInputStream(settings.getCertificateFile0()), idQuery);
} }
/** /**
@ -586,7 +601,7 @@ public class WeixinPayProxy {
* 商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续 * 商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续
* 请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理如果出现银行掉单,调用关单成功后,微信后台会主动发起退款 * 请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理如果出现银行掉单,调用关单成功后,微信后台会主动发起退款
* </p> * </p>
* *
* @param outTradeNo * @param outTradeNo
* 商户系统内部的订单号 * 商户系统内部的订单号
* @return 执行结果 * @return 执行结果
@ -604,7 +619,7 @@ public class WeixinPayProxy {
/** /**
* native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX)减小二维码数据量 * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX)减小二维码数据量
* 提升扫描速度和精确度 * 提升扫描速度和精确度
* *
* @param url * @param url
* 具有native标识的支付URL * 具有native标识的支付URL
* @return 转换后的短链接 * @return 转换后的短链接
@ -621,7 +636,7 @@ public class WeixinPayProxy {
/** /**
* 接口上报 * 接口上报
* *
* @param interfaceUrl * @param interfaceUrl
* 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q
* q.com/pay/unifiedorder * q.com/pay/unifiedorder
@ -642,14 +657,16 @@ public class WeixinPayProxy {
* 接口测试上报API</a> * 接口测试上报API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public XmlResult interfaceReport(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time, public XmlResult interfaceReport(String interfaceUrl, int executeTime,
XmlResult returnXml) throws WeixinException { String outTradeNo, String ip, Date time, XmlResult returnXml)
return payApi.interfaceReport(interfaceUrl, executeTime, outTradeNo, ip, time, returnXml); throws WeixinException {
return payApi.interfaceReport(interfaceUrl, executeTime, outTradeNo,
ip, time, returnXml);
} }
/** /**
* 发放代金券(需要证书) * 发放代金券(需要证书)
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param couponStockId * @param couponStockId
@ -668,25 +685,28 @@ public class WeixinPayProxy {
* 发放代金券接口</a> * 发放代金券接口</a>
* @throws WeixinException * @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 { 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)} * @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendCoupon(InputStream, String, String, String, String)}
*/ */
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, String openId) public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
throws WeixinException, IOException { String openId) throws WeixinException, IOException {
return couponApi.sendCoupon(new FileInputStream(settings.getCertificateFile0()), couponStockId, partnerTradeNo, return couponApi.sendCoupon(
openId, null); new FileInputStream(settings.getCertificateFile0()),
couponStockId, partnerTradeNo, openId, null);
} }
/** /**
* 查询代金券批次 * 查询代金券批次
* *
* @param couponStockId * @param couponStockId
* 代金券批次ID * 代金券批次ID
* @return 代金券批次信息 * @return 代金券批次信息
@ -697,13 +717,14 @@ public class WeixinPayProxy {
* 查询代金券批次信息接口</a> * 查询代金券批次信息接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CouponStock queryCouponStock(String couponStockId) throws WeixinException { public CouponStock queryCouponStock(String couponStockId)
throws WeixinException {
return couponApi.queryCouponStock(couponStockId); return couponApi.queryCouponStock(couponStockId);
} }
/** /**
* 查询代金券详细 * 查询代金券详细
* *
* @param couponId * @param couponId
* 代金券ID * 代金券ID
* @return 代金券详细信息 * @return 代金券详细信息
@ -714,13 +735,14 @@ public class WeixinPayProxy {
* 查询代金券详细信息接口</a> * 查询代金券详细信息接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CouponDetail queryCouponDetail(String couponId) throws WeixinException { public CouponDetail queryCouponDetail(String couponId)
throws WeixinException {
return couponApi.queryCouponDetail(couponId); return couponApi.queryCouponDetail(couponId);
} }
/** /**
* 发放红包 企业向微信用户个人发现金红包 * 发放红包 企业向微信用户个人发现金红包
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param redpacket * @param redpacket
@ -737,22 +759,25 @@ public class WeixinPayProxy {
* 发放裂变红包接口</a> * 发放裂变红包接口</a>
* @throws WeixinException * @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); return cashApi.sendRedpack(certificate, redpacket);
} }
/** /**
* 发放红包 * 发放红包
* *
* @see {@link #sendRedpack(InputStream, Redpacket)} * @see {@link #sendRedpack(InputStream, Redpacket)}
*/ */
public RedpacketSendResult sendRedpack(Redpacket redpacket) throws WeixinException, IOException { public RedpacketSendResult sendRedpack(Redpacket redpacket)
return cashApi.sendRedpack(new FileInputStream(settings.getCertificateFile0()), redpacket); throws WeixinException, IOException {
return cashApi.sendRedpack(
new FileInputStream(settings.getCertificateFile0()), redpacket);
} }
/** /**
* 查询红包记录 * 查询红包记录
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param outTradeNo * @param outTradeNo
@ -768,22 +793,36 @@ public class WeixinPayProxy {
* 查询裂变红包接口</a> * 查询裂变红包接口</a>
* @throws WeixinException * @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); return cashApi.queryRedpack(certificate, outTradeNo);
} }
/** /**
* 查询红包 * 查询红包
* *
* @see {@link #queryRedpack(InputStream,String)} * @see {@link #queryRedpack(InputStream,String)}
*/ */
public RedpacketRecord queryRedpack(String outTradeNo) throws WeixinException, IOException { public RedpacketRecord queryRedpack(String outTradeNo)
return cashApi.queryRedpack(new FileInputStream(settings.getCertificateFile0()), outTradeNo); throws WeixinException, IOException {
return cashApi
.queryRedpack(
new FileInputStream(settings.getCertificateFile0()),
outTradeNo);
} }
/** /**
* 企业付款 实现企业向个人付款针对部分有开发能力的商户 提供通过API完成企业付款的功能 比如目前的保险行业向客户退保给付理赔 * 企业付款 实现企业向个人付款针对部分有开发能力的商户 提供通过API完成企业付款的功能 比如目前的保险行业向客户退保给付理赔
* * <p>
* 接口调用规则
* <p>
* <li>给同一个实名用户付款单笔单日限额2W/2W
* <li>给同一个非实名用户付款单笔单日限额2000/2000
* <li>一个商户同一日付款总额限额100W
* <li>单笔最小金额默认为1元
* <li>每个用户每天最多可付款10次可以在商户平台--API安全进行设置
* <li>给同一个用户付款时间间隔不得低于15秒
*
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param payment * @param payment
@ -797,22 +836,25 @@ public class WeixinPayProxy {
* 企业付款接口</a> * 企业付款接口</a>
* @throws WeixinException * @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); return cashApi.sendCorpPayment(certificate, payment);
} }
/** /**
* 企业付款 * 企业付款
* *
* @see {@link #sendCorpPayment(InputStream, CorpPayment)} * @see {@link #sendCorpPayment(InputStream, CorpPayment)}
*/ */
public CorpPaymentResult sendCorpPayment(CorpPayment payment) throws WeixinException, IOException { public CorpPaymentResult sendCorpPayment(CorpPayment payment)
return cashApi.sendCorpPayment(new FileInputStream(settings.getCertificateFile0()), payment); throws WeixinException, IOException {
return cashApi.sendCorpPayment(
new FileInputStream(settings.getCertificateFile0()), payment);
} }
/** /**
* 企业付款查询 用于商户的企业付款操作进行结果查询返回付款操作详细结果 * 企业付款查询 用于商户的企业付款操作进行结果查询返回付款操作详细结果
* *
* @param certificate * @param certificate
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param outTradeNo * @param outTradeNo
@ -825,22 +867,27 @@ public class WeixinPayProxy {
* 企业付款查询接口</a> * 企业付款查询接口</a>
* @throws WeixinException * @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); return cashApi.queryCorpPayment(certificate, outTradeNo);
} }
/** /**
* 企业付款查询 * 企业付款查询
* *
* @see {@link #CorpPaymentRecord(InputStream, String)} * @see {@link #CorpPaymentRecord(InputStream, String)}
*/ */
public CorpPaymentRecord queryCorpPayment(String outTradeNo) throws WeixinException, IOException { public CorpPaymentRecord queryCorpPayment(String outTradeNo)
return cashApi.queryCorpPayment(new FileInputStream(settings.getCertificateFile0()), outTradeNo); throws WeixinException, IOException {
return cashApi
.queryCorpPayment(
new FileInputStream(settings.getCertificateFile0()),
outTradeNo);
} }
/** /**
* 授权码查询OPENID * 授权码查询OPENID
* *
* @param authCode * @param authCode
* 扫码支付授权码设备读取用户微信中的条码或者二维码信息 * 扫码支付授权码设备读取用户微信中的条码或者二维码信息
* @return 查询结果 * @return 查询结果
@ -857,7 +904,7 @@ public class WeixinPayProxy {
/** /**
* 查询结算资金 * 查询结算资金
* *
* @param status * @param status
* 是否结算 * 是否结算
* @param pageable * @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"> * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7">
* 查询结算资金接口</a> * 查询结算资金接口</a>
*/ */
public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end) public SettlementRecord querySettlement(boolean status, Pageable pageable,
throws WeixinException { Date start, Date end) throws WeixinException {
return cashApi.querySettlement(status, pageable, start, end); return cashApi.querySettlement(status, pageable, start, end);
} }
/** /**
* 查询汇率 * 查询汇率
* *
* @param currencyType * @param currencyType
* 外币币种 * 外币币种
* @param date * @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"> * "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8">
* 查询汇率接口</a> * 查询汇率接口</a>
*/ */
public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException { public double queryExchageRate(CurrencyType currencyType, Date date)
throws WeixinException {
return cashApi.queryExchageRate(currencyType, date); return cashApi.queryExchageRate(currencyType, date);
} }
/** /**
* 订单附加信息提交 * 订单附加信息提交
* *
* @param customsOrder * @param customsOrder
* 附加订单信息 * 附加订单信息
* @return 报关结果 * @return 报关结果
@ -911,13 +959,14 @@ public class WeixinPayProxy {
* 附加订单信息提交接口</a> * 附加订单信息提交接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) throws WeixinException { public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder)
throws WeixinException {
return customsApi.declareCustomsOrder(customsOrder); return customsApi.declareCustomsOrder(customsOrder);
} }
/** /**
* 订单附加信息查询 * 订单附加信息查询
* *
* @param idQuery * @param idQuery
* out_trade_no,transaction_id,sub_order_no,sub_order_id四选一 * out_trade_no,transaction_id,sub_order_no,sub_order_id四选一
* @param customsCity * @param customsCity
@ -930,7 +979,8 @@ public class WeixinPayProxy {
* 附加订单信息查询接口</a> * 附加订单信息查询接口</a>
* @throws WeixinException * @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); return customsApi.queryCustomsOrder(idQuery, customsCity);
} }

View File

@ -9,7 +9,7 @@ import com.alibaba.fastjson.annotation.JSONField;
/** /**
* 企业付款结果 * 企业付款结果
* *
* @className CorpPaymentResult * @className CorpPaymentResult
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年4月1日 * @date 2015年4月1日
@ -44,7 +44,7 @@ public class CorpPaymentResult extends MerchantResult {
protected CorpPaymentResult() { protected CorpPaymentResult() {
// jaxb required // jaxb required
} }
public String getTransactionId() { public String getTransactionId() {
return transactionId; return transactionId;
} }
@ -61,6 +61,6 @@ public class CorpPaymentResult extends MerchantResult {
public String toString() { public String toString() {
return "CorpPaymentResult [transactionId=" + transactionId return "CorpPaymentResult [transactionId=" + transactionId
+ ", outTradeNo=" + outTradeNo + ", paymentTime=" + paymentTime + ", outTradeNo=" + outTradeNo + ", paymentTime=" + paymentTime
+ "]"; + ", " + super.toString() + "]";
} }
} }

View File

@ -7,7 +7,7 @@ import com.alibaba.fastjson.annotation.JSONField;
/** /**
* 群发消息图文(消息内容存储在微信后台) * 群发消息图文(消息内容存储在微信后台)
* *
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年4月26日 * @date 2014年4月26日
* @since JDK 1.6 * @since JDK 1.6

View File

@ -6,7 +6,7 @@ package com.foxinmy.weixin4j.type;
* 旧版本微信用户点击后将没有回应 * 旧版本微信用户点击后将没有回应
* 开发者也不能正常接收到事件推送media_id和view_limited是专门给第三方平台旗下未微信认证具体而言是资质认证未通过的订阅号准备的事件类型 * 开发者也不能正常接收到事件推送media_id和view_limited是专门给第三方平台旗下未微信认证具体而言是资质认证未通过的订阅号准备的事件类型
* 它们是没有事件推送的能力相对受限其他类型的公众号不必使用</font> * 它们是没有事件推送的能力相对受限其他类型的公众号不必使用</font>
* *
* @className ButtonType * @className ButtonType
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年9月30日 * @date 2014年9月30日
@ -62,5 +62,9 @@ public enum ButtonType {
* 跳转图文消息URL:用户点击view_limited类型按钮后微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL * 跳转图文消息URL:用户点击view_limited类型按钮后微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL
* 永久素材类型只支持图文消息 请注意永久素材id必须是在素材管理/新增永久素材接口上传后获得的合法id * 永久素材类型只支持图文消息 请注意永久素材id必须是在素材管理/新增永久素材接口上传后获得的合法id
*/ */
view_limited; view_limited,
/**
* 以下类型请勿使用,在公众平台设置的按钮类型,如果尝试使用API方式创建菜单则会出错
*/
popups,text,img,voice,video,news;
} }

View File

@ -19,10 +19,11 @@ import com.foxinmy.weixin4j.mp.model.SemQuery;
import com.foxinmy.weixin4j.mp.model.SemResult; import com.foxinmy.weixin4j.mp.model.SemResult;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.ButtonType;
/** /**
* 辅助相关API * 辅助相关API
* *
* @className HelperApi * @className HelperApi
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年9月26日 * @date 2014年9月26日
@ -39,7 +40,7 @@ public class HelperApi extends MpApi {
/** /**
* 长链接转短链接 * 长链接转短链接
* *
* @param url * @param url
* 待转换的链接 * 待转换的链接
* @return 短链接 * @return 短链接
@ -62,7 +63,7 @@ public class HelperApi extends MpApi {
/** /**
* 语义理解 * 语义理解
* *
* @param semQuery * @param semQuery
* 语义理解协议 * 语义理解协议
* @return 语义理解结果 * @return 语义理解结果
@ -84,7 +85,7 @@ public class HelperApi extends MpApi {
/** /**
* 获取微信服务器IP地址 * 获取微信服务器IP地址
* *
* @return IP地址 * @return IP地址
* @see <a * @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140187&token=&lang=zh_CN">获取IP地址</a> * href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140187&token=&lang=zh_CN">获取IP地址</a>
@ -93,8 +94,8 @@ public class HelperApi extends MpApi {
public List<String> getWechatServerIp() throws WeixinException { public List<String> getWechatServerIp() throws WeixinException {
String getcallbackip_uri = getRequestUri("getcallbackip_uri"); String getcallbackip_uri = getRequestUri("getcallbackip_uri");
Token token = tokenHolder.getToken(); Token token = tokenHolder.getToken();
WeixinResponse response = weixinExecutor.post(String.format(getcallbackip_uri, WeixinResponse response = weixinExecutor.post(String.format(
token.getAccessToken())); getcallbackip_uri, token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("ip_list"), return JSON.parseArray(response.getAsJson().getString("ip_list"),
String.class); String.class);
} }
@ -102,7 +103,7 @@ public class HelperApi extends MpApi {
/** /**
* 获取公众号当前使用的自定义菜单的配置如果公众号是通过API调用设置的菜单则返回菜单的开发配置 * 获取公众号当前使用的自定义菜单的配置如果公众号是通过API调用设置的菜单则返回菜单的开发配置
* 而如果公众号是在公众平台官网通过网站功能发布菜单则本接口返回运营者设置的菜单配置 * 而如果公众号是在公众平台官网通过网站功能发布菜单则本接口返回运营者设置的菜单配置
* *
* @return 菜单集合 * @return 菜单集合
* @see {@link MenuApi#getMenu()} * @see {@link MenuApi#getMenu()}
* @see <a * @see <a
@ -115,10 +116,9 @@ public class HelperApi extends MpApi {
public MenuSetting getMenuSetting() throws WeixinException { public MenuSetting getMenuSetting() throws WeixinException {
String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri"); String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri");
Token token = tokenHolder.getToken(); Token token = tokenHolder.getToken();
WeixinResponse response = weixinExecutor.get(String.format(menu_get_selfmenu_uri, WeixinResponse response = weixinExecutor.get(String.format(
token.getAccessToken())); menu_get_selfmenu_uri, token.getAccessToken()));
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
JSONArray buttons = result.getJSONObject("selfmenu_info").getJSONArray( JSONArray buttons = result.getJSONObject("selfmenu_info").getJSONArray(
"button"); "button");
List<Button> buttonList = new ArrayList<Button>(buttons.size()); List<Button> buttonList = new ArrayList<Button>(buttons.size());
@ -128,6 +128,7 @@ public class HelperApi extends MpApi {
if (buttonObj.containsKey("sub_button")) { if (buttonObj.containsKey("sub_button")) {
JSONPath.set(buttonObj, "$.sub_button", buttonObj JSONPath.set(buttonObj, "$.sub_button", buttonObj
.getJSONObject("sub_button").getJSONArray("list")); .getJSONObject("sub_button").getJSONArray("list"));
buttonObj.put("type", ButtonType.popups);
} }
buttonList.add(JSON.parseObject(buttonObj.toJSONString(), buttonList.add(JSON.parseObject(buttonObj.toJSONString(),
Button.class, ButtonExtraProcessor.global)); Button.class, ButtonExtraProcessor.global));
@ -147,9 +148,15 @@ public class HelperApi extends MpApi {
if (key.equals("news_info")) { if (key.equals("news_info")) {
JSONArray news = ((JSONObject) value).getJSONArray("list"); JSONArray news = ((JSONObject) value).getJSONArray("list");
List<MpArticle> newsList = new ArrayList<MpArticle>(news.size()); List<MpArticle> newsList = new ArrayList<MpArticle>(news.size());
JSONObject article = null;
for (int i = 0; i < news.size(); i++) { for (int i = 0; i < news.size(); i++) {
newsList.add(JSON.parseObject(news.getString(i), article = news.getJSONObject(i);
MpArticle.class, ArticleExtraProcessor.global)); article.put("showCoverPic", article.remove("show_cover"));
article.put("coverUrl", article.remove("cover_url"));
article.put("contentUrl", article.remove("content_url"));
article.put("sourceUrl", article.remove("source_url"));
newsList.add(JSON.parseObject(article.toJSONString(),
MpArticle.class));
} }
JSONPath.set(object, "$.content", newsList); JSONPath.set(object, "$.content", newsList);
} else { } else {
@ -158,28 +165,9 @@ public class HelperApi extends MpApi {
} }
}; };
private static final class ArticleExtraProcessor implements ExtraProcessor {
private static final ArticleExtraProcessor global = new ArticleExtraProcessor();
private ArticleExtraProcessor() {
}
@Override
public void processExtra(Object object, String key, Object value) {
MpArticle mpArticle = (MpArticle) object;
if (key.equals("show_cover")) {
mpArticle.setShowCoverPic(value.equals("1"));
}
if (key.equals("source_url")) {
mpArticle.setSourceUrl(value.toString());
}
}
}
/** /**
* 获取公众号当前使用的自动回复规则包括关注后自动回复消息自动回复60分钟内触发一次关键词自动回复 * 获取公众号当前使用的自动回复规则包括关注后自动回复消息自动回复60分钟内触发一次关键词自动回复
* *
* @see com.foxinmy.weixin4j.mp.model.AutoReplySetting * @see com.foxinmy.weixin4j.mp.model.AutoReplySetting
* @see <a * @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751299&token=&lang=zh_CN">获取自动回复规则</a> * href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751299&token=&lang=zh_CN">获取自动回复规则</a>

View File

@ -9,7 +9,16 @@ import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.mp.api.HelperApi; import com.foxinmy.weixin4j.mp.api.HelperApi;
public class HelpTest extends TokenTest { /**
* 辅助API测试
*
* @className HelperTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年5月24日
* @since JDK 1.6
* @see
*/
public class HelperTest extends TokenTest {
private HelperApi helperApi; private HelperApi helperApi;
@Before @Before

View File

@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.util.ServerToolkits;
/** /**
* 微信回复编码类 * 微信回复编码类
* *
* @className WeixinResponseEncoder * @className WeixinResponseEncoder
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年11月13日 * @date 2014年11月13日

View File

@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.startup.WeixinServerBootstrap;
/** /**
* HTTP工具类 * HTTP工具类
* *
* @className HttpUtil * @className HttpUtil
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年11月15日 * @date 2014年11月15日
@ -31,15 +31,11 @@ public class HttpUtil {
/** /**
* 创建有内容的HttpResponse响应 * 创建有内容的HttpResponse响应
* *
* @param content * @param content
* 响应内容 * 响应内容
* @param status
* 响应状态
* @param contentType * @param contentType
* 响应类型 * 响应类型
* @param request
* 请求对象
* @return HttpResponse * @return HttpResponse
*/ */
public static HttpResponse createHttpResponse(String content, public static HttpResponse createHttpResponse(String content,
@ -58,12 +54,12 @@ public class HttpUtil {
} }
public static void resolveHeaders(FullHttpResponse httpResponse) { public static void resolveHeaders(FullHttpResponse httpResponse) {
/*if (HttpHeaders.isKeepAlive(httpRequest)) { /*
httpResponse.headers().set(CONNECTION, Values.KEEP_ALIVE); * if (HttpHeaders.isKeepAlive(httpRequest)) {
} * httpResponse.headers().set(CONNECTION, Values.KEEP_ALIVE); } if
if (HttpHeaders.isTransferEncodingChunked(httpRequest)) { * (HttpHeaders.isTransferEncodingChunked(httpRequest)) {
httpResponse.headers().set(TRANSFER_ENCODING, Values.CHUNKED); * httpResponse.headers().set(TRANSFER_ENCODING, Values.CHUNKED); }
}*/ */
httpResponse.headers().set(DATE, new Date()); httpResponse.headers().set(DATE, new Date());
httpResponse.headers().set(SERVER, SERVER); httpResponse.headers().set(SERVER, SERVER);
httpResponse.headers() httpResponse.headers()