diff --git a/weixin4j-base/CHANGE.md b/weixin4j-base/CHANGE.md index b7b4677d..8122a6ec 100644 --- a/weixin4j-base/CHANGE.md +++ b/weixin4j-base/CHANGE.md @@ -168,4 +168,8 @@ * 2016-08-22 - + 删除`Weixin4jSettings`配置类 \ No newline at end of file + + 删除`Weixin4jSettings`配置类 + +* 2018-04-14 + + + app、扫码、wap支付新增场景信息参数 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java index 7c52cba5..0b20a60a 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/PayApi.java @@ -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; @@ -61,680 +63,735 @@ import com.foxinmy.weixin4j.xml.XmlStream; */ public class PayApi extends MchApi { - public PayApi(WeixinPayAccount weixinAccount) { - super(weixinAccount); - } + public PayApi(WeixinPayAccount weixinAccount) { + super(weixinAccount); + } - /** - * 统一下单接口
- * 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI - * 、APP等不同场景生成交易串调起支付。 - * - * @param payPackage - * 包含订单信息的对象 - * @see com.foxinmy.weixin4j.payment.mch.MchPayPackage - * @see com.foxinmy.weixin4j.payment.mch.PrePay - * @see 统一下单接口 - * - * @return 预支付对象 - */ - public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException { - super.declareMerchant(payPackage); - payPackage.setSign(weixinSignature.sign(payPackage)); - String payJsRequestXml = XmlStream.toXML(payPackage); - WeixinResponse response = weixinExecutor.post(getRequestUri("order_create_uri"), payJsRequestXml); - return response.getAsObject(new TypeReference() { - }); - } + /** + * 统一下单接口
+ * 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI + * 、APP等不同场景生成交易串调起支付。 + * + * @param payPackage + * 包含订单信息的对象 + * @see com.foxinmy.weixin4j.payment.mch.MchPayPackage + * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @see 统一下单接口 + * + * @return 预支付对象 + */ + public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException { + super.declareMerchant(payPackage); + payPackage.setSign(weixinSignature.sign(payPackage)); + String payJsRequestXml = XmlStream.toXML(payPackage); + WeixinResponse response = weixinExecutor.post( + getRequestUri("order_create_uri"), payJsRequestXml); + return response.getAsObject(new TypeReference() { + }); + } - /** - * 创建支付请求对象 - * - * @param payPackage - * 支付详情 - * @return 支付请求对象 - * @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(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()); - 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.setPaymentAccount(weixinAccount); - return microPayRequest; - } - PrePay prePay = createPrePay(payPackage); - if (TradeType.APP.name().equals(tradeType)) { - return new APPPayRequest(prePay.getPrepayId(), weixinAccount); - } 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); - } else if (TradeType.MWEB.name().equals(tradeType)) { - return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), weixinAccount); - } else { - throw new WeixinException("unknown tradeType:" + tradeType); - } - } + /** + * 创建支付请求对象 + * + * @param payPackage + * 支付详情 + * @return 支付请求对象 + * @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(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()); + 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.setPaymentAccount(weixinAccount); + return microPayRequest; + } + PrePay prePay = createPrePay(payPackage); + if (TradeType.APP.name().equals(tradeType)) { + return new APPPayRequest(prePay.getPrepayId(), weixinAccount); + } 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); + } else if (TradeType.MWEB.name().equals(tradeType)) { + return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(), + weixinAccount); + } else { + throw new WeixinException("unknown tradeType:" + tradeType); + } + } - /** - * 创建JSAPI支付请求对象 - * - * @param openId - * 用户ID - * @param body - * 订单描述 - * @param outTradeNo - * 订单号 - * @param totalFee - * 订单总额(元) - * @param notifyUrl - * 支付通知地址 - * @param createIp - * ip地址 - * @param attach - * 附加数据 非必填 - * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest - * @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); - return createPayRequest(payPackage); - } + /** + * 创建JSAPI支付请求对象 + * + * @param openId + * 用户ID + * @param body + * 订单描述 + * @param outTradeNo + * 订单号 + * @param totalFee + * 订单总额(元) + * @param notifyUrl + * 支付通知地址 + * @param createIp + * ip地址 + * @param attach + * 附加数据 非必填 + * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest + * @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); + return createPayRequest(payPackage); + } - /** - *

- * 生成编辑地址请求 - *

- * - * err_msg edit_address:ok获取编辑收货地址成功
- * edit_address:fail获取编辑收货地址失败
- * userName 收货人姓名
- * telNumber 收货人电话
- * addressPostalCode 邮编
- * proviceFirstStageName 国标收货地址第一级地址
- * addressCitySecondStageName 国标收货地址第二级地址
- * addressCountiesThirdStageName 国标收货地址第三级地址
- * addressDetailInfo 详细收货地址信息
- * nationalCode 收货地址国家码
- * - * @param url - * 当前访问页的URL - * @param oauthToken - * oauth授权时产生的token - * @see - * 收货地址共享 - * @return 编辑地址请求JSON串 - */ - public String createAddressRequestJSON(String url, String oauthToken) { - Map map = new HashMap(); - map.put("appId", weixinAccount.getId()); - map.put("timeStamp", DateUtil.timestamp2string()); - map.put("nonceStr", RandomUtil.generateString(16)); - map.put("url", url); - map.put("accessToken", oauthToken); - String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true)); - map.remove("url"); - map.remove("accessToken"); - map.put("scope", "jsapi_address"); - map.put("signType", SignType.SHA1.name().toLowerCase()); - map.put("addrSign", sign); - return JSON.toJSONString(map); - } + /** + *

+ * 生成编辑地址请求 + *

+ * + * err_msg edit_address:ok获取编辑收货地址成功
edit_address:fail获取编辑收货地址失败
+ * userName 收货人姓名
telNumber 收货人电话
addressPostalCode 邮编
+ * proviceFirstStageName 国标收货地址第一级地址
addressCitySecondStageName + * 国标收货地址第二级地址
addressCountiesThirdStageName 国标收货地址第三级地址
+ * addressDetailInfo 详细收货地址信息
nationalCode 收货地址国家码
+ * + * @param url + * 当前访问页的URL + * @param oauthToken + * oauth授权时产生的token + * @see + * 收货地址共享 + * @return 编辑地址请求JSON串 + */ + public String createAddressRequestJSON(String url, String oauthToken) { + Map map = new HashMap(); + map.put("appId", weixinAccount.getId()); + map.put("timeStamp", DateUtil.timestamp2string()); + map.put("nonceStr", RandomUtil.generateString(16)); + map.put("url", url); + map.put("accessToken", oauthToken); + String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true)); + map.remove("url"); + map.remove("accessToken"); + map.put("scope", "jsapi_address"); + map.put("signType", SignType.SHA1.name().toLowerCase()); + map.put("addrSign", sign); + return JSON.toJSONString(map); + } - /** - * 创建Native支付(扫码支付)链接【模式一】 - * - * @param productId - * 与订单ID等价 - * @return 支付链接 - * @see 扫码支付 - * - * @see 模式一 - * - */ - public String createNativePayRequest(String productId) { - Map map = new HashMap(); - String timestamp = DateUtil.timestamp2string(); - String noncestr = RandomUtil.generateString(16); - map.put("appid", weixinAccount.getId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("time_stamp", timestamp); - 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); - } + /** + * 创建Native支付(扫码支付)链接【模式一】 + * + * @param productId + * 与订单ID等价 + * @return 支付链接 + * @see 扫码支付 + * + * @see 模式一 + * + */ + public String createNativePayRequest(String productId) { + Map map = new HashMap(); + String timestamp = DateUtil.timestamp2string(); + String noncestr = RandomUtil.generateString(16); + map.put("appid", weixinAccount.getId()); + map.put("mch_id", weixinAccount.getMchId()); + map.put("time_stamp", timestamp); + 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); + } - /** - * 创建Native支付(扫码支付)回调对象【模式一】 - * - * @param productId - * 商品ID - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return Native回调对象 - * @see com.foxinmy.weixin4j.payment.mch.NativePayResponse - * @see 扫码支付 - * - * @see 模式一 - * - * @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); - PrePay prePay = createPrePay(payPackage); - return new NativePayResponse(weixinAccount, prePay.getPrepayId()); - } + /** + * 创建Native支付(扫码支付)回调对象【模式一】 + * + * @param productId + * 商品ID + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @param attach + * 附加数据 非必填 + * @return Native回调对象 + * @see com.foxinmy.weixin4j.payment.mch.NativePayResponse + * @see 扫码支付 + * + * @see 模式一 + * + * @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); + PrePay prePay = createPrePay(payPackage); + return new NativePayResponse(weixinAccount, prePay.getPrepayId()); + } - /** - * 创建Native支付(扫码支付)链接【模式二】 - * - * @param productId - * 商品ID - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return Native支付对象 - * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest - * @see 扫码支付 - * - * @see 模式二 - * - * @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); - return createPayRequest(payPackage); - } + /** + * 创建Native支付(扫码支付)链接【模式二】 + * + * @param productId + * 商品ID + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @param attach + * 附加数据 非必填 + * @return Native支付对象 + * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest + * @see 扫码支付 + * + * @see 模式二 + * + * @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); + return createPayRequest(payPackage); + } - /** - * 创建APP支付请求对象 - * - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return APP支付对象 - * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest - * @see - * APP支付 - * @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); - return createPayRequest(payPackage); - } + /** + * 创建APP支付请求对象 + * + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @param attach + * 附加数据 非必填 + * @param store + * 门店信息 非必填 + * @return APP支付对象 + * @see com.foxinmy.weixin4j.payment.mch.SceneInfoStore + * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest + * @see + * APP支付 + * @throws WeixinException + */ + 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); + } - /** - * 创建WAP支付请求对象:正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面, - * 则可以在MWEB_URL后拼接上redirect_url参数,来指定回调页面 - * - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return WAP支付对象 - * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest - * @see WAP支付 - * - * @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); - return createPayRequest(payPackage); - } + /** + * 创建WAP支付请求对象:正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面, + * 则可以在MWEB_URL后拼接上redirect_url参数,来指定回调页面 + * + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @param attach + * 附加数据 非必填 + * @param app + * 应用信息 + * @return WAP支付对象 + * @see com.foxinmy.weixin4j.payment.mch.SceneInfoApp + * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest + * @see WAP支付 + * + * @throws WeixinException + */ + 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); + } - /** - * 提交被扫支付 - * - * @param authCode - * 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息 - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return 支付的订单信息 - * @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest - * @see com.foxinmy.weixin4j.payment.mch.Order - * @see - * 提交被扫支付API - * @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); - return createPayRequest(payPackage); - } + /** + * 提交被扫支付 + * + * @param authCode + * 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息 + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param createIp + * 订单生成的机器 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 + * 提交被扫支付API + * @throws WeixinException + */ + 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); + } - /** - * 订单查询 - *

- * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
- * 调用支付接口后,返回系统错误或未知交易状态情况;
- * 调用被扫支付API,返回USERPAYING的状态;
- * 调用关单或撤销接口API之前,需确认支付状态; - *

- * - * @param idQuery - * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @return 订单信息 - * @see com.foxinmy.weixin4j.payment.mch.Order - * @see - * 订单查询API - * @since V3 - * @throws WeixinException - */ - public Order queryOrder(IdQuery idQuery) throws WeixinException { - Map 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); - } + /** + * 订单查询 + *

+ * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
调用支付接口后,返回系统错误或未知交易状态情况;
+ * 调用被扫支付API,返回USERPAYING的状态;
调用关单或撤销接口API之前,需确认支付状态; + *

+ * + * @param idQuery + * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @return 订单信息 + * @see com.foxinmy.weixin4j.payment.mch.Order + * @see + * 订单查询API + * @since V3 + * @throws WeixinException + */ + public Order queryOrder(IdQuery idQuery) throws WeixinException { + Map 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); + } - /** - * 申请退款(请求需要双向证书) - *

- * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后, - * 按照退款规则将支付款按原路退到买家帐号上。 - *

- *

- * 1.交易时间超过半年的订单无法提交退款; - * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交 - * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 - *

- * - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @param outRefundNo - * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 - * @param totalFee - * 订单总金额,单位为元 - * @param refundFee - * 退款总金额,单位为元,可以做部分退款 - * @param refundFeeType - * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY - * @param opUserId - * 操作员帐号, 默认为商户号 - * @param refundDesc - * 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因 - * @param refundAccountType - * 退款资金来源,默认使用未结算资金退款:REFUND_SOURCE_UNSETTLED_FUNDS - * @return 退款申请结果 - * @see com.foxinmy.weixin4j.payment.mch.RefundResult - * @see - * 申请退款API - * @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 { - Map 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))); - if (StringUtil.isBlank(opUserId)) { - opUserId = weixinAccount.getMchId(); - } - map.put("op_user_id", opUserId); - if (refundFeeType == null) { - refundFeeType = CurrencyType.CNY; - } - if (refundAccountType == null) { - 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_account", refundAccountType.name()); - map.put("sign", weixinSignature.sign(map)); - String param = XmlStream.map2xml(map); - WeixinResponse response = getWeixinSSLExecutor().post(getRequestUri("refund_apply_uri"), param); - return response.getAsObject(new TypeReference() { - }); - } + /** + * 申请退款(请求需要双向证书) + *

+ * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后, + * 按照退款规则将支付款按原路退到买家帐号上。 + *

+ *

+ * 1.交易时间超过半年的订单无法提交退款; + * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交 + * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 + *

+ * + * @param idQuery + * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @param outRefundNo + * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 + * @param totalFee + * 订单总金额,单位为元 + * @param refundFee + * 退款总金额,单位为元,可以做部分退款 + * @param refundFeeType + * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY + * @param opUserId + * 操作员帐号, 默认为商户号 + * @param refundDesc + * 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因 + * @param refundAccountType + * 退款资金来源,默认使用未结算资金退款:REFUND_SOURCE_UNSETTLED_FUNDS + * @return 退款申请结果 + * @see com.foxinmy.weixin4j.payment.mch.RefundResult + * @see + * 申请退款API + * @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 { + Map 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))); + if (StringUtil.isBlank(opUserId)) { + opUserId = weixinAccount.getMchId(); + } + map.put("op_user_id", opUserId); + if (refundFeeType == null) { + refundFeeType = CurrencyType.CNY; + } + if (refundAccountType == null) { + 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_account", refundAccountType.name()); + map.put("sign", weixinSignature.sign(map)); + String param = XmlStream.map2xml(map); + WeixinResponse response = getWeixinSSLExecutor().post( + getRequestUri("refund_apply_uri"), param); + return response.getAsObject(new TypeReference() { + }); + } - /** - * 退款申请(全额退款) - * - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @param outRefundNo - * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 - * @param totalFee - * 订单总金额,单位为元 - * @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); - } + /** + * 退款申请(全额退款) + * + * @param idQuery + * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @param outRefundNo + * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 + * @param totalFee + * 订单总金额,单位为元 + * @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); + } - /** - * 冲正订单(需要证书)
- * 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
- * 接口逻辑:支 付失败的关单,支付成功的撤销支付
- * 7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口
- * 调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销 - *
- * - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @return 撤销结果 - * @since V3 - * @throws WeixinException - */ - public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException { - Map map = createBaseRequestMap(idQuery); - map.put("sign", weixinSignature.sign(map)); - String param = XmlStream.map2xml(map); - WeixinResponse response = getWeixinSSLExecutor().post(getRequestUri("order_reverse_uri"), param); - return response.getAsObject(new TypeReference() { - }); - } + /** + * 冲正订单(需要证书)
当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
接口逻辑:支 + * 付失败的关单,支付成功的撤销支付
7天以内的单可撤销,其他正常支付的单 + * 如需实现相同功能请调用退款接口
调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
+ * + * @param idQuery + * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @return 撤销结果 + * @since V3 + * @throws WeixinException + */ + public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException { + Map map = createBaseRequestMap(idQuery); + map.put("sign", weixinSignature.sign(map)); + String param = XmlStream.map2xml(map); + WeixinResponse response = getWeixinSSLExecutor().post( + getRequestUri("order_reverse_uri"), param); + return response.getAsObject(new TypeReference() { + }); + } - /** - * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量 - * ,提升扫描速度和精确度。 - * - * @param url - * 具有native标识的支付URL - * @return 转换后的短链接 - * @throws WeixinException - * @see - * 转换短链接API - */ - public String getShorturl(String url) throws WeixinException { - Map map = createBaseRequestMap(null); - try { - map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name())); - } catch (UnsupportedEncodingException e) { - ; - } - map.put("sign", weixinSignature.sign(map)); - String param = XmlStream.map2xml(map); - WeixinResponse response = weixinExecutor.post(getRequestUri("longurl_convert_uri"), param); - map = XmlStream.xml2map(response.getAsString()); - return map.get("short_url"); - } + /** + * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量 + * ,提升扫描速度和精确度。 + * + * @param url + * 具有native标识的支付URL + * @return 转换后的短链接 + * @throws WeixinException + * @see + * 转换短链接API + */ + public String getShorturl(String url) throws WeixinException { + Map map = createBaseRequestMap(null); + try { + map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name())); + } catch (UnsupportedEncodingException e) { + ; + } + map.put("sign", weixinSignature.sign(map)); + String param = XmlStream.map2xml(map); + WeixinResponse response = weixinExecutor.post( + getRequestUri("longurl_convert_uri"), param); + map = XmlStream.xml2map(response.getAsString()); + return map.get("short_url"); + } - /** - * 关闭订单 - *

- * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续 - * ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 - *

- * - * @param outTradeNo - * 商户系统内部的订单号 - * @return 处理结果 - * @since V3 - * @throws WeixinException - * @see - * 关闭订单API - */ - public MerchantResult closeOrder(String outTradeNo) throws WeixinException { - Map 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); - return response.getAsObject(new TypeReference() { - }); - } + /** + * 关闭订单 + *

+ * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续 + * ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 + *

+ * + * @param outTradeNo + * 商户系统内部的订单号 + * @return 处理结果 + * @since V3 + * @throws WeixinException + * @see + * 关闭订单API + */ + public MerchantResult closeOrder(String outTradeNo) throws WeixinException { + Map 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); + return response.getAsObject(new TypeReference() { + }); + } - /** - * 下载对账单
- * 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为 - * REVOKED;
- * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
- * 3.对账单中涉及金额的字段单位为“元”。
- * - * @param billDate - * 下载对账单的日期 - * @param billType - * 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单 - * REFUND,返回当日退款订单 - * @param outputStream - * 输出流 - * @param tarType - * 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 - * @since V3 - * @see - * 下载对账单API - * @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); - billDate = now.getTime(); - } - if (billType == null) { - billType = BillType.ALL; - } - String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate); - Map map = createBaseRequestMap(null); - map.put("bill_date", formatBillDate); - map.put("bill_type", billType.name()); - if (tarType != null) { - map.put("tar_type", tarType.name()); - } - map.put("sign", weixinSignature.sign(map)); - String param = XmlStream.map2xml(map); - WeixinResponse response = weixinExecutor.post(getRequestUri("downloadbill_uri"), param); + /** + * 下载对账单
+ * 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为 + * REVOKED;
+ * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
+ * 3.对账单中涉及金额的字段单位为“元”。
+ * + * @param billDate + * 下载对账单的日期 + * @param billType + * 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单 + * REFUND,返回当日退款订单 + * @param outputStream + * 输出流 + * @param tarType + * 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 + * @since V3 + * @see + * 下载对账单API + * @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); + billDate = now.getTime(); + } + if (billType == null) { + billType = BillType.ALL; + } + String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate); + Map map = createBaseRequestMap(null); + map.put("bill_date", formatBillDate); + map.put("bill_type", billType.name()); + if (tarType != null) { + map.put("tar_type", tarType.name()); + } + map.put("sign", weixinSignature.sign(map)); + String param = XmlStream.map2xml(map); + WeixinResponse response = weixinExecutor.post( + getRequestUri("downloadbill_uri"), param); - if (TarType.GZIP == tarType) { - try { - IOUtil.copy(response.getBody(), outputStream); - } catch (IOException e) { - ; - } - } else { - 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)); - String line = null; - while ((line = reader.readLine()) != null) { - writer.write(line); - writer.newLine(); - } - } catch (IOException e) { - throw new WeixinException(e); - } finally { - try { - if (reader != null) { - reader.close(); - } - if (writer != null) { - writer.close(); - } - } catch (IOException ignore) { - ; - } - } - } - } + if (TarType.GZIP == tarType) { + try { + IOUtil.copy(response.getBody(), outputStream); + } catch (IOException e) { + ; + } + } else { + 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)); + String line = null; + while ((line = reader.readLine()) != null) { + writer.write(line); + writer.newLine(); + } + } catch (IOException e) { + throw new WeixinException(e); + } finally { + try { + if (reader != null) { + reader.close(); + } + if (writer != null) { + writer.close(); + } + } catch (IOException ignore) { + ; + } + } + } + } - /** - * 退款查询 - * - *

- * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 - *

- * - * @param idQuery - * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id - * 四个参数必填一个,优先级为: - * refund_id>out_refund_no>transaction_id>out_trade_no - * @return 退款记录 - * @see com.foxinmy.weixin4j.payment.mch.RefundRecord - * @see com.foxinmy.weixin4j.payment.mch.RefundDetail - * @see - * 退款查询API - * @since V3 - * @throws WeixinException - */ - public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException { - Map 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); - } + /** + * 退款查询 + * + *

+ * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 + *

+ * + * @param idQuery + * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id + * 四个参数必填一个,优先级为: + * refund_id>out_refund_no>transaction_id>out_trade_no + * @return 退款记录 + * @see com.foxinmy.weixin4j.payment.mch.RefundRecord + * @see com.foxinmy.weixin4j.payment.mch.RefundDetail + * @see + * 退款查询API + * @since V3 + * @throws WeixinException + */ + public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException { + Map 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); + } - /** - * 接口上报 - * - * @param interfaceUrl - * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q - * q.com/pay/unifiedorder - * @param executeTime - * 接口耗时情况,单位为毫秒 - * @param outTradeNo - * 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。 - * @param ip - * 发起接口调用时的机器 IP - * @param time - * 商户调用该接口时商户自己 系统的时间 - * @param returnXml - * 调用接口返回的基本数据 - * @return 处理结果 - * @throws WeixinException - * @see - * 交易保障 - */ - @SuppressWarnings("unchecked") - public XmlResult reportInterface(String interfaceUrl, int executeTime, String outTradeNo, String ip, Date time, - XmlResult returnXml) throws WeixinException { - Map map = createBaseRequestMap(null); - map.put("interface_url", interfaceUrl); - map.put("execute_time_", Integer.toString(executeTime)); - map.put("out_trade_no", outTradeNo); - map.put("user_ip", ip); - map.put("time", DateUtil.fortmat2yyyyMMddHHmmss(time)); - map.putAll((Map) JSON.toJSON(returnXml)); - map.put("sign", weixinSignature.sign(map)); - String param = XmlStream.map2xml(map); - WeixinResponse response = weixinExecutor.post(getRequestUri("interface_report_uri"), param); - return response.getAsXml(); - } + /** + * 接口上报 + * + * @param interfaceUrl + * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q + * q.com/pay/unifiedorder + * @param executeTime + * 接口耗时情况,单位为毫秒 + * @param outTradeNo + * 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。 + * @param ip + * 发起接口调用时的机器 IP + * @param time + * 商户调用该接口时商户自己 系统的时间 + * @param returnXml + * 调用接口返回的基本数据 + * @return 处理结果 + * @throws WeixinException + * @see + * 交易保障 + */ + @SuppressWarnings("unchecked") + public XmlResult reportInterface(String interfaceUrl, int executeTime, + String outTradeNo, String ip, Date time, XmlResult returnXml) + throws WeixinException { + Map map = createBaseRequestMap(null); + map.put("interface_url", interfaceUrl); + map.put("execute_time_", Integer.toString(executeTime)); + map.put("out_trade_no", outTradeNo); + map.put("user_ip", ip); + map.put("time", DateUtil.fortmat2yyyyMMddHHmmss(time)); + map.putAll((Map) JSON.toJSON(returnXml)); + map.put("sign", weixinSignature.sign(map)); + String param = XmlStream.map2xml(map); + WeixinResponse response = weixinExecutor.post( + getRequestUri("interface_report_uri"), param); + return response.getAsXml(); + } - /** - * 授权码查询OPENID接口 - * - * @param authCode - * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 - * @return 查询结果 - * @see com.foxinmy.weixin4j.payment.mch.OpenIdResult - * @see - * 授权码查询OPENID - * @throws WeixinException - */ - public OpenIdResult authCode2openId(String authCode) throws WeixinException { - Map map = createBaseRequestMap(null); - 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); - return response.getAsObject(new TypeReference() { - }); - } + /** + * 授权码查询OPENID接口 + * + * @param authCode + * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 + * @return 查询结果 + * @see com.foxinmy.weixin4j.payment.mch.OpenIdResult + * @see + * 授权码查询OPENID + * @throws WeixinException + */ + public OpenIdResult authCode2openId(String authCode) throws WeixinException { + Map map = createBaseRequestMap(null); + 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); + return response.getAsObject(new TypeReference() { + }); + } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java index 3c4ef17c..b3a7363a 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/WeixinPayProxy.java @@ -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; @@ -57,812 +59,842 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; */ public class WeixinPayProxy { - /** - * 微信支付API:js支付、扫码支付等接口 - */ - private final PayApi payApi; - /** - * 代金券API - */ - private final CouponApi couponApi; - /** - * 现金API - */ - private final CashApi cashApi; - /** - * 海关API - */ - private final CustomsApi customsApi; - /** - * 商户信息 - */ - private final WeixinPayAccount weixinPayAccount; + /** + * 微信支付API:js支付、扫码支付等接口 + */ + private final PayApi payApi; + /** + * 代金券API + */ + private final CouponApi couponApi; + /** + * 现金API + */ + private final CashApi cashApi; + /** + * 海关API + */ + private final CustomsApi customsApi; + /** + * 商户信息 + */ + private final WeixinPayAccount weixinPayAccount; - /** - * 微信支付接口实现(使用weixin4j.properties配置的account商户信息) - */ - public WeixinPayProxy() { - this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), WeixinPayAccount.class)); - } + /** + * 微信支付接口实现(使用weixin4j.properties配置的account商户信息) + */ + public WeixinPayProxy() { + this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), + WeixinPayAccount.class)); + } - /** - * 微信支付接口实现 - * - * @param weixinPayAccount - * 微信商户信息 - */ - public WeixinPayProxy(WeixinPayAccount weixinPayAccount) { - if (weixinPayAccount == null) { - throw new IllegalArgumentException("weixinPayAccount must not be empty"); - } - this.weixinPayAccount = weixinPayAccount; - this.payApi = new PayApi(weixinPayAccount); - this.couponApi = new CouponApi(weixinPayAccount); - this.cashApi = new CashApi(weixinPayAccount); - this.customsApi = new CustomsApi(weixinPayAccount); - } + /** + * 微信支付接口实现 + * + * @param weixinPayAccount + * 微信商户信息 + */ + public WeixinPayProxy(WeixinPayAccount weixinPayAccount) { + if (weixinPayAccount == null) { + throw new IllegalArgumentException( + "weixinPayAccount must not be empty"); + } + this.weixinPayAccount = weixinPayAccount; + this.payApi = new PayApi(weixinPayAccount); + this.couponApi = new CouponApi(weixinPayAccount); + this.cashApi = new CashApi(weixinPayAccount); + this.customsApi = new CustomsApi(weixinPayAccount); + } - /** - * 获取微信商户账号信息 - * - * @return - */ - public WeixinPayAccount getWeixinPayAccount() { - return weixinPayAccount; - } + /** + * 获取微信商户账号信息 + * + * @return + */ + public WeixinPayAccount getWeixinPayAccount() { + return weixinPayAccount; + } - /** - * 获取微信签名类 - * - * @return - */ - public WeixinSignature getWeixinSignature() { - return payApi.getWeixinSignature(); - } + /** + * 获取微信签名类 + * + * @return + */ + public WeixinSignature getWeixinSignature() { + return payApi.getWeixinSignature(); + } - /** - * 统一下单接口
- * 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI - * 、APP等不同场景生成交易串调起支付。 - * - * @param payPackage - * 包含订单信息的对象 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.MchPayPackage - * @see com.foxinmy.weixin4j.payment.mch.PrePay - * @see 统一下单接口 - * - * @return 预支付对象 - */ - public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException { - return payApi.createPrePay(payPackage); - } + /** + * 统一下单接口
+ * 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI + * 、APP等不同场景生成交易串调起支付。 + * + * @param payPackage + * 包含订单信息的对象 + * @see com.foxinmy.weixin4j.api.PayApi + * @see com.foxinmy.weixin4j.payment.mch.MchPayPackage + * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @see 统一下单接口 + * + * @return 预支付对象 + */ + public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException { + return payApi.createPrePay(payPackage); + } - /** - * 创建支付请求对象 - * - * @param payPackage - * 支付详情 - * @return 支付请求对象 - * @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支付 - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() - * @throws WeixinException - */ - public MchPayRequest createPayRequest(MchPayPackage payPackage) throws WeixinException { - return payApi.createPayRequest(payPackage); - } + /** + * 创建支付请求对象 + * + * @param payPackage + * 支付详情 + * @return 支付请求对象 + * @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支付 + * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() + * @throws WeixinException + */ + public MchPayRequest createPayRequest(MchPayPackage payPackage) + throws WeixinException { + return payApi.createPayRequest(payPackage); + } - /** - * 创建JSAPI支付请求对象 - * - * @param openId - * 用户ID - * @param body - * 订单描述 - * @param outTradeNo - * 订单号 - * @param totalFee - * 订单总额(元) - * @param notifyUrl - * 支付通知地址 - * @param createIp - * ip地址 - * @param attach - * 附加数据 非必填 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() - * @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); - } + /** + * 创建JSAPI支付请求对象 + * + * @param openId + * 用户ID + * @param body + * 订单描述 + * @param outTradeNo + * 订单号 + * @param totalFee + * 订单总额(元) + * @param notifyUrl + * 支付通知地址 + * @param createIp + * ip地址 + * @param attach + * 附加数据 非必填 + * @see com.foxinmy.weixin4j.api.PayApi + * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest + * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() + * @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); + } - /** - *

- * 生成编辑地址请求 - *

- * - * err_msg edit_address:ok获取编辑收货地址成功
- * edit_address:fail获取编辑收货地址失败
- * userName 收货人姓名
- * telNumber 收货人电话
- * addressPostalCode 邮编
- * proviceFirstStageName 国标收货地址第一级地址
- * addressCitySecondStageName 国标收货地址第二级地址
- * addressCountiesThirdStageName 国标收货地址第三级地址
- * addressDetailInfo 详细收货地址信息
- * nationalCode 收货地址国家码
- * - * @param url - * 当前访问页的URL - * @param oauthToken - * oauth授权时产生的token - * @see com.foxinmy.weixin4j.api.PayApi - * @see - * 收货地址共享 - * @return 编辑地址请求JSON串 - */ - public String createAddressRequestJSON(String url, String oauthToken) { - return payApi.createAddressRequestJSON(url, oauthToken); - } + /** + *

+ * 生成编辑地址请求 + *

+ * + * err_msg edit_address:ok获取编辑收货地址成功
edit_address:fail获取编辑收货地址失败
+ * userName 收货人姓名
telNumber 收货人电话
addressPostalCode 邮编
+ * proviceFirstStageName 国标收货地址第一级地址
addressCitySecondStageName + * 国标收货地址第二级地址
addressCountiesThirdStageName 国标收货地址第三级地址
+ * addressDetailInfo 详细收货地址信息
nationalCode 收货地址国家码
+ * + * @param url + * 当前访问页的URL + * @param oauthToken + * oauth授权时产生的token + * @see com.foxinmy.weixin4j.api.PayApi + * @see + * 收货地址共享 + * @return 编辑地址请求JSON串 + */ + public String createAddressRequestJSON(String url, String oauthToken) { + return payApi.createAddressRequestJSON(url, oauthToken); + } - /** - * 创建Native支付(扫码支付)链接【模式一】 - * - * @param productId - * 与订单ID等价 - * @return 支付链接 - * @see com.foxinmy.weixin4j.api.PayApi - * @see 扫码支付 - * - * @see 模式一 - * - */ - public String createNativePayRequest(String productId) { - return payApi.createNativePayRequest(productId); - } + /** + * 创建Native支付(扫码支付)链接【模式一】 + * + * @param productId + * 与订单ID等价 + * @return 支付链接 + * @see com.foxinmy.weixin4j.api.PayApi + * @see 扫码支付 + * + * @see 模式一 + * + */ + public String createNativePayRequest(String productId) { + return payApi.createNativePayRequest(productId); + } - /** - * 创建Native支付(扫码支付)回调对象【模式一】 - * - * @param productId - * 商品ID - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return Native回调对象 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.NativePayResponse - * @see 扫码支付 - * - * @see 模式一 - * - * @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); - } + /** + * 创建Native支付(扫码支付)回调对象【模式一】 + * + * @param productId + * 商品ID + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @param attach + * 附加数据 非必填 + * @return Native回调对象 + * @see com.foxinmy.weixin4j.api.PayApi + * @see com.foxinmy.weixin4j.payment.mch.NativePayResponse + * @see 扫码支付 + * + * @see 模式一 + * + * @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); + } - /** - * 创建Native支付(扫码支付)链接【模式二】 - * - * @param productId - * 商品ID - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return Native支付对象 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() - * @see 扫码支付 - * - * @see 模式二 - * - * @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); - } + /** + * 创建Native支付(扫码支付)链接【模式二】 + * + * @param productId + * 商品ID + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @param attach + * 附加数据 非必填 + * @return Native支付对象 + * @see com.foxinmy.weixin4j.api.PayApi + * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest + * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() + * @see 扫码支付 + * + * @see 模式二 + * + * @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); + } - /** - * 创建APP支付请求对象 - * - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return APP支付对象 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() - * @see - * APP支付 - * @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); - } + /** + * 创建APP支付请求对象 + * + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 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 + * APP支付 + * @throws WeixinException + */ + 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); + } - /** - * 创建WAP支付请求对象 - * - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return WAP支付对象 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() - * @see WAP支付 - * - * @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); - } + /** + * 创建WAP支付请求对象 + * + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 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 WAP支付 + * + * @throws WeixinException + */ + 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); + } - /** - * 提交被扫支付 - * - * @param authCode - * 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息 - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据 非必填 - * @return 支付的订单信息 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.Order - * @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest#toRequestString() - * @see - * 提交被扫支付API - * @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); - } + /** + * 提交被扫支付 + * + * @param authCode + * 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息 + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param createIp + * 订单生成的机器 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 + * 提交被扫支付API + * @throws WeixinException + */ + 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); + } - /** - * 订单查询 - *

- * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
- * 调用支付接口后,返回系统错误或未知交易状态情况;
- * 调用被扫支付API,返回USERPAYING的状态;
- * 调用关单或撤销接口API之前,需确认支付状态; - *

- * - * @param idQuery - * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @since V3 - * @see com.foxinmy.weixin4j.payment.mch.Order - * @see com.foxinmy.weixin4j.api.PayApi - * @see - * 订单查询API - * @return 订单详情 - * @throws WeixinException - */ - public Order queryOrder(IdQuery idQuery) throws WeixinException { - return payApi.queryOrder(idQuery); - } + /** + * 订单查询 + *

+ * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
调用支付接口后,返回系统错误或未知交易状态情况;
+ * 调用被扫支付API,返回USERPAYING的状态;
调用关单或撤销接口API之前,需确认支付状态; + *

+ * + * @param idQuery + * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @since V3 + * @see com.foxinmy.weixin4j.payment.mch.Order + * @see com.foxinmy.weixin4j.api.PayApi + * @see + * 订单查询API + * @return 订单详情 + * @throws WeixinException + */ + public Order queryOrder(IdQuery idQuery) throws WeixinException { + return payApi.queryOrder(idQuery); + } - /** - * 申请退款(请求需要双向证书)
- *

- * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后, - * 按照退款规则将支付款按原路退到买家帐号上。 - *

- *

- * 1.交易时间超过半年的订单无法提交退款; - * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交 - * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 - *

- * - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @param outRefundNo - * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 - * @param totalFee - * 订单总金额,单位为元 - * @param refundFee - * 退款总金额,单位为元,可以做部分退款 - * @param refundFeeType - * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY - * @param opUserId - * 操作员帐号, 默认为商户号 - * @param refundDesc - * 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因 - * @param refundAccountType - * 退款资金来源,默认使用未结算资金退款:REFUND_SOURCE_UNSETTLED_FUNDS - * @return 退款申请结果 - * @see com.foxinmy.weixin4j.payment.mch.RefundResult - * @see com.foxinmy.weixin4j.api.PayApi - * @see - * 申请退款API - * @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); - } + /** + * 申请退款(请求需要双向证书)
+ *

+ * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后, + * 按照退款规则将支付款按原路退到买家帐号上。 + *

+ *

+ * 1.交易时间超过半年的订单无法提交退款; + * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交 + * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 + *

+ * + * @param idQuery + * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @param outRefundNo + * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 + * @param totalFee + * 订单总金额,单位为元 + * @param refundFee + * 退款总金额,单位为元,可以做部分退款 + * @param refundFeeType + * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY + * @param opUserId + * 操作员帐号, 默认为商户号 + * @param refundDesc + * 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因 + * @param refundAccountType + * 退款资金来源,默认使用未结算资金退款:REFUND_SOURCE_UNSETTLED_FUNDS + * @return 退款申请结果 + * @see com.foxinmy.weixin4j.payment.mch.RefundResult + * @see com.foxinmy.weixin4j.api.PayApi + * @see + * 申请退款API + * @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); + } - /** - * 退款申请(全额退款) - * - * @throws IOException - * - * @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)} - */ - public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, double totalFee) throws WeixinException { - return payApi.applyRefund(idQuery, outRefundNo, totalFee); - } + /** + * 退款申请(全额退款) + * + * @throws IOException + * + * @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)} + */ + public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, + double totalFee) throws WeixinException { + return payApi.applyRefund(idQuery, outRefundNo, totalFee); + } - /** - * 退款查询 - *

- * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 - *

- * - * @param idQuery - * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id - * 四个参数必填一个,优先级为: - * refund_id>out_refund_no>transaction_id>out_trade_no - * @return 退款记录 - * @see com.foxinmy.weixin4j.api.PayApi - * @see com.foxinmy.weixin4j.payment.mch.RefundRecord - * @see - * 退款查询API - * @since V3 - * @throws WeixinException - */ - public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException { - return payApi.queryRefund(idQuery); - } + /** + * 退款查询 + *

+ * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 + *

+ * + * @param idQuery + * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id + * 四个参数必填一个,优先级为: + * refund_id>out_refund_no>transaction_id>out_trade_no + * @return 退款记录 + * @see com.foxinmy.weixin4j.api.PayApi + * @see com.foxinmy.weixin4j.payment.mch.RefundRecord + * @see + * 退款查询API + * @since V3 + * @throws WeixinException + */ + public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException { + return payApi.queryRefund(idQuery); + } - /** - * 下载对账单
- * 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为 - * REVOKED;
- * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
- * 3.对账单中涉及金额的字段单位为“元”。
- * - * @param billDate - * 下载对账单的日期 - * @param billType - * 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单 - * REFUND,返回当日退款订单 - * @para outputStream 输出流 - * @param tarType - * 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 - * @since V2 & V3 - * @see com.foxinmy.weixin4j.api.PayApi - * @see - * 下载对账单API - * @throws WeixinException - */ - public void downloadBill(Date billDate, BillType billType, OutputStream outputStream, TarType tarType) - throws WeixinException { - payApi.downloadBill(billDate, billType, outputStream, tarType); - } + /** + * 下载对账单
+ * 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为 + * REVOKED;
+ * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
+ * 3.对账单中涉及金额的字段单位为“元”。
+ * + * @param billDate + * 下载对账单的日期 + * @param billType + * 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单 + * REFUND,返回当日退款订单 + * @para outputStream 输出流 + * @param tarType + * 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 + * @since V2 & V3 + * @see com.foxinmy.weixin4j.api.PayApi + * @see + * 下载对账单API + * @throws WeixinException + */ + public void downloadBill(Date billDate, BillType billType, + OutputStream outputStream, TarType tarType) throws WeixinException { + payApi.downloadBill(billDate, billType, outputStream, tarType); + } - /** - * 冲正订单(需要证书)
- * 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
- * 接口逻辑:支 付失败的关单,支付成功的撤销支付
- * 7天以内的单可撤销,其他正常支付的单 如需实现相同功能请调用退款接口
- * 调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销 - *
- * - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @return 撤销结果 - * @see com.foxinmy.weixin4j.api.PayApi - * @since V3 - * @throws WeixinException - */ - public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException { - return payApi.reverseOrder(idQuery); - } + /** + * 冲正订单(需要证书)
当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
接口逻辑:支 + * 付失败的关单,支付成功的撤销支付
7天以内的单可撤销,其他正常支付的单 + * 如需实现相同功能请调用退款接口
调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
+ * + * @param idQuery + * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @return 撤销结果 + * @see com.foxinmy.weixin4j.api.PayApi + * @since V3 + * @throws WeixinException + */ + public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException { + return payApi.reverseOrder(idQuery); + } - /** - * 关闭订单 - *

- * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续 - * ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 - *

- * - * @param outTradeNo - * 商户系统内部的订单号 - * @return 执行结果 - * @see com.foxinmy.weixin4j.api.PayApi - * @since V3 - * @throws WeixinException - * @see - * 关闭订单API - */ - public MerchantResult closeOrder(String outTradeNo) throws WeixinException { - return payApi.closeOrder(outTradeNo); - } + /** + * 关闭订单 + *

+ * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续 + * ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 + *

+ * + * @param outTradeNo + * 商户系统内部的订单号 + * @return 执行结果 + * @see com.foxinmy.weixin4j.api.PayApi + * @since V3 + * @throws WeixinException + * @see + * 关闭订单API + */ + public MerchantResult closeOrder(String outTradeNo) throws WeixinException { + return payApi.closeOrder(outTradeNo); + } - /** - * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量 - * ,提升扫描速度和精确度。 - * - * @param url - * 具有native标识的支付URL - * @return 转换后的短链接 - * @see com.foxinmy.weixin4j.api.PayApi - * @see - * 转换短链接API - * @since V3 - * @throws WeixinException - */ - public String getPayShorturl(String url) throws WeixinException { - return payApi.getShorturl(url); - } + /** + * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量 + * ,提升扫描速度和精确度。 + * + * @param url + * 具有native标识的支付URL + * @return 转换后的短链接 + * @see com.foxinmy.weixin4j.api.PayApi + * @see + * 转换短链接API + * @since V3 + * @throws WeixinException + */ + public String getPayShorturl(String url) throws WeixinException { + return payApi.getShorturl(url); + } - /** - * 接口上报 - * - * @param interfaceUrl - * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q - * q.com/pay/unifiedorder - * @param executeTime - * 接口耗时情况,单位为毫秒 - * @param outTradeNo - * 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。 - * @param ip - * 发起接口调用时的机器 IP - * @param time - * 商户调用该接口时商户自己 系统的时间 - * @param returnXml - * 调用接口返回的基本数据 - * @return 处理结果 - * @see com.foxinmy.weixin4j.api.PayApi - * @see - * 接口测试上报API - * @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); - } + /** + * 接口上报 + * + * @param interfaceUrl + * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q + * q.com/pay/unifiedorder + * @param executeTime + * 接口耗时情况,单位为毫秒 + * @param outTradeNo + * 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。 + * @param ip + * 发起接口调用时的机器 IP + * @param time + * 商户调用该接口时商户自己 系统的时间 + * @param returnXml + * 调用接口返回的基本数据 + * @return 处理结果 + * @see com.foxinmy.weixin4j.api.PayApi + * @see + * 接口测试上报API + * @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); + } - /** - * 发放代金券(需要证书) - * - * @param couponStockId - * 代金券批次id - * @param partnerTradeNo - * 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性 - * @param openId - * 用户的openid - * @param opUserId - * 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空 - * @return 发放结果 - * @see com.foxinmy.weixin4j.api.CouponApi - * @see com.foxinmy.weixin4j.payment.coupon.CouponResult - * @see - * 发放代金券接口 - * @throws WeixinException - */ - public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, String openId, String opUserId) - throws WeixinException { - return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId, opUserId); - } + /** + * 发放代金券(需要证书) + * + * @param couponStockId + * 代金券批次id + * @param partnerTradeNo + * 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性 + * @param openId + * 用户的openid + * @param opUserId + * 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空 + * @return 发放结果 + * @see com.foxinmy.weixin4j.api.CouponApi + * @see com.foxinmy.weixin4j.payment.coupon.CouponResult + * @see + * 发放代金券接口 + * @throws WeixinException + */ + public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, + String openId, String opUserId) throws WeixinException { + return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId, + opUserId); + } - /** - * 查询代金券批次 - * - * @param couponStockId - * 代金券批次ID - * @return 代金券批次信息 - * @see com.foxinmy.weixin4j.api.CouponApi - * @see com.foxinmy.weixin4j.payment.coupon.CouponStock - * @see - * 查询代金券批次信息接口 - * @throws WeixinException - */ - public CouponStock queryCouponStock(String couponStockId) throws WeixinException { - return couponApi.queryCouponStock(couponStockId); - } + /** + * 查询代金券批次 + * + * @param couponStockId + * 代金券批次ID + * @return 代金券批次信息 + * @see com.foxinmy.weixin4j.api.CouponApi + * @see com.foxinmy.weixin4j.payment.coupon.CouponStock + * @see + * 查询代金券批次信息接口 + * @throws WeixinException + */ + public CouponStock queryCouponStock(String couponStockId) + throws WeixinException { + return couponApi.queryCouponStock(couponStockId); + } - /** - * 查询代金券详细 - * - * @param openId - * 用户ID - * @param couponId - * 代金券ID - * @param stockId - * 代金劵对应的批次号 - * @return 代金券详细信息 - * @see com.foxinmy.weixin4j.api.CouponApi - * @see com.foxinmy.weixin4j.payment.coupon.CouponDetail - * @see - * 查询代金券详细信息接口 - * @throws WeixinException - */ - public CouponDetail queryCouponDetail(String openId, String couponId, String stockId) throws WeixinException { - return couponApi.queryCouponDetail(openId, couponId, stockId); - } + /** + * 查询代金券详细 + * + * @param openId + * 用户ID + * @param couponId + * 代金券ID + * @param stockId + * 代金劵对应的批次号 + * @return 代金券详细信息 + * @see com.foxinmy.weixin4j.api.CouponApi + * @see com.foxinmy.weixin4j.payment.coupon.CouponDetail + * @see + * 查询代金券详细信息接口 + * @throws WeixinException + */ + public CouponDetail queryCouponDetail(String openId, String couponId, + String stockId) throws WeixinException { + return couponApi.queryCouponDetail(openId, couponId, stockId); + } - /** - * 发放红包 企业向微信用户个人发现金红包 - * - * @param redpacket - * 红包信息 - * @return 发放结果 - * @see com.foxinmy.weixin4j.api.CashApi - * @see com.foxinmy.weixin4j.payment.mch.Redpacket - * @see com.foxinmy.weixin4j.payment.mch.RedpacketSendResult - * @see - * 发放现金红包接口 - * @see - * 发放裂变红包接口 - * @throws WeixinException - */ - public RedpacketSendResult sendRedpack(Redpacket redpacket) throws WeixinException { - return cashApi.sendRedpack(redpacket); - } + /** + * 发放红包 企业向微信用户个人发现金红包 + * + * @param redpacket + * 红包信息 + * @return 发放结果 + * @see com.foxinmy.weixin4j.api.CashApi + * @see com.foxinmy.weixin4j.payment.mch.Redpacket + * @see com.foxinmy.weixin4j.payment.mch.RedpacketSendResult + * @see + * 发放现金红包接口 + * @see + * 发放裂变红包接口 + * @throws WeixinException + */ + public RedpacketSendResult sendRedpack(Redpacket redpacket) + throws WeixinException { + return cashApi.sendRedpack(redpacket); + } - /** - * 批量发放红包 企业向微信用户个人发现金红包 - * - * @param redpacket - * 多个红包信息 - * @return 发放结果 - * @see com.foxinmy.weixin4j.api.CashApi - * @see #sendRedpacks(Redpacket...) - * @throws WeixinException - */ - public List> sendRedpacks(Redpacket... redpackets) { - return cashApi.sendRedpacks(redpackets); - } + /** + * 批量发放红包 企业向微信用户个人发现金红包 + * + * @param redpacket + * 多个红包信息 + * @return 发放结果 + * @see com.foxinmy.weixin4j.api.CashApi + * @see #sendRedpacks(Redpacket...) + * @throws WeixinException + */ + public List> sendRedpacks( + Redpacket... redpackets) { + return cashApi.sendRedpacks(redpackets); + } - /** - * 查询红包记录 - * - * @param outTradeNo - * 商户发放红包的商户订单号 - * @return 红包记录 - * @see com.foxinmy.weixin4j.api.CashApi - * @see com.foxinmy.weixin4j.payment.mch.RedpacketRecord - * @see - * 查询现金红包接口 - * @see - * 查询裂变红包接口 - * @throws WeixinException - */ - public RedpacketRecord queryRedpack(String outTradeNo) throws WeixinException { - return cashApi.queryRedpack(outTradeNo); - } + /** + * 查询红包记录 + * + * @param outTradeNo + * 商户发放红包的商户订单号 + * @return 红包记录 + * @see com.foxinmy.weixin4j.api.CashApi + * @see com.foxinmy.weixin4j.payment.mch.RedpacketRecord + * @see + * 查询现金红包接口 + * @see + * 查询裂变红包接口 + * @throws WeixinException + */ + public RedpacketRecord queryRedpack(String outTradeNo) + throws WeixinException { + return cashApi.queryRedpack(outTradeNo); + } - /** - * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 - *

- * 接口调用规则: - *

- *

  • 给同一个实名用户付款,单笔单日限额2W/2W - *
  • 给同一个非实名用户付款,单笔单日限额2000/2000 - *
  • 一个商户同一日付款总额限额100W - *
  • 单笔最小金额默认为1元 - *
  • 每个用户每天最多可付款10次,可以在商户平台--API安全进行设置 - *
  • 给同一个用户付款时间间隔不得低于15秒 - * - * @param payment - * 付款信息 - * @return 付款结果 - * @see com.foxinmy.weixin4j.api.CashApi - * @see com.foxinmy.weixin4j.payment.mch.CorpPayment - * @see com.foxinmy.weixin4j.payment.mch.CorpPaymentResult - * @see - * 企业付款接口 - * @throws WeixinException - */ - public CorpPaymentResult sendCorpPayment(CorpPayment payment) throws WeixinException { - return cashApi.sendCorpPayment(payment); - } + /** + * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 + *

    + * 接口调用规则: + *

    + *

  • 给同一个实名用户付款,单笔单日限额2W/2W + *
  • 给同一个非实名用户付款,单笔单日限额2000/2000 + *
  • 一个商户同一日付款总额限额100W + *
  • 单笔最小金额默认为1元 + *
  • 每个用户每天最多可付款10次,可以在商户平台--API安全进行设置 + *
  • 给同一个用户付款时间间隔不得低于15秒 + * + * @param payment + * 付款信息 + * @return 付款结果 + * @see com.foxinmy.weixin4j.api.CashApi + * @see com.foxinmy.weixin4j.payment.mch.CorpPayment + * @see com.foxinmy.weixin4j.payment.mch.CorpPaymentResult + * @see + * 企业付款接口 + * @throws WeixinException + */ + public CorpPaymentResult sendCorpPayment(CorpPayment payment) + throws WeixinException { + return cashApi.sendCorpPayment(payment); + } - /** - * 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果 - * - * @param outTradeNo - * 商户调用企业付款API时使用的商户订单号 - * @return 付款记录 - * @see com.foxinmy.weixin4j.api.CashApi - * @see com.foxinmy.weixin4j.payment.mch.CorpPaymentRecord - * @see - * 企业付款查询接口 - * @throws WeixinException - */ - public CorpPaymentRecord queryCorpPayment(String outTradeNo) throws WeixinException { - return cashApi.queryCorpPayment(outTradeNo); - } + /** + * 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果 + * + * @param outTradeNo + * 商户调用企业付款API时使用的商户订单号 + * @return 付款记录 + * @see com.foxinmy.weixin4j.api.CashApi + * @see com.foxinmy.weixin4j.payment.mch.CorpPaymentRecord + * @see + * 企业付款查询接口 + * @throws WeixinException + */ + public CorpPaymentRecord queryCorpPayment(String outTradeNo) + throws WeixinException { + return cashApi.queryCorpPayment(outTradeNo); + } - /** - * 授权码查询OPENID - * - * @param authCode - * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 - * @return 查询结果 - * @see com.foxinmy.weixin4j.api.CashApi - * @see com.foxinmy.weixin4j.payment.mch.OpenIdResult - * @see - * 授权码查询OPENID - * @throws WeixinException - */ - public OpenIdResult authCode2openId(String authCode) throws WeixinException { - return payApi.authCode2openId(authCode); - } + /** + * 授权码查询OPENID + * + * @param authCode + * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 + * @return 查询结果 + * @see com.foxinmy.weixin4j.api.CashApi + * @see com.foxinmy.weixin4j.payment.mch.OpenIdResult + * @see + * 授权码查询OPENID + * @throws WeixinException + */ + public OpenIdResult authCode2openId(String authCode) throws WeixinException { + return payApi.authCode2openId(authCode); + } - /** - * 查询结算资金 - * - * @param status - * 是否结算 - * @param pageable - * 分页数据 - * @param start - * 开始日期 查询未结算记录时,该字段可不传 - * @param end - * 结束日期 查询未结算记录时,该字段可不传 - * @return 结算金额记录 - * @throws WeixinException - * @see com.foxinmy.weixin4j.api.CashApi - * @see com.foxinmy.weixin4j.payment.mch.SettlementRecord - * @see - * 查询结算资金接口 - */ - public SettlementRecord querySettlement(boolean status, Pageable pageable, Date start, Date end) - throws WeixinException { - return cashApi.querySettlement(status, pageable, start, end); - } + /** + * 查询结算资金 + * + * @param status + * 是否结算 + * @param pageable + * 分页数据 + * @param start + * 开始日期 查询未结算记录时,该字段可不传 + * @param end + * 结束日期 查询未结算记录时,该字段可不传 + * @return 结算金额记录 + * @throws WeixinException + * @see com.foxinmy.weixin4j.api.CashApi + * @see com.foxinmy.weixin4j.payment.mch.SettlementRecord + * @see + * 查询结算资金接口 + */ + public SettlementRecord querySettlement(boolean status, Pageable pageable, + Date start, Date end) throws WeixinException { + return cashApi.querySettlement(status, pageable, start, end); + } - /** - * 查询汇率 - * - * @param currencyType - * 外币币种 - * @param date - * 日期 不填则默认当天 - * @return 汇率对象 - * @throws WeixinException - * @see com.foxinmy.weixin4j.api.CashApi - * @see - * 查询汇率接口 - */ - public double queryExchageRate(CurrencyType currencyType, Date date) throws WeixinException { - return cashApi.queryExchageRate(currencyType, date); - } + /** + * 查询汇率 + * + * @param currencyType + * 外币币种 + * @param date + * 日期 不填则默认当天 + * @return 汇率对象 + * @throws WeixinException + * @see com.foxinmy.weixin4j.api.CashApi + * @see + * 查询汇率接口 + */ + public double queryExchageRate(CurrencyType currencyType, Date date) + throws WeixinException { + return cashApi.queryExchageRate(currencyType, date); + } - /** - * 订单附加信息提交 - * - * @param customsOrder - * 附加订单信息 - * @return 报关结果 - * @see com.foxinmy.weixin4j.api.CustomsApi - * @see com.foxinmy.weixin4j.payment.mch.CustomsOrder - * @see com.foxinmy.weixin4j.payment.mch.CustomsOrderResult - * @see - * 附加订单信息提交接口 - * @throws WeixinException - */ - public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) throws WeixinException { - return customsApi.declareCustomsOrder(customsOrder); - } + /** + * 订单附加信息提交 + * + * @param customsOrder + * 附加订单信息 + * @return 报关结果 + * @see com.foxinmy.weixin4j.api.CustomsApi + * @see com.foxinmy.weixin4j.payment.mch.CustomsOrder + * @see com.foxinmy.weixin4j.payment.mch.CustomsOrderResult + * @see + * 附加订单信息提交接口 + * @throws WeixinException + */ + public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder) + throws WeixinException { + return customsApi.declareCustomsOrder(customsOrder); + } - /** - * 订单附加信息查询 - * - * @param idQuery - * out_trade_no,transaction_id,sub_order_no,sub_order_id四选一 - * @param customsCity - * 海关 - * @return 报关记录 - * @see com.foxinmy.weixin4j.payment.mch.CustomsOrderRecord - * @see com.foxinmy.weixin4j.api.CustomsApi - * @see - * 附加订单信息查询接口 - * @throws WeixinException - */ - public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery, CustomsCity customsCity) throws WeixinException { - return customsApi.queryCustomsOrder(idQuery, customsCity); - } + /** + * 订单附加信息查询 + * + * @param idQuery + * out_trade_no,transaction_id,sub_order_no,sub_order_id四选一 + * @param customsCity + * 海关 + * @return 报关记录 + * @see com.foxinmy.weixin4j.payment.mch.CustomsOrderRecord + * @see com.foxinmy.weixin4j.api.CustomsApi + * @see + * 附加订单信息查询接口 + * @throws WeixinException + */ + public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery, + CustomsCity customsCity) throws WeixinException { + return customsApi.queryCustomsOrder(idQuery, customsCity); + } - public final static String VERSION = "1.7.9"; + public final static String VERSION = "1.7.9"; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayPackage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayPackage.java index 4df383da..f454c14e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayPackage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayPackage.java @@ -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() + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/SceneInfoApp.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/SceneInfoApp.java new file mode 100644 index 00000000..95d652ef --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/SceneInfoApp.java @@ -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; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/SceneInfoStore.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/SceneInfoStore.java new file mode 100644 index 00000000..23674a6b --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/SceneInfoStore.java @@ -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 + "]"; + } +} \ No newline at end of file diff --git a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java index 689a1b01..25e8e118 100644 --- a/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java +++ b/weixin4j-base/src/test/java/com/foxinmy/weixin4j/base/test/PayTest.java @@ -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); } } \ No newline at end of file