提交 6dd231be authored 作者: hzh's avatar hzh

Merge branch 'dev'

package org.dromara.order.api;
import org.dromara.order.api.domain.OrderPay;
import org.dromara.order.api.domain.RemoteOrder;
import org.dromara.order.api.domain.RemoteSaveOrder;
import org.dromara.order.api.enums.OrderType;
import org.dromara.order.api.enums.Source;
import java.util.List;
......@@ -18,7 +21,7 @@ public interface RemoteOrderService {
* @param order 订单信息
* @return 订单支付信息
*/
String createOrder(RemoteSaveOrder order) throws Exception;
OrderPay createOrder(RemoteSaveOrder order) throws Exception;
/**
* 查询订单列表
......@@ -38,4 +41,14 @@ public interface RemoteOrderService {
*/
boolean autoUpdateOrGetCertificate(String serialNumber) throws Exception;
/**
* 计算服务费
*
* @param source 来源
* @param orderType 订单类型
* @param feeList 费用列表
* @return 服务费
*/
RemoteSaveOrder.Fee calcServiceFee(Source source, OrderType orderType, List<RemoteSaveOrder.Fee> feeList);
}
package org.dromara.order.api.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author hzh
* @date 2024-12-05
**/
@Data
public class OrderPay {
@Accessors(chain = true)
public class OrderPay implements Serializable {
/**
* 订单号
*/
private String orderNo;
/**
* 支付订单号
*/
private String orderPayNo;
/**
* 支付信息
*/
private String payInfo;
}
......@@ -3,13 +3,15 @@ package org.dromara.order.api.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author hzh
* @date 2024-12-09
**/
@Data
@Accessors(chain = true)
public class RemoteOrder {
public class RemoteOrder implements Serializable {
/**
* 订单类型
......
......@@ -10,7 +10,7 @@ import lombok.Getter;
@AllArgsConstructor
public enum Source {
YSH("ys", "云上");
YSH("YS", "云上");
private final String source;
private final String desc;
......
package org.dromara.common.pay.config;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
......@@ -19,9 +17,7 @@ import org.springframework.stereotype.Component;
*
* @author Javen
*/
@Getter
@Setter
@ToString
@Data
@Component
@ConfigurationProperties(prefix = "pay.wechat.v3")
public class WechatPayConfiguration {
......
package org.dromara.common.pay.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
......@@ -13,9 +10,6 @@ import java.io.Serializable;
* @date 2024-12-10
* @desc jsapi 回调参数
**/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
@SuppressWarnings("all")
......@@ -104,9 +98,6 @@ public class JsapiNotifyModel implements Serializable {
*/
private PromotionDetail promotion_detail;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class Payer implements Serializable {
......@@ -118,9 +109,6 @@ public class JsapiNotifyModel implements Serializable {
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class Amount implements Serializable {
......@@ -147,9 +135,6 @@ public class JsapiNotifyModel implements Serializable {
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class SceneInfo implements Serializable {
......@@ -161,9 +146,6 @@ public class JsapiNotifyModel implements Serializable {
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class PromotionDetail implements Serializable {
......@@ -227,9 +209,6 @@ public class JsapiNotifyModel implements Serializable {
*/
private GoodsDetail goods_detail;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class GoodsDetail implements Serializable {
......
package org.dromara.common.pay.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
......@@ -14,9 +11,6 @@ import java.util.List;
* @date 2024-12-13
* @desc 退款退款对象
**/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
@SuppressWarnings("all")
......@@ -108,9 +102,6 @@ public class RefundModel implements Serializable {
*/
private List<PromotionDetail> promotion_detail;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class RefundAmount implements Serializable {
......@@ -165,9 +156,6 @@ public class RefundModel implements Serializable {
*/
private Integer refund_fee;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class From implements Serializable {
......@@ -186,9 +174,6 @@ public class RefundModel implements Serializable {
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class PromotionDetail implements Serializable {
......@@ -230,9 +215,6 @@ public class RefundModel implements Serializable {
private List<GoodsDetail> goods_detail;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public static class GoodsDetail implements Serializable {
......
......@@ -48,11 +48,12 @@ public interface IWxPayService {
*
* @param timestamp 时间搓
* @param nonce nonce
* @param serialNo serialNo
* @param signature 签名
* @param result 支付通知密文
* @return 支付通知明文
*/
JsapiNotifyModel notify(String timestamp, String nonce, String signature, String result);
JsapiNotifyModel notify(String timestamp, String nonce, String serialNo, String signature, String result);
/**
* 退款
......
......@@ -74,7 +74,7 @@ public class WxPayServiceImpl implements IWxPayService {
unifiedOrderModel
.setAppid(config.getAppId())
.setMchid(config.getMchId())
.setNotify_url(config.getNotify());
.setNotify_url(config.getDomain() + config.getNotify());
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
IJPayHttpResponse response = WxPayApi.v3(
RequestMethodEnum.POST,
......@@ -95,9 +95,10 @@ public class WxPayServiceImpl implements IWxPayService {
String prepayId = jsonObject.getStr("prepay_id");
Map<String, String> map = WxPayKit.jsApiCreateSign(config.getAppId(), prepayId, config.getKeyPath());
return JSONUtil.toJsonStr(map);
}
} else {
throw new RuntimeException("下单失败!");
}
}
@Override
public boolean autoUpdateOrGetCertificate(String serialNumber) throws Exception {
......@@ -205,14 +206,13 @@ public class WxPayServiceImpl implements IWxPayService {
}
@Override
public JsapiNotifyModel notify(String timestamp, String nonce, String signature, String result) {
String serialNumber = getSerialNumber();
log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNumber, signature);
public JsapiNotifyModel notify(String timestamp, String nonce,String serialNo, String signature, String result) {
log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
log.info("支付通知密文 {}", result);
try {
// 需要通过证书序列号查找对应的证书,verifyNotify 中有验证证书的序列号
String plainText = WxPayKit.verifyNotify(
serialNumber,
serialNo,
result,
signature,
nonce,
......@@ -279,16 +279,8 @@ public class WxPayServiceImpl implements IWxPayService {
config.getKeyPath(),
JSONUtil.toJsonStr(params));
log.info("关闭订单:{} 查询响应 {}", outTradeNo, response);
if (response.getStatus() == IJPayConstants.CODE_200) {
// 根据证书序列号查询对应的证书来验证签名结果
boolean verifySignature = WxPayKit.verifySignature(response, config.getPlatformCertPath());
log.info("verifySignature: {}", verifySignature);
//验签成功
if (verifySignature) {
if (response.getStatus() == IJPayConstants.CODE_204) {
return true;
} else {
return false;
}
}
throw new RuntimeException("订单:" + outTradeNo + "关闭失败!");
} catch (Exception e) {
......
package org.dromara.common.pay.util;
import com.ijpay.core.kit.HttpKit;
import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
/**
* @author hzh
* @date 2024-12-19
**/
public class CustomHttpKit extends HttpKit {
public static String readData(HttpServletRequest request) {
BufferedReader br = null;
try {
StringBuilder result = new StringBuilder();
br = request.getReader();
for (String line; (line = br.readLine()) != null; ) {
if (result.length() > 0) {
result.append("\n");
}
result.append(line);
}
return result.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
......@@ -101,7 +101,7 @@ public class LoginHelper {
* 获取用户id
*/
public static String getOpenId() {
return Convert.toStr(getExtra(YS_USER_ID));
return Convert.toStr(getExtra(OPEN_ID));
}
/**
......
......@@ -81,6 +81,12 @@
<artifactId>ruoyi-api-server</artifactId>
</dependency>
<!-- RuoYi Api Order -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-order</artifactId>
</dependency>
</dependencies>
......
package org.dromara.job.snailjob;
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.aizuda.snailjob.client.job.core.dto.JobArgs;
import com.aizuda.snailjob.client.model.ExecuteResult;
import lombok.AllArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.order.api.RemoteOrderService;
import org.springframework.stereotype.Component;
/**
* @author hzh
* @date 2024-11-18
*/
@AllArgsConstructor
@Component
@JobExecutor(name = "payJobExecutor")
public class PayJobExecutor {
@DubboReference
private RemoteOrderService remoteOrderService;
public ExecuteResult jobExecute(JobArgs jobArgs) throws Exception {
remoteOrderService.autoUpdateOrGetCertificate(null);
return ExecuteResult.success("注册成功");
}
}
package org.dromara.order.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import com.ijpay.core.kit.HttpKit;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.pay.domain.JsapiNotifyModel;
import org.dromara.common.pay.util.CustomHttpKit;
import org.dromara.common.web.core.BaseController;
import org.dromara.order.domain.bo.OrderBo;
import org.dromara.order.domain.vo.OrderVo;
import org.dromara.order.service.IOrderPayService;
import org.dromara.order.service.IOrderService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
......@@ -49,97 +38,31 @@ import java.util.Map;
@RequestMapping("/order")
public class OrderController extends BaseController {
private final IOrderService orderService;
private final IOrderPayService orderPayService;
/**
* 查询订单费用列表
*/
@SaCheckPermission("order:order:list")
@GetMapping("/list")
public TableDataInfo<OrderVo> list(OrderBo bo, PageQuery pageQuery) {
return orderService.queryPageList(bo, pageQuery);
}
/**
* 导出订单费用列表
*/
@SaCheckPermission("order:order:export")
@Log(title = "订单费用", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(OrderBo bo, HttpServletResponse response) {
List<OrderVo> list = orderService.queryList(bo);
ExcelUtil.exportExcel(list, "订单费用", OrderVo.class, response);
}
/**
* 获取订单费用详细信息
* 回调函数
*
* @param id 主键
*/
@SaCheckPermission("order:order:query")
@GetMapping("/{id}")
public R<OrderVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(orderService.queryById(id));
}
/**
* 新增订单费用
*/
@SaCheckPermission("order:order:add")
@Log(title = "订单费用", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody OrderBo bo) {
return toAjax(orderService.insertByBo(bo));
}
/**
* 修改订单费用
*/
@SaCheckPermission("order:order:edit")
@Log(title = "订单费用", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody OrderBo bo) {
return toAjax(orderService.updateByBo(bo));
}
/**
* 删除订单费用
*
* @param ids 主键串
*/
@SaCheckPermission("order:order:remove")
@Log(title = "订单费用", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(orderService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 回调原函数
*
* @param request request
* @param response response
*/
@RequestMapping(value = "/v3/payNotify", method = {RequestMethod.POST, RequestMethod.GET})
public void payNotify(HttpServletRequest request, HttpServletResponse response) {
public void payNotify(HttpServletResponse response) {
Map<String, String> map = new HashMap<>(12);
try {
log.info("微信回调开始");
ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
jakarta.servlet.http.HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
ImmutableMap<String, String> builder = ImmutableMap.<String, String>builder()
.put("timestamp", request.getHeader("Wechatpay-Timestamp"))
.put("nonce", request.getHeader("Wechatpay-Nonce"))
.put("serialNo", request.getHeader("Wechatpay-Serial"))
.put("signature", request.getHeader("Wechatpay-Signature"))
.put("result", HttpKit.readData(request));
.put("result", CustomHttpKit.readData(request))
.build();
boolean result = orderPayService.notify(JSON.toJSONString(builder));
boolean result = orderPayService.notify(JSON.toJSONString(new HashMap<>(builder)));
if (result) {
response.setStatus(200);
......
......@@ -9,14 +9,18 @@ import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.pay.service.IWxPayService;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.order.api.RemoteOrderService;
import org.dromara.order.api.domain.OrderPay;
import org.dromara.order.api.domain.RemoteOrder;
import org.dromara.order.api.domain.RemoteSaveOrder;
import org.dromara.order.api.enums.OrderStatus;
import org.dromara.order.api.enums.OrderType;
import org.dromara.order.api.enums.Source;
import org.dromara.order.constant.WechatTradeState;
import org.dromara.order.domain.bo.OrderBo;
import org.dromara.order.domain.bo.OrderFeeBo;
......@@ -32,7 +36,6 @@ import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
......@@ -54,7 +57,7 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
@GlobalTransactional(rollbackFor = Exception.class)
@Override
public String createOrder(RemoteSaveOrder remoteOrder) throws Exception {
public OrderPay createOrder(RemoteSaveOrder remoteOrder) throws Exception {
ValidatorUtils.validate(remoteOrder);
//查询订单信息
Long userId = LoginHelper.getUserId();
......@@ -67,7 +70,7 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
).stream().findFirst().orElseGet(() -> {
//创建订单
OrderBo bo = new OrderBo()
.setUserId(LoginHelper.getUserId())
.setUserId(userId)
.setOrderNo(System.currentTimeMillis() + "")
.setSource(remoteOrder.getSource().getSource())
.setOrderType(remoteOrder.getOrderType().getType())
......@@ -81,10 +84,13 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
if (StringUtils.equals(order.getStatus(), OrderStatus.PAYED.getCode())) {
throw new ServiceException("订单已支付");
}
//获取订单支付信息
List<OrderFeeVo> feeList = Optional.ofNullable(orderFeeService.queryList(new OrderFeeBo()
.setOrderNo(order.getOrderNo())))
.orElseGet(() -> {
//删除历史订单费用信息
List<OrderFeeVo> orderFeeVos = orderFeeService.queryList(new OrderFeeBo()
.setOrderNo(order.getOrderNo()));
if (CollectionUtils.isNotEmpty(orderFeeVos)) {
orderFeeService.deleteWithValidByIds(StreamUtils.toList(orderFeeVos, OrderFeeVo::getId), false);
}
//创建订单费用信息
List<RemoteSaveOrder.Fee> list = remoteOrder.getFeeList();
......@@ -93,8 +99,10 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
RemoteSaveOrder.Fee serviceFee = IOrderServiceFeeStrategy.calcServiceFee(remoteOrder.getSource(), remoteOrder.getOrderType(), list);
list.add(serviceFee);
List<OrderFeeBo> ofList = list.stream().map(fee -> {
return new OrderFeeBo()
.setUserId(order.getUserId())
.setOrderNo(order.getOrderNo())
.setFeeDesc(fee.getFeeDesc())
.setFeeAmount(fee.getFeeAmount())
......@@ -103,8 +111,8 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
.setRemark(fee.getRemark());
}).collect(Collectors.toList());
orderFeeService.batchInsertByList(ofList);
return BeanUtil.copyToList(ofList, OrderFeeVo.class);
});
List<OrderFeeVo> feeList = BeanUtil.copyToList(ofList, OrderFeeVo.class);
//获取总金额
assert feeList != null;
BigDecimal amount = feeList.stream().map(OrderFeeVo::getFeeAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
......@@ -115,11 +123,15 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
for (OrderTradeVo ot : otList) {
if (StringUtils.equals(ot.getTradeState(), WechatTradeState.USERPAYING.getState())) {
wxPayService.close(ot.getOrderPayNo());
ot.setTradeState(WechatTradeState.CLOSED.getState());
orderTradeService.updateByBo(BeanUtil.copyProperties(ot, OrderTradeBo.class));
}
}
}
Date expireTime = DateUtil.offsetMinute(new Date(), expireMinute);
String openId = LoginHelper.getOpenId();
//创建支付订单
OrderTradeBo ot = new OrderTradeBo()
.setUserId(order.getUserId())
......@@ -133,18 +145,19 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
.setTradeType(remoteOrder.getTradeType().name())
.setExpireTime(expireTime)
.setTradeState(WechatTradeState.USERPAYING.getState())
.setPayOpenId(LoginHelper.getOpenId());
.setPayOpenId(openId);
orderTradeService.insertByBo(ot);
//跟新支付信息
order.setAmount(ot.getAmount());
order.setPayAmount(ot.getPayAmount());
order.setActualPayAmount(ot.getActualPayAmount());
order.setDiscountAmount(ot.getDiscountAmount());
orderService.updateByBo(BeanUtil.copyProperties(order, OrderBo.class));
//获取支付订单
return IPayStrategy.pay(JSON.toJSONString(ot), feeList, remoteOrder.getTradeType().name());
return new OrderPay()
.setOrderNo(order.getOriginOrderNo())
.setOrderPayNo(ot.getOrderPayNo())
.setPayInfo(IPayStrategy.pay(JSON.toJSONString(ot), feeList, remoteOrder.getTradeType().name()));
}
@Override
......@@ -165,4 +178,9 @@ public class RemoteOrderServiceImpl implements RemoteOrderService {
public boolean autoUpdateOrGetCertificate(String serialNumber) throws Exception {
return wxPayService.autoUpdateOrGetCertificate(serialNumber);
}
@Override
public RemoteSaveOrder.Fee calcServiceFee(Source source, OrderType orderType, List<RemoteSaveOrder.Fee> feeList) {
return IOrderServiceFeeStrategy.calcServiceFee(source, orderType, feeList);
}
}
......@@ -39,12 +39,16 @@ public class JsapiPayStrategy implements IPayStrategy {
//获取支付金额
int amount = new BigDecimal("100").multiply(feeAmount).intValue();
if (amount <= 0) {
throw new RuntimeException("支付金额不能小于等于0");
}
UnifiedOrderModel model = new UnifiedOrderModel()
.setDescription("测试")
.setOut_trade_no(ot.getOrderPayNo())
.setTime_expire(timeExpire)
.setAttach("")
.setAmount(new Amount().setTotal(amount))
.setAmount(new Amount().setTotal(1))
.setPayer(new Payer().setOpenid(ot.getPayOpenId()));
return wxPayService.jsapi(model);
}
......
......@@ -12,6 +12,7 @@ import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.pay.domain.JsapiNotifyModel;
import org.dromara.common.pay.service.IWxPayService;
import org.dromara.order.api.enums.OrderStatus;
import org.dromara.order.constant.WechatTradeState;
import org.dromara.order.domain.bo.OrderBo;
import org.dromara.order.domain.bo.OrderTradeBo;
import org.dromara.order.domain.vo.OrderTradeVo;
......@@ -25,7 +26,9 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* @author hzh
......@@ -52,6 +55,7 @@ public class WeChatOrderPayServiceImpl implements IOrderPayService {
JsapiNotifyModel model = wxPayService.notify(
bodyJson.getString("timestamp"),
bodyJson.getString("nonce"),
bodyJson.getString("serialNo"),
bodyJson.getString("signature"),
bodyJson.getString("result")
);
......@@ -80,10 +84,16 @@ public class WeChatOrderPayServiceImpl implements IOrderPayService {
String orderPayNo = model.getOut_trade_no();
String tradeState = model.getTrade_state();
List<String> notUpdateStateList = List.of(WechatTradeState.NOTPAY.getState(), WechatTradeState.USERPAYING.getState());
if (notUpdateStateList.contains(tradeState)) {
return;
}
OrderTradeVo orderTrade = orderTradeService.getOne(new OrderTradeBo().setOrderPayNo(orderPayNo));
if (Objects.isNull(orderTrade)) {
throw new RuntimeException("交易订单不存在");
}
if (!StringUtils.equals(tradeState, orderTrade.getTradeState())) {
//更新订单信息
String successTimeStr = model.getSuccess_time();
......@@ -93,27 +103,32 @@ public class WeChatOrderPayServiceImpl implements IOrderPayService {
String transactionId = model.getTransaction_id();
JsapiNotifyModel.Amount amount = model.getAmount();
//支付金额
int actualPayAmount = amount.getPayer_total();
Integer actualPayAmount = amount.getPayer_total();
//获取openId
String payOpenId = model.getPayer().getOpenid();
String payOpenId = Optional.ofNullable(model.getPayer()).map(JsapiNotifyModel.Payer::getOpenid).orElse(null);
orderTrade.setPayOpenId(payOpenId);
orderTrade.setPayTime(payTime);
orderTrade.setTransactionId(transactionId);
if (Objects.nonNull(actualPayAmount)) {
orderTrade.setActualPayAmount(new BigDecimal(actualPayAmount).divide(new BigDecimal(100), 2, RoundingMode.CEILING));
}
orderTrade.setTradeState(tradeState);
orderTrade.setTradeInfo(JSON.toJSONString(model));
orderTradeService.updateByBo(BeanUtil.copyProperties(orderTrade, OrderTradeBo.class));
if (StringUtils.equals(tradeState, WechatTradeState.SUCCESS.getState())) {
//跟新主表信息
OrderVo order = orderService.getOne(new OrderBo().setOrderNo(orderTrade.getOrderNo()));
order.setOrderPayNo(orderPayNo);
order.setActualPayAmount(orderTrade.getActualPayAmount());
order.setPayTime(new Date());
order.setPayTime(payTime);
order.setStatus(OrderStatus.PAYED.getCode());
orderService.updateByBo(BeanUtil.copyProperties(order, OrderBo.class));
//跟新云上相关信息
ysOrderService.payed(order.getOrderType(), order.getOrderNo());
ysOrderService.payed(order.getOrderType(), order.getOriginOrderNo());
}
}
}
......
......@@ -2,7 +2,9 @@ package org.dromara.server.controller;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.order.api.domain.OrderPay;
import org.dromara.order.api.domain.RemoteOrder;
import org.dromara.order.api.domain.RemoteSaveOrder;
import org.dromara.order.api.enums.OrderType;
import org.dromara.server.domain.vo.OrderPayVo;
import org.dromara.server.domain.vo.OrderQueryVo;
......@@ -32,7 +34,7 @@ public class OrderController {
* 下单支付接口
*/
@PostMapping("/pay")
public R<Object> pay(@Validated @RequestBody OrderPayVo vo) throws Exception {
public R<OrderPay> pay(@Validated @RequestBody OrderPayVo vo) throws Exception {
OrderType ot = OrderType.getEnum(vo.getOrderType());
return R.ok(service.createOrder(vo.getOrderNo(), ot));
}
......@@ -45,4 +47,16 @@ public class OrderController {
return R.ok(service.queryList(vo.getOrderType(), vo.getOrderNoList()));
}
/**
* 获取费用信息
* @param vo vo
* @return 费用列表
*/
@PostMapping("/calcFee")
public R<List<RemoteSaveOrder.Fee>> calcFee(@Validated @RequestBody OrderPayVo vo){
OrderType ot = OrderType.getEnum(vo.getOrderType());
return R.ok(service.calcFee(vo.getOrderNo(), ot));
}
}
package org.dromara.server.service;
import org.dromara.order.api.domain.OrderPay;
import org.dromara.order.api.domain.RemoteOrder;
import org.dromara.order.api.domain.RemoteSaveOrder;
import org.dromara.order.api.enums.OrderType;
import java.util.List;
......@@ -18,7 +20,7 @@ public interface IPayOrderService {
* @param orderType 订单类型
* @return 订单号
*/
String createOrder(String orderNo, OrderType orderType) throws Exception;
OrderPay createOrder(String orderNo, OrderType orderType) throws Exception;
/**
* 查询订单列表
......@@ -29,4 +31,11 @@ public interface IPayOrderService {
*/
List<RemoteOrder> queryList(String orderType, List<String> orderNoList);
/**
* 计算费用
* @param orderNo 订单号
* @param ot 订单类型
* @return 费用列表
*/
List<RemoteSaveOrder.Fee> calcFee(String orderNo, OrderType ot);
}
package org.dromara.server.service.impl;
import com.alibaba.nacos.common.utils.CollectionUtils;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.order.api.RemoteOrderService;
import org.dromara.order.api.domain.OrderPay;
import org.dromara.order.api.domain.RemoteOrder;
import org.dromara.order.api.domain.RemoteSaveOrder;
import org.dromara.order.api.enums.OrderType;
......@@ -12,6 +14,8 @@ import org.dromara.server.service.IOrderStrategy;
import org.dromara.server.service.IPayOrderService;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
......@@ -26,12 +30,16 @@ public class PayOrderServiceImpl implements IPayOrderService {
private RemoteOrderService remoteOrderService;
@Override
public String createOrder(String orderNo, OrderType orderType) throws Exception {
public OrderPay createOrder(String orderNo, OrderType orderType) throws Exception {
RemoteSaveOrder order = IOrderStrategy.createOrder(orderNo, orderType);
order.setSource(Source.YSH);
order.setOriginOrderNo(orderNo);
order.setTradeType(TradeType.JSAPI);
order.setOrderType(orderType);
BigDecimal amount = order.getFeeList().stream().map(RemoteSaveOrder.Fee::getFeeAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
if (amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("订单金额不能小于等于0");
}
return remoteOrderService.createOrder(order);
}
......@@ -39,4 +47,19 @@ public class PayOrderServiceImpl implements IPayOrderService {
public List<RemoteOrder> queryList(String orderType, List<String> orderNoList) {
return remoteOrderService.queryList(orderType, orderNoList);
}
@Override
public List<RemoteSaveOrder.Fee> calcFee(String orderNo, OrderType ot) {
RemoteSaveOrder order = IOrderStrategy.createOrder(orderNo, ot);
List<RemoteSaveOrder.Fee> feeList = order.getFeeList();
if (CollectionUtils.isEmpty(feeList)) {
return List.of();
}
RemoteSaveOrder.Fee fee = remoteOrderService.calcServiceFee(Source.YSH, ot, feeList);
if (fee != null) {
feeList = new ArrayList<>(feeList);
feeList.add(fee);
}
return feeList;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论