@h-ai/payment 0.1.0-alpha9 → 1.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/payment-config.ts","../src/payment-functions.ts","../src/providers/alipay/alipay-sign.ts","../src/providers/alipay/alipay-provider.ts","../src/providers/stripe/stripe-provider.ts","../src/providers/wechat/wechat-pay-sign.ts","../src/providers/wechat/wechat-pay-provider.ts","../src/payment-main.ts"],"names":["ok","err","core","refund","createSign","createVerify","logger"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/payment — 错误码 + 配置 Schema\n *\n * 支付模块的错误码、Zod 配置 Schema 与配置类型。\n * @module payment-config\n */\n\nimport { z } from 'zod'\nimport { paymentM } from './payment-i18n.js'\n\n// ─── 配置 Schema ───\n\n/** 微信支付配置 Schema */\nexport const WechatPayConfigSchema = z.object({\n mchId: z.string().min(1, paymentM('payment_configFieldRequired')),\n apiV3Key: z.string().min(1, paymentM('payment_configFieldRequired')),\n serialNo: z.string().min(1, paymentM('payment_configFieldRequired')),\n privateKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n platformCert: z.string().optional(),\n appId: z.string().min(1, paymentM('payment_configFieldRequired')),\n})\n\n/** 支付宝配置 Schema */\nexport const AlipayConfigSchema = z.object({\n appId: z.string().min(1, paymentM('payment_configFieldRequired')),\n privateKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n alipayPublicKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n signType: z.enum(['RSA2', 'RSA']).default('RSA2'),\n sandbox: z.boolean().default(false),\n})\n\n/** Stripe 配置 Schema */\nexport const StripeConfigSchema = z.object({\n secretKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n webhookSecret: z.string().min(1, paymentM('payment_configFieldRequired')),\n})\n\n/** 支付模块配置 Schema */\nexport const PaymentConfigSchema = z.object({\n wechat: WechatPayConfigSchema.optional(),\n alipay: AlipayConfigSchema.optional(),\n stripe: StripeConfigSchema.optional(),\n})\n\nexport type PaymentConfig = z.infer<typeof PaymentConfigSchema>\nexport type PaymentConfigInput = z.input<typeof PaymentConfigSchema>\nexport type WechatPayConfig = z.infer<typeof WechatPayConfigSchema>\nexport type AlipayConfig = z.infer<typeof AlipayConfigSchema>\nexport type StripeConfig = z.infer<typeof StripeConfigSchema>\n","/**\n * @h-ai/payment — 业务逻辑编排\n *\n * 统一路由到对应 Provider 的支付操作。\n * @module payment-functions\n */\n\nimport type { CreateAuditLogInput } from '@h-ai/audit'\nimport type { HaiResult } from '@h-ai/core'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from './payment-types.js'\nimport { audit } from '@h-ai/audit'\nimport { core, err, ok } from '@h-ai/core'\nimport { paymentM } from './payment-i18n.js'\nimport {\n\n HaiPaymentError,\n\n} from './payment-types.js'\n\nconst logger = core.logger.child({ module: 'payment', scope: 'functions' })\n\n/** Provider 注册表 */\nconst providers = new Map<string, PaymentProvider>()\n\n/**\n * 写审计日志(失败仅 warn,不影响支付操作)\n */\nasync function auditLog(input: CreateAuditLogInput): Promise<void> {\n const result = await audit.log(input)\n if (!result.success) {\n logger.warn('Failed to write payment audit log', { action: input.action, error: result.error.message })\n }\n}\n\n/**\n * 注册支付 Provider\n *\n * @param provider - PaymentProvider 实例\n */\nexport function registerProvider(provider: PaymentProvider): void {\n providers.set(provider.name, provider)\n}\n\n/**\n * 获取已注册的 Provider\n *\n * @param name - Provider 名称\n * @returns Provider 实例(不存在返回 undefined)\n */\nexport function getProvider(name: string): PaymentProvider | undefined {\n return providers.get(name)\n}\n\n/**\n * 获取 Provider(不存在则返回 err)\n */\nfunction requireProvider(name: string): HaiResult<PaymentProvider> {\n const provider = providers.get(name)\n if (!provider) {\n return err(\n HaiPaymentError.PROVIDER_NOT_FOUND,\n paymentM('payment_providerNotFound'),\n )\n }\n return ok(provider)\n}\n\n/**\n * 通过指定 Provider 创建订单\n *\n * @param providerName - Provider 名称('wechat' | 'alipay' | 'stripe')\n * @param input - 创建订单入参\n */\nexport async function createOrder(\n providerName: string,\n input: CreateOrderInput,\n): Promise<HaiResult<PaymentOrder>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n const orderResult = await result.data.createOrder(input)\n if (orderResult.success) {\n await auditLog({\n action: 'create_order',\n resource: 'payment',\n resourceId: input.orderNo,\n details: { provider: providerName, amount: input.amount, tradeType: input.tradeType },\n })\n }\n return orderResult\n}\n\n/**\n * 处理支付回调通知\n *\n * @param providerName - Provider 名称\n * @param request - 原始 HTTP 请求数据\n */\nexport async function handleNotify(\n providerName: string,\n request: PaymentNotifyRequest,\n): Promise<HaiResult<PaymentNotifyResult>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n const notifyResult = await result.data.handleNotify(request)\n if (notifyResult.success) {\n await auditLog({\n action: 'payment_notify',\n resource: 'payment',\n resourceId: notifyResult.data.orderNo,\n details: { provider: providerName, transactionId: notifyResult.data.transactionId, status: notifyResult.data.status, amount: notifyResult.data.amount },\n })\n }\n return notifyResult\n}\n\n/**\n * 查询订单状态\n *\n * @param providerName - Provider 名称\n * @param orderNo - 商户订单号\n */\nexport async function queryOrder(\n providerName: string,\n orderNo: string,\n): Promise<HaiResult<OrderStatus>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n return result.data.queryOrder(orderNo)\n}\n\n/**\n * 发起退款\n *\n * @param providerName - Provider 名称\n * @param input - 退款入参\n */\nexport async function refund(\n providerName: string,\n input: RefundInput,\n): Promise<HaiResult<RefundResult>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n const refundResult = await result.data.refund(input)\n if (refundResult.success) {\n await auditLog({\n action: 'refund',\n resource: 'payment',\n resourceId: input.orderNo,\n details: { provider: providerName, refundNo: input.refundNo, amount: input.amount },\n })\n }\n return refundResult\n}\n\n/**\n * 关闭订单\n *\n * @param providerName - Provider 名称\n * @param orderNo - 商户订单号\n */\nexport async function closeOrder(\n providerName: string,\n orderNo: string,\n): Promise<HaiResult<void>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n const closeResult = await result.data.closeOrder(orderNo)\n if (closeResult.success) {\n await auditLog({\n action: 'close_order',\n resource: 'payment',\n resourceId: orderNo,\n details: { provider: providerName },\n })\n }\n return closeResult\n}\n\n/**\n * 清空所有已注册 Provider(测试用)\n */\nexport function clearProviders(): void {\n providers.clear()\n}\n","/**\n * @h-ai/payment — 支付宝签名\n *\n * 支付宝 RSA2/RSA 签名与验签工具。\n * @module alipay-sign\n */\n\nimport { createSign, createVerify } from 'node:crypto'\n\n/**\n * 支付宝参数签名\n *\n * @param params - 待签名参数(已排除 sign)\n * @param privateKey - 应用私钥 PEM\n * @param signType - 签名类型(默认 RSA2)\n * @returns Base64 编码的签名\n */\nexport function signAlipayParams(\n params: Record<string, string>,\n privateKey: string,\n signType: 'RSA2' | 'RSA' = 'RSA2',\n): string {\n // 按 key 字典排序,拼接为 query string\n const sorted = Object.keys(params)\n .filter(k => params[k] !== undefined && params[k] !== '')\n .sort()\n .map(k => `${k}=${params[k]}`)\n .join('&')\n\n const algorithm = signType === 'RSA2' ? 'RSA-SHA256' : 'RSA-SHA1'\n const sign = createSign(algorithm)\n sign.update(sorted)\n return sign.sign(privateKey, 'base64')\n}\n\n/**\n * 验证支付宝回调签名\n *\n * @param params - 回调参数(含 sign 和 sign_type)\n * @param alipayPublicKey - 支付宝公钥 PEM\n * @returns 验签是否通过\n */\nexport function verifyAlipayNotify(\n params: Record<string, string>,\n alipayPublicKey: string,\n): boolean {\n const sign = params.sign ?? ''\n const signType = params.sign_type ?? 'RSA2'\n\n // 排除 sign 和 sign_type,按 key 排序拼接\n const sorted = Object.keys(params)\n .filter(k => k !== 'sign' && k !== 'sign_type' && params[k] !== undefined && params[k] !== '')\n .sort()\n .map(k => `${k}=${params[k]}`)\n .join('&')\n\n const algorithm = signType === 'RSA2' ? 'RSA-SHA256' : 'RSA-SHA1'\n const verify = createVerify(algorithm)\n verify.update(sorted)\n return verify.verify(alipayPublicKey, sign, 'base64')\n}\n","/**\n * @h-ai/payment — 支付宝 Provider\n *\n * 实现 PaymentProvider 接口,对接支付宝 Open API。\n * @module alipay-provider\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { AlipayConfig } from '../../payment-config.js'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from '../../payment-types.js'\nimport type { AlipayNotifyParams } from './alipay-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { paymentM } from '../../payment-i18n.js'\nimport {\n\n HaiPaymentError,\n\n} from '../../payment-types.js'\nimport { signAlipayParams, verifyAlipayNotify } from './alipay-sign.js'\n\n/** 支付宝网关地址 */\nconst ALIPAY_GATEWAY = 'https://openapi.alipay.com/gateway.do'\nconst ALIPAY_SANDBOX_GATEWAY = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do'\n\n/**\n * 创建支付宝 Provider\n *\n * @param config - 支付宝配置\n * @returns PaymentProvider 实例\n */\nexport function createAlipayProvider(config: AlipayConfig): PaymentProvider {\n const gateway = config.sandbox ? ALIPAY_SANDBOX_GATEWAY : ALIPAY_GATEWAY\n const signType = config.signType ?? 'RSA2'\n\n /** 构建公共参数 */\n function buildCommonParams(method: string, notifyUrl: string): Record<string, string> {\n return {\n app_id: config.appId,\n method,\n charset: 'utf-8',\n sign_type: signType,\n timestamp: new Date().toISOString().replace('T', ' ').slice(0, 19),\n version: '1.0',\n notify_url: notifyUrl,\n }\n }\n\n /** 根据 tradeType 映射到产品码和 API */\n function getTradeConfig(tradeType: string): { method: string, productCode: string } {\n const map: Record<string, { method: string, productCode: string }> = {\n jsapi: { method: 'alipay.trade.create', productCode: 'JSAPI_PAY' },\n h5: { method: 'alipay.trade.wap.pay', productCode: 'QUICK_WAP_WAY' },\n app: { method: 'alipay.trade.app.pay', productCode: 'QUICK_MSECURITY_PAY' },\n native: { method: 'alipay.trade.precreate', productCode: 'FACE_TO_FACE_PAYMENT' },\n }\n return map[tradeType] ?? map.h5\n }\n\n /** 发送支付宝 API 请求 */\n async function alipayRequest<T>(params: Record<string, string>): Promise<T> {\n const sign = signAlipayParams(params, config.privateKey, signType)\n const allParams = { ...params, sign }\n\n const queryString = Object.entries(allParams)\n .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)\n .join('&')\n\n const response = await fetch(`${gateway}?${queryString}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n })\n\n if (!response.ok) {\n throw new Error(`Alipay API failed: ${response.status}`)\n }\n\n return response.json() as T\n }\n\n return {\n name: 'alipay',\n\n async createOrder(input: CreateOrderInput): Promise<HaiResult<PaymentOrder>> {\n try {\n const { method, productCode } = getTradeConfig(input.tradeType)\n\n const bizContent = JSON.stringify({\n out_trade_no: input.orderNo,\n total_amount: (input.amount / 100).toFixed(2), // 分 → 元\n subject: input.description,\n product_code: productCode,\n passback_params: input.metadata ? JSON.stringify(input.metadata) : undefined,\n })\n\n const params = {\n ...buildCommonParams(method, input.notifyUrl),\n biz_content: bizContent,\n }\n\n const response = await alipayRequest<Record<string, unknown>>(params)\n const key = `${method.replace(/\\./g, '_')}_response`\n const data = response[key] as Record<string, unknown> | undefined\n\n return ok({\n provider: 'alipay',\n tradeType: input.tradeType,\n clientParams: data ?? {},\n prepayId: data?.trade_no as string | undefined,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.CREATE_ORDER_FAILED,\n paymentM('payment_createOrderFailed'),\n cause,\n )\n }\n },\n\n async handleNotify(request: PaymentNotifyRequest): Promise<HaiResult<PaymentNotifyResult>> {\n try {\n // 解析 form-urlencoded body\n const params: AlipayNotifyParams = {} as AlipayNotifyParams\n const pairs = request.body.split('&')\n for (const pair of pairs) {\n const [key, ...rest] = pair.split('=')\n params[decodeURIComponent(key)] = decodeURIComponent(rest.join('='))\n }\n\n // 验签\n const valid = verifyAlipayNotify(params as Record<string, string>, config.alipayPublicKey)\n if (!valid) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n\n const statusMap: Record<string, PaymentNotifyResult['status']> = {\n TRADE_SUCCESS: 'paid',\n TRADE_CLOSED: 'closed',\n TRADE_FINISHED: 'paid',\n WAIT_BUYER_PAY: 'pending',\n }\n\n return ok({\n orderNo: params.out_trade_no,\n transactionId: params.trade_no,\n amount: Math.round(Number.parseFloat(params.total_amount) * 100), // 元 → 分\n status: statusMap[params.trade_status] ?? 'pending',\n paidAt: params.gmt_payment ? new Date(params.gmt_payment) : undefined,\n raw: params as unknown as Record<string, unknown>,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.NOTIFY_PARSE_FAILED,\n paymentM('payment_notifyParseFailed'),\n cause,\n )\n }\n },\n\n async queryOrder(orderNo: string): Promise<HaiResult<OrderStatus>> {\n try {\n const method = 'alipay.trade.query'\n const params = {\n ...buildCommonParams(method, ''),\n biz_content: JSON.stringify({ out_trade_no: orderNo }),\n }\n\n const response = await alipayRequest<Record<string, unknown>>(params)\n const data = response.alipay_trade_query_response as Record<string, unknown> | undefined\n\n const statusMap: Record<string, OrderStatus['status']> = {\n TRADE_SUCCESS: 'paid',\n TRADE_CLOSED: 'closed',\n TRADE_FINISHED: 'paid',\n WAIT_BUYER_PAY: 'pending',\n }\n\n return ok({\n orderNo,\n transactionId: data?.trade_no as string | undefined,\n status: statusMap[data?.trade_status as string] ?? 'pending',\n amount: Math.round(Number.parseFloat(data?.total_amount as string ?? '0') * 100),\n paidAt: data?.send_pay_date ? new Date(data.send_pay_date as string) : undefined,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.QUERY_ORDER_FAILED,\n paymentM('payment_queryOrderFailed'),\n cause,\n )\n }\n },\n\n async refund(input: RefundInput): Promise<HaiResult<RefundResult>> {\n try {\n const method = 'alipay.trade.refund'\n const params = {\n ...buildCommonParams(method, ''),\n biz_content: JSON.stringify({\n out_trade_no: input.orderNo,\n out_request_no: input.refundNo,\n refund_amount: (input.amount / 100).toFixed(2),\n refund_reason: input.reason,\n }),\n }\n\n const response = await alipayRequest<Record<string, unknown>>(params)\n const data = response.alipay_trade_refund_response as Record<string, unknown> | undefined\n\n return ok({\n refundNo: input.refundNo,\n refundId: data?.trade_no as string ?? '',\n status: data?.fund_change === 'Y' ? 'success' : 'processing',\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n cause,\n )\n }\n },\n\n async closeOrder(orderNo: string): Promise<HaiResult<void>> {\n try {\n const method = 'alipay.trade.close'\n const params = {\n ...buildCommonParams(method, ''),\n biz_content: JSON.stringify({ out_trade_no: orderNo }),\n }\n\n await alipayRequest(params)\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiPaymentError.CLOSE_ORDER_FAILED,\n paymentM('payment_closeOrderFailed'),\n cause,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/payment — Stripe Provider\n *\n * 实现 PaymentProvider 接口,对接 Stripe API。\n * 使用 Stripe Checkout Session 模式。\n * @module stripe-provider\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { StripeConfig } from '../../payment-config.js'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from '../../payment-types.js'\nimport { createHmac } from 'node:crypto'\nimport { core, err, ok } from '@h-ai/core'\nimport { paymentM } from '../../payment-i18n.js'\nimport {\n\n HaiPaymentError,\n\n} from '../../payment-types.js'\n\n/** Stripe API 基地址 */\nconst STRIPE_API_BASE = 'https://api.stripe.com/v1'\n\n/**\n * 创建 Stripe Provider\n *\n * @param config - Stripe 配置\n * @returns PaymentProvider 实例\n */\nexport function createStripeProvider(config: StripeConfig): PaymentProvider {\n /** Stripe API 请求 */\n async function stripeRequest<T>(method: string, path: string, body?: Record<string, string>): Promise<T> {\n const response = await fetch(`${STRIPE_API_BASE}${path}`, {\n method,\n headers: {\n 'Authorization': `Bearer ${config.secretKey}`,\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: body\n ? Object.entries(body).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&')\n : undefined,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(`Stripe API ${method} ${path} failed: ${response.status} ${errorText}`)\n }\n\n return response.json() as T\n }\n\n /** Stripe Webhook 签名容忍时间窗口(秒) */\n const TIMESTAMP_TOLERANCE = 300\n\n /** 验证 Stripe Webhook 签名 */\n function verifyWebhookSignature(payload: string, signature: string): boolean {\n const parts = signature.split(',')\n const timestamp = parts.find(p => p.startsWith('t='))?.slice(2) ?? ''\n const v1 = parts.find(p => p.startsWith('v1='))?.slice(3) ?? ''\n\n // 时间戳重放保护\n const ts = Number.parseInt(timestamp, 10)\n if (Number.isNaN(ts) || Math.abs(Math.floor(Date.now() / 1000) - ts) > TIMESTAMP_TOLERANCE) {\n return false\n }\n\n const signedPayload = `${timestamp}.${payload}`\n const expected = createHmac('sha256', config.webhookSecret)\n .update(signedPayload)\n .digest('hex')\n\n try {\n return core.string.constantTimeEqual(v1, expected)\n }\n catch {\n return false\n }\n }\n\n return {\n name: 'stripe',\n\n async createOrder(input: CreateOrderInput): Promise<HaiResult<PaymentOrder>> {\n try {\n // 使用 Stripe Checkout Session\n const params: Record<string, string> = {\n 'mode': 'payment',\n 'line_items[0][price_data][currency]': input.currency?.toLowerCase() ?? 'usd',\n 'line_items[0][price_data][product_data][name]': input.description,\n 'line_items[0][price_data][unit_amount]': input.amount.toString(),\n 'line_items[0][quantity]': '1',\n }\n\n // metadata 传递订单号\n params['metadata[orderNo]'] = input.orderNo\n if (input.metadata) {\n for (const [k, v] of Object.entries(input.metadata)) {\n params[`metadata[${k}]`] = v\n }\n }\n\n const session = await stripeRequest<{\n id: string\n url: string\n payment_intent: string\n }>('POST', '/checkout/sessions', params)\n\n return ok({\n provider: 'stripe',\n tradeType: input.tradeType,\n clientParams: {\n sessionId: session.id,\n checkoutUrl: session.url,\n },\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.CREATE_ORDER_FAILED,\n paymentM('payment_createOrderFailed'),\n cause,\n )\n }\n },\n\n async handleNotify(request: PaymentNotifyRequest): Promise<HaiResult<PaymentNotifyResult>> {\n try {\n const signature = request.headers['stripe-signature'] ?? ''\n\n // 验签\n const valid = verifyWebhookSignature(request.body, signature)\n if (!valid) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n\n const event = JSON.parse(request.body) as {\n type: string\n data: {\n object: {\n id: string\n metadata?: Record<string, string>\n amount_total?: number\n payment_status?: string\n }\n }\n }\n\n const obj = event.data.object\n const orderNo = obj.metadata?.orderNo ?? ''\n\n const statusMap: Record<string, PaymentNotifyResult['status']> = {\n 'checkout.session.completed': 'paid',\n 'payment_intent.payment_failed': 'failed',\n }\n\n return ok({\n orderNo,\n transactionId: obj.id,\n amount: obj.amount_total ?? 0,\n status: statusMap[event.type] ?? 'pending',\n paidAt: new Date(),\n raw: event as unknown as Record<string, unknown>,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.NOTIFY_PARSE_FAILED,\n paymentM('payment_notifyParseFailed'),\n cause,\n )\n }\n },\n\n async queryOrder(orderNo: string): Promise<HaiResult<OrderStatus>> {\n try {\n // 搜索 checkout sessions by metadata\n const sessions = await stripeRequest<{\n data: Array<{\n id: string\n payment_status: string\n amount_total: number\n }>\n }>('GET', `/checkout/sessions?limit=1&metadata[orderNo]=${encodeURIComponent(orderNo)}`)\n\n const session = sessions.data[0]\n if (!session) {\n return ok({\n orderNo,\n status: 'pending',\n amount: 0,\n })\n }\n\n const statusMap: Record<string, OrderStatus['status']> = {\n paid: 'paid',\n unpaid: 'pending',\n no_payment_required: 'paid',\n }\n\n return ok({\n orderNo,\n transactionId: session.id,\n status: statusMap[session.payment_status] ?? 'pending',\n amount: session.amount_total,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.QUERY_ORDER_FAILED,\n paymentM('payment_queryOrderFailed'),\n cause,\n )\n }\n },\n\n async refund(input: RefundInput): Promise<HaiResult<RefundResult>> {\n try {\n // Stripe 退款需要 payment_intent ID,这里简化为根据 orderNo 查询\n const sessions = await stripeRequest<{\n data: Array<{ payment_intent: string }>\n }>('GET', `/checkout/sessions?limit=1&metadata[orderNo]=${encodeURIComponent(input.orderNo)}`)\n\n const paymentIntent = sessions.data[0]?.payment_intent\n if (!paymentIntent) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n )\n }\n\n const refund = await stripeRequest<{\n id: string\n status: string\n }>('POST', '/refunds', {\n payment_intent: paymentIntent,\n amount: input.amount.toString(),\n reason: input.reason ?? 'requested_by_customer',\n })\n\n return ok({\n refundNo: input.refundNo,\n refundId: refund.id,\n status: refund.status === 'succeeded' ? 'success' : 'processing',\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n cause,\n )\n }\n },\n\n async closeOrder(_orderNo: string): Promise<HaiResult<void>> {\n // Stripe Checkout Sessions 会自动过期,无需主动关闭\n return ok(undefined)\n },\n }\n}\n","/**\n * @h-ai/payment — 微信支付签名\n *\n * 微信支付 API v3 签名生成与验签工具。\n * @module wechat-pay-sign\n */\n\nimport { Buffer } from 'node:buffer'\nimport { createDecipheriv, createSign, createVerify, randomBytes } from 'node:crypto'\n\n/**\n * 生成随机字符串\n *\n * @param length - 字符串长度(默认 32)\n */\nexport function generateNonce(length = 32): string {\n return randomBytes(length).toString('hex').slice(0, length)\n}\n\n/**\n * 获取当前时间戳(秒)\n */\nexport function getTimestamp(): string {\n return Math.floor(Date.now() / 1000).toString()\n}\n\n/**\n * 微信 API v3 请求签名\n *\n * @param method - HTTP 方法\n * @param url - 请求路径(不含域名)\n * @param timestamp - 时间戳\n * @param nonce - 随机串\n * @param body - 请求体(空则为空字符串)\n * @param privateKey - 商户私钥 PEM\n * @returns SHA256-RSA2048 签名(Base64)\n */\nexport function signRequest(\n method: string,\n url: string,\n timestamp: string,\n nonce: string,\n body: string,\n privateKey: string,\n): string {\n const message = `${method}\\n${url}\\n${timestamp}\\n${nonce}\\n${body}\\n`\n const sign = createSign('RSA-SHA256')\n sign.update(message)\n return sign.sign(privateKey, 'base64')\n}\n\n/**\n * 微信 JSAPI 支付签名\n *\n * @param appId - 应用 ID\n * @param timestamp - 时间戳\n * @param nonce - 随机串\n * @param prepayId - 预支付 ID\n * @param privateKey - 商户私钥 PEM\n * @returns 签名\n */\nexport function signJsapi(\n appId: string,\n timestamp: string,\n nonce: string,\n prepayId: string,\n privateKey: string,\n): string {\n const message = `${appId}\\n${timestamp}\\n${nonce}\\nprepay_id=${prepayId}\\n`\n const sign = createSign('RSA-SHA256')\n sign.update(message)\n return sign.sign(privateKey, 'base64')\n}\n\n/**\n * 验证微信支付回调签名\n *\n * @param timestamp - 回调 header 中的时间戳\n * @param nonce - 回调 header 中的随机串\n * @param body - 回调原始 body\n * @param signature - 回调签名\n * @param platformCert - 微信支付平台证书 PEM\n * @returns 是否验签通过\n */\nexport function verifyNotifySignature(\n timestamp: string,\n nonce: string,\n body: string,\n signature: string,\n platformCert: string,\n): boolean {\n const message = `${timestamp}\\n${nonce}\\n${body}\\n`\n const verify = createVerify('RSA-SHA256')\n verify.update(message)\n return verify.verify(platformCert, signature, 'base64')\n}\n\n/**\n * AES-256-GCM 解密(微信支付回调资源解密)\n *\n * @param ciphertext - 密文(Base64)\n * @param nonce - 随机串\n * @param associatedData - 附加数据\n * @param apiV3Key - API v3 密钥\n * @returns 解密后的 JSON 字符串\n */\nexport function decryptResource(\n ciphertext: string,\n nonce: string,\n associatedData: string,\n apiV3Key: string,\n): string {\n const buf = Buffer.from(ciphertext, 'base64')\n const authTag = buf.subarray(buf.length - 16)\n const data = buf.subarray(0, buf.length - 16)\n\n const decipher = createDecipheriv('aes-256-gcm', apiV3Key, nonce)\n decipher.setAuthTag(authTag)\n decipher.setAAD(Buffer.from(associatedData))\n\n const decrypted = Buffer.concat([decipher.update(data), decipher.final()])\n return decrypted.toString('utf-8')\n}\n","/**\n * @h-ai/payment — 微信支付 Provider\n *\n * 实现 PaymentProvider 接口,对接微信支付 API v3。\n * @module wechat-pay-provider\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { WechatPayConfig } from '../../payment-config.js'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from '../../payment-types.js'\nimport type { WechatNotifyResource, WechatOrderRequest } from './wechat-pay-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { paymentM } from '../../payment-i18n.js'\nimport {\n\n HaiPaymentError,\n\n} from '../../payment-types.js'\nimport {\n decryptResource,\n generateNonce,\n getTimestamp,\n signJsapi,\n signRequest,\n verifyNotifySignature,\n} from './wechat-pay-sign.js'\n\n/** 微信支付 API 基地址 */\nconst WECHAT_API_BASE = 'https://api.mch.weixin.qq.com'\n\n/**\n * 创建微信支付 Provider\n *\n * @param config - 微信支付配置\n * @returns PaymentProvider 实例\n *\n * @example\n * ```ts\n * const wechatPay = createWechatPayProvider({\n * mchId: 'your-mch-id',\n * apiV3Key: 'your-api-v3-key',\n * serialNo: 'your-serial-no',\n * privateKey: fs.readFileSync('apiclient_key.pem', 'utf-8'),\n * appId: 'your-app-id',\n * })\n *\n * const result = await wechatPay.createOrder({\n * orderNo: 'ORD20240101001',\n * amount: 100, // 1 元\n * description: '测试商品',\n * tradeType: 'jsapi',\n * userId: 'openid-xxx',\n * notifyUrl: 'https://api.example.com/payment/notify/wechat',\n * })\n * ```\n */\nexport function createWechatPayProvider(config: WechatPayConfig): PaymentProvider {\n /**\n * 发送微信支付 API 请求\n */\n async function wechatRequest<T>(method: string, path: string, body?: unknown): Promise<T> {\n const timestamp = getTimestamp()\n const nonce = generateNonce()\n const bodyStr = body ? JSON.stringify(body) : ''\n\n const signature = signRequest(method, path, timestamp, nonce, bodyStr, config.privateKey)\n\n const authorization = `WECHATPAY2-SHA256-RSA2048 mchid=\"${config.mchId}\",nonce_str=\"${nonce}\",timestamp=\"${timestamp}\",serial_no=\"${config.serialNo}\",signature=\"${signature}\"`\n\n const response = await fetch(`${WECHAT_API_BASE}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': authorization,\n 'Accept': 'application/json',\n },\n body: bodyStr || undefined,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(`Wechat API ${method} ${path} failed: ${response.status} ${errorText}`)\n }\n\n return response.json() as T\n }\n\n /** 根据 tradeType 映射到微信 API 路径 */\n function getOrderPath(tradeType: string): string {\n const map: Record<string, string> = {\n jsapi: '/v3/pay/transactions/jsapi',\n h5: '/v3/pay/transactions/h5',\n app: '/v3/pay/transactions/app',\n native: '/v3/pay/transactions/native',\n }\n return map[tradeType] ?? '/v3/pay/transactions/jsapi'\n }\n\n return {\n name: 'wechat',\n\n async createOrder(input: CreateOrderInput): Promise<HaiResult<PaymentOrder>> {\n try {\n const requestBody: WechatOrderRequest = {\n appid: config.appId,\n mchid: config.mchId,\n description: input.description,\n out_trade_no: input.orderNo,\n notify_url: input.notifyUrl,\n amount: {\n total: input.amount,\n currency: input.currency ?? 'CNY',\n },\n }\n\n // JSAPI 需要 payer.openid\n if (input.tradeType === 'jsapi' && input.userId) {\n requestBody.payer = { openid: input.userId }\n }\n\n if (input.metadata) {\n requestBody.attach = JSON.stringify(input.metadata)\n }\n\n const path = getOrderPath(input.tradeType)\n const response = await wechatRequest<{ prepay_id?: string, h5_url?: string, code_url?: string }>('POST', path, requestBody)\n\n // 构建客户端调起参数\n let clientParams: Record<string, unknown> = {}\n\n if (input.tradeType === 'jsapi') {\n const timestamp = getTimestamp()\n const nonce = generateNonce()\n const paySign = signJsapi(config.appId, timestamp, nonce, response.prepay_id!, config.privateKey)\n\n clientParams = {\n appId: config.appId,\n timeStamp: timestamp,\n nonceStr: nonce,\n package: `prepay_id=${response.prepay_id}`,\n signType: 'RSA',\n paySign,\n }\n }\n else if (input.tradeType === 'h5') {\n clientParams = { h5Url: response.h5_url }\n }\n else if (input.tradeType === 'native') {\n clientParams = { codeUrl: response.code_url }\n }\n\n return ok({\n provider: 'wechat',\n tradeType: input.tradeType,\n clientParams,\n prepayId: response.prepay_id,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.CREATE_ORDER_FAILED,\n paymentM('payment_createOrderFailed'),\n cause,\n )\n }\n },\n\n async handleNotify(request: PaymentNotifyRequest): Promise<HaiResult<PaymentNotifyResult>> {\n try {\n const timestamp = request.headers['wechatpay-timestamp'] ?? ''\n const nonce = request.headers['wechatpay-nonce'] ?? ''\n const signature = request.headers['wechatpay-signature'] ?? ''\n\n // 验签(必须提供平台证书)\n if (!config.platformCert) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n const valid = verifyNotifySignature(timestamp, nonce, request.body, signature, config.platformCert)\n if (!valid) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n\n // 解密资源\n const body = JSON.parse(request.body) as {\n resource: { ciphertext: string, nonce: string, associated_data: string }\n }\n const decrypted = decryptResource(\n body.resource.ciphertext,\n body.resource.nonce,\n body.resource.associated_data,\n config.apiV3Key,\n )\n const resource = JSON.parse(decrypted) as WechatNotifyResource\n\n return ok({\n orderNo: resource.out_trade_no,\n transactionId: resource.transaction_id,\n amount: resource.amount.total,\n status: resource.trade_state === 'SUCCESS' ? 'paid' : 'failed',\n paidAt: resource.success_time ? new Date(resource.success_time) : undefined,\n raw: resource as unknown as Record<string, unknown>,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.NOTIFY_PARSE_FAILED,\n paymentM('payment_notifyParseFailed'),\n cause,\n )\n }\n },\n\n async queryOrder(orderNo: string): Promise<HaiResult<OrderStatus>> {\n try {\n const path = `/v3/pay/transactions/out-trade-no/${encodeURIComponent(orderNo)}?mchid=${encodeURIComponent(config.mchId)}`\n const response = await wechatRequest<{\n out_trade_no: string\n transaction_id: string\n trade_state: string\n amount: { total: number }\n success_time?: string\n }>('GET', path)\n\n const statusMap: Record<string, OrderStatus['status']> = {\n SUCCESS: 'paid',\n CLOSED: 'closed',\n REFUND: 'refunded',\n NOTPAY: 'pending',\n PAYERROR: 'failed',\n }\n\n return ok({\n orderNo: response.out_trade_no,\n transactionId: response.transaction_id,\n status: statusMap[response.trade_state] ?? 'pending',\n amount: response.amount.total,\n paidAt: response.success_time ? new Date(response.success_time) : undefined,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.QUERY_ORDER_FAILED,\n paymentM('payment_queryOrderFailed'),\n cause,\n )\n }\n },\n\n async refund(input: RefundInput): Promise<HaiResult<RefundResult>> {\n try {\n const response = await wechatRequest<{\n refund_id: string\n status: string\n }>('POST', '/v3/refund/domestic/refunds', {\n out_trade_no: input.orderNo,\n out_refund_no: input.refundNo,\n amount: {\n refund: input.amount,\n total: input.totalAmount ?? input.amount,\n currency: 'CNY',\n },\n reason: input.reason,\n })\n\n const statusMap: Record<string, RefundResult['status']> = {\n SUCCESS: 'success',\n PROCESSING: 'processing',\n ABNORMAL: 'failed',\n }\n\n return ok({\n refundNo: input.refundNo,\n refundId: response.refund_id,\n status: statusMap[response.status] ?? 'processing',\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n cause,\n )\n }\n },\n\n async closeOrder(orderNo: string): Promise<HaiResult<void>> {\n try {\n await wechatRequest('POST', `/v3/pay/transactions/out-trade-no/${encodeURIComponent(orderNo)}/close`, {\n mchid: config.mchId,\n })\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiPaymentError.CLOSE_ORDER_FAILED,\n paymentM('payment_closeOrderFailed'),\n cause,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/payment — 模块入口(生命周期管理)\n *\n * 提供支付模块的初始化、Provider 注册与统一支付操作 API。\n * `payment.init(config)` 负责根据配置自动注册可用的 Provider。\n *\n * @module payment-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { PaymentConfig, PaymentConfigInput } from './payment-config.js'\nimport type {\n OrderStatus,\n PaymentFunctions,\n PaymentNotifyResult,\n PaymentOrder,\n RefundResult,\n} from './payment-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { PaymentConfigSchema } from './payment-config.js'\nimport {\n clearProviders,\n closeOrder,\n createOrder,\n getProvider,\n handleNotify,\n queryOrder,\n refund,\n registerProvider,\n} from './payment-functions.js'\nimport { paymentM } from './payment-i18n.js'\nimport { HaiPaymentError } from './payment-types.js'\nimport { createAlipayProvider } from './providers/alipay/alipay-provider.js'\nimport { createStripeProvider } from './providers/stripe/stripe-provider.js'\nimport { createWechatPayProvider } from './providers/wechat/wechat-pay-provider.js'\n\nconst logger = core.logger.child({ module: 'payment', scope: 'main' })\n\n// ─── 内部状态 ───\n\nlet currentConfig: PaymentConfig | null = null\nlet initInProgress = false\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiPaymentError.NOT_INITIALIZED,\n () => paymentM('payment_notInitialized'),\n)\n\n// ─── 服务对象 ───\n\n/**\n * 支付模块服务对象\n *\n * @example\n * ```ts\n * import { payment } from '@h-ai/payment'\n *\n * await payment.init({\n * wechat: { mchId: '...', apiV3Key: '...', ... },\n * alipay: { appId: '...', privateKey: '...' , ... },\n * })\n *\n * const result = await payment.createOrder('wechat', {\n * orderNo: 'ORD001',\n * amount: 100,\n * description: '测试商品',\n * tradeType: 'jsapi',\n * userId: 'openid-xxx',\n * notifyUrl: 'https://api.example.com/payment/notify/wechat',\n * })\n * ```\n */\nexport const payment: PaymentFunctions = {\n /**\n * 初始化支付模块\n *\n * 根据提供的配置自动注册对应的 Provider。\n *\n * @param config - 支付配置\n */\n async init(config: PaymentConfigInput): Promise<HaiResult<void>> {\n if (initInProgress) {\n logger.warn('Payment module init already in progress, skipping')\n return err(\n HaiPaymentError.CONFIG_ERROR,\n paymentM('payment_configError', { params: { error: 'init already in progress' } }),\n )\n }\n\n initInProgress = true\n\n try {\n if (currentConfig !== null) {\n logger.warn('Payment module is already initialized, reinitializing')\n await payment.close()\n }\n\n logger.info('Initializing payment module')\n const parseResult = PaymentConfigSchema.safeParse(config)\n if (!parseResult.success) {\n logger.error('Payment config validation failed', { error: parseResult.error.message })\n return err(\n HaiPaymentError.CONFIG_ERROR,\n paymentM('payment_configError', { params: { error: parseResult.error.message } }),\n parseResult.error,\n )\n }\n const parsed = parseResult.data\n\n // 清除旧注册\n clearProviders()\n\n // 按配置自动注册 Provider\n if (parsed.wechat) {\n registerProvider(createWechatPayProvider(parsed.wechat))\n }\n if (parsed.alipay) {\n registerProvider(createAlipayProvider(parsed.alipay))\n }\n if (parsed.stripe) {\n registerProvider(createStripeProvider(parsed.stripe))\n }\n\n currentConfig = parsed\n logger.info('Payment module initialized', {\n providers: [\n parsed.wechat ? 'wechat' : null,\n parsed.alipay ? 'alipay' : null,\n parsed.stripe ? 'stripe' : null,\n ].filter(Boolean),\n })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Payment module initialization failed', { error })\n return err(\n HaiPaymentError.CONFIG_ERROR,\n paymentM('payment_initFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n /**\n * 关闭模块、清除所有 Provider\n */\n async close(): Promise<void> {\n if (!currentConfig) {\n logger.info('Payment module already closed, skipping')\n return\n }\n logger.info('Closing payment module')\n clearProviders()\n currentConfig = null\n logger.info('Payment module closed')\n },\n\n get config() { return currentConfig },\n get isInitialized() { return currentConfig !== null },\n\n /** 创建支付订单 */\n createOrder: (...args: Parameters<typeof createOrder>) =>\n currentConfig ? createOrder(...args) : Promise.resolve(notInitialized.result<PaymentOrder>()),\n\n /** 处理异步回调通知 */\n handleNotify: (...args: Parameters<typeof handleNotify>) =>\n currentConfig ? handleNotify(...args) : Promise.resolve(notInitialized.result<PaymentNotifyResult>()),\n\n /** 查询订单状态 */\n queryOrder: (...args: Parameters<typeof queryOrder>) =>\n currentConfig ? queryOrder(...args) : Promise.resolve(notInitialized.result<OrderStatus>()),\n\n /** 发起退款 */\n refund: (...args: Parameters<typeof refund>) =>\n currentConfig ? refund(...args) : Promise.resolve(notInitialized.result<RefundResult>()),\n\n /** 关闭订单 */\n closeOrder: (...args: Parameters<typeof closeOrder>) =>\n currentConfig ? closeOrder(...args) : Promise.resolve(notInitialized.result<void>()),\n\n /** 获取已注册的 Provider */\n getProvider,\n\n /** 手动注册 Provider(自定义渠道) */\n registerProvider,\n}\n"]}
1
+ {"version":3,"sources":["../src/payment-config.ts","../src/payment-functions.ts","../src/providers/payment-provider-http.ts","../src/providers/alipay/payment-alipay-sign.ts","../src/providers/alipay/payment-alipay-time.ts","../src/providers/alipay/payment-alipay-types.ts","../src/providers/alipay/payment-provider-alipay.ts","../src/providers/payment-provider-notify.ts","../src/providers/stripe/payment-stripe-repository-operation.ts","../src/providers/stripe/payment-provider-stripe.ts","../src/providers/wechat/payment-wechat-sign.ts","../src/providers/wechat/payment-wechat-types.ts","../src/providers/wechat/payment-provider-wechat.ts","../src/payment-main.ts"],"names":["z","err","ok","core","refund","createSign","createVerify","logger","reldb"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/payment — 错误码 + 配置 Schema\n *\n * 支付模块的错误码、Zod 配置 Schema 与配置类型。\n * @module payment-config\n */\n\nimport { z } from 'zod'\nimport { paymentM } from './payment-i18n.js'\n\n// ─── 配置 Schema ───\n\n/**\n * 微信公众号 JSAPI 配置 Schema;平台密钥按受信 serial 精确配置。\n * @example\n * ```ts\n * import { WechatPayConfigSchema } from '@h-ai/payment'\n * // 部署系统注入可信配置;Schema 校验形状,不证明密钥、证书或渠道账户可用。\n * const platformKeys: unknown = JSON.parse(process.env.HAI_PAYMENT_WECHAT_PLATFORMKEYS ?? '{}')\n * const parsed = WechatPayConfigSchema.safeParse({\n * mchId: process.env.HAI_PAYMENT_WECHAT_MCHID,\n * apiV3Key: process.env.HAI_PAYMENT_WECHAT_APIV3KEY,\n * serialNo: process.env.HAI_PAYMENT_WECHAT_SERIALNO,\n * privateKey: process.env.HAI_PAYMENT_WECHAT_PRIVATEKEY,\n * platformKeys,\n * appId: process.env.HAI_PAYMENT_WECHAT_APPID,\n * })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config = parsed.data\n * ```\n */\nexport const WechatPayConfigSchema = z.object({\n mchId: z.string().min(1, paymentM('payment_configFieldRequired')),\n apiV3Key: z.string().min(1, paymentM('payment_configFieldRequired')),\n serialNo: z.string().min(1, paymentM('payment_configFieldRequired')),\n privateKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n /** 精确按 Wechatpay-Serial 选择平台证书/公钥,轮换期间同时配置新旧标识。 */\n platformKeys: z.record(z.string().min(1), z.string().min(1))\n .refine(keys => Object.keys(keys).length > 0, paymentM('payment_configFieldRequired')),\n appId: z.string().min(1, paymentM('payment_configFieldRequired')),\n})\n\n/**\n * 支付宝手机网站支付配置 Schema;returnUrl 为可信 HTTPS 导航地址。\n * @example\n * ```ts\n * import { AlipayConfigSchema } from '@h-ai/payment'\n * // 部署系统注入可信配置;Schema 校验形状,不证明密钥、证书或渠道账户可用。\n * const parsed = AlipayConfigSchema.safeParse({\n * appId: process.env.HAI_PAYMENT_ALIPAY_APPID,\n * sellerId: process.env.HAI_PAYMENT_ALIPAY_SELLERID,\n * privateKey: process.env.HAI_PAYMENT_ALIPAY_PRIVATEKEY,\n * alipayPublicKey: process.env.HAI_PAYMENT_ALIPAY_ALIPAYPUBLICKEY,\n * returnUrl: 'https://shop.example.com/payment/result',\n * })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config = parsed.data\n * ```\n */\nexport const AlipayConfigSchema = z.object({\n appId: z.string().min(1, paymentM('payment_configFieldRequired')),\n sellerId: z.string().min(1, paymentM('payment_configFieldRequired')),\n privateKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n alipayPublicKey: z.string().min(1, paymentM('payment_configFieldRequired')),\n /** 手机网站支付完成后返回的可信 HTTPS 地址;仅用于页面导航,不能证明付款。 */\n returnUrl: z.url({ protocol: /^https$/ }),\n signType: z.enum(['RSA2', 'RSA']).default('RSA2'),\n sandbox: z.boolean().default(false),\n})\n\n/**\n * Stripe 托管 Checkout 配置 Schema;初始化前要求共享 reldb 就绪。\n * @example\n * ```ts\n * import { StripeConfigSchema } from '@h-ai/payment'\n * // 部署系统注入可信配置;Schema 校验形状,不证明密钥、证书或渠道账户可用。\n * const parsed = StripeConfigSchema.safeParse({\n * secretKey: process.env.HAI_PAYMENT_STRIPE_SECRETKEY,\n * webhookSecret: process.env.HAI_PAYMENT_STRIPE_WEBHOOKSECRET,\n * successUrl: 'https://shop.example.com/payment/result?session={CHECKOUT_SESSION_ID}',\n * })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config = parsed.data\n * ```\n */\nexport const StripeConfigSchema = z.object({\n secretKey: z.string().regex(/^(?:sk|rk)_(?:test|live)_\\S+$/, paymentM('payment_stripeKeyInvalid')),\n webhookSecret: z.string().min(1, paymentM('payment_configFieldRequired')),\n /** 托管 Checkout 完成后的可信跳转地址,可含 {CHECKOUT_SESSION_ID}。 */\n successUrl: z.url({ protocol: /^https?$/ }),\n /** 托管 Checkout 取消按钮的可信跳转地址;省略时不显示返回按钮。 */\n cancelUrl: z.url({ protocol: /^https?$/ }).optional(),\n webhookToleranceSeconds: z.number().int().positive().default(300),\n}).strict()\n\n/**\n * 支付模块配置 Schema;按配置注册渠道,密钥与运行时依赖由宿主提供。\n * @example\n * ```ts\n * import { PaymentConfigSchema } from '@h-ai/payment'\n * const parsed = PaymentConfigSchema.safeParse({ stripe: {\n * secretKey: process.env.HAI_PAYMENT_STRIPE_SECRETKEY,\n * webhookSecret: process.env.HAI_PAYMENT_STRIPE_WEBHOOKSECRET,\n * successUrl: 'https://shop.example.com/payment/result?session={CHECKOUT_SESSION_ID}',\n * } })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const toleranceSeconds = parsed.data.stripe?.webhookToleranceSeconds\n * ```\n */\nexport const PaymentConfigSchema = z.object({\n wechat: WechatPayConfigSchema.optional(),\n alipay: AlipayConfigSchema.optional(),\n stripe: StripeConfigSchema.optional(),\n})\n\n/**\n * PaymentConfigSchema 解析后的配置类型;不能把未解析输入当作该类型。\n * @example\n * ```ts\n * import { PaymentConfigSchema, type PaymentConfig } from '@h-ai/payment'\n * const parsed = PaymentConfigSchema.safeParse({ stripe: {\n * secretKey: process.env.HAI_PAYMENT_STRIPE_SECRETKEY,\n * webhookSecret: process.env.HAI_PAYMENT_STRIPE_WEBHOOKSECRET,\n * successUrl: 'https://shop.example.com/payment/result?session={CHECKOUT_SESSION_ID}',\n * } })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config: PaymentConfig = parsed.data\n * config.stripe?.webhookToleranceSeconds // 解析输出包含默认的签名容差。\n * ```\n */\nexport type PaymentConfig = z.infer<typeof PaymentConfigSchema>\n/**\n * 支付初始化输入;允许省略由 Schema 补齐的配置默认值。\n * @example\n * ```ts\n * import { payment, type PaymentConfigInput } from '@h-ai/payment'\n * async function initializePayment(input: PaymentConfigInput) {\n * // 启用 Stripe 时,宿主已经先初始化共享 reldb 并检查成功。\n * const result = await payment.init(input)\n * if (!result.success) throw new Error(result.error.message)\n * }\n * ```\n */\nexport type PaymentConfigInput = z.input<typeof PaymentConfigSchema>\n/**\n * 微信配置的解析输出类型;默认值已经由对应 Schema 补齐。\n * @example\n * ```ts\n * import { WechatPayConfigSchema, type WechatPayConfig } from '@h-ai/payment'\n * const platformKeys: unknown = JSON.parse(process.env.HAI_PAYMENT_WECHAT_PLATFORMKEYS ?? '{}')\n * const parsed = WechatPayConfigSchema.safeParse({\n * mchId: process.env.HAI_PAYMENT_WECHAT_MCHID,\n * apiV3Key: process.env.HAI_PAYMENT_WECHAT_APIV3KEY,\n * serialNo: process.env.HAI_PAYMENT_WECHAT_SERIALNO,\n * privateKey: process.env.HAI_PAYMENT_WECHAT_PRIVATEKEY,\n * platformKeys,\n * appId: process.env.HAI_PAYMENT_WECHAT_APPID,\n * })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config: WechatPayConfig = parsed.data\n * ```\n */\nexport type WechatPayConfig = z.infer<typeof WechatPayConfigSchema>\n/**\n * 支付宝配置的解析输出类型;默认值已经由对应 Schema 补齐。\n * @example\n * ```ts\n * import { AlipayConfigSchema, type AlipayConfig } from '@h-ai/payment'\n * const parsed = AlipayConfigSchema.safeParse({\n * appId: process.env.HAI_PAYMENT_ALIPAY_APPID,\n * sellerId: process.env.HAI_PAYMENT_ALIPAY_SELLERID,\n * privateKey: process.env.HAI_PAYMENT_ALIPAY_PRIVATEKEY,\n * alipayPublicKey: process.env.HAI_PAYMENT_ALIPAY_ALIPAYPUBLICKEY,\n * returnUrl: 'https://shop.example.com/payment/result',\n * })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config: AlipayConfig = parsed.data\n * ```\n */\nexport type AlipayConfig = z.infer<typeof AlipayConfigSchema>\n/**\n * Stripe配置的解析输出类型;默认值已经由对应 Schema 补齐。\n * @example\n * ```ts\n * import { StripeConfigSchema, type StripeConfig } from '@h-ai/payment'\n * const parsed = StripeConfigSchema.safeParse({\n * secretKey: process.env.HAI_PAYMENT_STRIPE_SECRETKEY,\n * webhookSecret: process.env.HAI_PAYMENT_STRIPE_WEBHOOKSECRET,\n * successUrl: 'https://shop.example.com/payment/result?session={CHECKOUT_SESSION_ID}',\n * })\n * if (!parsed.success) throw new Error('Payment configuration is invalid')\n * const config: StripeConfig = parsed.data\n * ```\n */\nexport type StripeConfig = z.infer<typeof StripeConfigSchema>\n","/**\n * @h-ai/payment — 业务逻辑编排\n *\n * 统一路由到对应 Provider 的支付操作。\n * @module payment-functions\n */\n\nimport type { CreateAuditLogInput } from '@h-ai/audit'\nimport type { HaiResult } from '@h-ai/core'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from './payment-types.js'\nimport { audit } from '@h-ai/audit'\nimport { core, err, ok } from '@h-ai/core'\nimport { paymentM } from './payment-i18n.js'\nimport { HaiPaymentError } from './payment-types.js'\n\nconst logger = core.logger.child({ module: 'payment', scope: 'functions' })\n\n/** Provider 注册表 */\nconst providers = new Map<string, PaymentProvider>()\n\n/**\n * 写审计日志(失败仅 warn,不影响支付操作)\n */\nasync function auditLog(input: CreateAuditLogInput): Promise<void> {\n const result = await audit.log(input)\n if (!result.success) {\n logger.warn('Failed to write payment audit log', { action: input.action, error: result.error.message })\n }\n}\n\nfunction isValidAmount(amount: number): boolean {\n return Number.isSafeInteger(amount) && amount > 0\n}\n\nfunction validateCreateOrderInput(input: CreateOrderInput): HaiResult<void> {\n if (!isValidAmount(input.amount)) {\n return err(\n HaiPaymentError.INVALID_AMOUNT,\n paymentM('payment_invalidAmount'),\n )\n }\n\n return ok(undefined)\n}\n\nfunction validateRefundInput(input: RefundInput): HaiResult<void> {\n if (!isValidAmount(input.amount)) {\n return err(\n HaiPaymentError.INVALID_AMOUNT,\n paymentM('payment_invalidAmount'),\n )\n }\n\n if (input.totalAmount !== undefined) {\n if (!isValidAmount(input.totalAmount) || input.totalAmount < input.amount) {\n return err(\n HaiPaymentError.INVALID_AMOUNT,\n paymentM('payment_invalidAmount'),\n )\n }\n }\n\n return ok(undefined)\n}\n\n/**\n * 注册支付 Provider\n *\n * @param provider - PaymentProvider 实例\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function registerCustomProvider(provider: PaymentProvider) {\n * registerProvider(provider)\n * return getProvider(provider.name)\n * }\n * ```\n */\nexport function registerProvider(provider: PaymentProvider): void {\n providers.set(provider.name, provider)\n}\n\n/**\n * 获取已注册的 Provider\n *\n * @param name - Provider 名称\n * @returns Provider 实例(不存在返回 undefined)\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const provider = getProvider('stripe')\n * if (provider) {\n * const result = await provider.queryOrder('ORDER_1')\n * if (!result.success) throw new Error(result.error.message)\n * }\n * ```\n */\nexport function getProvider(name: string): PaymentProvider | undefined {\n return providers.get(name)\n}\n\n/**\n * 获取 Provider(不存在则返回 err)\n */\nfunction requireProvider(name: string): HaiResult<PaymentProvider> {\n const provider = providers.get(name)\n if (!provider) {\n return err(\n HaiPaymentError.PROVIDER_NOT_FOUND,\n paymentM('payment_providerNotFound'),\n )\n }\n return ok(provider)\n}\n\n/**\n * 通过指定 Provider 创建订单\n *\n * @param providerName - Provider 名称('wechat' | 'alipay' | 'stripe')\n * @param input - 创建订单入参\n * @returns 成功返回客户端调起所需的订单参数;失败不代表渠道绝对没有执行,需遵循对应渠道幂等与核对规则。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 生命周期已注册目标 Provider;业务订单及退款标识已经持久化。\n * const result = await createOrder('stripe', {\n * orderNo: 'ORDER_1', amount: 100, currency: 'CNY', description: '测试商品',\n * tradeType: 'h5', notifyUrl: 'https://api.example.com/payment/notify/stripe',\n * })\n * if (!result.success) return result\n * return result\n * ```\n */\nexport async function createOrder(\n providerName: string,\n input: CreateOrderInput,\n): Promise<HaiResult<PaymentOrder>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n\n const validateResult = validateCreateOrderInput(input)\n if (!validateResult.success)\n return validateResult as HaiResult<PaymentOrder>\n\n const orderResult = await result.data.createOrder(input)\n if (orderResult.success) {\n await auditLog({\n action: 'create_order',\n resource: 'payment',\n resourceId: input.orderNo,\n details: { provider: providerName, amount: input.amount, tradeType: input.tradeType },\n })\n }\n return orderResult\n}\n\n/**\n * 处理支付回调通知\n *\n * @param providerName - Provider 名称\n * @param request - 原始 HTTP 请求数据\n * @returns 验签及解析结果;仅 status=paid 表示已付款,宿主仍需持久核对和幂等履约。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function verifyStripeNotification(request: PaymentNotifyRequest) {\n * const result = await handleNotify('stripe', request)\n * if (!result.success) return result\n * if (result.data.status === 'paid') {\n * // 仅将验签结果交给宿主的共享事务履约;必须核对订单/金额/币种并持久去重。\n * }\n * return result\n * }\n * ```\n */\nexport async function handleNotify(\n providerName: string,\n request: PaymentNotifyRequest,\n): Promise<HaiResult<PaymentNotifyResult>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n const notifyResult = await result.data.handleNotify(request)\n if (notifyResult.success) {\n await auditLog({\n action: 'payment_notify',\n resource: 'payment',\n resourceId: notifyResult.data.orderNo,\n details: { provider: providerName, transactionId: notifyResult.data.transactionId, eventId: notifyResult.data.eventId, status: notifyResult.data.status, amount: notifyResult.data.amount, currency: notifyResult.data.currency },\n })\n }\n return notifyResult\n}\n\n/**\n * 查询订单状态\n *\n * @param providerName - Provider 名称\n * @param orderNo - 商户订单号\n * @returns 成功返回渠道确认的订单状态;未知订单或渠道错误返回失败,不能默认为 pending。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 生命周期已注册目标 Provider;业务订单及退款标识已经持久化。\n * const result = await queryOrder('stripe', 'ORDER_1')\n * if (!result.success) return result\n * return result\n * ```\n */\nexport async function queryOrder(\n providerName: string,\n orderNo: string,\n): Promise<HaiResult<OrderStatus>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n return result.data.queryOrder(orderNo)\n}\n\n/**\n * 发起退款\n *\n * @param providerName - Provider 名称\n * @param input - 退款入参\n * @returns 成功返回本次退款受理状态;processing 不能视作退款完成。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 生命周期已注册目标 Provider;业务订单及退款标识已经持久化。\n * const result = await refund('stripe', { orderNo: 'ORDER_1', refundNo: 'REFUND_1', amount: 50 })\n * if (!result.success) return result\n * return result\n * ```\n */\nexport async function refund(\n providerName: string,\n input: RefundInput,\n): Promise<HaiResult<RefundResult>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n\n const validateResult = validateRefundInput(input)\n if (!validateResult.success)\n return validateResult as HaiResult<RefundResult>\n\n const refundResult = await result.data.refund(input)\n if (refundResult.success) {\n await auditLog({\n action: 'refund',\n resource: 'payment',\n resourceId: input.orderNo,\n details: { provider: providerName, refundNo: input.refundNo, amount: input.amount },\n })\n }\n return refundResult\n}\n\n/**\n * 关闭订单\n *\n * @param providerName - Provider 名称\n * @param orderNo - 商户订单号\n * @returns 只有渠道确认订单已关闭或过期才成功;已支付、未知状态或渠道错误返回失败。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 生命周期已注册目标 Provider;业务订单及退款标识已经持久化。\n * const result = await closeOrder('stripe', 'ORDER_1')\n * if (!result.success) return result\n * return result\n * ```\n */\nexport async function closeOrder(\n providerName: string,\n orderNo: string,\n): Promise<HaiResult<void>> {\n const result = requireProvider(providerName)\n if (!result.success)\n return result\n const closeResult = await result.data.closeOrder(orderNo)\n if (closeResult.success) {\n await auditLog({\n action: 'close_order',\n resource: 'payment',\n resourceId: orderNo,\n details: { provider: providerName },\n })\n }\n return closeResult\n}\n\n/**\n * 清空本进程的 Provider 调度注册表;生命周期关闭及隔离测试使用,不删除共享幂等记录。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 仅在停止接收支付调用之后,由 payment.close 清理当前进程的调度注册表。\n * clearProviders()\n * const unavailable = getProvider('stripe') // undefined;共享渠道操作记录不会被删除。\n * ```\n */\nexport function clearProviders(): void {\n providers.clear()\n}\n","/**\n * @h-ai/payment — Provider HTTP 辅助\n *\n * 为各支付 Provider 的 fetch 请求统一附加超时控制。\n * @module payment-provider-http\n */\n\nconst DEFAULT_PROVIDER_TIMEOUT_MS = 15_000\n\n/**\n * 支付渠道的有界 fetch;组合调用方取消与请求超时,不代替协议响应校验。\n * @param input - 受信支付渠道 URL;不得传入未经验证的用户目标地址。\n * @param init - 原生 fetch 请求设置;若带 signal,会与模块超时信号组合。\n * @param timeoutMs - 请求期限,单位毫秒,默认 10000。\n * @returns 原生 Response;HTTP 非成功状态仍由调用 Provider 检查。\n * @throws 网络错误、取消或超时会拒绝 Promise,由渠道 Provider 转为 HaiResult。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const response = await fetchWithTimeout('https://api.stripe.com/v1/account', {\n * method: 'GET', signal: AbortSignal.timeout(2_000),\n * }, 5_000)\n * if (!response.ok) throw new Error('Payment channel rejected the request')\n * // 这里只说明有界 HTTP;真实请求还须由对应 Provider 注入商户凭据与协议字段。\n * ```\n */\nexport async function fetchWithTimeout(input: string, init: RequestInit, timeoutMs = DEFAULT_PROVIDER_TIMEOUT_MS): Promise<Response> {\n return fetch(input, {\n ...init,\n signal: init.signal\n ? AbortSignal.any([init.signal, AbortSignal.timeout(timeoutMs)])\n : AbortSignal.timeout(timeoutMs),\n })\n}\n","/**\n * @h-ai/payment — 支付宝签名\n *\n * 支付宝 RSA2/RSA 签名与验签工具。\n * @module payment-alipay-sign\n */\n\nimport { createSign, createVerify } from 'node:crypto'\n\n/**\n * 支付宝参数签名\n *\n * @param params - 待签名参数(已排除 sign)\n * @param privateKey - 应用私钥 PEM\n * @param signType - 签名类型(默认 RSA2)\n * @returns Base64 编码的签名\n * @throws 私钥格式或签名参数不受 Node Crypto 支持时抛错,由 Provider 转为 HaiResult 失败。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function signForm(params: Record<string, string>, privateKeyPem: string): string {\n * // params 尚不包含 sign;私钥由受信商户配置注入,不写入日志或客户端。\n * return signAlipayParams(params, privateKeyPem, 'RSA2')\n * }\n * ```\n */\nexport function signAlipayParams(\n params: Record<string, string>,\n privateKey: string,\n signType: 'RSA2' | 'RSA' = 'RSA2',\n): string {\n // 按 key 字典排序,拼接为 query string\n const sorted = Object.keys(params)\n .filter(k => params[k] !== undefined && params[k] !== '')\n .sort()\n .map(k => `${k}=${params[k]}`)\n .join('&')\n\n const algorithm = signType === 'RSA2' ? 'RSA-SHA256' : 'RSA-SHA1'\n const sign = createSign(algorithm)\n sign.update(sorted)\n return sign.sign(privateKey, 'base64')\n}\n\n/**\n * 验证支付宝回调签名\n *\n * @param params - 回调参数(含 sign 和 sign_type)\n * @param alipayPublicKey - 支付宝公钥 PEM\n * @returns 验签是否通过\n * @throws 受信公钥格式非法或 Crypto 验签异常时抛错,由 Provider 通知边界转为失败。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function verifyForm(rawForm: string, trustedAlipayPublicKey: string): boolean {\n * const params = Object.fromEntries(new URLSearchParams(rawForm))\n * return verifyAlipayNotify(params, trustedAlipayPublicKey)\n * // 该 helper 只验签;商户身份、字段、金额和真实日历校验仍由 Provider 完成。\n * }\n * ```\n */\nexport function verifyAlipayNotify(\n params: Record<string, string>,\n alipayPublicKey: string,\n): boolean {\n const sign = params.sign ?? ''\n const signType = params.sign_type\n if (signType !== 'RSA' && signType !== 'RSA2')\n return false\n\n // 排除 sign 和 sign_type,按 key 排序拼接\n const sorted = Object.keys(params)\n .filter(k => k !== 'sign' && k !== 'sign_type' && params[k] !== undefined && params[k] !== '')\n .sort()\n .map(k => `${k}=${params[k]}`)\n .join('&')\n\n const algorithm = signType === 'RSA2' ? 'RSA-SHA256' : 'RSA-SHA1'\n const verify = createVerify(algorithm)\n verify.update(sorted)\n return verify.verify(alipayPublicKey, sign, 'base64')\n}\n","/** 支付宝协议中的北京时间格式化与真实日历校验。 */\n\nconst beijingFormatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'Asia/Shanghai',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hourCycle: 'h23',\n})\n\n/**\n * 格式化为支付宝要求的北京时间,不依赖当前节点的 TZ。\n * @param date - 待格式化的有效时间\n * @returns yyyy-MM-dd HH:mm:ss 格式的北京时间\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const beijingTime = formatAlipayTime(new Date('2026-10-22T00:00:00Z'))\n * // '2026-10-22 08:00:00';节点 TZ 为 UTC 时结果相同。\n * ```\n */\nexport function formatAlipayTime(date: Date): string {\n const parts = Object.fromEntries(beijingFormatter.formatToParts(date).map(part => [part.type, part.value]))\n return `${parts.year}-${parts.month}-${parts.day} ${parts.hour}:${parts.minute}:${parts.second}`\n}\n\n/**\n * 严格解析北京时间;回读校验拒绝 2 月 30 日等会被 Date 自动归一化的值。\n * @param value - 支付宝协议的北京时间字符串\n * @returns 对应的绝对时间;格式或日历非法时为 undefined\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const valid = parseAlipayTime('2026-10-22 08:00:00')?.toISOString()\n * const invalid = parseAlipayTime('2026-02-30 08:00:00') // undefined,不接受自动归一化日期。\n * ```\n */\nexport function parseAlipayTime(value: string): Date | undefined {\n if (!/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/.test(value))\n return undefined\n const date = new Date(`${value.replace(' ', 'T')}+08:00`)\n return Number.isFinite(date.getTime()) && formatAlipayTime(date) === value ? date : undefined\n}\n","/**\n * @h-ai/payment — 支付宝类型\n *\n * 支付宝 Open API 的内部请求/响应类型。\n * @module payment-alipay-types\n */\n\nimport { z } from 'zod'\nimport { parseAlipayTime } from './payment-alipay-time.js'\n\n/** 支付宝北京时间,拒绝非法日历日期。 */\nconst AlipayTimeSchema = z.string().refine(value => parseAlipayTime(value) !== undefined)\n\n/**\n * 支付宝响应根对象;仅允许 JSON 对象,按请求方法读取对应 envelope。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayResponseRootSchema.safeParse({ alipay_trade_close_response: { code: '10000' } })\n * if (!parsed.success) throw new Error('Invalid Alipay response')\n * const response = parsed.data // Schema 只校验结构;业务成功码与请求身份仍由 Provider 核对。\n * ```\n */\nexport const AlipayResponseRootSchema = z.record(z.string(), z.unknown())\n\n/**\n * 支付宝公共响应;错误描述不进入上层错误,避免泄漏原始业务数据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayResponseSchema.safeParse({ code: '40004', sub_code: 'ACQ.TRADE_NOT_EXIST' })\n * if (!parsed.success) throw new Error('Invalid Alipay response')\n * const response = parsed.data // Schema 只校验结构;业务成功码与请求身份仍由 Provider 核对。\n * ```\n */\nexport const AlipayResponseSchema = z.object({\n code: z.string().regex(/^\\d{5}$/),\n sub_code: z.string().optional(),\n})\n\n/** 支付宝金额字符串,禁止指数、负数和超过两位的小数。 */\nconst AlipayAmountSchema = z.string().regex(/^\\d+(?:\\.\\d{1,2})?$/)\n\n/**\n * 查单成功字段;未知交易状态和缺失金额均拒绝,不能默认成 pending 或零金额。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayQueryResponseSchema.safeParse({ out_trade_no: 'ORDER_1', trade_no: 'ALI_1', trade_status: 'TRADE_SUCCESS', total_amount: '1.00', send_pay_date: '2026-10-22 08:00:00' })\n * if (!parsed.success) throw new Error('Invalid Alipay response')\n * const response = parsed.data // Schema 只校验结构;业务成功码与请求身份仍由 Provider 核对。\n * ```\n */\nexport const AlipayQueryResponseSchema = z.object({\n out_trade_no: z.string().min(1),\n trade_no: z.string().min(1),\n trade_status: z.enum(['WAIT_BUYER_PAY', 'TRADE_CLOSED', 'TRADE_SUCCESS', 'TRADE_FINISHED']),\n total_amount: AlipayAmountSchema,\n send_pay_date: AlipayTimeSchema.optional(),\n})\n\n/**\n * 退款受理成功字段;fund_change 缺失或 N 不能证明退款到账。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayRefundResponseSchema.safeParse({ out_trade_no: 'ORDER_1', trade_no: 'ALI_1', refund_fee: '1.00', fund_change: 'Y' })\n * if (!parsed.success) throw new Error('Invalid Alipay response')\n * const response = parsed.data // Schema 只校验结构;业务成功码与请求身份仍由 Provider 核对。\n * ```\n */\nexport const AlipayRefundResponseSchema = z.object({\n out_trade_no: z.string().min(1),\n trade_no: z.string().min(1),\n refund_fee: AlipayAmountSchema,\n fund_change: z.enum(['Y', 'N']).optional(),\n})\n\n/**\n * 关单成功必须返回可核对的商户订单号和支付宝交易号。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayCloseResponseSchema.safeParse({ out_trade_no: 'ORDER_1', trade_no: 'ALI_1' })\n * if (!parsed.success) throw new Error('Invalid Alipay response')\n * const response = parsed.data // Schema 只校验结构;业务成功码与请求身份仍由 Provider 核对。\n * ```\n */\nexport const AlipayCloseResponseSchema = z.object({\n out_trade_no: z.string().min(1),\n trade_no: z.string().min(1),\n})\n\n/**\n * 支付宝交易通知参数;身份字段、通知 ID 和北京时间不可缺失。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayNotifyParamsSchema.safeParse({\n * app_id: 'app-1', seller_id: 'seller-1', notify_id: 'notify-1',\n * notify_type: 'trade_status_sync', notify_time: '2026-10-22 08:00:00',\n * sign_type: 'RSA2', sign: 'signature-from-channel', out_trade_no: 'ORDER_1',\n * trade_no: 'ALI_1', trade_status: 'TRADE_SUCCESS', total_amount: '1.00',\n * gmt_payment: '2026-10-22 07:59:00',\n * })\n * if (!parsed.success) throw new Error('Invalid Alipay notification')\n * const value = parsed.data // 结构通过并不代表该占位签名可信;还必须验签并核对 appId/sellerId。\n * ```\n */\nexport const AlipayNotifyParamsSchema = z.object({\n app_id: z.string().min(1),\n seller_id: z.string().min(1),\n notify_id: z.string().min(1),\n notify_type: z.literal('trade_status_sync'),\n notify_time: AlipayTimeSchema,\n sign_type: z.enum(['RSA', 'RSA2']),\n sign: z.string().min(1),\n out_trade_no: z.string().min(1),\n trade_no: z.string().min(1),\n trade_status: z.enum(['WAIT_BUYER_PAY', 'TRADE_CLOSED', 'TRADE_SUCCESS', 'TRADE_FINISHED']),\n total_amount: AlipayAmountSchema,\n gmt_payment: AlipayTimeSchema.optional(),\n}).catchall(z.string()).refine(params => !['TRADE_SUCCESS', 'TRADE_FINISHED'].includes(params.trade_status) || !!params.gmt_payment)\n\n/**\n * 已通过结构校验的支付宝通知;身份与签名由 Provider 继续校验。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = AlipayNotifyParamsSchema.safeParse({\n * app_id: 'app-1', seller_id: 'seller-1', notify_id: 'notify-1',\n * notify_type: 'trade_status_sync', notify_time: '2026-10-22 08:00:00',\n * sign_type: 'RSA2', sign: 'signature-from-channel', out_trade_no: 'ORDER_1',\n * trade_no: 'ALI_1', trade_status: 'TRADE_SUCCESS', total_amount: '1.00',\n * gmt_payment: '2026-10-22 07:59:00',\n * })\n * if (!parsed.success) throw new Error('Invalid Alipay notification')\n * const notification: AlipayNotifyParams = parsed.data\n * const businessOrderNo = notification.out_trade_no\n * ```\n */\nexport type AlipayNotifyParams = z.infer<typeof AlipayNotifyParamsSchema>\n","/**\n * @h-ai/payment — 支付宝 Provider\n *\n * 实现 PaymentProvider 接口,对接支付宝 Open API。\n * @module payment-provider-alipay\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ZodType } from 'zod'\nimport type { AlipayConfig } from '../../payment-config.js'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from '../../payment-types.js'\nimport type { AlipayNotifyParams } from './payment-alipay-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { paymentM } from '../../payment-i18n.js'\nimport { HaiPaymentError } from '../../payment-types.js'\nimport { fetchWithTimeout } from '../payment-provider-http.js'\nimport { signAlipayParams, verifyAlipayNotify } from './payment-alipay-sign.js'\nimport { formatAlipayTime, parseAlipayTime } from './payment-alipay-time.js'\nimport { AlipayCloseResponseSchema, AlipayNotifyParamsSchema, AlipayQueryResponseSchema, AlipayRefundResponseSchema, AlipayResponseRootSchema, AlipayResponseSchema } from './payment-alipay-types.js'\n\n/** 支付宝网关地址 */\nconst ALIPAY_GATEWAY = 'https://openapi.alipay.com/gateway.do'\nconst ALIPAY_SANDBOX_GATEWAY = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do'\n\nfunction formatFenAmount(amount: number): string {\n const yuan = Math.floor(amount / 100)\n const cents = String(amount % 100).padStart(2, '0')\n return `${yuan}.${cents}`\n}\n\nfunction parseAlipayAmount(value: string): number {\n const trimmedValue = value.trim()\n if (!/^\\d+(?:\\.\\d{1,2})?$/.test(trimmedValue)) {\n throw new Error('Invalid Alipay amount')\n }\n\n const [yuanPart, centsPart = ''] = trimmedValue.split('.')\n const amount = Number.parseInt(yuanPart, 10) * 100 + Number.parseInt(centsPart.padEnd(2, '0'), 10)\n if (!Number.isSafeInteger(amount)) {\n throw new TypeError('Invalid Alipay amount')\n }\n return amount\n}\n\nfunction parseAlipayNotifyParams(body: string): AlipayNotifyParams {\n const params = new URLSearchParams(body)\n if (new Set(params.keys()).size !== [...params].length)\n throw new Error('Ambiguous Alipay notification parameters')\n const parseResult = AlipayNotifyParamsSchema.safeParse(Object.fromEntries(params.entries()))\n if (!parseResult.success) {\n throw new Error('Invalid Alipay notification parameters')\n }\n\n return parseResult.data\n}\n\n/**\n * 创建支付宝 Provider\n *\n * @param config - 支付宝配置\n * @returns PaymentProvider 实例\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function createFromTrustedConfig(config: AlipayConfig) {\n * // 配置已经由渠道 Schema 解析;真实密钥、商户身份与通知端点由部署提供。\n * const provider = createAlipayProvider(config)\n * const name = provider.name // 'alipay'\n * return provider\n * }\n * ```\n */\nexport function createAlipayProvider(config: AlipayConfig): PaymentProvider {\n const gateway = config.sandbox ? ALIPAY_SANDBOX_GATEWAY : ALIPAY_GATEWAY\n const signType = config.signType ?? 'RSA2'\n\n /**\n * 由受信商户配置构建公共参数,时间固定按 Asia/Shanghai,不依赖节点 TZ。\n * @param method - 当前操作对应的支付宝固定方法名。\n * @param notifyUrl - 服务端配置的通知端点;不从任意客户端字段直接信任。\n * @returns 尚未包含 sign/biz_content 的公共协议字段;签名后只能作为 POST 表单发送。\n * @example 模块内部上下文\n * ```ts\n * const params = buildCommonParams('alipay.trade.wap.pay', 'https://api.example.com/payment/notify/alipay')\n * const beijingTimestamp = params.timestamp\n * // 页面支付随后补 return_url/biz_content 并签名,不请求服务端 JSON envelope。\n * ```\n */\n function buildCommonParams(method: string, notifyUrl: string): Record<string, string> {\n return {\n app_id: config.appId,\n method,\n format: 'JSON',\n charset: 'utf-8',\n sign_type: signType,\n timestamp: formatAlipayTime(new Date()),\n version: '1.0',\n notify_url: notifyUrl,\n }\n }\n\n /**\n * 发送请求并核验对应方法的业务响应,再解析操作所需字段。\n *\n * HTTP 200 不代表业务成功;禁止把错误对象、原始响应或 Zod 输入放入 cause。\n * @param params - 已固定 method 和 biz_content 的未签名公共参数。\n * @param schema - 对应该方法所需字段的响应 Schema。\n * @returns HTTP、方法 envelope、10000 业务码与字段校验均通过的结果。\n * @throws 超时、网络、业务码或字段校验失败时抛错,由对应公共操作转为 HaiResult。\n * @example 模块内部上下文\n * ```ts\n * async function closeKnownOrder(orderNo: string) {\n * const params = {\n * ...buildCommonParams('alipay.trade.close', ''),\n * biz_content: JSON.stringify({ out_trade_no: orderNo }),\n * }\n * const response = await alipayRequest(params, AlipayCloseResponseSchema)\n * if (response.out_trade_no !== orderNo) throw new Error('Order identity mismatch')\n * return response\n * }\n * ```\n */\n async function alipayRequest<T>(params: Record<string, string>, schema: ZodType<T>): Promise<T> {\n const sign = signAlipayParams(params, config.privateKey, signType)\n const allParams = { ...params, sign }\n\n const timedResponse = await fetchWithTimeout(gateway, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams(allParams).toString(),\n })\n\n if (!timedResponse.ok) {\n throw new Error(`Alipay API failed: ${timedResponse.status}`)\n }\n\n let body: unknown\n try {\n body = await timedResponse.json()\n }\n catch {\n throw new Error('Invalid Alipay JSON response')\n }\n\n const root = AlipayResponseRootSchema.safeParse(body)\n const key = `${params.method.replace(/\\./g, '_')}_response`\n if (!root.success || 'error_response' in root.data) {\n throw new Error('Invalid Alipay response envelope')\n }\n\n const response = root.data[key]\n const common = AlipayResponseSchema.safeParse(response)\n if (!common.success) {\n throw new Error('Invalid Alipay response code')\n }\n if (common.data.code !== '10000') {\n // 仅保留有界的渠道错误标识;msg/sub_msg 可能含订单、买家信息,不得透传。\n const subCode = common.data.sub_code\n const suffix = subCode && /^[\\w.-]{1,80}$/.test(subCode) ? `, sub_code=${subCode}` : ''\n throw new Error(`Alipay business request failed (code=${common.data.code}${suffix})`)\n }\n\n const parsed = schema.safeParse(response)\n if (!parsed.success) {\n throw new Error('Invalid Alipay business response')\n }\n return parsed.data\n }\n\n return {\n name: 'alipay',\n\n async createOrder(input: CreateOrderInput): Promise<HaiResult<PaymentOrder>> {\n if (input.tradeType !== 'h5')\n return err(HaiPaymentError.UNSUPPORTED_TRADE_TYPE, paymentM('payment_unsupportedTradeType'))\n if (input.currency !== undefined && input.currency !== 'CNY')\n return err(HaiPaymentError.INVALID_INPUT, paymentM('payment_invalidCreateOrderInput'))\n try {\n // WAP 是页面支付 API:离线签名后由浏览器 POST,不能当作服务端 JSON 请求。\n const fields = {\n ...buildCommonParams('alipay.trade.wap.pay', input.notifyUrl),\n return_url: config.returnUrl,\n biz_content: JSON.stringify({\n out_trade_no: input.orderNo,\n total_amount: formatFenAmount(input.amount),\n subject: input.description,\n product_code: 'QUICK_WAP_WAY',\n passback_params: input.metadata ? encodeURIComponent(JSON.stringify(input.metadata)) : undefined,\n }),\n }\n return ok({\n provider: 'alipay',\n tradeType: 'h5',\n clientParams: {\n gateway,\n fields: { ...fields, sign: signAlipayParams(fields, config.privateKey, signType) },\n },\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.CREATE_ORDER_FAILED,\n paymentM('payment_createOrderFailed'),\n cause,\n )\n }\n },\n\n async handleNotify(request: PaymentNotifyRequest): Promise<HaiResult<PaymentNotifyResult>> {\n try {\n const params = parseAlipayNotifyParams(request.body)\n\n // 验签\n const valid = params.sign_type === signType && verifyAlipayNotify(params, config.alipayPublicKey)\n if (!valid) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n if (params.app_id !== config.appId || params.seller_id !== config.sellerId) {\n return err(HaiPaymentError.NOTIFY_VERIFY_FAILED, paymentM('payment_notifyVerifyFailed'))\n }\n // 允许渠道跨日重试;重放靠持久 eventId 和订单状态 CAS,不套用微信的五分钟窗口。\n const notifiedAt = parseAlipayTime(params.notify_time)!\n const paidAt = params.gmt_payment ? parseAlipayTime(params.gmt_payment) : undefined\n if (notifiedAt.getTime() > Date.now() + 300_000\n || (paidAt && paidAt.getTime() > notifiedAt.getTime() + 300_000)) {\n throw new Error('Invalid Alipay notification time')\n }\n\n const statusMap: Record<string, PaymentNotifyResult['status']> = {\n TRADE_SUCCESS: 'paid',\n TRADE_CLOSED: 'closed',\n TRADE_FINISHED: 'paid',\n WAIT_BUYER_PAY: 'pending',\n }\n\n return ok({\n orderNo: params.out_trade_no,\n transactionId: params.trade_no,\n eventId: params.notify_id,\n amount: parseAlipayAmount(params.total_amount),\n currency: 'CNY',\n status: statusMap[params.trade_status],\n paidAt: ['TRADE_SUCCESS', 'TRADE_FINISHED'].includes(params.trade_status) ? paidAt : undefined,\n raw: params,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.NOTIFY_PARSE_FAILED,\n paymentM('payment_notifyParseFailed'),\n cause,\n )\n }\n },\n\n async queryOrder(orderNo: string): Promise<HaiResult<OrderStatus>> {\n try {\n const method = 'alipay.trade.query'\n const params = {\n ...buildCommonParams(method, ''),\n biz_content: JSON.stringify({ out_trade_no: orderNo }),\n }\n\n const data = await alipayRequest(params, AlipayQueryResponseSchema)\n if (data.out_trade_no !== orderNo) {\n throw new Error('Alipay response order mismatch')\n }\n\n const statusMap: Record<string, OrderStatus['status']> = {\n TRADE_SUCCESS: 'paid',\n TRADE_CLOSED: 'closed',\n TRADE_FINISHED: 'paid',\n WAIT_BUYER_PAY: 'pending',\n }\n\n return ok({\n orderNo,\n transactionId: data.trade_no,\n status: statusMap[data.trade_status],\n amount: parseAlipayAmount(data.total_amount),\n // 支付宝时间为北京时间,不能依赖节点的本地时区解释。\n paidAt: data.send_pay_date ? parseAlipayTime(data.send_pay_date) : undefined,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.QUERY_ORDER_FAILED,\n paymentM('payment_queryOrderFailed'),\n cause,\n )\n }\n },\n\n async refund(input: RefundInput): Promise<HaiResult<RefundResult>> {\n try {\n const method = 'alipay.trade.refund'\n const params = {\n ...buildCommonParams(method, ''),\n biz_content: JSON.stringify({\n out_trade_no: input.orderNo,\n out_request_no: input.refundNo,\n refund_amount: formatFenAmount(input.amount),\n refund_reason: input.reason,\n }),\n }\n\n const data = await alipayRequest(params, AlipayRefundResponseSchema)\n if (data.out_trade_no !== input.orderNo) {\n throw new Error('Alipay response order mismatch')\n }\n // refund_fee 是累计退款额,只校验安全整数,不与本次退款额直接比较。\n parseAlipayAmount(data.refund_fee)\n\n return ok({\n refundNo: input.refundNo,\n refundId: data.trade_no,\n status: data.fund_change === 'Y' ? 'success' : 'processing',\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n cause,\n )\n }\n },\n\n async closeOrder(orderNo: string): Promise<HaiResult<void>> {\n try {\n const method = 'alipay.trade.close'\n const params = {\n ...buildCommonParams(method, ''),\n biz_content: JSON.stringify({ out_trade_no: orderNo }),\n }\n\n const data = await alipayRequest(params, AlipayCloseResponseSchema)\n if (data.out_trade_no !== orderNo) {\n throw new Error('Alipay response order mismatch')\n }\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiPaymentError.CLOSE_ORDER_FAILED,\n paymentM('payment_closeOrderFailed'),\n cause,\n )\n }\n },\n }\n}\n","/** 各渠道通知共用的 HTTP header 读取规则。 */\n\n/**\n * 按大小写不敏感读取唯一协议头;重复大小写变体视作有歧义。\n * @param headers - 接入层保留的 HTTP headers\n * @param name - 目标名称\n * @returns 唯一字段值;缺失或重复时为 undefined\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const timestamp = getNotifyHeader({ 'Wechatpay-Timestamp': '1792627200' }, 'wechatpay-timestamp')\n * const ambiguous = getNotifyHeader({ Signature: 'first', signature: 'second' }, 'signature')\n * // timestamp 为唯一匹配值;ambiguous 为 undefined,不任选一个冲突头。\n * ```\n */\nexport function getNotifyHeader(headers: Record<string, string>, name: string): string | undefined {\n const values = Object.entries(headers).filter(([key]) => key.toLowerCase() === name.toLowerCase())\n return values.length === 1 ? values[0][1] : undefined\n}\n","/** Stripe 操作的持久预留、结果和支付渠道标识;不是业务订单仓库。 */\nimport type { HaiResult } from '@h-ai/core'\nimport type { ReldbFunctions } from '@h-ai/reldb'\n\nconst STRIPE_OPERATION_TABLE = 'hai_payment_stripe_operations'\n/** 比 Stripe API v1 最短 24 小时保留期留出一小时安全余量。 */\nconst SAFE_RETRY_SECONDS = 23 * 60 * 60\n\n/**\n * 数据库中的幂等操作记录。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function mayRetryUnknown(record: StripeOperationRecord): boolean {\n * return record.result === null && record.canRetry\n * // result=null 是结果未知,不能据此创建新幂等键;超窗必须人工核对渠道。\n * }\n * ```\n */\nexport interface StripeOperationRecord {\n /** 首次预留的规范请求摘要,后续重试不得改变参数。 */\n requestHash: string\n /** 成功持久化的渠道结果;null 表示尚未确认,不能等同于未执行。 */\n result: unknown | null\n /** Checkout Session 对应的 PaymentIntent,查单时可原子补全。 */\n paymentIntent: string | null\n /** 由共享数据库时间计算的安全重试窗口。 */\n canRetry: boolean\n}\n\n/**\n * SQL 读取结果;驱动可能将 JSON 返回对象或字符串。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const row: StripeOperationRow = {\n * request_hash: 'canonical-request-digest', result_json: null,\n * payment_intent: null, can_retry: 1,\n * }\n * const retryWindowOpen = row.can_retry === true || row.can_retry === 1 || row.can_retry === '1'\n * ```\n */\ninterface StripeOperationRow {\n request_hash: string\n result_json: unknown | null\n payment_intent: string | null\n can_retry: number | string | boolean\n}\n\n/**\n * Stripe 幂等操作仓库,使用数据库主键预留和条件更新协调节点。\n *\n * @remarks 内部 helper 可抛错,最近的 Provider 边界负责转换为 HaiResult。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function initializeOperations(db: ReldbFunctions) {\n * const repository = new StripeOperationRepository(db)\n * const initialized = await repository.initialize()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * const operation = await repository.reserve('stable-account-mode-order-digest', 'canonical-request-digest')\n * // 未确认结果保留预留;只能沿用原幂等键,不删除记录后盲重试。\n * return { repository, operation }\n * }\n * ```\n */\nexport class StripeOperationRepository {\n constructor(private readonly db: ReldbFunctions) {}\n\n /** 建表成功后才能发布 Provider;失败由 payment.init 返回。 */\n async initialize(): Promise<HaiResult<void>> {\n return this.db.ddl.createTable(STRIPE_OPERATION_TABLE, {\n id: { type: 'TEXT', primaryKey: true },\n request_hash: { type: 'TEXT', notNull: true },\n result_json: { type: 'JSON' },\n payment_intent: { type: 'TEXT' },\n created_at: { type: 'BIGINT', notNull: true },\n }, true)\n }\n\n /** 数据库时间避免不同应用节点的系统时钟影响安全重试窗口。 */\n private nowSql(): string {\n switch (this.db.config?.type) {\n case 'sqlite': return 'CAST(strftime(\\'%s\\', \\'now\\') AS INTEGER)'\n case 'postgresql': return 'CAST(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) AS BIGINT)'\n case 'mysql': return 'UNIX_TIMESTAMP()'\n default: throw new Error('Stripe operation repository requires an initialized database')\n }\n }\n\n /**\n * 读取持久操作记录,以共享数据库时间计算安全重试窗口,不根据渠道 metadata 列表猜订单。\n * @param id - 按账户、模式、操作类型和业务标识生成的稳定摘要 ID。\n * @returns 已保留的记录;无记录时为 null,result 为 null 仅代表结果未知。\n * @throws 查询失败或持久结果 JSON 非法时抛错,由最近的 Provider 边界转为 HaiResult。\n * @example 模块内部上下文\n * ```ts\n * async function lookup(repository: StripeOperationRepository, operationId: string) {\n * const record = await repository.load(operationId)\n * if (record?.result === null && !record.canRetry) {\n * throw new Error('Reconcile the channel outcome before retrying')\n * }\n * return record\n * }\n * ```\n */\n async load(id: string): Promise<StripeOperationRecord | null> {\n const result = await this.db.sql.get<StripeOperationRow>(\n `SELECT request_hash, result_json, payment_intent,\n CASE WHEN created_at > (${this.nowSql()} - ${SAFE_RETRY_SECONDS}) THEN 1 ELSE 0 END AS can_retry\n FROM ${STRIPE_OPERATION_TABLE} WHERE id = ?`,\n [id],\n )\n if (!result.success)\n throw new Error('Failed to load Stripe operation', { cause: result.error })\n if (!result.data)\n return null\n const row = result.data\n return {\n requestHash: row.request_hash,\n result: typeof row.result_json === 'string' ? JSON.parse(row.result_json) : row.result_json,\n paymentIntent: row.payment_intent,\n canRetry: row.can_retry === true || row.can_retry === 1 || row.can_retry === '1',\n }\n }\n\n /**\n * 通过主键插入原子预留;并发节点只接受相同请求摘要,不覆盖已有参数或删除未知操作。\n * @param id - 所有节点复用的稳定操作 ID,也是渠道幂等键。\n * @param requestHash - 路径和排序后表单参数的规范摘要。\n * @returns 数据库中唯一的操作记录;已有 result 必须复用而非重新请求渠道。\n * @throws 预留/读取失败或同标识复用不同参数时抛错,由 Provider 转为操作失败。\n * @example 模块内部上下文\n * ```ts\n * async function reserveOnce(repository: StripeOperationRepository, id: string, requestHash: string) {\n * const record = await repository.reserve(id, requestHash)\n * // result=null 可能是渠道执行后回执丢失;重试仍须原 id 且 canRetry=true。\n * if (record.result === null && !record.canRetry) throw new Error('Channel reconciliation required')\n * return record\n * }\n * ```\n */\n async reserve(id: string, requestHash: string): Promise<StripeOperationRecord> {\n let record = await this.load(id)\n if (!record) {\n const inserted = await this.db.sql.execute(\n `INSERT INTO ${STRIPE_OPERATION_TABLE} (id, request_hash, created_at) VALUES (?, ?, ${this.nowSql()})`,\n [id, requestHash],\n )\n record = await this.load(id)\n if (!record)\n throw new Error('Failed to reserve Stripe operation', { cause: inserted.success ? undefined : inserted.error })\n }\n if (record.requestHash !== requestHash)\n throw new Error('Stripe operation identifier was reused with different parameters')\n return record\n }\n\n /**\n * 以请求摘要和未完成状态作 CAS 发布渠道结果,再读取已持久化的唯一结果。\n * @param id - 已成功预留的稳定操作 ID。\n * @param requestHash - 与预留完全一致的规范请求摘要。\n * @param result - 已经由渠道结果 Schema 校验、允许持久化的最小结果。\n * @param paymentIntent - 已核对身份的 PaymentIntent;创建时尚未知可省略。\n * @returns 数据库确认的结果,可能由并发完成者先写入;调用者须再按结果 Schema 解析。\n * @throws 更新、重读或持久状态核对失败时抛错;不将未知状态伪装为成功。\n * @example 模块内部上下文\n * ```ts\n * async function persistConfirmed(repository: StripeOperationRepository, id: string, digest: string, confirmedMapping: unknown) {\n * // 调用前渠道响应已校验;digest 来自首次预留,不能以新参数覆盖旧操作。\n * return repository.complete(id, digest, confirmedMapping)\n * }\n * ```\n */\n async complete(id: string, requestHash: string, result: unknown, paymentIntent?: string | null): Promise<unknown> {\n const updated = await this.db.sql.execute(\n `UPDATE ${STRIPE_OPERATION_TABLE} SET result_json = ?, payment_intent = ?\n WHERE id = ? AND request_hash = ? AND result_json IS NULL`,\n [JSON.stringify(result), paymentIntent ?? null, id, requestHash],\n )\n if (!updated.success)\n throw new Error('Failed to persist Stripe operation result', { cause: updated.error })\n const persisted = await this.load(id)\n if (!persisted || persisted.requestHash !== requestHash || persisted.result === null)\n throw new Error('Stripe operation result was not persisted')\n return persisted.result\n }\n\n /**\n * 只在订单映射已完成时首次补全或幂等确认同一 PaymentIntent,禁止迟到写覆盖渠道身份。\n * @param id - 已确认 Checkout Session 映射的订单操作 ID。\n * @param paymentIntent - 从该 Session 读取且通过订单/金额/币种核对的渠道标识。\n * @throws 写入失败、订单未完成或已绑定不同 PaymentIntent 时抛错,由 Provider 转为失败。\n * @example 模块内部上下文\n * ```ts\n * async function bindVerifiedIntent(repository: StripeOperationRepository, orderOperationId: string, verifiedIntentId: string) {\n * await repository.rememberPaymentIntent(orderOperationId, verifiedIntentId)\n * // 仅确认渠道身份映射,不代表宿主业务已履约。\n * }\n * ```\n */\n async rememberPaymentIntent(id: string, paymentIntent: string): Promise<void> {\n const result = await this.db.sql.execute(\n `UPDATE ${STRIPE_OPERATION_TABLE} SET payment_intent = ?\n WHERE id = ? AND result_json IS NOT NULL AND (payment_intent IS NULL OR payment_intent = ?)`,\n [paymentIntent, id, paymentIntent],\n )\n if (!result.success)\n throw new Error('Failed to persist Stripe PaymentIntent', { cause: result.error })\n const record = await this.load(id)\n if (!record || record.paymentIntent !== paymentIntent)\n throw new Error('Stripe PaymentIntent conflicts with the persisted mapping')\n }\n}\n","/**\n * @h-ai/payment — Stripe Provider\n *\n * 实现 PaymentProvider 接口,对接 Stripe API。\n * 使用 Stripe Checkout Session 模式。\n * @module payment-provider-stripe\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { StripeConfig } from '../../payment-config.js'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from '../../payment-types.js'\nimport { createHash, createHmac } from 'node:crypto'\nimport { core, err, ok } from '@h-ai/core'\nimport { reldb } from '@h-ai/reldb'\nimport { z } from 'zod'\nimport { paymentM } from '../../payment-i18n.js'\nimport { HaiPaymentError } from '../../payment-types.js'\nimport { fetchWithTimeout } from '../payment-provider-http.js'\nimport { getNotifyHeader } from '../payment-provider-notify.js'\nimport { StripeOperationRepository } from './payment-stripe-repository-operation.js'\n\n/** Stripe API 基地址 */\nconst STRIPE_API_BASE = 'https://api.stripe.com/v1'\n/** 与已核验的 hosted_page 参数契约一致,避免账户默认 API 版本改变协议。 */\nconst STRIPE_API_VERSION = '2026-09-30.endive'\n\n/** 只持久化继续查单所需的渠道标识和返回给客户端的 Checkout URL。 */\nconst StripeCreatedSessionSchema = z.object({\n id: z.string().min(1),\n url: z.url(),\n payment_intent: z.string().min(1).nullable().optional(),\n})\n\n/** 订单号与首次请求金额/币种绑定;不保存密钥和完整渠道响应。 */\nconst StripeOrderMappingSchema = z.object({\n orderNo: z.string().min(1),\n amount: z.number().int().positive(),\n currency: z.string().regex(/^[A-Z]{3}$/),\n session: StripeCreatedSessionSchema,\n})\n\n/** Session 查询只接受实际有意义的支付状态,并核对其业务身份。 */\nconst StripeRetrievedSessionSchema = z.object({\n id: z.string().min(1),\n metadata: z.object({ orderNo: z.string().min(1) }),\n amount_total: z.number().int().nonnegative(),\n currency: z.string().regex(/^[a-z]{3}$/i),\n payment_status: z.enum(['paid', 'unpaid', 'no_payment_required']),\n payment_intent: z.string().min(1).nullable(),\n status: z.enum(['open', 'complete', 'expired']),\n})\n\n/** 退款受理结果;渠道错误或未知状态不能映射为假成功。 */\nconst StripeRefundSchema = z.object({\n id: z.string().min(1),\n status: z.enum(['pending', 'requires_action', 'succeeded', 'failed', 'canceled']),\n})\n\n/**\n * Stripe Checkout 通知快照;只接受本 Provider 实际消费的 Session 事件。\n *\n * 保留原始扩展字段用于业务核对;不同资源类型不可套用 Session 金额字段。\n */\nconst StripeCheckoutEventSchema = z.object({\n id: z.string().min(1),\n livemode: z.boolean(),\n // 本 Provider 只支持当前账户,不能消费 Connect/组织上下文的其它商户事件。\n account: z.never().optional(),\n context: z.never().optional(),\n created: z.number().int().nonnegative().max(8_640_000_000_000),\n type: z.enum([\n 'checkout.session.completed',\n 'checkout.session.async_payment_succeeded',\n 'checkout.session.async_payment_failed',\n 'checkout.session.expired',\n ]),\n data: z.object({\n object: z.object({\n object: z.literal('checkout.session'),\n id: z.string().min(1),\n mode: z.literal('payment'),\n metadata: z.object({ orderNo: z.string().min(1).regex(/\\S/) }).passthrough(),\n amount_total: z.number().int().nonnegative(),\n currency: z.string().regex(/^[a-z]{3}$/i),\n payment_status: z.enum(['paid', 'unpaid', 'no_payment_required']),\n }).passthrough(),\n }).passthrough(),\n}).passthrough().refine((event) => {\n const paid = event.data.object.payment_status !== 'unpaid'\n if (event.type === 'checkout.session.async_payment_succeeded')\n return paid\n if (event.type === 'checkout.session.async_payment_failed' || event.type === 'checkout.session.expired')\n return !paid\n return true\n}, { message: 'Checkout event type contradicts payment status' })\n\n/**\n * 创建 Stripe Provider\n *\n * @param config - Stripe 配置\n * @param repository - 已初始化的内部渠道操作仓库,由 payment.init 创建。\n * @returns PaymentProvider 实例\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function createFromTrustedConfig(config: StripeConfig) {\n * // reldb 已初始化为共享数据库;先等待持久操作表就绪再发布 Provider。\n * const repository = new StripeOperationRepository(reldb)\n * const initialized = await repository.initialize()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * return createStripeProvider(config, repository)\n * }\n * ```\n */\nexport function createStripeProvider(\n config: StripeConfig,\n repository = new StripeOperationRepository(reldb),\n): PaymentProvider {\n let accountScopePromise: Promise<string> | undefined\n\n /** Stripe API 请求 */\n async function stripeRequest<T>(method: string, path: string, options?: {\n body?: Record<string, string>\n idempotencyKey?: string\n }): Promise<T> {\n const response = await fetchWithTimeout(`${STRIPE_API_BASE}${path}`, {\n method,\n headers: {\n 'Authorization': `Bearer ${config.secretKey}`,\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'Stripe-Version': STRIPE_API_VERSION,\n ...(options?.idempotencyKey ? { 'Idempotency-Key': options.idempotencyKey } : {}),\n },\n body: options?.body\n ? Object.entries(options.body).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&')\n : undefined,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(`Stripe API ${method} ${path} failed: ${response.status} ${errorText}`)\n }\n\n return response.json() as T\n }\n\n /** 稳定账户身份与 test/live 隔离;密钥轮换不会改变持久映射命名空间。 */\n async function accountScope(): Promise<string> {\n if (!accountScopePromise) {\n accountScopePromise = (async () => {\n const mode = /^(?:sk|rk)_(test|live)_/.exec(config.secretKey)?.[1]\n if (!mode)\n throw new Error('Stripe requires a test or live secret/restricted API key')\n const account = z.object({ id: z.string().regex(/^acct_/).min(6) }).parse(await stripeRequest('GET', '/account'))\n return `${account.id}:${mode}`\n })().catch((error: unknown) => {\n accountScopePromise = undefined\n throw error\n })\n }\n return accountScopePromise\n }\n\n /**\n * 按账户、test/live 模式、操作类型和业务标识生成所有节点一致的幂等键。\n * 输出仅包含摘要,不携带明文密钥或业务标识;账户读取失败必须传播,不能临时换键。\n * @param kind - 创建订单、退款或主动关单的操作类型。\n * @param businessId - 持久化的 orderNo 或 refundNo;同一业务操作重试必须保持不变。\n * @returns 适合 Stripe Idempotency-Key 的稳定摘要字符串。\n * @example 模块内部上下文\n * ```ts\n * const first = await operationId('refund', 'REFUND_1')\n * const retry = await operationId('refund', 'REFUND_1')\n * if (first !== retry) throw new Error('Idempotency identity changed')\n * ```\n */\n async function operationId(kind: 'order' | 'refund' | 'close', businessId: string): Promise<string> {\n const digest = createHash('sha256').update(JSON.stringify([await accountScope(), kind, businessId])).digest('hex')\n return `hai-payment-${kind}-${digest}`\n }\n\n /**\n * 规范化参数并绑定数据库预留;仅对安全窗口内的未知结果沿用同一渠道幂等键请求。\n * 已持久化结果先经结果 Schema 解析后复用;渠道回执或数据库确认缺失时保留预留并失败。\n * @param options - 稳定 ID、固定渠道路径、表单参数及最小结果解析器。\n * @param options.id - 已包含账户、模式与业务标识的稳定操作 ID,复用作渠道幂等键。\n * @param options.path - 当前操作使用的固定 Stripe API 路径。\n * @param options.body - 与首次预留参数一致的渠道表单字段。\n * @param options.resultSchema - 持久化和返回值复用时都必须通过的最小结果 Schema。\n * @param options.execute - 将渠道原始响应转换为经过校验的最小结果,不承担外部履约。\n * @param options.paymentIntent - 从已校验结果提取 PaymentIntent 的可选函数。\n * @returns 经 Schema 校验并由数据库确认的单次操作结果。\n * @throws 参数冲突、过窗未知结果、渠道错误或持久化失败时抛错,由公共操作边界转换。\n * @example 模块内部上下文\n * ```ts\n * async function repeatKnownRefund(refundNo: string, body: Record<string, string>) {\n * return executeOperation({\n * id: await operationId('refund', refundNo), path: '/refunds', body,\n * resultSchema: StripeRefundSchema, execute: raw => StripeRefundSchema.parse(raw),\n * })\n * // body 必须与首次预留完全一致;不能借重试更改金额或 PaymentIntent。\n * }\n * ```\n */\n async function executeOperation<T>(options: {\n id: string\n path: string\n body: Record<string, string>\n resultSchema: z.ZodType<T>\n execute: (raw: unknown) => T\n paymentIntent?: (result: T) => string | null | undefined\n }): Promise<T> {\n const requestHash = createHash('sha256').update(JSON.stringify([\n options.path,\n Object.entries(options.body).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0),\n ])).digest('hex')\n const reserved = await repository.reserve(options.id, requestHash)\n if (reserved.result !== null)\n return options.resultSchema.parse(reserved.result)\n if (!reserved.canRetry)\n throw new Error('Stripe operation outcome is unknown beyond the safe retry window; reconcile before retrying')\n const result = options.execute(await stripeRequest('POST', options.path, { body: options.body, idempotencyKey: options.id }))\n return options.resultSchema.parse(await repository.complete(options.id, requestHash, result, options.paymentIntent?.(result)))\n }\n\n /**\n * 只按持久化 Session ID 查指定订单,核对订单号、金额、币种后原子补全 PaymentIntent。\n * @param orderNo - 由业务持久化、并已经创建过渠道映射的商户订单号。\n * @returns 与本账户/模式/订单映射一致的 Session;不会搜索 metadata 列表猜测订单。\n * @throws 无确认映射、渠道失败、字段非法或身份不一致时抛错,由操作边界转为失败。\n * @example 模块内部上下文\n * ```ts\n * const session = await retrieveOrder('ORDER_1')\n * const canExpire = session.status === 'open' && session.payment_status === 'unpaid'\n * // 只有渠道 expire 后再次确认 expired,才能把关单作为成功结果。\n * ```\n */\n async function retrieveOrder(orderNo: string) {\n const id = await operationId('order', orderNo)\n const operation = await repository.load(id)\n if (!operation || operation.result === null)\n throw new Error('Stripe order has no confirmed persisted Session mapping')\n const mapping = StripeOrderMappingSchema.parse(operation.result)\n const session = StripeRetrievedSessionSchema.parse(await stripeRequest('GET', `/checkout/sessions/${encodeURIComponent(mapping.session.id)}`))\n if (session.id !== mapping.session.id || session.metadata.orderNo !== orderNo\n || mapping.orderNo !== orderNo || session.amount_total !== mapping.amount\n || session.currency.toUpperCase() !== mapping.currency) {\n throw new Error('Stripe Session does not match the persisted order')\n }\n if (session.payment_intent)\n await repository.rememberPaymentIntent(id, session.payment_intent)\n return session\n }\n\n /** Stripe Webhook 签名容忍时间窗口(秒) */\n const TIMESTAMP_TOLERANCE = config.webhookToleranceSeconds ?? 300\n\n /**\n * 对原始通知 body 校验唯一时间戳、时间容差及任一有效 v1 签名,支持受信密钥轮换。\n * @param payload - 未重序列化的原始请求体。\n * @param signature - 唯一 Stripe-Signature 头值;重复头由外层拒绝。\n * @returns 签名和时钟同时可信时为 true;不代替 Session 事件、商户身份或持久业务去重。\n * @example 模块内部上下文\n * ```ts\n * function verifyRawBody(body: string, signatureHeader: string): boolean {\n * return verifyWebhookSignature(body, signatureHeader)\n * }\n * ```\n */\n function verifyWebhookSignature(payload: string, signature: string): boolean {\n const parts = signature.split(',').map(part => part.trim())\n const timestamps = parts.filter(p => p.startsWith('t='))\n if (timestamps.length !== 1)\n return false\n const timestamp = timestamps[0].slice(2)\n const signatures = parts.filter(p => p.startsWith('v1=')).map(p => p.slice(3))\n\n // 时间戳重放保护\n const ts = Number(timestamp)\n if (!/^(?:0|[1-9]\\d{0,11})$/.test(timestamp) || !Number.isSafeInteger(ts)\n || Math.abs(Math.floor(Date.now() / 1000) - ts) > TIMESTAMP_TOLERANCE) {\n return false\n }\n\n const signedPayload = `${timestamp}.${payload}`\n const expected = createHmac('sha256', config.webhookSecret)\n .update(signedPayload)\n .digest('hex')\n\n try {\n // Stripe 密钥轮换期间允许同一报文包含多个 v1 签名。\n return signatures.some(v1 => /^[a-f0-9]{64}$/.test(v1) && core.string.constantTimeEqual(v1, expected))\n }\n catch {\n return false\n }\n }\n\n return {\n name: 'stripe',\n\n async createOrder(input: CreateOrderInput): Promise<HaiResult<PaymentOrder>> {\n if (input.tradeType !== 'h5')\n return err(HaiPaymentError.UNSUPPORTED_TRADE_TYPE, paymentM('payment_unsupportedTradeType'))\n try {\n z.string().min(1).regex(/\\S/).parse(input.orderNo)\n if (input.metadata && Object.hasOwn(input.metadata, 'orderNo'))\n throw new Error('Stripe metadata orderNo is reserved')\n // 使用 Stripe Checkout Session\n const params: Record<string, string> = {\n 'mode': 'payment',\n 'ui_mode': 'hosted_page',\n 'success_url': config.successUrl,\n 'line_items[0][price_data][currency]': input.currency?.toLowerCase() ?? 'usd',\n 'line_items[0][price_data][product_data][name]': input.description,\n 'line_items[0][price_data][unit_amount]': input.amount.toString(),\n 'line_items[0][quantity]': '1',\n }\n if (config.cancelUrl)\n params.cancel_url = config.cancelUrl\n\n // metadata 传递订单号\n params['metadata[orderNo]'] = input.orderNo\n if (input.metadata) {\n for (const [k, v] of Object.entries(input.metadata)) {\n params[`metadata[${k}]`] = v\n }\n }\n\n const mapping = await executeOperation({\n id: await operationId('order', input.orderNo),\n path: '/checkout/sessions',\n body: params,\n resultSchema: StripeOrderMappingSchema,\n execute: raw => ({\n orderNo: input.orderNo,\n amount: input.amount,\n currency: input.currency?.toUpperCase() ?? 'USD',\n session: StripeCreatedSessionSchema.parse(raw),\n }),\n paymentIntent: result => result.session.payment_intent,\n })\n\n return ok({\n provider: 'stripe',\n tradeType: input.tradeType,\n clientParams: {\n sessionId: mapping.session.id,\n checkoutUrl: mapping.session.url,\n },\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.CREATE_ORDER_FAILED,\n paymentM('payment_createOrderFailed'),\n cause,\n )\n }\n },\n\n async handleNotify(request: PaymentNotifyRequest): Promise<HaiResult<PaymentNotifyResult>> {\n try {\n const signature = getNotifyHeader(request.headers, 'stripe-signature') ?? ''\n\n // 验签\n const valid = verifyWebhookSignature(request.body, signature)\n if (!valid) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n\n const parsed = StripeCheckoutEventSchema.safeParse(JSON.parse(request.body))\n if (!parsed.success)\n throw new Error('Invalid Stripe payment event')\n const event = parsed.data\n if (event.livemode !== /^(?:sk|rk)_live_/.test(config.secretKey)\n || event.created > Math.floor(Date.now() / 1000) + TIMESTAMP_TOLERANCE) {\n return err(HaiPaymentError.NOTIFY_VERIFY_FAILED, paymentM('payment_notifyVerifyFailed'))\n }\n const obj = event.data.object\n // completed 只表示 Checkout 已完成;延迟付款仍可能处于 unpaid。\n const status: PaymentNotifyResult['status'] = event.type === 'checkout.session.expired'\n ? 'closed'\n : event.type === 'checkout.session.async_payment_failed'\n ? 'failed'\n : obj.payment_status === 'unpaid' ? 'pending' : 'paid'\n\n return ok({\n orderNo: obj.metadata.orderNo,\n transactionId: obj.id,\n eventId: event.id,\n amount: obj.amount_total,\n currency: obj.currency.toUpperCase(),\n status,\n // 使用支付成功事件的时间,使重复通知不会改变 paidAt;pending/failed/closed 不宣称已支付。\n paidAt: status === 'paid' ? new Date(event.created * 1000) : undefined,\n raw: event,\n })\n }\n catch {\n return err(\n HaiPaymentError.NOTIFY_PARSE_FAILED,\n paymentM('payment_notifyParseFailed'),\n new Error('Invalid Stripe payment notification'),\n )\n }\n },\n\n async queryOrder(orderNo: string): Promise<HaiResult<OrderStatus>> {\n try {\n const session = await retrieveOrder(orderNo)\n\n const statusMap: Record<string, OrderStatus['status']> = {\n paid: 'paid',\n unpaid: 'pending',\n no_payment_required: 'paid',\n }\n\n return ok({\n orderNo,\n transactionId: session.id,\n status: session.status === 'expired' ? 'closed' : statusMap[session.payment_status],\n amount: session.amount_total,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.QUERY_ORDER_FAILED,\n paymentM('payment_queryOrderFailed'),\n cause,\n )\n }\n },\n\n async refund(input: RefundInput): Promise<HaiResult<RefundResult>> {\n try {\n z.string().min(1).regex(/\\S/).parse(input.refundNo)\n const session = await retrieveOrder(input.orderNo)\n if (!session.payment_intent || session.payment_status !== 'paid') {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n )\n }\n\n const body: Record<string, string> = {\n 'payment_intent': session.payment_intent,\n 'amount': input.amount.toString(),\n 'reason': 'requested_by_customer',\n 'metadata[orderNo]': input.orderNo,\n 'metadata[refundNo]': input.refundNo,\n }\n if (input.reason)\n body['metadata[reason]'] = input.reason\n const refund = await executeOperation({\n id: await operationId('refund', input.refundNo),\n path: '/refunds',\n body,\n resultSchema: StripeRefundSchema,\n execute: raw => StripeRefundSchema.parse(raw),\n })\n\n return ok({\n refundNo: input.refundNo,\n refundId: refund.id,\n status: refund.status === 'succeeded' ? 'success' : refund.status === 'failed' || refund.status === 'canceled' ? 'failed' : 'processing',\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n cause,\n )\n }\n },\n\n async closeOrder(orderNo: string): Promise<HaiResult<void>> {\n try {\n const session = await retrieveOrder(orderNo)\n if (session.payment_status !== 'unpaid' || session.status === 'complete')\n throw new Error('A completed or paid Stripe Session cannot be closed')\n if (session.status === 'expired')\n return ok(undefined)\n\n try {\n const expired = z.object({ id: z.string(), status: z.literal('expired') }).parse(\n await stripeRequest('POST', `/checkout/sessions/${encodeURIComponent(session.id)}/expire`, {\n body: {},\n idempotencyKey: await operationId('close', orderNo),\n }),\n )\n if (expired.id !== session.id)\n throw new Error('Stripe expiration response does not match the requested Session')\n }\n catch (cause) {\n // 其它节点已关单或响应丢失时,仅在重新读取并确认 expired 后返回幂等成功。\n const confirmed = await retrieveOrder(orderNo)\n if (confirmed.status !== 'expired' || confirmed.payment_status !== 'unpaid')\n throw cause\n }\n return ok(undefined)\n }\n catch (cause) {\n return err(HaiPaymentError.CLOSE_ORDER_FAILED, paymentM('payment_closeOrderFailed'), cause)\n }\n },\n }\n}\n","/**\n * @h-ai/payment — 微信支付签名\n *\n * 微信支付 API v3 签名生成与验签工具。\n * @module payment-wechat-sign\n */\n\nimport { Buffer } from 'node:buffer'\nimport { createDecipheriv, createSign, createVerify, randomBytes } from 'node:crypto'\n\n/**\n * 生成随机字符串\n *\n * @param length - 字符串长度(默认 32)\n * @returns 由 Node Crypto 随机字节生成的指定长度十六进制字符串。\n * @throws 随机数源不可用或 length 非法时抛错,由 Provider 操作边界处理。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const nonce = generateNonce(32)\n * const validShape = /^[0-9a-f]{32}$/.test(nonce)\n * ```\n */\nexport function generateNonce(length = 32): string {\n return randomBytes(length).toString('hex').slice(0, length)\n}\n\n/**\n * 获取当前时间戳(秒)\n * @returns 当前 Unix 时间的整秒十进制字符串;验签时间容差在 Provider 处理。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const timestamp = getTimestamp()\n * const unixSeconds = Number(timestamp) // 秒,不是 Date.now() 的毫秒。\n * ```\n */\nexport function getTimestamp(): string {\n return Math.floor(Date.now() / 1000).toString()\n}\n\n/**\n * 微信 API v3 请求签名\n *\n * @param method - HTTP 方法\n * @param url - 请求路径(不含域名)\n * @param timestamp - 时间戳\n * @param nonce - 随机串\n * @param body - 请求体(空则为空字符串)\n * @param privateKey - 商户私钥 PEM\n * @returns SHA256-RSA2048 签名(Base64)\n * @throws 私钥格式不合法或 Crypto 签名失败时抛错,由 Provider 转为 HaiResult。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function signTrustedRequest(privateKeyPem: string, body: string): string {\n * return signRequest('POST', '/v3/pay/transactions/jsapi', getTimestamp(), generateNonce(), body, privateKeyPem)\n * // HTTP 必须发送完全相同的路径和原始 body,不能签名后再改变序列化结果。\n * }\n * ```\n */\nexport function signRequest(\n method: string,\n url: string,\n timestamp: string,\n nonce: string,\n body: string,\n privateKey: string,\n): string {\n const message = `${method}\\n${url}\\n${timestamp}\\n${nonce}\\n${body}\\n`\n const sign = createSign('RSA-SHA256')\n sign.update(message)\n return sign.sign(privateKey, 'base64')\n}\n\n/**\n * 微信 JSAPI 支付签名\n *\n * @param appId - 应用 ID\n * @param timestamp - 时间戳\n * @param nonce - 随机串\n * @param prepayId - 预支付 ID\n * @param privateKey - 商户私钥 PEM\n * @returns 签名\n * @throws 私钥格式不合法或 Crypto 签名失败时抛错,由 Provider 转为 HaiResult。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function signClientInvocation(privateKeyPem: string, appId: string, prepayId: string) {\n * const timeStamp = getTimestamp()\n * const nonceStr = generateNonce()\n * const paySign = signJsapi(appId, timeStamp, nonceStr, prepayId, privateKeyPem)\n * return { appId, timeStamp, nonceStr, package: 'prepay_id=' + prepayId, signType: 'RSA', paySign }\n * }\n * ```\n */\nexport function signJsapi(\n appId: string,\n timestamp: string,\n nonce: string,\n prepayId: string,\n privateKey: string,\n): string {\n const message = `${appId}\\n${timestamp}\\n${nonce}\\nprepay_id=${prepayId}\\n`\n const sign = createSign('RSA-SHA256')\n sign.update(message)\n return sign.sign(privateKey, 'base64')\n}\n\n/**\n * 验证微信支付回调签名\n *\n * @param timestamp - 回调 header 中的时间戳\n * @param nonce - 回调 header 中的随机串\n * @param body - 回调原始 body\n * @param signature - 回调签名\n * @param platformKey - 已按 serial 选择的微信支付平台证书或公钥 PEM\n * @returns 是否验签通过\n * @throws 公钥格式非法或 Crypto 验签异常时抛错,由通知 Provider 边界转为失败。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function verifyRawNotification(timestamp: string, nonce: string, body: string, signature: string, trustedPlatformPem: string) {\n * return verifyNotifySignature(timestamp, nonce, body, signature, trustedPlatformPem)\n * // 调用前已按 Wechatpay-Serial 选定受信平台密钥;该 helper 不做时间、身份或业务去重校验。\n * }\n * ```\n */\nexport function verifyNotifySignature(\n timestamp: string,\n nonce: string,\n body: string,\n signature: string,\n platformKey: string,\n): boolean {\n const message = `${timestamp}\\n${nonce}\\n${body}\\n`\n const verify = createVerify('RSA-SHA256')\n verify.update(message)\n return verify.verify(platformKey, signature, 'base64')\n}\n\n/**\n * AES-256-GCM 解密(微信支付回调资源解密)\n *\n * @param ciphertext - 密文(Base64)\n * @param nonce - 随机串\n * @param associatedData - 附加数据\n * @param apiV3Key - API v3 密钥\n * @returns 解密后的 JSON 字符串\n * @throws 密钥、nonce、GCM 标签或密文非法时抛错;认证失败不返回明文,由 Provider 转为失败。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function decryptVerifiedResource(ciphertext: string, nonce: string, associatedData: string, apiV3Key: string): unknown {\n * // 外层通知签名已通过;密钥来自受信商户配置,后续仍须 Schema/商户身份/金额校验。\n * const plaintext = decryptResource(ciphertext, nonce, associatedData, apiV3Key)\n * const resource: unknown = JSON.parse(plaintext)\n * return resource\n * }\n * ```\n */\nexport function decryptResource(\n ciphertext: string,\n nonce: string,\n associatedData: string,\n apiV3Key: string,\n): string {\n const buf = Buffer.from(ciphertext, 'base64')\n const authTag = buf.subarray(buf.length - 16)\n const data = buf.subarray(0, buf.length - 16)\n\n const decipher = createDecipheriv('aes-256-gcm', apiV3Key, nonce)\n decipher.setAuthTag(authTag)\n decipher.setAAD(Buffer.from(associatedData))\n\n const decrypted = Buffer.concat([decipher.update(data), decipher.final()])\n return decrypted.toString('utf-8')\n}\n","/**\n * @h-ai/payment — 微信支付类型\n *\n * 微信支付 API v3 的内部请求/响应类型。\n * @module payment-wechat-types\n */\n\nimport { z } from 'zod'\n\n/**\n * 微信支付成功通知;事件创建时间不作为重试时的签名有效时间。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = WechatNotifyEnvelopeSchema.safeParse({\n * id: 'event-1', create_time: '2026-10-22T00:00:00Z', event_type: 'TRANSACTION.SUCCESS',\n * resource_type: 'encrypt-resource', resource: {\n * algorithm: 'AEAD_AES_256_GCM', original_type: 'transaction', ciphertext: 'encrypted-channel-resource', nonce: 'channel-nonce',\n * },\n * })\n * if (!parsed.success) throw new Error('Invalid Wechat notification')\n * // 结构成功不能替代真实验签/GCM认证;示例占位密文不具有支付证明效力。\n * ```\n */\nexport const WechatNotifyEnvelopeSchema = z.object({\n id: z.string().min(1),\n create_time: z.iso.datetime({ offset: true }),\n event_type: z.literal('TRANSACTION.SUCCESS'),\n resource_type: z.literal('encrypt-resource'),\n resource: z.object({\n algorithm: z.literal('AEAD_AES_256_GCM'),\n original_type: z.literal('transaction'),\n ciphertext: z.string().min(1),\n nonce: z.string().min(1),\n associated_data: z.string().optional(),\n }),\n})\n\n/**\n * 微信通知解密后必须具备的商户、订单和金额信息。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const parsed = WechatNotifyResourceSchema.safeParse({\n * appid: 'app-1', mchid: 'merchant-1', out_trade_no: 'ORDER_1', transaction_id: 'WX_1', trade_state: 'SUCCESS',\n * amount: { total: 100, currency: 'CNY' }, success_time: '2026-10-22T00:00:00Z',\n * })\n * if (!parsed.success) throw new Error('Invalid Wechat resource')\n * const amountInCents = parsed.data.amount.total // 解密后仍须核对可信商户、业务订单及币种。\n * ```\n */\nexport const WechatNotifyResourceSchema = z.object({\n appid: z.string().min(1),\n mchid: z.string().min(1),\n out_trade_no: z.string().min(1),\n transaction_id: z.string().min(1),\n trade_state: z.literal('SUCCESS'),\n amount: z.object({\n total: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n currency: z.string().regex(/^[A-Z]{3}$/),\n }).passthrough(),\n success_time: z.iso.datetime({ offset: true }),\n}).passthrough()\n\n/**\n * 微信 JSAPI 下单请求;本模块仅保留公众号网页的完整调起契约。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const request: WechatOrderRequest = {\n * appid: 'app-1', mchid: 'merchant-1', description: '测试商品', out_trade_no: 'ORDER_1',\n * notify_url: 'https://api.example.com/payment/notify/wechat', amount: { total: 100, currency: 'CNY' },\n * payer: { openid: 'openid-issued-for-app-1' },\n * }\n * // appid/mchid 来自受信配置;openid 必须由该公众号的授权流程获得。\n * ```\n */\nexport interface WechatOrderRequest {\n appid: string\n mchid: string\n description: string\n out_trade_no: string\n notify_url: string\n amount: {\n total: number\n currency: string\n }\n payer: {\n openid: string\n }\n attach?: string\n}\n","/**\n * @h-ai/payment — 微信支付 Provider\n *\n * 实现 PaymentProvider 接口,对接微信支付 API v3。\n * @module payment-provider-wechat\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { WechatPayConfig } from '../../payment-config.js'\nimport type { CreateOrderInput, OrderStatus, PaymentNotifyRequest, PaymentNotifyResult, PaymentOrder, PaymentProvider, RefundInput, RefundResult } from '../../payment-types.js'\nimport type { WechatOrderRequest } from './payment-wechat-types.js'\nimport { X509Certificate } from 'node:crypto'\nimport { err, ok } from '@h-ai/core'\nimport { paymentM } from '../../payment-i18n.js'\nimport { HaiPaymentError } from '../../payment-types.js'\nimport { fetchWithTimeout } from '../payment-provider-http.js'\nimport { getNotifyHeader } from '../payment-provider-notify.js'\nimport {\n decryptResource,\n generateNonce,\n getTimestamp,\n signJsapi,\n signRequest,\n verifyNotifySignature,\n} from './payment-wechat-sign.js'\nimport { WechatNotifyEnvelopeSchema, WechatNotifyResourceSchema } from './payment-wechat-types.js'\n\n/** 微信支付 API 基地址 */\nconst WECHAT_API_BASE = 'https://api.mch.weixin.qq.com'\n\n/**\n * 创建微信支付 Provider\n *\n * @param config - 微信支付配置\n * @returns PaymentProvider 实例\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function createFromTrustedConfig(config: WechatPayConfig) {\n * // 配置已经由渠道 Schema 解析;真实密钥、商户身份与通知端点由部署提供。\n * const provider = createWechatPayProvider(config)\n * const name = provider.name // 'wechat'\n * return provider\n * }\n * ```\n */\nexport function createWechatPayProvider(config: WechatPayConfig): PaymentProvider {\n /**\n * 精确选择受信平台密钥,并校验签名时间和证书有效期。\n * 不联网信任通知携带的未知 serial;配置轮换由宿主受信配置完成。\n * @param request - 保留原始 body 和协议头的通知请求。\n * @returns 唯一协议头、当前时间容差、受信 serial/证书及原始体签名均通过时为 true。\n * @example 模块内部上下文\n * ```ts\n * function authenticateNotification(request: PaymentNotifyRequest): boolean {\n * return verifyNotification(request)\n * // 成功后才允许解密资源,随后仍需核对 appId、mchId、订单、金额及持久去重。\n * }\n * ```\n */\n function verifyNotification(request: PaymentNotifyRequest): boolean {\n try {\n const timestamp = getNotifyHeader(request.headers, 'wechatpay-timestamp') ?? ''\n const nonce = getNotifyHeader(request.headers, 'wechatpay-nonce') ?? ''\n const signature = getNotifyHeader(request.headers, 'wechatpay-signature') ?? ''\n const serial = getNotifyHeader(request.headers, 'wechatpay-serial') ?? ''\n const signatureType = getNotifyHeader(request.headers, 'wechatpay-signature-type')\n const now = Date.now()\n if (!/^(?:0|[1-9]\\d{0,11})$/.test(timestamp) || !Number.isSafeInteger(Number(timestamp))\n || Math.abs(Math.floor(now / 1000) - Number(timestamp)) > 300\n || !nonce || !signature || !serial\n || (signatureType !== undefined && signatureType !== 'WECHATPAY2-SHA256-RSA2048')) {\n return false\n }\n const key = Object.hasOwn(config.platformKeys, serial) ? config.platformKeys[serial] : undefined\n if (!key)\n return false\n if (key.includes('-----BEGIN CERTIFICATE-----')) {\n const certificate = new X509Certificate(key)\n if (certificate.serialNumber.toUpperCase() !== serial.toUpperCase()\n || now < Date.parse(certificate.validFrom) || now > Date.parse(certificate.validTo)) {\n return false\n }\n }\n return verifyNotifySignature(timestamp, nonce, request.body, signature, key)\n }\n catch {\n return false\n }\n }\n\n /**\n * 发送微信支付 API 请求\n */\n async function wechatRequest<T>(method: string, path: string, body?: unknown): Promise<T> {\n const timestamp = getTimestamp()\n const nonce = generateNonce()\n const bodyStr = body ? JSON.stringify(body) : ''\n\n const signature = signRequest(method, path, timestamp, nonce, bodyStr, config.privateKey)\n\n const authorization = `WECHATPAY2-SHA256-RSA2048 mchid=\"${config.mchId}\",nonce_str=\"${nonce}\",timestamp=\"${timestamp}\",serial_no=\"${config.serialNo}\",signature=\"${signature}\"`\n\n const response = await fetchWithTimeout(`${WECHAT_API_BASE}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': authorization,\n 'Accept': 'application/json',\n },\n body: bodyStr || undefined,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(`Wechat API ${method} ${path} failed: ${response.status} ${errorText}`)\n }\n\n return response.json() as T\n }\n\n return {\n name: 'wechat',\n\n async createOrder(input: CreateOrderInput): Promise<HaiResult<PaymentOrder>> {\n if (input.tradeType !== 'jsapi')\n return err(HaiPaymentError.UNSUPPORTED_TRADE_TYPE, paymentM('payment_unsupportedTradeType'))\n if (typeof input.userId !== 'string' || !input.userId.trim() || input.userId.length > 128\n || (input.currency !== undefined && input.currency !== 'CNY')) {\n return err(HaiPaymentError.INVALID_INPUT, paymentM('payment_invalidCreateOrderInput'))\n }\n\n try {\n const requestBody: WechatOrderRequest = {\n appid: config.appId,\n mchid: config.mchId,\n description: input.description,\n out_trade_no: input.orderNo,\n notify_url: input.notifyUrl,\n amount: {\n total: input.amount,\n currency: 'CNY',\n },\n payer: { openid: input.userId },\n }\n\n if (input.metadata) {\n requestBody.attach = JSON.stringify(input.metadata)\n }\n\n const response = await wechatRequest<{ prepay_id?: unknown }>('POST', '/v3/pay/transactions/jsapi', requestBody)\n if (typeof response.prepay_id !== 'string' || !response.prepay_id.trim())\n throw new Error('Invalid Wechat JSAPI prepay response')\n\n const timestamp = getTimestamp()\n const nonce = generateNonce()\n const clientParams = {\n appId: config.appId,\n timeStamp: timestamp,\n nonceStr: nonce,\n package: `prepay_id=${response.prepay_id}`,\n signType: 'RSA',\n paySign: signJsapi(config.appId, timestamp, nonce, response.prepay_id, config.privateKey),\n }\n\n return ok({\n provider: 'wechat',\n tradeType: input.tradeType,\n clientParams,\n prepayId: response.prepay_id,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.CREATE_ORDER_FAILED,\n paymentM('payment_createOrderFailed'),\n cause,\n )\n }\n },\n\n async handleNotify(request: PaymentNotifyRequest): Promise<HaiResult<PaymentNotifyResult>> {\n try {\n if (!verifyNotification(request)) {\n return err(\n HaiPaymentError.NOTIFY_VERIFY_FAILED,\n paymentM('payment_notifyVerifyFailed'),\n )\n }\n\n // 解密资源\n const parsedBody = WechatNotifyEnvelopeSchema.safeParse(JSON.parse(request.body))\n if (!parsedBody.success)\n throw new Error('Invalid Wechat payment notification')\n const body = parsedBody.data\n const decrypted = decryptResource(\n body.resource.ciphertext,\n body.resource.nonce,\n body.resource.associated_data ?? '',\n config.apiV3Key,\n )\n const parsedResource = WechatNotifyResourceSchema.safeParse(JSON.parse(decrypted))\n if (!parsedResource.success)\n throw new Error('Invalid Wechat payment notification resource')\n const resource = parsedResource.data\n if (resource.appid !== config.appId || resource.mchid !== config.mchId) {\n return err(HaiPaymentError.NOTIFY_VERIFY_FAILED, paymentM('payment_notifyVerifyFailed'))\n }\n\n return ok({\n orderNo: resource.out_trade_no,\n transactionId: resource.transaction_id,\n eventId: body.id,\n amount: resource.amount.total,\n currency: resource.amount.currency,\n status: 'paid',\n paidAt: new Date(resource.success_time),\n raw: resource,\n })\n }\n catch {\n return err(\n HaiPaymentError.NOTIFY_PARSE_FAILED,\n paymentM('payment_notifyParseFailed'),\n new Error('Invalid Wechat payment notification'),\n )\n }\n },\n\n async queryOrder(orderNo: string): Promise<HaiResult<OrderStatus>> {\n try {\n const path = `/v3/pay/transactions/out-trade-no/${encodeURIComponent(orderNo)}?mchid=${encodeURIComponent(config.mchId)}`\n const response = await wechatRequest<{\n out_trade_no: string\n transaction_id: string\n trade_state: string\n amount: { total: number }\n success_time?: string\n }>('GET', path)\n\n const statusMap: Record<string, OrderStatus['status']> = {\n SUCCESS: 'paid',\n CLOSED: 'closed',\n REFUND: 'refunded',\n NOTPAY: 'pending',\n PAYERROR: 'failed',\n }\n\n return ok({\n orderNo: response.out_trade_no,\n transactionId: response.transaction_id,\n status: statusMap[response.trade_state] ?? 'pending',\n amount: response.amount.total,\n paidAt: response.success_time ? new Date(response.success_time) : undefined,\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.QUERY_ORDER_FAILED,\n paymentM('payment_queryOrderFailed'),\n cause,\n )\n }\n },\n\n async refund(input: RefundInput): Promise<HaiResult<RefundResult>> {\n try {\n const response = await wechatRequest<{\n refund_id: string\n status: string\n }>('POST', '/v3/refund/domestic/refunds', {\n out_trade_no: input.orderNo,\n out_refund_no: input.refundNo,\n amount: {\n refund: input.amount,\n total: input.totalAmount ?? input.amount,\n currency: 'CNY',\n },\n reason: input.reason,\n })\n\n const statusMap: Record<string, RefundResult['status']> = {\n SUCCESS: 'success',\n PROCESSING: 'processing',\n ABNORMAL: 'failed',\n }\n\n return ok({\n refundNo: input.refundNo,\n refundId: response.refund_id,\n status: statusMap[response.status] ?? 'processing',\n })\n }\n catch (cause) {\n return err(\n HaiPaymentError.REFUND_FAILED,\n paymentM('payment_refundFailed'),\n cause,\n )\n }\n },\n\n async closeOrder(orderNo: string): Promise<HaiResult<void>> {\n try {\n await wechatRequest('POST', `/v3/pay/transactions/out-trade-no/${encodeURIComponent(orderNo)}/close`, {\n mchid: config.mchId,\n })\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiPaymentError.CLOSE_ORDER_FAILED,\n paymentM('payment_closeOrderFailed'),\n cause,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/payment — 模块入口(生命周期管理)\n *\n * 提供支付模块的初始化、Provider 注册与统一支付操作 API。\n * `payment.init(config)` 负责根据配置自动注册可用的 Provider。\n *\n * @module payment-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { PaymentConfig, PaymentConfigInput } from './payment-config.js'\nimport type {\n OrderStatus,\n PaymentFunctions,\n PaymentNotifyResult,\n PaymentOrder,\n PaymentProvider,\n RefundResult,\n} from './payment-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { reldb } from '@h-ai/reldb'\nimport { PaymentConfigSchema } from './payment-config.js'\nimport {\n clearProviders,\n closeOrder,\n createOrder,\n getProvider,\n handleNotify,\n queryOrder,\n refund,\n registerProvider,\n} from './payment-functions.js'\nimport { paymentM } from './payment-i18n.js'\nimport { HaiPaymentError } from './payment-types.js'\nimport { createAlipayProvider } from './providers/alipay/payment-provider-alipay.js'\nimport { createStripeProvider } from './providers/stripe/payment-provider-stripe.js'\nimport { StripeOperationRepository } from './providers/stripe/payment-stripe-repository-operation.js'\nimport { createWechatPayProvider } from './providers/wechat/payment-provider-wechat.js'\n\nconst logger = core.logger.child({ module: 'payment', scope: 'main' })\n\n// ─── 内部状态 ───\n\nlet currentConfig: PaymentConfig | null = null\nlet initInProgress = false\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiPaymentError.NOT_INITIALIZED,\n () => paymentM('payment_notInitialized'),\n)\n\n// ─── 服务对象 ───\n\n/**\n * 支付生命周期与统一渠道操作入口;初始化失败必须停止依赖该模块的业务。\n * @example\n * ```ts\n * import { payment, type PaymentConfigInput } from '@h-ai/payment'\n * async function run(config: PaymentConfigInput) {\n * // 使用 Stripe 时,宿主已先初始化同一共享 reldb;payment.close 不关闭它。\n * const initialized = await payment.init(config)\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const order = await payment.queryOrder('stripe', 'ORDER_1')\n * if (!order.success) throw new Error(order.error.message)\n * return order.data\n * }\n * finally {\n * await payment.close()\n * }\n * }\n * ```\n */\nexport const payment: PaymentFunctions = {\n /**\n * 初始化支付模块\n *\n * 根据提供的配置自动注册对应的 Provider。\n * Stripe 要求共享 reldb 已初始化;仓库就绪后才发布 Provider,关闭时不代替宿主关闭 reldb。\n *\n * @param config - 支付配置\n */\n async init(config: PaymentConfigInput): Promise<HaiResult<void>> {\n if (initInProgress) {\n logger.warn('Payment module init already in progress, skipping')\n return err(\n HaiPaymentError.CONFIG_ERROR,\n paymentM('payment_configError', { params: { error: 'init already in progress' } }),\n )\n }\n\n initInProgress = true\n\n try {\n if (currentConfig !== null) {\n logger.warn('Payment module is already initialized, reinitializing')\n await payment.close()\n }\n\n logger.info('Initializing payment module')\n const parseResult = PaymentConfigSchema.safeParse(config)\n if (!parseResult.success) {\n logger.error('Payment config validation failed', { error: parseResult.error.message })\n return err(\n HaiPaymentError.CONFIG_ERROR,\n paymentM('payment_configError', { params: { error: parseResult.error.message } }),\n parseResult.error,\n )\n }\n const parsed = parseResult.data\n\n // Stripe 的渠道映射和幂等记录必须持久化;建表成功后才能发布 Provider。\n let stripeProvider: PaymentProvider | undefined\n if (parsed.stripe) {\n if (!reldb.isInitialized)\n return err(HaiPaymentError.CONFIG_ERROR, paymentM('payment_stripeDatabaseRequired'))\n const repository = new StripeOperationRepository(reldb)\n const ready = await repository.initialize()\n if (!ready.success)\n return err(HaiPaymentError.CONFIG_ERROR, paymentM('payment_stripeStoreInitFailed'), ready.error)\n stripeProvider = createStripeProvider(parsed.stripe, repository)\n }\n\n // 清除旧注册\n clearProviders()\n\n // 按配置自动注册 Provider\n if (parsed.wechat) {\n registerProvider(createWechatPayProvider(parsed.wechat))\n }\n if (parsed.alipay) {\n registerProvider(createAlipayProvider(parsed.alipay))\n }\n if (stripeProvider)\n registerProvider(stripeProvider)\n\n currentConfig = parsed\n logger.info('Payment module initialized', {\n providers: [\n parsed.wechat ? 'wechat' : null,\n parsed.alipay ? 'alipay' : null,\n parsed.stripe ? 'stripe' : null,\n ].filter(Boolean),\n })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Payment module initialization failed', { error })\n return err(\n HaiPaymentError.CONFIG_ERROR,\n paymentM('payment_initFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n /**\n * 关闭模块、清除所有 Provider\n */\n async close(): Promise<void> {\n if (!currentConfig) {\n logger.info('Payment module already closed, skipping')\n return\n }\n logger.info('Closing payment module')\n clearProviders()\n currentConfig = null\n logger.info('Payment module closed')\n },\n\n get config() { return currentConfig },\n get isInitialized() { return currentConfig !== null },\n\n /** 创建支付订单 */\n createOrder: (...args: Parameters<typeof createOrder>) =>\n currentConfig ? createOrder(...args) : Promise.resolve(notInitialized.result<PaymentOrder>()),\n\n /** 处理异步回调通知 */\n handleNotify: (...args: Parameters<typeof handleNotify>) =>\n currentConfig ? handleNotify(...args) : Promise.resolve(notInitialized.result<PaymentNotifyResult>()),\n\n /** 查询订单状态 */\n queryOrder: (...args: Parameters<typeof queryOrder>) =>\n currentConfig ? queryOrder(...args) : Promise.resolve(notInitialized.result<OrderStatus>()),\n\n /** 发起退款 */\n refund: (...args: Parameters<typeof refund>) =>\n currentConfig ? refund(...args) : Promise.resolve(notInitialized.result<RefundResult>()),\n\n /** 关闭订单 */\n closeOrder: (...args: Parameters<typeof closeOrder>) =>\n currentConfig ? closeOrder(...args) : Promise.resolve(notInitialized.result<void>()),\n\n /** 获取已注册的 Provider */\n getProvider,\n\n /** 手动注册 Provider(自定义渠道) */\n registerProvider,\n}\n"]}