From b8398ac1d1b64fe9c090273c8ca4b02d528ae3df Mon Sep 17 00:00:00 2001 From: "pikachu1995@126.com" Date: Thu, 23 Feb 2023 17:50:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=81=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=AE=9D=E6=8F=90=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/payment/kit/CashierSupport.java | 10 + .../cn/lili/modules/payment/kit/Payment.java | 8 + .../kit/plugin/alipay/AliPayPlugin.java | 41 ++- .../kit/plugin/unionpay/UnionPayApi.java | 38 +++ .../plugin/unionpay/UnionPayApiConfig.java | 57 ++++ .../plugin/unionpay/UnionPayApiConfigKit.java | 87 ++++++ .../kit/plugin/unionpay/UnionPayPlugin.java | 247 ++++++++++++++++++ .../plugin/unionpay/enums/ServiceEnum.java | 95 +++++++ .../kit/plugin/unionpay/model/ApplyModel.java | 55 ++++ .../unionpay/model/AuthCodeToOpenIdModel.java | 37 +++ .../kit/plugin/unionpay/model/BaseModel.java | 105 ++++++++ .../unionpay/model/BillDownloadModel.java | 35 +++ .../unionpay/model/CloseOrderModel.java | 36 +++ .../plugin/unionpay/model/MicroPayModel.java | 51 ++++ .../unionpay/model/OrderQueryModel.java | 37 +++ .../plugin/unionpay/model/RefundModel.java | 43 +++ .../unionpay/model/RefundQueryModel.java | 39 +++ .../plugin/unionpay/model/ReverseModel.java | 36 +++ .../unionpay/model/UnifiedOrderModel.java | 60 +++++ .../unionpay/model/UnionPayUserIdModel.java | 37 +++ .../kit/plugin/wechat/WechatPlugin.java | 60 +++++ .../plugin/wechat/enums/WechatApiEnum.java | 5 + .../wechat/model/TransferDetailInput.java | 29 ++ .../plugin/wechat/model/TransferModel.java | 31 +++ .../entity/dos/MemberWithdrawApply.java | 5 + .../serviceimpl/MemberWalletServiceImpl.java | 7 +- 26 files changed, 1289 insertions(+), 2 deletions(-) create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApi.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfig.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfigKit.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayPlugin.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/enums/ServiceEnum.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ApplyModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/AuthCodeToOpenIdModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BaseModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BillDownloadModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/CloseOrderModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/MicroPayModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/OrderQueryModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundQueryModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ReverseModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnifiedOrderModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnionPayUserIdModel.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferDetailInput.java create mode 100644 framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferModel.java diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/CashierSupport.java b/framework/src/main/java/cn/lili/modules/payment/kit/CashierSupport.java index cec468fb..fb8874cc 100644 --- a/framework/src/main/java/cn/lili/modules/payment/kit/CashierSupport.java +++ b/framework/src/main/java/cn/lili/modules/payment/kit/CashierSupport.java @@ -18,6 +18,7 @@ import cn.lili.modules.system.entity.dto.payment.PaymentSupportSetting; import cn.lili.modules.system.entity.dto.payment.dto.PaymentSupportItem; import cn.lili.modules.system.entity.enums.SettingEnum; import cn.lili.modules.system.service.SettingService; +import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply; import cn.lili.modules.wallet.service.MemberWalletService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -142,6 +143,15 @@ public class CashierSupport { payment.notify(request); } + /** + * 用户提现 + * @param paymentMethodEnum 支付渠道 + * @param memberWithdrawApply 用户提现申请 + */ + public void transfer(PaymentMethodEnum paymentMethodEnum, MemberWithdrawApply memberWithdrawApply){ + Payment payment = (Payment) SpringContextUtil.getBean(paymentMethodEnum.getPlugin()); + payment.transfer(memberWithdrawApply); + } /** * 获取收银台参数 * diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/Payment.java b/framework/src/main/java/cn/lili/modules/payment/kit/Payment.java index f67c2619..fba4010e 100644 --- a/framework/src/main/java/cn/lili/modules/payment/kit/Payment.java +++ b/framework/src/main/java/cn/lili/modules/payment/kit/Payment.java @@ -6,6 +6,7 @@ import cn.lili.common.vo.ResultMessage; import cn.lili.modules.payment.entity.RefundLog; import cn.lili.modules.payment.entity.enums.PaymentMethodEnum; import cn.lili.modules.payment.kit.dto.PayParam; +import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -110,6 +111,13 @@ public interface Payment { throw new ServiceException(ResultCode.PAY_ERROR); } + /** + * 提现 + */ + default void transfer(MemberWithdrawApply memberWithdrawApply) { + throw new ServiceException(ResultCode.PAY_ERROR); + } + /** * 支付回调地址 * diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/alipay/AliPayPlugin.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/alipay/AliPayPlugin.java index 9641d751..2d72e845 100644 --- a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/alipay/AliPayPlugin.java +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/alipay/AliPayPlugin.java @@ -26,11 +26,13 @@ import cn.lili.modules.system.entity.dos.Setting; import cn.lili.modules.system.entity.dto.payment.AlipayPaymentSetting; import cn.lili.modules.system.entity.enums.SettingEnum; import cn.lili.modules.system.service.SettingService; +import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.domain.*; import com.alipay.api.internal.util.AlipaySignature; -import com.alipay.api.response.AlipayTradeCancelResponse; +import com.alipay.api.request.AlipayFundTransUniTransferRequest; +import com.alipay.api.response.AlipayFundTransUniTransferResponse; import com.alipay.api.response.AlipayTradeRefundResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -229,6 +231,43 @@ public class AliPayPlugin implements Payment { log.info("支付异步通知:"); } + /** + * 支付宝提现 + * 文档地址:https://opendocs.alipay.com/open/02byuo?scene=ca56bca529e64125a2786703c6192d41&ref=api + * + * @param memberWithdrawApply 会员提现申请 + */ + @Override + public void transfer(MemberWithdrawApply memberWithdrawApply) { + AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel(); + model.setOutBizNo(SnowFlake.createStr("T")); + model.setRemark("用户提现"); + model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}"); + model.setBizScene("DIRECT_TRANSFER"); + Participant payeeInfo = new Participant(); + payeeInfo.setIdentity(memberWithdrawApply.getConnectNumber()); + payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); + payeeInfo.setName(memberWithdrawApply.getRealName()); + model.setPayeeInfo(payeeInfo); + + model.setTransAmount(memberWithdrawApply.getApplyMoney().toString()); + model.setProductCode("TRANS_ACCOUNT_NO_PWD"); + model.setOrderTitle("用户提现"); + //交互退款 + try { + AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = AliPayApi.uniTransferToResponse(model,null); + log.error("支付宝退款,参数:{},支付宝响应:{}", JSONUtil.toJsonStr(model), JSONUtil.toJsonStr(alipayFundTransUniTransferResponse)); + if (alipayFundTransUniTransferResponse.isSuccess()) { + + } else { + log.error(alipayFundTransUniTransferResponse.getSubMsg()); + } + } catch (Exception e) { + log.error("用户提现异常:", e); + throw new ServiceException(ResultCode.PAY_ERROR); + } + } + /** * 验证支付结果 * diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApi.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApi.java new file mode 100644 index 00000000..7f10c265 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApi.java @@ -0,0 +1,38 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付接口

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay; + +import cn.lili.modules.payment.kit.core.kit.HttpKit; +import cn.lili.modules.payment.kit.core.kit.WxPayKit; + +import java.util.Map; + +public class UnionPayApi { + public static String authUrl = "https://qr.95516.com/qrcGtwWeb-web/api/userAuth?version=1.0.0&redirectUrl=%s"; + + public static String execution(String url, Map params) { + return HttpKit.getDelegate().post(url, WxPayKit.toXml(params)); + } + + /** + * 获取用户授权 API + * + * @param url 回调地址,可以自定义参数 https://pay.javen.com/callback?sdk=ijpay + * @return 银联重定向 Url + */ + public static String buildAuthUrl(String url) { + return String.format(authUrl, url); + } + +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfig.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfig.java new file mode 100644 index 00000000..66ea9f1c --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfig.java @@ -0,0 +1,57 @@ + +package cn.lili.modules.payment.kit.plugin.unionpay; + +import lombok.*; + +import java.io.Serializable; + +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付等常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付常用配置

+ * + * @author Javen + */ +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UnionPayApiConfig implements Serializable { + private static final long serialVersionUID = -9025648880068727445L; + + /** + * 商户平台分配的账号 + */ + private String mchId; + /** + * 连锁商户号 + */ + private String groupMchId; + /** + * 授权交易机构代码 + */ + private String agentMchId; + /** + * 商户平台分配的密钥 + */ + private String apiKey; + /** + * 商户平台网关 + */ + private String serverUrl; + /** + * 应用域名,回调中会使用此参数 + */ + private String domain; + /** + * 其他附加参数 + */ + private Object exParams; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfigKit.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfigKit.java new file mode 100644 index 00000000..9f5dc3f0 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayApiConfigKit.java @@ -0,0 +1,87 @@ + +package cn.lili.modules.payment.kit.plugin.unionpay; + +import cn.hutool.core.util.StrUtil; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付等常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付常用配置 Kit

+ * + * @author Javen + */ +public class UnionPayApiConfigKit { + private static final ThreadLocal TL = new ThreadLocal(); + + private static final Map CFG_MAP = new ConcurrentHashMap(); + private static final String DEFAULT_CFG_KEY = "_default_key_"; + + /** + * 添加云闪付配置,每个 mchId 只需添加一次,相同 mchId 将被覆盖 + * + * @param UnionPayApiConfig 云闪付配置 + * @return {@link UnionPayApiConfig} 云闪付配置 + */ + public static UnionPayApiConfig putApiConfig(UnionPayApiConfig UnionPayApiConfig) { + if (CFG_MAP.size() == 0) { + CFG_MAP.put(DEFAULT_CFG_KEY, UnionPayApiConfig); + } + return CFG_MAP.put(UnionPayApiConfig.getMchId(), UnionPayApiConfig); + } + + public static UnionPayApiConfig setThreadLocalApiConfig(UnionPayApiConfig UnionPayApiConfig) { + if (StrUtil.isNotEmpty(UnionPayApiConfig.getMchId())) { + setThreadLocalMchId(UnionPayApiConfig.getMchId()); + } + return putApiConfig(UnionPayApiConfig); + } + + public static UnionPayApiConfig removeApiConfig(UnionPayApiConfig UnionPayApiConfig) { + return removeApiConfig(UnionPayApiConfig.getMchId()); + } + + public static UnionPayApiConfig removeApiConfig(String mchId) { + return CFG_MAP.remove(mchId); + } + + public static void setThreadLocalMchId(String mchId) { + if (StrUtil.isEmpty(mchId)) { + mchId = CFG_MAP.get(DEFAULT_CFG_KEY).getMchId(); + } + TL.set(mchId); + } + + public static void removeThreadLocalMchId() { + TL.remove(); + } + + public static String getMchId() { + String appId = TL.get(); + if (StrUtil.isEmpty(appId)) { + appId = CFG_MAP.get(DEFAULT_CFG_KEY).getMchId(); + } + return appId; + } + + public static UnionPayApiConfig getApiConfig() { + String appId = getMchId(); + return getApiConfig(appId); + } + + public static UnionPayApiConfig getApiConfig(String appId) { + UnionPayApiConfig cfg = CFG_MAP.get(appId); + if (cfg == null) { + throw new IllegalStateException("需事先调用 UnionPayApiConfigKit.putApiConfig(UnionPayApiConfig) 将 mchId 对应的 UnionPayApiConfig 对象存入,才可以使用 UnionPayApiConfigKit.getUnionPayApiConfig() 的系列方法"); + } + return cfg; + } +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayPlugin.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayPlugin.java new file mode 100644 index 00000000..ebcd9d59 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/UnionPayPlugin.java @@ -0,0 +1,247 @@ +package cn.lili.modules.payment.kit.plugin.unionpay; + +import cn.hutool.core.net.URLEncoder; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import cn.lili.common.enums.ResultCode; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.utils.SnowFlake; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.payment.kit.CashierSupport; +import cn.lili.modules.payment.kit.Payment; +import cn.lili.modules.payment.kit.core.enums.SignType; +import cn.lili.modules.payment.kit.core.kit.HttpKit; +import cn.lili.modules.payment.kit.core.kit.IpKit; +import cn.lili.modules.payment.kit.core.kit.WxPayKit; +import cn.lili.modules.payment.kit.dto.PayParam; +import cn.lili.modules.payment.kit.params.dto.CashierParam; +import cn.lili.modules.payment.kit.plugin.unionpay.enums.ServiceEnum; +import cn.lili.modules.payment.kit.plugin.unionpay.model.UnifiedOrderModel; +import cn.lili.modules.payment.service.PaymentService; +import cn.lili.modules.system.entity.dos.Setting; +import cn.lili.modules.system.entity.dto.payment.UnionPaymentSetting; +import cn.lili.modules.system.entity.enums.SettingEnum; +import cn.lili.modules.system.service.SettingService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/** + * 银联云闪付 支付 + * + * @author Bulbasaur + * @since 2023/02/14 17:44 + */ +@Slf4j +@Component +public class UnionPayPlugin implements Payment { + + + /** + * 收银台 + */ + @Autowired + private CashierSupport cashierSupport; + /** + * 支付日志 + */ + @Autowired + private PaymentService paymentService; + /** + * 配置 + */ + @Autowired + private SettingService settingService; + + @Override + public ResultMessage nativePay(HttpServletRequest request, PayParam payParam) { + try { + CashierParam cashierParam = cashierSupport.cashierParam(payParam); + UnionPaymentSetting unionPaymentSetting = this.unionPaymentSetting(); + String notifyUrl = unionPaymentSetting.getUnionPayDomain().concat("/unionPay/payNotify"); + //用户ip + String ip = IpKit.getRealIp(request); + //第三方付款订单 + String outOrderNo = SnowFlake.getIdStr(); + String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8); + Map params = UnifiedOrderModel.builder() + .service(ServiceEnum.NATIVE.toString()) + .mch_id(unionPaymentSetting.getUnionPayMachId()) + .out_trade_no(outOrderNo) + .body(cashierParam.getDetail()) + .attach(attach) + .total_fee("0") + .mch_create_ip(ip) + .notify_url(notifyUrl) + .nonce_str(WxPayKit.generateStr()) + .build().createSign(unionPaymentSetting.getUnionPayKey(), SignType.MD5); + + String xmlResult = UnionPayApi.execution(unionPaymentSetting.getUnionPayServerUrl(), params); + log.info("xmlResult:" + xmlResult); + Map result = WxPayKit.xmlToMap(xmlResult); + log.info(result.toString()); + return null; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @Override + public ResultMessage appPay(HttpServletRequest request, PayParam payParam) { + try { + + CashierParam cashierParam = cashierSupport.cashierParam(payParam); + UnionPaymentSetting unionPaymentSetting = this.unionPaymentSetting(); + String notifyUrl = unionPaymentSetting.getUnionPayDomain().concat("/unionPay/payNotify"); + String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8); + + //用户ip + String ip = IpKit.getRealIp(request); + Map params = UnifiedOrderModel.builder() + .service(ServiceEnum.WEI_XIN_APP_PAY.toString()) + .mch_id(unionPaymentSetting.getUnionPayMachId()) + .appid(unionPaymentSetting.getUnionPayAppId()) + .out_trade_no(WxPayKit.generateStr()) + .body(cashierParam.getDetail()) + .attach(attach) + .total_fee("0") + .mch_create_ip(ip) + .notify_url(notifyUrl) + .nonce_str(WxPayKit.generateStr()) + .build() + .createSign(unionPaymentSetting.getUnionPayKey(), SignType.MD5); + + System.out.println(params); + + String xmlResult = UnionPayApi.execution(unionPaymentSetting.getUnionPayServerUrl(), params); + log.info("xmlResult:" + xmlResult); + Map result = WxPayKit.xmlToMap(xmlResult); + if (!WxPayKit.verifyNotify(result, unionPaymentSetting.getUnionPayKey(), SignType.MD5)) { + log.error("签名异常"); + } + String status = result.get("status"); + String resultCode = result.get("result_code"); + if (!"0".equals(status) && !"0".equals(resultCode)) { + log.error(result.get("err_msg")); + return null; + } + log.error(result.get("pay_info")); + return null; + } catch (Exception e) { + log.error(e.getMessage()); + e.printStackTrace(); + + return null; + + } + } + + @Override + public ResultMessage jsApiPay(HttpServletRequest request, PayParam payParam) { + String buyerLogonId=""; + String buyerId=""; + CashierParam cashierParam = cashierSupport.cashierParam(payParam); + UnionPaymentSetting unionPaymentSetting = this.unionPaymentSetting(); + String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8); + //用户ip + String ip = IpKit.getRealIp(request); + try { + if (StrUtil.isEmpty(buyerLogonId) && StrUtil.isEmpty(buyerId)) { + log.error("buyer_logon_id buyer_id 不能同时为空"); + return null; + } + + String notifyUrl = unionPaymentSetting.getUnionPayDomain().concat("/unionPay/payNotify"); + + + Map params = UnifiedOrderModel.builder() + .service(ServiceEnum.ALI_PAY_JS_PAY.toString()) + .mch_id(unionPaymentSetting.getUnionPayMachId()) + .out_trade_no(WxPayKit.generateStr()) + .body(cashierParam.getDetail()) + .attach(attach) + .total_fee("0") + .mch_create_ip(ip) + .notify_url(notifyUrl) + .nonce_str(WxPayKit.generateStr()) + .buyer_id(buyerId) + .buyer_logon_id(buyerLogonId) + .build() + .createSign(unionPaymentSetting.getUnionPayKey(), SignType.MD5); + + System.out.println(params); + + String xmlResult = UnionPayApi.execution(unionPaymentSetting.getUnionPayServerUrl(), params); + log.info("xmlResult:" + xmlResult); + Map result = WxPayKit.xmlToMap(xmlResult); + log.info(result.toString()); + return null; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + + @Override + public void callBack(HttpServletRequest request) { + try { + verifyNotify(request); + } catch (Exception e) { + log.error("支付异常", e); + } + } + + @Override + public void notify(HttpServletRequest request) { + try { + verifyNotify(request); + } catch (Exception e) { + log.error("支付异常", e); + } + } + + private void verifyNotify(HttpServletRequest request) throws Exception { + String xmlMsg = HttpKit.readData(request); + log.info("支付通知=" + xmlMsg); + Map params = WxPayKit.xmlToMap(xmlMsg); + + String status = params.get("status"); + String returnCode = params.get("result_code"); + + log.info(status + " " + returnCode); + + if ("0".equals(status) && "0".equals(returnCode)) { + UnionPaymentSetting unionPaymentSetting = this.unionPaymentSetting(); + // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态 + // 注意此处签名方式需与统一下单的签名类型一致 + if (WxPayKit.verifyNotify(params, unionPaymentSetting.getUnionPayKey(), SignType.MD5)) { + log.info("支付成功...."); + // 更新订单信息 + // 发送通知等 + + } + } + + } + /** + * 获取微信支付配置 + * + * @return + */ + private UnionPaymentSetting unionPaymentSetting() { + try { + Setting systemSetting = settingService.get(SettingEnum.UNIONPAY_PAYMENT.name()); + UnionPaymentSetting unionPaymentSetting = JSONUtil.toBean(systemSetting.getSettingValue(), UnionPaymentSetting.class); + return unionPaymentSetting; + } catch (Exception e) { + log.error("微信支付暂不支持", e); + throw new ServiceException(ResultCode.PAY_NOT_SUPPORT); + } + } +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/enums/ServiceEnum.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/enums/ServiceEnum.java new file mode 100644 index 00000000..856dc00a --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/enums/ServiceEnum.java @@ -0,0 +1,95 @@ +package cn.lili.modules.payment.kit.plugin.unionpay.enums; + +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付接口类型枚举

+ * + * @author Javen + */ +public enum ServiceEnum { + /** + * 刷卡支付 + */ + MICRO_PAY("unified.trade.micropay"), + /** + * 扫码支付 + */ + NATIVE("unified.trade.native"), + /** + * 微信公众号、小程序支付统一下单 + */ + WEI_XIN_JS_PAY("pay.weixin.jspay"), + /** + * 微信 App 支付 + */ + WEI_XIN_APP_PAY("pay.weixin.raw.app"), + /** + * 查询订单 + */ + QUERY("unified.trade.query"), + /** + * 申请退款 + */ + REFUND("unified.trade.refund"), + /** + * 退款查询 + */ + REFUND_QUERY("unified.trade.refundquery"), + /** + * 关闭订单 + */ + CLOSE("unified.trade.close"), + /** + * 撤销订单 + */ + MICRO_PAY_REVERSE("unified.micropay.reverse"), + /** + * 授权码查询 openid + */ + AUTH_CODE_TO_OPENID("unified.tools.authcodetoopenid"), + /** + * 银联 JS 支付获取 userId + */ + UNION_PAY_USER_ID("pay.unionpay.userid"), + /** + * 银联 JS 支付下单 + */ + UNION_JS_PAY("pay.unionpay.jspay"), + /** + * 支付宝服务窗口支付 + */ + ALI_PAY_JS_PAY("pay.alipay.jspay"), + /** + * 下载单个商户时的对账单 + */ + BILL_MERCHANT("pay.bill.merchant"), + /** + * 下载连锁商户下所有门店的对账单 + */ + BILL_BIG_MERCHANT("pay.bill.bigMerchant"), + /** + * 下载某内部机构/外包服务机构下所有商户的对账单 + */ + BILL_AGENT("pay.bill.agent"); + + /** + * 接口类型 + */ + private final String service; + + ServiceEnum(String domain) { + this.service = domain; + } + + @Override + public String toString() { + return service; + } +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ApplyModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ApplyModel.java new file mode 100644 index 00000000..c440a65c --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ApplyModel.java @@ -0,0 +1,55 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-商户进件

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class ApplyModel extends BaseModel{ + /** + * 合作伙伴 ID 即机构号 + */ + private String partner; + /** + * 服务名称 + */ + private String serviceName; + /** + * 支持 MD5 和RSA,默认为MD5 + */ + private String signType; + /** + * 字符集,默认为UTF-8 + */ + private String charset; + /** + * 请求数据 + */ + private String data; + /** + * 数据类型 + */ + private String dataType; + /** + * 数据签名 + */ + private String dataSign; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/AuthCodeToOpenIdModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/AuthCodeToOpenIdModel.java new file mode 100644 index 00000000..ef0cab1e --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/AuthCodeToOpenIdModel.java @@ -0,0 +1,37 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-授权码查询 openId

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class AuthCodeToOpenIdModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String sub_appid; + private String auth_code; + private String nonce_str; + private String sign; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BaseModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BaseModel.java new file mode 100644 index 00000000..1935bb59 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BaseModel.java @@ -0,0 +1,105 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

Model 公用方法

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import cn.hutool.core.util.StrUtil; +import cn.lili.modules.payment.kit.core.enums.SignType; +import cn.lili.modules.payment.kit.core.kit.WxPayKit; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class BaseModel { + + /** + * 将建构的 builder 转为 Map + * + * @return 转化后的 Map + */ + public Map toMap() { + String[] fieldNames = getFiledNames(this); + HashMap map = new HashMap(fieldNames.length); + for (String name : fieldNames) { + String value = (String) getFieldValueByName(name, this); + if (StrUtil.isNotEmpty(value)) { + map.put(name, value); + } + } + return map; + } + + /** + * 构建签名 Map + * + * @param partnerKey API KEY + * @param signType {@link SignType} 签名类型 + * @return 构建签名后的 Map + */ + public Map createSign(String partnerKey, SignType signType) { + return createSign(partnerKey, signType, true); + } + + /** + * 构建签名 Map + * + * @param partnerKey API KEY + * @param signType {@link SignType} 签名类型 + * @param haveSignType 签名是否包含 sign_type 字段 + * @return 构建签名后的 Map + */ + public Map createSign(String partnerKey, SignType signType, boolean haveSignType) { + return WxPayKit.buildSign(toMap(), partnerKey, signType, haveSignType); + } + + + + /** + * 获取属性名数组 + * + * @param obj 对象 + * @return 返回对象属性名数组 + */ + public String[] getFiledNames(Object obj) { + Field[] fields = obj.getClass().getDeclaredFields(); + String[] fieldNames = new String[fields.length]; + for (int i = 0; i < fields.length; i++) { + fieldNames[i] = fields[i].getName(); + } + return fieldNames; + } + + /** + * 根据属性名获取属性值 + * + * @param fieldName 属性名称 + * @param obj 对象 + * @return 返回对应属性的值 + */ + public Object getFieldValueByName(String fieldName, Object obj) { + try { + String firstLetter = fieldName.substring(0, 1).toUpperCase(); + String getter = new StringBuffer().append("get") + .append(firstLetter) + .append(fieldName.substring(1)) + .toString(); + Method method = obj.getClass().getMethod(getter); + return method.invoke(obj); + } catch (Exception e) { + return null; + } + } + +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BillDownloadModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BillDownloadModel.java new file mode 100644 index 00000000..90049165 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/BillDownloadModel.java @@ -0,0 +1,35 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-下单对账单

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class BillDownloadModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String bill_date; + private String bill_type; + private String sign_type; + private String mch_id; + private String nonce_str; + private String sign; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/CloseOrderModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/CloseOrderModel.java new file mode 100644 index 00000000..c9d3ca25 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/CloseOrderModel.java @@ -0,0 +1,36 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-关闭订单

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class CloseOrderModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String out_trade_no; + private String nonce_str; + private String sign; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/MicroPayModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/MicroPayModel.java new file mode 100644 index 00000000..e48180a6 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/MicroPayModel.java @@ -0,0 +1,51 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-付款码支付

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class MicroPayModel extends BaseModel { + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String out_trade_no; + private String device_info; + private String body; + private String goods_detail; + private String sub_appid; + private String attach; + private String need_receipt; + private String total_fee; + private String mch_create_ip; + private String auth_code; + private String time_start; + private String time_expire; + private String op_user_id; + private String op_shop_id; + private String op_device_id; + private String goods_tag; + private String nonce_str; + private String sign; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/OrderQueryModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/OrderQueryModel.java new file mode 100644 index 00000000..4dd9b660 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/OrderQueryModel.java @@ -0,0 +1,37 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-订单查询

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class OrderQueryModel extends BaseModel { + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String out_trade_no; + private String transaction_id; + private String sign_agentno; + private String groupno; + private String nonce_str; + private String sign; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundModel.java new file mode 100644 index 00000000..a1be6be2 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundModel.java @@ -0,0 +1,43 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-退款

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class RefundModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String out_trade_no; + private String transaction_id; + private String out_refund_no; + private String total_fee; + private String refund_fee; + private String op_user_id; + private String refund_channel; + private String nonce_str; + private String sign; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundQueryModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundQueryModel.java new file mode 100644 index 00000000..8808eee9 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/RefundQueryModel.java @@ -0,0 +1,39 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-查询退款

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class RefundQueryModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String out_trade_no; + private String transaction_id; + private String out_refund_no; + private String refund_id; + private String nonce_str; + private String sign; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ReverseModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ReverseModel.java new file mode 100644 index 00000000..f0efb4b6 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/ReverseModel.java @@ -0,0 +1,36 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-撤销订单

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class ReverseModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String out_trade_no; + private String nonce_str; + private String sign; + private String sign_agentno; + private String groupno; +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnifiedOrderModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnifiedOrderModel.java new file mode 100644 index 00000000..b760bed7 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnifiedOrderModel.java @@ -0,0 +1,60 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-统一下单

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class UnifiedOrderModel extends BaseModel { + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String appid; + private String is_raw; + private String is_minipg; + private String out_trade_no; + private String device_info; + private String op_shop_id; + private String body; + private String sub_openid; + private String user_id; + private String attach; + private String sub_appid; + private String total_fee; + private String need_receipt; + private String customer_ip; + private String mch_create_ip; + private String notify_url; + private String time_start; + private String time_expire; + private String qr_code_timeout_express; + private String op_user_id; + private String goods_tag; + private String product_id; + private String nonce_str; + private String buyer_logon_id; + private String buyer_id; + private String limit_credit_pay; + private String sign; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnionPayUserIdModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnionPayUserIdModel.java new file mode 100644 index 00000000..a0795dd3 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/unionpay/model/UnionPayUserIdModel.java @@ -0,0 +1,37 @@ +/** + *

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。

+ * + *

不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。

+ * + *

IJPay 交流群: 723992875

+ * + *

Node.js 版: https://gitee.com/javen205/TNWX

+ * + *

云闪付-银联 JS 支付获取 userId

+ * + * @author Javen + */ +package cn.lili.modules.payment.kit.plugin.unionpay.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class UnionPayUserIdModel extends BaseModel{ + private String service; + private String version; + private String charset; + private String sign_type; + private String mch_id; + private String nonce_str; + private String sign; + private String user_auth_code; + private String app_up_identifier; + private String sign_agentno; + private String groupno; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java index 3ba64830..3497d8e2 100644 --- a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java @@ -42,6 +42,7 @@ import cn.lili.modules.system.entity.dos.Setting; import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting; import cn.lili.modules.system.entity.enums.SettingEnum; import cn.lili.modules.system.service.SettingService; +import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -52,6 +53,8 @@ import javax.servlet.http.HttpServletResponse; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -465,6 +468,63 @@ public class WechatPlugin implements Payment { } } + /** + * 微信提现 + * 文档地址:https://pay.weixin.qq.com/docs/merchant/apis/batch-transfer-to-balance/transfer-batch/initiate-batch-transfer.html + * + * @param memberWithdrawApply 会员提现申请 + */ + @Override + public void transfer(MemberWithdrawApply memberWithdrawApply) { + + try { + WechatPaymentSetting setting = wechatPaymentSetting(); + Connect connect = connectService.queryConnect( + ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()) + .unionType(ConnectEnum.WECHAT_OPEN_ID.name()).build() + ); + //根据自身情况设置AppId,此处我存放的是服务号的APPID,下方的openID需要对应此处的APPID配置 + TransferModel transferModel = new TransferModel() + .setAppid(setting.getServiceAppId()) + .setOut_batch_no(SnowFlake.createStr("T")) + .setBatch_name("用户提现") + .setBatch_remark("用户提现") + .setTotal_amount(CurrencyUtil.fen(memberWithdrawApply.getApplyMoney())) + .setTotal_num(1) + .setTransfer_scene_id("1000"); + List transferDetailListList = new ArrayList<>(); + { + TransferDetailInput transferDetailInput = new TransferDetailInput(); + transferDetailInput.setOut_detail_no(SnowFlake.createStr("TD")); + transferDetailInput.setTransfer_amount(CurrencyUtil.fen(memberWithdrawApply.getApplyMoney())); + transferDetailInput.setTransfer_remark("用户提现"); + transferDetailInput.setOpenid(connect.getUnionId()); +// transferDetailInput.setUserName( +// "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45"); +// transferDetailInput.setUserIdCard( +// "8609cb22e1774a50a930e414cc71eca06121bcd266335cda230d24a7886a8d9f"); + transferDetailListList.add(transferDetailInput); + } + transferModel.setTransfer_detail_list(transferDetailListList); + + PaymentHttpResponse response = WechatApi.v3( + RequestMethodEnums.POST, + WechatDomain.CHINA.toString(), + WechatApiEnum.TRANSFER_BATCHES.toString(), + setting.getMchId(), + setting.getSerialNumber(), + null, + setting.getApiclient_key(), + JSONUtil.toJsonStr(transferModel) + ); + log.info("微信提现响应 {}", response); + //根据自身业务进行接下来的任务处理 + } catch (Exception e) { + e.printStackTrace(); + } + + } + /** * 验证结果,执行支付回调 * diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/enums/WechatApiEnum.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/enums/WechatApiEnum.java index 49306c74..a7303a6e 100644 --- a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/enums/WechatApiEnum.java +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/enums/WechatApiEnum.java @@ -555,6 +555,11 @@ public enum WechatApiEnum { * 连锁品牌-删除分账接收方 */ BRAND_PROFIT_SHARING_RECEIVERS_delete("/v3/brand/profitsharing/receivers/delete"), + + /** + * 发起商家转账 + */ + TRANSFER_BATCHES("/v3/transfer/batches"), ; /** diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferDetailInput.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferDetailInput.java new file mode 100644 index 00000000..bbb603fe --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferDetailInput.java @@ -0,0 +1,29 @@ +package cn.lili.modules.payment.kit.plugin.wechat.model; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 转账的明细 + * + * @author Bulbasaur + */ +@Data +@Accessors(chain = true) +public class TransferDetailInput { + //商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成 + private String out_detail_no; + //转账金额单位为“分” + private Integer transfer_amount; + //单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符 + private String transfer_remark; + //商户appid下,某用户的openid + private String openid; + + //收款方真实姓名。支持标准RSA算法和国密算法,公钥由微信侧提供 + //明细转账金额<0.3元时,不允许填写收款用户姓名 + //明细转账金额 >= 2,000元时,该笔明细必须填写收款用户姓名 + //同一批次转账明细中的姓名字段传入规则需保持一致,也即全部填写、或全部不填写 + //若商户传入收款用户姓名,微信支付会校验用户openID与姓名是否一致,并提供电子回单 + //private String user_name; +} diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferModel.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferModel.java new file mode 100644 index 00000000..a81abeca --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/model/TransferModel.java @@ -0,0 +1,31 @@ +package cn.lili.modules.payment.kit.plugin.wechat.model; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 提现 + * @author Bulbasaur + */ +@Data +@Accessors(chain = true) +public class TransferModel { + //申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid) + private String appid; + //商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一 + private String out_batch_no; + //该笔批量转账的名称 + private String batch_name; + //转账说明,UTF8编码,最多允许32个字符 + private String batch_remark; + //转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作 + private Integer total_amount; + //一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作 + private Integer total_num; + //发起批量转账的明细列表,最多一千笔 + private List transfer_detail_list; + //必填,指定该笔转账使用的转账场景ID + private String transfer_scene_id; +} diff --git a/framework/src/main/java/cn/lili/modules/wallet/entity/dos/MemberWithdrawApply.java b/framework/src/main/java/cn/lili/modules/wallet/entity/dos/MemberWithdrawApply.java index 364bd5ad..78c630ae 100644 --- a/framework/src/main/java/cn/lili/modules/wallet/entity/dos/MemberWithdrawApply.java +++ b/framework/src/main/java/cn/lili/modules/wallet/entity/dos/MemberWithdrawApply.java @@ -56,4 +56,9 @@ public class MemberWithdrawApply extends BaseEntity { @ApiModelProperty(value = "sn") private String sn; + @ApiModelProperty(value = "真实姓名") + private String realName; + @ApiModelProperty(value = "第三方平台账号") + private String connectNumber; + } diff --git a/framework/src/main/java/cn/lili/modules/wallet/serviceimpl/MemberWalletServiceImpl.java b/framework/src/main/java/cn/lili/modules/wallet/serviceimpl/MemberWalletServiceImpl.java index be6f99ee..4ea20933 100644 --- a/framework/src/main/java/cn/lili/modules/wallet/serviceimpl/MemberWalletServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/wallet/serviceimpl/MemberWalletServiceImpl.java @@ -11,6 +11,8 @@ import cn.lili.common.utils.SnowFlake; import cn.lili.common.utils.StringUtils; import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.service.MemberService; +import cn.lili.modules.payment.entity.enums.PaymentMethodEnum; +import cn.lili.modules.payment.kit.CashierSupport; import cn.lili.modules.system.entity.dos.Setting; import cn.lili.modules.system.entity.dto.WithdrawalSetting; import cn.lili.modules.system.entity.enums.SettingEnum; @@ -77,6 +79,8 @@ public class MemberWalletServiceImpl extends ServiceImpl