ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/poji/shop/ShopProportionVo.java
@@ -1,4 +1,31 @@ package com.ruoyi.system.api.domain.poji.shop; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.math.BigDecimal; import java.util.Date; @Data public class ShopProportionVo { /** * 分成id */ private Long proportionId; /** * 商户id */ private Long shopId; /** * 商户类型 */ private Integer shopType; /** * 分成比例 */ private BigDecimal proportionPercent; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/miniapp/NotifyController.java
@@ -1,38 +1,34 @@ package com.ruoyi.order.controller.miniapp; import com.ruoyi.common.core.domain.R; import com.github.binarywang.wxpay.bean.ecommerce.*; import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Response; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyData; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.ProfitSharingV3Service; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.v3.auth.Verifier; import com.github.binarywang.wxpay.v3.util.AesUtils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.order.domain.dto.AppSureOrderDto; import com.ruoyi.order.domain.dto.WXPayNotifyDto; import com.ruoyi.order.domain.vo.AppSureOrderVo; import com.ruoyi.order.domain.vo.ProfitSharingNotifyNewResult; import com.ruoyi.order.enums.WxPayNotifyEventTypeEnum; import com.ruoyi.order.service.account.BackMessageService; import com.ruoyi.order.service.order.OrderService; import com.wechat.pay.contrib.apache.httpclient.notification.Notification; import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler; import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.core.RSAConfig; import com.wechat.pay.java.core.cipher.PrivacyEncryptor; import com.wechat.pay.java.core.notification.NotificationConfig; import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import net.bytebuddy.asm.Advice; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.security.GeneralSecurityException; import java.util.Map; import java.util.Objects; /** * @program: ruoyi @@ -44,88 +40,82 @@ @RestController @RequestMapping("/app/notify") public class NotifyController extends BaseController { /** 商户号 */ public static String merchantId = ""; /** 商户API私钥路径 */ public static String privateKeyPath = ""; /** 商户证书序列号 */ public static String merchantSerialNumber = ""; /** 微信支付平台证书路径 */ public static String wechatPayCertificatePath = ""; /** 商户APIV3密钥 */ public static String apiV3key = "..."; public static final String WECHAT_PAY_SERIAL = "Wechatpay-Serial"; public static final String WECHAT_PAY_SIGNATURE = "Wechatpay-Signature"; public static final String WECHAT_PAY_TIMESTAMP = "Wechatpay-Timestamp"; public static final String WECHAT_PAY_NONCE = "Wechatpay-Nonce"; private static final Gson GSON = new GsonBuilder().create(); @Resource private OrderService orderService; @RequestMapping(value = "/payNotify", method = RequestMethod.POST) @ApiOperation(value = "微信支付通知") public Map payNotify(HttpServletRequest request, HttpServletResponse response) { Config config = new RSAConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .wechatPayCertificatesFromPath(wechatPayCertificatePath) .build(); @Autowired private WxPayService wxService; @Resource private BackMessageService backMessageService; PrivacyEncryptor encryptor = config.createEncryptor(); String wechatPayCertificateSerialNumber = encryptor.getWechatpaySerial(); @PostMapping(value = "/payNotify") @ApiOperation(value = "微信支付/退款通知") public String payNotify(@RequestBody String notifyData, HttpServletRequest request, HttpServletResponse response) throws WxPayException { // 获取请求头 SignatureHeader signatureHeader = getSignatureHeader(response); String nonoc=request.getHeader("Wechatpay-Nonce"); String signature=request.getHeader("Wechatpay-Signature"); String timestamp=request.getHeader("Wechatpay-Timestamp"); String serial=request.getHeader("Wechatpay-Serial"); String signatureType=request.getHeader("Wechatpay-Signature-Type"); NotifyResponse responseData = GSON.fromJson(notifyData, NotifyResponse.class); String eventType = responseData.getEventType(); String requestBody=""; try { BufferedReader reader = request.getReader(); String line = ""; StringBuffer inputString = new StringBuffer(); while ( (line = reader.readLine()) != null ) { inputString.append(line); int resultType = 1; String resultMessage = ""; if(WxPayNotifyEventTypeEnum.TRANSACTION_SUCCESS.getCode().equals(eventType)){ PartnerTransactionsNotifyResult notifyResult = wxService.getEcommerceService().parsePartnerNotifyResult(notifyData, signatureHeader); PartnerTransactionsResult result = notifyResult.getResult(); // 支付通知回调 if("SUCCESS".equals(result.getTradeState())){ orderService.payBack(result); } if(inputString!=null && !"".equals(inputString)) { requestBody = inputString.toString(); resultMessage = GSON.toJson(notifyResult); } else if(WxPayNotifyEventTypeEnum.REFUND_SUCCESS.getCode().equals(eventType) || WxPayNotifyEventTypeEnum.REFUND_ABNORMAL.getCode().equals(eventType) || WxPayNotifyEventTypeEnum.REFUND_CLOSED.getCode().equals(eventType)){ RefundNotifyResult result = wxService.getEcommerceService().parseRefundNotifyResult(notifyData, signatureHeader); orderService.orderRefundBack(result); resultType = 2; resultMessage = GSON.toJson(result); } reader.close(); } catch (IOException e) { e.printStackTrace(); // 保存支付/退款回调信息 backMessageService.saveBackMessage(resultType, resultMessage); return WxPayNotifyV3Response.success("成功"); } RequestParam requestParam = new RequestParam.Builder() .serialNumber(wechatPayCertificateSerialNumber) .nonce(nonoc) .signature(signature) .timestamp(timestamp) .body(requestBody) .build(); @PostMapping(value = "/profitSharingNotify") @ApiOperation(value = "微信分账通知") public String profitSharingNotify(@RequestBody String notifyData, HttpServletRequest request, HttpServletResponse response) throws WxPayException { ProfitSharingV3Service sharingV3Service = wxService.getProfitSharingV3Service(); // ProfitSharingNotifyResult NotificationConfig notifiConfig = new RSAAutoCertificateConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .apiV3Key(apiV3key) .build(); NotificationParser parser = new NotificationParser(notifiConfig); Transaction transaction = parser.parse(requestParam, Transaction.class); // 获取请求头 SignatureHeader signatureHeader = getSignatureHeader(response); String tradeStateEnum=transaction.getTradeState().toString(); if(tradeStateEnum.equals("success")){ orderService.payBack(transaction); ProfitSharingNotifyNewResult notifyResult = getProfitSharingNotifyData(notifyData, signatureHeader); ProfitSharingNotifyResult result = notifyResult.getResult(); String eventType = notifyResult.getRawData().getEventType(); if(WxPayNotifyEventTypeEnum.PROFIT_SHARING_SUCCESS.getCode().equals(eventType)){ // 分账通知回调 orderService.profitSharingBack(result); } Map map=new HashMap(); map.put("code","SUCCESS"); map.put("message","成功"); String resultMessage = GSON.toJson(notifyResult); // 保存记录分账回调信息 backMessageService.saveBackMessage(3, resultMessage); return map; return WxPayNotifyV3Response.success("成功"); } @RequestMapping(value = "/shareNotify", method = RequestMethod.POST) @@ -135,4 +125,49 @@ return null; } public ProfitSharingNotifyNewResult getProfitSharingNotifyData(String notifyData, SignatureHeader header) throws WxPayException { if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) { throw new WxPayException("非法请求,头部信息验证失败"); } ProfitSharingNotifyData response = GSON.fromJson(notifyData, ProfitSharingNotifyData.class); ProfitSharingNotifyData.Resource resource = response.getResource(); String cipherText = resource.getCipherText(); String associatedData = resource.getAssociatedData(); String nonce = resource.getNonce(); String apiV3Key = this.wxService.getConfig().getApiV3Key(); try { String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key); ProfitSharingNotifyResult profitSharingResult = GSON.fromJson(result, ProfitSharingNotifyResult.class); ProfitSharingNotifyNewResult notifyResult = new ProfitSharingNotifyNewResult(); notifyResult.setRawData(response); notifyResult.setResult(profitSharingResult); return notifyResult; } catch (GeneralSecurityException | IOException e) { throw new WxPayException("解析报文异常!", e); } } private boolean verifyNotifySign(SignatureHeader header, String data) throws WxPayException { String beforeSign = String.format("%s\n%s\n%s\n", header.getTimeStamp(), header.getNonce(), data); Verifier verifier = this.wxService.getConfig().getVerifier(); if (verifier == null) { throw new WxPayException("证书检验对象为空"); } return verifier.verify(header.getSerialNo(), beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned()); } private SignatureHeader getSignatureHeader(HttpServletResponse response){ SignatureHeader signatureHeader = new SignatureHeader(); signatureHeader.setSerialNo(response.getHeader(WECHAT_PAY_SERIAL)); signatureHeader.setSigned(response.getHeader(WECHAT_PAY_SIGNATURE)); signatureHeader.setNonce(response.getHeader(WECHAT_PAY_NONCE)); signatureHeader.setTimeStamp(response.getHeader(WECHAT_PAY_TIMESTAMP)); return signatureHeader; } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/account/BackMessage.java
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.activerecord.Model; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.util.Date; import lombok.Data; import lombok.EqualsAndHashCode; @@ -38,7 +39,7 @@ @TableField("del_flag") private String delFlag; /** * 回调类型1支付回调2退款回调 * 回调类型 1支付回调 2退款回调 3、分账 */ @TableField("result_type") private Integer resultType; @@ -47,6 +48,11 @@ */ @TableField("result_message") private String resultMessage; /** * 回调时间 */ @TableField("create_time") private Date createTime; @Override ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/account/OrderPayment.java
@@ -49,6 +49,12 @@ @TableField("shop_id") private Long shopId; /** * 订单二级商户号 */ @TableField("sub_mch_id") private String subMchId; /** * 订单id */ @TableField("order_id") ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/account/OrderRefund.java
@@ -99,7 +99,21 @@ * 回调时间 */ @TableField("back_time") private Date backTime; private String backTime; /** * 微信退款订单id */ @TableField("wx_refund_id") private String wxRefundId; /** * 1、发起退款 2、已退款 */ @TableField("refund_status") private Integer refundStatus; @Override ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/account/PaymentMessage.java
@@ -47,7 +47,7 @@ * 发起关联id */ @TableField("send_id") private Long sendId; private String sendId; /** * 发送报文 */ ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/account/ProfitSharing.java
@@ -93,7 +93,15 @@ * 完成时间 */ @TableField("finish_time") private Date finishTime; private String finishTime; /** * 微信分账/回退单号 */ @TableField("wx_order_id") private String wxOrderId; /** * 分账失败原因 1、ACCOUNT_ABNORMAL : 分账接收账户异常 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/vo/ProfitSharingNotifyNewResult.java
New file @@ -0,0 +1,23 @@ package com.ruoyi.order.domain.vo; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyData; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyResult; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @NoArgsConstructor public class ProfitSharingNotifyNewResult implements Serializable { private static final long serialVersionUID = -6602962275015706689L; /** * 源数据 */ private ProfitSharingNotifyData rawData; /** * 解密后的数据 */ private ProfitSharingNotifyResult result; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/enums/RefundStatusEnum.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.order.enums; import com.ruoyi.order.enums.dict.IDict; public enum RefundStatusEnum implements IDict<Integer> { /** * 退款状态,枚举值: * SUCCESS:退款成功 * CLOSE:退款关闭 * ABNORMAL:退款异常 */ SUCCESS(2, "SUCCESS"), CLOSE(3, "CLOSE"), ABNORMAL(4, "ABNORMAL"); RefundStatusEnum(Integer code, String text){ init(code, text); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/enums/WxPayNotifyEventTypeEnum.java
New file @@ -0,0 +1,22 @@ package com.ruoyi.order.enums; import com.ruoyi.order.enums.dict.IDict; public enum WxPayNotifyEventTypeEnum implements IDict<String> { /** * 微信回调通知 支付成功通知的类型为 TRANSACTION.SUCCESS 分账 PROFITSHARING.SUCCESS */ TRANSACTION_SUCCESS("TRANSACTION.SUCCESS", "TRANSACTION.SUCCESS"), PROFIT_SHARING_SUCCESS("PROFITSHARING.SUCCESS", "PROFITSHARING.SUCCESS"), REFUND_SUCCESS("REFUND.SUCCESS", "REFUND.SUCCESS"), REFUND_ABNORMAL("REFUND.ABNORMAL", "REFUND.ABNORMAL"), REFUND_CLOSED("REFUND.CLOSED", "REFUND.CLOSED"); WxPayNotifyEventTypeEnum(String code, String text){ init(code, text); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/enums/dict/DictBean.java
New file @@ -0,0 +1,15 @@ package com.ruoyi.order.enums.dict; import lombok.Data; /** * 字典bean * 只有code和text,可用于展示下拉框 * * @author luozhan */ @Data public class DictBean<T> implements IDict<T> { private final T code; private final String text; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/enums/dict/IDict.java
New file @@ -0,0 +1,170 @@ package com.ruoyi.order.enums.dict; import java.lang.reflect.Field; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; /** * 字典接口 * <p> * 自定义的字典枚举类实现本接口后可省略属性code和text,以及对应的get方法 * 在构造方法中只需调用init方法即可初始化 * * @author luozhan * @date 2021-12 */ public interface IDict<T> { /** * 通过code获取value * * @param clazz 枚举class * @param code code * @return text */ static <T> String getTextByCode(Class<? extends IDict<T>> clazz, T code) { return Stream.of(clazz.getEnumConstants()) .filter((IDict<T> e) -> e.getCode().equals(code)) .map(IDict::getText) .findAny().orElse(""); } /** * 通过text获取code * * @param clazz 枚举class * @param text text * @return code */ static <T> T getCodeByText(Class<? extends IDict<T>> clazz, String text) { return Stream.of(clazz.getEnumConstants()) .filter((IDict<T> e) -> e.getText().equals(text)) .map(IDict::getCode) .findAny().orElse(null); } /** * 通过code获取字典枚举实例 * * @param clazz 枚举class * @param code code * @param <T> 字典code类型 * @param <R> 枚举类型 * @return 字典枚举实例 */ @SuppressWarnings("unchecked") static <T, R extends IDict<T>> R getByCode(Class<? extends IDict<T>> clazz, T code) { return Stream.of(clazz.getEnumConstants()) .filter((IDict<T> e) -> (e.getCode().equals(code))) .map(v -> (R) v) .findAny() .orElse(null); } /** * 获取给定的字典枚举项(常用下拉框数据请求) * * @param enums 可指定需要哪些项 * @return List */ @SafeVarargs static <T, E extends IDict<T>> List<IDict<T>> getItems(E... enums) { return Stream.of(enums) .map(DictPool::getDict) .collect(Collectors.toList()); } /** * 获取所有字典枚举项,除开指定的枚举 * * @param exclude 指定排除的枚举 * @return List */ @SafeVarargs @SuppressWarnings("unchecked") static <T, E extends IDict<T>> List<IDict<T>> getItemsExclude(E... exclude) { Class<IDict<T>> clazz = (Class<IDict<T>>) exclude.getClass().getComponentType(); IDict<T>[] allEnum = clazz.getEnumConstants(); List<IDict<T>> excludeList = Arrays.asList(exclude); return Stream.of(allEnum) .filter(e -> !excludeList.contains(e)) .map(DictPool::getDict) .collect(Collectors.toList()); } /** * 获取所有字典枚举项(常用下拉框数据请求) * 枚举值上标记@Deprecated的不会返回 * * @param clazz 字典枚举类 * @return List */ static <T> List<IDict<T>> getAll(Class<? extends IDict<T>> clazz) { Map<String, Field> fieldCache = Arrays.stream(clazz.getDeclaredFields()). filter(Field::isEnumConstant). collect(Collectors.toMap(Field::getName, Function.identity())); IDict<T>[] allEnum = clazz.getEnumConstants(); return Stream.of(allEnum) .filter(e -> !fieldCache.get(((Enum<?>) e).name()).isAnnotationPresent(Deprecated.class)) .map(DictPool::getDict) .collect(Collectors.toList()); } /** * 初始化 * * @param code 字典编码 * @param text 字典文本 */ default void init(T code, String text) { DictPool.putDict(this, code, text); } /** * 获取编码 * * @return 编码 */ default T getCode() { return DictPool.getDict(this).getCode(); } /** * 获取文本 * * @return 文本 */ default String getText() { return DictPool.getDict(this).getText(); } @SuppressWarnings("all") class DictPool { private static final Map<IDict, DictBean> DICT_MAP = new ConcurrentHashMap<>(); private static final Map<String, Class<? extends IDict>> DICT_NAME_CLASS_MAP = new ConcurrentHashMap<>(); static <T> void putDict(IDict<T> dict, T code, String text) { DICT_NAME_CLASS_MAP.put(dict.getClass().getName(), dict.getClass()); DICT_MAP.put(dict, new DictBean<>(code, text)); } public static List<IDict<Object>> getDict(String dictName) { Class<? extends IDict> aClass = DICT_NAME_CLASS_MAP.get(dictName); return IDict.getAll((Class<? extends IDict<Object>>) aClass); } static <K extends IDict<T>, T> DictBean<T> getDict(K dict) { return DICT_MAP.get(dict); } } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/account/BackMessageService.java
@@ -13,4 +13,10 @@ */ public interface BackMessageService extends IService<BackMessage> { /** * 保存回调记录 * @param resultType * @param resultMessage */ void saveBackMessage(int resultType, String resultMessage); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/account/OrderPaymentService.java
@@ -28,7 +28,7 @@ * @param goodsNames * @param prepayId */ void saveOrderPayment(Long userId, Long shopId, String orderId, BigDecimal payMoney, Date endTime, String profitSharing, String openid, String goodsNames, String prepayId); void saveOrderPayment(Long userId, Long shopId, String subMchId, String orderId, BigDecimal payMoney, Date endTime, String profitSharing, String openid, String goodsNames, String prepayId); /** * ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/account/PaymentMessageService.java
@@ -20,5 +20,5 @@ * @param sendMessage * @param resultMessage */ void savePaymentMessage(String sendType, Long sendId, String sendMessage, String resultMessage); void savePaymentMessage(String sendType, String sendId, String sendMessage, String resultMessage); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/account/ProfitSharingService.java
@@ -1,7 +1,10 @@ package com.ruoyi.order.service.account; import com.github.binarywang.wxpay.bean.ecommerce.ProfitSharingResult; import com.ruoyi.order.domain.pojo.account.ProfitSharing; import com.baomidou.mybatisplus.extension.service.IService; import java.math.BigDecimal; /** * <p> @@ -13,4 +16,12 @@ */ public interface ProfitSharingService extends IService<ProfitSharing> { /** * 创建按分账记录 * @param shopId * @param orderId * @param orderMoney * @param result */ void saveProfitSharing(Long shopId, String orderId, BigDecimal orderMoney, ProfitSharingResult result); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/account/BackMessageServiceImpl.java
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.Date; /** * <p> * 回调报文 服务实现类 @@ -17,4 +19,13 @@ @Service public class BackMessageServiceImpl extends ServiceImpl<BackMessageMapper, BackMessage> implements BackMessageService { @Override public void saveBackMessage(int resultType, String resultMessage) { BackMessage backMessage = new BackMessage(); backMessage.setDelFlag("0"); backMessage.setResultType(resultType); backMessage.setResultMessage(resultMessage); backMessage.setCreateTime(new Date()); this.saveOrUpdate(backMessage); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/account/OrderPaymentServiceImpl.java
@@ -24,7 +24,7 @@ public class OrderPaymentServiceImpl extends ServiceImpl<OrderPaymentMapper, OrderPayment> implements OrderPaymentService { @Override public void saveOrderPayment(Long userId, Long shopId, String orderId, BigDecimal payMoney, Date endTime, public void saveOrderPayment(Long userId, Long shopId, String subMchId, String orderId, BigDecimal payMoney, Date endTime, String profitSharing, String openid, String goodsNames, String prepayId) { OrderPayment payment = new OrderPayment(); payment.setPaymentId(IdUtils.simpleUUID()); @@ -33,6 +33,7 @@ payment.setOrderId(orderId); payment.setPayMoney(payMoney); payment.setTimeExpire(endTime); payment.setSubMchId(subMchId); // 0 否 1、是 payment.setProfitSharing("Y".equals(profitSharing) ? 1 : 0); payment.setUserOpenId(openid); ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/account/PaymentMessageServiceImpl.java
@@ -20,7 +20,7 @@ public class PaymentMessageServiceImpl extends ServiceImpl<PaymentMessageMapper, PaymentMessage> implements PaymentMessageService { @Override public void savePaymentMessage(String sendType, Long sendId, String sendMessage, String resultMessage) { public void savePaymentMessage(String sendType, String sendId, String sendMessage, String resultMessage) { PaymentMessage paymentMessage = new PaymentMessage(); paymentMessage.setDelFlag("0"); paymentMessage.setSendType(sendType); ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/account/ProfitSharingServiceImpl.java
@@ -1,10 +1,17 @@ package com.ruoyi.order.service.impl.account; import com.github.binarywang.wxpay.bean.ecommerce.ProfitSharingResult; import com.ruoyi.common.core.utils.uuid.IdUtils; import com.ruoyi.order.domain.pojo.account.ProfitSharing; import com.ruoyi.order.mapper.account.ProfitSharingMapper; import com.ruoyi.order.service.account.ProfitSharingService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Date; import java.util.List; /** * <p> @@ -17,4 +24,31 @@ @Service public class ProfitSharingServiceImpl extends ServiceImpl<ProfitSharingMapper, ProfitSharing> implements ProfitSharingService { @Override public void saveProfitSharing(Long shopId, String orderId, BigDecimal orderMoney, ProfitSharingResult result) { ProfitSharing profitSharing = new ProfitSharing(); profitSharing.setShareId(result.getOutOrderNo()); profitSharing.setDelFlag(0); profitSharing.setShareStatus("FINISHED".equals(result.getStatus()) ? 2 : 1); profitSharing.setShopId(shopId); profitSharing.setOrderId(orderId); profitSharing.setOrderMoney(orderMoney); List<ProfitSharingResult.Receiver> receivers = result.getReceivers(); if(null != receivers && !receivers.isEmpty()){ ProfitSharingResult.Receiver receiver = receivers.get(0); profitSharing.setReceiverAccount(receiver.getReceiverMchid()); BigDecimal receiverAmount = new BigDecimal(receiver.getAmount()); receiverAmount = receiverAmount.divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP); profitSharing.setReceiverAmount(receiverAmount); profitSharing.setSurpMoney(orderMoney.subtract(receiverAmount)); profitSharing.setReceiverDescription(receiver.getDescription()); profitSharing.setFinishFlag(0); profitSharing.setFailReason(receiver.getFailReason()); profitSharing.setDetailId(receiver.getDetailId()); } profitSharing.setCreateTime(new Date()); this.saveOrUpdate(profitSharing); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java
@@ -1,16 +1,16 @@ package com.ruoyi.order.service.impl.order; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingReceiver; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingRequest; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.ecommerce.*; import com.github.binarywang.wxpay.bean.ecommerce.ProfitSharingRequest.Receiver; import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.google.common.base.Joiner; @@ -27,14 +27,19 @@ import com.ruoyi.order.domain.dto.*; import com.ruoyi.order.domain.pojo.account.OrderPayment; import com.ruoyi.order.domain.pojo.account.OrderRefund; import com.ruoyi.order.domain.pojo.account.ProfitSharing; import com.ruoyi.order.domain.pojo.order.ConsumerGoods; import com.ruoyi.order.domain.pojo.order.Order; import com.ruoyi.order.domain.pojo.order.OrderGoods; import com.ruoyi.order.domain.pojo.order.PayRecord; import com.ruoyi.order.domain.vo.*; import com.ruoyi.order.enums.RefundStatusEnum; import com.ruoyi.order.enums.dict.IDict; import com.ruoyi.order.mapper.order.OrderMapper; import com.ruoyi.order.service.account.OrderPaymentService; import com.ruoyi.order.service.account.OrderRefundService; import com.ruoyi.order.service.account.PaymentMessageService; import com.ruoyi.order.service.account.ProfitSharingService; import com.ruoyi.order.service.order.*; import com.ruoyi.system.api.constant.AppErrorConstant; import com.ruoyi.system.api.constant.DelayTaskEnum; @@ -53,7 +58,7 @@ import com.ruoyi.system.api.domain.poji.sys.SysUser; import com.ruoyi.system.api.domain.vo.*; import com.ruoyi.system.api.service.*; import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; @@ -62,6 +67,7 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; @@ -78,6 +84,7 @@ * @since 2023-04-25 */ @Service @Slf4j public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService { @Resource @@ -133,6 +140,12 @@ @Resource private OrderPaymentService orderPaymentService; @Resource private ProfitSharingService profitSharingService; @Resource private OrderRefundService orderRefundService; /** * @description: buyGoods @@ -723,57 +736,16 @@ appPlaceOrderVo.setOrderId(orderId); appPlaceOrderVo.setOrderNo(orderNo); try { // 创建支付订单 Long shopId = appPlaceOrderDto.getShopId(); R<String> resultMch = remoteShopService.getShopSubMchId(shopId); String subMchId = resultMch.getData(); if(StringUtils.isEmpty(subMchId)){ throw new ServiceException("获取微信商户号失败"); } WxPayConfig config = wxService.getConfig(); config.setSubMchId(subMchId); WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setTradeType(WxPayConstants.TradeType.JSAPI); request.setSubMchId(subMchId); // 商户订单号 request.setOutTradeNo(orderNo); // 订单总金额 Integer totalFee = order.getPayMoney().multiply(new BigDecimal(100)).intValue(); request.setTotalFee(totalFee); request.setProductId(orderNo); request.setNotifyUrl(config.getNotifyUrl()); request.setProfitSharing("Y"); request.setOpenid(appPlaceOrderDto.getOpenid()); request.setSpbillCreateIp(appPlaceOrderDto.getSpbillCreateIp()); // 商品描述 body String body = "商品购买"; String goodsName = ""; if(null != goods){ body = goods.getGoodsName() + "-" + body; goodsName = goods.getGoodsName(); } request.setBody(body); request.checkAndSign(config); // 小程序微信下单支付 createWxPayInfo(appPlaceOrderVo, userId, order.getShopId(), goodsName, orderNo, orderId, order.getPayMoney(), appPlaceOrderDto.getOpenid(), appPlaceOrderDto.getSpbillCreateIp(), goodsNameList); // 请求参数 Gson gson = new Gson(); String payRequestJson = gson.toJson(request); WxPayMpOrderResult result = wxService.createOrder(request); String payResponseJson = gson.toJson(request); // 支付相关信息返回 appPlaceOrderVo.setAppId(result.getAppId()); appPlaceOrderVo.setMchId(config.getMchId()); appPlaceOrderVo.setTimeStamp(result.getTimeStamp()); appPlaceOrderVo.setNonceStr(result.getNonceStr()); appPlaceOrderVo.setPackageStr(result.getPackageValue()); appPlaceOrderVo.setSignType(result.getSignType()); appPlaceOrderVo.setPaySign(result.getPaySign()); appPlaceOrderVo.setPrepayId(result.getPackageValue()); //减去优惠券 if(StringUtils.isNotBlank(memberCouponSJ.toString())){ @@ -793,16 +765,94 @@ remoteConfigService.addDelayTask(delayTask); appPlaceOrderVo.setEndTime(DateUtils.addMinutes(order.getCreateTime(),delayTime)); return appPlaceOrderVo; } /** * 小程序支付下单API * @param appPlaceOrderVo * @param userId * @param shopId * @param goodsName * @param orderNo * @param orderId * @param payMoney * @param openid * @param payerClientIp * @param goodsNameList */ private void createWxPayInfo(AppPlaceOrderVo appPlaceOrderVo, Long userId, Long shopId, String goodsName, String orderNo, String orderId, BigDecimal payMoney, String openid, String payerClientIp, List<String> goodsNameList){ try { // 创建支付订单 R<String> resultMch = remoteShopService.getShopSubMchId(shopId); String subMchId = resultMch.getData(); if (StringUtils.isEmpty(subMchId)) { throw new ServiceException("获取微信商户号失败"); } WxPayConfig config = wxService.getConfig(); config.setSubMchId(subMchId); PartnerTransactionsRequest request = new PartnerTransactionsRequest(); request.setSpAppid(config.getAppId()); request.setSpMchid(config.getMchId()); request.setSubMchid(config.getSubMchId()); // 商品描述 body String description = goodsName + "-商品购买"; request.setDescription(description); request.setOutTradeNo(orderNo); request.setNotifyUrl(config.getNotifyUrl()); // 结算信息 PartnerTransactionsRequest.SettleInfo settleInfo = new PartnerTransactionsRequest.SettleInfo(); settleInfo.setProfitSharing(true); settleInfo.setSubsidyAmount(BigDecimal.ZERO); request.setSettleInfo(settleInfo); // 订单总金额 Integer totalFee = payMoney.multiply(new BigDecimal(100)).intValue(); PartnerTransactionsRequest.Amount amount = new PartnerTransactionsRequest.Amount(); amount.setTotal(totalFee); amount.setCurrency("CNY"); request.setAmount(amount); // 支付者 PartnerTransactionsRequest.Payer payer = new PartnerTransactionsRequest.Payer(); payer.setSpOpenid(openid); request.setPayer(payer); // 场景信息 PartnerTransactionsRequest.SceneInfo sceneInfo = new PartnerTransactionsRequest.SceneInfo(); sceneInfo.setPayerClientIp(payerClientIp); request.setSceneInfo(sceneInfo); TransactionsResult.JsapiResult result = wxService.getEcommerceService().partnerTransactions(TradeTypeEnum.JSAPI, request); // 请求参数 Gson gson = new Gson(); String payRequestJson = gson.toJson(request); // 返回参数 String payResponseJson = gson.toJson(result); // 支付相关信息返回 appPlaceOrderVo.setAppId(result.getAppId()); appPlaceOrderVo.setMchId(config.getMchId()); appPlaceOrderVo.setTimeStamp(result.getTimeStamp()); appPlaceOrderVo.setNonceStr(result.getNonceStr()); appPlaceOrderVo.setPackageStr(result.getPackageValue()); appPlaceOrderVo.setSignType(result.getSignType()); appPlaceOrderVo.setPaySign(result.getPaySign()); appPlaceOrderVo.setPrepayId(result.getPackageValue()); // 保存支付订单统一下单日志 paymentMessageService.savePaymentMessage("1", 0L, payRequestJson, payResponseJson); paymentMessageService.savePaymentMessage("1", orderId, payRequestJson, payResponseJson); // 保存支付订单统一下单支付记录 orderPaymentService.saveOrderPayment(userId, shopId, orderId, order.getPayMoney(), appPlaceOrderVo.getEndTime(), "Y", appPlaceOrderDto.getOpenid(), orderPaymentService.saveOrderPayment(userId, shopId, subMchId, orderId, payMoney, appPlaceOrderVo.getEndTime(), "Y", openid, Joiner.on(";").join(goodsNameList),result.getPackageValue()); return appPlaceOrderVo; } catch (WxPayException e){ throw new ServiceException(e.getMessage()); } @@ -1189,11 +1239,13 @@ @Override public void cancelOrder(String orderId) { Order order = this.getById(orderId); // 订单状态-1.删除 0.已取消 1.待支付 2.待核销 3.已完成 if (order.getOrderStatus() == 0) { throw new ServiceException(AppErrorConstant.CANCEL_CANCEL_ORDER); }else if (order.getOrderStatus() == 1) { this.autoCancelOrder(orderId); }else if(order.getOrderStatus() == 2){ // 2.待核销 -> 订单退款 this.refundOrder(orderId); }else{ throw new ServiceException(AppErrorConstant.CANCEL_ERROR_ORDER); @@ -1417,38 +1469,85 @@ payRecord.setPayType(2); payRecordService.save(payRecord); submitProfitSharing(orderId, order.getOrderNo(), order.getShopId(), order.getOrderMoney()); return merVerifyOrderVo; } private void submitProfitSharing(String orderId, String orderNo, Long shopId, BigDecimal orderMoney) { String sendMessage = ""; String resultMessage = ""; try { // TODO 核销完成 开始分账(平台收取服务费) OrderPayment payment = orderPaymentService.getByOrderId(orderId); String transactionId = payment.getTransactionId(); String platformTyMacId = MyWxPayConfig.getPlatformTyMacId(); R<String> resultMch = remoteShopService.getShopSubMchId(order.getShopId()); R<String> resultMch = remoteShopService.getShopSubMchId(shopId); String subMchId = resultMch.getData(); if(StringUtils.isEmpty(subMchId)){ throw new ServiceException("获取微信商户号失败"); } if (!StringUtils.isEmpty(subMchId)) { R<ShopProportionVo> resultShopProportion = remoteShopService.getShopProportion(order.getShopId()); R<ShopProportionVo> resultShopProportion = remoteShopService.getShopProportion(shopId); ShopProportionVo shopProportion = resultShopProportion.getData(); if(null == shopProportion){ throw new ServiceException("获取商户分成失败"); if (null != shopProportion) { ProfitSharingRequest request = new ProfitSharingRequest(); request.setSubMchid(subMchId); request.setTransactionId(transactionId); request.setOutOrderNo(orderNo); List<Receiver> receiverList = new ArrayList<>(); String description = "订单:" + orderNo + " 平台抽取佣金"; BigDecimal proportionPercent = shopProportion.getProportionPercent(); if (null == proportionPercent) { proportionPercent = BigDecimal.ZERO; } ProfitSharingRequest request = new ProfitSharingRequest(); request.setSubMchId(subMchId); request.setTransactionId(transactionId); request.setOutOrderNo(order.getOrderNo()); List<ProfitSharingReceiver> receiverList = new ArrayList<>(); ProfitSharingReceiver receiver = new ProfitSharingReceiver(); // TODO 分账 // receiver.set // request.setReceivers(); ProfitSharingResult result = new ProfitSharingResult(); result.setOutOrderNo(orderNo); result.setStatus("FINISHED"); // platformTyMacId // wxService.getProfitSharingV3Service().profitSharing() // 计算分成金额 int amount = orderMoney.multiply(proportionPercent).setScale(0, RoundingMode.UP).intValue(); log.info("订单分账:{} 分账金额: {}", orderNo, amount); if (amount > 0) { // 分账创建 Receiver receiver = new Receiver(); receiver.setType("MERCHANT_ID"); receiver.setReceiverAccount(platformTyMacId); receiver.setAmount(amount); receiver.setDescription(description); return merVerifyOrderVo; receiverList.add(receiver); request.setReceivers(receiverList); // 分账完成 request.setFinish(true); result = wxService.getEcommerceService().profitSharing(request); } // 创建分账记录 profitSharingService.saveProfitSharing(shopId, orderId, orderMoney, result); // 保存请求信息 sendMessage = JSONObject.toJSONString(request); resultMessage = JSONObject.toJSONString(result); } else { resultMessage = String.format("订单分账:%s 获取商户分成失败", orderNo); log.info(resultMessage); } } else { resultMessage = String.format("订单分账:%s 获取微信商户号失败", orderNo); log.info(resultMessage); } } catch (WxPayException e) { resultMessage = String.format("订单分账:%s 分账失败:%s", orderNo, e.getMessage()); log.info(resultMessage); e.printStackTrace(); } // 保存分账信息 paymentMessageService.savePaymentMessage("4", orderId, sendMessage, resultMessage); } /** @@ -1546,11 +1645,11 @@ /** * @param merVerifyPrizeDto * @return MerVerifyAwardVo * @description 确认核销奖品 * @author jqs * @date 2023/7/9 9:54 * @param merVerifyPrizeDto * @return MerVerifyAwardVo */ @Override @Transactional @@ -3048,12 +3147,12 @@ } /** * @description 获取核销奖品 * @author jqs * @date 2023/7/8 17:46 * @param verifyCode * @param shopId * @return MerVerifyAwardVo * @description 获取核销奖品 * @author jqs * @date 2023/7/8 17:46 */ @Override public MerVerifyAwardVo verifyPrize(String verifyCode,Long shopId){ @@ -3335,11 +3434,11 @@ } /** * @param merOrderPageDto * @return MerTotalOrderVo * @description 商户端订单管理统计 * @author jqs * @date 2023/7/31 10:53 * @param merOrderPageDto * @return MerTotalOrderVo */ @Override public MerTotalOrderVo totalMerOrder(MerOrderPageDto merOrderPageDto) { @@ -3419,11 +3518,11 @@ } /** * @param orderId * @return void * @description 自动取消订单 * @author jqs * @date 2023/7/13 17:15 * @param orderId * @return void */ @Override @Transactional @@ -3485,15 +3584,15 @@ } /** * @param transaction * @return void * @description 订单支付回调 * @author jqs * @date 2023/7/13 17:57 * @param transaction * @return void */ @Override @Transactional public void payBack(Transaction transaction) { public void payBack(PartnerTransactionsResult transaction) { // 更新订单状态 String orderId=transaction.getOutTradeNo(); Order order = this.getById(orderId); @@ -3623,11 +3722,11 @@ } /** * @param orderId * @return void * @description 订单退款 * @author jqs * @date 2023/7/13 18:36 * @param orderId * @return void */ @Override @Transactional @@ -3645,7 +3744,7 @@ orderRefund.setOrderId(order.getOrderId()); orderRefund.setUserId(order.getUserId()); orderRefund.setShopId(order.getShopId()); orderRefund.setRefundMoney(order.getPayMoney()); orderRefund.setRefundMoney(order.getOnlinePayMoney()); orderRefund.setOrderMoney(order.getPayMoney()); orderRefund.setCreateTime(new Date()); // 初始化各类商品的收款金额 @@ -3774,14 +3873,68 @@ activityTotalChangeDto.setUserId(order.getUserId()); remoteActivityService.changeActivityTotal(activityTotalChangeDto); } // 用户取消订单退款 BigDecimal onlinePayMoney = order.getOnlinePayMoney(); if(BigDecimal.ZERO.compareTo(onlinePayMoney) < 0){ // 订单支付金额大于0,可发起退款 orderWxApplyRefund(orderId, refundId, onlinePayMoney, orderRefund); } orderRefund.setRefundStatus(1); orderRefundService.saveOrUpdate(orderRefund); } /** * 申请退款API */ private void orderWxApplyRefund(String orderId, String outRefundNo, BigDecimal payMoney, OrderRefund orderRefund){ try { // 创建支付订单 OrderPayment orderPayment = orderPaymentService.getByOrderId(orderId); if (null == orderPayment) { return; } String subMchId = orderPayment.getSubMchId(); WxPayConfig config = wxService.getConfig(); RefundsRequest request = new RefundsRequest(); request.setSpAppid(config.getAppId()); request.setSubMchid(subMchId); request.setTransactionId(orderPayment.getTransactionId()); request.setOutRefundNo(outRefundNo); request.setReason("用户取消订单"); // 订单金额 int total = payMoney.multiply(new BigDecimal(100)).intValue(); RefundsRequest.Amount amount = RefundsRequest.Amount.builder().refund(total).total(total).currency("CNY").build(); request.setAmount(amount); request.setNotifyUrl(config.getNotifyUrl()); RefundsResult result = wxService.getEcommerceService().refunds(request); // 微信退款id orderRefund.setWxRefundId(result.getRefundId()); // 请求参数 Gson gson = new Gson(); String refundRequestJson = gson.toJson(request); // 返回参数 String refundResponseJson = gson.toJson(result); // 保存支付订单统一下单日志 paymentMessageService.savePaymentMessage("3", orderId, refundRequestJson, refundResponseJson); } catch (WxPayException e) { throw new ServiceException(e.getMessage()); } } /** * @param staffTotalDto * @return StaffActivityOrderTotalVo * @description 员工端活动订单统计 * @author jqs * @date 2023/7/17 15:25 * @param staffTotalDto * @return StaffActivityOrderTotalVo */ @Override public StaffActivityOrderTotalVo getStaffActivityOrderTotal(StaffTotalDto staffTotalDto){ @@ -3790,11 +3943,11 @@ } /** * @param staffTotalDto * @return StaffActivityTotalVo * @description 员工端活动统计 * @author jqs * @date 2023/7/17 15:51 * @param staffTotalDto * @return StaffActivityTotalVo */ @Override public StaffActivityTotalVo getStaffActivityTotal(StaffTotalDto staffTotalDto){ @@ -3803,11 +3956,11 @@ } /** * @param staffTotalDto * @return MerOrderDistributionTotalVo * @description 员工端活动统计订单分布 * @author jqs * @date 2023/7/17 16:16 * @param staffTotalDto * @return MerOrderDistributionTotalVo */ @Override public MerOrderDistributionTotalVo getStaffOrderDistributionTotal(StaffTotalDto staffTotalDto){ @@ -3870,11 +4023,11 @@ /** * @param staffTotalDto * @return MerOrderTypeTotalVo * @description 员工端活动统计销售占比 * @author jqs * @date 2023/7/17 17:03 * @param staffTotalDto * @return MerOrderTypeTotalVo */ @Override public MerOrderTypeTotalVo getStaffOrderTypeTotal(StaffTotalDto staffTotalDto){ @@ -3915,11 +4068,11 @@ } /** * @param staffTotalDto * @return StaffActivityDateMemberTotalVo * @description 员工端获客人数 * @author jqs * @date 2023/7/17 18:42 * @param staffTotalDto * @return StaffActivityDateMemberTotalVo */ @Override public StaffActivityDateMemberTotalVo getStaffActivityGetMemberTotal(StaffTotalDto staffTotalDto) { @@ -3956,11 +4109,11 @@ } /** * @param staffTotalDto * @return StaffActivityDateMemberTotalVo * @description 员工端获客人数 * @author jqs * @date 2023/7/17 18:42 * @param staffTotalDto * @return StaffActivityDateMemberTotalVo */ @Override public StaffActivityDateMemberTotalVo getStaffActivityMemberTotal(StaffTotalDto staffTotalDto) { @@ -3997,12 +4150,12 @@ } /** * @description 获取时间段日期 * @author jqs * @date 2023/7/17 19:11 * @param startDate * @param endDate * @return List<String> * @description 获取时间段日期 * @author jqs * @date 2023/7/17 19:11 */ public static List<String> getDateRange(String startDate, String endDate) { List<String> dateList = new ArrayList<>(); @@ -4016,11 +4169,11 @@ } /** * @param * @return void * @description 检查订单状态定时任务 * @author jqs * @date 2023/7/25 14:40 * @param * @return void */ @Override public void checkOrderStatus(){ @@ -4042,6 +4195,43 @@ } } @Override public void profitSharingBack(ProfitSharingNotifyResult result) { try { String outOrderNo = result.getOutOrderNo(); ProfitSharing profitSharing = profitSharingService.getById(outOrderNo); if(null != profitSharing){ profitSharing.setWxOrderId(result.getOrderId()); profitSharing.setFinishTime(result.getSuccessTime()); profitSharing.setFinishFlag(1); profitSharingService.saveOrUpdate(profitSharing); } } catch (Exception e){ log.error("==分账回成功回调操作====【{}】========={}", result.getOutOrderNo(), e.getMessage()); } } @Override public void orderRefundBack(RefundNotifyResult result) { try { String outRefundNo = result.getOutRefundNo(); String refundStatus = result.getRefundStatus(); OrderRefund orderRefund = orderRefundService.getById(outRefundNo); if(null != orderRefund){ orderRefund.setWxRefundId(result.getRefundId()); orderRefund.setBackTime(result.getSuccessTime()); orderRefund.setRefundStatus(IDict.getCodeByText(RefundStatusEnum.class, refundStatus)); orderRefundService.saveOrUpdate(orderRefund); } } catch (Exception e){ log.error("==退款回成功回调操作====【{}】========={}", result.getOutRefundNo(), e.getMessage()); } } private void autoTimeCancelOrder(Order order){ String orderId = order.getOrderId(); order.setOrderStatus(0); ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/order/OrderService.java
@@ -2,6 +2,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.github.binarywang.wxpay.bean.ecommerce.PartnerTransactionsResult; import com.github.binarywang.wxpay.bean.ecommerce.RefundNotifyResult; import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyResult; import com.ruoyi.order.domain.dto.*; import com.ruoyi.order.domain.pojo.order.Order; import com.ruoyi.order.domain.vo.*; @@ -416,7 +419,7 @@ * @param Transaction transaction * @return void */ void payBack(Transaction transaction); void payBack(PartnerTransactionsResult transaction); /** * 取消订单 @@ -489,4 +492,16 @@ * @return void */ void checkOrderStatus(); /** * 分账通知回调 * @param result */ void profitSharingBack(ProfitSharingNotifyResult result); /** * 订单退款回调 * @param result */ void orderRefundBack(RefundNotifyResult result); }