Browse Source
- 添加了 PaymentWithOrderRequest 类用于订单创建和支付请求 - 在 PaymentService接口中新增了 createPaymentWithOrder 方法 - 在 PaymentServiceImpl 中实现了订单创建和支付的逻辑 - 更新了 ShopOrderController 中的订单创建逻辑 - 添加了新的 API 文档 unified_payment_with_order_api.mdpan
6 changed files with 553 additions and 4 deletions
@ -0,0 +1,158 @@ |
|||
package com.gxwebsoft.payment.dto; |
|||
|
|||
import com.gxwebsoft.payment.enums.PaymentType; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.Data; |
|||
|
|||
import javax.validation.Valid; |
|||
import javax.validation.constraints.*; |
|||
import java.math.BigDecimal; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 支付与订单创建请求DTO |
|||
* 用于统一支付模块中的订单创建和支付 |
|||
* |
|||
* @author 科技小王子 |
|||
* @since 2025-01-26 |
|||
*/ |
|||
@Data |
|||
@Schema(name = "PaymentWithOrderRequest", description = "支付与订单创建请求") |
|||
public class PaymentWithOrderRequest { |
|||
|
|||
// ========== 支付相关字段 ==========
|
|||
|
|||
@Schema(description = "支付类型", required = true) |
|||
@NotNull(message = "支付类型不能为空") |
|||
private PaymentType paymentType; |
|||
|
|||
@Schema(description = "支付金额", required = true) |
|||
@NotNull(message = "支付金额不能为空") |
|||
@DecimalMin(value = "0.01", message = "支付金额必须大于0") |
|||
@Digits(integer = 10, fraction = 2, message = "支付金额格式不正确") |
|||
private BigDecimal amount; |
|||
|
|||
@Schema(description = "订单标题", required = true) |
|||
@NotBlank(message = "订单标题不能为空") |
|||
@Size(max = 60, message = "订单标题长度不能超过60个字符") |
|||
private String subject; |
|||
|
|||
@Schema(description = "订单描述") |
|||
@Size(max = 500, message = "订单描述长度不能超过500个字符") |
|||
private String description; |
|||
|
|||
@Schema(description = "租户ID", required = true) |
|||
@NotNull(message = "租户ID不能为空") |
|||
@Positive(message = "租户ID必须为正数") |
|||
private Integer tenantId; |
|||
|
|||
// ========== 订单相关字段 ==========
|
|||
|
|||
@Schema(description = "订单信息", required = true) |
|||
@Valid |
|||
@NotNull(message = "订单信息不能为空") |
|||
private OrderInfo orderInfo; |
|||
|
|||
/** |
|||
* 订单信息 |
|||
*/ |
|||
@Data |
|||
@Schema(name = "OrderInfo", description = "订单信息") |
|||
public static class OrderInfo { |
|||
|
|||
@Schema(description = "订单类型,0商城订单 1预定订单/外卖 2会员卡") |
|||
@NotNull(message = "订单类型不能为空") |
|||
@Min(value = 0, message = "订单类型值无效") |
|||
@Max(value = 2, message = "订单类型值无效") |
|||
private Integer type; |
|||
|
|||
@Schema(description = "收货人姓名") |
|||
@Size(max = 50, message = "收货人姓名长度不能超过50个字符") |
|||
private String realName; |
|||
|
|||
@Schema(description = "收货地址") |
|||
@Size(max = 200, message = "收货地址长度不能超过200个字符") |
|||
private String address; |
|||
|
|||
@Schema(description = "关联收货地址ID") |
|||
private Integer addressId; |
|||
|
|||
@Schema(description = "快递/自提,0快递 1自提") |
|||
private Integer deliveryType; |
|||
|
|||
@Schema(description = "下单渠道,0小程序预定 1俱乐部训练场 3活动订场") |
|||
private Integer channel; |
|||
|
|||
@Schema(description = "商户ID") |
|||
private Long merchantId; |
|||
|
|||
@Schema(description = "商户名称") |
|||
private String merchantName; |
|||
|
|||
@Schema(description = "使用的优惠券ID") |
|||
private Integer couponId; |
|||
|
|||
@Schema(description = "备注") |
|||
@Size(max = 500, message = "备注长度不能超过500字符") |
|||
private String comments; |
|||
|
|||
@Schema(description = "订单商品列表", required = true) |
|||
@Valid |
|||
@NotEmpty(message = "订单商品列表不能为空") |
|||
private List<OrderGoodsItem> goodsItems; |
|||
} |
|||
|
|||
/** |
|||
* 订单商品项 |
|||
*/ |
|||
@Data |
|||
@Schema(name = "OrderGoodsItem", description = "订单商品项") |
|||
public static class OrderGoodsItem { |
|||
|
|||
@Schema(description = "商品ID", required = true) |
|||
@NotNull(message = "商品ID不能为空") |
|||
@Positive(message = "商品ID必须为正数") |
|||
private Integer goodsId; |
|||
|
|||
@Schema(description = "商品SKU ID") |
|||
private Integer skuId; |
|||
|
|||
@Schema(description = "商品数量", required = true) |
|||
@NotNull(message = "商品数量不能为空") |
|||
@Min(value = 1, message = "商品数量必须大于0") |
|||
private Integer quantity; |
|||
|
|||
@Schema(description = "规格信息,如:颜色:红色|尺寸:L") |
|||
private String specInfo; |
|||
} |
|||
|
|||
/** |
|||
* 获取格式化的金额字符串 |
|||
*/ |
|||
public String getFormattedAmount() { |
|||
if (amount == null) { |
|||
return "0.00"; |
|||
} |
|||
return String.format("%.2f", amount); |
|||
} |
|||
|
|||
/** |
|||
* 验证订单商品总金额是否与支付金额一致 |
|||
*/ |
|||
public boolean isAmountConsistent() { |
|||
if (amount == null || orderInfo == null || orderInfo.getGoodsItems() == null) { |
|||
return false; |
|||
} |
|||
|
|||
// 这里可以添加商品金额计算逻辑
|
|||
// 实际实现时需要查询数据库获取商品价格
|
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return String.format("PaymentWithOrderRequest{paymentType=%s, amount=%s, subject='%s', tenantId=%d, goodsCount=%d}", |
|||
paymentType, getFormattedAmount(), subject, tenantId, |
|||
orderInfo != null && orderInfo.getGoodsItems() != null ? orderInfo.getGoodsItems().size() : 0); |
|||
} |
|||
} |
@ -0,0 +1,184 @@ |
|||
# 统一支付模块 - 订单创建与支付接口 |
|||
|
|||
## 🎯 **新接口概述** |
|||
|
|||
新增了 `POST /api/payment/create-with-order` 接口,实现了: |
|||
1. **订单创建**:完整的商品验证、库存扣减、价格计算 |
|||
2. **支付发起**:统一支付模块的支付创建 |
|||
3. **数据一致性**:事务保证订单和支付的一致性 |
|||
|
|||
## 📋 **接口详情** |
|||
|
|||
### **请求地址** |
|||
``` |
|||
POST /api/payment/create-with-order |
|||
``` |
|||
|
|||
### **请求参数** |
|||
```json |
|||
{ |
|||
"paymentType": "WECHAT_NATIVE", |
|||
"amount": 100.00, |
|||
"subject": "网站建设服务订单", |
|||
"description": "网站建设服务", |
|||
"tenantId": 10398, |
|||
"orderInfo": { |
|||
"type": 0, |
|||
"realName": "无", |
|||
"address": "无", |
|||
"addressId": 0, |
|||
"deliveryType": 0, |
|||
"channel": 0, |
|||
"merchantId": null, |
|||
"merchantName": null, |
|||
"couponId": null, |
|||
"comments": "网站建设服务订单", |
|||
"goodsItems": [ |
|||
{ |
|||
"goodsId": 10004, |
|||
"skuId": null, |
|||
"quantity": 1, |
|||
"specInfo": null |
|||
} |
|||
] |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### **响应数据** |
|||
```json |
|||
{ |
|||
"code": 200, |
|||
"message": "订单创建并发起支付成功", |
|||
"data": { |
|||
"success": true, |
|||
"orderNo": "ORDER_1756547282147", |
|||
"paymentType": "WECHAT_NATIVE", |
|||
"paymentStatus": "PENDING", |
|||
"amount": 100.00, |
|||
"tenantId": 10398, |
|||
"codeUrl": "weixin://wxpay/bizpayurl?pr=xxx", |
|||
"currency": "CNY", |
|||
"createTime": "2025-01-26T10:30:00" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## 🔄 **处理流程** |
|||
|
|||
### **1. 请求验证** |
|||
- 用户登录状态验证 |
|||
- 支付参数验证(金额、类型等) |
|||
- 订单参数验证(商品列表、收货信息等) |
|||
|
|||
### **2. 订单创建** |
|||
``` |
|||
PaymentServiceImpl.createPaymentWithOrder() |
|||
↓ |
|||
convertToOrderCreateRequest() - 转换请求格式 |
|||
↓ |
|||
orderBusinessService.createOrder() - 完整订单创建逻辑 |
|||
↓ |
|||
- 商品验证(存在性、状态、价格) |
|||
- 库存验证和扣减 |
|||
- 优惠券处理 |
|||
- 订单保存 |
|||
- 订单商品保存 |
|||
- 微信支付订单创建 |
|||
``` |
|||
|
|||
### **3. 支付响应** |
|||
- 返回微信支付二维码URL |
|||
- 包含订单号和支付状态 |
|||
- 统一的响应格式 |
|||
|
|||
## 🆚 **与现有接口对比** |
|||
|
|||
| 接口 | 功能 | 优势 | 适用场景 | |
|||
|------|------|------|----------| |
|||
| `/api/payment/create` | 纯支付 | 简单快速 | 已有订单,只需支付 | |
|||
| `/api/shop/shop-order` | 纯订单 | 完整业务逻辑 | 创建订单,后续支付 | |
|||
| `/api/payment/create-with-order` | 订单+支付 | 一体化流程 | **推荐**:预下单场景 | |
|||
|
|||
## 🎯 **兼容性处理** |
|||
|
|||
### **支持你的数据格式** |
|||
你的原始数据: |
|||
```json |
|||
{ |
|||
"addressId": 0, |
|||
"comments": "网站建设服务订单", |
|||
"deliveryType": 0, |
|||
"payType": 102, |
|||
"goodsItems": [{"goodsId": 10004, "quantity": 1}], |
|||
"orderNo": "ORDER_1756547282147", |
|||
"realName": "无" |
|||
} |
|||
``` |
|||
|
|||
**转换为新格式**: |
|||
```json |
|||
{ |
|||
"paymentType": "WECHAT_NATIVE", |
|||
"amount": 100.00, |
|||
"subject": "网站建设服务订单", |
|||
"tenantId": 10398, |
|||
"orderInfo": { |
|||
"type": 0, |
|||
"realName": "无", |
|||
"addressId": 0, |
|||
"deliveryType": 0, |
|||
"comments": "网站建设服务订单", |
|||
"goodsItems": [{"goodsId": 10004, "quantity": 1}] |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## ✅ **优势总结** |
|||
|
|||
### **1. 架构统一** |
|||
- 所有支付逻辑集中在统一支付模块 |
|||
- 统一的错误处理和日志记录 |
|||
- 统一的响应格式 |
|||
|
|||
### **2. 业务完整** |
|||
- 复用现有的完整订单创建逻辑 |
|||
- 商品验证、库存管理、优惠券处理 |
|||
- 支付成功后的完整回调处理 |
|||
|
|||
### **3. 数据一致性** |
|||
- 事务保证订单创建和支付的原子性 |
|||
- 支付失败时订单状态正确 |
|||
- 支付成功时自动更新订单状态 |
|||
|
|||
### **4. 扩展性好** |
|||
- 支持多种支付方式(微信、支付宝、银联等) |
|||
- 支持复杂订单场景(多商品、多规格、优惠券等) |
|||
- 预留了通知和业务逻辑扩展接口 |
|||
|
|||
## 🚀 **测试建议** |
|||
|
|||
### **1. 创建订单并支付** |
|||
```bash |
|||
curl -X POST "http://127.0.0.1:9200/api/payment/create-with-order" \ |
|||
-H "Content-Type: application/json" \ |
|||
-d '{ |
|||
"paymentType": "WECHAT_NATIVE", |
|||
"amount": 100.00, |
|||
"subject": "网站建设服务", |
|||
"tenantId": 10398, |
|||
"orderInfo": { |
|||
"type": 0, |
|||
"realName": "测试用户", |
|||
"comments": "测试订单", |
|||
"goodsItems": [{"goodsId": 10004, "quantity": 1}] |
|||
} |
|||
}' |
|||
``` |
|||
|
|||
### **2. 查询支付状态** |
|||
```bash |
|||
curl "http://127.0.0.1:9200/api/payment/query?orderNo=ORDER_xxx&tenantId=10398&paymentType=WECHAT_NATIVE" |
|||
``` |
|||
|
|||
这个方案既保持了架构的统一性,又提供了完整的业务功能! |
Loading…
Reference in new issue