Files
bw-mini-app-server/src/payment/dto/stripe-payment.dto.ts
imeepos 489756b7a0 feat: 集成Google OAuth认证和完善Stripe支付系统
- 新增Google OAuth 2.0认证模块
  - 实现Google Strategy和AuthController
  - 添加Google平台适配器和用户统一管理
  - 支持OAuth回调和token交换机制

- 完善Stripe支付集成
  - 新增Stripe支付适配器和控制器
  - 实现webhook事件处理和支付确认
  - 支持多币种和国际化支付

- 扩展平台类型支持
  - 在PlatformType中新增GOOGLE和STRIPE
  - 更新适配器工厂注册机制
  - 完善跨平台用户身份管理

- 增强依赖和配置
  - 添加@nestjs/passport和passport-google-oauth20
  - 更新支付方法枚举和货币支持
  - 完善订单号生成和回调URL构建
2025-09-26 15:26:37 +08:00

330 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { IsString, IsNumber, IsOptional, IsEnum, Min, Max } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { PaymentBusinessType } from '../interfaces/payment.interface';
/**
* Stripe支付货币枚举
*/
export enum StripeCurrency {
USD = 'USD',
EUR = 'EUR',
GBP = 'GBP',
JPY = 'JPY',
AUD = 'AUD',
CAD = 'CAD',
SGD = 'SGD',
HKD = 'HKD',
}
/**
* 创建Stripe支付订单DTO
*/
export class CreateStripePaymentOrderDto {
@ApiProperty({
description: '用户ID',
example: 'user_123456789',
})
@IsString()
userId: string;
@ApiProperty({
description: '业务类型',
enum: PaymentBusinessType,
example: PaymentBusinessType.CREDIT_PURCHASE,
})
@IsEnum(PaymentBusinessType)
businessType: PaymentBusinessType;
@ApiProperty({
description: '业务关联ID',
example: 'credits_500',
})
@IsString()
businessId: string;
@ApiProperty({
description: '支付金额(分)',
example: 4800,
minimum: 1,
maximum: 100000000,
})
@IsNumber()
@Min(1)
@Max(100000000)
@Type(() => Number)
amount: number;
@ApiProperty({
description: '货币类型',
enum: StripeCurrency,
example: StripeCurrency.USD,
})
@IsEnum(StripeCurrency)
currency: StripeCurrency;
@ApiPropertyOptional({
description: '商品描述',
example: '购买500积分包',
})
@IsOptional()
@IsString()
description?: string;
@ApiPropertyOptional({
description: '用户邮箱用于Stripe客户信息',
example: 'user@example.com',
})
@IsOptional()
@IsString()
customerEmail?: string;
@ApiPropertyOptional({
description: '附加数据',
example: { source: 'web', campaign: 'holiday_sale' },
})
@IsOptional()
metadata?: any;
}
/**
* Stripe支付订单响应DTO
*/
export class StripePaymentOrderResponseDto {
@ApiProperty({
description: '本地订单ID',
example: 'ord_123456789',
})
orderId: string;
@ApiProperty({
description: 'Stripe PaymentIntent ID',
example: 'pi_1234567890abcdef',
})
paymentIntentId: string;
@ApiProperty({
description: '客户端密钥',
example: 'pi_1234567890abcdef_secret_xyz',
})
clientSecret: string;
@ApiProperty({
description: 'Stripe可发布密钥',
example: 'pk_test_1234567890abcdef',
})
publishableKey: string;
@ApiProperty({
description: '支付金额(分)',
example: 4800,
})
amount: number;
@ApiProperty({
description: '货币类型',
example: 'USD',
})
currency: string;
@ApiProperty({
description: '订单状态',
example: 'pending',
})
status: string;
@ApiProperty({
description: '创建时间',
example: '2024-01-01T00:00:00.000Z',
})
createdAt: Date;
}
/**
* Stripe Webhook事件DTO
*/
export class StripeWebhookEventDto {
@ApiProperty({
description: '事件ID',
example: 'evt_1234567890abcdef',
})
@IsString()
id: string;
@ApiProperty({
description: '事件类型',
example: 'payment_intent.succeeded',
})
@IsString()
type: string;
@ApiProperty({
description: '事件数据',
})
data: {
object: any;
};
@ApiPropertyOptional({
description: '创建时间戳',
example: 1640995200,
})
@IsOptional()
@IsNumber()
created?: number;
}
/**
* 确认Stripe支付DTO
*/
export class ConfirmStripePaymentDto {
@ApiProperty({
description: 'PaymentIntent ID',
example: 'pi_1234567890abcdef',
})
@IsString()
paymentIntentId: string;
@ApiPropertyOptional({
description: '支付方法ID',
example: 'pm_1234567890abcdef',
})
@IsOptional()
@IsString()
paymentMethodId?: string;
}
/**
* Stripe退款申请DTO
*/
export class CreateStripeRefundDto {
@ApiProperty({
description: '原订单ID',
example: 'ord_123456789',
})
@IsString()
orderId: string;
@ApiProperty({
description: '退款金额(分)',
example: 2400,
minimum: 1,
})
@IsNumber()
@Min(1)
@Type(() => Number)
refundAmount: number;
@ApiProperty({
description: '退款原因',
example: '用户申请退款',
})
@IsString()
reason: string;
}
/**
* Stripe退款响应DTO
*/
export class StripeRefundResponseDto {
@ApiProperty({
description: '退款记录ID',
example: 'ref_123456789',
})
refundId: string;
@ApiProperty({
description: 'Stripe退款ID',
example: 're_1234567890abcdef',
})
stripeRefundId: string;
@ApiProperty({
description: '退款状态',
example: 'pending',
})
status: string;
@ApiProperty({
description: '退款金额(分)',
example: 2400,
})
refundAmount: number;
@ApiPropertyOptional({
description: '预计到账时间',
example: '2024-01-08T00:00:00.000Z',
})
estimatedArrivalTime?: Date;
@ApiProperty({
description: '创建时间',
example: '2024-01-01T00:00:00.000Z',
})
createdAt: Date;
}
/**
* Stripe支付方法DTO
*/
export class StripePaymentMethodDto {
@ApiProperty({
description: '支付方法ID',
example: 'pm_1234567890abcdef',
})
@IsString()
id: string;
@ApiProperty({
description: '支付方法类型',
example: 'card',
})
@IsString()
type: string;
@ApiPropertyOptional({
description: '卡片信息',
})
@IsOptional()
card?: {
brand: string;
last4: string;
exp_month: number;
exp_year: number;
};
}
/**
* Stripe客户信息DTO
*/
export class StripeCustomerDto {
@ApiPropertyOptional({
description: '客户邮箱',
example: 'customer@example.com',
})
@IsOptional()
@IsString()
email?: string;
@ApiPropertyOptional({
description: '客户姓名',
example: 'John Doe',
})
@IsOptional()
@IsString()
name?: string;
@ApiPropertyOptional({
description: '客户描述',
example: 'Premium user from web platform',
})
@IsOptional()
@IsString()
description?: string;
@ApiPropertyOptional({
description: '客户元数据',
})
@IsOptional()
metadata?: Record<string, string>;
}