app、扫码、wap支付新增场景信息参数

This commit is contained in:
jinyu 2018-04-14 22:05:39 +08:00
parent a71facbf8b
commit 6382fe6195
7 changed files with 1712 additions and 1434 deletions

View File

@ -169,3 +169,7 @@
* 2016-08-22
+ 删除`Weixin4jSettings`配置类
* 2018-04-14
+ app、扫码、wap支付新增场景信息参数

View File

@ -32,6 +32,8 @@ import com.foxinmy.weixin4j.payment.mch.Order;
import com.foxinmy.weixin4j.payment.mch.PrePay;
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
import com.foxinmy.weixin4j.payment.mch.RefundResult;
import com.foxinmy.weixin4j.payment.mch.SceneInfoApp;
import com.foxinmy.weixin4j.payment.mch.SceneInfoStore;
import com.foxinmy.weixin4j.payment.mch.WAPPayRequest;
import com.foxinmy.weixin4j.type.CurrencyType;
import com.foxinmy.weixin4j.type.IdQuery;
@ -83,7 +85,8 @@ public class PayApi extends MchApi {
super.declareMerchant(payPackage);
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>() {
});
}
@ -101,21 +104,27 @@ public class PayApi extends MchApi {
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinException
*/
public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException {
public MchPayRequest createPayRequest(MchPayPackage payPackage)
throws WeixinException {
if (StringUtil.isBlank(payPackage.getTradeType())) {
throw new WeixinException("tradeType not be empty");
}
String tradeType = payPackage.getTradeType().toUpperCase();
if (TradeType.MICROPAY.name().equals(tradeType)) {
MchPayPackage _payPackage = new MchPayPackage(payPackage.getBody(), payPackage.getDetail(),
payPackage.getOutTradeNo(), DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null, null,
payPackage.getCreateIp(), null, null, payPackage.getAuthCode(), null, payPackage.getAttach(), null,
null, payPackage.getGoodsTag(), payPackage.getLimitPay(), payPackage.getSubAppId());
MchPayPackage _payPackage = new MchPayPackage(payPackage.getBody(),
payPackage.getDetail(), payPackage.getOutTradeNo(),
DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null,
null, payPackage.getCreateIp(), null, null,
payPackage.getAuthCode(), null, payPackage.getAttach(),
null, null, payPackage.getGoodsTag(),
payPackage.getLimitPay(), payPackage.getSubAppId());
super.declareMerchant(_payPackage);
_payPackage.setSign(weixinSignature.sign(_payPackage));
String para = XmlStream.toXML(_payPackage);
WeixinResponse response = weixinExecutor.post(getRequestUri("micropay_uri"), para);
MICROPayRequest microPayRequest = response.getAsObject(new TypeReference<MICROPayRequest>() {
WeixinResponse response = weixinExecutor.post(
getRequestUri("micropay_uri"), para);
MICROPayRequest microPayRequest = response
.getAsObject(new TypeReference<MICROPayRequest>() {
});
microPayRequest.setPaymentAccount(weixinAccount);
return microPayRequest;
@ -126,9 +135,11 @@ public class PayApi extends MchApi {
} else if (TradeType.JSAPI.name().equals(tradeType)) {
return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount);
} else if (TradeType.NATIVE.name().equals(tradeType)) {
return new NATIVEPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), weixinAccount);
return new NATIVEPayRequest(prePay.getPrepayId(),
prePay.getPayUrl(), weixinAccount);
} else if (TradeType.MWEB.name().equals(tradeType)) {
return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), weixinAccount);
return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(),
weixinAccount);
} else {
throw new WeixinException("unknown tradeType:" + tradeType);
}
@ -155,10 +166,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);
}
@ -167,16 +180,11 @@ public class PayApi extends MchApi {
* 生成编辑地址请求
* </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
@ -226,8 +234,9 @@ 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);
}
/**
@ -257,10 +266,12 @@ 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());
}
@ -292,10 +303,12 @@ 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);
}
@ -314,17 +327,27 @@ public class PayApi extends MchApi {
* 订单生成的机器 IP
* @param attach
* 附加数据 非必填
* @param store
* 门店信息 非必填
* @return APP支付对象
* @see com.foxinmy.weixin4j.payment.mch.SceneInfoStore
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest
* @see <a href=
* "https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1">
* 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,
SceneInfoStore store) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.APP, null, null, null,
attach);
if (store != null) {
payPackage.setSceneInfo(String.format(
"{\"store_id\": \"%s\", \"store_name\":\"%s\"}",
store.getId(), store.getName()));
}
return createPayRequest(payPackage);
}
@ -344,17 +367,26 @@ public class PayApi extends MchApi {
* 订单生成的机器 IP
* @param attach
* 附加数据 非必填
* @param app
* 应用信息
* @return WAP支付对象
* @see com.foxinmy.weixin4j.payment.mch.SceneInfoApp
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest
* @see <a href=
* "https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付
* </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.MWEB,
null, null, null, attach);
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach,
SceneInfoApp app) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, notifyUrl, createIp, TradeType.MWEB, null, null,
null, attach);
if (app != null) {
payPackage.setSceneInfo(String.format("{\"h5_info\":\"%s\"}",
app.getSceneInfo()));
}
return createPayRequest(payPackage);
}
@ -373,28 +405,35 @@ public class PayApi extends MchApi {
* 订单生成的机器 IP
* @param attach
* 附加数据 非必填
* @param store
* 门店信息 非必填
* @return 支付的订单信息
* @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest
* @see com.foxinmy.weixin4j.payment.mch.Order
* @see com.foxinmy.weixin4j.payment.mch.SceneInfoStore
* @see <a href=
* "http://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10">
* 提交被扫支付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, authCode, null, attach);
public MchPayRequest createMicroPayRequest(String authCode, String body,
String outTradeNo, double totalFee, String createIp, String attach,
SceneInfoStore store) throws WeixinException {
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
totalFee, null, createIp, TradeType.MICROPAY, null, authCode,
null, attach);
if (store != null) {
payPackage.setSceneInfo(String.format("{\"store_info\":\"%s\"}",
JSON.toJSONString(store)));
}
return createPayRequest(payPackage);
}
/**
* 订单查询
* <p>
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br>
* 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br>
* 调用关单或撤销接口API之前需确认支付状态
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br> 调用关单或撤销接口API之前需确认支付状态
* </P>
*
* @param idQuery
@ -412,8 +451,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);
}
/**
@ -453,13 +494,16 @@ public class PayApi extends MchApi {
* @since V3
* @throws WeixinException
*/
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee, double refundFee,
CurrencyType refundFeeType, String opUserId, String refundDesc, RefundAccountType refundAccountType)
throws WeixinException {
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee, double refundFee, CurrencyType refundFeeType,
String opUserId, String refundDesc,
RefundAccountType refundAccountType) throws WeixinException {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("out_refund_no", outRefundNo);
map.put("total_fee", Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
map.put("refund_fee", Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
map.put("total_fee",
Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
map.put("refund_fee",
Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
if (StringUtil.isBlank(opUserId)) {
opUserId = weixinAccount.getMchId();
}
@ -477,7 +521,8 @@ public class PayApi extends MchApi {
map.put("refund_account", refundAccountType.name());
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = getWeixinSSLExecutor().post(getRequestUri("refund_apply_uri"), param);
WeixinResponse response = getWeixinSSLExecutor().post(
getRequestUri("refund_apply_uri"), param);
return response.getAsObject(new TypeReference<RefundResult>() {
});
}
@ -494,17 +539,17 @@ public class PayApi extends MchApi {
* 订单总金额,单位为元
* @see {@link #applyRefund(IdQuery, String, double, double, CurrencyType, String, String, RefundAccountType)}
*/
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException {
return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null, null, null, null);
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee) throws WeixinException {
return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null,
null, 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 idQuery
* 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级:
@ -517,7 +562,8 @@ public class PayApi extends MchApi {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = getWeixinSSLExecutor().post(getRequestUri("order_reverse_uri"), param);
WeixinResponse response = getWeixinSSLExecutor().post(
getRequestUri("order_reverse_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() {
});
}
@ -543,7 +589,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");
}
@ -565,10 +612,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>() {
});
}
@ -595,8 +644,8 @@ public class PayApi extends MchApi {
* 下载对账单API</a>
* @throws WeixinException
*/
public void downloadBill(Date billDate, BillType billType, OutputStream outputStream, TarType tarType)
throws WeixinException {
public void downloadBill(Date billDate, BillType billType,
OutputStream outputStream, TarType tarType) throws WeixinException {
if (billDate == null) {
Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_MONTH, -1);
@ -614,7 +663,8 @@ public class PayApi extends MchApi {
}
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);
if (TarType.GZIP == tarType) {
try {
@ -626,8 +676,10 @@ public class PayApi extends MchApi {
BufferedReader reader = null;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(outputStream, Consts.UTF_8));
reader = new BufferedReader(new InputStreamReader(response.getBody(), Consts.UTF_8));
writer = new BufferedWriter(new OutputStreamWriter(
outputStream, Consts.UTF_8));
reader = new BufferedReader(new InputStreamReader(
response.getBody(), Consts.UTF_8));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
@ -674,8 +726,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("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);
}
/**
@ -701,8 +755,9 @@ public class PayApi extends MchApi {
* 交易保障</a>
*/
@SuppressWarnings("unchecked")
public XmlResult reportInterface(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time,
XmlResult returnXml) throws WeixinException {
public XmlResult reportInterface(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));
@ -712,7 +767,8 @@ 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.getAsXml();
}
@ -733,7 +789,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

@ -36,6 +36,8 @@ import com.foxinmy.weixin4j.payment.mch.RedpacketRecord;
import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult;
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
import com.foxinmy.weixin4j.payment.mch.RefundResult;
import com.foxinmy.weixin4j.payment.mch.SceneInfoApp;
import com.foxinmy.weixin4j.payment.mch.SceneInfoStore;
import com.foxinmy.weixin4j.payment.mch.SettlementRecord;
import com.foxinmy.weixin4j.sign.WeixinSignature;
import com.foxinmy.weixin4j.type.CurrencyType;
@ -82,7 +84,8 @@ public class WeixinPayProxy {
* 微信支付接口实现(使用weixin4j.properties配置的account商户信息)
*/
public WeixinPayProxy() {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), WeixinPayAccount.class));
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinPayAccount.class));
}
/**
@ -93,7 +96,8 @@ public class WeixinPayProxy {
*/
public WeixinPayProxy(WeixinPayAccount weixinPayAccount) {
if (weixinPayAccount == null) {
throw new IllegalArgumentException("weixinPayAccount must not be empty");
throw new IllegalArgumentException(
"weixinPayAccount must not be empty");
}
this.weixinPayAccount = weixinPayAccount;
this.payApi = new PayApi(weixinPayAccount);
@ -154,7 +158,8 @@ public class WeixinPayProxy {
* @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString()
* @throws WeixinException
*/
public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException {
public MchPayRequest createPayRequest(MchPayPackage payPackage)
throws WeixinException {
return payApi.createPayRequest(payPackage);
}
@ -181,9 +186,11 @@ public class WeixinPayProxy {
* @return JSAPI支付对象
* @throws WeixinException
*/
public MchPayRequest createJSPayRequest(String openId, String body, String outTradeNo, double totalFee,
String notifyUrl, String createIp, String attach) throws WeixinException {
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
public MchPayRequest createJSPayRequest(String openId, String body,
String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee,
notifyUrl, createIp, attach);
}
/**
@ -191,16 +198,11 @@ public class WeixinPayProxy {
* 生成编辑地址请求
* </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
@ -262,9 +264,11 @@ public class WeixinPayProxy {
* </a>
* @throws WeixinException
*/
public NativePayResponse createNativePayResponse(String productId, String body, String outTradeNo, double totalFee,
String notifyUrl, String createIp, String attach) throws WeixinException {
return payApi.createNativePayResponse(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
public NativePayResponse createNativePayResponse(String productId,
String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
return payApi.createNativePayResponse(productId, body, outTradeNo,
totalFee, notifyUrl, createIp, attach);
}
/**
@ -296,9 +300,11 @@ public class WeixinPayProxy {
* </a>
* @throws WeixinException
*/
public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee,
String notifyUrl, String createIp, String attach) throws WeixinException {
return payApi.createNativePayRequest(productId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
public MchPayRequest createNativePayRequest(String productId, String body,
String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
return payApi.createNativePayRequest(productId, body, outTradeNo,
totalFee, notifyUrl, createIp, attach);
}
/**
@ -316,8 +322,11 @@ public class WeixinPayProxy {
* 订单生成的机器 IP
* @param attach
* 附加数据 非必填
* @param store
* 门店信息 非必填
* @return APP支付对象
* @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.SceneInfoStore
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest
* @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString()
* @see <a href=
@ -325,9 +334,11 @@ public class WeixinPayProxy {
* APP支付</a>
* @throws WeixinException
*/
public MchPayRequest createAppPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
return payApi.createAppPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach);
public MchPayRequest createAppPayRequest(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach,
SceneInfoStore store) throws WeixinException {
return payApi.createAppPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach, store);
}
/**
@ -345,8 +356,11 @@ public class WeixinPayProxy {
* 订单生成的机器 IP
* @param attach
* 附加数据 非必填
* @param app
* 应用信息
* @return WAP支付对象
* @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.SceneInfoApp
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest
* @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString()
* @see <a href=
@ -354,9 +368,11 @@ public class WeixinPayProxy {
* </a>
* @throws WeixinException
*/
public MchPayRequest createWapPayRequest(String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, String attach) throws WeixinException {
return payApi.createWapPayRequest(body, outTradeNo, totalFee, notifyUrl, createIp, attach);
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp, String attach,
SceneInfoApp app) throws WeixinException {
return payApi.createWapPayRequest(body, outTradeNo, totalFee,
notifyUrl, createIp, attach, app);
}
/**
@ -374,9 +390,12 @@ public class WeixinPayProxy {
* 订单生成的机器 IP
* @param attach
* 附加数据 非必填
* @param store
* 门店信息 非必填
* @return 支付的订单信息
* @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.Order
* @see com.foxinmy.weixin4j.payment.mch.SceneInfoStore
* @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest
* @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString()
* @see <a href=
@ -384,18 +403,18 @@ public class WeixinPayProxy {
* 提交被扫支付API</a>
* @throws WeixinException
*/
public MchPayRequest createMicroPayRequest(String authCode, String body, String outTradeNo, double totalFee,
String createIp, String attach) throws WeixinException {
return payApi.createMicroPayRequest(authCode, body, outTradeNo, totalFee, createIp, attach);
public MchPayRequest createMicroPayRequest(String authCode, String body,
String outTradeNo, double totalFee, String createIp, String attach,
SceneInfoStore store) throws WeixinException {
return payApi.createMicroPayRequest(authCode, body, outTradeNo,
totalFee, createIp, attach, store);
}
/**
* 订单查询
* <p>
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br>
* 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br>
* 调用关单或撤销接口API之前需确认支付状态
* 当商户后台网络服务器等出现异常商户系统最终未接收到支付通知</br> 调用支付接口后返回系统错误或未知交易状态情况</br>
* 调用被扫支付API返回USERPAYING的状态</br> 调用关单或撤销接口API之前需确认支付状态
* </P>
*
* @param idQuery
@ -452,11 +471,12 @@ public class WeixinPayProxy {
* @since V3
* @throws WeixinException
*/
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee, double refundFee,
CurrencyType refundFeeType, String opUserId, String refundDesc, RefundAccountType refundAccountType)
throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee, refundFee, refundFeeType, opUserId, refundDesc,
refundAccountType);
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee, double refundFee, CurrencyType refundFeeType,
String opUserId, String refundDesc,
RefundAccountType refundAccountType) throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee, refundFee,
refundFeeType, opUserId, refundDesc, refundAccountType);
}
/**
@ -466,7 +486,8 @@ public class WeixinPayProxy {
*
* @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)}
*/
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException {
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee) throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee);
}
@ -515,18 +536,16 @@ public class WeixinPayProxy {
* 下载对账单API</a>
* @throws WeixinException
*/
public void downloadBill(Date billDate, BillType billType, OutputStream outputStream, TarType tarType)
throws WeixinException {
public void downloadBill(Date billDate, BillType billType,
OutputStream outputStream, TarType tarType) throws WeixinException {
payApi.downloadBill(billDate, billType, outputStream, tarType);
}
/**
* 冲正订单(需要证书)</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 idQuery
* 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级:
@ -602,9 +621,11 @@ public class WeixinPayProxy {
* 接口测试上报API</a>
* @throws WeixinException
*/
public XmlResult reportInterface(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time,
XmlResult returnXml) throws WeixinException {
return payApi.reportInterface(interfaceUrl, executeTime, outTradeNo, ip, time, returnXml);
public XmlResult reportInterface(String interfaceUrl, int executeTime,
String outTradeNo, String ip, Date time, XmlResult returnXml)
throws WeixinException {
return payApi.reportInterface(interfaceUrl, executeTime, outTradeNo,
ip, time, returnXml);
}
/**
@ -626,9 +647,10 @@ public class WeixinPayProxy {
* 发放代金券接口</a>
* @throws WeixinException
*/
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, String openId, String opUserId)
throws WeixinException {
return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId, opUserId);
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
String openId, String opUserId) throws WeixinException {
return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId,
opUserId);
}
/**
@ -644,7 +666,8 @@ public class WeixinPayProxy {
* 查询代金券批次信息接口</a>
* @throws WeixinException
*/
public CouponStock queryCouponStock(String couponStockId) throws WeixinException {
public CouponStock queryCouponStock(String couponStockId)
throws WeixinException {
return couponApi.queryCouponStock(couponStockId);
}
@ -665,7 +688,8 @@ public class WeixinPayProxy {
* 查询代金券详细信息接口</a>
* @throws WeixinException
*/
public CouponDetail queryCouponDetail(String openId, String couponId, String stockId) throws WeixinException {
public CouponDetail queryCouponDetail(String openId, String couponId,
String stockId) throws WeixinException {
return couponApi.queryCouponDetail(openId, couponId, stockId);
}
@ -686,7 +710,8 @@ public class WeixinPayProxy {
* 发放裂变红包接口</a>
* @throws WeixinException
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket) throws WeixinException {
public RedpacketSendResult sendRedpack(Redpacket redpacket)
throws WeixinException {
return cashApi.sendRedpack(redpacket);
}
@ -700,7 +725,8 @@ public class WeixinPayProxy {
* @see #sendRedpacks(Redpacket...)
* @throws WeixinException
*/
public List<Future<RedpacketSendResult>> sendRedpacks(Redpacket... redpackets) {
public List<Future<RedpacketSendResult>> sendRedpacks(
Redpacket... redpackets) {
return cashApi.sendRedpacks(redpackets);
}
@ -720,7 +746,8 @@ public class WeixinPayProxy {
* 查询裂变红包接口</a>
* @throws WeixinException
*/
public RedpacketRecord queryRedpack(String outTradeNo) throws WeixinException {
public RedpacketRecord queryRedpack(String outTradeNo)
throws WeixinException {
return cashApi.queryRedpack(outTradeNo);
}
@ -747,7 +774,8 @@ public class WeixinPayProxy {
* 企业付款接口</a>
* @throws WeixinException
*/
public CorpPaymentResult sendCorpPayment(CorpPayment payment) throws WeixinException {
public CorpPaymentResult sendCorpPayment(CorpPayment payment)
throws WeixinException {
return cashApi.sendCorpPayment(payment);
}
@ -764,7 +792,8 @@ public class WeixinPayProxy {
* 企业付款查询接口</a>
* @throws WeixinException
*/
public CorpPaymentRecord queryCorpPayment(String outTradeNo) throws WeixinException {
public CorpPaymentRecord queryCorpPayment(String outTradeNo)
throws WeixinException {
return cashApi.queryCorpPayment(outTradeNo);
}
@ -804,8 +833,8 @@ public class WeixinPayProxy {
* "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7">
* 查询结算资金接口</a>
*/
public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end)
throws WeixinException {
public SettlementRecord querySettlement(boolean status, Pageable pageable,
Date start, Date end) throws WeixinException {
return cashApi.querySettlement(status, pageable, start, end);
}
@ -823,7 +852,8 @@ public class WeixinPayProxy {
* "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8">
* 查询汇率接口</a>
*/
public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException {
public double queryExchageRate(CurrencyType currencyType, Date date)
throws WeixinException {
return cashApi.queryExchageRate(currencyType, date);
}
@ -841,7 +871,8 @@ public class WeixinPayProxy {
* 附加订单信息提交接口</a>
* @throws WeixinException
*/
public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) throws WeixinException {
public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder)
throws WeixinException {
return customsApi.declareCustomsOrder(customsOrder);
}
@ -860,7 +891,8 @@ public class WeixinPayProxy {
* 附加订单信息查询接口</a>
* @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);
}

View File

@ -71,6 +71,12 @@ public class MchPayPackage extends PayPackage {
@XmlElement(name = "sub_openid")
@JSONField(name = "sub_openid")
private String subOpenId;
/**
* 场景信息
*/
@XmlElement(name = "scene_info")
@JSONField(name = "scene_info")
private String sceneInfo;
protected MchPayPackage() {
// jaxb required
@ -200,11 +206,20 @@ public class MchPayPackage extends PayPackage {
this.subOpenId = subOpenId;
}
public String getSceneInfo() {
return sceneInfo;
}
public void setSceneInfo(String sceneInfo) {
this.sceneInfo = sceneInfo;
}
@Override
public String toString() {
return "MchPayPackage [tradeType=" + tradeType + ",feeType=" + feeType
+ ", openId=" + openId + ", productId=" + productId
+ ", authCode=" + authCode + ", limitPay=" + limitPay
+ ", subOpenId=" + subOpenId + ", " + super.toString() + "]";
+ ", subOpenId=" + subOpenId + ", sceneInfo=" + sceneInfo
+ ", " + super.toString() + "]";
}
}

View File

@ -0,0 +1,99 @@
package com.foxinmy.weixin4j.payment.mch;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SceneInfoApp {
/**
* 终端类型
*/
private String type;
/**
* 应用名称
*/
private String name;
/**
* 应用路径
*/
private String path;
private String sceneInfo;
private SceneInfoApp(String type, String name, String path) {
this.type = type;
this.name = name;
this.path = path;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
public String getPath() {
return path;
}
public String getSceneInfo() {
return sceneInfo;
}
public void setSceneInfo(String sceneInfo) {
this.sceneInfo = sceneInfo;
}
/**
* IOS应用
*
* @param appName 应用名
* @param bundleId 模块ID
* @return
*/
public static SceneInfoApp createIOSAPP(String appName, String bundleId) {
SceneInfoApp app = new SceneInfoApp("IOS", appName, bundleId);
String sceneInfo = String
.format("{\"type\": \"%s\",\"app_name\": \"%s\",\"bundle_id\": \"%s\"}",
app.getType(), app.getName(), app.getPath());
app.setSceneInfo(sceneInfo);
return app;
}
/**
* Android应用
*
* @param appName 应用名
* @param packageName 包名
* @return
*/
public static SceneInfoApp createAndroidAPP(String appName, String packageName) {
SceneInfoApp app = new SceneInfoApp("IOS", appName, packageName);
String sceneInfo = String
.format("{\"type\": \"%s\",\"app_name\": \"%s\",\"package_name\": \"%s\"}",
app.getType(), app.getName(), app.getPath());
app.setSceneInfo(sceneInfo);
return app;
}
/**
* Wap应用
*
* @param name
* 网站名
* @param url
* 网站URL地址
* @return
*/
public static SceneInfoApp createWapAPP(String name, String url) {
SceneInfoApp app = new SceneInfoApp("Wap", name, url);
String sceneInfo = String.format(
"{\"type\": \"%s\",\"wap_name\": \"%s\",\"wap_url\": \"%s\"}",
app.getType(), app.getName(), app.getPath());
app.setSceneInfo(sceneInfo);
return app;
}
}

View File

@ -0,0 +1,75 @@
package com.foxinmy.weixin4j.payment.mch;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SceneInfoStore {
/**
* SZTX001 门店唯一标识
*/
private String id;
/**
* 腾讯大厦腾大餐厅 门店名称
*/
private String name;
/**
* 门店所在地行政区划码详细见最新县及县以上行政区划代码
*/
@XmlElement(name = "area_code")
@JSONField(name = "area_code")
private String areaCode;
/**
* 科技园中一路腾讯大厦 门店详细地址
*/
private String address;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public SceneInfoStore(String id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "SceneInfoStore [id=" + id + ", name=" + name + ", areaCode="
+ areaCode + ", address=" + address + "]";
}
}

View File

@ -45,11 +45,7 @@ public class PayTest {
protected final static WeixinPayProxy PAY;
static {
ACCOUNT = new WeixinPayAccount(
"id",
"支付秘钥",
"商户号",
"加载证书的密码,默认为商户号",
ACCOUNT = new WeixinPayAccount("id", "支付秘钥", "商户号", "加载证书的密码,默认为商户号",
"证书文件路径");
SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey());
PAY = new WeixinPayProxy(ACCOUNT);
@ -171,7 +167,7 @@ public class PayTest {
double totalFee = 1d;
String createIp = "127.0.0.1";
MchPayRequest request = PAY.createMicroPayRequest(authCode, body,
outTradeNo, totalFee, createIp, null);
outTradeNo, totalFee, createIp, null, null);
System.err.println(request);
}
}