[fix]微信充值和提现
This commit is contained in:
parent
568cf4a9be
commit
4b518e023c
@ -1,10 +1,22 @@
|
|||||||
package org.dromara.app;
|
package org.dromara.app;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.business.IChargeBusiness;
|
||||||
|
import com.wzj.soopin.transaction.convert.ChargeConvert;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.ChargeBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.po.Charge;
|
||||||
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
import com.wzj.soopin.transaction.enums.PaymentClientEnum;
|
import com.wzj.soopin.transaction.enums.PaymentClientEnum;
|
||||||
import com.wzj.soopin.transaction.enums.PaymentMethodEnum;
|
import com.wzj.soopin.transaction.enums.PaymentMethodEnum;
|
||||||
|
import com.wzj.soopin.transaction.enums.TransState;
|
||||||
|
import com.wzj.soopin.transaction.enums.easypay.PayType;
|
||||||
import com.wzj.soopin.transaction.kit.CashierSupport;
|
import com.wzj.soopin.transaction.kit.CashierSupport;
|
||||||
import com.wzj.soopin.transaction.kit.dto.PayParam;
|
import com.wzj.soopin.transaction.kit.dto.PayParam;
|
||||||
import com.wzj.soopin.transaction.kit.params.dto.CashierParam;
|
import com.wzj.soopin.transaction.kit.params.dto.CashierParam;
|
||||||
|
import com.wzj.soopin.transaction.service.IChargeService;
|
||||||
|
import com.wzj.soopin.transaction.service.PayOrderService;
|
||||||
|
import com.wzj.soopin.transaction.util.SnowFlake;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
import io.swagger.annotations.ApiImplicitParams;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@ -16,10 +28,14 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.constant.ResultCode;
|
import org.dromara.common.core.constant.ResultCode;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 买家端,收银台接口
|
* 买家端,收银台接口
|
||||||
@ -34,11 +50,11 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AppPayController {
|
public class AppPayController {
|
||||||
|
|
||||||
|
private final IChargeBusiness chargeBusiness;
|
||||||
private final CashierSupport cashierSupport;
|
private final CashierSupport cashierSupport;
|
||||||
|
|
||||||
|
|
||||||
// @ApiImplicitParams({
|
// @ApiImplicitParams({
|
||||||
// @ApiImplicitParam(name = "client", value = "客户端类型", paramType = "path", allowableValues = "PC,H5,WECHAT_MP,APP")
|
// @ApiImplicitParam(name = "client", value = "客户端类型", paramType = "path", allowableValues = "PC,H5,WECHAT_MP,APP")
|
||||||
// })
|
// })
|
||||||
@PostMapping(value = "/tradeDetail")
|
@PostMapping(value = "/tradeDetail")
|
||||||
@ -51,19 +67,29 @@ public class AppPayController {
|
|||||||
|
|
||||||
|
|
||||||
@ApiImplicitParams({
|
@ApiImplicitParams({
|
||||||
@ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"),
|
@ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"),
|
||||||
@ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP")
|
@ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP")
|
||||||
})
|
})
|
||||||
@PostMapping(value = "/pay")
|
@PostMapping(value = "/pay")
|
||||||
@Operation(summary = "支付")
|
@Operation(summary = "支付")
|
||||||
public R payment(
|
public R payment(
|
||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
@RequestBody @Validated PayParam payParam) {
|
@RequestBody @Validated PayParam payParam, @RequestBody ChargeBO chargeBO) {
|
||||||
PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(payParam.getPaymentMethod());
|
PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(payParam.getPaymentMethod());
|
||||||
PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(payParam.getPaymentClient());
|
PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(payParam.getPaymentClient());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
LoginUser user = LoginHelper.getLoginUser();
|
||||||
|
if (user == null) {
|
||||||
|
return R.notLogin();
|
||||||
|
}
|
||||||
|
//先生成充值订单
|
||||||
|
chargeBO.setMemberId(user.getUserId());
|
||||||
|
chargeBO.setMethod(paymentMethodEnum.getCode());
|
||||||
|
chargeBusiness.charge(chargeBO);
|
||||||
|
payParam.setSn(chargeBO.getCode());
|
||||||
return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
|
return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
|
||||||
} catch (ServiceException se) {
|
} catch (ServiceException se) {
|
||||||
log.info("支付异常", se);
|
log.info("支付异常", se);
|
||||||
|
BIN
ruoyi-admin/src/main/resources/cert/apiclient_cert.p12
Normal file
BIN
ruoyi-admin/src/main/resources/cert/apiclient_cert.p12
Normal file
Binary file not shown.
25
ruoyi-admin/src/main/resources/cert/apiclient_cert.pem
Normal file
25
ruoyi-admin/src/main/resources/cert/apiclient_cert.pem
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEKzCCAxOgAwIBAgIUa6aB2bIZA01veFH1fWG+kxerSP0wDQYJKoZIhvcNAQEL
|
||||||
|
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||||
|
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||||
|
Q0EwHhcNMjMxMTA2MDkwODIwWhcNMjgxMTA0MDkwODIwWjCBhDETMBEGA1UEAwwK
|
||||||
|
MTY1ODY2NTcxMDEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTAwLgYDVQQL
|
||||||
|
DCfml6Dnu4jooZfvvIjlpKnmtKXvvInnp5HmioDmnInpmZDlhazlj7gxCzAJBgNV
|
||||||
|
BAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||||
|
ADCCAQoCggEBAPIJ7lvlud4KUXNjQb044xtoBWuF516f8h2mPrtIMkrKb4R9gKbE
|
||||||
|
OaRFbeGOL5FAcRS0jWYtEoWgRrQ1EVim0Lhlqq5OAAiKtgTphW0ZSiK4dauhzFMI
|
||||||
|
WByO/KalzzwKWFT0iFHP4UqiWZL1g9Dw9BUiJM3EnutQ7gP9d2wAm8h4Ltoo4Mfm
|
||||||
|
RA5IqQzlItXrNMEr/iHpAsPEWuQOviVuut2xJHhm7blgWqg0IwtdljvSYGXE77Hv
|
||||||
|
Cjr1RCVxTC8xtmKc8X5kaKEXH1d9fFH8sovyTF5pOiYZEkhOybtJE626etHbrVhk
|
||||||
|
Nl0YDS1o9ypNrcYIQe/Um9JuCqxOl6H/Uh0CAwEAAaOBuTCBtjAJBgNVHRMEAjAA
|
||||||
|
MAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2
|
||||||
|
Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJD
|
||||||
|
MDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJC
|
||||||
|
MjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQCv
|
||||||
|
bdw6QwSePVI64eTddCW8pY9Dbi66IjUcqgvjwDzHIUQCMx0NHBGJRCmN0f/f5xpM
|
||||||
|
nVg4I7RAkQ7WgFM78+MYUFJ5II368El8vTnhzRQ3Fv27v22G1EE/RAl7cQF9VB0X
|
||||||
|
j1gaB09pPqfMD40Mg522CNh7NNVqCPr3mlTAj2PMalCT7VhDDqUxmqm9RtBd9ARN
|
||||||
|
FMqx+FrUuFR5Y0N5o0OVcMbGcl8/krLqeUSZwy1Y42+KbViEqRxjTTOJEw/0B6TS
|
||||||
|
6nUIBddt24ucWnOmlkhfs8Xf4YbLSP52H9EfSOgZ4vZ2OZ0kBngbZzZgLSFM2LNk
|
||||||
|
UEBJbv+ElQBvKr2GP+EC
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.wzj.soopin.transaction.business;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.ChargeBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.vo.ChargeVO;
|
||||||
|
import org.dromara.common.web.core.IBusiness;
|
||||||
|
|
||||||
|
public interface IChargeBusiness extends IBusiness<ChargeVO, ChargeBO> {
|
||||||
|
boolean charge(ChargeBO bo);
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.wzj.soopin.transaction.business.impl;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.business.IChargeBusiness;
|
||||||
|
import com.wzj.soopin.transaction.convert.ChargeConvert;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.ChargeBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.po.Charge;
|
||||||
|
import com.wzj.soopin.transaction.domain.vo.ChargeVO;
|
||||||
|
import com.wzj.soopin.transaction.enums.ChargeStatus;
|
||||||
|
import com.wzj.soopin.transaction.service.IChargeService;
|
||||||
|
import com.wzj.soopin.transaction.util.SnowFlake;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
|
import org.dromara.common.web.core.BusinessImpl;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ChargeBusinessImpl extends BusinessImpl<IChargeService, ChargeConvert, ChargeVO, ChargeBO, Charge> implements IChargeBusiness {
|
||||||
|
@Override
|
||||||
|
public boolean charge(ChargeBO bo) {
|
||||||
|
|
||||||
|
//先检查是否发起过,如果发起过则返回原订单
|
||||||
|
Charge existCharge = service.getByCode(bo.getCode());
|
||||||
|
if (existCharge!=null){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Charge charge = converter.toPo(bo);
|
||||||
|
service.charge(charge);
|
||||||
|
bo.setCode(charge.getCode());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -68,7 +68,7 @@ public class Charge extends BaseAudit {
|
|||||||
private LocalDateTime auditTime;
|
private LocalDateTime auditTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提现方式
|
* 充值方式
|
||||||
*/
|
*/
|
||||||
private Integer method;
|
private Integer method;
|
||||||
|
|
||||||
|
@ -99,4 +99,6 @@ public class PayOrder extends BaseAudit {
|
|||||||
@TableLogic(value = "0", delval = "1")
|
@TableLogic(value = "0", delval = "1")
|
||||||
@TableField(value = "del_flag", fill = FieldFill.INSERT, jdbcType = JdbcType.CHAR)
|
@TableField(value = "del_flag", fill = FieldFill.INSERT, jdbcType = JdbcType.CHAR)
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|
||||||
|
private String title;
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@ import lombok.Getter;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public enum ChargeStatus {
|
public enum ChargeStatus {
|
||||||
WAITING(0, "待验证"),
|
WAITING(0, "未支付"),
|
||||||
PENDING(1, "充值成功"),
|
PENDING(1, "待验证"),
|
||||||
SUCCESS(2, "充值失败");
|
SUCCESS(2, "充值成功"),
|
||||||
|
FAIL(3, "充值失败");
|
||||||
|
|
||||||
private Integer code;
|
private Integer code;
|
||||||
private String message;
|
private String message;
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.wzj.soopin.transaction.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态枚举
|
||||||
|
*
|
||||||
|
* @author Chopper
|
||||||
|
* @since 2020/11/17 7:28 下午
|
||||||
|
*/
|
||||||
|
public enum PayStatusEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态
|
||||||
|
*/
|
||||||
|
UNPAID("待付款"),
|
||||||
|
PAID("已付款"),
|
||||||
|
CANCEL("已取消"),
|
||||||
|
REFUNDED("已退款");
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
PayStatusEnum(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String description() {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.wzj.soopin.transaction.enums;
|
package com.wzj.soopin.transaction.enums;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付方式枚举
|
* 支付方式枚举
|
||||||
*
|
*
|
||||||
@ -11,23 +13,23 @@ public enum PaymentMethodEnum {
|
|||||||
/**
|
/**
|
||||||
* 微信
|
* 微信
|
||||||
*/
|
*/
|
||||||
WECHAT("wechatPlugin", "微信"),
|
WECHAT("wechatPlugin", 1),
|
||||||
/**
|
/**
|
||||||
* 支付宝
|
* 支付宝
|
||||||
*/
|
*/
|
||||||
ALIPAY("aliPayPlugin", "支付宝"),
|
ALIPAY("aliPayPlugin", 2),
|
||||||
/**
|
/**
|
||||||
* 余额支付
|
* 余额支付
|
||||||
*/
|
*/
|
||||||
WALLET("walletPlugin", "余额支付"),
|
WALLET("walletPlugin", 3),
|
||||||
/**
|
/**
|
||||||
* 线下转账
|
* 线下转账
|
||||||
*/
|
*/
|
||||||
BANK_TRANSFER("bankTransferPlugin", "线下转账"),
|
BANK_TRANSFER("bankTransferPlugin", 4),
|
||||||
/**
|
/**
|
||||||
* 易生支付
|
* 易生支付
|
||||||
*/
|
*/
|
||||||
EASY_PAY("easyPayPlugin", "易生支付");
|
EASY_PAY("easyPayPlugin", 5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件id 调用对象,需要实现payment接口
|
* 插件id 调用对象,需要实现payment接口
|
||||||
@ -36,14 +38,14 @@ public enum PaymentMethodEnum {
|
|||||||
/**
|
/**
|
||||||
* 支付名称
|
* 支付名称
|
||||||
*/
|
*/
|
||||||
private final String paymentName;
|
private final Integer code;
|
||||||
|
|
||||||
public String getPlugin() {
|
public String getPlugin() {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String paymentName() {
|
public Integer getCode() {
|
||||||
return paymentName;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,9 +63,9 @@ public enum PaymentMethodEnum {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentMethodEnum(String plugin, String paymentName) {
|
PaymentMethodEnum(String plugin, Integer code) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.paymentName = paymentName;
|
this.code = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.wzj.soopin.transaction.kit;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付设置
|
||||||
|
*
|
||||||
|
* @author Chopper
|
||||||
|
* @since 2020-12-02 10:08
|
||||||
|
*/
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "wechat.pay.v3")
|
||||||
|
public class WechatPaymentSetting {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APP应用id
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
/**
|
||||||
|
* 小程序应用id
|
||||||
|
*/
|
||||||
|
private String mpAppId;
|
||||||
|
/**
|
||||||
|
* 服务号应用id
|
||||||
|
*/
|
||||||
|
private String serviceAppId;
|
||||||
|
/**
|
||||||
|
* 商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
/**
|
||||||
|
* 私钥
|
||||||
|
*/
|
||||||
|
private String apiclient_key;
|
||||||
|
/**
|
||||||
|
* pem 证书
|
||||||
|
*/
|
||||||
|
private String apiclient_cert_pem;
|
||||||
|
/**
|
||||||
|
* p12 证书
|
||||||
|
*/
|
||||||
|
private String apiclient_cert_p12;
|
||||||
|
/**
|
||||||
|
* 商户证书序列号
|
||||||
|
*/
|
||||||
|
private String mchSerialNo;
|
||||||
|
/**
|
||||||
|
* apiv3私钥
|
||||||
|
*/
|
||||||
|
private String apiV3Key;
|
||||||
|
|
||||||
|
private String privateKeyPath;
|
||||||
|
}
|
@ -377,9 +377,9 @@ public class WxPayKit {
|
|||||||
if (signType == null) {
|
if (signType == null) {
|
||||||
signType = SignType.MD5;
|
signType = SignType.MD5;
|
||||||
}
|
}
|
||||||
// String packageSign = createSign(packageParams, partnerKey, signType);
|
String packageSign = createSign(packageParams, partnerKey, signType);
|
||||||
// 部分微信APP支付 提示签名错误 解开下方注释 替换上边的代码就好。
|
// 部分微信APP支付 提示签名错误 解开下方注释 替换上边的代码就好。
|
||||||
String packageSign = createAppSign(packageParams, partnerKey);
|
// String packageSign = createAppSign(packageParams, partnerKey);
|
||||||
packageParams.put("sign", packageSign);
|
packageParams.put("sign", packageSign);
|
||||||
return packageParams;
|
return packageParams;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class DateTimeZoneUtil implements Serializable {
|
|||||||
if (date == null) {
|
if (date == null) {
|
||||||
throw new Exception("date is not null");
|
throw new Exception("date is not null");
|
||||||
}
|
}
|
||||||
// ZonedDateTime zonedDateTime = DateTimeConverterUtil.toZonedDateTime(date);
|
// ZonedDateTime zonedDateTime = Date(date);
|
||||||
// time = DateTimeFormatterUtil.format(zonedDateTime, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_XXX_FMT);
|
// time = DateTimeFormatterUtil.format(zonedDateTime, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_XXX_FMT);
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.wzj.soopin.transaction.kit.dto;
|
package com.wzj.soopin.transaction.kit.dto;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.kit.params.dto.CashierParam;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -22,7 +23,6 @@ public class PayParam {
|
|||||||
@ApiModelProperty(value = "交易类型", allowableValues = "TRADE,ORDER,RECHARGE")
|
@ApiModelProperty(value = "交易类型", allowableValues = "TRADE,ORDER,RECHARGE")
|
||||||
private String orderType;
|
private String orderType;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@ApiModelProperty(value = "订单号")
|
@ApiModelProperty(value = "订单号")
|
||||||
private String sn;
|
private String sn;
|
||||||
|
|
||||||
@ -34,5 +34,4 @@ public class PayParam {
|
|||||||
|
|
||||||
private String paymentClient;
|
private String paymentClient;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import java.util.List;
|
|||||||
public class CashierParam {
|
public class CashierParam {
|
||||||
|
|
||||||
@ApiModelProperty(value = "价格")
|
@ApiModelProperty(value = "价格")
|
||||||
private BigDecimal price;
|
private Long price;
|
||||||
|
|
||||||
@ApiModelProperty(value = "支付title")
|
@ApiModelProperty(value = "支付title")
|
||||||
private String title;
|
private String title;
|
||||||
|
@ -63,7 +63,7 @@ public class OrderCashier implements CashierExecute {
|
|||||||
if (!order.getStatus().equals(OrderStatusEnum.UNPAID.getValue())) {
|
if (!order.getStatus().equals(OrderStatusEnum.UNPAID.getValue())) {
|
||||||
throw new ServiceException(ResultCode.PAY_BAN);
|
throw new ServiceException(ResultCode.PAY_BAN);
|
||||||
}
|
}
|
||||||
cashierParam.setPrice(order.getPayAmount());
|
cashierParam.setPrice(order.getPayAmount().longValue());
|
||||||
//
|
//
|
||||||
// try {
|
// try {
|
||||||
// BaseSetting baseSetting = JSONUtil.toBean(settingService.get(SettingEnum.BASE_SETTING.name()).getSettingValue(), BaseSetting.class);
|
// BaseSetting baseSetting = JSONUtil.toBean(settingService.get(SettingEnum.BASE_SETTING.name()).getSettingValue(), BaseSetting.class);
|
||||||
|
@ -2,17 +2,27 @@ package com.wzj.soopin.transaction.kit.params.impl;
|
|||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.domain.po.Charge;
|
||||||
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
import com.wzj.soopin.transaction.enums.CashierEnum;
|
import com.wzj.soopin.transaction.enums.CashierEnum;
|
||||||
|
import com.wzj.soopin.transaction.enums.ChargeStatus;
|
||||||
|
import com.wzj.soopin.transaction.enums.PayStatusEnum;
|
||||||
import com.wzj.soopin.transaction.kit.dto.PayParam;
|
import com.wzj.soopin.transaction.kit.dto.PayParam;
|
||||||
import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams;
|
import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams;
|
||||||
import com.wzj.soopin.transaction.kit.params.CashierExecute;
|
import com.wzj.soopin.transaction.kit.params.CashierExecute;
|
||||||
import com.wzj.soopin.transaction.kit.params.dto.CashierParam;
|
import com.wzj.soopin.transaction.kit.params.dto.CashierParam;
|
||||||
|
import com.wzj.soopin.transaction.mapper.ChargeMapper;
|
||||||
|
import com.wzj.soopin.transaction.mapper.PayOrderMapper;
|
||||||
|
import com.wzj.soopin.transaction.service.IChargeService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.constant.ResultCode;
|
import org.dromara.common.core.constant.ResultCode;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 充值信息获取
|
* 充值信息获取
|
||||||
*
|
*
|
||||||
@ -21,17 +31,12 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
@AllArgsConstructor
|
||||||
public class RechargeCashier implements CashierExecute {
|
public class RechargeCashier implements CashierExecute {
|
||||||
/**
|
private final IChargeService chargeService;
|
||||||
* 余额
|
|
||||||
*/
|
|
||||||
// @Autowired
|
|
||||||
// private RechargeService rechargeService;
|
|
||||||
// /**
|
|
||||||
// * 设置
|
|
||||||
// */
|
|
||||||
// @Autowired
|
|
||||||
// private SettingService settingService;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,25 +60,22 @@ public class RechargeCashier implements CashierExecute {
|
|||||||
//准备返回的数据
|
//准备返回的数据
|
||||||
CashierParam cashierParam = new CashierParam();
|
CashierParam cashierParam = new CashierParam();
|
||||||
//订单信息获取
|
//订单信息获取
|
||||||
// Recharge recharge = rechargeService.getRecharge(payParam.getSn());
|
Charge recharge = chargeService.getByCode(payParam.getSn());
|
||||||
//
|
|
||||||
// //如果订单已支付,则不能发器支付
|
//如果订单已支付,则不能发器支付
|
||||||
// if (recharge.getPayStatus().equals(PayStatusEnum.PAID.name())) {
|
if (!recharge.getStatus().equals(ChargeStatus.WAITING.getCode())) {
|
||||||
// throw new ServiceException(ResultCode.PAY_DOUBLE_ERROR);
|
throw new ServiceException(ResultCode.PAY_DOUBLE_ERROR);
|
||||||
// }
|
}
|
||||||
//
|
cashierParam.setPrice( recharge.getMoney().longValue());
|
||||||
//
|
|
||||||
// cashierParam.setPrice(recharge.getRechargeMoney());
|
try {
|
||||||
//
|
cashierParam.setTitle("在线充值");
|
||||||
// try {
|
} catch (Exception e) {
|
||||||
// BaseSetting baseSetting = JSONUtil.toBean(settingService.get(SettingEnum.BASE_SETTING.name()).getSettingValue(), BaseSetting.class);
|
cashierParam.setTitle("多用户商城,在线充值");
|
||||||
// cashierParam.setTitle(baseSetting.getSiteName());
|
}
|
||||||
// } catch (Exception e) {
|
cashierParam.setDetail("余额充值");
|
||||||
// cashierParam.setTitle("多用户商城,在线充值");
|
cashierParam.setCreateTime(recharge.getCreateTime());
|
||||||
// }
|
return cashierParam;
|
||||||
// cashierParam.setDetail("余额充值");
|
|
||||||
// cashierParam.setCreateTime(recharge.getCreateTime());
|
|
||||||
// return cashierParam;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -290,7 +290,7 @@ public class EasyPayPlugin implements Payment {
|
|||||||
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
|
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
|
||||||
|
|
||||||
//支付金额
|
//支付金额
|
||||||
BigDecimal fen =cashierParam.getPrice();
|
Long fen =cashierParam.getPrice();
|
||||||
//第三方付款订单
|
//第三方付款订单
|
||||||
String outOrderNo = SnowFlake.getIdStr();
|
String outOrderNo = SnowFlake.getIdStr();
|
||||||
//过期时间
|
//过期时间
|
||||||
@ -312,7 +312,7 @@ public class EasyPayPlugin implements Payment {
|
|||||||
//回传参数
|
//回传参数
|
||||||
.setAttach(attach)
|
.setAttach(attach)
|
||||||
.setNotify_url(notifyUrl("apiProperties.getBuyer()", PaymentMethodEnum.WECHAT))
|
.setNotify_url(notifyUrl("apiProperties.getBuyer()", PaymentMethodEnum.WECHAT))
|
||||||
.setAmount(new Amount().setTotal(fen));
|
.setAmount(new Amount().setTotal(fen.intValue()));
|
||||||
|
|
||||||
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
|
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
|
||||||
// PaymentHttpResponse response = WechatApi.v3(
|
// PaymentHttpResponse response = WechatApi.v3(
|
||||||
|
@ -28,6 +28,8 @@ import org.redisson.api.RLock;
|
|||||||
import org.redisson.api.RedissonClient;
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WalletPlugin
|
* WalletPlugin
|
||||||
@ -163,7 +165,7 @@ public class WalletPlugin implements Payment {
|
|||||||
}
|
}
|
||||||
//个人账户扣减
|
//个人账户扣减
|
||||||
boolean result = accountBillService.reduceMoney(
|
boolean result = accountBillService.reduceMoney(
|
||||||
cashierParam.getPrice(),
|
BigDecimal.valueOf(cashierParam.getPrice() ),
|
||||||
loginUser.getUserId(),
|
loginUser.getUserId(),
|
||||||
|
|
||||||
AccountBillSourceEnum.PAYMENT,
|
AccountBillSourceEnum.PAYMENT,
|
||||||
|
@ -7,16 +7,16 @@ import cn.hutool.json.JSONArray;
|
|||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.wzj.soopin.order.utils.StringUtils;
|
||||||
import com.wzj.soopin.transaction.domain.po.RefundLog;
|
import com.wzj.soopin.transaction.domain.po.RefundLog;
|
||||||
import com.wzj.soopin.transaction.enums.PaymentMethodEnum;
|
import com.wzj.soopin.transaction.enums.PaymentMethodEnum;
|
||||||
import com.wzj.soopin.transaction.kit.CashierSupport;
|
import com.wzj.soopin.transaction.kit.CashierSupport;
|
||||||
import com.wzj.soopin.transaction.kit.Payment;
|
import com.wzj.soopin.transaction.kit.Payment;
|
||||||
|
import com.wzj.soopin.transaction.kit.WechatPaymentSetting;
|
||||||
import com.wzj.soopin.transaction.kit.core.PaymentHttpResponse;
|
import com.wzj.soopin.transaction.kit.core.PaymentHttpResponse;
|
||||||
import com.wzj.soopin.transaction.kit.core.enums.RequestMethodEnums;
|
import com.wzj.soopin.transaction.kit.core.enums.RequestMethodEnums;
|
||||||
import com.wzj.soopin.transaction.kit.core.enums.SignType;
|
import com.wzj.soopin.transaction.kit.core.enums.SignType;
|
||||||
import com.wzj.soopin.transaction.kit.core.kit.HttpKit;
|
import com.wzj.soopin.transaction.kit.core.kit.*;
|
||||||
import com.wzj.soopin.transaction.kit.core.kit.IpKit;
|
|
||||||
import com.wzj.soopin.transaction.kit.core.kit.WxPayKit;
|
|
||||||
import com.wzj.soopin.transaction.kit.core.utils.DateTimeZoneUtil;
|
import com.wzj.soopin.transaction.kit.core.utils.DateTimeZoneUtil;
|
||||||
import com.wzj.soopin.transaction.kit.dto.PayParam;
|
import com.wzj.soopin.transaction.kit.dto.PayParam;
|
||||||
import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams;
|
import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams;
|
||||||
@ -27,20 +27,31 @@ import com.wzj.soopin.transaction.kit.plugin.wechat.model.*;
|
|||||||
import com.wzj.soopin.transaction.service.PaymentService;
|
import com.wzj.soopin.transaction.service.PaymentService;
|
||||||
import com.wzj.soopin.transaction.service.RefundLogService;
|
import com.wzj.soopin.transaction.service.RefundLogService;
|
||||||
import com.wzj.soopin.transaction.util.CurrencyUtil;
|
import com.wzj.soopin.transaction.util.CurrencyUtil;
|
||||||
|
import com.wzj.soopin.transaction.util.SnowFlake;
|
||||||
|
import com.wzj.soopin.transaction.wechat.WechatPayConfig;
|
||||||
|
import com.wzj.soopin.transaction.wechat.WechatPayException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.constant.CachePrefix;
|
||||||
import org.dromara.common.core.constant.ResultCode;
|
import org.dromara.common.core.constant.ResultCode;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.common.redis.redis.RedisCache;
|
||||||
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付
|
* 微信支付
|
||||||
@ -94,6 +105,10 @@ public class WechatPlugin implements Payment {
|
|||||||
// @Autowired
|
// @Autowired
|
||||||
// private OrderService orderService;
|
// private OrderService orderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WechatPaymentSetting setting;
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Object> h5pay(HttpServletRequest request, HttpServletResponse response1, PayParam payParam) {
|
public R<Object> h5pay(HttpServletRequest request, HttpServletResponse response1, PayParam payParam) {
|
||||||
@ -236,63 +251,68 @@ public class WechatPlugin implements Payment {
|
|||||||
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
|
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
|
||||||
|
|
||||||
//支付金额
|
//支付金额
|
||||||
// Integer fen = CurrencyUtil.fen(cashierParam.getPrice());
|
Integer fen = cashierParam.getPrice().intValue();
|
||||||
// //第三方付款订单
|
//第三方付款订单
|
||||||
// String outOrderNo = SnowFlake.getIdStr();
|
String outOrderNo = SnowFlake.getIdStr();
|
||||||
// //过期时间
|
//过期时间
|
||||||
// String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
|
ZonedDateTime zonedDateTime = LocalDateTime.now().plusMinutes(3).atZone(ZoneId.of("UTC"));
|
||||||
//
|
|
||||||
// String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
|
// 自定义无毫秒的 RFC 3339 格式器
|
||||||
//
|
DateTimeFormatter rfc3339NoMillis = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
|
||||||
// WechatPaymentSetting setting = wechatPaymentSetting();
|
String timeExpire = zonedDateTime.format(rfc3339NoMillis);
|
||||||
// String appid = setting.getAppId();
|
|
||||||
// if (appid == null) {
|
String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam.getSn()), StandardCharsets.UTF_8);
|
||||||
// throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
|
|
||||||
// }
|
String appid = setting.getAppId();
|
||||||
// UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
|
if (appid == null) {
|
||||||
// .setAppid(appid)
|
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
|
||||||
// .setMchid(setting.getMchId())
|
}
|
||||||
// .setDescription(cashierParam.getDetail())
|
UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
|
||||||
// .setOut_trade_no(outOrderNo)
|
.setAppid(appid)
|
||||||
// .setTime_expire(timeExpire)
|
.setMchid(setting.getMchId())
|
||||||
// .setAttach(attach)
|
.setDescription(cashierParam.getDetail())
|
||||||
// .setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT))
|
.setOut_trade_no(outOrderNo)
|
||||||
// .setAmount(new Amount().setTotal(fen));
|
.setTime_expire(timeExpire)
|
||||||
//
|
.setAttach(attach)
|
||||||
//
|
.setNotify_url("http://cjh.wuzhongjie.com.cn/app/wechat/notify")
|
||||||
// log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
|
.setAmount(new Amount().setTotal(fen));
|
||||||
// PaymentHttpResponse response = WechatApi.v3(
|
|
||||||
// RequestMethodEnums.POST,
|
|
||||||
// WechatDomain.CHINA.toString(),
|
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
|
||||||
// WechatApiEnum.APP_PAY.toString(),
|
PaymentHttpResponse response = WechatApi.v3(
|
||||||
// setting.getMchId(),
|
RequestMethodEnums.POST,
|
||||||
// setting.getSerialNumber(),
|
WechatDomain.CHINA.toString(),
|
||||||
// null,
|
WechatApiEnum.APP_PAY.toString(),
|
||||||
// setting.getApiclient_key(),
|
setting.getMchId(),
|
||||||
// JSONUtil.toJsonStr(unifiedOrderModel)
|
setting.getMchSerialNo(),
|
||||||
// );
|
setting.getMchSerialNo(),
|
||||||
// //根据证书序列号查询对应的证书来验证签名结果
|
setting.getPrivateKeyPath() ,
|
||||||
// boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
|
JSONUtil.toJsonStr(unifiedOrderModel)
|
||||||
// log.info("verifySignature: {}", verifySignature);
|
|
||||||
// log.info("统一下单响应 {}", response);
|
);
|
||||||
//
|
//根据证书序列号查询对应的证书来验证签名结果
|
||||||
// if (verifySignature) {
|
boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
|
||||||
// JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
|
log.info("verifySignature: {}", verifySignature);
|
||||||
// String prepayId = jsonObject.getStr("prepay_id");
|
log.info("统一下单响应 {}", response);
|
||||||
// Map<String, String> map = WxPayKit.appPrepayIdCreateSign(appid,
|
|
||||||
// setting.getMchId(),
|
if (verifySignature) {
|
||||||
// prepayId,
|
JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
|
||||||
// setting.getApiclient_key(), SignType.HMACSHA256);
|
String prepayId = jsonObject.getStr("prepay_id");
|
||||||
// log.info("唤起支付参数:{}", map);
|
Map<String, String> map = WxPayKit.appPrepayIdCreateSign(appid,
|
||||||
//
|
setting.getMchId(),
|
||||||
// return R.ok(map);
|
prepayId,
|
||||||
// }
|
setting.getApiclient_key(), SignType.HMACSHA256);
|
||||||
|
log.info("唤起支付参数:{}", map);
|
||||||
|
|
||||||
|
return R.ok(map);
|
||||||
|
}
|
||||||
log.error("微信支付参数验证错误,请及时处理");
|
log.error("微信支付参数验证错误,请及时处理");
|
||||||
throw new ServiceException(ResultCode.PAY_ERROR);
|
throw new ServiceException(ResultCode.PAY_ERROR);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("支付异常", e);
|
log.error("支付异常", e);
|
||||||
throw new ServiceException(ResultCode.PAY_ERROR);
|
throw new ServiceException(ResultCode.PAY_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -614,81 +634,80 @@ public class WechatPlugin implements Payment {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * 获取平台公钥
|
* 获取平台公钥
|
||||||
// *
|
*
|
||||||
// * @return 平台公钥
|
* @return 平台公钥
|
||||||
// */
|
*/
|
||||||
// private X509Certificate getPlatformCert() {
|
private X509Certificate getPlatformCert() {
|
||||||
// //获取缓存中的平台公钥,如果有则直接返回,否则去微信请求
|
//获取缓存中的平台公钥,如果有则直接返回,否则去微信请求
|
||||||
// String publicCert = cache.getString(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix());
|
String publicCert = RedisUtils.getCacheObject(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix());
|
||||||
// if (!StringUtils.isEmpty(publicCert)) {
|
if (!StringUtils.isEmpty(publicCert)) {
|
||||||
// return PayKit.getCertificate(publicCert);
|
return PayKit.getCertificate(publicCert);
|
||||||
// }
|
}
|
||||||
// //获取平台证书列表
|
//获取平台证书列表
|
||||||
// try {
|
try {
|
||||||
//
|
|
||||||
// WechatPaymentSetting setting = wechatPaymentSetting();
|
|
||||||
//
|
PaymentHttpResponse response = WechatApi.v3(
|
||||||
// PaymentHttpResponse response = WechatApi.v3(
|
RequestMethodEnums.GET,
|
||||||
// RequestMethodEnums.GET,
|
WechatDomain.CHINA.toString(),
|
||||||
// WechatDomain.CHINA.toString(),
|
WechatApiEnum.GET_CERTIFICATES.toString(),
|
||||||
// WechatApiEnum.GET_CERTIFICATES.toString(),
|
setting.getMchId(),
|
||||||
// setting.getMchId(),
|
setting.getMchSerialNo(),
|
||||||
// setting.getSerialNumber(),
|
null,
|
||||||
// null,
|
setting.getPrivateKeyPath(),
|
||||||
// setting.getApiclient_key(),
|
""
|
||||||
// ""
|
);
|
||||||
// );
|
String body = response.getBody();
|
||||||
// String body = response.getBody();
|
log.info("获取微信平台证书body: {}", body);
|
||||||
// log.info("获取微信平台证书body: {}", body);
|
|
||||||
//
|
if (response.getStatus() == 200) {
|
||||||
// if (response.getStatus() == 200) {
|
JSONObject jsonObject = JSONUtil.parseObj(body);
|
||||||
// JSONObject jsonObject = JSONUtil.parseObj(body);
|
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||||
// JSONArray dataArray = jsonObject.getJSONArray("data");
|
log.info("证书信息: {}", dataArray);
|
||||||
// log.info("证书信息: {}", dataArray);
|
|
||||||
//
|
//默认认为只有一个平台证书
|
||||||
// //默认认为只有一个平台证书
|
JSONObject encryptObject = dataArray.getJSONObject(0);
|
||||||
// JSONObject encryptObject = dataArray.getJSONObject(0);
|
JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
|
||||||
// JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
|
String associatedData = encryptCertificate.getStr("associated_data");
|
||||||
// String associatedData = encryptCertificate.getStr("associated_data");
|
String cipherText = encryptCertificate.getStr("ciphertext");
|
||||||
// String cipherText = encryptCertificate.getStr("ciphertext");
|
String nonce = encryptCertificate.getStr("nonce");
|
||||||
// String nonce = encryptCertificate.getStr("nonce");
|
publicCert = getPlatformCertStr(associatedData, nonce, cipherText);
|
||||||
// publicCert = getPlatformCertStr(associatedData, nonce, cipherText);
|
long second = (PayKit.getCertificate(publicCert).getNotAfter().getTime() - System.currentTimeMillis()) / 1000;
|
||||||
// long second = (PayKit.getCertificate(publicCert).getNotAfter().getTime() - System.currentTimeMillis()) / 1000;
|
redisCache.setCacheObject(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix(), publicCert, (int) second, TimeUnit.SECONDS);
|
||||||
// cache.put(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix(), publicCert, second);
|
} else {
|
||||||
// } else {
|
log.error("证书获取失败:{}" + body);
|
||||||
// log.error("证书获取失败:{}" + body);
|
throw new ServiceException(ResultCode.WECHAT_CERT_ERROR);
|
||||||
// throw new ServiceException(ResultCode.WECHAT_CERT_ERROR);
|
}
|
||||||
// }
|
return PayKit.getCertificate(publicCert);
|
||||||
// return PayKit.getCertificate(publicCert);
|
} catch (Exception e) {
|
||||||
// } catch (Exception e) {
|
log.error("证书获取失败", e);
|
||||||
// log.error("证书获取失败", e);
|
}
|
||||||
// }
|
return null;
|
||||||
// return null;
|
}
|
||||||
// }
|
|
||||||
//
|
/**
|
||||||
// /**
|
* 获取平台证书缓存的字符串
|
||||||
// * 获取平台证书缓存的字符串
|
* 下列各个密钥参数
|
||||||
// * 下列各个密钥参数
|
*
|
||||||
// *
|
* @param associatedData 密钥参数
|
||||||
// * @param associatedData 密钥参数
|
* @param nonce 密钥参数
|
||||||
// * @param nonce 密钥参数
|
* @param cipherText 密钥参数
|
||||||
// * @param cipherText 密钥参数
|
* @return platform key
|
||||||
// * @return platform key
|
* @throws GeneralSecurityException 密钥获取异常
|
||||||
// * @throws GeneralSecurityException 密钥获取异常
|
*/
|
||||||
// */
|
private String getPlatformCertStr(String associatedData, String nonce, String cipherText) throws GeneralSecurityException {
|
||||||
// private String getPlatformCertStr(String associatedData, String nonce, String cipherText) throws GeneralSecurityException {
|
|
||||||
//
|
|
||||||
//
|
AesUtil aesUtil = new AesUtil(setting.getApiV3Key().getBytes(StandardCharsets.UTF_8));
|
||||||
// AesUtil aesUtil = new AesUtil(wechatPaymentSetting().getApiKey3().getBytes(StandardCharsets.UTF_8));
|
//平台证书密文解密
|
||||||
// //平台证书密文解密
|
//encrypt_certificate 中的 associated_data nonce ciphertext
|
||||||
// //encrypt_certificate 中的 associated_data nonce ciphertext
|
return aesUtil.decryptToString(
|
||||||
// return aesUtil.decryptToString(
|
associatedData.getBytes(StandardCharsets.UTF_8),
|
||||||
// associatedData.getBytes(StandardCharsets.UTF_8),
|
nonce.getBytes(StandardCharsets.UTF_8),
|
||||||
// nonce.getBytes(StandardCharsets.UTF_8),
|
cipherText
|
||||||
// cipherText
|
);
|
||||||
// );
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public class Amount {
|
|||||||
/**
|
/**
|
||||||
* 总金额
|
* 总金额
|
||||||
*/
|
*/
|
||||||
private BigDecimal total;
|
private Integer total;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 货币类型
|
* 货币类型
|
||||||
|
@ -9,4 +9,6 @@ public interface IChargeService extends IService<Charge> {
|
|||||||
|
|
||||||
boolean charge(Charge charge);
|
boolean charge(Charge charge);
|
||||||
|
|
||||||
|
Charge getByCode(String code);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.wzj.soopin.transaction.service.impl;
|
package com.wzj.soopin.transaction.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.wzj.soopin.member.domain.po.AccountBill;
|
import com.wzj.soopin.member.domain.po.AccountBill;
|
||||||
import com.wzj.soopin.member.domain.po.MemberAccount;
|
import com.wzj.soopin.member.domain.po.MemberAccount;
|
||||||
@ -11,6 +12,7 @@ import com.wzj.soopin.transaction.domain.po.Charge;
|
|||||||
import com.wzj.soopin.transaction.enums.ChargeStatus;
|
import com.wzj.soopin.transaction.enums.ChargeStatus;
|
||||||
import com.wzj.soopin.transaction.mapper.ChargeMapper;
|
import com.wzj.soopin.transaction.mapper.ChargeMapper;
|
||||||
import com.wzj.soopin.transaction.service.IChargeService;
|
import com.wzj.soopin.transaction.service.IChargeService;
|
||||||
|
import com.wzj.soopin.transaction.util.SnowFlake;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
@ -44,13 +46,13 @@ public class ChargeServiceImpl extends ServiceImpl<ChargeMapper, Charge> impleme
|
|||||||
memberAccount.setWallet(memberAccount.getWallet().add(charge.getMoney()));
|
memberAccount.setWallet(memberAccount.getWallet().add(charge.getMoney()));
|
||||||
memberAccountService.updateById(memberAccount);
|
memberAccountService.updateById(memberAccount);
|
||||||
//生成充值记录
|
//生成充值记录
|
||||||
AccountBill accountBill=AccountBill.builder()
|
AccountBill accountBill = AccountBill.builder()
|
||||||
.accountId(charge.getMemberId())
|
.accountId(charge.getMemberId())
|
||||||
.changeAmount(charge.getMoney())
|
.changeAmount(charge.getMoney())
|
||||||
.changeType(AccountBillChangeTypeEnum.IN.getCode())
|
.changeType(AccountBillChangeTypeEnum.IN.getCode())
|
||||||
.changeDesc("充值")
|
.changeDesc("充值")
|
||||||
.source(AccountBillSourceEnum.RECHARGE.getCode())
|
.source(AccountBillSourceEnum.RECHARGE.getCode())
|
||||||
.build();
|
.build();
|
||||||
accountBillService.save(accountBill);
|
accountBillService.save(accountBill);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -62,18 +64,29 @@ public class ChargeServiceImpl extends ServiceImpl<ChargeMapper, Charge> impleme
|
|||||||
@Override
|
@Override
|
||||||
public boolean charge(Charge charge) {
|
public boolean charge(Charge charge) {
|
||||||
//判断充值金额不能为零
|
//判断充值金额不能为零
|
||||||
if (charge.getMoney().compareTo(BigDecimal.ZERO) == 0) {
|
if (charge.getMoney()==null||charge.getMoney().compareTo(BigDecimal.ZERO) == 0) {
|
||||||
throw new ServiceException("充值金额不能为零");
|
throw new ServiceException("充值金额不能为零");
|
||||||
}
|
}
|
||||||
//状态为待审核
|
//状态为待充值
|
||||||
charge.setStatus(ChargeStatus.WAITING.getCode());
|
charge.setStatus(ChargeStatus.WAITING.getCode());
|
||||||
charge.setType(1);
|
charge.setType(1);
|
||||||
//手续费
|
//手续费
|
||||||
charge.setFee(new BigDecimal("0.01").multiply(charge.getMoney()));
|
charge.setFee(new BigDecimal("0.01").multiply(charge.getMoney()));
|
||||||
//实际金额
|
//实际金额
|
||||||
charge.setActualMoney(charge.getMoney().subtract(charge.getFee()));
|
charge.setActualMoney(charge.getMoney().subtract(charge.getFee()));
|
||||||
|
|
||||||
|
//设置充值信息
|
||||||
|
if (charge.getMemberId() == null) {
|
||||||
|
throw new ServiceException("充值用户不能为空");
|
||||||
|
}
|
||||||
|
charge.setCode(SnowFlake.createStr("RC"));
|
||||||
//保存充值记录
|
//保存充值记录
|
||||||
save(charge);
|
save(charge);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Charge getByCode(String code) {
|
||||||
|
return baseMapper.selectOne(new LambdaQueryWrapper<Charge>().eq(Charge::getCode, code));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.wzj.soopin.transaction.service.impl;
|
package com.wzj.soopin.transaction.service.impl;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.enums.TransState;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
@ -8,4 +9,10 @@ import com.wzj.soopin.transaction.service.PayOrderService;
|
|||||||
@Service
|
@Service
|
||||||
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements PayOrderService{
|
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements PayOrderService{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean save(PayOrder entity) {
|
||||||
|
//
|
||||||
|
entity.setTransState(TransState.PENDING.getCode());
|
||||||
|
return super.save(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ public class WithdrawServiceImpl extends ServiceImpl<WithdrawMapper, Withdraw> i
|
|||||||
}
|
}
|
||||||
//检查当前用于的账户余额是否充足
|
//检查当前用于的账户余额是否充足
|
||||||
BigDecimal balance = memberAccount.getWallet();
|
BigDecimal balance = memberAccount.getWallet();
|
||||||
if (balance.compareTo(withdraw.getMoney()) < 0) {
|
if (balance==null||balance.compareTo(withdraw.getMoney()) < 0) {
|
||||||
throw new RuntimeException("用户余额不足");
|
throw new RuntimeException("用户余额不足");
|
||||||
}
|
}
|
||||||
//生成费用
|
//生成费用
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.wzj.soopin.transaction.util;
|
package com.wzj.soopin.transaction.util;
|
||||||
|
|
||||||
|
import com.google.type.Decimal;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -120,9 +122,8 @@ public final class CurrencyUtil {
|
|||||||
* @param money 金额
|
* @param money 金额
|
||||||
* @return 转换单位为分
|
* @return 转换单位为分
|
||||||
*/
|
*/
|
||||||
public static Integer fen(Double money) {
|
public static Integer fen(BigDecimal money) {
|
||||||
double price = mul(money, 100);
|
return money.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
return (int) price;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +47,7 @@ public class SnowFlake {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String createStr(String prefix) {
|
public static String createStr(String prefix) {
|
||||||
return prefix + DateUtil.toString(new Date(), "yyyyMMdd") + SnowFlake.getId();
|
return prefix + DateUtil.toString(new Date(), "yyyyMMdd") + SnowFlake.getIdStr();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getIdStr() {
|
public static String getIdStr() {
|
||||||
|
@ -204,7 +204,11 @@ http {
|
|||||||
index index.html;
|
index index.html;
|
||||||
try_files $uri $uri/ /busniess/index.html;
|
try_files $uri $uri/ /busniess/index.html;
|
||||||
}
|
}
|
||||||
|
location ^~ /file/ {
|
||||||
|
proxy_pass http://43.143.227.203:9000/;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
# app分享
|
# app分享
|
||||||
location ^~ /spa {
|
location ^~ /spa {
|
||||||
alias /data/wzj/download/spa;
|
alias /data/wzj/download/spa;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user