Commit 44548ee03f573dbb70381767481147ad5a155491

Authored by YunaiV
1 parent fd8567f0

feat:【MALL 商城】商城分佣提现,完成对微信转账(小程序)的对接

yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java
... ... @@ -31,6 +31,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi
31 31 @Validated
32 32 @Slf4j
33 33 public class AppBrokerageRecordController {
  34 +
34 35 @Resource
35 36 private BrokerageRecordService brokerageRecordService;
36 37  
... ... @@ -49,4 +50,4 @@ public class AppBrokerageRecordController {
49 50 return success(brokerageRecordService.calculateProductBrokeragePrice(getLoginUserId(), spuId));
50 51 }
51 52  
52 53 -}
  54 +}
53 55 \ No newline at end of file
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/transfer/AppPayTransferController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.app.transfer;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService;
  5 +import io.swagger.v3.oas.annotations.Operation;
  6 +import io.swagger.v3.oas.annotations.Parameter;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
  8 +import jakarta.annotation.Resource;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.springframework.validation.annotation.Validated;
  11 +import org.springframework.web.bind.annotation.GetMapping;
  12 +import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RequestParam;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +
  16 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  17 +
  18 +@Tag(name = "用户 APP - 转账单")
  19 +@RestController
  20 +@RequestMapping("/pay/transfer")
  21 +@Validated
  22 +@Slf4j
  23 +public class AppPayTransferController {
  24 +
  25 + @Resource
  26 + private PayTransferService transferService;
  27 +
  28 + @GetMapping("/sync")
  29 + @Operation(summary = "同步转账单") // 目的:解决微信转账的异步回调可能有延迟的问题
  30 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  31 + public CommonResult<Boolean> syncTransfer(@RequestParam("id") Long id) {
  32 + transferService.syncTransfer(id);
  33 + return success(true);
  34 + }
  35 +
  36 +}
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
... ... @@ -140,7 +140,7 @@ public class PayOrderServiceImpl implements PayOrderService {
140 140 PayOrderDO order = validateOrderCanSubmit(reqVO.getId());
141 141 // 1.32 校验支付渠道是否有效
142 142 PayChannelDO channel = validateChannelCanSubmit(order.getAppId(), reqVO.getChannelCode());
143   - PayClient client = channelService.getPayClient(channel.getId());
  143 + PayClient<?> client = channelService.getPayClient(channel.getId());
144 144  
145 145 // 2. 插入 PayOrderExtensionDO
146 146 String no = noRedisDAO.generate(payProperties.getOrderNoPrefix());
... ... @@ -237,7 +237,7 @@ public class PayOrderServiceImpl implements PayOrderService {
237 237 appService.validPayApp(appId);
238 238 // 校验支付渠道是否有效
239 239 PayChannelDO channel = channelService.validPayChannel(appId, channelCode);
240   - PayClient client = channelService.getPayClient(channel.getId());
  240 + PayClient<?> client = channelService.getPayClient(channel.getId());
241 241 if (client == null) {
242 242 log.error("[validatePayChannelCanSubmit][渠道编号({}) 找不到对应的支付客户端]", channel.getId());
243 243 throw exception(CHANNEL_NOT_FOUND);
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java
... ... @@ -98,7 +98,7 @@ public class PayRefundServiceImpl implements PayRefundService {
98 98 PayOrderDO order = validatePayOrderCanRefund(reqDTO, app.getId());
99 99 // 1.3 校验支付渠道是否有效
100 100 PayChannelDO channel = channelService.validPayChannel(order.getChannelId());
101   - PayClient client = channelService.getPayClient(channel.getId());
  101 + PayClient<?> client = channelService.getPayClient(channel.getId());
102 102 if (client == null) {
103 103 log.error("[refund][渠道编号({}) 找不到对应的支付客户端]", channel.getId());
104 104 throw exception(CHANNEL_NOT_FOUND);
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java
... ... @@ -53,6 +53,13 @@ public interface PayTransferService {
53 53 int syncTransfer();
54 54  
55 55 /**
  56 + * 【单个】同步渠道转账单状态
  57 + *
  58 + * @param id 转账单编号
  59 + */
  60 + void syncTransfer(Long id);
  61 +
  62 + /**
56 63 * 渠道的转账通知
57 64 *
58 65 * @param channelId 渠道编号
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java
... ... @@ -68,7 +68,7 @@ public class PayTransferServiceImpl implements PayTransferService {
68 68 PayAppDO payApp = appService.validPayApp(reqDTO.getAppKey());
69 69 // 1.2 校验支付渠道是否有效
70 70 PayChannelDO channel = channelService.validPayChannel(payApp.getId(), reqDTO.getChannelCode());
71   - PayClient client = channelService.getPayClient(channel.getId());
  71 + PayClient<?> client = channelService.getPayClient(channel.getId());
72 72 if (client == null) {
73 73 log.error("[createTransfer][渠道编号({}) 找不到对应的支付客户端]", channel.getId());
74 74 throw exception(CHANNEL_NOT_FOUND);
... ... @@ -273,10 +273,19 @@ public class PayTransferServiceImpl implements PayTransferService {
273 273 return count;
274 274 }
275 275  
  276 + @Override
  277 + public void syncTransfer(Long id) {
  278 + PayTransferDO transfer = transferMapper.selectById(id);
  279 + if (transfer == null) {
  280 + throw exception(PAY_TRANSFER_NOT_FOUND);
  281 + }
  282 + syncTransfer(transfer);
  283 + }
  284 +
276 285 private boolean syncTransfer(PayTransferDO transfer) {
277 286 try {
278 287 // 1. 查询转账订单信息
279   - PayClient payClient = channelService.getPayClient(transfer.getChannelId());
  288 + PayClient<?> payClient = channelService.getPayClient(transfer.getChannelId());
280 289 if (payClient == null) {
281 290 log.error("[syncTransfer][渠道编号({}) 找不到对应的支付客户端]", transfer.getChannelId());
282 291 return false;
... ...
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java
... ... @@ -311,7 +311,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
311 311 .thenReturn(mockClient);
312 312  
313 313 // 调用
314   - PayClient client = channelService.getPayClient(id);
  314 + PayClient<?> client = channelService.getPayClient(id);
315 315 // 断言
316 316 assertSame(client, mockClient);
317 317 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
... ... @@ -350,7 +350,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
350 350 when(channelService.validPayChannel(eq(1L), eq(PayChannelEnum.ALIPAY_APP.getCode())))
351 351 .thenReturn(channel);
352 352 // mock 方法(client)
353   - PayClient client = mock(PayClient.class);
  353 + PayClient<?> client = mock(PayClient.class);
354 354 when(channelService.getPayClient(eq(10L))).thenReturn(client);
355 355 // mock 方法()
356 356 PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o ->
... ... @@ -404,7 +404,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
404 404 when(channelService.validPayChannel(eq(1L), eq(PayChannelEnum.ALIPAY_APP.getCode())))
405 405 .thenReturn(channel);
406 406 // mock 方法(client)
407   - PayClient client = mock(PayClient.class);
  407 + PayClient<?> client = mock(PayClient.class);
408 408 when(channelService.getPayClient(eq(10L))).thenReturn(client);
409 409 // mock 方法(支付渠道的调用)
410 410 PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> o.setChannelErrorCode(null).setChannelErrorMsg(null)
... ... @@ -462,7 +462,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
462 462 o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.WAITING.getStatus()));
463 463 orderExtensionMapper.insert(orderExtension);
464 464 // mock 方法(PayClient 已支付)
465   - PayClient client = mock(PayClient.class);
  465 + PayClient<?> client = mock(PayClient.class);
466 466 when(channelService.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client);
467 467 when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class,
468 468 o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())));
... ... @@ -481,7 +481,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
481 481 o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.WAITING.getStatus()));
482 482 orderExtensionMapper.insert(orderExtension);
483 483 // mock 方法(PayClient 已支付)
484   - PayClient client = mock(PayClient.class);
  484 + PayClient<?> client = mock(PayClient.class);
485 485 when(channelService.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client);
486 486 when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class,
487 487 o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
... ... @@ -873,7 +873,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
873 873 .setCreateTime(LocalDateTime.now()));
874 874 orderExtensionMapper.insert(orderExtension);
875 875 // mock 方法(PayClient)
876   - PayClient client = mock(PayClient.class);
  876 + PayClient<?> client = mock(PayClient.class);
877 877 when(channelService.getPayClient(eq(10L))).thenReturn(client);
878 878 // mock 方法(PayClient 异常)
879 879 when(client.getOrder(any())).thenThrow(new RuntimeException());
... ... @@ -900,7 +900,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
900 900 .setCreateTime(LocalDateTime.now()));
901 901 orderExtensionMapper.insert(orderExtension);
902 902 // mock 方法(PayClient)
903   - PayClient client = mock(PayClient.class);
  903 + PayClient<?> client = mock(PayClient.class);
904 904 when(channelService.getPayClient(eq(10L))).thenReturn(client);
905 905 // mock 方法(PayClient 成功返回)
906 906 PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class,
... ... @@ -934,7 +934,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
934 934 .setCreateTime(LocalDateTime.now()));
935 935 orderExtensionMapper.insert(orderExtension);
936 936 // mock 方法(PayClient)
937   - PayClient client = mock(PayClient.class);
  937 + PayClient<?> client = mock(PayClient.class);
938 938 when(channelService.getPayClient(eq(10L))).thenReturn(client);
939 939 // mock 方法(PayClient 成功返回)
940 940 PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class,
... ... @@ -965,7 +965,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
965 965 .setOrderId(order.getId()));
966 966 orderExtensionMapper.insert(orderExtension);
967 967 // mock 方法(PayClient)
968   - PayClient client = mock(PayClient.class);
  968 + PayClient<?> client = mock(PayClient.class);
969 969 when(channelService.getPayClient(eq(10L))).thenReturn(client);
970 970  
971 971 // 调用
... ... @@ -1012,7 +1012,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
1012 1012 .setChannelId(10L));
1013 1013 orderExtensionMapper.insert(orderExtension);
1014 1014 // mock 方法(PayClient)
1015   - PayClient client = mock(PayClient.class);
  1015 + PayClient<?> client = mock(PayClient.class);
1016 1016 when(channelService.getPayClient(eq(10L))).thenReturn(client);
1017 1017 // mock 方法(PayClient 退款返回)
1018 1018 PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class,
... ... @@ -1046,7 +1046,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
1046 1046 .setChannelId(10L));
1047 1047 orderExtensionMapper.insert(orderExtension);
1048 1048 // mock 方法(PayClient)
1049   - PayClient client = mock(PayClient.class);
  1049 + PayClient<?> client = mock(PayClient.class);
1050 1050 when(channelService.getPayClient(eq(10L))).thenReturn(client);
1051 1051 // mock 方法(PayClient 成功返回)
1052 1052 PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class,
... ... @@ -1080,7 +1080,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
1080 1080 .setChannelId(10L));
1081 1081 orderExtensionMapper.insert(orderExtension);
1082 1082 // mock 方法(PayClient)
1083   - PayClient client = mock(PayClient.class);
  1083 + PayClient<?> client = mock(PayClient.class);
1084 1084 when(channelService.getPayClient(eq(10L))).thenReturn(client);
1085 1085 // mock 方法(PayClient 关闭返回)
1086 1086 PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class,
... ...
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java
... ... @@ -331,7 +331,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
331 331 .setCode(PayChannelEnum.ALIPAY_APP.getCode()));
332 332 when(channelService.validPayChannel(eq(1L))).thenReturn(channel);
333 333 // mock 方法(client)
334   - PayClient client = mock(PayClient.class);
  334 + PayClient<?> client = mock(PayClient.class);
335 335 when(channelService.getPayClient(eq(10L))).thenReturn(client);
336 336 // mock 数据(refund 已存在)
337 337 PayRefundDO refund = randomPojo(PayRefundDO.class, o ->
... ... @@ -363,7 +363,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
363 363 .setCode(PayChannelEnum.ALIPAY_APP.getCode()));
364 364 when(channelService.validPayChannel(eq(10L))).thenReturn(channel);
365 365 // mock 方法(client)
366   - PayClient client = mock(PayClient.class);
  366 + PayClient<?> client = mock(PayClient.class);
367 367 when(channelService.getPayClient(eq(10L))).thenReturn(client);
368 368 // mock 方法(client 调用发生异常)
369 369 when(client.unifiedRefund(any(PayRefundUnifiedReqDTO.class))).thenThrow(new RuntimeException());
... ... @@ -407,7 +407,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
407 407 .setCode(PayChannelEnum.ALIPAY_APP.getCode()));
408 408 when(channelService.validPayChannel(eq(10L))).thenReturn(channel);
409 409 // mock 方法(client)
410   - PayClient client = mock(PayClient.class);
  410 + PayClient<?> client = mock(PayClient.class);
411 411 when(channelService.getPayClient(eq(10L))).thenReturn(client);
412 412 // mock 方法(client 成功)
413 413 PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class);
... ... @@ -664,7 +664,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
664 664 .setOrderNo("P110").setNo("R220"));
665 665 refundMapper.insert(refund);
666 666 // mock 方法(client)
667   - PayClient client = mock(PayClient.class);
  667 + PayClient<?> client = mock(PayClient.class);
668 668 when(channelService.getPayClient(eq(10L))).thenReturn(client);
669 669 // mock 方法(client 返回指定状态)
670 670 PayRefundRespDTO respDTO = randomPojo(PayRefundRespDTO.class, o -> o.setStatus(status));
... ... @@ -686,7 +686,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
686 686 .setOrderNo("P110").setNo("R220"));
687 687 refundMapper.insert(refund);
688 688 // mock 方法(client)
689   - PayClient client = mock(PayClient.class);
  689 + PayClient<?> client = mock(PayClient.class);
690 690 when(channelService.getPayClient(eq(10L))).thenReturn(client);
691 691 // mock 方法(client 抛出异常)
692 692 when(client.getRefund(eq("P110"), eq("R220"))).thenThrow(new RuntimeException());
... ...
yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java
... ... @@ -42,7 +42,7 @@ public class PayClientFactoryImplIntegrationTest {
42 42 // 创建客户端
43 43 Long channelId = RandomUtil.randomLong();
44 44 payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.WX_PUB.getCode(), config);
45   - PayClient client = payClientFactory.getPayClient(channelId);
  45 + PayClient<?> client = payClientFactory.getPayClient(channelId);
46 46 // 发起支付
47 47 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
48 48 // CommonResult<?> result = client.unifiedOrder(reqDTO);
... ... @@ -65,7 +65,7 @@ public class PayClientFactoryImplIntegrationTest {
65 65 // 创建客户端
66 66 Long channelId = RandomUtil.randomLong();
67 67 payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.WX_PUB.getCode(), config);
68   - PayClient client = payClientFactory.getPayClient(channelId);
  68 + PayClient<?> client = payClientFactory.getPayClient(channelId);
69 69 // 发起支付
70 70 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
71 71 // CommonResult<?> result = client.unifiedOrder(reqDTO);
... ... @@ -88,7 +88,7 @@ public class PayClientFactoryImplIntegrationTest {
88 88 // 创建客户端
89 89 Long channelId = RandomUtil.randomLong();
90 90 payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config);
91   - PayClient client = payClientFactory.getPayClient(channelId);
  91 + PayClient<?> client = payClientFactory.getPayClient(channelId);
92 92 // 发起支付
93 93 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
94 94 reqDTO.setNotifyUrl("http://yunai.natapp1.cc/admin-api/pay/notify/callback/18"); // TODO @tina: 这里改成你的 natapp 回调地址
... ... @@ -112,7 +112,7 @@ public class PayClientFactoryImplIntegrationTest {
112 112 // 创建客户端
113 113 Long channelId = RandomUtil.randomLong();
114 114 payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config);
115   - PayClient client = payClientFactory.getPayClient(channelId);
  115 + PayClient<?> client = payClientFactory.getPayClient(channelId);
116 116 // 发起支付
117 117 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO();
118 118 // CommonResult<?> result = client.unifiedOrder(reqDTO);
... ...