Files
soul/lib/payment/types.ts
卡若 b60edb3d47 feat: 完整重构小程序匹配功能 + 修复UI对齐 + 文章数据API
主要更新:
1. 按H5网页端完全重构匹配功能(match页面)
   - 4种匹配类型: 创业合伙/资源对接/导师顾问/团队招募
   - 资源对接等类型弹出手机号/微信号输入框
   - 去掉重新匹配按钮,改为返回按钮

2. 修复所有卡片对齐和宽度问题
   - 目录页附录卡片居中
   - 首页阅读进度卡片满宽度
   - 我的页面菜单卡片对齐
   - 推广中心分享卡片统一宽度

3. 修复目录页图标和文字对齐
   - section-icon固定40rpx宽高
   - section-title与图标垂直居中

4. 更新真实完整文章标题(62篇)
   - 从book目录读取真实markdown文件名
   - 替换之前的简化标题

5. 新增文章数据API
   - /api/db/chapters - 获取完整书籍结构
   - 支持按ID获取单篇文章内容
2026-01-21 15:49:12 +08:00

290 lines
6.3 KiB
TypeScript

/**
* 通用支付模块类型定义 (Universal Payment Module Types)
* 基于 Universal_Payment_Module v4.0 设计
*
* 作者: 卡若
* 版本: v4.0
*/
// 支付平台枚举
export type PaymentPlatform = 'alipay' | 'wechat' | 'paypal' | 'stripe' | 'usdt' | 'coin';
// 支付网关类型
export type PaymentGateway =
| 'alipay_web' | 'alipay_wap' | 'alipay_qr'
| 'wechat_native' | 'wechat_jsapi' | 'wechat_h5' | 'wechat_app'
| 'paypal' | 'stripe' | 'usdt' | 'coin';
// 订单状态
export type OrderStatus = 'created' | 'paying' | 'paid' | 'closed' | 'refunded';
// 交易状态
export type TradeStatus = 'paying' | 'paid' | 'closed' | 'refunded';
// 交易类型
export type TradeType = 'purchase' | 'recharge';
// 支付结果类型
export type PaymentResultType = 'url' | 'qrcode' | 'json' | 'address' | 'direct';
// 货币类型
export type Currency = 'CNY' | 'USD' | 'EUR' | 'USDT';
/**
* 创建订单请求参数
*/
export interface CreateOrderParams {
userId: string;
title: string;
amount: number; // 金额(元)
currency?: Currency;
productId?: string;
productType?: 'section' | 'fullbook' | 'membership' | 'vip';
extraParams?: Record<string, unknown>;
}
/**
* 订单信息
*/
export interface Order {
sn: string; // 订单号
userId: string;
title: string;
priceAmount: number; // 原价(分)
payAmount: number; // 应付金额(分)
currency: Currency;
status: OrderStatus;
productId?: string;
productType?: string;
extraData?: Record<string, unknown>;
paidAt?: Date;
closedAt?: Date;
expiredAt?: Date;
createdAt: Date;
updatedAt: Date;
}
/**
* 发起支付请求参数
*/
export interface CheckoutParams {
orderSn: string;
gateway: PaymentGateway;
returnUrl?: string;
openid?: string; // 微信JSAPI需要
coinAmount?: number; // 虚拟币抵扣
}
/**
* 创建交易请求数据
*/
export interface CreateTradeData {
goodsTitle: string;
goodsDetail?: string;
tradeSn: string;
orderSn: string;
amount: number; // 金额(分)
notifyUrl: string;
returnUrl?: string;
platformType?: string; // web/wap/jsapi/native/h5/app
createIp?: string;
openId?: string;
attach?: Record<string, unknown>;
}
/**
* 支付交易结果
*/
export interface TradeResult {
type: PaymentResultType;
payload: string | Record<string, string>;
tradeSn: string;
expiration?: number; // 过期时间(秒)
amount?: number;
coinDeducted?: number;
prepayId?: string; // 微信预支付ID
}
/**
* 回调解析结果
*/
export interface NotifyResult {
status: 'paying' | 'paid' | 'closed' | 'refunded' | 'failed';
tradeSn: string;
platformSn: string;
payAmount: number; // 分
payTime: Date;
currency: Currency;
attach?: Record<string, unknown>;
rawData?: Record<string, unknown>;
}
/**
* 交易流水
*/
export interface PayTrade {
id?: string;
tradeSn: string;
orderSn: string;
userId: string;
title: string;
amount: number; // 分
cashAmount: number; // 现金支付金额(分)
coinAmount: number; // 虚拟币抵扣金额
currency: Currency;
platform: PaymentPlatform;
platformType?: string;
platformSn?: string;
platformCreatedParams?: Record<string, unknown>;
platformCreatedResult?: Record<string, unknown>;
status: TradeStatus;
type: TradeType;
payTime?: Date;
notifyData?: Record<string, unknown>;
sellerId?: string;
createdAt: Date;
updatedAt: Date;
}
/**
* 退款记录
*/
export interface Refund {
id?: string;
refundSn: string;
tradeSn: string;
orderSn: string;
amount: number; // 分
reason?: string;
status: 'pending' | 'processing' | 'success' | 'failed';
platformRefundSn?: string;
refundedAt?: Date;
operatorId?: string;
createdAt: Date;
updatedAt: Date;
}
/**
* 支付网关配置
*/
export interface GatewayConfig {
enabled: boolean;
mode: 'sandbox' | 'production';
[key: string]: unknown;
}
/**
* 支付宝配置
*/
export interface AlipayConfig extends GatewayConfig {
appId: string;
pid: string;
sellerEmail?: string;
privateKey?: string;
publicKey?: string;
md5Key?: string;
}
/**
* 微信支付配置
*/
export interface WechatConfig extends GatewayConfig {
appId: string;
appSecret?: string;
serviceAppId?: string; // 服务号AppID
serviceSecret?: string;
mchId: string;
mchKey: string;
certPath?: string;
keyPath?: string;
}
/**
* 统一响应格式
*/
export interface PaymentResponse<T = unknown> {
code: number;
message: string;
data: T | null;
}
/**
* 支付方式信息
*/
export interface PaymentMethod {
gateway: PaymentGateway;
name: string;
icon: string;
enabled: boolean;
available: boolean; // 当前环境是否可用
}
/**
* 支付异常
*/
export class PaymentException extends Error {
constructor(message: string, public code?: string) {
super(message);
this.name = 'PaymentException';
}
}
export class SignatureError extends PaymentException {
constructor(message = '签名验证失败') {
super(message, 'SIGNATURE_ERROR');
this.name = 'SignatureError';
}
}
export class AmountMismatchError extends PaymentException {
constructor(message = '金额不匹配') {
super(message, 'AMOUNT_MISMATCH');
this.name = 'AmountMismatchError';
}
}
export class GatewayNotFoundError extends PaymentException {
constructor(gateway: string) {
super(`不支持的支付网关: ${gateway}`, 'GATEWAY_NOT_FOUND');
this.name = 'GatewayNotFoundError';
}
}
/**
* 工具函数:元转分
*/
export function yuanToFen(yuan: number): number {
return Math.round(yuan * 100);
}
/**
* 工具函数:分转元
*/
export function fenToYuan(fen: number): number {
return Math.round(fen) / 100;
}
/**
* 生成订单号
* 格式: YYYYMMDD + 6位随机数
*/
export function generateOrderSn(prefix = ''): string {
const date = new Date();
const dateStr = date.toISOString().slice(0, 10).replace(/-/g, '');
const random = Math.floor(Math.random() * 1000000).toString().padStart(6, '0');
return `${prefix}${dateStr}${random}`;
}
/**
* 生成交易流水号
* 格式: T + YYYYMMDDHHMMSS + 5位随机数
*/
export function generateTradeSn(prefix = 'T'): string {
const now = new Date();
const timestamp = now.toISOString()
.replace(/[-:T]/g, '')
.slice(0, 14);
const random = Math.floor(Math.random() * 100000).toString().padStart(5, '0');
return `${prefix}${timestamp}${random}`;
}