微信、支付宝提现
This commit is contained in:
parent
0a3696ac56
commit
b8398ac1d1
@ -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);
|
||||
}
|
||||
/**
|
||||
* 获取收银台参数
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付回调地址
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证支付结果
|
||||
*
|
||||
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付接口</p>
|
||||
*
|
||||
* @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<String, String> 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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
|
||||
package cn.lili.modules.payment.kit.plugin.unionpay;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付等常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付常用配置</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付等常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付常用配置 Kit</p>
|
||||
*
|
||||
* @author Javen
|
||||
*/
|
||||
public class UnionPayApiConfigKit {
|
||||
private static final ThreadLocal<String> TL = new ThreadLocal<String>();
|
||||
|
||||
private static final Map<String, UnionPayApiConfig> CFG_MAP = new ConcurrentHashMap<String, UnionPayApiConfig>();
|
||||
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;
|
||||
}
|
||||
}
|
@ -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<Object> 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<String, String> 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<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
||||
log.info(result.toString());
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultMessage<Object> 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<String, String> 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<String, String> 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<Object> 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<String, String> 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<String, String> 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<String, String> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package cn.lili.modules.payment.kit.plugin.unionpay.enums;
|
||||
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付接口类型枚举</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-商户进件</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-授权码查询 openId</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>Model 公用方法</p>
|
||||
*
|
||||
* @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<String, String> toMap() {
|
||||
String[] fieldNames = getFiledNames(this);
|
||||
HashMap<String, String> map = new HashMap<String, String>(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<String, String> 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<String, String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-下单对账单</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-关闭订单</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-付款码支付</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-订单查询</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-退款</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-查询退款</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-撤销订单</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-统一下单</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
|
||||
*
|
||||
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
|
||||
*
|
||||
* <p>IJPay 交流群: 723992875</p>
|
||||
*
|
||||
* <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
|
||||
*
|
||||
* <p>云闪付-银联 JS 支付获取 userId</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
@ -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<TransferDetailInput> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证结果,执行支付回调
|
||||
*
|
||||
|
@ -555,6 +555,11 @@ public enum WechatApiEnum {
|
||||
* 连锁品牌-删除分账接收方
|
||||
*/
|
||||
BRAND_PROFIT_SHARING_RECEIVERS_delete("/v3/brand/profitsharing/receivers/delete"),
|
||||
|
||||
/**
|
||||
* 发起商家转账
|
||||
*/
|
||||
TRANSFER_BATCHES("/v3/transfer/batches"),
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
@ -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<TransferDetailInput> transfer_detail_list;
|
||||
//必填,指定该笔转账使用的转账场景ID
|
||||
private String transfer_scene_id;
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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<MemberWalletMapper, Mem
|
||||
*/
|
||||
@Autowired
|
||||
private MemberWithdrawApplyService memberWithdrawApplyService;
|
||||
@Autowired
|
||||
private CashierSupport cashierSupport;
|
||||
|
||||
@Override
|
||||
public MemberWalletVO getMemberWallet(String memberId) {
|
||||
@ -302,7 +306,8 @@ public class MemberWalletServiceImpl extends ServiceImpl<MemberWalletMapper, Mem
|
||||
memberWithdrawApply.setInspectTime(new Date());
|
||||
//保存或者修改零钱提现
|
||||
this.memberWithdrawApplyService.saveOrUpdate(memberWithdrawApply);
|
||||
//TODO 调用自动提现接口
|
||||
//TODO 做成配置项目
|
||||
cashierSupport.transfer(PaymentMethodEnum.WECHAT,memberWithdrawApply);
|
||||
boolean result = true;
|
||||
//如果微信提现失败 则抛出异常 回滚数据
|
||||
if (!result) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user