import type { PaymentApiKey, PaymentApp, PaymentAppCreateResponse, PaymentAppListResponse, } from '../../../packages/shared/src/contracts/payment'; import type { ConfirmWechatProfileRechargeOrderResponse, CreateProfileRechargeOrderResponse, ExternalApiKeyCreateResponse, ExternalApiKeyListResponse, ExternalApiKeyMutationResponse, ProfileDashboardSummary, ProfileMembershipPlan, ProfileMembershipUpgradeQuote, ProfileRechargeCenterResponse, ProfileRechargeOrder, ProfileReferralInviteCenterResponse, ProfileWalletLedgerResponse, RedeemProfileReferralInviteCodeResponse, RedeemProfileRewardCodeResponse, } from '../../../packages/shared/src/contracts/runtime'; import { appendApiErrorRequestId, parseApiErrorMessage, } from '../../../packages/shared/src/http'; import { type ApiAuthImpact, type ApiRetryOptions, fetchWithApiAuth, requestJson, } from '../apiClient'; import { readSseJsonStream } from '../sseStream'; const PLATFORM_PROFILE_API_BASE = '/api/profile'; const PLATFORM_PROFILE_READ_RETRY: ApiRetryOptions = { maxRetries: 1, baseDelayMs: 180, maxDelayMs: 480, }; const PLATFORM_PROFILE_WRITE_RETRY: ApiRetryOptions = { maxRetries: 1, baseDelayMs: 240, maxDelayMs: 640, retryUnsafeMethods: true, }; export type PlatformProfileRequestOptions = { signal?: AbortSignal; retry?: ApiRetryOptions; skipAuth?: boolean; skipRefresh?: boolean; authImpact?: ApiAuthImpact; notifyAuthStateChange?: boolean; clearAuthOnUnauthorized?: boolean; }; function requestPlatformProfileJson( path: string, init: RequestInit, fallbackMessage: string, options: PlatformProfileRequestOptions = {}, ) { const method = (init.method ?? 'GET').toUpperCase(); const retry = options.retry ?? (method === 'GET' ? PLATFORM_PROFILE_READ_RETRY : PLATFORM_PROFILE_WRITE_RETRY); const normalizedPath = path.startsWith('/') ? path : `/${path}`; return requestJson( `${PLATFORM_PROFILE_API_BASE}${normalizedPath}`, { ...init, signal: options.signal, }, fallbackMessage, { retry, skipAuth: options.skipAuth, skipRefresh: options.skipRefresh, authImpact: options.authImpact, notifyAuthStateChange: options.notifyAuthStateChange, clearAuthOnUnauthorized: options.clearAuthOnUnauthorized, }, ); } export function getPlatformProfileDashboard( options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/dashboard', { method: 'GET' }, '读取个人看板失败', options, ); } export function getPlatformProfileWalletLedger( options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/wallet-ledger', { method: 'GET' }, '读取资产流水失败', options, ); } export function listPlatformProfileExternalApiKeys( options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/api-keys', { method: 'GET' }, '读取 API Key 失败', options, ); } export function createPlatformProfileExternalApiKey( name: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/api-keys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name }), }, '创建 API Key 失败', options, ); } export function revokePlatformProfileExternalApiKey( keyId: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( `/api-keys/${encodeURIComponent(keyId)}`, { method: 'DELETE' }, '撤销 API Key 失败', options, ); } export function listPlatformProfilePaymentApps( options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/payment/apps', { method: 'GET' }, '读取支付服务失败', options, ); } export function createPlatformProfilePaymentApp( name: string, callbackUrl: string | null, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/payment/apps', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, callbackUrl }), }, '创建支付应用失败', options, ); } export function updatePlatformProfilePaymentApp( appId: string, enabled: boolean, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( `/payment/apps/${encodeURIComponent(appId)}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled }), }, '更新支付应用失败', options, ); } export function revokePlatformProfilePaymentApiKey( keyId: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( `/payment/keys/${encodeURIComponent(keyId)}`, { method: 'DELETE' }, '撤销支付 API Key 失败', options, ); } export function getPlatformProfileRechargeCenter( options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/recharge-center', { method: 'GET' }, '读取泥点购买信息失败', options, ); } export function createPlatformProfileRechargeOrder( productId: string, paymentChannel: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/recharge/orders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ productId, paymentChannel }), }, '充值失败', options, ); } export function getPlatformProfileMembershipUpgradeQuote( targetPlan: ProfileMembershipPlan, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/membership/upgrade-quote', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ targetPlan }), }, '读取升级报价失败', options, ); } export function confirmWechatPlatformProfileRechargeOrder( orderId: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( `/recharge/orders/${encodeURIComponent(orderId)}/wechat/confirm`, { method: 'POST' }, '确认微信支付订单失败', options, ); } type PlatformProfileRechargeOrderSseEvent = | { type: 'order'; payload: ConfirmWechatProfileRechargeOrderResponse; } | { type: 'done'; payload: { orderId: string; status: string }; } | { type: 'error'; payload: { message: string }; }; function normalizePlatformProfileRechargeOrderSseEvent( eventName: string, parsed: Record, ): PlatformProfileRechargeOrderSseEvent | null { if (eventName === 'order' && parsed.order && parsed.center) { return { type: 'order', payload: parsed as ConfirmWechatProfileRechargeOrderResponse, }; } if (eventName === 'done') { const orderId = typeof parsed.orderId === 'string' ? parsed.orderId.trim() : ''; const status = typeof parsed.status === 'string' ? parsed.status.trim() : ''; if (orderId && status) { return { type: 'done', payload: { orderId, status }, }; } } if (eventName === 'error') { const message = typeof parsed.message === 'string' && parsed.message.trim() ? parsed.message.trim() : ''; return { type: 'error', payload: { message }, }; } return null; } function isPlatformProfileRechargeOrderTerminal( order: Pick, ) { if (order.status === 'pending') { return false; } if (order.status === 'expired' && !order.expirationCheckedAt) { return false; } return true; } export async function watchWechatPlatformProfileRechargeOrder( orderId: string, options: PlatformProfileRequestOptions = {}, ): Promise { const response = await fetchWithApiAuth( `${PLATFORM_PROFILE_API_BASE}/recharge/orders/${encodeURIComponent(orderId)}/wechat/events`, { method: 'GET', headers: { Accept: 'text/event-stream' }, signal: options.signal, }, { skipRefresh: options.skipRefresh, skipAuth: options.skipAuth, authImpact: options.authImpact, notifyAuthStateChange: options.notifyAuthStateChange, clearAuthOnUnauthorized: options.clearAuthOnUnauthorized, }, ); if (!response.ok) { const responseText = await response.text(); throw new Error( appendApiErrorRequestId( parseApiErrorMessage(responseText, '订阅充值订单状态失败'), response.headers.get('x-request-id'), ), ); } if (!response.body) { throw new Error('streaming response body is unavailable'); } let finalResponse: ConfirmWechatProfileRechargeOrderResponse | null = null; let lastResponse: ConfirmWechatProfileRechargeOrderResponse | null = null; await readSseJsonStream(response, ({ eventName, parsed }) => { const normalized = normalizePlatformProfileRechargeOrderSseEvent( eventName, parsed, ); if (!normalized) { return; } if (normalized.type === 'order') { lastResponse = normalized.payload; if (isPlatformProfileRechargeOrderTerminal(normalized.payload.order)) { finalResponse = normalized.payload; return false; } return; } if (normalized.type === 'done') { if ( !finalResponse && lastResponse && isPlatformProfileRechargeOrderTerminal(lastResponse.order) ) { finalResponse = lastResponse; } return false; } throw new Error(normalized.payload.message || '订阅充值订单状态失败'); }); if (!finalResponse) { throw new Error('充值订单状态流返回不完整'); } return finalResponse; } export function getPlatformProfileReferralInviteCenter( options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/referrals/invite-center', { method: 'GET' }, '读取邀请码失败', options, ); } export function redeemPlatformProfileReferralInviteCode( inviteCode: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/referrals/redeem-code', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ inviteCode }), }, '填写邀请码失败', options, ); } export function redeemPlatformProfileRewardCode( code: string, options: PlatformProfileRequestOptions = {}, ) { return requestPlatformProfileJson( '/redeem-codes/redeem', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code }), }, '兑换失败', options, ); }