From 38b56fd552fff34db3b25293fadbae12ccd34fe8 Mon Sep 17 00:00:00 2001 From: Kit Date: Fri, 20 Sep 2019 15:00:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A7=E7=89=88=E4=BA=BA=E8=84=B8=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E6=8E=A5=E5=8F=A3=EF=BC=9B=E8=8E=B7=E5=8F=96=E5=87=AD?= =?UTF-8?q?=E8=AF=81=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foxinmy/weixin4j/pay/WeixinPayProxy.java | 33 ++++++++++++++ .../com/foxinmy/weixin4j/pay/api/PayApi.java | 43 +++++++++++++++---- .../payment/face/PayfaceAuthinfoRequest.java | 15 ++++--- .../pay/payment/mch/MchPayPackage.java | 19 +++++++- .../pay/payment/mch/MerchantTradeResult.java | 2 +- .../weixin4j/pay/payment/mch/Order.java | 2 +- .../foxinmy/weixin4j/pay/type/TradeType.java | 6 ++- .../weixin4j/payment/weixin.properties | 4 +- .../weixin4j/pay/test/TestFacePay.java | 31 +++++++++++++ .../pay/test/TestGetPayFaceAuthInfo.java | 24 +++++++++++ 10 files changed, 159 insertions(+), 20 deletions(-) create mode 100644 weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestFacePay.java create mode 100644 weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestGetPayFaceAuthInfo.java diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/WeixinPayProxy.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/WeixinPayProxy.java index 7c0f80a8..b7bb54e7 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/WeixinPayProxy.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/WeixinPayProxy.java @@ -384,6 +384,39 @@ public class WeixinPayProxy { totalFee, createIp, attach, store); } + /** + * 旧版刷脸支付接口 + * + * @param faceCode + * 人脸凭证 + * @param body + * 商品或支付单简要描述,格式要求:门店品牌名-城市分店名-实际商品名称 + * @param outTradeNo + * 商户系统内部的订单号,32个字符内、可包含字母;更换授权码必须要换新的商户订单号 + * @param totalFee + * 订单总金额,单位为分,只能为整数 + * @param createIp + * 调用微信支付API的机器IP + * @param openId + * 用户在商户appid 下的唯一标识 + * @param attach + * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 + * @return + * @throws WeixinException + * @see + * 刷脸支付后端接口 + * @see + */ + public MchPayRequest createFacePayRequest(String faceCode, String body, + String outTradeNo, double totalFee, String createIp, String openId, + String attach) throws WeixinException { + return payApi.createFacePayRequest(faceCode, body, outTradeNo, + totalFee, createIp, openId, attach); + } + /** * 订单查询 *

diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/api/PayApi.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/api/PayApi.java index c326b3d0..1db3a582 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/api/PayApi.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/api/PayApi.java @@ -80,19 +80,21 @@ public class PayApi extends MchApi { throw new WeixinException("tradeType not be empty"); } String tradeType = payPackage.getTradeType().toUpperCase(); - if (TradeType.MICROPAY.name().equals(tradeType)) { + if (TradeType.MICROPAY.name().equals(tradeType) || TradeType.FACEPAY.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()); + payPackage.getDetail(), payPackage.getOutTradeNo(), + DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null, + null, payPackage.getCreateIp(), null, payPackage.getOpenId(), + payPackage.getAuthCode(), null, payPackage.getAttach(), + null, null, payPackage.getGoodsTag(), + payPackage.getLimitPay(), payPackage.getSubAppId(), payPackage.getFaceCode()); + super.declareMerchant(_payPackage); _payPackage.setSign(weixinSignature.sign(_payPackage)); String para = XmlStream.toXML(_payPackage); - WeixinResponse response = weixinExecutor.post( - getRequestUri("micropay_uri"), para); + 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() { }); @@ -789,4 +791,27 @@ public class PayApi extends MchApi { getRequestUri("get_wxpayface_authinfo_uri"), request.toRequestString()); return response.getAsObject(new TypeReference() {}); } + + /** + * 微信旧版刷脸支付 + * + * @param faceCode + * @param body + * @param outTradeNo + * @param totalFee + * @param createIp + * @param openId + * @param attach + * @return + * @throws WeixinException + */ + public MchPayRequest createFacePayRequest(String faceCode, String body, + String outTradeNo, double totalFee, String createIp, String openId, + String attach) throws WeixinException { + MchPayPackage payPackage = new MchPayPackage(body, outTradeNo, + totalFee, null, createIp, TradeType.FACEPAY, openId, null, + null, attach); + payPackage.setFaceCode(faceCode); + return createPayRequest(payPackage); + } } diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/face/PayfaceAuthinfoRequest.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/face/PayfaceAuthinfoRequest.java index 33e78e4b..c2d2a20d 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/face/PayfaceAuthinfoRequest.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/face/PayfaceAuthinfoRequest.java @@ -4,6 +4,7 @@ import com.foxinmy.weixin4j.pay.model.WeixinPayAccount; import com.foxinmy.weixin4j.pay.sign.WeixinPaymentSignature; import com.foxinmy.weixin4j.pay.type.SignType; import com.foxinmy.weixin4j.util.*; +import com.foxinmy.weixin4j.xml.XmlStream; import java.util.HashMap; import java.util.Map; @@ -65,7 +66,7 @@ public class PayfaceAuthinfoRequest { } public String toRequestString(){ - StringBuilder content = new StringBuilder(); + /*StringBuilder content = new StringBuilder(); content.append(""); content.append(String.format("%s", payAccount.getId())); content.append(String.format("%s", payAccount.getMchId())); @@ -87,11 +88,12 @@ public class PayfaceAuthinfoRequest { if(StringUtil.isNotBlank(attach)){ content.append(String.format("", attach)); } - content.append(""); - return content.toString(); + content.append("");*/ + Map paramsMap = getRequestParam(); + return XmlStream.map2xml(paramsMap); } - private String getRequestSign(){ + private Map getRequestParam(){ Map map = new HashMap(); map.put("appid", payAccount.getId()); map.put("mch_id", payAccount.getMchId()); @@ -112,6 +114,9 @@ public class PayfaceAuthinfoRequest { if(StringUtil.isNotBlank(attach)) { map.put("attach", attach); } - return paymentSignature.sign(map); + String sign = paymentSignature.sign(map); + map.put("sign", sign); + + return map; } } diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MchPayPackage.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MchPayPackage.java index e890dbbb..79730533 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MchPayPackage.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MchPayPackage.java @@ -77,6 +77,10 @@ public class MchPayPackage extends PayPackage { @JSONField(name = "scene_info") private String sceneInfo; + @XmlElement(name = "face_code") + @JSONField(name = "face_code") + private String faceCode; + protected MchPayPackage() { // jaxb required } @@ -110,7 +114,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); } /** @@ -151,12 +155,14 @@ public class MchPayPackage extends PayPackage { * @param subOpenId * 用户在子商户appid下的唯一标识 非必填 * openid和sub_openid可以选传其中之一,如果选择传sub_openid ,则必须传sub_appid + * @param faceCode + * 人脸凭证,用于旧版刷脸支付。 */ 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) { + Date timeExpire, String goodsTag, String limitPay, String subOpenId, String faceCode) { super(body, detial, outTradeNo, totalFee, notifyUrl, createIp, attach, timeStart, timeExpire, goodsTag); this.tradeType = tradeType != null ? tradeType.name() : null; @@ -167,6 +173,7 @@ public class MchPayPackage extends PayPackage { this.productId = productId; this.limitPay = limitPay; this.subOpenId = subOpenId; + this.faceCode = faceCode; } public String getTradeType() { @@ -213,6 +220,14 @@ public class MchPayPackage extends PayPackage { this.sceneInfo = sceneInfo; } + public String getFaceCode() { + return faceCode; + } + + public void setFaceCode(String faceCode) { + this.faceCode = faceCode; + } + @Override public String toString() { return "MchPayPackage [tradeType=" + tradeType + ",feeType=" + feeType diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MerchantTradeResult.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MerchantTradeResult.java index 3f297f3f..d257f11b 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MerchantTradeResult.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/MerchantTradeResult.java @@ -44,7 +44,7 @@ public class MerchantTradeResult extends MerchantResult { /** * 货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY * - * @see com.foxinmy.weixin4j.mp.type.CurrencyType + * @see com.foxinmy.weixin4j.pay.type.CurrencyType */ @XmlElement(name = "fee_type") @JSONField(name = "fee_type") diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/Order.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/Order.java index f1e7be19..9265c63c 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/Order.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/payment/mch/Order.java @@ -68,7 +68,7 @@ public class Order extends MerchantTradeResult { /** * 现金支付货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY * - * @see com.foxinmy.weixin4j.mp.type.CurrencyType + * @see com.foxinmy.weixin4j.pay.type.CurrencyType */ @XmlElement(name = "cash_fee_type") @JSONField(name = "cash_fee_type") diff --git a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/type/TradeType.java b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/type/TradeType.java index 14e321c5..c9bfc2e2 100644 --- a/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/type/TradeType.java +++ b/weixin4j-pay/src/main/java/com/foxinmy/weixin4j/pay/type/TradeType.java @@ -29,5 +29,9 @@ public enum TradeType { /** * WAP支付 */ - MWEB; + MWEB, + /** + * 刷脸支付 + */ + FACEPAY; } diff --git a/weixin4j-pay/src/main/resources/com/foxinmy/weixin4j/payment/weixin.properties b/weixin4j-pay/src/main/resources/com/foxinmy/weixin4j/payment/weixin.properties index 73f25c10..736d4544 100644 --- a/weixin4j-pay/src/main/resources/com/foxinmy/weixin4j/payment/weixin.properties +++ b/weixin4j-pay/src/main/resources/com/foxinmy/weixin4j/payment/weixin.properties @@ -55,4 +55,6 @@ customsorder_declare_uri={mch_base_url}/mch/customs/customdeclareorder # \u8BA2\u5355\u9644\u52A0\u4FE1\u606F\u67E5\u8BE2 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 \ No newline at end of file +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 \ No newline at end of file diff --git a/weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestFacePay.java b/weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestFacePay.java new file mode 100644 index 00000000..b5d0858c --- /dev/null +++ b/weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestFacePay.java @@ -0,0 +1,31 @@ +package com.foxinmy.weixin4j.pay.test; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.pay.WeixinPayProxy; +import com.foxinmy.weixin4j.pay.model.WeixinPayAccount; +import com.foxinmy.weixin4j.pay.payment.mch.MchPayRequest; +import org.junit.Test; + +public class TestFacePay { + + @Test + public void test() throws WeixinException { + String appid = ""; + String mchid = ""; + String paySignKey = ""; + WeixinPayAccount payAccount = new WeixinPayAccount(appid, paySignKey, mchid); + WeixinPayProxy proxy = new WeixinPayProxy(payAccount); + + String orderNo = "TESTORDER2019092001"; + String openId = "oguJRswolIOGg7Vd1VaqGJuDBFAE"; + String faceCode = "0f879a6c-5fff-421c-a233-5fac0f4aad12"; + + MchPayRequest rsp = proxy.createFacePayRequest(faceCode, "测试的人脸支付", + orderNo, 1, + "127.0.0.1", openId, null); + + JSONObject obj = (JSONObject) JSON.toJSON(rsp); + } +} diff --git a/weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestGetPayFaceAuthInfo.java b/weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestGetPayFaceAuthInfo.java new file mode 100644 index 00000000..57ac56a7 --- /dev/null +++ b/weixin4j-pay/src/test/java/com/foxinmy/weixin4j/pay/test/TestGetPayFaceAuthInfo.java @@ -0,0 +1,24 @@ +package com.foxinmy.weixin4j.pay.test; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.pay.WeixinPayProxy; +import com.foxinmy.weixin4j.pay.model.WeixinPayAccount; +import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfo; +import org.junit.Assert; +import org.junit.Test; + +public class TestGetPayFaceAuthInfo { + @Test + public void test() throws WeixinException { + String appid = ""; + String mchid = ""; + String paySignKey = ""; + String rawData = "7rfwfRXEDBBbs5MjHW67ritEHtQ7AchIcd0E1zfBxmxyIEXA3aiPTdtrZ1I1fXn6Mpyln11al546YOfNK/HXe81b589a9EyAHuoziZmoe+qJFf2ulkwBWOFffnSN05Qy/ykboG4PciO5yvIMlKEEdmqEjj4ck9oBmAKCqXCM2bRDqNEQOuckZGqGsJsM4xyKEZmlL4cLk+/l9xtvOseJccBeDJfkg5fAdwG1z7lX1DThdyb8uRuE3UCvVghQ21KslyIrF9G6rhh3bP83sD//QklJsdf/dapidxkCACfZkGyNl7wFDnjj5bUgwj9pYW3gQBUff606pI9Eh7VoLwFb768DGfSGHVTwQOPeq+Ldu0bAFyuTNFZUBETYnOCZx0ue7ehDmfmFSxyqVfLRhmlMTPHC/AHRVp6wwg1EnQUTRpUltHdn4O3w5B0PRDVlXogdri0WaTDyrYo18GaZvUdCWld09NZboEPknWEgfQfwaF4vow6R4negvKCVna5kNbjDlDRWNaN+AKtHIznnPKWipc6UunBKeMw/kNTced2f73dUEDALGLPE41nnxA7y1uePWMXVJyNGnWxk461/nz6g/NfyJAgIOILrO1wThEhBd6tFAJGQwu366fnN/5eU9XfBzApHE+OIrtYyRLYJHVaAsAeXOy+PvVqMUFkEWJ3iSLJUZhLJYUbnqVEZaIeAvMY0NJ5+E26WvXXhIGr91gPq35aEjuPu4LKbGTw1jgM="; + + WeixinPayAccount payAccount = new WeixinPayAccount(appid, paySignKey, mchid); + WeixinPayProxy proxy = new WeixinPayProxy(payAccount); + PayfaceAuthinfo info = proxy.getWxPayfaceAuthinfo("TEST01", "甘坑客家小镇", "TESTDEVICE01", rawData); + System.out.print(info); + Assert.assertEquals("SUCCESS", info.getReturnCode()); + } +}