押金支付接口实现

This commit is contained in:
Kit 2019-09-22 11:43:40 +08:00
parent 38b56fd552
commit 2524f34c33
12 changed files with 224 additions and 131 deletions

View File

@ -1,5 +1,8 @@
package com.foxinmy.weixin4j.util; package com.foxinmy.weixin4j.util;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -57,4 +60,26 @@ public final class DigestUtil {
byte[] data = StringUtil.getBytesUtf8(content); byte[] data = StringUtil.getBytesUtf8(content);
return HexUtil.encodeHexString(getDigest(Consts.MD5).digest(data)); return HexUtil.encodeHexString(getDigest(Consts.MD5).digest(data));
} }
/**
* HMAC-SHA256签名
*
* @param content
* 待签名字符串
* @param key
* 支付密钥
* @return
* @throws InvalidKeyException
*/
public static String HMACSHA256(String content, String key) throws InvalidKeyException{
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
mac.init(secret_key);
byte[] bytes = mac.doFinal(content.getBytes());
return HexUtil.encodeHexString(bytes);
} catch (NoSuchAlgorithmException e) {
}
return null;
}
} }

View File

@ -1,59 +1,59 @@
# \u5fae\u4fe1\u5546\u6237\u5e73\u53f0\u6587\u6863\u8bf4\u660e # \u5FAE\u4FE1\u5546\u6237\u5E73\u53F0\u6587\u6863\u8BF4\u660E
# https://pay.weixin.qq.com/ # https://pay.weixin.qq.com/
# https://pay.weixin.qq.com/wiki/doc/api/index.php # https://pay.weixin.qq.com/wiki/doc/api/index.php
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
mch_base_url=https://api.mch.weixin.qq.com mch_base_url=https://api.mch.weixin.qq.com
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305 # \u53D1\u9001\u73B0\u91D1\u7EA2\u5305
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
# \u53d1\u9001\u73b0\u91d1\u88c2\u53d8\u7ea2\u5305 # \u53D1\u9001\u73B0\u91D1\u88C2\u53D8\u7EA2\u5305
groupredpack_send_uri={mch_base_url}/mmpaymkttransfers/sendgroupredpack groupredpack_send_uri={mch_base_url}/mmpaymkttransfers/sendgroupredpack
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305 # \u67E5\u8BE2\u73B0\u91D1\u7EA2\u5305
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
# \u7edf\u4e00\u8ba2\u5355\u751f\u6210 # \u7EDF\u4E00\u8BA2\u5355\u751F\u6210
order_create_uri={mch_base_url}/pay/unifiedorder order_create_uri={mch_base_url}/pay/unifiedorder
# \u88ab\u626b\u652f\u4ed8 # \u88AB\u626B\u652F\u4ED8
micropay_uri={mch_base_url}/pay/micropay micropay_uri={mch_base_url}/pay/micropay
# \u8ba2\u5355\u67e5\u8be2 # \u8BA2\u5355\u67E5\u8BE2
order_query_uri={mch_base_url}/pay/orderquery order_query_uri={mch_base_url}/pay/orderquery
# \u5173\u95ed\u8ba2\u5355 # \u5173\u95ED\u8BA2\u5355
order_close_uri={mch_base_url}/pay/closeorder order_close_uri={mch_base_url}/pay/closeorder
# \u5bf9\u8d26\u5355\u4e0b\u8f7d # \u5BF9\u8D26\u5355\u4E0B\u8F7D
downloadbill_uri={mch_base_url}/pay/downloadbill downloadbill_uri={mch_base_url}/pay/downloadbill
# \u9000\u6b3e\u67e5\u8be2 # \u9000\u6B3E\u67E5\u8BE2
refund_query_uri={mch_base_url}/pay/refundquery refund_query_uri={mch_base_url}/pay/refundquery
# \u9000\u6b3e\u7533\u8bf7 # \u9000\u6B3E\u7533\u8BF7
refund_apply_uri={mch_base_url}/secapi/pay/refund refund_apply_uri={mch_base_url}/secapi/pay/refund
# \u51b2\u6b63\u64a4\u9500 # \u51B2\u6B63\u64A4\u9500
order_reverse_uri={mch_base_url}/secapi/pay/reverse order_reverse_uri={mch_base_url}/secapi/pay/reverse
# \u957f\u94fe\u63a5\u8f6c\u6362 # \u957F\u94FE\u63A5\u8F6C\u6362
longurl_convert_uri={mch_base_url}/tools/shorturl longurl_convert_uri={mch_base_url}/tools/shorturl
# \u53d1\u653e\u4ee3\u91d1\u5238 # \u53D1\u653E\u4EE3\u91D1\u5238
coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon
# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f # \u67E5\u8BE2\u4EE3\u91D1\u5238\u6279\u6B21\u4FE1\u606F
couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock
# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f # \u67E5\u8BE2\u4EE3\u91D1\u5238\u8BE6\u7EC6\u4FE1\u606F
coupondetail_query_uri={mch_base_url}/mmpaymkttransfers/querycouponsinfo coupondetail_query_uri={mch_base_url}/mmpaymkttransfers/querycouponsinfo
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305 # \u53D1\u9001\u73B0\u91D1\u7EA2\u5305
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305 # \u67E5\u8BE2\u73B0\u91D1\u7EA2\u5305
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e # \u4F01\u4E1A\u5411\u4E2A\u4EBA\u4ED8\u6B3E
corppayment_send_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers corppayment_send_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers
# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2 # \u4F01\u4E1A\u4ED8\u6B3E\u67E5\u8BE2
corppayment_query_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo corppayment_query_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo
# \u63a5\u53e3\u4e0a\u62a5 # \u63A5\u53E3\u4E0A\u62A5
interface_report_uri={mch_base_url}/payitil/report interface_report_uri={mch_base_url}/payitil/report
# \u6388\u6743\u7801\u67e5\u8be2OPENID\u63a5\u53e3 # \u6388\u6743\u7801\u67E5\u8BE2OPENID\u63A5\u53E3
authcode_openid_uri={mch_base_url}/tools/authcodetoopenid authcode_openid_uri={mch_base_url}/tools/authcodetoopenid
# native\u652f\u4ed8url(\u6a21\u5f0f1) # native\u652F\u4ED8url(\u6A21\u5F0F1)
native_pay_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s native_pay_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s
# \u67e5\u8be2\u7ed3\u7b97\u8d44\u91d1 # \u67E5\u8BE2\u7ED3\u7B97\u8D44\u91D1
settlement_query_uri={mch_base_url}/pay/settlementquery settlement_query_uri={mch_base_url}/pay/settlementquery
# \u67e5\u8be2\u6c47\u7387 # \u67E5\u8BE2\u6C47\u7387
exchagerate_query_uri={mch_base_url}/pay/queryexchagerate exchagerate_query_uri={mch_base_url}/pay/queryexchagerate
# \u8ba2\u5355\u9644\u52a0\u4fe1\u606f\u63d0\u4ea4 # \u8BA2\u5355\u9644\u52A0\u4FE1\u606F\u63D0\u4EA4
customsorder_declare_uri={mch_base_url}/mch/customs/customdeclareorder customsorder_declare_uri={mch_base_url}/mch/customs/customdeclareorder
# \u8ba2\u5355\u9644\u52a0\u4fe1\u606f\u67e5\u8be2 # \u8BA2\u5355\u9644\u52A0\u4FE1\u606F\u67E5\u8BE2
customsorder_query_uri={mch_base_url}/mch/customs/customdeclarequery customsorder_query_uri={mch_base_url}/mch/customs/customdeclarequery

View File

@ -167,31 +167,6 @@ public class WeixinPayProxy {
notifyUrl, createIp, attach); notifyUrl, createIp, attach);
} }
/**
* <p>
* 生成编辑地址请求
* </p>
*
* err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br>
* userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br>
* proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName
* 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br>
*
* @param url
* 当前访问页的URL
* @param oauthToken
* oauth授权时产生的token
* @see PayApi
* @see <a href=
* "https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_8&index=7">
* 收货地址共享</a>
* @return 编辑地址请求JSON串
*/
public String createAddressRequestJSON(String url, String oauthToken) {
return payApi.createAddressRequestJSON(url, oauthToken);
}
/** /**
* 创建Native支付(扫码支付)链接模式一 * 创建Native支付(扫码支付)链接模式一
* *
@ -394,7 +369,7 @@ public class WeixinPayProxy {
* @param outTradeNo * @param outTradeNo
* 商户系统内部的订单号,32个字符内可包含字母更换授权码必须要换新的商户订单号 * 商户系统内部的订单号,32个字符内可包含字母更换授权码必须要换新的商户订单号
* @param totalFee * @param totalFee
* 订单总金额单位为分只能为整数 * 订单总金额单位
* @param createIp * @param createIp
* 调用微信支付API的机器IP * 调用微信支付API的机器IP
* @param openId * @param openId
@ -417,6 +392,37 @@ public class WeixinPayProxy {
totalFee, createIp, openId, attach); totalFee, createIp, openId, attach);
} }
/**
* 押金支付请求
*
* @param code
* 授权码/人脸凭证
* @param body
* 商品或支付单简要描述格式要求门店品牌名-城市分店名-实际商品名称
* @param outTradeNo
* 商户系统内部的订单号,32个字符内可包含字母更换授权码必须要换新的商户订单号
* @param totalFee
* 订单总金额单位元
* @param createIp
* 调用微信支付API的机器IP
* @param openId
* 用户在商户appid 下的唯一标识人脸支付押金时提供
* @param attach
* 附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据非必填
* @param store
* 门店信息仅在付款码支付押金时提供非必填
* @param isFacePay
* 是否人脸押金支付否则是付款码押金支付
* @return
* @throws WeixinException
*/
public MchPayRequest createDepositPayRequest(String code, String body,
String outTradeNo, double totalFee, String createIp, String openId,
String attach, SceneInfoStore store, boolean isFacePay) throws WeixinException{
return payApi.createDepositPayRequest(code, body, outTradeNo, totalFee, createIp, openId, attach, store, isFacePay);
}
/** /**
* 订单查询 * 订单查询
* <p> * <p>

View File

@ -10,6 +10,7 @@ import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfo;
import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfoRequest; import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfoRequest;
import com.foxinmy.weixin4j.pay.payment.mch.*; import com.foxinmy.weixin4j.pay.payment.mch.*;
import com.foxinmy.weixin4j.pay.type.mch.BillType; import com.foxinmy.weixin4j.pay.type.mch.BillType;
import com.foxinmy.weixin4j.pay.type.mch.DepositType;
import com.foxinmy.weixin4j.pay.type.mch.RefundAccountType; import com.foxinmy.weixin4j.pay.type.mch.RefundAccountType;
import com.foxinmy.weixin4j.pay.type.*; import com.foxinmy.weixin4j.pay.type.*;
import com.foxinmy.weixin4j.util.*; import com.foxinmy.weixin4j.util.*;
@ -87,17 +88,28 @@ public class PayApi extends MchApi {
null, payPackage.getCreateIp(), null, payPackage.getOpenId(), null, payPackage.getCreateIp(), null, payPackage.getOpenId(),
payPackage.getAuthCode(), null, payPackage.getAttach(), payPackage.getAuthCode(), null, payPackage.getAttach(),
null, null, payPackage.getGoodsTag(), null, null, payPackage.getGoodsTag(),
payPackage.getLimitPay(), payPackage.getSubAppId(), payPackage.getFaceCode()); payPackage.getLimitPay(), payPackage.getSubAppId(), payPackage.getFaceCode(),
payPackage.getDeposit());
// 默认为MD5签名
SignType signType= SignType.MD5;
super.declareMerchant(_payPackage); super.declareMerchant(_payPackage);
_payPackage.setSign(weixinSignature.sign(_payPackage)); // 默认为刷卡支付付款码支付的API地址
String url = getRequestUri("micropay_uri");
if(payPackage.getDeposit()==DepositType.Y){
// 押金支付只支持HMAC-SHA256签名
signType = SignType.HMAC$SHA256;
_payPackage.setSignType("HMAC-SHA256");
// 如果是押金支付改为押金支付的API地址
url = TradeType.MICROPAY.name().equals(tradeType) ? getRequestUri("deposit_micropay_uri") :
getRequestUri("deposit_facepay_uri");
}else if(TradeType.FACEPAY.name().equals(tradeType)){
url = getRequestUri("facepay_url");
}
_payPackage.setSign(weixinSignature.sign(_payPackage, signType));
String para = XmlStream.toXML(_payPackage); String para = XmlStream.toXML(_payPackage);
String url = TradeType.MICROPAY.name().equals(tradeType) ? getRequestUri("micropay_uri") :
getRequestUri("facepay_url");
WeixinResponse response = weixinExecutor.post(url, para); WeixinResponse response = weixinExecutor.post(url, para);
MICROPayRequest microPayRequest = response MICROPayRequest microPayRequest = response.getAsObject(new TypeReference<MICROPayRequest>() {});
.getAsObject(new TypeReference<MICROPayRequest>() {
});
microPayRequest.setPaymentAccount(weixinAccount); microPayRequest.setPaymentAccount(weixinAccount);
return microPayRequest; return microPayRequest;
} }
@ -147,42 +159,6 @@ public class PayApi extends MchApi {
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
/**
* <p>
* 生成编辑地址请求
* </p>
*
* err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br>
* userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br>
* proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName
* 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br>
* addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br>
*
* @param url
* 当前访问页的URL
* @param oauthToken
* oauth授权时产生的token
* @see <a href=
* "https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_8&index=7">
* 收货地址共享</a>
* @return 编辑地址请求JSON串
*/
public String createAddressRequestJSON(String url, String oauthToken) {
Map<String, String> map = new HashMap<String, String>();
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支付(扫码支付)链接模式一 * 创建Native支付(扫码支付)链接模式一
* *
@ -814,4 +790,26 @@ public class PayApi extends MchApi {
payPackage.setFaceCode(faceCode); payPackage.setFaceCode(faceCode);
return createPayRequest(payPackage); return createPayRequest(payPackage);
} }
public MchPayRequest createDepositPayRequest(String code, String body, String outTradeNo, double totalFee,
String createIp, String openId, String attach, SceneInfoStore store,
boolean isFacePay) throws WeixinException {
MchPayPackage payPackage;
if(isFacePay) {
payPackage = new MchPayPackage(body, outTradeNo, totalFee, null, createIp, TradeType.FACEPAY,
openId, null, null, attach);
payPackage.setFaceCode(code);
payPackage.setDeposit(DepositType.Y);
return createPayRequest(payPackage);
}else{
payPackage = new MchPayPackage(body, outTradeNo, totalFee, null, createIp, TradeType.MICROPAY,
openId, code, null, attach);
payPackage.setDeposit(DepositType.Y);
if (store != null) {
payPackage.setSceneInfo(String.format("{\"store_info\":\"%s\"}",
JSON.toJSONString(store)));
}
return createPayRequest(payPackage);
}
}
} }

View File

@ -14,7 +14,7 @@ import java.util.Map;
* *
* @className PayfaceAuthinfoRequest * @className PayfaceAuthinfoRequest
* @author kit(kit_21cn@21cn.com) * @author kit(kit_21cn@21cn.com)
* @date 2015年12月25 * @date 2019年9月18
* @since JDK 1.6 * @since JDK 1.6
* @see <a href="https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#获取调用凭证-get-wxpayface-authinfo"> * @see <a href="https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#获取调用凭证-get-wxpayface-authinfo">
* 获取调用凭证-get-wxpayface-authinfo</a> * 获取调用凭证-get-wxpayface-authinfo</a>

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.pay.payment.PayPackage; import com.foxinmy.weixin4j.pay.payment.PayPackage;
import com.foxinmy.weixin4j.pay.type.CurrencyType; import com.foxinmy.weixin4j.pay.type.CurrencyType;
import com.foxinmy.weixin4j.pay.type.TradeType; import com.foxinmy.weixin4j.pay.type.TradeType;
import com.foxinmy.weixin4j.pay.type.mch.DepositType;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
@ -76,10 +77,18 @@ public class MchPayPackage extends PayPackage {
@XmlElement(name = "scene_info") @XmlElement(name = "scene_info")
@JSONField(name = "scene_info") @JSONField(name = "scene_info")
private String sceneInfo; private String sceneInfo;
/**
* 人脸凭证用于旧版人脸支付
*/
@XmlElement(name = "face_code") @XmlElement(name = "face_code")
@JSONField(name = "face_code") @JSONField(name = "face_code")
private String faceCode; private String faceCode;
/**
* 是否押金人脸支付Y-,N-普通人脸支付
*/
@XmlElement(name = "deposit")
@JSONField(name = "deposit")
private DepositType deposit;
protected MchPayPackage() { protected MchPayPackage() {
// jaxb required // jaxb required
@ -114,7 +123,7 @@ public class MchPayPackage extends PayPackage {
String openId, String authCode, String productId, String attach) { String openId, String authCode, String productId, String attach) {
this(body, null, outTradeNo, totalFee, CurrencyType.CNY, notifyUrl, this(body, null, outTradeNo, totalFee, CurrencyType.CNY, notifyUrl,
createIp, tradeType, openId, authCode, productId, attach, null, createIp, tradeType, openId, authCode, productId, attach, null,
null, null, null, null, null); null, null, null, null, null, null);
} }
/** /**
@ -157,12 +166,15 @@ public class MchPayPackage extends PayPackage {
* openid和sub_openid可以选传其中之一如果选择传sub_openid ,则必须传sub_appid * openid和sub_openid可以选传其中之一如果选择传sub_openid ,则必须传sub_appid
* @param faceCode * @param faceCode
* 人脸凭证用于旧版刷脸支付 * 人脸凭证用于旧版刷脸支付
* @param depositType
* 是否押金支付
*/ */
public MchPayPackage(String body, String detial, String outTradeNo, public MchPayPackage(String body, String detial, String outTradeNo,
double totalFee, CurrencyType feeType, String notifyUrl, double totalFee, CurrencyType feeType, String notifyUrl,
String createIp, TradeType tradeType, String openId, String createIp, TradeType tradeType, String openId,
String authCode, String productId, String attach, Date timeStart, String authCode, String productId, String attach, Date timeStart,
Date timeExpire, String goodsTag, String limitPay, String subOpenId, String faceCode) { Date timeExpire, String goodsTag, String limitPay, String subOpenId, String faceCode,
DepositType depositType) {
super(body, detial, outTradeNo, totalFee, notifyUrl, createIp, attach, super(body, detial, outTradeNo, totalFee, notifyUrl, createIp, attach,
timeStart, timeExpire, goodsTag); timeStart, timeExpire, goodsTag);
this.tradeType = tradeType != null ? tradeType.name() : null; this.tradeType = tradeType != null ? tradeType.name() : null;
@ -174,6 +186,7 @@ public class MchPayPackage extends PayPackage {
this.limitPay = limitPay; this.limitPay = limitPay;
this.subOpenId = subOpenId; this.subOpenId = subOpenId;
this.faceCode = faceCode; this.faceCode = faceCode;
this.deposit = depositType;
} }
public String getTradeType() { public String getTradeType() {
@ -228,12 +241,27 @@ public class MchPayPackage extends PayPackage {
this.faceCode = faceCode; this.faceCode = faceCode;
} }
public DepositType getDeposit() {
return deposit;
}
public void setDeposit(DepositType deposit) {
this.deposit = deposit;
}
@Override @Override
public String toString() { public String toString() {
return "MchPayPackage [tradeType=" + tradeType + ",feeType=" + feeType return "MchPayPackage{" +
+ ", openId=" + openId + ", productId=" + productId "tradeType='" + tradeType + '\'' +
+ ", authCode=" + authCode + ", limitPay=" + limitPay ", feeType='" + feeType + '\'' +
+ ", subOpenId=" + subOpenId + ", sceneInfo=" + sceneInfo ", openId='" + openId + '\'' +
+ ", " + super.toString() + "]"; ", productId='" + productId + '\'' +
", authCode='" + authCode + '\'' +
", limitPay='" + limitPay + '\'' +
", subOpenId='" + subOpenId + '\'' +
", sceneInfo='" + sceneInfo + '\'' +
", faceCode='" + faceCode + '\'' +
", deposit=" + deposit +
'}';
} }
} }

View File

@ -2,7 +2,7 @@ package com.foxinmy.weixin4j.pay.payment.mch;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.http.weixin.XmlResult; import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.type.SignType; import com.foxinmy.weixin4j.pay.type.SignType;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
@ -135,12 +135,6 @@ public class MerchantResult extends XmlResult {
return signType; return signType;
} }
@JSONField(serialize = false)
public SignType getFormatSignType() {
return signType != null ? SignType.valueOf(signType.toUpperCase())
: null;
}
public void setSignType(String signType) { public void setSignType(String signType) {
this.signType = signType; this.signType = signType;
} }

View File

@ -1,8 +1,11 @@
package com.foxinmy.weixin4j.pay.sign; package com.foxinmy.weixin4j.pay.sign;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.pay.type.SignType; import com.foxinmy.weixin4j.pay.type.SignType;
import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.DigestUtil;
import java.security.InvalidKeyException;
/** /**
* 微信支付签名实现 * 微信支付签名实现
* *
@ -23,14 +26,27 @@ public class WeixinPaymentSignature extends AbstractWeixinSignature {
this.paySignKey = paySignKey; this.paySignKey = paySignKey;
} }
@Override
public SignType getSignType() {
return SignType.MD5;
}
@Override @Override
public String sign(Object obj) { public String sign(Object obj) {
StringBuilder sb = join(obj).append("&key=").append(paySignKey); StringBuilder sb = join(obj).append("&key=").append(paySignKey);
return DigestUtil.MD5(sb.toString()).toUpperCase(); return DigestUtil.MD5(sb.toString()).toUpperCase();
} }
@Override
public String sign(Object obj, SignType signType) {
if(signType==null){
return sign(obj);
}
switch (signType){
case HMAC$SHA256:
StringBuilder sb = join(obj).append("&key=").append(paySignKey);
try {
return DigestUtil.HMACSHA256(sb.toString(), paySignKey).toUpperCase();
}catch (InvalidKeyException e){
throw new RuntimeException("商户支付密钥有误", e);
}
default:
return sign(obj);
}
}
} }

View File

@ -17,27 +17,29 @@ public interface WeixinSignature {
* *
* @return * @return
*/ */
public boolean encoder(); boolean encoder();
/** /**
* 是否转换小写 * 是否转换小写
* *
* @return * @return
*/ */
public boolean lowerCase(); boolean lowerCase();
/** /**
* 签名类型 * 签名默认的MD5签名
*
* @return
*/
public SignType getSignType();
/**
* 签名
* *
* @param obj * @param obj
* @return * @return
*/ */
public String sign(Object obj); String sign(Object obj);
/**
* 签名指定签名算法
*
* @param obj
* @param signType
* @return
*/
String sign(Object obj, SignType signType);
} }

View File

@ -10,5 +10,5 @@ package com.foxinmy.weixin4j.pay.type;
* @see * @see
*/ */
public enum SignType { public enum SignType {
SHA1, MD5, HMAC$SHA256 MD5, HMAC$SHA256
} }

View File

@ -0,0 +1,20 @@
package com.foxinmy.weixin4j.pay.type.mch;
/**
* 是否押金支付
*
* @className DepositType
* @author kit(kit_21cn@21cn.com)
* @date 2019年9月21日
* @since JDK 1.6
*/
public enum DepositType {
/**
*
*/
Y,
/**
*
*/
N;
}

View File

@ -58,3 +58,7 @@ customsorder_query_uri={mch_base_url}/mch/customs/customdeclarequery
get_wxpayface_authinfo_uri={payapp_base_url}/face/get_wxpayface_authinfo get_wxpayface_authinfo_uri={payapp_base_url}/face/get_wxpayface_authinfo
# \u65E7\u7248\u5237\u8138\u652F\u4ED8\u63A5\u53E3 # \u65E7\u7248\u5237\u8138\u652F\u4ED8\u63A5\u53E3
facepay_url={mch_base_url}/pay/facepay facepay_url={mch_base_url}/pay/facepay
# \u652F\u4ED8\u62BC\u91D1\uFF08\u4EBA\u8138\uFF09
deposit_facepay_uri={mch_base_url}/deposit/facepay
# \u652F\u4ED8\u62BC\u91D1\uFF08\u4ED8\u6B3E\u7801\uFF09
deposit_micropay_uri={mch_base_url}/deposit/micropay