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 | +} | ... | ... |