第三方组件开发授权流程改变

This commit is contained in:
jinyu 2017-08-13 20:46:49 +08:00
commit af879a9d32
3 changed files with 1435 additions and 1479 deletions

View File

@ -83,8 +83,7 @@ public class PayApi extends MchApi {
super.declareMerchant(payPackage); super.declareMerchant(payPackage);
payPackage.setSign(weixinSignature.sign(payPackage)); payPackage.setSign(weixinSignature.sign(payPackage));
String payJsRequestXml = XmlStream.toXML(payPackage); String payJsRequestXml = XmlStream.toXML(payPackage);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("order_create_uri"), payJsRequestXml);
getRequestUri("order_create_uri"), payJsRequestXml);
return response.getAsObject(new TypeReference<PrePay>() { return response.getAsObject(new TypeReference<PrePay>() {
}); });
} }
@ -102,27 +101,21 @@ public class PayApi extends MchApi {
* @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) public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException {
throws WeixinException {
if (StringUtil.isBlank(payPackage.getTradeType())) { if (StringUtil.isBlank(payPackage.getTradeType())) {
throw new WeixinException("tradeType not be empty"); throw new WeixinException("tradeType not be empty");
} }
String tradeType = payPackage.getTradeType().toUpperCase(); String tradeType = payPackage.getTradeType().toUpperCase();
if (TradeType.MICROPAY.name().equals(tradeType)) { if (TradeType.MICROPAY.name().equals(tradeType)) {
MchPayPackage _payPackage = new MchPayPackage(payPackage.getBody(), MchPayPackage _payPackage = new MchPayPackage(payPackage.getBody(), payPackage.getDetail(),
payPackage.getDetail(), payPackage.getOutTradeNo(), payPackage.getOutTradeNo(), DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null, null,
DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null, payPackage.getCreateIp(), null, null, payPackage.getAuthCode(), null, payPackage.getAttach(), null,
null, payPackage.getCreateIp(), null, null, null, payPackage.getGoodsTag(), payPackage.getLimitPay(), payPackage.getSubAppId());
payPackage.getAuthCode(), null, payPackage.getAttach(),
null, null, payPackage.getGoodsTag(),
payPackage.getLimitPay(), payPackage.getSubAppId());
super.declareMerchant(_payPackage); super.declareMerchant(_payPackage);
_payPackage.setSign(weixinSignature.sign(_payPackage)); _payPackage.setSign(weixinSignature.sign(_payPackage));
String para = XmlStream.toXML(_payPackage); String para = XmlStream.toXML(_payPackage);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("micropay_uri"), para);
getRequestUri("micropay_uri"), para); MICROPayRequest microPayRequest = response.getAsObject(new TypeReference<MICROPayRequest>() {
MICROPayRequest microPayRequest = response
.getAsObject(new TypeReference<MICROPayRequest>() {
}); });
microPayRequest.setPaymentAccount(weixinAccount); microPayRequest.setPaymentAccount(weixinAccount);
return microPayRequest; return microPayRequest;
@ -133,11 +126,9 @@ public class PayApi extends MchApi {
} else if (TradeType.JSAPI.name().equals(tradeType)) { } else if (TradeType.JSAPI.name().equals(tradeType)) {
return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount); return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount);
} else if (TradeType.NATIVE.name().equals(tradeType)) { } else if (TradeType.NATIVE.name().equals(tradeType)) {
return new NATIVEPayRequest(prePay.getPrepayId(), return new NATIVEPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), weixinAccount);
prePay.getPayUrl(), weixinAccount);
} else if (TradeType.MWEB.name().equals(tradeType)) { } else if (TradeType.MWEB.name().equals(tradeType)) {
return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), weixinAccount);
weixinAccount);
} else { } else {
throw new WeixinException("unknown tradeType:" + tradeType); throw new WeixinException("unknown tradeType:" + tradeType);
} }
@ -164,12 +155,10 @@ public class PayApi extends MchApi {
* @return JSAPI支付对象 * @return JSAPI支付对象
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createJSPayRequest(String openId, String body, public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee,
String outTradeNo, double totalFee, String notifyUrl, String notifyUrl, String createIp, String attach) throws WeixinException {
String createIp, String attach) throws WeixinException { MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.JSAPI,
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, openId, null, null, attach);
totalFee, notifyUrl, createIp, TradeType.JSAPI, openId, null,
null, attach);
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
@ -178,11 +167,16 @@ public class PayApi extends MchApi {
* 生成编辑地址请求 * 生成编辑地址请求
* </p> * </p>
* *
* err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br> * err_msg edit_address:ok获取编辑收货地址成功</br>
* userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br> * edit_address:fail获取编辑收货地址失败</br>
* proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName * userName 收货人姓名</br>
* 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br> * telNumber 收货人电话</br>
* addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br> * addressPostalCode 邮编</br>
* proviceFirstStageName 国标收货地址第一级地址</br>
* addressCitySecondStageName 国标收货地址第二级地址</br>
* addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br>
* nationalCode 收货地址国家码</br>
* *
* @param url * @param url
* 当前访问页的URL * 当前访问页的URL
@ -232,9 +226,8 @@ public class PayApi extends MchApi {
map.put("nonce_str", noncestr); map.put("nonce_str", noncestr);
map.put("product_id", productId); map.put("product_id", productId);
String sign = weixinSignature.sign(map); String sign = weixinSignature.sign(map);
return String.format(getRequestUri("native_pay_uri"), sign, return String.format(getRequestUri("native_pay_uri"), sign, weixinAccount.getId(), weixinAccount.getMchId(),
weixinAccount.getId(), weixinAccount.getMchId(), productId, productId, timestamp, noncestr);
timestamp, noncestr);
} }
/** /**
@ -264,12 +257,10 @@ public class PayApi extends MchApi {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public NativePayResponse createNativePayResponse(String productId, public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee,
String body, String outTradeNo, double totalFee, String notifyUrl, String notifyUrl, String createIp, String attach) throws WeixinException {
String createIp, String attach) throws WeixinException { MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.NATIVE,
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, null, null, productId, attach);
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
productId, attach);
PrePay prePay = createPrePay(payPackage); PrePay prePay = createPrePay(payPackage);
return new NativePayResponse(weixinAccount, prePay.getPrepayId()); return new NativePayResponse(weixinAccount, prePay.getPrepayId());
} }
@ -301,12 +292,10 @@ public class PayApi extends MchApi {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createNativePayRequest(String productId, String body, public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee,
String outTradeNo, double totalFee, String notifyUrl, String notifyUrl, String createIp, String attach) throws WeixinException {
String createIp, String attach) throws WeixinException { MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.NATIVE,
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, null, null, productId, attach);
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
productId, attach);
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
@ -332,12 +321,10 @@ public class PayApi extends MchApi {
* APP支付</a> * APP支付</a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createAppPayRequest(String body, String outTradeNo, public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
double totalFee, String notifyUrl, String createIp, String attach) String createIp, String attach) throws WeixinException {
throws WeixinException { MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.APP,
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, null, null, null, attach);
totalFee, notifyUrl, createIp, TradeType.APP, null, null, null,
attach);
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
@ -364,12 +351,10 @@ public class PayApi extends MchApi {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createWapPayRequest(String body, String outTradeNo, public MchPayRequest createWapPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
double totalFee, String notifyUrl, String createIp, String attach) String createIp, String attach) throws WeixinException {
throws WeixinException { MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.MWEB,
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, null, null, null, attach);
totalFee, notifyUrl, createIp, TradeType.MWEB, null, null,
null, attach);
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
@ -396,20 +381,20 @@ public class PayApi extends MchApi {
* 提交被扫支付API</a> * 提交被扫支付API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createMicroPayRequest(String authCode, String body, public MchPayRequest createMicroPayRequest(String authCode, String body, String outTradeNo, double totalFee,
String outTradeNo, double totalFee, String createIp, String attach) String createIp, String attach) throws WeixinException {
throws WeixinException { MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, null, createIp, TradeType.MICROPAY,
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, null, authCode, null, attach);
totalFee, null, createIp, TradeType.MICROPAY, null, authCode,
null, attach);
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
/** /**
* 订单查询 * 订单查询
* <p> * <p>
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> 调用支付接口后返回系统错误或未知交易状态情况</br> * 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br>
* 调用被扫支付API返回USERPAYING的状态</br> 调用关单或撤销接口API之前需确认支付状态 * 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br>
* 调用关单或撤销接口API之前需确认支付状态
* </P> * </P>
* *
* @param idQuery * @param idQuery
@ -427,10 +412,8 @@ public class PayApi extends MchApi {
Map<String, String> map = createBaseRequestMap(idQuery); Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("order_query_uri"), param);
getRequestUri("order_query_uri"), param); return ListsuffixResultDeserializer.deserialize(response.getAsString(), Order.class);
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
Order.class);
} }
/** /**
@ -458,6 +441,8 @@ public class PayApi extends MchApi {
* 货币类型符合ISO 4217标准的三位字母代码默认人民币CNY * 货币类型符合ISO 4217标准的三位字母代码默认人民币CNY
* @param opUserId * @param opUserId
* 操作员帐号, 默认为商户号 * 操作员帐号, 默认为商户号
* @param refundDesc
* 退款原因若商户传入会在下发给用户的退款消息中体现退款原因
* @param refundAccountType * @param refundAccountType
* 退款资金来源,默认使用未结算资金退款REFUND_SOURCE_UNSETTLED_FUNDS * 退款资金来源,默认使用未结算资金退款REFUND_SOURCE_UNSETTLED_FUNDS
* @return 退款申请结果 * @return 退款申请结果
@ -468,16 +453,13 @@ public class PayApi extends MchApi {
* @since V3 * @since V3
* @throws WeixinException * @throws WeixinException
*/ */
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee, double refundFee,
double totalFee, double refundFee, CurrencyType refundFeeType, CurrencyType refundFeeType, String opUserId, String refundDesc, RefundAccountType refundAccountType)
String opUserId, RefundAccountType refundAccountType)
throws WeixinException { throws WeixinException {
Map<String, String> map = createBaseRequestMap(idQuery); Map<String, String> map = createBaseRequestMap(idQuery);
map.put("out_refund_no", outRefundNo); map.put("out_refund_no", outRefundNo);
map.put("total_fee", map.put("total_fee", Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
Integer.toString(DateUtil.formatYuan2Fen(totalFee))); map.put("refund_fee", Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
map.put("refund_fee",
Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
if (StringUtil.isBlank(opUserId)) { if (StringUtil.isBlank(opUserId)) {
opUserId = weixinAccount.getMchId(); opUserId = weixinAccount.getMchId();
} }
@ -488,12 +470,14 @@ public class PayApi extends MchApi {
if (refundAccountType == null) { if (refundAccountType == null) {
refundAccountType = RefundAccountType.REFUND_SOURCE_UNSETTLED_FUNDS; refundAccountType = RefundAccountType.REFUND_SOURCE_UNSETTLED_FUNDS;
} }
if (StringUtil.isNotBlank(refundDesc)) {
map.put("refund_desc", refundDesc);
}
map.put("refund_fee_type", refundFeeType.name()); map.put("refund_fee_type", refundFeeType.name());
map.put("refund_account", refundAccountType.name()); map.put("refund_account", refundAccountType.name());
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = getWeixinSSLExecutor().post( WeixinResponse response = getWeixinSSLExecutor().post(getRequestUri("refund_apply_uri"), param);
getRequestUri("refund_apply_uri"), param);
return response.getAsObject(new TypeReference<RefundResult>() { return response.getAsObject(new TypeReference<RefundResult>() {
}); });
} }
@ -508,19 +492,19 @@ public class PayApi extends MchApi {
* 商户系统内部的退款单号, 户系统内部唯一,同一退款单号多次请求只退一笔 * 商户系统内部的退款单号, 户系统内部唯一,同一退款单号多次请求只退一笔
* @param totalFee * @param totalFee
* 订单总金额,单位为元 * 订单总金额,单位为元
* @see {@link #applyRefund(IdQuery, String, double, double,CurrencyType, String)} * @see {@link #applyRefund(IdQuery, String, double, double, CurrencyType, String, String, RefundAccountType)}
*/ */
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException {
double totalFee) throws WeixinException { return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null, null, null, null);
return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null,
null, null);
} }
/** /**
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑: * 冲正订单(需要证书)</br>
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单 * 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br>
* 如需实现相同功能请调用退款接口</font></br> <font * 接口逻辑: 付失败的关单,支付成功的撤销支付</br>
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font> </br> * <font color="red">7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口</font></br>
* <font color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font>
* </br>
* *
* @param idQuery * @param idQuery
* 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级: * 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级:
@ -533,8 +517,7 @@ public class PayApi extends MchApi {
Map<String, String> map = createBaseRequestMap(idQuery); Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = getWeixinSSLExecutor().post( WeixinResponse response = getWeixinSSLExecutor().post(getRequestUri("order_reverse_uri"), param);
getRequestUri("order_reverse_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() { return response.getAsObject(new TypeReference<MerchantResult>() {
}); });
} }
@ -560,8 +543,7 @@ public class PayApi extends MchApi {
} }
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("longurl_convert_uri"), param);
getRequestUri("longurl_convert_uri"), param);
map = XmlStream.xml2map(response.getAsString()); map = XmlStream.xml2map(response.getAsString());
return map.get("short_url"); return map.get("short_url");
} }
@ -583,12 +565,10 @@ public class PayApi extends MchApi {
* 关闭订单API</a> * 关闭订单API</a>
*/ */
public MerchantResult closeOrder(String outTradeNo) throws WeixinException { public MerchantResult closeOrder(String outTradeNo) throws WeixinException {
Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo, Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo, IdType.TRADENO));
IdType.TRADENO));
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("order_close_uri"), param);
getRequestUri("order_close_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() { return response.getAsObject(new TypeReference<MerchantResult>() {
}); });
} }
@ -615,8 +595,8 @@ public class PayApi extends MchApi {
* 下载对账单API</a> * 下载对账单API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public void downloadBill(Date billDate, BillType billType, public void downloadBill(Date billDate, BillType billType, OutputStream outputStream, TarType tarType)
OutputStream outputStream, TarType tarType) throws WeixinException { throws WeixinException {
if (billDate == null) { if (billDate == null) {
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_MONTH, -1); now.add(Calendar.DAY_OF_MONTH, -1);
@ -634,8 +614,7 @@ public class PayApi extends MchApi {
} }
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("downloadbill_uri"), param);
getRequestUri("downloadbill_uri"), param);
if (TarType.GZIP == tarType) { if (TarType.GZIP == tarType) {
try { try {
@ -647,10 +626,8 @@ public class PayApi extends MchApi {
BufferedReader reader = null; BufferedReader reader = null;
BufferedWriter writer = null; BufferedWriter writer = null;
try { try {
writer = new BufferedWriter(new OutputStreamWriter( writer = new BufferedWriter(new OutputStreamWriter(outputStream, Consts.UTF_8));
outputStream, Consts.UTF_8)); reader = new BufferedReader(new InputStreamReader(response.getBody(), Consts.UTF_8));
reader = new BufferedReader(new InputStreamReader(
response.getBody(), Consts.UTF_8));
String line = null; String line = null;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
writer.write(line); writer.write(line);
@ -697,10 +674,8 @@ public class PayApi extends MchApi {
Map<String, String> map = createBaseRequestMap(idQuery); Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("refund_query_uri"), param);
getRequestUri("refund_query_uri"), param); return ListsuffixResultDeserializer.deserialize(response.getAsString(), RefundRecord.class);
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
RefundRecord.class);
} }
/** /**
@ -726,9 +701,8 @@ public class PayApi extends MchApi {
* 交易保障</a> * 交易保障</a>
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public XmlResult reportInterface(String interfaceUrl, int executeTime, public XmlResult reportInterface(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time,
String outTradeNo, String ip, Date time, XmlResult returnXml) XmlResult returnXml) throws WeixinException {
throws WeixinException {
Map<String, String> map = createBaseRequestMap(null); Map<String, String> map = createBaseRequestMap(null);
map.put("interface_url", interfaceUrl); map.put("interface_url", interfaceUrl);
map.put("execute_time_", Integer.toString(executeTime)); map.put("execute_time_", Integer.toString(executeTime));
@ -738,8 +712,7 @@ public class PayApi extends MchApi {
map.putAll((Map<String, String>) JSON.toJSON(returnXml)); map.putAll((Map<String, String>) JSON.toJSON(returnXml));
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("interface_report_uri"), param);
getRequestUri("interface_report_uri"), param);
return response.getAsXml(); return response.getAsXml();
} }
@ -760,8 +733,7 @@ public class PayApi extends MchApi {
map.put("auth_code", authCode); map.put("auth_code", authCode);
map.put("sign", weixinSignature.sign(map)); map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(getRequestUri("authcode_openid_uri"), param);
getRequestUri("authcode_openid_uri"), param);
return response.getAsObject(new TypeReference<OpenIdResult>() { return response.getAsObject(new TypeReference<OpenIdResult>() {
}); });
} }

View File

@ -82,8 +82,7 @@ public class WeixinPayProxy {
* 微信支付接口实现(使用weixin4j.properties配置的account商户信息) * 微信支付接口实现(使用weixin4j.properties配置的account商户信息)
*/ */
public WeixinPayProxy() { public WeixinPayProxy() {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), WeixinPayAccount.class));
WeixinPayAccount.class));
} }
/** /**
@ -94,8 +93,7 @@ public class WeixinPayProxy {
*/ */
public WeixinPayProxy(WeixinPayAccount weixinPayAccount) { public WeixinPayProxy(WeixinPayAccount weixinPayAccount) {
if (weixinPayAccount == null) { if (weixinPayAccount == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException("weixinPayAccount must not be empty");
"weixinPayAccount must not be empty");
} }
this.weixinPayAccount = weixinPayAccount; this.weixinPayAccount = weixinPayAccount;
this.payApi = new PayApi(weixinPayAccount); this.payApi = new PayApi(weixinPayAccount);
@ -156,8 +154,7 @@ public class WeixinPayProxy {
* @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString()
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createPayRequest(MchPayPackage payPackage) public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException {
throws WeixinException {
return payApi.createPayRequest(payPackage); return payApi.createPayRequest(payPackage);
} }
@ -184,11 +181,9 @@ public class WeixinPayProxy {
* @return JSAPI支付对象 * @return JSAPI支付对象
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createJSPayRequest(String openId, String body, public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee,
String outTradeNo, double totalFee, String notifyUrl, String notifyUrl, String createIp, String attach) throws WeixinException {
String createIp, String attach) throws WeixinException { return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
} }
/** /**
@ -196,11 +191,16 @@ public class WeixinPayProxy {
* 生成编辑地址请求 * 生成编辑地址请求
* </p> * </p>
* *
* err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br> * err_msg edit_address:ok获取编辑收货地址成功</br>
* userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br> * edit_address:fail获取编辑收货地址失败</br>
* proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName * userName 收货人姓名</br>
* 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br> * telNumber 收货人电话</br>
* addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br> * addressPostalCode 邮编</br>
* proviceFirstStageName 国标收货地址第一级地址</br>
* addressCitySecondStageName 国标收货地址第二级地址</br>
* addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br>
* nationalCode 收货地址国家码</br>
* *
* @param url * @param url
* 当前访问页的URL * 当前访问页的URL
@ -262,11 +262,9 @@ public class WeixinPayProxy {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public NativePayResponse createNativePayResponse(String productId, public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee,
String body, String outTradeNo, double totalFee, String notifyUrl, String notifyUrl, String createIp, String attach) throws WeixinException {
String createIp, String attach) throws WeixinException { return payApi.createNativePayResponse(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
return payApi.createNativePayResponse(productId, body, outTradeNo,
totalFee, notifyUrl, createIp, attach);
} }
/** /**
@ -298,11 +296,9 @@ public class WeixinPayProxy {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createNativePayRequest(String productId, String body, public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee,
String outTradeNo, double totalFee, String notifyUrl, String notifyUrl, String createIp, String attach) throws WeixinException {
String createIp, String attach) throws WeixinException { return payApi.createNativePayRequest(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
return payApi.createNativePayRequest(productId, body, outTradeNo,
totalFee, notifyUrl, createIp, attach);
} }
/** /**
@ -329,11 +325,9 @@ public class WeixinPayProxy {
* APP支付</a> * APP支付</a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createAppPayRequest(String body, String outTradeNo, public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
double totalFee, String notifyUrl, String createIp, String attach) String createIp, String attach) throws WeixinException {
throws WeixinException { return payApi.createAppPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach);
return payApi.createAppPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
} }
/** /**
@ -360,11 +354,9 @@ public class WeixinPayProxy {
* </a> * </a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createWapPayRequest(String body, String outTradeNo, public MchPayRequest createWapPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
double totalFee, String notifyUrl, String createIp, String attach) String createIp, String attach) throws WeixinException {
throws WeixinException { return payApi.createWapPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach);
return payApi.createWapPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
} }
/** /**
@ -392,18 +384,18 @@ public class WeixinPayProxy {
* 提交被扫支付API</a> * 提交被扫支付API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public MchPayRequest createMicroPayRequest(String authCode, String body, public MchPayRequest createMicroPayRequest(String authCode, String body, String outTradeNo, double totalFee,
String outTradeNo, double totalFee, String createIp, String attach) String createIp, String attach) throws WeixinException {
throws WeixinException { return payApi.createMicroPayRequest(authCode, body, outTradeNo, totalFee, createIp, attach);
return payApi.createMicroPayRequest(authCode, body, outTradeNo,
totalFee, createIp, attach);
} }
/** /**
* 订单查询 * 订单查询
* <p> * <p>
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> 调用支付接口后返回系统错误或未知交易状态情况</br> * 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br>
* 调用被扫支付API返回USERPAYING的状态</br> 调用关单或撤销接口API之前需确认支付状态 * 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br>
* 调用关单或撤销接口API之前需确认支付状态
* </P> * </P>
* *
* @param idQuery * @param idQuery
@ -447,6 +439,8 @@ public class WeixinPayProxy {
* 货币类型符合ISO 4217标准的三位字母代码默认人民币CNY * 货币类型符合ISO 4217标准的三位字母代码默认人民币CNY
* @param opUserId * @param opUserId
* 操作员帐号, 默认为商户号 * 操作员帐号, 默认为商户号
* @param refundDesc
* 退款原因若商户传入会在下发给用户的退款消息中体现退款原因
* @param refundAccountType * @param refundAccountType
* 退款资金来源,默认使用未结算资金退款REFUND_SOURCE_UNSETTLED_FUNDS * 退款资金来源,默认使用未结算资金退款REFUND_SOURCE_UNSETTLED_FUNDS
* @return 退款申请结果 * @return 退款申请结果
@ -458,12 +452,11 @@ public class WeixinPayProxy {
* @since V3 * @since V3
* @throws WeixinException * @throws WeixinException
*/ */
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee, double refundFee,
double totalFee, double refundFee, CurrencyType refundFeeType, CurrencyType refundFeeType, String opUserId, String refundDesc, RefundAccountType refundAccountType)
String opUserId, RefundAccountType refundAccountType)
throws WeixinException { throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee, refundFee, return payApi.applyRefund(idQuery, outRefundNo, totalFee, refundFee, refundFeeType, opUserId, refundDesc,
refundFeeType, opUserId, refundAccountType); refundAccountType);
} }
/** /**
@ -473,8 +466,7 @@ public class WeixinPayProxy {
* *
* @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)} * @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)}
*/ */
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException {
double totalFee) throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee); return payApi.applyRefund(idQuery, outRefundNo, totalFee);
} }
@ -523,16 +515,18 @@ public class WeixinPayProxy {
* 下载对账单API</a> * 下载对账单API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public void downloadBill(Date billDate, BillType billType, public void downloadBill(Date billDate, BillType billType, OutputStream outputStream, TarType tarType)
OutputStream outputStream, TarType tarType) throws WeixinException { throws WeixinException {
payApi.downloadBill(billDate, billType, outputStream, tarType); payApi.downloadBill(billDate, billType, outputStream, tarType);
} }
/** /**
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑: * 冲正订单(需要证书)</br>
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单 * 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br>
* 如需实现相同功能请调用退款接口</font></br> <font * 接口逻辑: 付失败的关单,支付成功的撤销支付</br>
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font> </br> * <font color="red">7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口</font></br>
* <font color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font>
* </br>
* *
* @param idQuery * @param idQuery
* 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级: * 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级:
@ -608,11 +602,9 @@ public class WeixinPayProxy {
* 接口测试上报API</a> * 接口测试上报API</a>
* @throws WeixinException * @throws WeixinException
*/ */
public XmlResult reportInterface(String interfaceUrl, int executeTime, public XmlResult reportInterface(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time,
String outTradeNo, String ip, Date time, XmlResult returnXml) XmlResult returnXml) throws WeixinException {
throws WeixinException { return payApi.reportInterface(interfaceUrl, executeTime, outTradeNo, ip, time, returnXml);
return payApi.reportInterface(interfaceUrl, executeTime, outTradeNo,
ip, time, returnXml);
} }
/** /**
@ -634,10 +626,9 @@ public class WeixinPayProxy {
* 发放代金券接口</a> * 发放代金券接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, String openId, String opUserId)
String openId, String opUserId) throws WeixinException { throws WeixinException {
return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId, return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId, opUserId);
opUserId);
} }
/** /**
@ -653,8 +644,7 @@ public class WeixinPayProxy {
* 查询代金券批次信息接口</a> * 查询代金券批次信息接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CouponStock queryCouponStock(String couponStockId) public CouponStock queryCouponStock(String couponStockId) throws WeixinException {
throws WeixinException {
return couponApi.queryCouponStock(couponStockId); return couponApi.queryCouponStock(couponStockId);
} }
@ -675,8 +665,7 @@ public class WeixinPayProxy {
* 查询代金券详细信息接口</a> * 查询代金券详细信息接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CouponDetail queryCouponDetail(String openId, String couponId, public CouponDetail queryCouponDetail(String openId, String couponId, String stockId) throws WeixinException {
String stockId) throws WeixinException {
return couponApi.queryCouponDetail(openId, couponId, stockId); return couponApi.queryCouponDetail(openId, couponId, stockId);
} }
@ -697,8 +686,7 @@ public class WeixinPayProxy {
* 发放裂变红包接口</a> * 发放裂变红包接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public RedpacketSendResult sendRedpack(Redpacket redpacket) public RedpacketSendResult sendRedpack(Redpacket redpacket) throws WeixinException {
throws WeixinException {
return cashApi.sendRedpack(redpacket); return cashApi.sendRedpack(redpacket);
} }
@ -712,8 +700,7 @@ public class WeixinPayProxy {
* @see #sendRedpacks(Redpacket...) * @see #sendRedpacks(Redpacket...)
* @throws WeixinException * @throws WeixinException
*/ */
public List<Future<RedpacketSendResult>> sendRedpacks( public List<Future<RedpacketSendResult>> sendRedpacks(Redpacket... redpackets) {
Redpacket... redpackets) {
return cashApi.sendRedpacks(redpackets); return cashApi.sendRedpacks(redpackets);
} }
@ -733,8 +720,7 @@ public class WeixinPayProxy {
* 查询裂变红包接口</a> * 查询裂变红包接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public RedpacketRecord queryRedpack(String outTradeNo) public RedpacketRecord queryRedpack(String outTradeNo) throws WeixinException {
throws WeixinException {
return cashApi.queryRedpack(outTradeNo); return cashApi.queryRedpack(outTradeNo);
} }
@ -761,8 +747,7 @@ public class WeixinPayProxy {
* 企业付款接口</a> * 企业付款接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CorpPaymentResult sendCorpPayment(CorpPayment payment) public CorpPaymentResult sendCorpPayment(CorpPayment payment) throws WeixinException {
throws WeixinException {
return cashApi.sendCorpPayment(payment); return cashApi.sendCorpPayment(payment);
} }
@ -779,8 +764,7 @@ public class WeixinPayProxy {
* 企业付款查询接口</a> * 企业付款查询接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CorpPaymentRecord queryCorpPayment(String outTradeNo) public CorpPaymentRecord queryCorpPayment(String outTradeNo) throws WeixinException {
throws WeixinException {
return cashApi.queryCorpPayment(outTradeNo); return cashApi.queryCorpPayment(outTradeNo);
} }
@ -820,8 +804,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, public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end)
Date start, Date end) throws WeixinException { throws WeixinException {
return cashApi.querySettlement(status, pageable, start, end); return cashApi.querySettlement(status, pageable, start, end);
} }
@ -839,8 +823,7 @@ 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) public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException {
throws WeixinException {
return cashApi.queryExchageRate(currencyType, date); return cashApi.queryExchageRate(currencyType, date);
} }
@ -858,8 +841,7 @@ public class WeixinPayProxy {
* 附加订单信息提交接口</a> * 附加订单信息提交接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) throws WeixinException {
throws WeixinException {
return customsApi.declareCustomsOrder(customsOrder); return customsApi.declareCustomsOrder(customsOrder);
} }
@ -878,8 +860,7 @@ public class WeixinPayProxy {
* 附加订单信息查询接口</a> * 附加订单信息查询接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery, public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery, CustomsCity customsCity) throws WeixinException {
CustomsCity customsCity) throws WeixinException {
return customsApi.queryCustomsOrder(idQuery, customsCity); return customsApi.queryCustomsOrder(idQuery, customsCity);
} }

View File

@ -22,6 +22,7 @@ import com.foxinmy.weixin4j.payment.mch.RefundRecord;
import com.foxinmy.weixin4j.payment.mch.RefundResult; import com.foxinmy.weixin4j.payment.mch.RefundResult;
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
import com.foxinmy.weixin4j.sign.WeixinSignature; import com.foxinmy.weixin4j.sign.WeixinSignature;
import com.foxinmy.weixin4j.type.CurrencyType;
import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.IdType; import com.foxinmy.weixin4j.type.IdType;
import com.foxinmy.weixin4j.type.TradeType; import com.foxinmy.weixin4j.type.TradeType;
@ -87,9 +88,10 @@ public class PayTest {
@Test @Test
public void downbill() throws WeixinException, IOException { public void downbill() throws WeixinException, IOException {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2012); // c.set(Calendar.YEAR, 2016);
c.set(Calendar.MONTH, 3); // c.set(Calendar.MONTH, 3);
c.set(Calendar.DAY_OF_MONTH, 4); // c.set(Calendar.DAY_OF_MONTH, 4);
c.add(Calendar.DAY_OF_MONTH, -1);
System.err.println(c.getTime()); System.err.println(c.getTime());
OutputStream os = new FileOutputStream("/tmp/bill20160813.txt"); OutputStream os = new FileOutputStream("/tmp/bill20160813.txt");
PAY.downloadBill(c.getTime(), BillType.ALL, os, null); PAY.downloadBill(c.getTime(), BillType.ALL, os, null);
@ -99,8 +101,9 @@ public class PayTest {
public void refund() throws WeixinException, IOException { public void refund() throws WeixinException, IOException {
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO); IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
RefundResult result = PAY.applyRefund(idQuery, RefundResult result = PAY.applyRefund(idQuery,
"TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, null, "TT_R" + System.currentTimeMillis(), 0.01d, 0.01d,
"10020674", RefundAccountType.REFUND_SOURCE_RECHARGE_FUNDS); CurrencyType.CNY, "10020674", "退款描述",
RefundAccountType.REFUND_SOURCE_RECHARGE_FUNDS);
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode()); Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
Assert.assertEquals(Consts.SUCCESS, result.getResultCode()); Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
System.err.println(result); System.err.println(result);