Commit 063d5e3a8a4376645c751e7bc7ea6686411e37fc
1 parent
1391e20e
增加支付接入的示例 10%
Showing
9 changed files
with
382 additions
and
1 deletions
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.controller.admin.demo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO; | ||
| 7 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderRespVO; | ||
| 8 | +import cn.iocoder.yudao.module.pay.convert.demo.PayDemoOrderConvert; | ||
| 9 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; | ||
| 10 | +import cn.iocoder.yudao.module.pay.service.demo.PayDemoOrderService; | ||
| 11 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 12 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 13 | +import org.springframework.validation.annotation.Validated; | ||
| 14 | +import org.springframework.web.bind.annotation.*; | ||
| 15 | + | ||
| 16 | +import javax.annotation.Resource; | ||
| 17 | +import javax.validation.Valid; | ||
| 18 | + | ||
| 19 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 20 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||
| 21 | + | ||
| 22 | +@Tag(name = "管理后台 - 示例订单") | ||
| 23 | +@RestController | ||
| 24 | +@RequestMapping("/pay/demo-order") | ||
| 25 | +@Validated | ||
| 26 | +public class PayDemoOrderController { | ||
| 27 | + | ||
| 28 | + @Resource | ||
| 29 | + private PayDemoOrderService payDemoOrderService; | ||
| 30 | + | ||
| 31 | + @PostMapping("/create") | ||
| 32 | + @Operation(summary = "创建示例订单") | ||
| 33 | + public CommonResult<Long> createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) { | ||
| 34 | + return success(payDemoOrderService.createDemoOrder(getLoginUserId(), createReqVO)); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + @GetMapping("/page") | ||
| 38 | + @Operation(summary = "获得示例订单分页") | ||
| 39 | + public CommonResult<PageResult<PayDemoOrderRespVO>> getDemoOrderPage(@Valid PageParam pageVO) { | ||
| 40 | + PageResult<PayDemoOrderDO> pageResult = payDemoOrderService.getDemoOrderPage(pageVO); | ||
| 41 | + return success(PayDemoOrderConvert.INSTANCE.convertPage(pageResult)); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/PayDemoOrderCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo; | ||
| 2 | + | ||
| 3 | +import lombok.*; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | + | ||
| 6 | +import javax.validation.constraints.NotEmpty; | ||
| 7 | +import javax.validation.constraints.NotNull; | ||
| 8 | + | ||
| 9 | +@Schema(description = "管理后台 - 示例订单创建 Request VO") | ||
| 10 | +@Data | ||
| 11 | +public class PayDemoOrderCreateReqVO { | ||
| 12 | + | ||
| 13 | + @Schema(description = "商品编号", required = true, example = "17682") | ||
| 14 | + @NotNull(message = "商品编号不能为空") | ||
| 15 | + private Long spuId; | ||
| 16 | + | ||
| 17 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/PayDemoOrderRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.*; | ||
| 5 | + | ||
| 6 | +import java.time.LocalDateTime; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | +* 示例订单 Base VO,提供给添加、修改、详细的子 VO 使用 | ||
| 10 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | ||
| 11 | +*/ | ||
| 12 | +@Data | ||
| 13 | +public class PayDemoOrderRespVO { | ||
| 14 | + | ||
| 15 | + @Schema(description = "用户编号", required = true, example = "23199") | ||
| 16 | + private Long userId; | ||
| 17 | + | ||
| 18 | + @Schema(description = "商品编号", required = true, example = "17682") | ||
| 19 | + private Long spuId; | ||
| 20 | + | ||
| 21 | + @Schema(description = "商家备注", example = "李四") | ||
| 22 | + private String spuName; | ||
| 23 | + | ||
| 24 | + @Schema(description = "价格,单位:分", required = true, example = "30381") | ||
| 25 | + private Integer price; | ||
| 26 | + | ||
| 27 | + @Schema(description = "是否已支付", required = true) | ||
| 28 | + private Boolean payed; | ||
| 29 | + | ||
| 30 | + @Schema(description = "支付订单编号", example = "16863") | ||
| 31 | + private Long payOrderId; | ||
| 32 | + | ||
| 33 | + @Schema(description = "订单支付时间") | ||
| 34 | + private LocalDateTime payTime; | ||
| 35 | + | ||
| 36 | + @Schema(description = "退款金额,单位:分", required = true, example = "14039") | ||
| 37 | + private Integer refundPrice; | ||
| 38 | + | ||
| 39 | + @Schema(description = "退款时间") | ||
| 40 | + private LocalDateTime refundTime; | ||
| 41 | + | ||
| 42 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java deleted
| 1 | -package cn.iocoder.yudao.module.pay.controller.app; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoOrderConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.convert.demo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderRespVO; | ||
| 6 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; | ||
| 7 | +import org.mapstruct.Mapper; | ||
| 8 | +import org.mapstruct.factory.Mappers; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 示例订单 Convert | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +@Mapper | ||
| 16 | +public interface PayDemoOrderConvert { | ||
| 17 | + | ||
| 18 | + PayDemoOrderConvert INSTANCE = Mappers.getMapper(PayDemoOrderConvert.class); | ||
| 19 | + | ||
| 20 | + PayDemoOrderDO convert(PayDemoOrderCreateReqVO bean); | ||
| 21 | + | ||
| 22 | + PayDemoOrderRespVO convert(PayDemoOrderDO bean); | ||
| 23 | + | ||
| 24 | + PageResult<PayDemoOrderRespVO> convertPage(PageResult<PayDemoOrderDO> page); | ||
| 25 | + | ||
| 26 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoOrderDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.dal.dataobject.demo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.KeySequence; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 7 | +import lombok.*; | ||
| 8 | + | ||
| 9 | +import java.time.LocalDateTime; | ||
| 10 | +import java.util.Date; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 示例订单 | ||
| 14 | + * | ||
| 15 | + * 演示业务系统的订单,如何接入 pay 系统的支付与退款 | ||
| 16 | + * | ||
| 17 | + * @author 芋道源码 | ||
| 18 | + */ | ||
| 19 | +@TableName("pay_demo_order") | ||
| 20 | +@KeySequence("pay_demo_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||
| 21 | +@Data | ||
| 22 | +@EqualsAndHashCode(callSuper = true) | ||
| 23 | +@ToString(callSuper = true) | ||
| 24 | +@Builder | ||
| 25 | +@NoArgsConstructor | ||
| 26 | +@AllArgsConstructor | ||
| 27 | +public class PayDemoOrderDO extends BaseDO { | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * 订单编号,自增 | ||
| 31 | + */ | ||
| 32 | + @TableId | ||
| 33 | + private Long id; | ||
| 34 | + /** | ||
| 35 | + * 用户编号 | ||
| 36 | + */ | ||
| 37 | + private Long userId; | ||
| 38 | + /** | ||
| 39 | + * 商品编号 | ||
| 40 | + */ | ||
| 41 | + private Long spuId; | ||
| 42 | + /** | ||
| 43 | + * 商品名称 | ||
| 44 | + */ | ||
| 45 | + private String spuName; | ||
| 46 | + /** | ||
| 47 | + * 价格,单位:分 | ||
| 48 | + */ | ||
| 49 | + private Integer price; | ||
| 50 | + | ||
| 51 | + // ========== 支付相关字段 ========== | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * 是否支付 | ||
| 55 | + */ | ||
| 56 | + private Boolean payed; | ||
| 57 | + /** | ||
| 58 | + * 支付订单编号 | ||
| 59 | + * | ||
| 60 | + * 对接 pay-module-biz 支付服务的支付订单编号,即 PayOrderDO 的 id 编号 | ||
| 61 | + */ | ||
| 62 | + private Long payOrderId; | ||
| 63 | + /** | ||
| 64 | + * 付款时间 | ||
| 65 | + */ | ||
| 66 | + private LocalDateTime payTime; | ||
| 67 | + /** | ||
| 68 | + * 支付渠道 | ||
| 69 | + * | ||
| 70 | + * 对应 PayChannelEnum 枚举 | ||
| 71 | + */ | ||
| 72 | + private String payChannelCode; | ||
| 73 | + | ||
| 74 | + // ========== 退款相关字段 ========== | ||
| 75 | + /** | ||
| 76 | + * 退款金额 | ||
| 77 | + */ | ||
| 78 | + private Integer refundPrice; | ||
| 79 | + /** | ||
| 80 | + * 退款时间 | ||
| 81 | + * | ||
| 82 | + * 由于可以多次退款,记录最后一次退款的时间 | ||
| 83 | + */ | ||
| 84 | + private Date refundTime; | ||
| 85 | + | ||
| 86 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoOrderMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.dal.mysql.demo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 6 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 7 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; | ||
| 8 | +import org.apache.ibatis.annotations.Mapper; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 示例订单 Mapper | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +@Mapper | ||
| 16 | +public interface PayDemoOrderMapper extends BaseMapperX<PayDemoOrderDO> { | ||
| 17 | + | ||
| 18 | + default PageResult<PayDemoOrderDO> selectPage(PageParam reqVO) { | ||
| 19 | + return selectPage(reqVO, new LambdaQueryWrapperX<PayDemoOrderDO>() | ||
| 20 | + .orderByDesc(PayDemoOrderDO::getId)); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.service.demo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; | ||
| 7 | + | ||
| 8 | +import javax.validation.Valid; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 示例订单 Service 接口 | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +public interface PayDemoOrderService { | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 创建示例订单 | ||
| 19 | + * | ||
| 20 | + * @param userId 用户编号 | ||
| 21 | + * @param createReqVO 创建信息 | ||
| 22 | + * @return 编号 | ||
| 23 | + */ | ||
| 24 | + Long createDemoOrder(Long userId, @Valid PayDemoOrderCreateReqVO createReqVO); | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 获得示例订单 | ||
| 28 | + * | ||
| 29 | + * @param id 编号 | ||
| 30 | + * @return 示例订单 | ||
| 31 | + */ | ||
| 32 | + PayDemoOrderDO getDemoOrder(Long id); | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 获得示例订单分页 | ||
| 36 | + * | ||
| 37 | + * @param pageReqVO 分页查询 | ||
| 38 | + * @return 示例订单分页 | ||
| 39 | + */ | ||
| 40 | + PageResult<PayDemoOrderDO> getDemoOrderPage(PageParam pageReqVO); | ||
| 41 | + | ||
| 42 | +} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.service.demo; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.lang.Assert; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | +import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | ||
| 7 | +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | ||
| 8 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO; | ||
| 9 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; | ||
| 10 | +import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoOrderMapper; | ||
| 11 | +import org.springframework.stereotype.Service; | ||
| 12 | +import org.springframework.validation.annotation.Validated; | ||
| 13 | + | ||
| 14 | +import javax.annotation.Resource; | ||
| 15 | +import java.time.Duration; | ||
| 16 | +import java.util.HashMap; | ||
| 17 | +import java.util.Map; | ||
| 18 | + | ||
| 19 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; | ||
| 20 | +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * 示例订单 Service 实现类 | ||
| 24 | + * | ||
| 25 | + * @author 芋道源码 | ||
| 26 | + */ | ||
| 27 | +@Service | ||
| 28 | +@Validated | ||
| 29 | +public class PayDemoOrderServiceImpl implements PayDemoOrderService { | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 接入的实力应用编号 | ||
| 33 | + * | ||
| 34 | + * 从 [支付管理 -> 应用信息] 里添加 | ||
| 35 | + */ | ||
| 36 | + private static final Long PAY_APP_ID = 7L; | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 商品信息 Map | ||
| 40 | + * | ||
| 41 | + * key:商品编号 | ||
| 42 | + * value:[商品名、商品价格] | ||
| 43 | + */ | ||
| 44 | + private final Map<Long, Object[]> spuNames = new HashMap<>(); | ||
| 45 | + | ||
| 46 | + @Resource | ||
| 47 | + private PayOrderApi payOrderApi; | ||
| 48 | + | ||
| 49 | + @Resource | ||
| 50 | + private PayDemoOrderMapper payDemoOrderMapper; | ||
| 51 | + | ||
| 52 | + public PayDemoOrderServiceImpl() { | ||
| 53 | + spuNames.put(1L, new Object[]{"华为手机", 1}); | ||
| 54 | + spuNames.put(2L, new Object[]{"小米电视", 10}); | ||
| 55 | + spuNames.put(3L, new Object[]{"苹果手表", 100}); | ||
| 56 | + spuNames.put(4L, new Object[]{"华硕笔记本", 200}); | ||
| 57 | + spuNames.put(5L, new Object[]{"蔚来汽车", 300}); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public Long createDemoOrder(Long userId, PayDemoOrderCreateReqVO createReqVO) { | ||
| 62 | + // 1.1 获得商品 | ||
| 63 | + Object[] spu = spuNames.get(createReqVO.getSpuId()); | ||
| 64 | + Assert.notNull(spu, "商品({}) 不存在", createReqVO.getSpuId()); | ||
| 65 | + String spuName = (String) spu[0]; | ||
| 66 | + Integer price = (Integer) spu[1]; | ||
| 67 | + // 1.2 插入 demo 订单 | ||
| 68 | + PayDemoOrderDO demoOrder = new PayDemoOrderDO().setUserId(userId) | ||
| 69 | + .setSpuId(createReqVO.getSpuId()).setSpuName(spuName) | ||
| 70 | + .setPayed(false).setRefundPrice(0); | ||
| 71 | + payDemoOrderMapper.insert(demoOrder); | ||
| 72 | + | ||
| 73 | + // 2.1 创建支付单 | ||
| 74 | + Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO() | ||
| 75 | + .setAppId(PAY_APP_ID).setUserIp(getClientIP()) // 支付应用 | ||
| 76 | + .setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号 | ||
| 77 | + .setSubject(spuName).setBody("").setAmount(price) // 价格信息 | ||
| 78 | + .setExpireTime(addTime(Duration.ofHours(2L)))); // 支付的过期时间 | ||
| 79 | + // 2.2 更新支付单到 demo 订单 | ||
| 80 | + payDemoOrderMapper.updateById(new PayDemoOrderDO().setId(demoOrder.getId()) | ||
| 81 | + .setPayOrderId(payOrderId)); | ||
| 82 | + // 返回 | ||
| 83 | + return demoOrder.getId(); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | +// private void validateDemoOrderExists(Long id) { | ||
| 87 | +// if (demoOrderMapper.selectById(id) == null) { | ||
| 88 | +// throw exception(DEMO_ORDER_NOT_EXISTS); | ||
| 89 | +// } | ||
| 90 | +// } | ||
| 91 | + | ||
| 92 | + @Override | ||
| 93 | + public PayDemoOrderDO getDemoOrder(Long id) { | ||
| 94 | + return payDemoOrderMapper.selectById(id); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + @Override | ||
| 98 | + public PageResult<PayDemoOrderDO> getDemoOrderPage(PageParam pageReqVO) { | ||
| 99 | + return payDemoOrderMapper.selectPage(pageReqVO); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | +} |