diff --git a/CHANGE.md b/CHANGE.md index 7a913147..6cf7e674 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -596,4 +596,9 @@ + weixin4j-qy:新增企业号联系人筛选配置类(JSSDKContactConfigurator) + weixin4j-server:DigestUtil 重命名为 DigestUtils + + +* 2015-12-26 + + + weixin4j-base:MchPayRequest抽象化 \ No newline at end of file diff --git a/README.md b/README.md index 803613a2..517c3ae2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ weixin4j ------- * **weixin4j-base** - `微信支付(刷卡/扫码/公众号/现金红包/企业付款)` + `微信支付(刷卡/扫码/JS/APP/WAP/现金红包/企业付款)` * **weixin4j-mp** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/Pay3Api.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/Pay3Api.java index b19259c5..359c860f 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/Pay3Api.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/Pay3Api.java @@ -27,19 +27,22 @@ import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.payment.MicroPayPackage; import com.foxinmy.weixin4j.payment.PayURLConsts; +import com.foxinmy.weixin4j.payment.mch.APPPayRequest; import com.foxinmy.weixin4j.payment.mch.ApiResult; import com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult; +import com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest; import com.foxinmy.weixin4j.payment.mch.MchPayPackage; import com.foxinmy.weixin4j.payment.mch.MchPayRequest; +import com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest; 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.WAPPayRequest; import com.foxinmy.weixin4j.type.BillType; import com.foxinmy.weixin4j.type.CurrencyType; import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdType; -import com.foxinmy.weixin4j.type.SignType; import com.foxinmy.weixin4j.type.TradeType; import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.DigestUtil; @@ -109,7 +112,40 @@ public class Pay3Api { } /** - * 生成V3.x版本JSAPI支付请求对象 + * 创建支付请求对象 + * + * @param payPackage + * 支付详情 + * @return 支付请求对象 + * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付 + * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付 + * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付 + * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付 + * @throws WeixinPayException + */ + public MchPayRequest createPayRequest(MchPayPackage payPackage) + throws WeixinPayException { + payPackage.setSign(DigestUtil.paysignMd5(payPackage, + weixinAccount.getPaySignKey())); + PrePay prePay = createPrePay(payPackage); + String tradeType = payPackage.getTradeType(); + if (TradeType.APP.name().equalsIgnoreCase(tradeType)) { + return new APPPayRequest(prePay, weixinAccount); + } else if (TradeType.JSAPI.name().equalsIgnoreCase(tradeType)) { + return new JSAPIPayRequest(prePay, weixinAccount); + } else if (TradeType.NATIVE.name().equalsIgnoreCase(tradeType)) { + return new NATIVEPayRequest(prePay, weixinAccount); + } else if (TradeType.WAP.name().equalsIgnoreCase(tradeType)) { + return new WAPPayRequest(prePay, weixinAccount); + } else if (TradeType.MICROPAY.name().equalsIgnoreCase(tradeType)) { + throw new WeixinPayException("maybe use createMicroPay method?"); + } else { + throw new WeixinPayException("unknown tradeType:" + tradeType); + } + } + + /** + * 创建JSAPI支付请求对象 * * @param openId * 用户ID @@ -123,74 +159,21 @@ public class Pay3Api { * 支付通知地址 * @param createIp * ip地址 - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest - * @return MchPayRequest对象;注意:如果要转换为JSON格式请使用fastjson中的JSON - * #toJSONString方法或直接用MchPayRequest#asPayJsRequestJson方法 + * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest + * @return JSAPI支付对象 * @throws WeixinPayException */ - public MchPayRequest createPayJsRequest(String openId, String body, + public MchPayRequest createJsPayRequest(String openId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return createPayJsRequest(openId, body, outTradeNo, totalFee, - notifyUrl, createIp, null, null, null, null, null); - } - - /** - * 生成V3.x版本JSAPI支付请求对象【完整参数】 - * - * @param openId - * 用户ID - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 - * @param timeStart - * 订单生成时间,格式为yyyyMMddHHmmss - * @param timeExpire - * 订单失效时间,格式为yyyyMMddHHmmss;注意:最短失效时间间隔必须大于5分钟 - * @param goodsTag - * 商品标记,代金券或立减优惠功能的参数 - * @param limitPay - * 指定支付方式:no_credit--指定不能使用信用卡支付 - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest - * @return MchPayRequest对象;注意:如果要转换为JSON格式请使用fastjson中的JSON对象或者直接用MchPayRequest# - * asPayJsRequestJson方法 - * @throws WeixinPayException - */ - public MchPayRequest createPayJsRequest(String openId, String body, - String outTradeNo, double totalFee, String notifyUrl, - String createIp, String attach, Date timeStart, Date timeExpire, - String goodsTag, String limitPay) throws WeixinPayException { MchPayPackage payPackage = new MchPayPackage(weixinAccount, openId, body, outTradeNo, totalFee, notifyUrl, createIp, TradeType.JSAPI); - payPackage.setAttach(attach); - payPackage.setTimeStart(timeStart); - payPackage.setTimeExpire(timeExpire); - payPackage.setGoodsTag(goodsTag); - payPackage.setLimitPay(limitPay); - payPackage.setSign(DigestUtil.paysignMd5(payPackage, - weixinAccount.getPaySignKey())); - PrePay prePay = createPrePay(payPackage); - MchPayRequest jsPayRequest = new MchPayRequest(prePay); - jsPayRequest.setSignType(SignType.MD5); - jsPayRequest.setPaySign(DigestUtil.paysignMd5(jsPayRequest, - weixinAccount.getPaySignKey())); - return jsPayRequest; + return createPayRequest(payPackage); } /** - * 创建V3.x NativePay支付(扫码支付)链接【模式一】 + * 创建Native支付(扫码支付)链接【模式一】 * * @param productId * 与订单ID等价 @@ -215,7 +198,7 @@ public class Pay3Api { } /** - * 创建V3.x NativePay支付(扫码支付)链接【模式二】【必填参数】 + * 创建Native支付(扫码支付)链接【模式二】 * * @param productId * 商品ID @@ -229,24 +212,24 @@ public class Pay3Api { * 支付回调URL * @param createIp * 订单生成的机器 IP - * @return 支付链接 + * @return Native支付对象 + * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest * @see 扫码支付 * @see 模式二 * @throws WeixinPayException */ - public String createNativePayRequestURL(String productId, String body, + public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return createNativePayRequestURL(productId, body, outTradeNo, totalFee, - notifyUrl, createIp, null, null, null, null, null); + MchPayPackage payPackage = new MchPayPackage(weixinAccount, null, body, + outTradeNo, totalFee, notifyUrl, createIp, TradeType.NATIVE); + return createPayRequest(payPackage); } /** - * 创建V3.x Native支付(扫码支付)链接【模式二】【完整参数】 + * 创建APP支付请求对象 * - * @param productId - * 商品ID * @param body * 商品描述 * @param outTradeNo @@ -257,38 +240,45 @@ public class Pay3Api { * 支付回调URL * @param createIp * 订单生成的机器 IP - * @param attach - * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 - * @param timeStart - * 订单生成时间,格式为yyyyMMddHHmmss - * @param timeExpire - * 订单失效时间,格式为yyyyMMddHHmmss;注意:最短失效时间间隔必须大于5分钟 - * @param goodsTag - * 商品标记,代金券或立减优惠功能的参数 - * @param limitPay - * 指定支付方式:no_credit--指定不能使用信用卡支付 - * @return 支付链接 - * @see 扫码支付 + * @return APP支付对象 + * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest * @see 模式二 + * href="https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1">APP支付 * @throws WeixinPayException */ - public String createNativePayRequestURL(String productId, String body, - String outTradeNo, double totalFee, String notifyUrl, - String createIp, String attach, Date timeStart, Date timeExpire, - String goodsTag, String limitPay) throws WeixinPayException { + public MchPayRequest createAppPayRequest(String body, String outTradeNo, + double totalFee, String notifyUrl, String createIp) + throws WeixinPayException { MchPayPackage payPackage = new MchPayPackage(weixinAccount, null, body, - outTradeNo, totalFee, notifyUrl, createIp, TradeType.NATIVE); - payPackage.setProductId(productId); - payPackage.setAttach(attach); - payPackage.setTimeStart(timeStart); - payPackage.setTimeExpire(timeExpire); - payPackage.setGoodsTag(goodsTag); - payPackage.setLimitPay(limitPay); - payPackage.setSign(DigestUtil.paysignMd5(payPackage, - weixinAccount.getPaySignKey())); - PrePay prePay = createPrePay(payPackage); - return prePay.getCodeUrl(); + outTradeNo, totalFee, notifyUrl, createIp, TradeType.APP); + return createPayRequest(payPackage); + } + + /** + * 创建WAP支付请求对象 + * + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @return WAP支付对象 + * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest + * @see WAP支付 + * @throws WeixinPayException + */ + public MchPayRequest createWAPPayRequest(String body, String outTradeNo, + double totalFee, String notifyUrl, String createIp) + throws WeixinPayException { + MchPayPackage payPackage = new MchPayPackage(weixinAccount, null, body, + outTradeNo, totalFee, notifyUrl, createIp, TradeType.WAP); + return createPayRequest(payPackage); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayRequest.java index 522506c1..91113ad3 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayRequest.java @@ -4,6 +4,7 @@ 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 javax.xml.bind.annotation.XmlTransient; import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.util.DateUtil; @@ -22,6 +23,19 @@ public class PayRequest extends PayBaseInfo { @JSONField(name = "package") private String packageInfo; + /** + * 冗余字段 + */ + @XmlTransient + @JSONField(serialize = false) + private String prepayId; + /** + * 冗余字段 + */ + @XmlTransient + @JSONField(serialize = false) + private String partnerId; + public PayRequest() { super(null, DateUtil.timestamp2string(), RandomUtil.generateString(16)); } @@ -39,6 +53,22 @@ public class PayRequest extends PayBaseInfo { this.packageInfo = packageInfo; } + public String getPrepayId() { + return prepayId; + } + + public void setPrepayId(String prepayId) { + this.prepayId = prepayId; + } + + public String getPartnerId() { + return partnerId; + } + + public void setPartnerId(String partnerId) { + this.partnerId = partnerId; + } + @Override public String toString() { return "package" + packageInfo + ", " + super.toString(); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java index c7f2d723..fd1b786b 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/PayURLConsts.java @@ -113,12 +113,19 @@ public final class PayURLConsts { */ public static final String MCH_NATIVE_URL = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s"; + /** + * WAP支付 + * + * @see WAP支付说明 + */ + public static final String MCH_WAP_URL = "weixin://wap/pay?%s"; /** * 授权码查询OPENID接口 */ public static final String MCH_AUTHCODE_OPENID_URL = MCH_BASE_URL + "/tools/authcodetoopenid"; - + /** *

* 生成编辑地址请求 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 ba3139da..6564f510 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 @@ -66,7 +66,6 @@ public class WeixinPayProxy { * * @param weixinAccount * 支付相关的公众号账号信息 - * */ public WeixinPayProxy(WeixinPayAccount weixinAccount) { this.weixinAccount = weixinAccount; @@ -106,7 +105,25 @@ public class WeixinPayProxy { } /** - * 生成JSAPI支付请求对象 + * 创建支付请求对象 + * + * @param payPackage + * 支付详情 + * @return 支付请求对象 + * @see com.foxinmy.weixin4j.api.Pay3Api + * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付 + * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付 + * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付 + * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付 + * @throws WeixinPayException + */ + public MchPayRequest createPayRequest(MchPayPackage payPackage) + throws WeixinPayException { + return pay3Api.createPayRequest(payPackage); + } + + /** + * 创建JSAPI支付请求对象 * * @param openId * 用户ID @@ -120,61 +137,18 @@ public class WeixinPayProxy { * 支付通知地址 * @param createIp * ip地址 - * @return MchPayRequest对象;注意:如果要转换为JSON格式请使用fastjson中的JSON - * #toJSONString方法或直接用MchPayRequest#asPayJsRequestJson方法 * @see com.foxinmy.weixin4j.api.Pay3Api - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest + * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest + * @return JSAPI支付对象 * @throws WeixinPayException */ - public MchPayRequest createPayJsRequest(String openId, String body, + public MchPayRequest createJsPayRequest(String openId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createPayJsRequest(openId, body, outTradeNo, totalFee, + return pay3Api.createJsPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp); } - /** - * 生成JSAPI支付请求对象【完整参数】 - * - * @param openId - * 用户ID - * @param body - * 商品描述 - * @param outTradeNo - * 商户内部唯一订单号 - * @param totalFee - * 商品总额 单位元 - * @param notifyUrl - * 支付回调URL - * @param createIp - * 订单生成的机器 IP - * @param attach - * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 - * @param timeStart - * 订单生成时间,格式为yyyyMMddHHmmss - * @param timeExpire - * 订单失效时间,格式为yyyyMMddHHmmss;注意:最短失效时间间隔必须大于5分钟 - * @param goodsTag - * 商品标记,代金券或立减优惠功能的参数 - * @param limitPay - * 指定支付方式:no_credit--指定不能使用信用卡支付 - * @see com.foxinmy.weixin4j.api.Pay3Api - * @see com.foxinmy.weixin4j.payment.mch.MchPayRequest - * @return MchPayRequest对象;注意:如果要转换为JSON格式请使用fastjson中的JSON - * #toJSONString方法或直接用MchPayRequest#asPayJsRequestJson方法 - * @throws WeixinPayException - */ - public MchPayRequest createPayJsRequest(String openId, String body, - String outTradeNo, double totalFee, String notifyUrl, - String createIp, String attach, Date timeStart, Date timeExpire, - String goodsTag, String limitPay) throws WeixinPayException { - return pay3Api.createPayJsRequest(openId, body, outTradeNo, totalFee, - notifyUrl, createIp, attach, timeStart, timeExpire, goodsTag, - limitPay); - } - /** * 创建Native支付(扫码支付)链接【模式一】 * @@ -191,7 +165,7 @@ public class WeixinPayProxy { } /** - * 创建V3.x NativePay支付(扫码支付)链接【模式二】【必填参数】 + * 创建Native支付(扫码支付)链接【模式二】 * * @param productId * 商品ID @@ -205,25 +179,24 @@ public class WeixinPayProxy { * 支付回调URL * @param createIp * 订单生成的机器 IP - * @return 支付链接 + * @return Native支付对象 * @see com.foxinmy.weixin4j.api.Pay3Api + * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest * @see 扫码支付 * @see 模式二 * @throws WeixinPayException */ - public String createNativePayRequestURL(String productId, String body, + public MchPayRequest createNativePayRequest(String productId, String body, String outTradeNo, double totalFee, String notifyUrl, String createIp) throws WeixinPayException { - return pay3Api.createNativePayRequestURL(productId, body, outTradeNo, + return pay3Api.createNativePayRequest(productId, body, outTradeNo, totalFee, notifyUrl, createIp); } /** - * 创建Native支付(扫码支付)链接【模式二】【完整参数】 + * 创建APP支付请求对象 * - * @param productId - * 商品ID * @param body * 商品描述 * @param outTradeNo @@ -234,30 +207,45 @@ public class WeixinPayProxy { * 支付回调URL * @param createIp * 订单生成的机器 IP - * @param attach - * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 - * @param timeStart - * 订单生成时间,格式为yyyyMMddHHmmss - * @param timeExpire - * 订单失效时间,格式为yyyyMMddHHmmss;注意:最短失效时间间隔必须大于5分钟 - * @param goodsTag - * 商品标记,代金券或立减优惠功能的参数 - * @param limitPay - * 指定支付方式:no_credit--指定不能使用信用卡支付 - * @return 支付链接 + * @return APP支付对象 * @see com.foxinmy.weixin4j.api.Pay3Api - * @see 扫码支付 + * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest * @see 模式二 + * href="https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1">APP支付 * @throws WeixinPayException */ - public String createNativePayRequestURL(String productId, String body, - String outTradeNo, double totalFee, String notifyUrl, - String createIp, String attach, Date timeStart, Date timeExpire, - String goodsTag, String limitPay) throws WeixinPayException { - return pay3Api.createNativePayRequestURL(productId, body, outTradeNo, - totalFee, notifyUrl, createIp, attach, timeStart, timeExpire, - goodsTag, limitPay); + public MchPayRequest createAppPayRequest(String body, String outTradeNo, + double totalFee, String notifyUrl, String createIp) + throws WeixinPayException { + return pay3Api.createAppPayRequest(body, outTradeNo, totalFee, + notifyUrl, createIp); + } + + /** + * 创建WAP支付请求对象 + * + * @param body + * 商品描述 + * @param outTradeNo + * 商户内部唯一订单号 + * @param totalFee + * 商品总额 单位元 + * @param notifyUrl + * 支付回调URL + * @param createIp + * 订单生成的机器 IP + * @return WAP支付对象 + * @see com.foxinmy.weixin4j.api.Pay3Api + * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest + * @see WAP支付 + * @throws WeixinPayException + */ + public MchPayRequest createWAPPayRequest(String body, String outTradeNo, + double totalFee, String notifyUrl, String createIp) + throws WeixinPayException { + return pay3Api.createWAPPayRequest(body, outTradeNo, totalFee, + notifyUrl, createIp); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java new file mode 100644 index 00000000..4aaba830 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/APPPayRequest.java @@ -0,0 +1,63 @@ +package com.foxinmy.weixin4j.payment.mch; + +import com.foxinmy.weixin4j.model.WeixinPayAccount; +import com.foxinmy.weixin4j.payment.PayRequest; +import com.foxinmy.weixin4j.util.DigestUtil; +import com.foxinmy.weixin4j.util.MapUtil; + +/** + * APP支付 + * + * @className APPPayRequest + * @author jy + * @date 2015年12月25日 + * @since JDK 1.6 + * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @see com.foxinmy.weixin4j.payment.PayRequest + * @see APP支付 + */ +public class APPPayRequest extends AbstractPayRequest { + + public APPPayRequest(PrePay prePay, WeixinPayAccount payAccount) { + super(prePay, payAccount); + } + + /** + * 只做查看之用,请不要尝试作为支付请求 + */ + @Override + public PayRequest toRequestObject() { + PayRequest payRequest = new PayRequest(getPayAccount().getId(), + "Sign=WXPay"); + payRequest.setPrepayId(getPrePay().getPrepayId()); + payRequest.setPartnerId(getPayAccount().getPartnerId()); + return payRequest; + } + + @Override + public String toRequestString() { + PayRequest payRequest = toRequestObject(); + String sign = DigestUtil.MD5( + String.format("%s&key=%s", + MapUtil.toJoinString(payRequest, false, true, null), + getPayAccount().getPaySignKey())).toUpperCase(); + StringBuilder content = new StringBuilder(); + content.append(""); + content.append(String.format("", + payRequest.getAppId())); + content.append(String.format("", + payRequest.getPartnerId())); + content.append(String.format("", + payRequest.getPrepayId())); + content.append(String.format("", + payRequest.getPackageInfo())); + content.append(String.format("", + payRequest.getNonceStr())); + content.append(String.format("", + payRequest.getTimeStamp())); + content.append(String.format("", sign)); + content.append(""); + return content.toString(); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java new file mode 100644 index 00000000..6049b86c --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/AbstractPayRequest.java @@ -0,0 +1,30 @@ +package com.foxinmy.weixin4j.payment.mch; + +import com.alibaba.fastjson.JSON; +import com.foxinmy.weixin4j.model.WeixinPayAccount; + +public abstract class AbstractPayRequest implements MchPayRequest { + + private final PrePay prePay; + private final WeixinPayAccount payAccount; + + public AbstractPayRequest(PrePay prePay, WeixinPayAccount payAccount) { + this.prePay = prePay; + this.payAccount = payAccount; + } + + @Override + public PrePay getPrePay() { + return this.prePay; + } + + @Override + public WeixinPayAccount getPayAccount() { + return this.payAccount; + } + + @Override + public String toRequestString() { + return JSON.toJSONString(toRequestObject()); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java new file mode 100644 index 00000000..e79f2aa2 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/JSAPIPayRequest.java @@ -0,0 +1,40 @@ +package com.foxinmy.weixin4j.payment.mch; + +import com.foxinmy.weixin4j.model.WeixinPayAccount; +import com.foxinmy.weixin4j.payment.PayRequest; +import com.foxinmy.weixin4j.type.SignType; +import com.foxinmy.weixin4j.util.DigestUtil; + +/** + * 公众号JS支付:get_brand_wcpay_request
+ *

+ * get_brand_wcpay_request:ok 支付成功
+ * get_brand_wcpay_request:cancel 支付过程中用户取消
+ * get_brand_wcpay_request:fail 支付失败 + *

+ * + * @className JSAPIPayRequest + * @author jy + * @date 2015年12月25日 + * @since JDK 1.6 + * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @see com.foxinmy.weixin4j.payment.PayRequest + * @see 网页端调起支付API + */ +public class JSAPIPayRequest extends AbstractPayRequest { + + public JSAPIPayRequest(PrePay prePay, WeixinPayAccount payAccount) { + super(prePay, payAccount); + } + + @Override + public PayRequest toRequestObject() { + PayRequest payRequest = new PayRequest(getPayAccount().getId(), + "prepay_id=" + getPrePay().getPrepayId()); + payRequest.setSignType(SignType.MD5); + payRequest.setPaySign(DigestUtil.paysignMd5(payRequest, getPayAccount() + .getPaySignKey())); + return payRequest; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayRequest.java index 4f694351..9d712c10 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/MchPayRequest.java @@ -1,91 +1,46 @@ package com.foxinmy.weixin4j.payment.mch; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.payment.PayRequest; -import com.foxinmy.weixin4j.type.SignType; -import com.foxinmy.weixin4j.util.DigestUtil; /** - * JS支付:get_brand_wcpay_request
- *

- * get_brand_wcpay_request:ok 支付成功
- * get_brand_wcpay_request:cancel 支付过程中用户取消
- * get_brand_wcpay_request:fail 支付失败 - *

- *

- * NATIVE支付:PayRequest.TradeType=NATIVE - *

+ * 支付请求接口 * * @className MchPayRequest * @author jy - * @date 2014年8月17日 - * @since JDK 1.6 - * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @date 2015年12月25日 + * @since JDK 1.7 + * @see JSAPIPayRequest JS支付 + * @see NATIVEPayRequest 扫码支付 + * @see APPPayRequest APP支付 + * @see WAPPayRequest WAP支付 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class MchPayRequest extends PayRequest { - - private static final long serialVersionUID = -5972173459255255197L; - - @XmlTransient - @JSONField(serialize = false) - private PrePay prePay; - - protected MchPayRequest() { - // jaxb required - } - - public MchPayRequest(PrePay prePay) { - super(prePay.getAppId(), "prepay_id=" + prePay.getPrepayId()); - this.prePay = prePay; - } - - public MchPayRequest(String appId, String prepayId) { - super(appId, "prepay_id=" + prepayId); - this.prePay = new PrePay(); - this.prePay.setAppId(appId); - this.prePay.setPrepayId(prepayId); - } - - public PrePay getPrePay() { - return prePay; - } +public interface MchPayRequest { + /** + * 预支付对象 + * + * @return + */ + public PrePay getPrePay(); /** - * 针对未签名的 MchPayRequest + * 商户信息 * - * @param paySignKey - * 支付签名密钥 - * @return JSAPI支付JSON串 + * @return */ - @XmlTransient - @JSONField(serialize = false) - public String asPayJsRequestJson(String paySignKey) { - this.setSignType(SignType.MD5); - this.setPaySign(DigestUtil.paysignMd5(this, paySignKey)); - return asPayJsRequestJson(); - } + public WeixinPayAccount getPayAccount(); /** - * 针对已签名的 MchPayRequest + * 支付请求字符串 * - * @return JSAPI支付JSON串 + * @return */ - @XmlTransient - @JSONField(serialize = false) - public String asPayJsRequestJson() { - return JSON.toJSONString(this); - } + public String toRequestString(); - @Override - public String toString() { - return "MchPayRequest [" + super.toString() + "]"; - } + /** + * 支付请求对象 + * + * @return + */ + public PayRequest toRequestObject(); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NATIVEPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NATIVEPayRequest.java new file mode 100644 index 00000000..1c379847 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/NATIVEPayRequest.java @@ -0,0 +1,37 @@ +package com.foxinmy.weixin4j.payment.mch; + +import com.foxinmy.weixin4j.model.WeixinPayAccount; +import com.foxinmy.weixin4j.payment.PayRequest; + +/** + * NATIVE扫码支付(模式二) + * + * @className NATIVEPayRequest + * @author jy + * @date 2015年12月25日 + * @since JDK 1.6 + * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @see com.foxinmy.weixin4j.payment.PayRequest + * @see NATIVE扫码支付(模式二) + */ +public class NATIVEPayRequest extends AbstractPayRequest { + + public NATIVEPayRequest(PrePay prePay, WeixinPayAccount payAccount) { + super(prePay, payAccount); + } + + /** + * 只做查看之用,请不要尝试作为支付请求 + */ + @Override + public PayRequest toRequestObject() { + return new PayRequest(getPayAccount().getId(), "code_url=" + + getPrePay().getCodeUrl()); + } + + @Override + public String toRequestString() { + return getPrePay().getCodeUrl(); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java new file mode 100644 index 00000000..ec39768f --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/WAPPayRequest.java @@ -0,0 +1,50 @@ +package com.foxinmy.weixin4j.payment.mch; + +import com.foxinmy.weixin4j.model.Consts; +import com.foxinmy.weixin4j.model.WeixinPayAccount; +import com.foxinmy.weixin4j.payment.PayRequest; +import com.foxinmy.weixin4j.payment.PayURLConsts; +import com.foxinmy.weixin4j.util.DigestUtil; +import com.foxinmy.weixin4j.util.MapUtil; +import com.foxinmy.weixin4j.util.URLEncodingUtil; + +/** + * WAP支付 + * + * @className WAPPayRequest + * @author jy + * @date 2015年12月25日 + * @since JDK 1.6 + * @see com.foxinmy.weixin4j.payment.mch.PrePay + * @see com.foxinmy.weixin4j.payment.PayRequest + * @see WAP支付 + */ +public class WAPPayRequest extends AbstractPayRequest { + + public WAPPayRequest(PrePay prePay, WeixinPayAccount payAccount) { + super(prePay, payAccount); + } + + /** + * 只做查看之用,请不要尝试作为支付请求 + */ + @Override + public PayRequest toRequestObject() { + PayRequest payRequest = new PayRequest(getPayAccount().getId(), "WAP"); + payRequest.setPrepayId(getPrePay().getPrepayId()); + return payRequest; + } + + @Override + public String toRequestString() { + PayRequest payRequest = toRequestObject(); + String original = MapUtil.toJoinString(payRequest, true, true, null); + String sign = DigestUtil.MD5( + String.format("%s&key=%s", original, getPayAccount() + .getPaySignKey())).toUpperCase(); + return String.format(PayURLConsts.MCH_WAP_URL, URLEncodingUtil + .encoding(String.format("%s&sign=%s", original, sign), + Consts.UTF_8, true)); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/TradeType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/TradeType.java index 309285fb..3c1cecfe 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/TradeType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/TradeType.java @@ -25,5 +25,9 @@ public enum TradeType { /** * APP支付 */ - APP; + APP, + /** + * WAP支付 + */ + WAP; }