Bläddra i källkod

微信退款申请

master
chenchaod 2 månader sedan
förälder
incheckning
f3cf6000a4
15 ändrade filer med 417 tillägg och 0 borttagningar
  1. 3
    0
      gly-base-core/src/main/java/cn/com/taiji/core/entity/comm/CommonPayConfig.java
  2. 23
    0
      gly-base-core/src/main/java/cn/com/taiji/core/entity/dict/pay/RefundAccount.java
  3. 22
    0
      gly-base-core/src/main/java/cn/com/taiji/core/entity/dict/pay/RefundChannel.java
  4. 25
    0
      gly-base-core/src/main/java/cn/com/taiji/core/entity/dict/pay/RefundStatus.java
  5. 66
    0
      gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV2Request.java
  6. 43
    0
      gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV2Response.java
  7. 67
    0
      gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV3Request.java
  8. 56
    0
      gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV3Response.java
  9. 2
    0
      gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/WeiXinServiceCmd.java
  10. 3
    0
      zhywpt-app-userw/src/main/java/cn/com/taiji/userw/dto/wx/WxPayAddReqDTO.java
  11. 3
    0
      zhywpt-app-userw/src/main/java/cn/com/taiji/userw/dto/wx/WxPayUpdateReqDTO.java
  12. 8
    0
      zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/handler/WinXinServiceHandler.java
  13. 1
    0
      zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/weixin/QueryPayResultV2Manager.java
  14. 49
    0
      zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/weixin/RefundV2Manager.java
  15. 46
    0
      zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/weixin/RefundV3Manager.java

+ 3
- 0
gly-base-core/src/main/java/cn/com/taiji/core/entity/comm/CommonPayConfig.java Visa fil

@@ -61,6 +61,9 @@ public class CommonPayConfig extends StringPropertyUUIDEntity {
@Column(name = "UPDATE_TIME")
private LocalDateTime updateTime = LocalDateTime.now();//更新时间

@Column(name = "WX_SERVICE_TYPE")
private Integer wxServiceType;//微信商户下单类型,1普通商户,2服务商





+ 23
- 0
gly-base-core/src/main/java/cn/com/taiji/core/entity/dict/pay/RefundAccount.java Visa fil

@@ -0,0 +1,23 @@
package cn.com.taiji.core.entity.dict.pay;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* @Author:ChenChao
* @Date:2025/5/20 20:54
* @Filename:RefundAccount
* @description:wx退款资金账户
*/
@AllArgsConstructor
@Getter
public enum RefundAccount {
UNSETTLED("未结算资金"),
AVAILABLE("可用余额"),
UNAVAILABLE("不可用余额"),
OPERATION("运营账户"),
BASIC("基本账户(含可用余额和不可用余额)"),
ECNY_BASIC("数字人民币基本账户"),
;
private String name;
}

+ 22
- 0
gly-base-core/src/main/java/cn/com/taiji/core/entity/dict/pay/RefundChannel.java Visa fil

@@ -0,0 +1,22 @@
package cn.com.taiji.core.entity.dict.pay;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* @Author:ChenChao
* @Date:2025/5/20 20:47
* @Filename:RefundChannel
* @description: wx退款渠道
*/
@AllArgsConstructor
@Getter
public enum RefundChannel {

ORIGINAL("原路退款"),
BALANCE("退回余额"),
OTHER_BALANCE("原账户异常退到其他余额账户"),
OTHER_BANKCARD(" 原银行卡异常退到其他银行卡"),//(发起异常退款成功后返回)
;
private String name;
}

+ 25
- 0
gly-base-core/src/main/java/cn/com/taiji/core/entity/dict/pay/RefundStatus.java Visa fil

@@ -0,0 +1,25 @@
package cn.com.taiji.core.entity.dict.pay;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* @Author:ChenChao
* @Date:2025/5/20 20:51
* @Filename:RefundStatus
* @description:wx退款状态
*/
@AllArgsConstructor
@Getter
public enum RefundStatus {

SUCCESS("退款成功"),

CLOSED("退款关闭"),

PROCESSING("退款处理中"),

ABNORMAL("退款异常"),
;
private String name;
}

+ 66
- 0
gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV2Request.java Visa fil

@@ -0,0 +1,66 @@
package cn.com.taiji.core.model.comm.protocol.ats.weiXin;

import cn.com.taiji.core.model.comm.protocol.ats.AbstractAtsRequest;
import cn.com.taiji.core.model.comm.protocol.constraint.IntegerConstant;
import cn.com.taiji.core.model.comm.protocol.valid.ErrorMsgBuilder;
import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
* @Author:ChenChao
* @Date:2025/5/20 19:57
* @Filename:AtsRefundRequest
* @description: 退款申请
*/
@Setter
@Getter
public class AtsRefundV2Request extends AbstractAtsRequest<AtsRefundV2Response> {

public AtsRefundV2Request() {
super(WeiXinServiceCmd.REFUNDV2);
}

/**
* 1单独下单url-普通商户下单
* 2服务商下单
* 3合并下单url
* 目前只提供单独下单和服务商下单
*/
@IntegerConstant(values = "1,2")
@NotNull
private Integer createType;
@NotBlank
private String outTradeNo;//商户订单号

@NotBlank
private String outRefundNo;//商户退款单号(由自己系统生成)

@NotNull
private Integer totalFee;//订单金额

@NotNull
private Integer refundFee;//退款金额

private String refundFeeType = "CNY";//退款货币种类

private String refundDesc;//退款原因
private String notifyUrl;//退款结果通知url

@NotBlank
private String appId;//服务商的APPID
@NotBlank
private String mchId;
private String subAppId;
private String subMchId;
@NotBlank
private String mchKey;
@Override
protected void validate(ErrorMsgBuilder builder) {
if (createType == 2){
builder.validFieldNotBlank("subMchId", subMchId);
}
}
}

+ 43
- 0
gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV2Response.java Visa fil

@@ -0,0 +1,43 @@
package cn.com.taiji.core.model.comm.protocol.ats.weiXin;

import cn.com.taiji.core.entity.dict.pay.RefundAccount;
import cn.com.taiji.core.entity.dict.pay.RefundChannel;
import cn.com.taiji.core.entity.dict.pay.RefundStatus;
import cn.com.taiji.core.model.comm.protocol.ats.AbstractAtsResponse;
import lombok.Getter;
import lombok.Setter;

/**
* @Author:ChenChao
* @Date:2025/5/20 19:57
* @Filename:AtsRefundResponse
* @description: 退款申请响应
*/
@Getter
@Setter
public class AtsRefundV2Response extends AbstractAtsResponse {

private String transactionId;//微信支付订单号 是

private String outTradeNo;//商户订单号 是

private String outRefundNo;//商户退款单号 是

private String refundId;//微信退款单号 是

private Integer refundFee;//退款金额 是

private Integer settlementRefundFee;//应结退款金额 否

private Integer totalFee;//订单金额 是

private Integer settlementTotalFee;//应结订单金额 否

private String feeType;//货币类型 否

private Integer cashFee;//现金支付金额 是

private Integer cashRefundFee;//现金退款金额 否


}

+ 67
- 0
gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV3Request.java Visa fil

@@ -0,0 +1,67 @@
package cn.com.taiji.core.model.comm.protocol.ats.weiXin;

import cn.com.taiji.core.model.comm.protocol.ats.AbstractAtsRequest;
import cn.com.taiji.core.model.comm.protocol.constraint.IntegerConstant;
import cn.com.taiji.core.model.comm.protocol.valid.ErrorMsgBuilder;
import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
* @Author:ChenChao
* @Date:2025/5/20 19:57
* @Filename:AtsRefundRequest
* @description: 退款申请
*/
@Setter
@Getter
public class AtsRefundV3Request extends AbstractAtsRequest<AtsRefundV3Response> {

public AtsRefundV3Request() {
super(WeiXinServiceCmd.REFUNDV3);
}

/**
* 1单独下单url-普通商户下单
* 2服务商下单
* 3合并下单url
* 目前只提供单独下单和服务商下单
*/
@IntegerConstant(values = "1,2")
@NotNull
private Integer createType;
@NotBlank
private String outTradeNo;//商户订单号

@NotBlank
private String outRefundNo;//商户退款单号(由自己系统生成)

private String reason;//退款原因

@NotNull
private Long refund;//退款金额

@NotNull
private Long total;//订单金额

private String currency = "CNY";//默认CNY

@NotBlank
protected String mchid;//直连商户号 spMchid;服务商户号
@NotBlank
private String apiV3Key; // API V3密钥
@NotBlank
private String privateKey;// 你的商户私钥
@NotBlank
private String serialNo;// 商户证书序列号

private String subMchid;//子商户号
@Override
protected void validate(ErrorMsgBuilder builder) {
if (createType == 2){
builder.validFieldNotBlank("subMchid", subMchid);
}
}
}

+ 56
- 0
gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/AtsRefundV3Response.java Visa fil

@@ -0,0 +1,56 @@
package cn.com.taiji.core.model.comm.protocol.ats.weiXin;

import cn.com.taiji.core.entity.dict.pay.RefundAccount;
import cn.com.taiji.core.entity.dict.pay.RefundChannel;
import cn.com.taiji.core.entity.dict.pay.RefundStatus;
import cn.com.taiji.core.model.comm.protocol.ats.AbstractAtsResponse;
import lombok.Getter;
import lombok.Setter;

/**
* @Author:ChenChao
* @Date:2025/5/20 19:57
* @Filename:AtsRefundResponse
* @description: 退款申请响应
*/
@Getter
@Setter
public class AtsRefundV3Response extends AbstractAtsResponse {

private String refundId;//微信支付退款单号 是

private String outRefundNo;//商户退款单号 -商户申请退款时传的商户系统内部退款单号。 是

private String transactionId;//微信支付订单号 是

private String outTradeNo;//商户订单号 是

/**
* 1)退回银行卡:{银行名称}{卡类型}{卡尾号}
* 2)退回支付用户零钱:支付用户零钱
* 3)退还商户:商户基本账户商户结算银行账户
* 4)退回支付用户零钱通:支付用户零钱通
* 5)退回支付用户银行电子账户:支付用户银行电子账户
* 6)退回支付用户零花钱:支付用户零花钱
* 7)退回用户经营账户:用户经营账户
* 8)退回支付用户来华零钱包:支付用户来华零钱包
* 9)退回企业支付商户:企业支付商户
*/
private String userReceivedAccount;//退款入账账户 是
private String successTime; //退款成功时间 是
private String createTime; // 退款创建时间 是

private Long total;//订单金额 是
private Long refund;//退款金额 是
private Long payerTotal;//用户实际支付金额 是
private Long payerRefund;//用户退款金额 - 指用户实际收到的现金退款金额 是
private Long settlementRefund; //应结退款金额 是
private Long settlementTotal; //应结订单金额 是
private Long discountRefund;//优惠退款金额 是
private String currency;//退款币种 是

private RefundChannel refundChannel;//退款渠道 是
private RefundAccount refundAccount;//资金账户 退款所使用资金对应的资金账户类型 是
private RefundStatus refundStatus;//退款状态 是

}

+ 2
- 0
gly-base-core/src/main/java/cn/com/taiji/core/model/comm/protocol/ats/weiXin/WeiXinServiceCmd.java Visa fil

@@ -10,6 +10,8 @@ public enum WeiXinServiceCmd implements SignServiceCommand {
QUERYPAYRESULTV2("查询V2支付结果","queryPayResultV2", AtsQueryPayResultV2Request.class),
CREATEPAYORDERV3("V3统一下单","creatOrderV3", AtsCreatPayOrderV3Request.class),
QUERYPAYRESULTV3("查询V3支付结果","queryPayResultV3", AtsQueryPayResultV3Request.class),
REFUNDV3("微信V3退款申请","refundV3", AtsRefundV3Request.class),
REFUNDV2("微信V2退款申请","refundV2", AtsRefundV2Request.class),
VEHICLEUSERSTATE("微信车主状态查询及获取签约参数","vehicleUserState", AtsVehicleUserStateRequest.class),
MPSENDMESSAGE("微信公众号发送订阅信息","mpSendMessage", WxMpSendMessageRequest.class),
MPISSUBSCRIBED("微信公众号是否订阅","isSubscribed", WxMpIsSubscribedRequest.class),

+ 3
- 0
zhywpt-app-userw/src/main/java/cn/com/taiji/userw/dto/wx/WxPayAddReqDTO.java Visa fil

@@ -50,12 +50,15 @@ public class WxPayAddReqDTO extends AbstractBizRequestDTO {
@ApiModelProperty(value = "渠道编号")
@NotBlank
private String agencyId;//渠道编号
@ApiModelProperty(value = "微信商户下单类型,1普通商户,2服务商")
private Integer wxServiceType;//微信商户下单类型,1普通商户,2服务商

@Override
protected void validate(ViolationValidator validator) {
super.validate(validator);
if (PayChannelType.WEIXINPAY.equals(payChannelType)){
// validator.validField("wxPayVersion",wxPayVersion==null,"微信支付版本不能为空");
validator.validFieldNotNull("wxServiceType",wxServiceType);
validator.validFieldNotNull("wxPayVersion",wxPayVersion);
validator.validFieldNotBlank("wxAppId",wxAppId);
validator.validFieldNotBlank("wxMchId",wxMchId);

+ 3
- 0
zhywpt-app-userw/src/main/java/cn/com/taiji/userw/dto/wx/WxPayUpdateReqDTO.java Visa fil

@@ -53,12 +53,15 @@ public class WxPayUpdateReqDTO extends AbstractBizRequestDTO {
@ApiModelProperty(value = "渠道编号")
@NotBlank
private String agencyId;//渠道编号
@ApiModelProperty(value = "微信商户下单类型,1普通商户,2服务商")
private Integer wxServiceType;//微信商户下单类型,1普通商户,2服务商

@Override
protected void validate(ViolationValidator validator) {
super.validate(validator);
if (PayChannelType.WEIXINPAY.equals(payChannelType)){
// validator.validField("wxPayVersion",wxPayVersion==null,"微信支付版本不能为空");
validator.validFieldNotNull("wxServiceType",wxServiceType);
validator.validFieldNotNull("wxPayVersion",wxPayVersion);
validator.validFieldNotBlank("wxAppId",wxAppId);
validator.validFieldNotBlank("wxMchId",wxMchId);

+ 8
- 0
zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/handler/WinXinServiceHandler.java Visa fil

@@ -38,6 +38,10 @@ public class WinXinServiceHandler extends AbstractAtsServiceHandler<WeiXinServic
@Autowired
private QueryPayResultV3Manager queryPayResultV3Manager;
@Autowired
private RefundV2Manager refundV2Manager;
@Autowired
private RefundV3Manager refundV3Manager;
@Autowired
private WxMessageManager wxMessageManager;
@Autowired
private VehicleUserStateManager vehicleUserStateManager;
@@ -55,6 +59,10 @@ public class WinXinServiceHandler extends AbstractAtsServiceHandler<WeiXinServic
return createPayOrderV3Manager.serviceHandle((AtsCreatPayOrderV3Request) request);
case QUERYPAYRESULTV3:
return queryPayResultV3Manager.serviceHandle((AtsQueryPayResultV3Request) request);
case REFUNDV2:
return refundV2Manager.serviceHandle((AtsRefundV2Request) request);
case REFUNDV3:
return refundV3Manager.serviceHandle((AtsRefundV3Request) request);
case MPISSUBSCRIBED:
return wxMessageManager.isSubscribed((WxMpIsSubscribedRequest) request);
case MPSENDMESSAGE:

+ 1
- 0
zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/weixin/QueryPayResultV2Manager.java Visa fil

@@ -32,6 +32,7 @@ public class QueryPayResultV2Manager extends AbstractManager {

public AtsQueryPayResultV2Response serviceHandle(AtsQueryPayResultV2Request req) throws ServiceHandleException {
logger.info("微信支付V2查询支付结果请求参数{}",req.toJson());
req.validate();
WxPayConfig wxPayConfig = wechatConfig.initV2Config(req.getAppId(), req.getMchId(), req.getMchKey(), req.getSubAppId(), req.getSubMchId());
wxPayService.setConfig(wxPayConfig);
WxPayOrderQueryRequest request = copyProperties(req, new WxPayOrderQueryRequest());

+ 49
- 0
zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/weixin/RefundV2Manager.java Visa fil

@@ -0,0 +1,49 @@
package cn.com.taiji.ats.manager.weixin;

import cn.com.taiji.ats.config.WechatConfig;
import cn.com.taiji.common.manager.AbstractManager;
import cn.com.taiji.common.manager.net.http.ServiceHandleException;
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeResponse;
import cn.com.taiji.core.model.comm.protocol.ats.weiXin.AtsRefundV2Request;
import cn.com.taiji.core.model.comm.protocol.ats.weiXin.AtsRefundV2Response;
import cn.com.taiji.core.model.comm.protocol.valid.GlyServiceError;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* @Author:ChenChao
* @Date:2025/5/20 21:35
* @Filename:RefundV2Manager
* @description:
*/
@Service
public class RefundV2Manager extends AbstractManager {
@Autowired
private WechatConfig wechatConfig;
@Autowired
private WxPayService wxPayService;

public AtsRefundV2Response serviceHandle(AtsRefundV2Request req) throws ServiceHandleException {
logger.info("微信支付V2退款申请请求参数{}",req.toJson());
req.validate();
//初始化配置信息
WxPayConfig wxPayConfig = wechatConfig.initV2Config(req.getAppId(), req.getMchId(), req.getMchKey(),
req.getSubAppId(), req.getSubMchId());
wxPayService.setConfig(wxPayConfig);
WxPayRefundRequest request = copyProperties(req, new WxPayRefundRequest());
AtsRefundV2Response response = new AtsRefundV2Response();
try {
WxPayRefundResult refund = wxPayService.refund(request);
response = copyProperties(refund,response);
} catch (WxPayException e) {
logger.error("微信V2退款失败:{}", e.getMessage());
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException(e.getMessage());
}
return response;
}
}

+ 46
- 0
zhywpt-service-ats/src/main/java/cn/com/taiji/ats/manager/weixin/RefundV3Manager.java Visa fil

@@ -0,0 +1,46 @@
package cn.com.taiji.ats.manager.weixin;

import cn.com.taiji.ats.config.WechatConfig;
import cn.com.taiji.common.manager.AbstractManager;
import cn.com.taiji.common.manager.net.http.ServiceHandleException;
import cn.com.taiji.core.entity.dict.pay.RefundAccount;
import cn.com.taiji.core.entity.dict.pay.RefundChannel;
import cn.com.taiji.core.entity.dict.pay.RefundStatus;
import cn.com.taiji.core.model.comm.protocol.ats.weiXin.AtsRefundV3Request;
import cn.com.taiji.core.model.comm.protocol.ats.weiXin.AtsRefundV3Response;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* @Author:ChenChao
* @Date:2025/5/20 20:03
* @Filename:RefundManager
* @description:
*/
@Service
public class RefundV3Manager extends AbstractManager {

@Autowired
private WechatConfig wechatConfig;

public AtsRefundV3Response serviceHandle(AtsRefundV3Request req) throws ServiceHandleException {
logger.info("微信支付V3退款申请请求参数{}",req.toJson());
req.validate();
//配置支付信息
RSAAutoCertificateConfig config =
wechatConfig.initV3Config(req.getMchid(), req.getApiV3Key(), req.getPrivateKey(), req.getSerialNo());
// 初始化服务
RefundService service = new RefundService.Builder().config(config).build();
CreateRequest createRequest = copyProperties(req, new CreateRequest());
Refund refund = service.create(createRequest);
AtsRefundV3Response response = copyProperties(refund, new AtsRefundV3Response());
response.setRefundChannel(RefundChannel.valueOf(refund.getChannel().name()));
response.setRefundAccount(RefundAccount.valueOf(refund.getFundsAccount().name()));
response.setRefundStatus(RefundStatus.valueOf(refund.getStatus().name()));
return response;
}
}

Laddar…
Avbryt
Spara