feat: 支持官方支付宝与易支付支付宝同时展示
- PaymentType 改为 string 类型,支持复合 key(如 alipay_direct) - 官方支付宝注册为 alipay_direct,易支付保持 alipay/wxpay - 前端按 PAYMENT_TYPE_META 展示标签区分(官方直连/易支付) - 管理后台显示统一改为 getPaymentTypeLabel 通用映射 - 修复 admin/OrderTable 中 wechat 拼写错误
This commit is contained in:
@@ -14,11 +14,11 @@ import { getEnv } from '@/lib/config';
|
||||
import type { AlipayTradeQueryResponse, AlipayTradeRefundResponse, AlipayTradeCloseResponse } from './types';
|
||||
|
||||
export class AlipayProvider implements PaymentProvider {
|
||||
readonly name = 'alipay';
|
||||
readonly name = 'alipay-direct';
|
||||
readonly providerKey = 'alipay';
|
||||
readonly supportedTypes: PaymentType[] = ['alipay'];
|
||||
readonly supportedTypes: PaymentType[] = ['alipay_direct'];
|
||||
readonly defaultLimits = {
|
||||
alipay: { singleMax: 1000, dailyMax: 10000 },
|
||||
alipay_direct: { singleMax: 1000, dailyMax: 10000 },
|
||||
};
|
||||
|
||||
async createPayment(request: CreatePaymentRequest): Promise<CreatePaymentResponse> {
|
||||
|
||||
@@ -67,6 +67,11 @@ const envSchema = z.object({
|
||||
.optional()
|
||||
.transform((v) => (v !== undefined ? Number(v) : undefined))
|
||||
.pipe(z.number().min(0).optional()),
|
||||
MAX_DAILY_AMOUNT_ALIPAY_DIRECT: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((v) => (v !== undefined ? Number(v) : undefined))
|
||||
.pipe(z.number().min(0).optional()),
|
||||
MAX_DAILY_AMOUNT_WXPAY: z
|
||||
.string()
|
||||
.optional()
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { EasyPayCreateResponse, EasyPayQueryResponse, EasyPayRefundResponse
|
||||
export interface CreatePaymentOptions {
|
||||
outTradeNo: string;
|
||||
amount: string;
|
||||
paymentType: 'alipay' | 'wxpay';
|
||||
paymentType: string;
|
||||
clientIp: string;
|
||||
productName: string;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ function normalizeCidList(cid?: string): string | undefined {
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
function resolveCid(paymentType: 'alipay' | 'wxpay'): string | undefined {
|
||||
function resolveCid(paymentType: string): string | undefined {
|
||||
const env = getEnv();
|
||||
if (paymentType === 'alipay') {
|
||||
return normalizeCidList(env.EASY_PAY_CID_ALIPAY) || normalizeCidList(env.EASY_PAY_CID);
|
||||
|
||||
@@ -75,19 +75,36 @@ export interface PaymentTypeMeta {
|
||||
export const PAYMENT_TYPE_META: Record<string, PaymentTypeMeta> = {
|
||||
alipay: {
|
||||
label: '支付宝',
|
||||
sublabel: 'ALIPAY',
|
||||
sublabel: '易支付',
|
||||
color: '#00AEEF',
|
||||
selectedBorder: 'border-cyan-400',
|
||||
selectedBg: 'bg-cyan-50',
|
||||
iconBg: 'bg-[#00AEEF]',
|
||||
},
|
||||
alipay_direct: {
|
||||
label: '支付宝',
|
||||
sublabel: '官方直连',
|
||||
color: '#1677FF',
|
||||
selectedBorder: 'border-blue-500',
|
||||
selectedBg: 'bg-blue-50',
|
||||
iconBg: 'bg-[#1677FF]',
|
||||
},
|
||||
wxpay: {
|
||||
label: '微信支付',
|
||||
sublabel: '易支付',
|
||||
color: '#2BB741',
|
||||
selectedBorder: 'border-green-500',
|
||||
selectedBg: 'bg-green-50',
|
||||
iconBg: 'bg-[#2BB741]',
|
||||
},
|
||||
wxpay_direct: {
|
||||
label: '微信支付',
|
||||
sublabel: '官方直连',
|
||||
color: '#07C160',
|
||||
selectedBorder: 'border-green-600',
|
||||
selectedBg: 'bg-green-50',
|
||||
iconBg: 'bg-[#07C160]',
|
||||
},
|
||||
stripe: {
|
||||
label: 'Stripe',
|
||||
sublabel: '信用卡 / 借记卡',
|
||||
@@ -98,6 +115,21 @@ export const PAYMENT_TYPE_META: Record<string, PaymentTypeMeta> = {
|
||||
},
|
||||
};
|
||||
|
||||
/** 获取支付方式的显示名称(如 '支付宝(官方直连)') */
|
||||
export function getPaymentTypeLabel(type: string): string {
|
||||
const meta = PAYMENT_TYPE_META[type];
|
||||
if (!meta) return type;
|
||||
return meta.sublabel ? `${meta.label}(${meta.sublabel})` : meta.label;
|
||||
}
|
||||
|
||||
/** 获取基础支付方式图标类型(alipay_direct → alipay) */
|
||||
export function getPaymentIconType(type: string): string {
|
||||
if (type.startsWith('alipay')) return 'alipay';
|
||||
if (type.startsWith('wxpay')) return 'wxpay';
|
||||
if (type.startsWith('stripe')) return 'stripe';
|
||||
return type;
|
||||
}
|
||||
|
||||
export function getStatusBadgeClass(status: string, isDark: boolean): string {
|
||||
if (['COMPLETED', 'PAID'].includes(status)) {
|
||||
return isDark ? 'bg-emerald-500/20 text-emerald-200' : 'bg-emerald-100 text-emerald-700';
|
||||
|
||||
@@ -36,7 +36,7 @@ export function initPaymentProviders(): void {
|
||||
if (!env.ALIPAY_APP_ID || !env.ALIPAY_PRIVATE_KEY) {
|
||||
throw new Error('PAYMENT_PROVIDERS 含 alipay,但缺少 ALIPAY_APP_ID 或 ALIPAY_PRIVATE_KEY');
|
||||
}
|
||||
paymentRegistry.register(new AlipayProvider());
|
||||
paymentRegistry.register(new AlipayProvider()); // 注册 alipay_direct
|
||||
}
|
||||
|
||||
if (providers.includes('stripe')) {
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
/** Unified payment method types across all providers */
|
||||
export type PaymentType = 'alipay' | 'wxpay' | 'stripe';
|
||||
export type PaymentType = string;
|
||||
|
||||
/**
|
||||
* 从复合 key 中提取基础支付方式(如 'alipay_direct' → 'alipay')
|
||||
* 用于传给第三方 API 时映射回标准名称
|
||||
*/
|
||||
export function getBasePaymentType(type: string): string {
|
||||
if (type.startsWith('alipay')) return 'alipay';
|
||||
if (type.startsWith('wxpay')) return 'wxpay';
|
||||
if (type.startsWith('stripe')) return 'stripe';
|
||||
return type;
|
||||
}
|
||||
|
||||
/** Request to create a payment with any provider */
|
||||
export interface CreatePaymentRequest {
|
||||
|
||||
Reference in New Issue
Block a user