初始化
This commit is contained in:
139
doc/接口设计/4. 订单设计-支付.md
Normal file
139
doc/接口设计/4. 订单设计-支付.md
Normal file
@@ -0,0 +1,139 @@
|
||||
> 我们的支付时不允许在订单的支付接口传订单金额的,所以我们采用了订单号进行支付的形式
|
||||
|
||||
## 支付
|
||||
|
||||
我们来到`PayController` ,这里就是统一支付的接口,当然这里的统一支付采用的是模拟支付。
|
||||
|
||||
我们直接看一下核心代码:
|
||||
|
||||
```java
|
||||
PayInfoDto payInfo = payService.pay(userId, payParam);
|
||||
```
|
||||
|
||||
再看看里面的代码:
|
||||
|
||||
```java
|
||||
// 修改订单信息
|
||||
for (String orderNumber : orderNumbers) {
|
||||
OrderSettlement orderSettlement = new OrderSettlement();
|
||||
orderSettlement.setPayNo(payNo);
|
||||
orderSettlement.setPayType(payParam.getPayType());
|
||||
orderSettlement.setUserId(userId);
|
||||
orderSettlement.setOrderNumber(orderNumber);
|
||||
orderSettlementMapper.updateByOrderNumberAndUserId(orderSettlement);
|
||||
|
||||
Order order = orderMapper.getOrderByOrderNumber(orderNumber);
|
||||
prodName.append(order.getProdName()).append(StrUtil.COMMA);
|
||||
}
|
||||
```
|
||||
|
||||
这里对传过来的支付参数`orderNumbers`进行了拆分,为每个订单的结算信息都进行了更新,所以这里便支持了分单支付和并单支付的流程。
|
||||
|
||||
|
||||
|
||||
订单金额:
|
||||
|
||||
```java
|
||||
// 除了ordernumber不一样,其他都一样
|
||||
List<OrderSettlement> settlements = orderSettlementMapper.getSettlementsByPayNo(payNo);
|
||||
// 应支付的总金额
|
||||
double payAmount = 0.0;
|
||||
for (OrderSettlement orderSettlement : settlements) {
|
||||
payAmount = Arith.add(payAmount, orderSettlement.getPayAmount());
|
||||
}
|
||||
```
|
||||
|
||||
这里面应支付的金额是通过数据库中获取的订单金额,是不接受任何前端传入的订单金额的。
|
||||
|
||||
|
||||
|
||||
## 支付回调
|
||||
|
||||
|
||||
|
||||
我们回到`controller`
|
||||
|
||||
```java
|
||||
orderRequest.setNotifyUrl(apiConfig.getDomainName() + "/notice/pay/order");
|
||||
```
|
||||
|
||||
这里面规定的,订单回调的地址,这也就是为什么需要`api.properties` 传入`api.domainName`的原因
|
||||
|
||||
|
||||
|
||||
根据订单配置`/notice/pay/order`,我们去到订单回调的`controller`既`PayNoticeController`
|
||||
|
||||
- 验签
|
||||
|
||||
因为订单的已经决定的订单已经支付成功,所以订单的回调是需要做一些验证的。不然谁都可以调用订单回调的地址,实在是十分危险。
|
||||
|
||||
其实`wxjava`这个工具包已经对返回的参数进行了校验
|
||||
|
||||
```java
|
||||
WxPayOrderNotifyResult parseOrderNotifyResult = wxMiniPayService.parseOrderNotifyResult(xmlData);
|
||||
```
|
||||
|
||||
在上面这个方法之下,就有那么一句话
|
||||
|
||||
```java
|
||||
result.checkResult(this, this.getConfig().getSignType(), false);
|
||||
```
|
||||
|
||||
|
||||
|
||||
- 更新支付状态
|
||||
|
||||
我们看看这里的业务核心方法:
|
||||
|
||||
```java
|
||||
// 根据内部订单号更新order settlement
|
||||
payService.paySuccess(payNo, bizPayNo);
|
||||
```
|
||||
|
||||
|
||||
|
||||
```java
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<String> paySuccess(String payNo, String bizPayNo) {
|
||||
List<OrderSettlement> orderSettlements = orderSettlementMapper.selectList(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getPayNo, payNo));
|
||||
|
||||
OrderSettlement settlement = orderSettlements.get(0);
|
||||
|
||||
// 订单已支付
|
||||
if (settlement.getPayStatus() == 1) {
|
||||
log.info("订单已支付,settlement.id:{}",settlement.getSettlementId());
|
||||
return null;
|
||||
}
|
||||
// 修改订单结算信息
|
||||
if (orderSettlementMapper.updateToPay(payNo, settlement.getVersion()) < 1) {
|
||||
throw new YamiShopBindException("结算信息已更改");
|
||||
}
|
||||
|
||||
|
||||
List<String> orderNumbers = orderSettlements.stream().map(OrderSettlement::getOrderNumber).collect(Collectors.toList());
|
||||
|
||||
// 将订单改为已支付状态
|
||||
orderMapper.updateByToPaySuccess(orderNumbers, PayType.WECHATPAY.value());
|
||||
|
||||
List<Order> orders = orderNumbers.stream().map(orderNumber -> {
|
||||
Order order = orderMapper.getOrderByOrderNumber(orderNumber);
|
||||
order.setOrderItems(orderItemMapper.listByOrderNumber(orderNumber));
|
||||
return order;
|
||||
}).collect(Collectors.toList());
|
||||
eventPublisher.publishEvent(new PaySuccessOrderEvent(orders));
|
||||
return orderNumbers;
|
||||
}
|
||||
```
|
||||
|
||||
这里无非就是找到原来的订单,将订单变成已支付的状态。
|
||||
|
||||
|
||||
|
||||
而这里同样有事件支付成功的事件
|
||||
|
||||
```java
|
||||
eventPublisher.publishEvent(new PaySuccessOrderEvent(orders));
|
||||
```
|
||||
|
||||
这里的事件也是和营销活动有关的,比如分销,这些代码也是商业版才有的。
|
||||
Reference in New Issue
Block a user