第一次提交
This commit is contained in:
38
fastbee-pay/fastbee-pay-api/pom.xml
Normal file
38
fastbee-pay/fastbee-pay-api/pom.xml
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.fastbee.pay</groupId>
|
||||
<artifactId>fastbee-pay</artifactId>
|
||||
<version>3.8.5</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.fastbee.pay.api</groupId>
|
||||
<artifactId>fastbee-pay-api</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.fastbee</groupId>-->
|
||||
<!-- <artifactId>fastbee-common</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.projectlombok</groupId>-->
|
||||
<!-- <artifactId>lombok</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.fastbee.pay.framework</groupId>
|
||||
<artifactId>fastbee-pay-framework</artifactId>
|
||||
<version>3.8.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,34 @@
|
||||
package com.fastbee.pay.api.api.notify.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 支付单的通知 Request DTO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PayOrderNotifyReqDTO {
|
||||
|
||||
/**
|
||||
* 商户订单编号
|
||||
*/
|
||||
@NotEmpty(message = "商户订单号不能为空")
|
||||
private String merchantOrderId;
|
||||
|
||||
/**
|
||||
* 支付订单编号
|
||||
*/
|
||||
@NotNull(message = "支付订单编号不能为空")
|
||||
private Long payOrderId;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.fastbee.pay.api.api.notify.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 退款单的通知 Request DTO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PayRefundNotifyReqDTO {
|
||||
|
||||
/**
|
||||
* 商户退款单编号
|
||||
*/
|
||||
@NotEmpty(message = "商户退款单编号不能为空")
|
||||
private String merchantOrderId;
|
||||
|
||||
/**
|
||||
* 支付退款编号
|
||||
*/
|
||||
@NotNull(message = "支付退款编号不能为空")
|
||||
private Long payRefundId;
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 占位符,无特殊作用
|
||||
*/
|
||||
package com.fastbee.pay.api.api.notify;
|
@ -0,0 +1,32 @@
|
||||
package com.fastbee.pay.api.api.order;
|
||||
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderCreateReqDTO;
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderRespDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 支付单 API 接口
|
||||
*
|
||||
* @author LeeYan9
|
||||
* @since 2022-08-26
|
||||
*/
|
||||
public interface PayOrderApi {
|
||||
|
||||
/**
|
||||
* 创建支付单
|
||||
*
|
||||
* @param reqDTO 创建请求
|
||||
* @return 支付单编号
|
||||
*/
|
||||
Long createOrder(@Valid PayOrderCreateReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 获得支付单
|
||||
*
|
||||
* @param id 支付单编号
|
||||
* @return 支付单
|
||||
*/
|
||||
PayOrderRespDTO getOrder(Long id);
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.fastbee.pay.api.api.order.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付单创建 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayOrderCreateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 应用编号
|
||||
*/
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
@NotEmpty(message = "用户 IP 不能为空")
|
||||
private String userIp;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
|
||||
/**
|
||||
* 商户订单编号
|
||||
*/
|
||||
@NotEmpty(message = "商户订单编号不能为空")
|
||||
private String merchantOrderId;
|
||||
/**
|
||||
* 商品标题
|
||||
*/
|
||||
@NotEmpty(message = "商品标题不能为空")
|
||||
@Length(max = 32, message = "商品标题不能超过 32")
|
||||
private String subject;
|
||||
/**
|
||||
* 商品描述
|
||||
*/
|
||||
@Length(max = 128, message = "商品描述信息长度不能超过128")
|
||||
private String body;
|
||||
|
||||
// ========== 订单相关字段 ==========
|
||||
|
||||
/**
|
||||
* 支付金额,单位:分
|
||||
*/
|
||||
@NotNull(message = "支付金额不能为空")
|
||||
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
|
||||
private Integer price;
|
||||
|
||||
/**
|
||||
* 支付过期时间
|
||||
*/
|
||||
@NotNull(message = "支付过期时间不能为空")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.fastbee.pay.api.api.order.dto;
|
||||
|
||||
import com.fastbee.pay.api.enums.order.PayOrderStatusEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付单信息 Response DTO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderRespDTO {
|
||||
|
||||
/**
|
||||
* 订单编号,数据库自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 渠道编码
|
||||
* 枚举 PayChannelEnum
|
||||
*/
|
||||
private String channelCode;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
/**
|
||||
* 商户订单编号
|
||||
* 例如说,内部系统 A 的订单号。需要保证每个 PayMerchantDO 唯一
|
||||
*/
|
||||
private String merchantOrderId;
|
||||
|
||||
// ========== 订单相关字段 ==========
|
||||
/**
|
||||
* 支付金额,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 支付状态
|
||||
* 枚举 {@link PayOrderStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
// ========== 渠道相关字段 ==========
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.fastbee.pay.api.api.refund;
|
||||
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundCreateReqDTO;
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundRespDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 退款单 API 接口
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
public interface PayRefundApi {
|
||||
|
||||
/**
|
||||
* 创建退款单
|
||||
*
|
||||
* @param reqDTO 创建请求
|
||||
* @return 退款单编号
|
||||
*/
|
||||
Long createRefund(@Valid PayRefundCreateReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 获得退款单
|
||||
*
|
||||
* @param id 退款单编号
|
||||
* @return 退款单
|
||||
*/
|
||||
PayRefundRespDTO getRefund(Long id);
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.fastbee.pay.api.api.refund.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 退款单创建 Request DTO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayRefundCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 应用编号
|
||||
*/
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
@NotEmpty(message = "用户 IP 不能为空")
|
||||
private String userIp;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
/**
|
||||
* 商户订单编号
|
||||
*/
|
||||
@NotEmpty(message = "商户订单编号不能为空")
|
||||
private String merchantOrderId;
|
||||
|
||||
/**
|
||||
* 商户退款编号
|
||||
*/
|
||||
@NotEmpty(message = "商户退款编号不能为空")
|
||||
private String merchantRefundId;
|
||||
|
||||
/**
|
||||
* 退款描述
|
||||
*/
|
||||
@NotEmpty(message = "退款描述不能为空")
|
||||
@Length(max = 128, message = "退款描述长度不能超过 128")
|
||||
private String reason;
|
||||
|
||||
// ========== 订单相关字段 ==========
|
||||
|
||||
/**
|
||||
* 退款金额,单位:分
|
||||
*/
|
||||
@NotNull(message = "退款金额不能为空")
|
||||
@Min(value = 1, message = "退款金额必须大于零")
|
||||
private Integer price;
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.fastbee.pay.api.api.refund.dto;
|
||||
|
||||
import com.fastbee.pay.api.enums.refund.PayRefundStatusEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 退款单信息 Response DTO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Data
|
||||
public class PayRefundRespDTO {
|
||||
|
||||
/**
|
||||
* 退款单编号
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
// ========== 退款相关字段 ==========
|
||||
/**
|
||||
* 退款状态
|
||||
* 枚举 {@link PayRefundStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 退款金额,单位:分
|
||||
*/
|
||||
private Integer refundPrice;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
/**
|
||||
* 商户订单编号
|
||||
*/
|
||||
private String merchantOrderId;
|
||||
/**
|
||||
* 退款成功时间
|
||||
*/
|
||||
private LocalDateTime successTime;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.fastbee.pay.api.enums;
|
||||
|
||||
/**
|
||||
* Pay 字典类型的枚举类
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
public interface DictTypeConstants {
|
||||
|
||||
String CHANNEL_CODE = "pay_channel_code"; // 支付渠道编码
|
||||
|
||||
String ORDER_STATUS = "pay_order_status"; // 支付渠道
|
||||
|
||||
String REFUND_STATUS = "pay_order_status"; // 退款状态
|
||||
|
||||
String NOTIFY_STATUS = "pay_notify_status"; // 回调状态
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.fastbee.pay.api.enums;
|
||||
|
||||
import com.fastbee.common.exception.ErrorCode;
|
||||
import com.fastbee.common.utils.MessageUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Pay 错误码 Core 枚举类
|
||||
* pay 系统,使用 1-007-000-000 段
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== APP 模块 1007000000 ==========
|
||||
ErrorCode APP_NOT_FOUND = new ErrorCode(1007000000, MessageUtils.message("app.not.found"));
|
||||
ErrorCode APP_IS_DISABLE = new ErrorCode(1007000002, MessageUtils.message("app.is.disable"));
|
||||
ErrorCode APP_EXIST_ORDER_CANT_DELETE = new ErrorCode(1007000003, MessageUtils.message("app.exist.order.cant.delete"));
|
||||
ErrorCode APP_EXIST_REFUND_CANT_DELETE = new ErrorCode(1007000004, MessageUtils.message("app.exist.refund.cant.delete"));
|
||||
|
||||
// ========== CHANNEL 模块 1007001000 ==========
|
||||
ErrorCode CHANNEL_NOT_FOUND = new ErrorCode(1007001000, MessageUtils.message("channel.not.found"));
|
||||
ErrorCode CHANNEL_IS_DISABLE = new ErrorCode(1007001001, MessageUtils.message("channel.is.disable"));
|
||||
ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001004, MessageUtils.message("channel.exists.same.channel.error"));
|
||||
|
||||
// ========== ORDER 模块 1007002000 ==========
|
||||
ErrorCode ORDER_NOT_FOUND = new ErrorCode(1007002000, MessageUtils.message("order.not.found"));
|
||||
ErrorCode ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, MessageUtils.message("order.status.is.not.waiting"));
|
||||
ErrorCode ORDER_STATUS_IS_SUCCESS = new ErrorCode(1007002002, MessageUtils.message("order.status.is.success"));
|
||||
ErrorCode ORDER_IS_EXPIRED = new ErrorCode(1007002003, MessageUtils.message("order.is.expired"));
|
||||
ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, MessageUtils.message("order.submit.channel.error"));
|
||||
ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, MessageUtils.message("order.refund.fail.status.error"));
|
||||
|
||||
// ========== ORDER 模块(拓展单) 1007003000 ==========
|
||||
ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, MessageUtils.message("order.extension.not.found"));
|
||||
ErrorCode ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, MessageUtils.message("order.extension.status.is.not.waiting"));
|
||||
ErrorCode ORDER_EXTENSION_IS_PAID = new ErrorCode(1007003002, MessageUtils.message("order.extension.is.paid"));
|
||||
|
||||
// ========== 支付模块(退款) 1007006000 ==========
|
||||
ErrorCode REFUND_PRICE_EXCEED = new ErrorCode(1007006000, MessageUtils.message("refund.price.exceed"));
|
||||
ErrorCode REFUND_HAS_REFUNDING = new ErrorCode(1007006002, MessageUtils.message("refund.has.refunding"));
|
||||
ErrorCode REFUND_EXISTS = new ErrorCode(1007006003, MessageUtils.message("refund.exists"));
|
||||
ErrorCode REFUND_NOT_FOUND = new ErrorCode(1007006004, MessageUtils.message("refund.not.found"));
|
||||
ErrorCode REFUND_STATUS_IS_NOT_WAITING = new ErrorCode(1007006005, MessageUtils.message("refund.statue.is.not.waiting"));
|
||||
|
||||
// ========== 示例订单 1007900000 ==========
|
||||
ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, MessageUtils.message("demo.order.not.found"));
|
||||
ErrorCode DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1007900001, MessageUtils.message("demo.order.update.paid.status.not.unpaid"));
|
||||
ErrorCode DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1007900002, MessageUtils.message("demo.order.update.paid.fail.pay.order.id.error"));
|
||||
ErrorCode DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1007900003, MessageUtils.message("demo.order.update.paid.fail.pay.order.status.not.success"));
|
||||
ErrorCode DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1007900004, MessageUtils.message("demo.order.update.paid.fail.pay.price.not.match"));
|
||||
ErrorCode DEMO_ORDER_REFUND_FAIL_NOT_PAID = new ErrorCode(1007900005, MessageUtils.message("demo.order.refund.fail.not.paid"));
|
||||
ErrorCode DEMO_ORDER_REFUND_FAIL_REFUNDED = new ErrorCode(1007900006, MessageUtils.message("demo.order.refund.fail.refunded"));
|
||||
ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1007900007, MessageUtils.message("demo.order.refund.fail.refund.not.found"));
|
||||
ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS = new ErrorCode(1007900008, MessageUtils.message("demo.order.refund.fail.refund.not.success"));
|
||||
ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1007900009, MessageUtils.message("demo.order.refund.fail.refund.order.id.error"));
|
||||
ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1007900010, MessageUtils.message("demo.order.refund.fail.refund.price.not.match"));
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.fastbee.pay.api.enums.member;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 钱包操作类型枚举
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WalletOperateTypeEnum {
|
||||
TOP_UP_INC(1, "充值增加"),
|
||||
ORDER_DEC(2, "订单消费扣除");
|
||||
// TODO 其它类型
|
||||
|
||||
private final Integer type;
|
||||
|
||||
private final String desc;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.pay.api.enums.member;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 钱包交易大类枚举
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WalletTransactionGategoryEnum {
|
||||
TOP_UP(1, "充值"),
|
||||
SPENDING(2, "支出");
|
||||
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
private final Integer category;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
private final String desc;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.fastbee.pay.api.enums.notify;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 支付通知状态枚举
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PayNotifyStatusEnum {
|
||||
|
||||
WAITING(0, "等待通知"),
|
||||
SUCCESS(10, "通知成功"),
|
||||
FAILURE(20, "通知失败"), // 多次尝试,彻底失败
|
||||
REQUEST_SUCCESS(21, "请求成功,但是结果失败"),
|
||||
REQUEST_FAILURE(22, "请求失败"),
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.fastbee.pay.api.enums.notify;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 支付通知类型
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PayNotifyTypeEnum {
|
||||
|
||||
ORDER(1, "支付单"),
|
||||
REFUND(2, "退款单"),
|
||||
;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.fastbee.pay.api.enums.order;
|
||||
|
||||
import com.fastbee.common.core.text.IntArrayValuable;
|
||||
import com.fastbee.common.utils.object.ObjectUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 支付订单的状态枚举
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PayOrderStatusEnum implements IntArrayValuable {
|
||||
|
||||
WAITING(0, "未支付"),
|
||||
SUCCESS(10, "支付成功"),
|
||||
REFUND(20, "已退款"),
|
||||
CLOSED(30, "支付关闭"), // 注意:全部退款后,还是 REFUND 状态
|
||||
;
|
||||
|
||||
private final Integer status;
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支付成功
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 是否支付成功
|
||||
*/
|
||||
public static boolean isSuccess(Integer status) {
|
||||
return Objects.equals(status, SUCCESS.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支付成功或者已退款
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 是否支付成功或者已退款
|
||||
*/
|
||||
public static boolean isSuccessOrRefund(Integer status) {
|
||||
return ObjectUtils.equalsAny(status,
|
||||
SUCCESS.getStatus(), REFUND.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支付关闭
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 是否支付关闭
|
||||
*/
|
||||
public static boolean isClosed(Integer status) {
|
||||
return Objects.equals(status, CLOSED.getStatus());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.fastbee.pay.api.enums.refund;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 渠道的退款状态枚举
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PayRefundStatusEnum {
|
||||
|
||||
WAITING(0, "未退款"),
|
||||
SUCCESS(10, "退款成功"),
|
||||
FAILURE(20, "退款失败");
|
||||
|
||||
private final Integer status;
|
||||
private final String name;
|
||||
|
||||
public static boolean isSuccess(Integer status) {
|
||||
return Objects.equals(status, SUCCESS.getStatus());
|
||||
}
|
||||
|
||||
public static boolean isFailure(Integer status) {
|
||||
return Objects.equals(status, FAILURE.getStatus());
|
||||
}
|
||||
|
||||
}
|
68
fastbee-pay/fastbee-pay-core/pom.xml
Normal file
68
fastbee-pay/fastbee-pay-core/pom.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.fastbee.pay</groupId>
|
||||
<artifactId>fastbee-pay</artifactId>
|
||||
<version>3.8.5</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.fastbee.pay.core</groupId>
|
||||
<artifactId>fastbee-pay-core</artifactId>
|
||||
|
||||
<!-- <properties>-->
|
||||
<!-- <maven.compiler.source>8</maven.compiler.source>-->
|
||||
<!-- <maven.compiler.target>8</maven.compiler.target>-->
|
||||
<!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
|
||||
<!-- </properties>-->
|
||||
<dependencies>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.projectlombok</groupId>-->
|
||||
<!-- <artifactId>lombok</artifactId>-->
|
||||
<!-- <version>1.18.22</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.fastbee</groupId>-->
|
||||
<!-- <artifactId>fastbee-common</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.fastbee.pay.framework</groupId>-->
|
||||
<!-- <artifactId>fastbee-pay-framework</artifactId>-->
|
||||
<!-- <version>3.8.5</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.fastbee.pay.api</groupId>
|
||||
<artifactId>fastbee-pay-api</artifactId>
|
||||
<version>3.8.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>13.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.alibaba</groupId>-->
|
||||
<!-- <artifactId>easyexcel-core</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.mapstruct</groupId>-->
|
||||
<!-- <artifactId>mapstruct</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-core</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.google.guava</groupId>-->
|
||||
<!-- <artifactId>guava</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-framework</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,35 @@
|
||||
package com.fastbee.pay.core.api.order;
|
||||
|
||||
import com.fastbee.pay.api.api.order.PayOrderApi;
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderCreateReqDTO;
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderRespDTO;
|
||||
import com.fastbee.pay.core.convert.order.PayOrderConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import com.fastbee.pay.core.service.order.PayOrderService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 支付单 API 实现类
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Service
|
||||
public class PayOrderApiImpl implements PayOrderApi {
|
||||
|
||||
@Resource
|
||||
private PayOrderService payOrderService;
|
||||
|
||||
@Override
|
||||
public Long createOrder(PayOrderCreateReqDTO reqDTO) {
|
||||
return payOrderService.createOrder(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayOrderRespDTO getOrder(Long id) {
|
||||
PayOrder order = payOrderService.getOrder(id);
|
||||
return PayOrderConvert.INSTANCE.convert2(order);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.fastbee.pay.core.api.refund;
|
||||
|
||||
import com.fastbee.pay.api.api.refund.PayRefundApi;
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundCreateReqDTO;
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundRespDTO;
|
||||
import com.fastbee.pay.core.convert.refund.PayRefundConvert;
|
||||
import com.fastbee.pay.core.service.refund.PayRefundService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 退款单 API 实现类
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class PayRefundApiImpl implements PayRefundApi {
|
||||
|
||||
@Resource
|
||||
private PayRefundService payRefundService;
|
||||
|
||||
@Override
|
||||
public Long createRefund(PayRefundCreateReqDTO reqDTO) {
|
||||
return payRefundService.createPayRefund(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayRefundRespDTO getRefund(Long id) {
|
||||
return PayRefundConvert.INSTANCE.convert02(payRefundService.getRefund(id));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.fastbee.pay.core.controller.admin.app;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.pay.core.controller.admin.app.vo.*;
|
||||
import com.fastbee.pay.core.convert.app.PayAppConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import com.fastbee.pay.core.service.app.PayAppService;
|
||||
import com.fastbee.pay.core.service.channel.PayChannelService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.collection.CollectionUtils.convertList;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Api(tags = "管理后台 - 支付应用信息")
|
||||
@RestController
|
||||
@RequestMapping("/pay/app")
|
||||
@Validated
|
||||
public class PayAppController {
|
||||
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建支付应用信息")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:create')")
|
||||
public CommonResult<Long> createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) {
|
||||
return success(appService.createApp(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新支付应用信息")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:update')")
|
||||
public CommonResult<Boolean> updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) {
|
||||
appService.updateApp(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@ApiOperation("更新支付应用状态")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:update')")
|
||||
public CommonResult<Boolean> updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) {
|
||||
appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除支付应用信息")
|
||||
@ApiParam(name = "id", value = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:delete')")
|
||||
public CommonResult<Boolean> deleteApp(@RequestParam("id") Long id) {
|
||||
appService.deleteApp(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得支付应用信息")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<PayAppRespVO> getApp(@RequestParam("id") Long id) {
|
||||
PayApp app = appService.getApp(id);
|
||||
return success(PayAppConvert.INSTANCE.convert(app));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得支付应用信息分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<PageResult<PayAppPageItemRespVO>> getAppPage(@Valid PayAppPageReqVO pageVO) {
|
||||
// 得到应用分页列表
|
||||
PageResult<PayApp> pageResult = appService.getAppPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
|
||||
// 得到所有的应用编号,查出所有的渠道
|
||||
Collection<Long> appIds = convertList(pageResult.getList(), PayApp::getId);
|
||||
List<PayChannel> channels = channelService.getChannelListByAppIds(appIds);
|
||||
|
||||
// 拼接后返回
|
||||
return success(PayAppConvert.INSTANCE.convertPage(pageResult, channels));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得应用列表")
|
||||
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
|
||||
public CommonResult<List<PayAppRespVO>> getAppList() {
|
||||
List<PayApp> appListDO = appService.getAppList();
|
||||
return success(PayAppConvert.INSTANCE.convertList(appListDO));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用名", required = true, example = "小豆")
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", required = true, example = "0")
|
||||
@NotNull(message = "开启状态不能为空")
|
||||
// @InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "我是一个测试应用")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "支付结果的回调地址", required = true, example = "http://127.0.0.1:48080/pay-callback")
|
||||
@NotNull(message = "支付结果的回调地址不能为空")
|
||||
@URL(message = "支付结果的回调地址必须为 URL 格式")
|
||||
private String orderNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "退款结果的回调地址", required = true, example = "http://127.0.0.1:48080/refund-callback")
|
||||
@NotNull(message = "退款结果的回调地址不能为空")
|
||||
@URL(message = "退款结果的回调地址必须为 URL 格式")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付应用信息创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppCreateReqVO extends PayAppBaseVO {
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付应用信息分页查询 Response VO,相比于支付信息,还会多出应用渠道的开关信息")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppPageItemRespVO extends PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "已配置的支付渠道编码", required = true, example = "[alipay_pc, alipay_wap]")
|
||||
private Set<String> channelCodes;
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import com.fastbee.common.core.domain.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付应用信息分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "应用名", example = "小豆")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付应用信息 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppRespVO extends PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付应用信息更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppUpdateReqVO extends PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.fastbee.pay.core.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(description = "管理后台 - 应用更新状态 Request VO")
|
||||
@Data
|
||||
public class PayAppUpdateStatusReqVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "状态,见 SysCommonStatusEnum 枚举", required = true, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.fastbee.pay.core.controller.admin.channel;
|
||||
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.pay.core.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.channel.vo.PayChannelRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||
import com.fastbee.pay.core.convert.channel.PayChannelConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import com.fastbee.pay.core.service.channel.PayChannelService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Api(tags = "管理后台 - 支付渠道")
|
||||
@RestController
|
||||
@RequestMapping("/pay/channel")
|
||||
@Validated
|
||||
public class PayChannelController {
|
||||
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建支付渠道")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:create')")
|
||||
public CommonResult<Long> createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) {
|
||||
return success(channelService.createChannel(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新支付渠道")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:update')")
|
||||
public CommonResult<Boolean> updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) {
|
||||
channelService.updateChannel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除支付渠道")
|
||||
@ApiParam(name = "id", value = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:delete')")
|
||||
public CommonResult<Boolean> deleteChannel(@RequestParam("id") Long id) {
|
||||
channelService.deleteChannel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得支付渠道")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
||||
public CommonResult<PayChannelRespVO> getChannel(@RequestParam(value = "id", required = false) Long id,
|
||||
@RequestParam(value = "appId", required = false) Long appId,
|
||||
@RequestParam(value = "code", required = false) String code) {
|
||||
PayChannel channel = null;
|
||||
if (id != null) {
|
||||
channel = channelService.getChannel(id);
|
||||
} else if (appId != null && code != null) {
|
||||
channel = channelService.getChannelByAppIdAndCode(appId, code);
|
||||
}
|
||||
return success(new PayChannelRespVO());
|
||||
// return success(PayChannelConvert.INSTANCE.convert(channel));
|
||||
}
|
||||
|
||||
@GetMapping("/get-enable-code-list")
|
||||
@ApiOperation("获得指定应用的开启的支付渠道编码列表")
|
||||
@ApiParam(name = "appId", value = "应用编号", required = true, example = "1")
|
||||
public CommonResult<Set<String>> getEnableChannelCodeList(@RequestParam("appId") Long appId) {
|
||||
List<PayChannel> channels = channelService.getEnableChannelList(appId);
|
||||
return success(convertSet(channels, PayChannel::getCode));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.fastbee.pay.core.controller.admin.channel.vo;
|
||||
|
||||
import com.fastbee.common.enums.CommonStatusEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 支付渠道 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "开启状态", required = true, example = "1")
|
||||
@NotNull(message = "开启状态不能为空")
|
||||
// @InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "我是小备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "渠道费率,单位:百分比", required = true, example = "10")
|
||||
@NotNull(message = "渠道费率,单位:百分比不能为空")
|
||||
private Double feeRate;
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.pay.core.controller.admin.channel.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付渠道 创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelCreateReqVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", required = true, example = "alipay_pc")
|
||||
@NotNull(message = "渠道编码不能为空")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "渠道配置的 json 字符串")
|
||||
@NotBlank(message = "渠道配置不能为空")
|
||||
private String config;
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastbee.pay.core.controller.admin.channel.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付渠道 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelRespVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true, example = "1024")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", required = true, example = "alipay_pc")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "配置", required = true)
|
||||
private String config;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.pay.core.controller.admin.channel.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付渠道 更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelUpdateReqVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "渠道配置的json字符串")
|
||||
@NotBlank(message = "渠道配置不能为空")
|
||||
private String config;
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.fastbee.pay.core.controller.admin.demo;
|
||||
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.common.core.domain.PageParam;
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.pay.api.api.notify.dto.PayOrderNotifyReqDTO;
|
||||
import com.fastbee.pay.api.api.notify.dto.PayRefundNotifyReqDTO;
|
||||
import com.fastbee.pay.core.controller.admin.demo.vo.OrderInfoCreateReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.demo.vo.OrderInfoRespVO;
|
||||
import com.fastbee.pay.core.convert.demo.OrderInfoConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.demo.OrderInfo;
|
||||
import com.fastbee.pay.core.service.demo.OrderInfoService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
|
||||
import static com.fastbee.common.utils.ServletUtils.getClientIP;
|
||||
|
||||
@Api(tags = "管理后台 - 示例订单")
|
||||
@RestController
|
||||
@RequestMapping("/order")
|
||||
@Validated
|
||||
public class OrderInfoController {
|
||||
|
||||
@Resource
|
||||
private OrderInfoService OrderInfoService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建示例订单")
|
||||
public CommonResult<Long> createOrder(@Valid @RequestBody OrderInfoCreateReqVO createReqVO) {
|
||||
return success(OrderInfoService.createOrder(getLoginUser().getUserId(), createReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得示例订单分页")
|
||||
public CommonResult<PageResult<OrderInfoRespVO>> getOrderPage(@Valid PageParam pageVO) {
|
||||
PageResult<OrderInfo> pageResult = OrderInfoService.getOrderPage(pageVO);
|
||||
return success(OrderInfoConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@PostMapping("/update-paid")
|
||||
@ApiOperation("更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
@PermitAll // 无需登录,安全由 OrderInfoService 内部校验实现
|
||||
// @OperateLog(enable = false) // 禁用操作日志,因为没有操作人
|
||||
public CommonResult<Boolean> updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
|
||||
OrderInfoService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
|
||||
notifyReqDTO.getPayOrderId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/refund")
|
||||
@ApiOperation("发起示例订单的退款")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> refundOrder(@RequestParam("id") Long id) {
|
||||
OrderInfoService.refundOrder(id, getClientIP());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/update-refunded")
|
||||
@ApiOperation("更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
@PermitAll // 无需登录,安全由 OrderInfoService 内部校验实现
|
||||
// @OperateLog(enable = false) // 禁用操作日志,因为没有操作人
|
||||
public CommonResult<Boolean> updateOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) {
|
||||
OrderInfoService.updateOrderRefunded(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
|
||||
notifyReqDTO.getPayRefundId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.fastbee.pay.core.controller.admin.demo.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(description = "管理后台 - 示例订单创建 Request VO")
|
||||
@Data
|
||||
public class OrderInfoCreateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "商品编号", required = true, example = "17682")
|
||||
@NotNull(message = "商品编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.fastbee.pay.core.controller.admin.demo.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 示例订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class OrderInfoRespVO {
|
||||
|
||||
@ApiModelProperty(value = "订单编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "23199")
|
||||
private Long userId;
|
||||
|
||||
@ApiModelProperty(value = "商品编号", required = true, example = "17682")
|
||||
private Long spuId;
|
||||
|
||||
@ApiModelProperty(value = "商家备注", example = "李四")
|
||||
private String spuName;
|
||||
|
||||
@ApiModelProperty(value = "价格,单位:分", required = true, example = "30381")
|
||||
private Integer price;
|
||||
|
||||
@ApiModelProperty(value = "是否已支付", required = true)
|
||||
private Boolean payStatus;
|
||||
|
||||
@ApiModelProperty(value = "支付订单编号", example = "16863")
|
||||
private Long payOrderId;
|
||||
|
||||
@ApiModelProperty(value = "订单支付时间")
|
||||
private LocalDateTime payTime;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道", example = "alipay_qr")
|
||||
private String payChannelCode;
|
||||
|
||||
@ApiModelProperty(value = "支付退款编号", example = "23366")
|
||||
private Long payRefundId;
|
||||
|
||||
@ApiModelProperty(value = "退款金额,单位:分", required = true, example = "14039")
|
||||
private Integer refundPrice;
|
||||
|
||||
@ApiModelProperty(value = "退款时间")
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
package com.fastbee.pay.core.controller.admin.notify;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.common.utils.MessageUtils;
|
||||
import com.fastbee.pay.core.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.notify.vo.PayNotifyTaskRespVO;
|
||||
import com.fastbee.pay.core.convert.notify.PayNotifyTaskConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.notify.PayNotifyLog;
|
||||
import com.fastbee.pay.core.domain.dataobject.notify.PayNotifyTask;
|
||||
import com.fastbee.pay.core.service.app.PayAppService;
|
||||
import com.fastbee.pay.core.service.notify.PayNotifyService;
|
||||
import com.fastbee.pay.core.service.order.PayOrderService;
|
||||
import com.fastbee.pay.core.service.refund.PayRefundService;
|
||||
import com.fastbee.pay.framework.client.PayClient;
|
||||
import com.fastbee.pay.framework.client.PayClientFactory;
|
||||
import com.fastbee.pay.framework.client.dto.order.PayOrderRespDTO;
|
||||
import com.fastbee.pay.framework.client.dto.refund.PayRefundRespDTO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.exception.ServiceExceptionUtil.exception;
|
||||
import static com.fastbee.common.utils.collection.CollectionUtils.convertList;
|
||||
import static com.fastbee.pay.api.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND;
|
||||
|
||||
|
||||
@Api(tags = "管理后台 - 回调通知")
|
||||
@RestController
|
||||
@RequestMapping("/pay/notify")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class PayNotifyController {
|
||||
|
||||
@Resource
|
||||
private PayOrderService orderService;
|
||||
@Resource
|
||||
private PayRefundService refundService;
|
||||
@Resource
|
||||
private PayNotifyService notifyService;
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
|
||||
@Resource
|
||||
private PayClientFactory payClientFactory;
|
||||
|
||||
@PostMapping(value = "/order/{channelId}")
|
||||
@ApiOperation("支付渠道的统一【支付】回调")
|
||||
@PermitAll
|
||||
// @OperateLog(enable = false) // 回调地址,无需记录操作日志
|
||||
public String notifyOrder(@PathVariable("channelId") Long channelId,
|
||||
@RequestParam(required = false) Map<String, String> params,
|
||||
@RequestBody(required = false) String body) {
|
||||
log.info("[notifyOrder][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||
// 1. 校验支付渠道是否存在
|
||||
PayClient payClient = payClientFactory.getPayClient(channelId);
|
||||
if (payClient == null) {
|
||||
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||
throw exception(CHANNEL_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 2. 解析通知数据
|
||||
PayOrderRespDTO notify = payClient.parseOrderNotify(params, body);
|
||||
orderService.notifyOrder(channelId, notify);
|
||||
return MessageUtils.message("success");
|
||||
}
|
||||
|
||||
@PostMapping(value = "/refund/{channelId}")
|
||||
@ApiOperation("支付渠道的统一【退款】回调")
|
||||
@PermitAll
|
||||
// @OperateLog(enable = false) // 回调地址,无需记录操作日志
|
||||
public String notifyRefund(@PathVariable("channelId") Long channelId,
|
||||
@RequestParam(required = false) Map<String, String> params,
|
||||
@RequestBody(required = false) String body) {
|
||||
log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||
// 1. 校验支付渠道是否存在
|
||||
PayClient payClient = payClientFactory.getPayClient(channelId);
|
||||
if (payClient == null) {
|
||||
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||
throw exception(CHANNEL_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 2. 解析通知数据
|
||||
PayRefundRespDTO notify = payClient.parseRefundNotify(params, body);
|
||||
refundService.notifyRefund(channelId, notify);
|
||||
return MessageUtils.message("success");
|
||||
}
|
||||
|
||||
@GetMapping("/get-detail")
|
||||
@ApiOperation("获得回调通知的明细")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:notify:query')")
|
||||
public CommonResult<PayNotifyTaskDetailRespVO> getNotifyTaskDetail(@RequestParam("id") Long id) {
|
||||
PayNotifyTask task = notifyService.getNotifyTask(id);
|
||||
if (task == null) {
|
||||
return success(null);
|
||||
}
|
||||
// 拼接返回
|
||||
PayApp app = appService.getApp(task.getAppId());
|
||||
List<PayNotifyLog> logs = notifyService.getNotifyLogList(id);
|
||||
return success(PayNotifyTaskConvert.INSTANCE.convert(task, app, logs));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得回调通知分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:notify:query')")
|
||||
public CommonResult<PageResult<PayNotifyTaskRespVO>> getNotifyTaskPage(@Valid PayNotifyTaskPageReqVO pageVO) {
|
||||
PageResult<PayNotifyTask> pageResult = notifyService.getNotifyTaskPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
// 拼接返回
|
||||
Map<Long, PayApp> appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTask::getAppId));
|
||||
return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.fastbee.pay.core.controller.admin.notify.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 回调通知 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayNotifyTaskBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "10636")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "通知类型", required = true, example = "2")
|
||||
private Byte type;
|
||||
|
||||
@ApiModelProperty(value = "数据编号", required = true, example = "6722")
|
||||
private Long dataId;
|
||||
|
||||
@ApiModelProperty(value = "通知状态", required = true, example = "1")
|
||||
private Byte status;
|
||||
|
||||
@ApiModelProperty(value = "商户订单编号", required = true, example = "26697")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "下一次通知时间", required = true)
|
||||
private LocalDateTime nextNotifyTime;
|
||||
|
||||
@ApiModelProperty(value = "最后一次执行时间", required = true)
|
||||
private LocalDateTime lastExecuteTime;
|
||||
|
||||
@ApiModelProperty(value = "当前通知次数", required = true)
|
||||
private Byte notifyTimes;
|
||||
|
||||
@ApiModelProperty(value = "最大可通知次数", required = true)
|
||||
private Byte maxNotifyTimes;
|
||||
|
||||
@ApiModelProperty(value = "异步通知地址", required = true, example = "https://www.iocoder.cn")
|
||||
private String notifyUrl;
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
|
||||
package com.fastbee.pay.core.controller.admin.notify.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(description = "管理后台 - 回调通知的明细 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayNotifyTaskDetailRespVO extends PayNotifyTaskBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "任务编号", required = true, example = "3380")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间", required = true)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@ApiModelProperty(value = "应用名称", example = "wx_pay")
|
||||
private String appName;
|
||||
|
||||
@ApiModelProperty(value = "回调日志列表")
|
||||
private List<Log> logs;
|
||||
|
||||
@ApiModel(description = "管理后台 - 回调日志")
|
||||
@Data
|
||||
public static class Log {
|
||||
|
||||
@ApiModelProperty(value = "日志编号", required = true, example = "8848")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "通知状态", required = true, example = "1")
|
||||
private Byte status;
|
||||
|
||||
@ApiModelProperty(value = "当前通知次数", required = true)
|
||||
private Byte notifyTimes;
|
||||
|
||||
@ApiModelProperty(value = "HTTP 响应结果", required = true)
|
||||
private String response;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.fastbee.pay.core.controller.admin.notify.vo;
|
||||
|
||||
import com.fastbee.common.core.domain.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
@ApiModel(description = "管理后台 - 回调通知分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayNotifyTaskPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", example = "10636")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "通知类型", example = "2")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty(value = "数据编号", example = "6722")
|
||||
private Long dataId;
|
||||
|
||||
@ApiModelProperty(value = "通知状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "商户订单编号", example = "26697")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.pay.core.controller.admin.notify.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 回调通知 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayNotifyTaskRespVO extends PayNotifyTaskBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "任务编号", required = true, example = "3380")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "应用名称", example = "wx_pay")
|
||||
private String appName;
|
||||
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.fastbee.pay.core.controller.admin.order;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderDetailsRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderExcelVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderExportReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderPageItemRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderPageReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||
import com.fastbee.pay.core.convert.order.PayOrderConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrderExtension;
|
||||
import com.fastbee.pay.core.service.app.PayAppService;
|
||||
import com.fastbee.pay.core.service.order.PayOrderService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.ServletUtils.getClientIP;
|
||||
import static com.fastbee.common.utils.collection.CollectionUtils.convertList;
|
||||
|
||||
|
||||
@Api(tags = "管理后台 - 支付订单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/order")
|
||||
@Validated
|
||||
public class PayOrderController {
|
||||
|
||||
@Resource
|
||||
private PayOrderService orderService;
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得支付订单")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||
public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id) {
|
||||
return success(PayOrderConvert.INSTANCE.convert(orderService.getOrder(id)));
|
||||
}
|
||||
|
||||
@GetMapping("/get-detail")
|
||||
@ApiOperation("获得支付订单详情")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||
public CommonResult<PayOrderDetailsRespVO> getOrderDetail(@RequestParam("id") Long id) {
|
||||
PayOrder order = orderService.getOrder(id);
|
||||
if (order == null) {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
PayApp app = appService.getApp(order.getAppId());
|
||||
PayOrderExtension orderExtension = orderService.getOrderExtension(order.getExtensionId());
|
||||
return success(PayOrderConvert.INSTANCE.convert(order, orderExtension, app));
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
@ApiOperation("提交支付订单")
|
||||
public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
|
||||
PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP());
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得支付订单分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||
public CommonResult<PageResult<PayOrderPageItemRespVO>> getOrderPage(@Valid PayOrderPageReqVO pageVO) {
|
||||
PageResult<PayOrder> pageResult = orderService.getOrderPage(pageVO);
|
||||
if (CollectionUtil.isEmpty(pageResult.getList())) {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<Long, PayApp> appMap = appService.getAppMap(convertList(pageResult.getList(), PayOrder::getAppId));
|
||||
return success(PayOrderConvert.INSTANCE.convertPage(pageResult, appMap));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiOperation("导出支付订单 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:export')")
|
||||
// @OperateLog(type = EXPORT)
|
||||
public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<PayOrder> list = orderService.getOrderList(exportReqVO);
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
// ExcelUtils.write(response, "支付订单.xls", "数据",
|
||||
// PayOrderExcelVO.class, new ArrayList<>());
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<Long, PayApp> appMap = appService.getAppMap(convertList(list, PayOrder::getAppId));
|
||||
List<PayOrderExcelVO> excelList = PayOrderConvert.INSTANCE.convertList(list, appMap);
|
||||
// 导出 Excel
|
||||
// ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelList);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
/**
|
||||
* 支付订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编号", example = "2048")
|
||||
private Long channelId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "商户订单编号", required = true, example = "888")
|
||||
@NotNull(message = "商户订单编号不能为空")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "商品标题", required = true, example = "土豆")
|
||||
@NotNull(message = "商品标题不能为空")
|
||||
private String subject;
|
||||
|
||||
@ApiModelProperty(value = "商品描述", required = true, example = "我是土豆")
|
||||
@NotNull(message = "商品描述不能为空")
|
||||
private String body;
|
||||
|
||||
@ApiModelProperty(value = "异步通知地址", required = true, example = "http://127.0.0.1:48080/pay/notify")
|
||||
@NotNull(message = "异步通知地址不能为空")
|
||||
private String notifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "支付金额,单位:分", required = true, example = "10")
|
||||
@NotNull(message = "支付金额,单位:分不能为空")
|
||||
private Long price;
|
||||
|
||||
@ApiModelProperty(value = "渠道手续费,单位:百分比", example = "10")
|
||||
private Double channelFeeRate;
|
||||
|
||||
@ApiModelProperty(value = "渠道手续金额,单位:分", example = "100")
|
||||
private Integer channelFeePrice;
|
||||
|
||||
@ApiModelProperty(value = "支付状态", required = true, example = "1")
|
||||
@NotNull(message = "支付状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
|
||||
@NotNull(message = "用户 IP不能为空")
|
||||
private String userIp;
|
||||
|
||||
@ApiModelProperty(value = "订单失效时间", required = true)
|
||||
@NotNull(message = "订单失效时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@ApiModelProperty(value = "订单支付成功时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@ApiModelProperty(value = "支付成功的订单拓展单编号", example = "50")
|
||||
private Long extensionId;
|
||||
|
||||
@ApiModelProperty(value = "支付订单号", example = "2048888")
|
||||
private String no;
|
||||
|
||||
@ApiModelProperty(value = "退款总金额,单位:分", required = true, example = "10")
|
||||
@NotNull(message = "退款总金额,单位:分不能为空")
|
||||
private Long refundPrice;
|
||||
|
||||
@ApiModelProperty(value = "渠道用户编号", example = "2048")
|
||||
private String channelUserId;
|
||||
|
||||
@ApiModelProperty(value = "渠道订单号", example = "4096")
|
||||
private String channelOrderNo;
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单详细信息 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderDetailsRespVO extends PayOrderBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "支付订单编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "应用名称", required = true, example = "fastbee")
|
||||
private String appName;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间", required = true)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 支付订单扩展
|
||||
*/
|
||||
private PayOrderExtension extension;
|
||||
|
||||
@Data
|
||||
@ApiModel(description = "支付订单扩展")
|
||||
public static class PayOrderExtension {
|
||||
|
||||
@ApiModelProperty(value = "支付订单号", required = true, example = "1024")
|
||||
private String no;
|
||||
|
||||
@ApiModelProperty(value = "支付异步通知的内容")
|
||||
private String channelNotifyData;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fastbee.pay.api.enums.DictTypeConstants;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付订单 Excel VO
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderExcelVO {
|
||||
|
||||
@ExcelProperty("编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ExcelProperty(value = "支付金额")
|
||||
private Integer price;
|
||||
|
||||
@ExcelProperty(value = "退款金额")
|
||||
private Integer refundPrice;
|
||||
|
||||
@ExcelProperty(value = "手续金额")
|
||||
private Integer channelFeePrice;
|
||||
|
||||
@ExcelProperty("商户单号")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ExcelProperty(value = "支付单号")
|
||||
private String no;
|
||||
|
||||
@ExcelProperty("渠道单号")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ExcelProperty(value = "支付状态")
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty(value = "渠道编号名称")
|
||||
private String channelCode;
|
||||
|
||||
@ExcelProperty("订单支付成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@ExcelProperty("订单失效时间")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@ExcelProperty(value = "应用名称")
|
||||
private String appName;
|
||||
|
||||
@ExcelProperty("商品标题")
|
||||
private String subject;
|
||||
|
||||
@ExcelProperty("商品描述")
|
||||
private String body;
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单 Excel 导出 Request VO,参数和 PayOrderPageReqVO 是一致的")
|
||||
@Data
|
||||
public class PayOrderExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "商户订单编号", example = "4096")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编号", example = "1888")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ApiModelProperty(value = "支付单号", example = "2014888")
|
||||
private String no;
|
||||
|
||||
@ApiModelProperty(value = "支付状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderPageItemRespVO extends PayOrderBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "支付订单编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "应用名称", example = "wx_pay")
|
||||
private String appName;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import com.fastbee.common.core.domain.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "商户订单编号", example = "4096")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编号", example = "1888")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ApiModelProperty(value = "支付单号", example = "2014888")
|
||||
private String no;
|
||||
|
||||
@ApiModelProperty(value = "支付状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderRespVO extends PayOrderBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "支付订单编号", required = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单提交 Request VO")
|
||||
@Data
|
||||
public class PayOrderSubmitReqVO {
|
||||
|
||||
@ApiModelProperty(value = "支付单编号", required = true, example = "1024")
|
||||
@NotNull(message = "支付单编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道", required = true, example = "wx_pub")
|
||||
@NotEmpty(message = "支付渠道不能为空")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数")
|
||||
private Map<String, String> channelExtras;
|
||||
|
||||
@ApiModelProperty(value = "展示模式", example = "url") // 参见 {@link PayDisplayModeEnum} 枚举。如果不传递,则每个支付渠道使用默认的方式
|
||||
private String displayMode;
|
||||
|
||||
@ApiModelProperty(value = "回跳地址")
|
||||
@URL(message = "回跳地址的格式必须是 URL")
|
||||
private String returnUrl;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.fastbee.pay.core.controller.admin.order.vo;
|
||||
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(description = "管理后台 - 支付订单提交 Response VO")
|
||||
@Data
|
||||
public class PayOrderSubmitRespVO {
|
||||
|
||||
@ApiModelProperty(value = "支付状态", required = true, example = "10") // 参见 PayOrderStatusEnum 枚举
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "展示模式", required = true, example = "url") // 参见 PayDisplayModeEnum 枚举
|
||||
private String displayMode;
|
||||
|
||||
@ApiModelProperty(value = "展示内容", required = true)
|
||||
private String displayContent;
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.pay.core.controller.admin.refund.vo.*;
|
||||
import com.fastbee.pay.core.convert.refund.PayRefundConvert;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.refund.PayRefund;
|
||||
import com.fastbee.pay.core.service.app.PayAppService;
|
||||
import com.fastbee.pay.core.service.refund.PayRefundService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.collection.CollectionUtils.convertList;
|
||||
|
||||
|
||||
@Api(tags = "管理后台 - 退款订单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/refund")
|
||||
@Validated
|
||||
public class PayRefundController {
|
||||
|
||||
@Resource
|
||||
private PayRefundService refundService;
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得退款订单")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:refund:query')")
|
||||
public CommonResult<PayRefundDetailsRespVO> getRefund(@RequestParam("id") Long id) {
|
||||
PayRefund refund = refundService.getRefund(id);
|
||||
if (refund == null) {
|
||||
return success(new PayRefundDetailsRespVO());
|
||||
}
|
||||
|
||||
// 拼接数据
|
||||
PayApp app = appService.getApp(refund.getAppId());
|
||||
return success(PayRefundConvert.INSTANCE.convert(refund, app));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiModelProperty("获得退款订单分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:refund:query')")
|
||||
public CommonResult<PageResult<PayRefundPageItemRespVO>> getRefundPage(@Valid PayRefundPageReqVO pageVO) {
|
||||
PageResult<PayRefund> pageResult = refundService.getRefundPage(pageVO);
|
||||
if (CollectionUtil.isEmpty(pageResult.getList())) {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 处理应用ID数据
|
||||
Map<Long, PayApp> appMap = appService.getAppMap(convertList(pageResult.getList(), PayRefund::getAppId));
|
||||
return success(PayRefundConvert.INSTANCE.convertPage(pageResult, appMap));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiModelProperty("导出退款订单 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('pay:refund:export')")
|
||||
// @OperateLog(type = EXPORT)
|
||||
public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<PayRefund> list = refundService.getRefundList(exportReqVO);
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
// ExcelUtils.write(response, "退款订单.xls", "数据",
|
||||
// PayRefundExcelVO.class, new ArrayList<>());
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<Long, PayApp> appMap = appService.getAppMap(convertList(list, PayRefund::getAppId));
|
||||
List<PayRefundExcelVO> excelList = PayRefundConvert.INSTANCE.convertList(list, appMap);
|
||||
// 导出 Excel
|
||||
// ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelList);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 退款订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayRefundBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "外部退款号", required = true, example = "110")
|
||||
private String no;
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编号", required = true, example = "2048")
|
||||
private Long channelId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", required = true, example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "订单编号", required = true, example = "1024")
|
||||
private Long orderId;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
|
||||
@ApiModelProperty(value = "商户订单编号", required = true, example = "225")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "商户退款订单号", required = true, example = "512")
|
||||
private String merchantRefundId;
|
||||
|
||||
@ApiModelProperty(value = "异步通知地址", required = true)
|
||||
private String notifyUrl;
|
||||
|
||||
// ========== 退款相关字段 ==========
|
||||
|
||||
@ApiModelProperty(value = "退款状态", required = true, example = "0")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "支付金额", required = true, example = "100")
|
||||
private Long payPrice;
|
||||
|
||||
@ApiModelProperty(value = "退款金额,单位分", required = true, example = "200")
|
||||
private Long refundPrice;
|
||||
|
||||
@ApiModelProperty(value = "退款原因", required = true, example = "我要退了")
|
||||
private String reason;
|
||||
|
||||
@ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
|
||||
private String userIp;
|
||||
|
||||
// ========== 渠道相关字段 ==========
|
||||
|
||||
@ApiModelProperty(value = "渠道订单号", required = true, example = "233")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ApiModelProperty(value = "渠道退款单号", example = "2022")
|
||||
private String channelRefundNo;
|
||||
|
||||
@ApiModelProperty(value = "退款成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@ApiModelProperty(value = "调用渠道的错误码")
|
||||
private String channelErrorCode;
|
||||
|
||||
@ApiModelProperty(value = "调用渠道的错误提示")
|
||||
private String channelErrorMsg;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道的额外参数")
|
||||
private String channelNotifyData;
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 退款订单详情 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayRefundDetailsRespVO extends PayRefundBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "支付退款编号", required = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "应用名称", required = true, example = "我是fastbee")
|
||||
private String appName;
|
||||
|
||||
@ApiModelProperty(value = "支付订单", required = true)
|
||||
private Order order;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@ApiModel(value = "管理后台 - 支付订单")
|
||||
@Data
|
||||
public static class Order {
|
||||
|
||||
@ApiModelProperty(value = "商品标题", required = true, example = "土豆")
|
||||
private String subject;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fastbee.common.annotation.DictFormat;
|
||||
import com.fastbee.pay.api.enums.DictTypeConstants;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 退款订单 Excel VO
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Data
|
||||
public class PayRefundExcelVO {
|
||||
|
||||
@ExcelProperty("支付退款编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ExcelProperty(value = "支付金额")
|
||||
private Integer payPrice;
|
||||
|
||||
@ExcelProperty(value = "退款金额")
|
||||
private Integer refundPrice;
|
||||
|
||||
@ExcelProperty("商户退款单号")
|
||||
private String merchantRefundId;
|
||||
@ExcelProperty("退款单号")
|
||||
private String no;
|
||||
@ExcelProperty("渠道退款单号")
|
||||
private String channelRefundNo;
|
||||
|
||||
@ExcelProperty("商户支付单号")
|
||||
private String merchantOrderId;
|
||||
@ExcelProperty("渠道支付单号")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ExcelProperty(value = "退款状态")
|
||||
// @DictFormat(DictTypeConstants.REFUND_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty(value = "退款渠道")
|
||||
// @DictFormat(DictTypeConstants.CHANNEL_CODE)
|
||||
private String channelCode;
|
||||
|
||||
@ExcelProperty("成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@ExcelProperty(value = "支付应用")
|
||||
private String appName;
|
||||
|
||||
@ExcelProperty("退款原因")
|
||||
private String reason;
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
@ApiModel(description = "管理后台 - 退款订单 Excel 导出 Request VO,参数和 PayRefundPageReqVO 是一致的")
|
||||
@Data
|
||||
public class PayRefundExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "商户支付单号", example = "10")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "商户退款单号", example = "20")
|
||||
private String merchantRefundId;
|
||||
|
||||
@ApiModelProperty(value = "渠道支付单号", example = "30")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ApiModelProperty(value = "渠道退款单号", example = "40")
|
||||
private String channelRefundNo;
|
||||
|
||||
@ApiModelProperty(value = "退款状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund.vo;
|
||||
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "管理后台 - 退款订单分页查询 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayRefundPageItemRespVO extends PayRefundBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "支付订单编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "应用名称", required = true, example = "我是fastbee")
|
||||
private String appName;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.fastbee.pay.core.controller.admin.refund.vo;
|
||||
|
||||
import com.fastbee.common.core.domain.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.fastbee.common.utils.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
@ApiModel(description = "管理后台 - 退款订单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayRefundPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@ApiModelProperty(value = "商户支付单号", example = "10")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ApiModelProperty(value = "商户退款单号", example = "20")
|
||||
private String merchantRefundId;
|
||||
|
||||
@ApiModelProperty(value = "渠道支付单号", example = "30")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ApiModelProperty(value = "渠道退款单号", example = "40")
|
||||
private String channelRefundNo;
|
||||
|
||||
@ApiModelProperty(value = "退款状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.fastbee.pay.core.controller.app.channel;
|
||||
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import com.fastbee.pay.core.service.channel.PayChannelService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.collection.CollectionUtils.convertSet;
|
||||
|
||||
|
||||
@Api(tags = "用户 App - 支付渠道")
|
||||
@RestController
|
||||
@RequestMapping("/pay/channel")
|
||||
@Validated
|
||||
public class AppPayChannelController {
|
||||
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
@GetMapping("/get-enable-code-list")
|
||||
@ApiOperation("获得指定应用的开启的支付渠道编码列表")
|
||||
@ApiParam(name = "appId", value = "应用编号", required = true, example = "1")
|
||||
public CommonResult<Set<String>> getEnableChannelCodeList(@RequestParam("appId") Long appId) {
|
||||
List<PayChannel> channels = channelService.getEnableChannelList(appId);
|
||||
return success(convertSet(channels, PayChannel::getCode));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
### /pay/create 提交支付订单【alipay_pc】
|
||||
POST {{appApi}}/pay/order/submit
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{appToken}}
|
||||
tenant-id: {{appTenentId}}
|
||||
|
||||
{
|
||||
"id": 174,
|
||||
"channelCode": "alipay_pc"
|
||||
}
|
||||
|
||||
### /pay/create 提交支付订单【wx_bar】
|
||||
POST {{appApi}}/pay/order/submit
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{appToken}}
|
||||
tenant-id: {{appTenentId}}
|
||||
|
||||
{
|
||||
"id": 202,
|
||||
"channelCode": "wx_bar",
|
||||
"channelExtras": {
|
||||
"authCode": "134042110834344848"
|
||||
}
|
||||
}
|
||||
|
||||
### /pay/create 提交支付订单【wx_pub】
|
||||
POST {{appApi}}/pay/order/submit
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{appToken}}
|
||||
tenant-id: {{appTenentId}}
|
||||
|
||||
{
|
||||
"id": 202,
|
||||
"channelCode": "wx_pub",
|
||||
"channelExtras": {
|
||||
"openid": "ockUAwIZ-0OeMZl9ogcZ4ILrGba0"
|
||||
}
|
||||
}
|
||||
|
||||
### /pay/create 提交支付订单【wx_lite】
|
||||
POST {{appApi}}/pay/order/submit
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{appToken}}
|
||||
tenant-id: {{appTenentId}}
|
||||
|
||||
{
|
||||
"id": 202,
|
||||
"channelCode": "wx_lite",
|
||||
"channelExtras": {
|
||||
"openid": "oLefc4g5GjKWHJjLjMSXB3wX0fD0"
|
||||
}
|
||||
}
|
||||
|
||||
### /pay/create 提交支付订单【wx_native】
|
||||
POST {{appApi}}/pay/order/submit
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{appToken}}
|
||||
tenant-id: {{appTenentId}}
|
||||
|
||||
{
|
||||
"id": 202,
|
||||
"channelCode": "wx_native"
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.fastbee.pay.core.controller.app.order;
|
||||
|
||||
import com.fastbee.common.core.domain.CommonResult;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||
import com.fastbee.pay.core.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
||||
import com.fastbee.pay.core.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
||||
import com.fastbee.pay.core.convert.order.PayOrderConvert;
|
||||
import com.fastbee.pay.core.service.order.PayOrderService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static com.fastbee.common.core.domain.CommonResult.success;
|
||||
import static com.fastbee.common.utils.ServletUtils.getClientIP;
|
||||
|
||||
|
||||
@Api(tags = "用户 APP - 支付订单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/order")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AppPayOrderController {
|
||||
|
||||
@Resource
|
||||
private PayOrderService payOrderService;
|
||||
|
||||
// TODO fastbee:临时 demo,技术打样。
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得支付订单")
|
||||
@ApiParam(name = "id", value = "编号", required = true, example = "1024")
|
||||
public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id) {
|
||||
return success(PayOrderConvert.INSTANCE.convert(payOrderService.getOrder(id)));
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
@ApiOperation("提交支付订单")
|
||||
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) {
|
||||
PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP());
|
||||
return success(PayOrderConvert.INSTANCE.convert3(respVO));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastbee.pay.core.controller.app.order.vo;
|
||||
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitReqVO;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(description = "用户 APP - 支付订单提交 Request VO")
|
||||
@Data
|
||||
public class AppPayOrderSubmitReqVO extends PayOrderSubmitReqVO {
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.fastbee.pay.core.controller.app.order.vo;
|
||||
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(description = "用户 APP - 支付订单提交 Response VO")
|
||||
@Data
|
||||
public class AppPayOrderSubmitRespVO extends PayOrderSubmitRespVO {
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* TODO fastbee:占个位置,没啥用
|
||||
*/
|
||||
package com.fastbee.pay.core.controller.app.refund;
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 提供 RESTful API 给前端:
|
||||
* 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目
|
||||
* 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
|
||||
*/
|
||||
package com.fastbee.pay.core.controller;
|
@ -0,0 +1,48 @@
|
||||
package com.fastbee.pay.core.convert.app;
|
||||
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.common.utils.collection.CollectionUtils;
|
||||
import com.fastbee.pay.core.controller.admin.app.vo.PayAppCreateReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.app.vo.PayAppPageItemRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.app.vo.PayAppRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.app.vo.PayAppUpdateReqVO;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Convert
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayAppConvert {
|
||||
|
||||
PayAppConvert INSTANCE = Mappers.getMapper(PayAppConvert.class);
|
||||
|
||||
PayAppPageItemRespVO pageConvert (PayApp bean);
|
||||
|
||||
PayApp convert(PayAppCreateReqVO bean);
|
||||
|
||||
PayApp convert(PayAppUpdateReqVO bean);
|
||||
|
||||
PayAppRespVO convert(PayApp bean);
|
||||
|
||||
List<PayAppRespVO> convertList(List<PayApp> list);
|
||||
|
||||
PageResult<PayAppPageItemRespVO> convertPage(PageResult<PayApp> page);
|
||||
|
||||
default PageResult<PayAppPageItemRespVO> convertPage(PageResult<PayApp> pageResult, List<PayChannel> channels) {
|
||||
PageResult<PayAppPageItemRespVO> voPageResult = convertPage(pageResult);
|
||||
// 处理 channel 关系
|
||||
Map<Long, Set<String>> appIdChannelMap = CollectionUtils.convertMultiMap2(channels, PayChannel::getAppId, PayChannel::getCode);
|
||||
voPageResult.getList().forEach(app -> app.setChannelCodes(appIdChannelMap.get(app.getId())));
|
||||
return voPageResult;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.fastbee.pay.core.convert.channel;
|
||||
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.pay.core.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.channel.vo.PayChannelRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface PayChannelConvert {
|
||||
|
||||
PayChannelConvert INSTANCE = Mappers.getMapper(PayChannelConvert.class);
|
||||
|
||||
@Mapping(target = "config",ignore = true)
|
||||
PayChannel convert(PayChannelCreateReqVO bean);
|
||||
|
||||
@Mapping(target = "config",ignore = true)
|
||||
PayChannel convert(PayChannelUpdateReqVO bean);
|
||||
|
||||
// @Mapping(target = "config",expression = "java(cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString(bean.getConfig()))")
|
||||
// PayChannelRespVO convert(PayChannel bean);
|
||||
|
||||
// PageResult<PayChannelRespVO> convertPage(PageResult<PayChannel> page);
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.pay.core.convert.demo;
|
||||
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.pay.core.controller.admin.demo.vo.OrderInfoCreateReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.demo.vo.OrderInfoRespVO;
|
||||
import com.fastbee.pay.core.domain.dataobject.demo.OrderInfo;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 示例订单 Convert
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderInfoConvert {
|
||||
|
||||
OrderInfoConvert INSTANCE = Mappers.getMapper(OrderInfoConvert.class);
|
||||
|
||||
OrderInfo convert(OrderInfoCreateReqVO bean);
|
||||
|
||||
OrderInfoRespVO convert(OrderInfo bean);
|
||||
|
||||
PageResult<OrderInfoRespVO> convertPage(PageResult<OrderInfo> page);
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.fastbee.pay.core.convert.notify;
|
||||
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.common.utils.MapUtils;
|
||||
import com.fastbee.pay.core.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.notify.vo.PayNotifyTaskRespVO;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.notify.PayNotifyLog;
|
||||
import com.fastbee.pay.core.domain.dataobject.notify.PayNotifyTask;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付通知 Convert
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayNotifyTaskConvert {
|
||||
|
||||
PayNotifyTaskConvert INSTANCE = Mappers.getMapper(PayNotifyTaskConvert.class);
|
||||
|
||||
PayNotifyTaskRespVO convert(PayNotifyTask bean);
|
||||
|
||||
default PageResult<PayNotifyTaskRespVO> convertPage(PageResult<PayNotifyTask> page, Map<Long, PayApp> appMap){
|
||||
PageResult<PayNotifyTaskRespVO> result = convertPage(page);
|
||||
result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName())));
|
||||
return result;
|
||||
}
|
||||
PageResult<PayNotifyTaskRespVO> convertPage(PageResult<PayNotifyTask> page);
|
||||
|
||||
default PayNotifyTaskDetailRespVO convert(PayNotifyTask task, PayApp app, List<PayNotifyLog> logs) {
|
||||
PayNotifyTaskDetailRespVO respVO = convert(task, logs);
|
||||
if (app != null) {
|
||||
respVO.setAppName(app.getName());
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
PayNotifyTaskDetailRespVO convert(PayNotifyTask task, List<PayNotifyLog> logs);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.fastbee.pay.core.convert.order;
|
||||
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.common.utils.MapUtils;
|
||||
import com.fastbee.common.utils.collection.CollectionUtils;
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderCreateReqDTO;
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderRespDTO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderDetailsRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderExcelVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderPageItemRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitReqVO;
|
||||
import com.fastbee.pay.core.controller.admin.order.vo.PayOrderSubmitRespVO;
|
||||
import com.fastbee.pay.core.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrderExtension;
|
||||
import com.fastbee.pay.framework.client.dto.order.PayOrderUnifiedReqDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付订单 Convert
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayOrderConvert {
|
||||
|
||||
PayOrderConvert INSTANCE = Mappers.getMapper(PayOrderConvert.class);
|
||||
|
||||
PayOrderRespVO convert(PayOrder bean);
|
||||
|
||||
PayOrderRespDTO convert2(PayOrder order);
|
||||
|
||||
default PayOrderDetailsRespVO convert(PayOrder order, PayOrderExtension orderExtension, PayApp app) {
|
||||
PayOrderDetailsRespVO respVO = convertDetail(order);
|
||||
respVO.setExtension(convert(orderExtension));
|
||||
if (app != null) {
|
||||
respVO.setAppName(app.getName());
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
PayOrderDetailsRespVO convertDetail(PayOrder bean);
|
||||
PayOrderDetailsRespVO.PayOrderExtension convert(PayOrderExtension bean);
|
||||
|
||||
default PageResult<PayOrderPageItemRespVO> convertPage(PageResult<PayOrder> page, Map<Long, PayApp> appMap) {
|
||||
PageResult<PayOrderPageItemRespVO> result = convertPage(page);
|
||||
result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName())));
|
||||
return result;
|
||||
}
|
||||
PageResult<PayOrderPageItemRespVO> convertPage(PageResult<PayOrder> page);
|
||||
|
||||
default List<PayOrderExcelVO> convertList(List<PayOrder> list, Map<Long, PayApp> appMap) {
|
||||
return CollectionUtils.convertList(list, order -> {
|
||||
PayOrderExcelVO excelVO = convertExcel(order);
|
||||
MapUtils.findAndThen(appMap, order.getAppId(), app -> excelVO.setAppName(app.getName()));
|
||||
return excelVO;
|
||||
});
|
||||
}
|
||||
PayOrderExcelVO convertExcel(PayOrder bean);
|
||||
|
||||
PayOrder convert(PayOrderCreateReqDTO bean);
|
||||
|
||||
@Mapping(target = "id", ignore = true)
|
||||
PayOrderExtension convert(PayOrderSubmitReqVO bean, String userIp);
|
||||
|
||||
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO, String userIp);
|
||||
|
||||
@Mapping(source = "order.status", target = "status")
|
||||
PayOrderSubmitRespVO convert(PayOrder order, com.fastbee.pay.framework.client.dto.order.PayOrderRespDTO respDTO);
|
||||
|
||||
AppPayOrderSubmitRespVO convert3(PayOrderSubmitRespVO bean);
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* 提供 POJO 类的实体转换
|
||||
* 目前使用 MapStruct 框架
|
||||
*/
|
||||
package com.fastbee.pay.core.convert;
|
@ -0,0 +1,56 @@
|
||||
package com.fastbee.pay.core.convert.refund;
|
||||
|
||||
import com.fastbee.common.core.domain.PageResult;
|
||||
import com.fastbee.common.utils.MapUtils;
|
||||
import com.fastbee.common.utils.collection.CollectionUtils;
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundCreateReqDTO;
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundRespDTO;
|
||||
import com.fastbee.pay.core.controller.admin.refund.vo.PayRefundDetailsRespVO;
|
||||
import com.fastbee.pay.core.controller.admin.refund.vo.PayRefundExcelVO;
|
||||
import com.fastbee.pay.core.controller.admin.refund.vo.PayRefundPageItemRespVO;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import com.fastbee.pay.core.domain.dataobject.refund.PayRefund;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface PayRefundConvert {
|
||||
|
||||
PayRefundConvert INSTANCE = Mappers.getMapper(PayRefundConvert.class);
|
||||
|
||||
|
||||
default PayRefundDetailsRespVO convert(PayRefund refund, PayApp app) {
|
||||
PayRefundDetailsRespVO respVO = convert(refund);
|
||||
if (app != null) {
|
||||
respVO.setAppName(app.getName());
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
PayRefundDetailsRespVO convert(PayRefund bean);
|
||||
PayRefundDetailsRespVO.Order convert(PayOrder bean);
|
||||
|
||||
default PageResult<PayRefundPageItemRespVO> convertPage(PageResult<PayRefund> page, Map<Long, PayApp> appMap) {
|
||||
PageResult<PayRefundPageItemRespVO> result = convertPage(page);
|
||||
result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName())));
|
||||
return result;
|
||||
}
|
||||
PageResult<PayRefundPageItemRespVO> convertPage(PageResult<PayRefund> page);
|
||||
|
||||
PayRefund convert(PayRefundCreateReqDTO bean);
|
||||
|
||||
PayRefundRespDTO convert02(PayRefund bean);
|
||||
|
||||
default List<PayRefundExcelVO> convertList(List<PayRefund> list, Map<Long, PayApp> appMap) {
|
||||
return CollectionUtils.convertList(list, order -> {
|
||||
PayRefundExcelVO excelVO = convertExcel(order);
|
||||
MapUtils.findAndThen(appMap, order.getAppId(), app -> excelVO.setAppName(app.getName()));
|
||||
return excelVO;
|
||||
});
|
||||
}
|
||||
PayRefundExcelVO convertExcel(PayRefund bean);
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/MapStruct/>
|
@ -0,0 +1,56 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.app;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fastbee.common.core.domain.BaseDO;
|
||||
import com.fastbee.common.enums.CommonStatusEnum;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付应用 DO
|
||||
* 一个商户下,可能会有多个支付应用。例如说,京东有京东商城、京东到家等等
|
||||
* 不过一般来说,一个商户,只有一个应用哈~
|
||||
* 即 PayMerchantDO : PayApp = 1 : n
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName("pay_app")
|
||||
//@KeySequence("pay_app_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class PayApp extends BaseDO {
|
||||
|
||||
/**
|
||||
* 应用编号,数据库自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 应用名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 支付结果的回调地址
|
||||
*/
|
||||
private String orderNotifyUrl;
|
||||
/**
|
||||
* 退款结果的回调地址
|
||||
*/
|
||||
private String refundNotifyUrl;
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.channel;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.fastbee.common.core.domain.TenantBaseDO;
|
||||
import com.fastbee.common.enums.CommonStatusEnum;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.framework.client.PayClientConfig;
|
||||
import com.fastbee.pay.framework.enums.channel.PayChannelEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付渠道 DO
|
||||
* 一个应用下,会有多种支付渠道,例如说微信支付、支付宝支付等等
|
||||
* 即 PayApp : PayChannel = 1 : n
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName(value = "pay_channel", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class PayChannel extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 渠道编号,数据库自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 渠道编码
|
||||
* 枚举 {@link PayChannelEnum}
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 状态
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 渠道费率,单位:百分比
|
||||
*/
|
||||
private Double feeRate;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 应用编号
|
||||
* 关联 {@link PayApp#getId()}
|
||||
*/
|
||||
private Long appId;
|
||||
/**
|
||||
* 支付渠道配置
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private PayClientConfig config;
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.demo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fastbee.common.core.domain.BaseDO;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 订单信息, 实际根据自己的业务系统设计
|
||||
* 用id关联 pay 系统的支付与退款
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName("order_info")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class OrderInfo extends BaseDO {
|
||||
|
||||
/**
|
||||
* 订单编号,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 商户显示订单编号
|
||||
*/
|
||||
private String orderNo;
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private Long spuId;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String spuName;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
|
||||
// ========== 支付相关字段 ==========
|
||||
/**
|
||||
* 是否支付
|
||||
*/
|
||||
private Boolean payStatus;
|
||||
/**
|
||||
* 支付订单编号
|
||||
* 对接 pay-module-biz 支付服务的支付订单编号,即 PayOrder 的 id 编号
|
||||
*/
|
||||
private Long payOrderId;
|
||||
/**
|
||||
* 付款时间
|
||||
*/
|
||||
private LocalDateTime payTime;
|
||||
/**
|
||||
* 支付渠道
|
||||
* 对应 PayChannelEnum 枚举
|
||||
*/
|
||||
private String payChannelCode;
|
||||
|
||||
// ========== 退款相关字段 ==========
|
||||
/**
|
||||
* 支付退款单号
|
||||
*/
|
||||
private Long payRefundId;
|
||||
/**
|
||||
* 退款金额,单位:分
|
||||
*/
|
||||
private Integer refundPrice;
|
||||
/**
|
||||
* 退款完成时间
|
||||
*/
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.notify;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fastbee.common.core.domain.BaseDO;
|
||||
import com.fastbee.pay.api.enums.notify.PayNotifyStatusEnum;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 商户支付、退款等的通知 Log
|
||||
* 每次通知时,都会在该表中,记录一次 Log,方便排查问题
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName("pay_notify_log")
|
||||
@KeySequence("pay_notify_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PayNotifyLog extends BaseDO {
|
||||
|
||||
/**
|
||||
* 日志编号,自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 通知任务编号
|
||||
* 关联 {@link PayNotifyTask#getId()}
|
||||
*/
|
||||
private Long taskId;
|
||||
/**
|
||||
* 第几次被通知
|
||||
* 对应到 {@link PayNotifyTask#getNotifyTimes()}
|
||||
*/
|
||||
private Integer notifyTimes;
|
||||
/**
|
||||
* HTTP 响应结果
|
||||
*/
|
||||
private String response;
|
||||
/**
|
||||
* 支付通知状态
|
||||
* 外键 {@link PayNotifyStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.notify;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fastbee.common.core.domain.TenantBaseDO;
|
||||
import com.fastbee.pay.api.enums.notify.PayNotifyStatusEnum;
|
||||
import com.fastbee.pay.api.enums.notify.PayNotifyTypeEnum;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import com.fastbee.pay.core.domain.dataobject.refund.PayRefund;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付通知
|
||||
* 在支付系统收到支付渠道的支付、退款的结果后,需要不断的通知到业务系统,直到成功。
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName("pay_notify_task")
|
||||
@KeySequence("pay_notify_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class PayNotifyTask extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 通知频率,单位为秒。
|
||||
*
|
||||
* 算上首次的通知,实际是一共 1 + 8 = 9 次。
|
||||
*/
|
||||
public static final Integer[] NOTIFY_FREQUENCY = new Integer[]{
|
||||
15, 15, 30, 180,
|
||||
1800, 1800, 1800, 3600
|
||||
};
|
||||
|
||||
/**
|
||||
* 编号,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 应用编号
|
||||
* 关联 {@link PayApp#getId()}
|
||||
*/
|
||||
private Long appId;
|
||||
/**
|
||||
* 通知类型
|
||||
* 外键 {@link PayNotifyTypeEnum}
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 数据编号,根据不同 type 进行关联:
|
||||
* 1. {@link PayNotifyTypeEnum#ORDER} 时,关联 {@link PayOrder#getId()}
|
||||
* 2. {@link PayNotifyTypeEnum#REFUND} 时,关联 {@link PayRefund#getId()}
|
||||
*/
|
||||
private Long dataId;
|
||||
/**
|
||||
* 商户订单编号
|
||||
*/
|
||||
private String merchantOrderId;
|
||||
/**
|
||||
* 通知状态
|
||||
* 外键 {@link PayNotifyStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 下一次通知时间
|
||||
*/
|
||||
private LocalDateTime nextNotifyTime;
|
||||
/**
|
||||
* 最后一次执行时间
|
||||
*/
|
||||
private LocalDateTime lastExecuteTime;
|
||||
/**
|
||||
* 当前通知次数
|
||||
*/
|
||||
private Integer notifyTimes;
|
||||
/**
|
||||
* 最大可通知次数
|
||||
*/
|
||||
private Integer maxNotifyTimes;
|
||||
/**
|
||||
* 通知地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.order;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fastbee.common.core.domain.BaseDO;
|
||||
import com.fastbee.pay.api.enums.order.PayOrderStatusEnum;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import com.fastbee.pay.framework.enums.channel.PayChannelEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付订单 DO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName("pay_order")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class PayOrder extends BaseDO {
|
||||
|
||||
/**
|
||||
* 订单编号,数据库自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 应用编号
|
||||
* 关联 {@link PayApp#getId()}
|
||||
*/
|
||||
private Long appId;
|
||||
/**
|
||||
* 渠道编号
|
||||
* 关联 {@link PayChannel#getId()}
|
||||
*/
|
||||
private Long channelId;
|
||||
/**
|
||||
* 渠道编码
|
||||
* 枚举 {@link PayChannelEnum}
|
||||
*/
|
||||
private String channelCode;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
|
||||
/**
|
||||
* 商户订单编号
|
||||
* 例如说,内部系统 A 的订单号,需要保证每个 PayApp 唯一
|
||||
*/
|
||||
private String merchantOrderId;
|
||||
/**
|
||||
* 商品标题
|
||||
*/
|
||||
private String subject;
|
||||
/**
|
||||
* 商品描述信息
|
||||
*/
|
||||
private String body;
|
||||
/**
|
||||
* 异步通知地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
|
||||
// ========== 订单相关字段 ==========
|
||||
|
||||
/**
|
||||
* 支付金额,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 渠道手续费,单位:百分比
|
||||
* 冗余 {@link PayChannel#getFeeRate()}
|
||||
*/
|
||||
private Double channelFeeRate;
|
||||
/**
|
||||
* 渠道手续金额,单位:分
|
||||
*/
|
||||
private Integer channelFeePrice;
|
||||
/**
|
||||
* 支付状态
|
||||
* 枚举 {@link PayOrderStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
private String userIp;
|
||||
/**
|
||||
* 订单失效时间
|
||||
*/
|
||||
private LocalDateTime expireTime;
|
||||
/**
|
||||
* 订单支付成功时间
|
||||
*/
|
||||
private LocalDateTime successTime;
|
||||
/**
|
||||
* 支付成功的订单拓展单编号
|
||||
* 关联 {@link PayOrderExtension#getId()}
|
||||
*/
|
||||
private Long extensionId;
|
||||
/**
|
||||
* 支付成功的外部订单号
|
||||
* 关联 {@link PayOrderExtension#getNo()}
|
||||
*/
|
||||
private String no;
|
||||
|
||||
// ========== 退款相关字段 ==========
|
||||
/**
|
||||
* 退款总金额,单位:分
|
||||
*/
|
||||
private Integer refundPrice;
|
||||
|
||||
// ========== 渠道相关字段 ==========
|
||||
/**
|
||||
* 渠道用户编号
|
||||
* 例如说,微信 openid、支付宝账号
|
||||
*/
|
||||
private String channelUserId;
|
||||
/**
|
||||
* 渠道订单号
|
||||
*/
|
||||
private String channelOrderNo;
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.order;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.fastbee.common.core.domain.BaseDO;
|
||||
import com.fastbee.pay.api.api.order.dto.PayOrderRespDTO;
|
||||
import com.fastbee.pay.api.enums.order.PayOrderStatusEnum;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付订单拓展 DO
|
||||
* 每次调用支付渠道,都会生成一条对应记录
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName(value = "pay_order_extension",autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class PayOrderExtension extends BaseDO {
|
||||
|
||||
/**
|
||||
* 订单拓展编号,数据库自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 外部订单号,根据规则生成
|
||||
* 调用支付渠道时,使用该字段作为对接的订单号:
|
||||
* 1. 微信支付:对应 <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml">JSAPI 支付</a> 的 out_trade_no 字段
|
||||
* 2. 支付宝支付:对应 <a href="https://opendocs.alipay.com/open/270/105898">电脑网站支付</a> 的 out_trade_no 字段
|
||||
* 例如说,P202110132239124200055
|
||||
*/
|
||||
private String no;
|
||||
/**
|
||||
* 订单号
|
||||
* 关联 {@link PayOrder#getId()}
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 渠道编号
|
||||
* 关联 {@link PayChannel#getId()}
|
||||
*/
|
||||
private Long channelId;
|
||||
/**
|
||||
* 渠道编码
|
||||
*/
|
||||
private String channelCode;
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
private String userIp;
|
||||
/**
|
||||
* 支付状态
|
||||
* 枚举 {@link PayOrderStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 支付渠道的额外参数
|
||||
* 参见 <a href="https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html">参数说明</>
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<String, String> channelExtras;
|
||||
|
||||
/**
|
||||
* 调用渠道的错误码
|
||||
*/
|
||||
private String channelErrorCode;
|
||||
/**
|
||||
* 调用渠道报错时,错误信息
|
||||
*/
|
||||
private String channelErrorMsg;
|
||||
|
||||
/**
|
||||
* 支付渠道的同步/异步通知的内容
|
||||
* 对应 {@link PayOrderRespDTO#getRawData()}
|
||||
*/
|
||||
private String channelNotifyData;
|
||||
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
package com.fastbee.pay.core.domain.dataobject.refund;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fastbee.common.core.domain.BaseDO;
|
||||
import com.fastbee.pay.api.api.refund.dto.PayRefundRespDTO;
|
||||
import com.fastbee.pay.api.enums.refund.PayRefundStatusEnum;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import com.fastbee.pay.framework.enums.channel.PayChannelEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付退款单 DO
|
||||
* 一个支付订单,可以拥有多个支付退款单
|
||||
* 即 PayOrder : PayRefund = 1 : n
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@TableName("pay_refund")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class PayRefund extends BaseDO {
|
||||
|
||||
/**
|
||||
* 退款单编号,数据库自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 外部退款号,根据规则生成
|
||||
* 调用支付渠道时,使用该字段作为对接的退款号:
|
||||
* 1. 微信退款:对应 <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4">申请退款</a> 的 out_refund_no 字段
|
||||
* 2. 支付宝退款:对应 <a href="https://opendocs.alipay.com/open/02e7go"统一收单交易退款接口></a> 的 out_request_no 字段
|
||||
*/
|
||||
private String no;
|
||||
|
||||
/**
|
||||
* 应用编号
|
||||
* 关联 {@link PayApp#getId()}
|
||||
*/
|
||||
private Long appId;
|
||||
/**
|
||||
* 渠道编号
|
||||
* 关联 {@link PayChannel#getId()}
|
||||
*/
|
||||
private Long channelId;
|
||||
/**
|
||||
* 商户编码
|
||||
* 枚举 {@link PayChannelEnum}
|
||||
*/
|
||||
private String channelCode;
|
||||
/**
|
||||
* 订单编号
|
||||
* 关联 {@link PayOrder#getId()}
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 支付订单编号
|
||||
* 冗余 {@link PayOrder#getNo()}
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
/**
|
||||
* 商户订单编号
|
||||
* 例如说,内部系统 A 的订单号,需要保证每个 PayApp 唯一
|
||||
*/
|
||||
private String merchantOrderId;
|
||||
/**
|
||||
* 商户退款订单号
|
||||
* 例如说,内部系统 A 的订单号,需要保证每个 PayApp 唯一
|
||||
*/
|
||||
private String merchantRefundId;
|
||||
/**
|
||||
* 异步通知地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
|
||||
// ========== 退款相关字段 ==========
|
||||
/**
|
||||
* 退款状态
|
||||
* 枚举 {@link PayRefundStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 支付金额,单位:分
|
||||
*/
|
||||
private Integer payPrice;
|
||||
/**
|
||||
* 退款金额,单位:分
|
||||
*/
|
||||
private Integer refundPrice;
|
||||
|
||||
/**
|
||||
* 退款原因
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
private String userIp;
|
||||
|
||||
// ========== 渠道相关字段 ==========
|
||||
/**
|
||||
* 渠道订单号
|
||||
* 冗余 {@link PayOrder#getChannelOrderNo()}
|
||||
*/
|
||||
private String channelOrderNo;
|
||||
/**
|
||||
* 渠道退款单号
|
||||
* 1. 微信退款:对应 <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4">申请退款</a> 的 refund_id 字段
|
||||
* 2. 支付宝退款:没有字段
|
||||
*/
|
||||
private String channelRefundNo;
|
||||
/**
|
||||
* 退款成功时间
|
||||
*/
|
||||
private LocalDateTime successTime;
|
||||
|
||||
/**
|
||||
* 调用渠道的错误码
|
||||
*/
|
||||
private String channelErrorCode;
|
||||
/**
|
||||
* 调用渠道的错误提示
|
||||
*/
|
||||
private String channelErrorMsg;
|
||||
|
||||
/**
|
||||
* 支付渠道的同步/异步通知的内容
|
||||
* 对应 {@link PayRefundRespDTO#getRawData()}
|
||||
*/
|
||||
private String channelNotifyData;
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.fastbee.pay.core.domain.mapper.app;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.app.PayApp;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayAppMapper extends BaseMapperX<PayApp> {
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastbee.pay.core.domain.mapper.channel;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.channel.PayChannel;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayChannelMapper extends BaseMapperX<PayChannel> {
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.fastbee.pay.core.domain.mapper.demo;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.demo.OrderInfo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 示例订单 Mapper
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderInfoMapper extends BaseMapperX<OrderInfo> {
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastbee.pay.core.domain.mapper.notify;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.notify.PayNotifyLog;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayNotifyLogMapper extends BaseMapperX<PayNotifyLog> {
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastbee.pay.core.domain.mapper.notify;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.notify.PayNotifyTask;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayNotifyTaskMapper extends BaseMapperX<PayNotifyTask> {
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastbee.pay.core.domain.mapper.order;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrderExtension;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayOrderExtensionMapper extends BaseMapperX<PayOrderExtension> {
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastbee.pay.core.domain.mapper.order;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.order.PayOrder;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayOrderMapper extends BaseMapperX<PayOrder> {
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.fastbee.pay.core.domain.mapper.refund;
|
||||
|
||||
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
|
||||
import com.fastbee.pay.core.domain.dataobject.refund.PayRefund;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PayRefundMapper extends BaseMapperX<PayRefund> {
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.fastbee.pay.core.domain.redis;
|
||||
|
||||
/**
|
||||
* 支付 Redis Key 枚举类
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
public interface RedisKeyConstants {
|
||||
|
||||
/**
|
||||
* 通知任务的分布式锁
|
||||
*
|
||||
* KEY 格式:pay_notify:lock:%d // 参数来自 DefaultLockKeyBuilder 类
|
||||
* VALUE 数据格式:HASH // RLock.class:Redisson 的 Lock 锁,使用 Hash 数据结构
|
||||
* 过期时间:不固定
|
||||
*/
|
||||
String PAY_NOTIFY_LOCK = "pay_notify:lock:%d";
|
||||
|
||||
/**
|
||||
* 支付序号的缓存
|
||||
*
|
||||
* KEY 格式:pay_no:{prefix}
|
||||
* VALUE 数据格式:编号自增
|
||||
*/
|
||||
String PAY_NO = "pay_no";
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.fastbee.pay.core.domain.redis.no;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付序号的 Redis DAO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Repository
|
||||
public class PayNoRedisDAO {
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
/**
|
||||
* 生成序号
|
||||
*
|
||||
* @param prefix 前缀
|
||||
* @return 序号
|
||||
*/
|
||||
public String generate(String prefix) {
|
||||
String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN);
|
||||
Long no = stringRedisTemplate.opsForValue().increment(noPrefix);
|
||||
return noPrefix + no;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.fastbee.pay.core.domain.redis.notify;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
/**
|
||||
* 支付通知的锁 Redis DAO
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Repository
|
||||
public class PayNotifyLockRedisDAO {
|
||||
|
||||
// @Resource
|
||||
// private RedissonClient redissonClient;
|
||||
//
|
||||
// public void lock(Long id, Long timeoutMillis, Runnable runnable) {
|
||||
// String lockKey = formatKey(id);
|
||||
// RLock lock = redissonClient.getLock(lockKey);
|
||||
// try {
|
||||
// lock.lock(timeoutMillis, TimeUnit.MILLISECONDS);
|
||||
// // 执行逻辑
|
||||
// runnable.run();
|
||||
// } finally {
|
||||
// lock.unlock();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static String formatKey(Long id) {
|
||||
// return String.format(PAY_NOTIFY_LOCK, id);
|
||||
// }
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.fastbee.pay.core.framework.job.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class PayJobConfiguration {
|
||||
|
||||
public static final String NOTIFY_THREAD_POOL_TASK_EXECUTOR = "NOTIFY_THREAD_POOL_TASK_EXECUTOR";
|
||||
|
||||
@Bean(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
|
||||
public ThreadPoolTaskExecutor notifyThreadPoolTaskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(8); // 设置核心线程数
|
||||
executor.setMaxPoolSize(16); // 设置最大线程数
|
||||
executor.setKeepAliveSeconds(60); // 设置空闲时间
|
||||
executor.setQueueCapacity(100); // 设置队列大小
|
||||
executor.setThreadNamePrefix("notify-task-"); // 配置线程池的前缀
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
// 进行加载
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 占位
|
||||
*/
|
||||
package com.fastbee.pay.core.framework.job.core;
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 属于 pay 模块的 framework 封装
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
package com.fastbee.pay.core.framework;
|
@ -0,0 +1,9 @@
|
||||
package com.fastbee.pay.core.framework.pay.config;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(PayProperties.class)
|
||||
public class PayConfiguration {
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.fastbee.pay.core.framework.pay.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@ConfigurationProperties(prefix = "yudao.pay")
|
||||
@Validated
|
||||
@Data
|
||||
public class PayProperties {
|
||||
|
||||
private static final String ORDER_NO_PREFIX = "P";
|
||||
private static final String REFUND_NO_PREFIX = "R";
|
||||
|
||||
/**
|
||||
* 支付回调地址
|
||||
* 实际上,对应的 PayNotifyController 的 notifyOrder 方法的 URL
|
||||
* 回调顺序:支付渠道(支付宝支付、微信支付) => yudao-module-pay 的 orderNotifyUrl 地址 => 业务的 PayApp.orderNotifyUrl 地址
|
||||
*/
|
||||
@NotEmpty(message = "支付回调地址不能为空")
|
||||
@URL(message = "支付回调地址的格式必须是 URL")
|
||||
private String orderNotifyUrl;
|
||||
|
||||
/**
|
||||
* 退款回调地址
|
||||
* 实际上,对应的 PayNotifyController 的 notifyRefund 方法的 URL
|
||||
* 回调顺序:支付渠道(支付宝支付、微信支付) => yudao-module-pay 的 refundNotifyUrl 地址 => 业务的 PayApp.notifyRefundUrl 地址
|
||||
*/
|
||||
@NotEmpty(message = "支付回调地址不能为空")
|
||||
@URL(message = "支付回调地址的格式必须是 URL")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
/**
|
||||
* 支付订单 no 的前缀
|
||||
*/
|
||||
@NotEmpty(message = "支付订单 no 的前缀不能为空")
|
||||
private String orderNoPrefix = ORDER_NO_PREFIX;
|
||||
|
||||
/**
|
||||
* 退款订单 no 的前缀
|
||||
*/
|
||||
@NotEmpty(message = "退款订单 no 的前缀不能为空")
|
||||
private String refundNoPrefix = REFUND_NO_PREFIX;
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 占位,无实际作用
|
||||
*/
|
||||
package com.fastbee.pay.core.framework.pay.core;
|
@ -0,0 +1,22 @@
|
||||
package com.fastbee.pay.core.framework.web.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* pay 模块的 web 组件的 Configuration
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class PayWebConfiguration {
|
||||
|
||||
/**
|
||||
* pay 模块的 API 分组
|
||||
*/
|
||||
// @Bean
|
||||
// public GroupedOpenApi payGroupedOpenApi() {
|
||||
// return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("pay");
|
||||
// }
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user