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

@ -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,8 +84,9 @@ 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);
} }
@ -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,6 +133,15 @@ 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的证书文件
@ -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,8 +176,10 @@ 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);
} }
@ -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 {
@ -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,7 +259,8 @@ 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>() {
}); });
} }
@ -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

@ -20,7 +20,7 @@ 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 {

View File

@ -37,6 +37,7 @@ 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;
@ -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,7 +12,7 @@ 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)

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

@ -138,7 +138,8 @@ 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);
} }
@ -184,12 +185,15 @@ 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);
} }
/** /**
@ -214,9 +218,11 @@ 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);
} }
/** /**
@ -224,16 +230,11 @@ public class WeixinPayProxy {
* 生成编辑地址请求 * 生成编辑地址请求
* </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
@ -295,9 +296,11 @@ 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);
} }
/** /**
@ -328,9 +331,11 @@ 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);
} }
/** /**
@ -356,9 +361,11 @@ 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);
} }
/** /**
@ -384,9 +391,11 @@ 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);
} }
/** /**
@ -413,18 +422,18 @@ 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
@ -480,9 +489,11 @@ 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);
} }
/** /**
@ -492,9 +503,11 @@ public class WeixinPayProxy {
* *
* @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);
} }
/** /**
@ -540,17 +553,16 @@ 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)
@ -562,7 +574,8 @@ 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);
} }
@ -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);
} }
/** /**
@ -642,9 +657,11 @@ 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);
} }
/** /**
@ -668,9 +685,11 @@ 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);
} }
/** /**
@ -678,10 +697,11 @@ public class WeixinPayProxy {
* *
* @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);
} }
/** /**
@ -697,7 +717,8 @@ 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);
} }
@ -714,7 +735,8 @@ 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);
} }
@ -737,7 +759,8 @@ 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);
} }
@ -746,8 +769,10 @@ public class WeixinPayProxy {
* *
* @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);
} }
/** /**
@ -768,7 +793,8 @@ 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);
} }
@ -777,12 +803,25 @@ public class WeixinPayProxy {
* *
* @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的证书文件
@ -797,7 +836,8 @@ 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);
} }
@ -806,8 +846,10 @@ public class WeixinPayProxy {
* *
* @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);
} }
/** /**
@ -825,7 +867,8 @@ 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);
} }
@ -834,8 +877,12 @@ public class WeixinPayProxy {
* *
* @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);
} }
/** /**
@ -874,8 +921,8 @@ 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);
} }
@ -893,7 +940,8 @@ 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);
} }
@ -911,7 +959,8 @@ 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);
} }
@ -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

@ -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

@ -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,6 +19,7 @@ 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
@ -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);
} }
@ -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,25 +165,6 @@ 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分钟内触发一次关键词自动回复
* *

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

@ -34,12 +34,8 @@ public class HttpUtil {
* *
* @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()