#66 and cleanup with Metrics plugin

This commit is contained in:
jinyu 2016-05-24 17:18:59 +08:00
parent 866b37c54b
commit 57a6c6d6e3
9 changed files with 267 additions and 341 deletions

View File

@ -52,7 +52,7 @@ import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 支付API
*
*
* @className PayApi
* @author jinyu(foxinmy@gmail.com)
* @date 2014年10月28日
@ -68,7 +68,7 @@ public class PayApi extends MchApi {
* 统一下单接口</br>
* 除被扫支付场景以外商户系统先调用该接口在微信支付服务后台生成预支付交易单返回正确的预支付交易回话标识后再按扫码JSAPI
* APP等不同场景生成交易串调起支付
*
*
* @param payPackage
* 包含订单信息的对象
* @see com.foxinmy.weixin4j.payment.mch.MchPayPackage
@ -82,14 +82,15 @@ public class PayApi extends MchApi {
payPackage.declareWeixinPayAccount(weixinAccount);
payPackage.setSign(weixinSignature.sign(payPackage));
String payJsRequestXml = XmlStream.toXML(payPackage);
WeixinResponse response = weixinExecutor.post(getRequestUri("order_create_uri"), payJsRequestXml);
WeixinResponse response = weixinExecutor.post(
getRequestUri("order_create_uri"), payJsRequestXml);
return response.getAsObject(new TypeReference<PrePay>() {
});
}
/**
* 创建支付请求对象
*
*
* @param payPackage
* 支付详情
* @return 支付请求对象
@ -100,88 +101,37 @@ public class PayApi extends MchApi {
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinException
*/
public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException {
PrePay prePay = createPrePay(payPackage);
public MchPayRequest createPayRequest(MchPayPackage payPackage)
throws WeixinException {
String tradeType = payPackage.getTradeType();
if (TradeType.MICROPAY.name().equalsIgnoreCase(tradeType)) {
String para = XmlStream.toXML(payPackage);
WeixinResponse response = weixinExecutor.post(
getRequestUri("micropay_uri"), para);
MICROPayRequest microPayRequest = response
.getAsObject(new TypeReference<MICROPayRequest>() {
});
microPayRequest.setPaymentAccount(weixinAccount);
return microPayRequest;
}
PrePay prePay = createPrePay(payPackage);
if (TradeType.APP.name().equalsIgnoreCase(tradeType)) {
return new APPPayRequest(prePay.getPrepayId(), weixinAccount);
} else if (TradeType.JSAPI.name().equalsIgnoreCase(tradeType)) {
return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount);
} else if (TradeType.NATIVE.name().equalsIgnoreCase(tradeType)) {
return new NATIVEPayRequest(prePay.getPrepayId(), prePay.getCodeUrl(), weixinAccount);
return new NATIVEPayRequest(prePay.getPrepayId(),
prePay.getCodeUrl(), weixinAccount);
} else if (TradeType.WAP.name().equalsIgnoreCase(tradeType)) {
return new WAPPayRequest(prePay.getPrepayId(), weixinAccount);
} else if (TradeType.MICROPAY.name().equalsIgnoreCase(tradeType)) {
String para = XmlStream.toXML(payPackage);
WeixinResponse response = weixinExecutor.post(getRequestUri("micropay_uri"), para);
MICROPayRequest microPayRequest = response.getAsObject(new TypeReference<MICROPayRequest>() {
});
microPayRequest.setPaymentAccount(weixinAccount);
return microPayRequest;
} else {
throw new WeixinException("unknown tradeType:" + tradeType);
}
}
/**
* 创建支付请求对象完整参数
*
* @param body
* 商品描述 <font color="red">必填项</font>
* @param detail
* 商品名称明细列表 非必填项
* @param outTradeNo
* 商户内部唯一订单号 <font color="red">必填项</font>
* @param totalFee
* 商品总额 单位元 <font color="red">必填项</font>
* @param notifyUrl
* 支付回调URL <font color="red">必填项</font>
* @param createIp
* 订单生成的机器IP <font color="red">必填项</font>
* @param tradeType
* 交易类型 <font color="red">必填项</font>
* @param openId
* 用户ID <font color="red">tradeType=JSAPI时必填</font>
* @param productId
* 产品ID <font color="red">tradeType=NATIVE时必填</font>
* @param attach
* 附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据 非必填项
* @param timeStart
* 订单生成时间格式为yyyyMMddHHmmss 非必填项
* @param timeExpire
* 订单失效时间格式为yyyyMMddHHmmss;注意最短失效时间间隔必须大于5分钟 非必填项
* @param goodsTag
* 商品标记代金券或立减优惠功能的参数 非必填项
* @param limitPay
* 指定支付方式:no_credit--指定不能使用信用卡支付 非必填项
* @param subOpenId
* 用户在子商户appid下的唯一标识 非必填
* openid和sub_openid可以选传其中之一如果选择传sub_openid ,则必须传sub_appid
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付
* @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest 刷卡支付
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinException
*/
public MchPayRequest createPayRequest(String body, String detail, String outTradeNo, double totalFee,
String notifyUrl, String createIp, TradeType tradeType, String openId, String productId, String attach,
Date timeStart, Date timeExpire, String goodsTag, String limitPay, String subOpenId)
throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, tradeType, openId,
null, productId, attach);
payPackage.setTimeStart(timeStart);
payPackage.setTimeExpire(timeExpire);
payPackage.setGoodsTag(goodsTag);
payPackage.setLimitPay(limitPay);
payPackage.setDetail(detail);
payPackage.setSubOpenId(subOpenId);
return createPayRequest(payPackage);
}
/**
* 创建JSAPI支付请求对象
*
*
* @param openId
* 用户ID
* @param body
@ -189,7 +139,7 @@ public class PayApi extends MchApi {
* @param outTradeNo
* 订单号
* @param totalFee
* 订单总额 按实际金额传入即可() 构造函数会转换为分
* 订单总额()
* @param notifyUrl
* 支付通知地址
* @param createIp
@ -200,10 +150,12 @@ public class PayApi extends MchApi {
* @return JSAPI支付对象
* @throws WeixinException
*/
public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee,
String notifyUrl, String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.JSAPI,
openId, null, null, attach);
public MchPayRequest createJSPayRequest(String openId, String body,
String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.JSAPI, openId, null,
null, attach);
return createPayRequest(payPackage);
}
@ -211,18 +163,13 @@ public class PayApi extends MchApi {
* <p>
* 生成编辑地址请求
* </p>
*
* err_msg edit_address:ok获取编辑收货地址成功</br>
* edit_address:fail获取编辑收货地址失败</br>
* userName 收货人姓名</br>
* telNumber 收货人电话</br>
* addressPostalCode 邮编</br>
* proviceFirstStageName 国标收货地址第一级地址</br>
* addressCitySecondStageName 国标收货地址第二级地址</br>
* addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br>
* nationalCode 收货地址国家码</br>
*
*
* err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br>
* userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br>
* proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName
* 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br>
*
* @param url
* 当前访问页的URL
* @param oauthToken
@ -250,7 +197,7 @@ public class PayApi extends MchApi {
/**
* 创建Native支付(扫码支付)链接模式一
*
*
* @param productId
* 与订单ID等价
* @return 支付链接
@ -271,13 +218,14 @@ public class PayApi extends MchApi {
map.put("nonce_str", noncestr);
map.put("product_id", productId);
String sign = weixinSignature.sign(map);
return String.format(getRequestUri("native_pay_uri"), sign, weixinAccount.getId(), weixinAccount.getMchId(),
productId, timestamp, noncestr);
return String.format(getRequestUri("native_pay_uri"), sign,
weixinAccount.getId(), weixinAccount.getMchId(), productId,
timestamp, noncestr);
}
/**
* 创建Native支付(扫码支付)回调对象模式一
*
*
* @param productId
* 商品ID
* @param body
@ -302,17 +250,19 @@ public class PayApi extends MchApi {
* </a>
* @throws WeixinException
*/
public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee,
String notifyUrl, String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.NATIVE,
null, null, productId, attach);
public NativePayResponse createNativePayResponse(String productId,
String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
productId, attach);
PrePay prePay = createPrePay(payPackage);
return new NativePayResponse(weixinAccount, prePay.getPrepayId());
}
/**
* 创建Native支付(扫码支付)链接模式二
*
*
* @param productId
* 商品ID
* @param body
@ -337,16 +287,18 @@ public class PayApi extends MchApi {
* </a>
* @throws WeixinException
*/
public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee,
String notifyUrl, String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.NATIVE,
null, null, productId, attach);
public MchPayRequest createNativePayRequest(String productId, String body,
String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
productId, attach);
return createPayRequest(payPackage);
}
/**
* 创建APP支付请求对象
*
*
* @param body
* 商品描述
* @param outTradeNo
@ -366,16 +318,18 @@ public class PayApi extends MchApi {
* APP支付</a>
* @throws WeixinException
*/
public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.APP,
null, null, null, attach);
public MchPayRequest createAppPayRequest(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach)
throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.APP, null, null, null,
attach);
return createPayRequest(payPackage);
}
/**
* 创建WAP支付请求对象
*
*
* @param body
* 商品描述
* @param outTradeNo
@ -395,16 +349,18 @@ public class PayApi extends MchApi {
* </a>
* @throws WeixinException
*/
public MchPayRequest createWAPPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.WAP,
null, null, null, attach);
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach)
throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.WAP, null, null, null,
attach);
return createPayRequest(payPackage);
}
/**
* 提交被扫支付
*
*
* @param authCode
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
* @param body
@ -425,22 +381,22 @@ public class PayApi extends MchApi {
* 提交被扫支付API</a>
* @throws WeixinException
*/
public MchPayRequest createMICROPayRequest(String authCode, String body, String outTradeNo, double totalFee,
String createIp, String attach) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, totalFee, null, createIp, TradeType.MICROPAY,
null, null, null, attach);
public MchPayRequest createMicroPayRequest(String authCode, String body,
String outTradeNo, double totalFee, String createIp, String attach)
throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, null, createIp, TradeType.MICROPAY, null, null, null,
attach);
return createPayRequest(payPackage);
}
/**
* 订单查询
* <p>
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br>
* 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br>
* 调用关单或撤销接口API之前需确认支付状态
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br> 调用关单或撤销接口API之前需确认支付状态
* </P>
*
*
* @param idQuery
* 商户系统内部的订单号, transaction_idout_trade_no 选一,如果同时存在优先级:
* transaction_id> out_trade_no
@ -456,8 +412,10 @@ public class PayApi extends MchApi {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("order_query_uri"), param);
return ListsuffixResultDeserializer.deserialize(response.getAsString(), Order.class);
WeixinResponse response = weixinExecutor.post(
getRequestUri("order_query_uri"), param);
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
Order.class);
}
/**
@ -471,7 +429,7 @@ public class PayApi extends MchApi {
* 2.微信支付退款支持单笔交易分多次退款多次退款需要提交原支付订单的商户订单号和设置不同的退款单号一笔退款失败后重新提交
* 要采用原来的退款单号总退款金额不能超过用户实际支付金额
* </p>
*
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
@ -495,8 +453,9 @@ public class PayApi extends MchApi {
* @since V3
* @throws WeixinException
*/
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, CurrencyType refundFeeType, String opUserId) throws WeixinException {
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
String outRefundNo, double totalFee, double refundFee,
CurrencyType refundFeeType, String opUserId) throws WeixinException {
WeixinResponse response = null;
try {
Map<String, String> map = createBaseRequestMap(idQuery);
@ -513,7 +472,8 @@ public class PayApi extends MchApi {
map.put("refund_fee_type", refundFeeType.name());
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
response = createSSLRequestExecutor(certificate).post(getRequestUri("refund_apply_uri"), param);
response = createSSLRequestExecutor(certificate).post(
getRequestUri("refund_apply_uri"), param);
} finally {
if (certificate != null) {
try {
@ -529,7 +489,7 @@ public class PayApi extends MchApi {
/**
* 退款申请(全额退款)
*
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
@ -541,19 +501,18 @@ public class PayApi extends MchApi {
* 订单总金额,单位为元
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double,CurrencyType, String)}
*/
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery, String outRefundNo, double totalFee)
throws WeixinException {
return applyRefund(certificate, idQuery, outRefundNo, totalFee, totalFee, null, null);
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
String outRefundNo, double totalFee) throws WeixinException {
return applyRefund(certificate, idQuery, outRefundNo, totalFee,
totalFee, null, null);
}
/**
* 冲正订单(需要证书)</br>
* 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br>
* 接口逻辑: 付失败的关单,支付成功的撤销支付</br>
* <font color="red">7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口</font></br>
* <font color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font>
* </br>
*
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
* 如需实现相同功能请调用退款接口</font></br> <font
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上先调用查单接口,如果没有确切的返回,再调用撤销</font> </br>
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
@ -563,13 +522,14 @@ public class PayApi extends MchApi {
* @since V3
* @throws WeixinException
*/
public MerchantResult reverseOrder(InputStream certificate, IdQuery idQuery) throws WeixinException {
public MerchantResult reverseOrder(InputStream certificate, IdQuery idQuery)
throws WeixinException {
try {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = createSSLRequestExecutor(certificate).post(getRequestUri("order_reverse_uri"),
param);
WeixinResponse response = createSSLRequestExecutor(certificate)
.post(getRequestUri("order_reverse_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() {
});
} finally {
@ -586,7 +546,7 @@ public class PayApi extends MchApi {
/**
* native支付URL转短链接用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX)减小二维码数据量
* 提升扫描速度和精确度
*
*
* @param url
* 具有native标识的支付URL
* @return 转换后的短链接
@ -604,7 +564,8 @@ public class PayApi extends MchApi {
}
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("longurl_convert_uri"), param);
WeixinResponse response = weixinExecutor.post(
getRequestUri("longurl_convert_uri"), param);
map = XmlStream.xml2map(response.getAsString());
return map.get("short_url");
}
@ -615,7 +576,7 @@ public class PayApi extends MchApi {
* 商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续
* 请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理如果出现银行掉单,调用关单成功后,微信后台会主动发起退款
* </p>
*
*
* @param outTradeNo
* 商户系统内部的订单号
* @return 处理结果
@ -626,10 +587,12 @@ public class PayApi extends MchApi {
* 关闭订单API</a>
*/
public MerchantResult closeOrder(String outTradeNo) throws WeixinException {
Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo, IdType.TRADENO));
Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo,
IdType.TRADENO));
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("order_close_uri"), param);
WeixinResponse response = weixinExecutor.post(
getRequestUri("order_close_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() {
});
}
@ -640,7 +603,7 @@ public class PayApi extends MchApi {
* REVOKED;<br>
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
* 3.对账单中涉及金额的字段单位为<br>
*
*
* @param billDate
* 下载对账单的日期
* @param billType
@ -655,7 +618,8 @@ public class PayApi extends MchApi {
* 下载对账单API</a>
* @throws WeixinException
*/
public File downloadBill(Date billDate, BillType billType, String billPath) throws WeixinException {
public File downloadBill(Date billDate, BillType billType, String billPath)
throws WeixinException {
if (billDate == null) {
Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_MONTH, -1);
@ -665,7 +629,8 @@ public class PayApi extends MchApi {
billType = BillType.ALL;
}
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt", formatBillDate, billType.name().toLowerCase(),
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt",
formatBillDate, billType.name().toLowerCase(),
weixinAccount.getId());
File file = new File(String.format("%s/%s", billPath, fileName));
if (file.exists()) {
@ -676,14 +641,16 @@ public class PayApi extends MchApi {
map.put("bill_type", billType.name());
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("downloadbill_uri"), param);
WeixinResponse response = weixinExecutor.post(
getRequestUri("downloadbill_uri"), param);
BufferedReader reader = null;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), Consts.UTF_8));
reader = new BufferedReader(
new InputStreamReader(response.getBody(), Consts.UTF_8));
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file), Consts.UTF_8));
reader = new BufferedReader(new InputStreamReader(
response.getBody(), Consts.UTF_8));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
@ -708,11 +675,11 @@ public class PayApi extends MchApi {
/**
* 退款查询
*
*
* <p>
* 提交退款申请后通过调用该接口查询退款状态退款有一定延时用零钱支付的退款20分钟内到账银行卡支付的退款3个工作日后重新查询退款状态
* </p>
*
*
* @param idQuery
* 单号 refund_idout_refund_no out_trade_no transaction_id
* 四个参数必填一个,优先级为:
@ -730,13 +697,15 @@ public class PayApi extends MchApi {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("refund_query_uri"), param);
return ListsuffixResultDeserializer.deserialize(response.getAsString(), RefundRecord.class);
WeixinResponse response = weixinExecutor.post(
getRequestUri("refund_query_uri"), param);
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
RefundRecord.class);
}
/**
* 接口上报
*
*
* @param interfaceUrl
* 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q
* q.com/pay/unifiedorder
@ -757,8 +726,9 @@ public class PayApi extends MchApi {
* 接口测试上报API</a>
*/
@SuppressWarnings("unchecked")
public XmlResult interfaceReport(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time,
XmlResult returnXml) throws WeixinException {
public XmlResult interfaceReport(String interfaceUrl, int executeTime,
String outTradeNo, String ip, Date time, XmlResult returnXml)
throws WeixinException {
Map<String, String> map = createBaseRequestMap(null);
map.put("interface_url", interfaceUrl);
map.put("execute_time_", Integer.toString(executeTime));
@ -768,13 +738,14 @@ public class PayApi extends MchApi {
map.putAll((Map<String, String>) JSON.toJSON(returnXml));
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("interface_report_uri"), param);
WeixinResponse response = weixinExecutor.post(
getRequestUri("interface_report_uri"), param);
return response.getAsXmlResult();
}
/**
* 授权码查询OPENID接口
*
*
* @param authCode
* 扫码支付授权码设备读取用户微信中的条码或者二维码信息
* @return 查询结果
@ -789,7 +760,8 @@ public class PayApi extends MchApi {
map.put("auth_code", authCode);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(getRequestUri("authcode_openid_uri"), param);
WeixinResponse response = weixinExecutor.post(
getRequestUri("authcode_openid_uri"), param);
return response.getAsObject(new TypeReference<OpenIdResult>() {
});
}

View File

@ -59,7 +59,10 @@ public class WeixinException extends Exception {
buf.append(" >> ").append(desc);
}
if (buf.length() > 0) {
buf.append(" >> ").append(WeixinErrorUtil.getText(code));
String text = getErrorText();
if (StringUtil.isNotBlank(text)) {
buf.append(" >> ").append(text);
}
return buf.toString();
} else {
return super.getMessage();

View File

@ -26,7 +26,7 @@ import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 负责微信请求的执行
*
*
* @className WeixinRequestExecutor
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月15日
@ -103,8 +103,7 @@ public class WeixinRequestExecutor {
HttpHeaders headers = httpResponse.getHeaders();
WeixinResponse response = new WeixinResponse(httpResponse);
logger.info("weixin response << " + httpResponse.getProtocol()
+ httpResponse.getStatus().toString() + ":"
+ response.getAsString());
+ httpResponse.getStatus() + ":" + response.getAsString());
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
String disposition = headers
.getFirst(HttpHeaders.CONTENT_DISPOSITION);

View File

@ -40,7 +40,6 @@ import com.foxinmy.weixin4j.type.BillType;
import com.foxinmy.weixin4j.type.CurrencyType;
import com.foxinmy.weixin4j.type.CustomsCity;
import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.TradeType;
import com.foxinmy.weixin4j.util.Weixin4jSettings;
/**
@ -143,59 +142,6 @@ public class WeixinPayProxy {
return payApi.createPayRequest(payPackage);
}
/**
* 创建支付请求对象完整参数
*
* @param body
* 商品描述 <font color="red">必填项</font>
* @param detail
* 商品名称明细列表 非必填项
* @param outTradeNo
* 商户内部唯一订单号 <font color="red">必填项</font>
* @param totalFee
* 商品总额 单位元 <font color="red">必填项</font>
* @param notifyUrl
* 支付回调URL <font color="red">必填项</font>
* @param createIp
* 订单生成的机器IP <font color="red">必填项</font>
* @param tradeType
* 交易类型 <font color="red">必填项</font>
* @param openId
* 用户ID <font color="red">tradeType=JSAPI时必填</font>
* @param productId
* 产品ID <font color="red">tradeType=NATIVE时必填</font>
* @param attach
* 附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据 非必填项
* @param timeStart
* 订单生成时间格式为yyyyMMddHHmmss 非必填项
* @param timeExpire
* 订单失效时间格式为yyyyMMddHHmmss;注意最短失效时间间隔必须大于5分钟 非必填项
* @param goodsTag
* 商品标记代金券或立减优惠功能的参数 非必填项
* @param limitPay
* 指定支付方式:no_credit--指定不能使用信用卡支付 非必填项
* @param subOpenId
* 用户在子商户appid下的唯一标识 非必填
* openid和sub_openid可以选传其中之一如果选择传sub_openid ,则必须传sub_appid
* @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付
* @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest 刷卡支付
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinException
*/
public MchPayRequest createPayRequest(String body, String detail,
String outTradeNo, double totalFee, String notifyUrl,
String createIp, TradeType tradeType, String openId,
String productId, String attach, Date timeStart, Date timeExpire,
String goodsTag, String limitPay, String subOpenId)
throws WeixinException {
return payApi.createPayRequest(body, detail, outTradeNo, totalFee,
notifyUrl, createIp, tradeType, openId, productId, attach,
timeStart, timeExpire, goodsTag, limitPay, subOpenId);
}
/**
* 创建JSAPI支付请求对象
*
@ -206,7 +152,7 @@ public class WeixinPayProxy {
* @param outTradeNo
* 订单号
* @param totalFee
* 订单总额 按实际金额传入即可() 构造函数会转换为分
* 订单总额()
* @param notifyUrl
* 支付通知地址
* @param createIp
@ -391,10 +337,10 @@ public class WeixinPayProxy {
* </a>
* @throws WeixinException
*/
public MchPayRequest createWAPPayRequest(String body, String outTradeNo,
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach)
throws WeixinException {
return payApi.createWAPPayRequest(body, outTradeNo, totalFee,
return payApi.createWapPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
}
@ -422,10 +368,10 @@ public class WeixinPayProxy {
* 提交被扫支付API</a>
* @throws WeixinException
*/
public MchPayRequest createMICROPayRequest(String authCode, String body,
public MchPayRequest createMicroPayRequest(String authCode, String body,
String outTradeNo, double totalFee, String createIp, String attach)
throws WeixinException {
return payApi.createMICROPayRequest(authCode, body, outTradeNo,
return payApi.createMicroPayRequest(authCode, body, outTradeNo,
totalFee, createIp, attach);
}

View File

@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.type.TradeType;
/**
* 支付订单详情
*
*
* @className MchPayPackage
* @author jinyu(foxinmy@gmail.com)
* @date 2014年10月21日
@ -71,7 +71,7 @@ public class MchPayPackage extends PayPackage {
/**
* 微信支付
*
*
* @param body
* 支付详情 必填
* @param outTradeNo
@ -103,39 +103,37 @@ public class MchPayPackage extends PayPackage {
/**
* 完整参数
*
*
* @param body
* 支付详情 必填
* 商品描述 <font color="red">必填项</font>
* @param detail
* 订单详情 非必填
* 商品名称明细列表 非必填项
* @param outTradeNo
* 商户侧订单号 必填
* 商户内部唯一订单号 <font color="red">必填项</font>
* @param totalFee
* 支付金额(单位元) 必填
* 商品总额 单位元 <font color="red">必填项</font>
* @param notifyUrl
* 支付回调URL 必填
* 支付回调URL <font color="red">必填</font>
* @param createIp
* 发起支付的IP地址 必填
* 订单生成的机器IP <font color="red">必填项</font>
* @param tradeType
* 支付类型 必填
* 交易类型 <font color="red">必填项</font>
* @param openId
* 用户唯一标识 公众号JSAPI支付必填
* 用户ID <font color="red">tradeType=JSAPI时必填</font>
* @param authCode
* 支付授权码 刷卡MICROPAY支付必填
* 刷卡支付授权码 <font color="red">tradeType=MICROPAY时必填</font>
* @param productId
* 商品ID 扫码NATIVE支付必填
* 产品ID <font color="red">tradeType=NATIVE时必填</font>
* @param attach
* 支付时附加信息 非必填
* 附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据 非必填项
* @param timeStart
* 订单生成时间 非必填
* 订单生成时间格式为yyyyMMddHHmmss 非必填
* @param timeExpire
* 订单失效时间 非必填
* 订单失效时间格式为yyyyMMddHHmmss;注意最短失效时间间隔必须大于5分钟 非必填
* @param goodsTag
* 商品标记 非必填
* @param productId
* 商品ID native支付必填
* 商品标记代金券或立减优惠功能的参数 非必填项
* @param limitPay
* 指定支付方式 非必填
* 指定支付方式:no_credit--指定不能使用信用卡支付 非必填项
* @param subOpenId
* 用户在子商户appid下的唯一标识 非必填
* openid和sub_openid可以选传其中之一如果选择传sub_openid ,则必须传sub_appid

View File

@ -126,42 +126,6 @@ public class Redpacket extends MerchantResult {
public Redpacket(String outTradeNo, String sendName, String openId,
double totalAmount, int totalNum, String wishing, String clientIp,
String actName, String remark) {
this(null, null, outTradeNo, sendName, openId, totalAmount, totalNum,
wishing, clientIp, actName, remark);
}
/**
* 红包 完整参数
*
* @param msgAppId
* 触达用户appid 服务商模式下触达用户时的appid(可填服务商自己的appid或子商户的appid)服务商模式下必填
* 服务商模式下填入的子商户appid必须在微信支付商户平台中先录入否则会校验不过
* @param consumeMchId
* 常规模式下无效服务商模式下选填服务商模式下不填默认扣子商户的钱
* @param outTradeNo
* 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 必填
* @param sendName
* 红包发送者名称 必填
* @param openid
* 接受收红包的用户的openid 必填
* @param totalAmount
* 付款金额 <font color="red">单位为元,自动格式化为分</font> 必填
* @param totalNum
* 红包发放总人数 大于1视为裂变红包 必填
* @param wishing
* 红包祝福语 必填
* @param clientIp
* Ip地址 必填
* @param actName
* 活动名称 必填
* @param remark
* 备注 必填
*/
public Redpacket(String msgAppId, String consumeMchId, String outTradeNo,
String sendName, String openId, double totalAmount, int totalNum,
String wishing, String clientIp, String actName, String remark) {
this.msgAppId = msgAppId;
this.consumeMchId = consumeMchId;
this.outTradeNo = outTradeNo;
this.sendName = sendName;
this.openId = openId;
@ -214,6 +178,22 @@ public class Redpacket extends MerchantResult {
return remark;
}
public String getMsgAppId() {
return msgAppId;
}
public void setMsgAppId(String msgAppId) {
this.msgAppId = msgAppId;
}
public String getConsumeMchId() {
return consumeMchId;
}
public void setConsumeMchId(String consumeMchId) {
this.consumeMchId = consumeMchId;
}
@Override
public String toString() {
return "Redpacket [msgAppId=" + msgAppId + ", consumeMchId="

View File

@ -15,6 +15,7 @@ import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.model.WeixinPayAccount;
import com.foxinmy.weixin4j.payment.WeixinPayProxy;
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
import com.foxinmy.weixin4j.payment.mch.MerchantResult;
import com.foxinmy.weixin4j.payment.mch.Order;
import com.foxinmy.weixin4j.payment.mch.PrePay;
@ -29,7 +30,7 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings;
/**
* 支付测试商户平台
*
*
* @className PayTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年1月30日
@ -150,4 +151,16 @@ public class PayTest {
ip, time, returnXml);
System.err.println(returnXml);
}
@Test
public void testMicroPay() throws WeixinException {
String authCode = "扫描码";
String body = "商品描述";
String outTradeNo = "M001";
double totalFee = 1d;
String createIp = "127.0.0.1";
MchPayRequest request = PAY.createMicroPayRequest(authCode, body,
outTradeNo, totalFee, createIp, null);
System.err.println(request);
}
}

View File

@ -59,7 +59,7 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
/**
* V2老支付API
*
*
* @className PayOldApi
* @author jinyu(foxinmy@gmail.com)
* @date 2014年10月28日
@ -111,13 +111,13 @@ public class PayOldApi extends MpApi {
/**
* 生成V2.x版本JSAPI支付字符串
*
*
* @param body
* 支付详情
* @param outTradeNo
* 订单号
* @param totalFee
* 订单总额 按实际金额传入即可() 构造函数会转换为分
* 订单总额()
* @param notifyUrl
* 支付回调URL
* @param createIp
@ -126,50 +126,20 @@ public class PayOldApi extends MpApi {
*/
public String createPayJsRequestJson(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp) {
return createPayJsRequestJson(body, outTradeNo, totalFee, notifyUrl,
createIp, null, null, null, 0d, 0d, null);
PayPackageV2 payPackage = new PayPackageV2(getPayAccount()
.getPartnerId(), body, outTradeNo, totalFee, notifyUrl,
createIp);
return createPayJsRequestJson(payPackage);
}
/**
* 生成V2.x版本JSAPI支付字符串
*
* @param body
* 支付详情
* @param outTradeNo
* 订单号
* @param totalFee
* 订单总额 按实际金额传入即可() 构造函数会转换为分
* @param notifyUrl
* 支付回调URL
* @param createIp
* 订单生成的机器 IP
* @param attach
* 附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据
* @param timeStart
* 订单生成时间格式为yyyyMMddHHmmss
* @param timeExpire
* 订单失效时间格式为yyyyMMddHHmmss;注意最短失效时间间隔必须大于5分钟
* @param transportFee
* 物流费用 如有值 必须保证 transportFee+productFee=totalFee
* @param transportFee
* 商品费用 如有值 必须保证 transportFee+productFee=totalFee
* @param goodsTag
* 商品标记代金券或立减优惠功能的参数
*
* @param payPackage
* 支付信息
* @return 支付json串
*/
public String createPayJsRequestJson(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach,
Date timeStart, Date timeExpire, double transportFee,
double productFee, String goodsTag) {
PayPackageV2 payPackage = new PayPackageV2(getPayAccount()
.getPartnerId(), body, outTradeNo, totalFee, notifyUrl,
createIp);
payPackage.setAttach(attach);
payPackage.setTimeStart(timeStart);
payPackage.setTimeExpire(timeExpire);
payPackage.setTransportFee(transportFee);
payPackage.setProductFee(productFee);
payPackage.setGoodsTag(goodsTag);
public String createPayJsRequestJson(PayPackageV2 payPackage) {
PayRequest payRequest = new PayRequest(getPayAccount().getId(),
weixinOldSignature.sign(payPackage, getPayAccount()
.getPartnerKey()));
@ -181,7 +151,7 @@ public class PayOldApi extends MpApi {
/**
* 创建V2.x NativePay支付链接
*
*
* @param productId
* 与订单ID等价
* @return 支付链接
@ -203,7 +173,7 @@ public class PayOldApi extends MpApi {
/**
* 订单查询
*
*
* @param idQuery
* 订单号
* @return 订单信息
@ -259,7 +229,7 @@ public class PayOldApi extends MpApi {
* 交易时间超过 1 年的订单无法提交退款; </br> 支持部分退款,部分退需要设置相同的订单号和不同的 out_refund_no一笔退款失
* 败后重新提交,要采用原来的 out_refund_no总退款金额不能超过用户实际支付金额</br>
* </p>
*
*
* @param certificate
* 证书文件(V2版本后缀为*.pfx)
* @param idQuery
@ -275,7 +245,7 @@ public class PayOldApi extends MpApi {
* 操作员帐号, 默认为商户号
* @param mopara
* opUserPasswd
*
*
* @return 退款申请结果
* @see com.foxinmy.weixin4j.mp.oldpayment.RefundResultV2
* @since V2
@ -370,7 +340,7 @@ public class PayOldApi extends MpApi {
/**
* 退款申请
*
*
* @param certificate
* 证书文件(V2版本后缀为*.pfx)
* @param idQuery
@ -399,7 +369,7 @@ public class PayOldApi extends MpApi {
/**
* 退款申请
*
*
* @param certificate
* 证书文件(V2版本后缀为*.pfx)
* @param idQuery
@ -452,7 +422,7 @@ public class PayOldApi extends MpApi {
* REVOKED;<br>
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
* 3.对账单中涉及金额的字段单位为<br>
*
*
* @param billDate
* 下载对账单的日期 为空则取前一天
* @param billType
@ -475,8 +445,9 @@ public class PayOldApi extends MpApi {
billType = BillType.ALL;
}
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt", formatBillDate,
billType.name().toLowerCase(), getPayAccount().getId());
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt",
formatBillDate, billType.name().toLowerCase(), getPayAccount()
.getId());
File file = new File(String.format("%s/%s", billPath, fileName));
if (file.exists()) {
return file;
@ -524,7 +495,7 @@ public class PayOldApi extends MpApi {
/**
* 退款查询</br> 退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态
*
*
* @param idQuery
* 单号 refund_idout_refund_no out_trade_no transaction_id
* 四个参数必填一个,优先级为:
@ -550,7 +521,7 @@ public class PayOldApi extends MpApi {
/**
* 发货通知
*
*
* @param openId
* 用户ID
* @param transid
@ -590,7 +561,7 @@ public class PayOldApi extends MpApi {
/**
* 维权处理
*
*
* @param openId
* 用户ID
* @param feedbackId

View File

@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.util.DateUtil;
/**
* V2支付的订单详情
*
*
* @className PayPackageV2
* @author jinyu(foxinmy@gmail.com)
* @date 2014年8月17日
@ -65,12 +65,56 @@ public class PayPackageV2 extends PayPackage {
// jaxb required
}
/**
* 支付信息
*
* @param partner
* 商户号 <font color="red">必填</font>
* @param body
* 支付详情 <font color="red">必填</font>
* @param outTradeNo
* 订单号 <font color="red">必填</font>
* @param totalFee
* 订单总额() <font color="red">必填</font>
* @param notifyUrl
* 支付回调URL <font color="red">必填</font>
* @param createIp
* 订单生成的机器 IP <font color="red">必填</font>
*/
public PayPackageV2(String partner, String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp) {
this(partner, body, outTradeNo, totalFee, notifyUrl, createIp, null,
null, null, 0d, 0d, null);
}
/**
* 支付信息 完整参数
*
* @param partner
* 商户号 <font color="red">必填</font>
* @param body
* 支付详情 <font color="red">必填</font>
* @param outTradeNo
* 订单号 <font color="red">必填</font>
* @param totalFee
* 订单总额() <font color="red">必填</font>
* @param notifyUrl
* 支付回调URL <font color="red">必填</font>
* @param createIp
* 订单生成的机器 IP <font color="red">必填</font>
* @param attach
* 附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据
* @param timeStart
* 订单生成时间格式为yyyyMMddHHmmss
* @param timeExpire
* 订单失效时间格式为yyyyMMddHHmmss;注意最短失效时间间隔必须大于5分钟
* @param transportFee
* 物流费用 如有值 必须保证 transportFee+productFee=totalFee
* @param transportFee
* 商品费用 如有值 必须保证 transportFee+productFee=totalFee
* @param goodsTag
* 商品标记代金券或立减优惠功能的参数
*/
public PayPackageV2(String partner, String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach,
Date timeStart, Date timeExpire, double transportFee,
@ -80,8 +124,8 @@ public class PayPackageV2 extends PayPackage {
setTotalFee(totalFee);
setNotifyUrl(notifyUrl);
setCreateIp(createIp);
setAttach(attach);;
setTimeStart(timeStart);
setAttach(attach);
setTimeStart(timeStart);
setTimeExpire(timeExpire);
setGoodsTag(goodsTag);
this.bankType = "WX";
@ -116,7 +160,7 @@ public class PayPackageV2 extends PayPackage {
/**
* <font color="red">单位为元,自动格式化为分</font>
*
*
* @param transportFee
* 物流费用 单位为元
*/
@ -130,7 +174,7 @@ public class PayPackageV2 extends PayPackage {
/**
* <font color="red">单位为元,自动格式化为分</font>
*
*
* @param productFee
* 商品 单位为元
*/