押金支付接口实现
This commit is contained in:
@@ -167,31 +167,6 @@ public class WeixinPayProxy {
|
||||
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支付(扫码支付)链接【模式一】
|
||||
*
|
||||
@@ -394,7 +369,7 @@ public class WeixinPayProxy {
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号,32个字符内、可包含字母;更换授权码必须要换新的商户订单号
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为分,只能为整数
|
||||
* 订单总金额,单位元
|
||||
* @param createIp
|
||||
* 调用微信支付API的机器IP
|
||||
* @param openId
|
||||
@@ -417,6 +392,37 @@ public class WeixinPayProxy {
|
||||
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>
|
||||
|
||||
@@ -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.mch.*;
|
||||
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.*;
|
||||
import com.foxinmy.weixin4j.util.*;
|
||||
@@ -87,17 +88,28 @@ public class PayApi extends MchApi {
|
||||
null, payPackage.getCreateIp(), null, payPackage.getOpenId(),
|
||||
payPackage.getAuthCode(), null, payPackage.getAttach(),
|
||||
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);
|
||||
_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 url = TradeType.MICROPAY.name().equals(tradeType) ? getRequestUri("micropay_uri") :
|
||||
getRequestUri("facepay_url");
|
||||
|
||||
WeixinResponse response = weixinExecutor.post(url, para);
|
||||
MICROPayRequest microPayRequest = response
|
||||
.getAsObject(new TypeReference<MICROPayRequest>() {
|
||||
});
|
||||
MICROPayRequest microPayRequest = response.getAsObject(new TypeReference<MICROPayRequest>() {});
|
||||
microPayRequest.setPaymentAccount(weixinAccount);
|
||||
return microPayRequest;
|
||||
}
|
||||
@@ -147,42 +159,6 @@ public class PayApi extends MchApi {
|
||||
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支付(扫码支付)链接【模式一】
|
||||
*
|
||||
@@ -814,4 +790,26 @@ public class PayApi extends MchApi {
|
||||
payPackage.setFaceCode(faceCode);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import java.util.Map;
|
||||
*
|
||||
* @className PayfaceAuthinfoRequest
|
||||
* @author kit(kit_21cn@21cn.com)
|
||||
* @date 2015年12月25日
|
||||
* @date 2019年9月18日
|
||||
* @since JDK 1.6
|
||||
* @see <a href="https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#获取调用凭证-get-wxpayface-authinfo">
|
||||
* 获取调用凭证-get-wxpayface-authinfo</a>
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.payment.PayPackage;
|
||||
import com.foxinmy.weixin4j.pay.type.CurrencyType;
|
||||
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.XmlAccessorType;
|
||||
@@ -76,10 +77,18 @@ public class MchPayPackage extends PayPackage {
|
||||
@XmlElement(name = "scene_info")
|
||||
@JSONField(name = "scene_info")
|
||||
private String sceneInfo;
|
||||
|
||||
/**
|
||||
* 人脸凭证,用于旧版人脸支付。
|
||||
*/
|
||||
@XmlElement(name = "face_code")
|
||||
@JSONField(name = "face_code")
|
||||
private String faceCode;
|
||||
/**
|
||||
* 是否押金人脸支付,Y-是,N-普通人脸支付
|
||||
*/
|
||||
@XmlElement(name = "deposit")
|
||||
@JSONField(name = "deposit")
|
||||
private DepositType deposit;
|
||||
|
||||
protected MchPayPackage() {
|
||||
// jaxb required
|
||||
@@ -114,7 +123,7 @@ public class MchPayPackage extends PayPackage {
|
||||
String openId, String authCode, String productId, String attach) {
|
||||
this(body, null, outTradeNo, totalFee, CurrencyType.CNY, notifyUrl,
|
||||
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
|
||||
* @param faceCode
|
||||
* 人脸凭证,用于旧版刷脸支付。
|
||||
* @param depositType
|
||||
* 是否押金支付
|
||||
*/
|
||||
public MchPayPackage(String body, String detial, String outTradeNo,
|
||||
double totalFee, CurrencyType feeType, String notifyUrl,
|
||||
String createIp, TradeType tradeType, String openId,
|
||||
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,
|
||||
timeStart, timeExpire, goodsTag);
|
||||
this.tradeType = tradeType != null ? tradeType.name() : null;
|
||||
@@ -174,6 +186,7 @@ public class MchPayPackage extends PayPackage {
|
||||
this.limitPay = limitPay;
|
||||
this.subOpenId = subOpenId;
|
||||
this.faceCode = faceCode;
|
||||
this.deposit = depositType;
|
||||
}
|
||||
|
||||
public String getTradeType() {
|
||||
@@ -228,12 +241,27 @@ public class MchPayPackage extends PayPackage {
|
||||
this.faceCode = faceCode;
|
||||
}
|
||||
|
||||
public DepositType getDeposit() {
|
||||
return deposit;
|
||||
}
|
||||
|
||||
public void setDeposit(DepositType deposit) {
|
||||
this.deposit = deposit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MchPayPackage [tradeType=" + tradeType + ",feeType=" + feeType
|
||||
+ ", openId=" + openId + ", productId=" + productId
|
||||
+ ", authCode=" + authCode + ", limitPay=" + limitPay
|
||||
+ ", subOpenId=" + subOpenId + ", sceneInfo=" + sceneInfo
|
||||
+ ", " + super.toString() + "]";
|
||||
return "MchPayPackage{" +
|
||||
"tradeType='" + tradeType + '\'' +
|
||||
", feeType='" + feeType + '\'' +
|
||||
", openId='" + openId + '\'' +
|
||||
", productId='" + productId + '\'' +
|
||||
", authCode='" + authCode + '\'' +
|
||||
", limitPay='" + limitPay + '\'' +
|
||||
", subOpenId='" + subOpenId + '\'' +
|
||||
", sceneInfo='" + sceneInfo + '\'' +
|
||||
", faceCode='" + faceCode + '\'' +
|
||||
", deposit=" + deposit +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.foxinmy.weixin4j.pay.payment.mch;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
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.XmlAccessorType;
|
||||
@@ -135,12 +135,6 @@ public class MerchantResult extends XmlResult {
|
||||
return signType;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public SignType getFormatSignType() {
|
||||
return signType != null ? SignType.valueOf(signType.toUpperCase())
|
||||
: null;
|
||||
}
|
||||
|
||||
public void setSignType(String signType) {
|
||||
this.signType = signType;
|
||||
}
|
||||
|
||||
+21
-5
@@ -1,8 +1,11 @@
|
||||
package com.foxinmy.weixin4j.pay.sign;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.pay.type.SignType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
/**
|
||||
* 微信支付签名实现
|
||||
*
|
||||
@@ -23,14 +26,27 @@ public class WeixinPaymentSignature extends AbstractWeixinSignature {
|
||||
this.paySignKey = paySignKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignType getSignType() {
|
||||
return SignType.MD5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sign(Object obj) {
|
||||
StringBuilder sb = join(obj).append("&key=").append(paySignKey);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,27 +17,29 @@ public interface WeixinSignature {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean encoder();
|
||||
boolean encoder();
|
||||
|
||||
/**
|
||||
* 是否转换小写
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean lowerCase();
|
||||
boolean lowerCase();
|
||||
|
||||
/**
|
||||
* 签名类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SignType getSignType();
|
||||
|
||||
/**
|
||||
* 签名
|
||||
* 签名(默认的MD5签名)
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public String sign(Object obj);
|
||||
String sign(Object obj);
|
||||
|
||||
/**
|
||||
* 签名(指定签名算法)
|
||||
*
|
||||
* @param obj
|
||||
* @param signType
|
||||
* @return
|
||||
*/
|
||||
String sign(Object obj, SignType signType);
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ package com.foxinmy.weixin4j.pay.type;
|
||||
* @see
|
||||
*/
|
||||
public enum SignType {
|
||||
SHA1, MD5, HMAC$SHA256
|
||||
MD5, HMAC$SHA256
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -57,4 +57,8 @@ customsorder_query_uri={mch_base_url}/mch/customs/customdeclarequery
|
||||
# \u5237\u8138\u652F\u4ED8\u4EA4\u4E92\u6D41\u7A0B--\u83B7\u53D6\u8C03\u7528\u51ED\u8BC1
|
||||
get_wxpayface_authinfo_uri={payapp_base_url}/face/get_wxpayface_authinfo
|
||||
# \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
|
||||
Reference in New Issue
Block a user