@pandait.tech/payment-nuvei 0.2.1 → 0.4.0
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/README.md +70 -18
- package/dist/handlers/index.cjs +2 -1
- package/dist/handlers/index.cjs.map +1 -1
- package/dist/handlers/index.js +2 -1
- package/dist/handlers/index.js.map +1 -1
- package/dist/ui/styles.css +2 -0
- package/package.json +16 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/http.ts","../../src/sdk.ts","../../src/handlers/charge.ts","../../src/handlers/webhook.ts","../../src/handlers/3ds-callback.ts","../../src/handlers/3ds-complete.ts","../../src/handlers/3ds-timeout.ts","../../src/handlers/refund.ts","../../src/handlers/init-checkout.ts","../../src/handlers/cards.ts","../../src/handlers/verify.ts","../../src/handlers/test-charge.ts","../../src/handlers/proxy.ts"],"names":["currentOrder","currentOrderData","FieldValue","POST","GET","userEmail","crypto","DELETE"],"mappings":"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","file":"index.js","sourcesContent":["// Web-standard HTTP helpers — no framework coupling.\n//\n// The handlers operate on the Fetch API `Request`/`Response` types so they run\n// on any runtime that speaks them: Next.js App Router (NextRequest/NextResponse\n// are subtypes, so handlers drop in unchanged), Cloud Functions v2 / Express\n// (via the adapters in ./adapters), Vercel, Deno, Bun, plain Node 18+.\n\n/**\n * Build a JSON `Response`. Drop-in replacement for `NextResponse.json(data, init)`.\n * Uses manual serialization (not `Response.json`) for broadest runtime support.\n */\nexport function json(data: unknown, init?: ResponseInit): Response {\n const headers = new Headers(init?.headers);\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json; charset=utf-8\");\n }\n return new Response(JSON.stringify(data), { ...init, headers });\n}\n\n/**\n * Read a cookie value from a request's `Cookie` header. Replaces\n * `request.cookies.get(name)?.value` (which is Next-specific).\n */\nexport function getCookie(request: Request, name: string): string | undefined {\n const header = request.headers.get(\"cookie\");\n if (!header) return undefined;\n for (const part of header.split(\";\")) {\n const eq = part.indexOf(\"=\");\n if (eq === -1) continue;\n const key = part.slice(0, eq).trim();\n if (key === name) {\n return decodeURIComponent(part.slice(eq + 1).trim());\n }\n }\n return undefined;\n}\n","// Source: pauhenriques-website/src/lib/nuvei.ts\n// Phase 1 step 1.2: verbatim copy. Refactor to factory pattern (createNuveiClient) happens in step 1.3.\n\nimport crypto from \"crypto\";\n\nconst NUVEI_DOMAIN = \"paymentez.com\";\n\nfunction getBaseUrl(): string {\n const env = process.env.NUVEI_ENV === \"prod\" ? \"prod\" : \"stg\";\n return env === \"prod\"\n ? `https://ccapi.${NUVEI_DOMAIN}`\n : `https://ccapi-stg.${NUVEI_DOMAIN}`;\n}\n\n\nfunction getServerCredentials() {\n const appCode = process.env.NUVEI_SERVER_APP_CODE;\n const appKey = process.env.NUVEI_SERVER_APP_KEY;\n if (!appCode || !appKey) {\n throw new Error(\"Nuvei server credentials not configured\");\n }\n return { appCode, appKey };\n}\n\nexport function generateAuthToken(): string {\n const { appCode, appKey } = getServerCredentials();\n const timestamp = Math.floor(Date.now() / 1000);\n const uniqToken = crypto\n .createHash(\"sha256\")\n .update(`${appKey}${timestamp}`)\n .digest(\"hex\");\n return Buffer.from(`${appCode};${timestamp};${uniqToken}`).toString(\n \"base64\",\n );\n}\n\nfunction getProxyUrl(): string | null {\n return process.env.NUVEI_PROXY_URL || null;\n}\n\nexport async function nuveiRequest<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body?: Record<string, unknown>,\n): Promise<T> {\n const authToken = generateAuthToken();\n const proxyUrl = getProxyUrl();\n\n // Use Cloud Function proxy if configured (workaround for Cloud Run / Nuvei incompatibility)\n if (proxyUrl) {\n console.log(`[nuvei] ${method} ${path} via proxy`);\n const proxyResponse = await fetch(proxyUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-nuvei-auth-token\": authToken,\n \"x-nuvei-env\": process.env.NUVEI_ENV || \"stg\",\n },\n body: JSON.stringify({ path, method, body }),\n });\n if (!proxyResponse.ok) {\n const errorBody = await proxyResponse.text();\n console.error(`[nuvei] ${method} ${path} proxy failed with status ${proxyResponse.status}. Body: ${errorBody}`);\n try {\n return JSON.parse(errorBody) as T;\n } catch {\n throw new Error(`Nuvei proxy ${method} ${path} failed: ${proxyResponse.status}`);\n }\n }\n return proxyResponse.json() as Promise<T>;\n }\n\n // Direct call\n const url = `${getBaseUrl()}${path}`;\n\n const options: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Auth-Token\": authToken,\n },\n };\n\n if (body && method === \"POST\") {\n options.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, options);\n const responseText = await response.text();\n console.log(`[nuvei] ${method} ${path} → ${response.status} | body: ${responseText.slice(0, 300)}`);\n\n if (!response.ok) {\n console.error(`[nuvei] ${method} ${path} failed with status ${response.status}`);\n try {\n return JSON.parse(responseText) as T;\n } catch {\n throw new Error(`Nuvei ${method} ${path} failed: ${response.status}`);\n }\n }\n\n try {\n return JSON.parse(responseText) as T;\n } catch {\n throw new Error(`Nuvei ${method} ${path}: invalid JSON response`);\n }\n}\n\nexport async function listCards(uid: string) {\n return nuveiRequest<{\n cards: Array<{\n bin: string;\n status: string;\n token: string;\n holder_name: string;\n expiry_year: string;\n expiry_month: string;\n transaction_reference: string;\n type: string;\n number: string;\n }>;\n result_size: number;\n }>(`/v2/card/list?uid=${encodeURIComponent(uid)}`, \"GET\");\n}\n\nexport async function deleteCard(token: string, uid: string) {\n return nuveiRequest<{ message: string }>(\"/v2/card/delete/\", \"POST\", {\n card: { token },\n user: { id: uid },\n });\n}\n\nexport async function refundTransaction(transactionId: string) {\n return nuveiRequest<{\n status: string;\n detail: string;\n }>(\"/v2/transaction/refund/\", \"POST\", {\n transaction: { id: transactionId },\n });\n}\n\nexport async function verifyCard(params: {\n userId: string;\n transactionReference: string;\n value: string;\n}) {\n return nuveiRequest<{\n transaction?: {\n status: string;\n status_detail: number;\n id: string;\n message: string | null;\n };\n error?: {\n type: string;\n help: string;\n description: string;\n };\n }>(\"/v2/transaction/verify/\", \"POST\", {\n user: {\n id: params.userId,\n },\n transaction: {\n id: params.transactionReference,\n },\n type: \"BY_AMOUNT\",\n value: params.value,\n });\n}\n\nexport interface ThreeDSResponse {\n authentication: {\n status: string;\n return_code: string;\n return_message?: string;\n cavv?: string;\n eci?: string;\n xid?: string;\n reference_id?: string;\n };\n browser_response: {\n hidden_iframe?: string;\n challenge_request?: string;\n };\n sdk_response?: {\n acs_trans_id?: string;\n acs_reference_number?: string;\n };\n}\n\nexport interface DebitResponse {\n transaction?: {\n status: string;\n current_status: string;\n id: string;\n message: string | null;\n status_detail: number;\n authorization_code: string | null;\n };\n card?: {\n bin: string;\n type: string;\n number: string;\n };\n \"3ds\"?: ThreeDSResponse;\n error?: {\n type: string;\n help: string;\n description: string;\n };\n}\n\nexport async function debitWithToken(params: {\n userId: string;\n userEmail: string;\n amount: number;\n description: string;\n devReference: string;\n cardToken: string;\n cvc?: string;\n vat?: number;\n taxableAmount?: number;\n installments?: number;\n installmentsType?: number;\n browserInfo?: {\n accept_header: string;\n user_agent: string;\n language: string;\n timezone_offset: number;\n screen_width: number;\n screen_height: number;\n color_depth: number;\n js_enabled: boolean;\n java_enabled: boolean;\n ip_address?: string;\n };\n termUrl?: string;\n}) {\n const order: Record<string, unknown> = {\n amount: params.amount,\n description: params.description,\n dev_reference: params.devReference,\n vat: params.vat ?? 0,\n taxable_amount: params.taxableAmount ?? (params.amount - (params.vat ?? 0)),\n tax_percentage: 15,\n };\n\n if (params.installments && params.installments > 0) {\n order.installments = params.installments;\n order.installments_type = params.installmentsType ?? 0;\n }\n\n const body: Record<string, unknown> = {\n user: {\n id: params.userId,\n email: params.userEmail,\n },\n order,\n card: {\n token: params.cardToken,\n ...(params.cvc ? { cvc: params.cvc } : {}),\n },\n };\n\n if (params.browserInfo && params.termUrl) {\n body.extra_params = {\n threeDS2_data: {\n term_url: params.termUrl,\n device_type: \"browser\",\n },\n browser_info: params.browserInfo,\n };\n }\n\n return nuveiRequest<DebitResponse>(\"/v2/transaction/debit/\", \"POST\", body);\n}\n\n// --- 3DS Verify API ---\n\nexport interface VerifyThreeDSParams {\n transactionId: string;\n userId: string;\n type: \"AUTHENTICATION_CONTINUE\" | \"BY_CRES\" | \"BY_OTP\";\n value?: string;\n}\n\nexport async function verifyThreeDS(params: VerifyThreeDSParams): Promise<DebitResponse> {\n const body: Record<string, unknown> = {\n user: {\n id: params.userId,\n },\n transaction: { id: params.transactionId },\n type: params.type,\n value: params.value ?? \"\",\n more_info: true,\n };\n return nuveiRequest<DebitResponse>(\"/v2/transaction/verify/\", \"POST\", body);\n}\n","// Source: pauhenriques-website/src/app/api/payment/charge/route.ts\n// Phase 1 step 1.3: refactored to factory pattern createChargeHandler(deps).\n//\n// All Pau-specific logic (course retry paths, paymentLink branch, tallerId branch,\n// course enrollment) is now externalized as injectable callbacks. Consumers (Pau,\n// whitelabel clients, future custom-made sites) provide their own implementations\n// while the core charge flow (rate limit, turnstile, order validation, Nuvei debit,\n// 3DS/OTP handling, Firestore updates, email dispatch) lives here.\n\nimport { json, getCookie } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { debitWithToken, deleteCard } from \"../sdk.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n GetPriceDisplayFn,\n MinimalOrder,\n RateLimitFn,\n TurnstileFn,\n ValidateCustomOrderFn,\n} from \"./types.js\";\n\n// --- Static error message tables (Nuvei-specific, no parametrization needed) ---\n\nconst NUVEI_ERROR_MESSAGES: Record<number, string> = {\n 0: \"Error del procesador de pagos. Intenta de nuevo.\",\n // 1 = review/pending — handled separately, not shown as error\n 2: \"Error en la validación del banco. Verifica los datos de tu tarjeta.\",\n // 3 = success, not used here\n 4: \"Tarjeta rechazada por el banco. Intenta con otra tarjeta.\",\n 5: \"Transacción no permitida por el banco emisor.\",\n 6: \"Error de comunicación con el banco. Intenta en unos minutos.\",\n 7: \"Tarjeta reportada como perdida o robada. Contacta a tu banco.\",\n 8: \"Tarjeta rechazada por seguridad antifraude.\",\n 9: \"Transacción denegada por el banco. Contacta a tu banco o intenta con otra tarjeta.\",\n 10: \"La tarjeta no pudo ser procesada. Intenta con otra tarjeta.\",\n 11: \"Transacción rechazada por el sistema antifraude.\",\n 12: \"Tarjeta en lista restringida. Contacta a tu banco.\",\n 13: \"Tarjeta inválida o deshabilitada. Contacta a tu banco.\",\n 14: \"El monto excede el límite permitido por tu tarjeta.\",\n 19: \"Transacción rechazada por filtro antifraude.\",\n 20: \"Tarjeta vencida. Actualiza tu método de pago.\",\n 21: \"Código de seguridad (CVV) incorrecto.\",\n 22: \"Tipo de tarjeta no soportado para esta transacción.\",\n 23: \"Transacción rechazada. Intenta de nuevo más tarde.\",\n 31: \"Tu banco requiere verificación OTP. Ingresa el código enviado a tu teléfono.\",\n 36: \"Tu banco requiere verificación adicional 3DS. Completa el proceso en la ventana emergente.\",\n 37: \"Tu banco requiere verificación adicional 3DS. Completa el proceso en la ventana emergente.\",\n};\n\nconst THREEDS_AUTH_MESSAGES: Record<string, string> = {\n N: \"Autenticación 3DS rechazada por tu banco. Intenta con otra tarjeta.\",\n R: \"Tu banco rechazó la autenticación 3DS.\",\n U: \"No se pudo verificar la autenticación 3DS. Intenta de nuevo.\",\n};\n\nfunction getNuveiUserMessage(\n statusDetail?: number,\n rawMessage?: string | null,\n): string {\n if (statusDetail !== undefined && NUVEI_ERROR_MESSAGES[statusDetail]) {\n return NUVEI_ERROR_MESSAGES[statusDetail];\n }\n if (rawMessage?.toLowerCase().includes(\"insufficient\")) {\n return NUVEI_ERROR_MESSAGES[9]!;\n }\n if (rawMessage?.toLowerCase().includes(\"expired\")) {\n return NUVEI_ERROR_MESSAGES[20]!;\n }\n if (rawMessage?.toLowerCase().includes(\"cvv\")) {\n return NUVEI_ERROR_MESSAGES[21]!;\n }\n return \"No se pudo procesar el pago. Verifica los datos de tu tarjeta o intenta con otra.\";\n}\n\n// --- Public types ---\n\ninterface BrowserInfo {\n accept_header: string;\n user_agent: string;\n language: string;\n timezone_offset: number;\n screen_width: number;\n screen_height: number;\n color_depth: number;\n js_enabled: boolean;\n java_enabled: boolean;\n ip_address?: string;\n}\n\ninterface ChargeRequestBody {\n token: string;\n cvc?: string;\n orderId: string;\n amount: number;\n vat: number;\n description: string;\n userId: string;\n userEmail: string;\n browserInfo?: BrowserInfo;\n installments?: number;\n installmentsType?: number;\n deleteCardAfterPayment?: boolean;\n turnstileToken?: string;\n}\n\n/** Dependencies the charge handler factory needs. */\nexport interface ChargeHandlerDeps {\n /** Firebase Admin services. Provided by the consumer (so the package never owns its own Firebase init). */\n firebase: FirebaseDeps;\n /** Email service. Consumer wires up Resend (or any provider) with their own branding/templates. */\n email: EmailService;\n /** Pricing function — receives product fields and returns the effective final subtotal. Consumer-specific because pricing rules vary per business. */\n getPriceDisplay: GetPriceDisplayFn;\n /** Merchant name. Used as fallback for the Nuvei transaction description when the request body doesn't provide one (visible to the cardholder in their bank statement). */\n merchantName: string;\n /** Optional rate limit check. If omitted, no rate limiting is applied. */\n rateLimit?: RateLimitFn;\n /** Optional Turnstile (Cloudflare bot protection) verification. If omitted, the turnstileToken from the body is ignored. */\n turnstile?: TurnstileFn;\n /** Optional Cloud Functions base URL for the 3DS challenge callback (termUrl). If omitted, falls back to `process.env.CLOUD_FUNCTIONS_BASE_URL`. */\n cloudFunctionsBaseUrl?: string;\n /** Optional custom order validator — used for non-standard order flows (e.g. paymentLinks, taller-specific orders). If returned result is `{ handled: false }` the handler runs standard product/promotion validation. */\n validateCustomOrder?: ValidateCustomOrderFn;\n /** Optional post-success hook — runs after the order is marked paid and the Firestore batch commits. Use this for course enrollment, paymentLink usage tracking, fulfillment triggers, etc. Errors are caught and logged but don't fail the response. */\n onPaymentSucceeded?: (order: MinimalOrder & { id: string }) => Promise<void>;\n /** Optional retry URL builder for payment-failed emails. Receives the order, returns the URL the customer should be sent to. Default: `https://${request.host}/checkout`. */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n /** Optional logger (defaults to console). */\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router POST handler for the `/api/payment/charge` endpoint.\n *\n * Performs: session verification, rate limiting, Turnstile, order/stock/price/coupon\n * validation, Nuvei debit call, 3DS/OTP handling, Firestore order updates, email\n * dispatch, and optional post-success side effects via `onPaymentSucceeded`.\n */\nexport function createChargeHandler(deps: ChargeHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n // 1. Verify session\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesion invalida\" }, { status: 401 });\n }\n\n // 2. Client IP (used for rate limit + Turnstile remoteip hint)\n const clientIpForLimit =\n request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ||\n request.headers.get(\"x-real-ip\") ||\n \"unknown\";\n\n // 3. Rate limit (optional)\n if (deps.rateLimit) {\n const allowed = await deps.rateLimit(\n `charge:${clientIpForLimit}`,\n 10,\n 15 * 60 * 1000,\n );\n if (!allowed) {\n return json(\n { error: \"Demasiados intentos. Intentá de nuevo en unos minutos.\" },\n { status: 429 },\n );\n }\n }\n\n // 4. Parse body\n const body: ChargeRequestBody = await request.json();\n\n // 5. Turnstile (optional, but if configured, fail-closed)\n if (deps.turnstile) {\n const turnstileToken = body.turnstileToken;\n if (!turnstileToken) {\n return json(\n { error: \"Verificación de seguridad faltante. Recargá la página.\" },\n { status: 403 },\n );\n }\n const turnstileResult = await deps.turnstile(\n turnstileToken,\n clientIpForLimit === \"unknown\" ? undefined : clientIpForLimit,\n );\n if (!turnstileResult.success) {\n return json(\n { error: \"No pudimos verificar que sos humano. Recargá la página.\" },\n { status: 403 },\n );\n }\n }\n\n const {\n token,\n cvc,\n orderId,\n amount,\n vat,\n description,\n userId,\n userEmail,\n browserInfo,\n installments,\n installmentsType,\n } = body;\n\n logger.log(\"[charge] Request:\", {\n token: token?.substring(0, 10) + \"...\",\n orderId,\n amount,\n userId: userId?.substring(0, 8) + \"...\",\n });\n\n if (!token || !orderId || !amount) {\n return json({ error: \"Datos incompletos\" }, { status: 400 });\n }\n\n // 6. Verify user matches session\n if (decodedToken.uid !== userId) {\n return json({ error: \"Usuario no coincide\" }, { status: 403 });\n }\n\n // 7. Order existence + pending status\n const orderDoc = await db.collection(\"orders\").doc(orderId).get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n if (orderData.status !== \"pending\") {\n return json(\n { error: \"Esta orden ya fue procesada\" },\n { status: 409 },\n );\n }\n\n // 8. Custom order validation hook (e.g. paymentLink, tallerId flows)\n // If the consumer handles this order via a custom flow, skip standard\n // product/promotion validation entirely.\n let runStandardValidation = true;\n if (deps.validateCustomOrder) {\n const customResult = await deps.validateCustomOrder({\n orderId,\n orderData,\n amount,\n });\n if (customResult.handled) {\n if (!customResult.valid) {\n return json(\n { error: customResult.error },\n { status: customResult.status },\n );\n }\n runStandardValidation = false;\n }\n }\n\n // 9. Standard validation: stock, price, coupon\n if (runStandardValidation) {\n const orderItems = orderData.items ?? [];\n let verifiedSubtotal = 0;\n for (const item of orderItems) {\n const productDoc = await db\n .collection(\"products\")\n .doc(item.productId)\n .get();\n if (!productDoc.exists || !productDoc.data()?.isActive) {\n return json(\n { error: `El producto \"${item.name}\" ya no está disponible` },\n { status: 409 },\n );\n }\n const productData = productDoc.data()!;\n const isDigital = productData.isDigital === true;\n const stock = productData.stock ?? 0;\n if (!isDigital && stock < item.quantity) {\n return json(\n {\n error: `Stock insuficiente para \"${item.name}\" (disponible: ${stock})`,\n },\n { status: 409 },\n );\n }\n const display = deps.getPriceDisplay({\n price: productData.price ?? 0,\n autoDiscounts: productData.autoDiscounts,\n });\n const expectedItemSubtotal = display.finalSubtotal;\n if (Math.abs(expectedItemSubtotal - item.price) > 0.02) {\n return json(\n {\n error: `El precio de \"${item.name}\" cambió. Recargá la página para ver el precio actualizado.`,\n },\n { status: 409 },\n );\n }\n verifiedSubtotal += expectedItemSubtotal * item.quantity;\n }\n\n // Re-validate coupon if applied\n let verifiedDiscount = 0;\n const orderDiscount = orderData.discount ?? 0;\n const orderPromotionId = orderData.promotionId;\n\n if (orderPromotionId && orderDiscount > 0) {\n const promoDoc = await db\n .collection(\"promotions\")\n .doc(orderPromotionId)\n .get();\n if (!promoDoc.exists || !promoDoc.data()?.isActive) {\n return json(\n { error: \"El cupon aplicado ya no es valido. Remuevelo y vuelve a intentar.\" },\n { status: 409 },\n );\n }\n const promo = promoDoc.data()!;\n\n const now = new Date();\n const validFrom = promo.rules.validFrom.toDate\n ? promo.rules.validFrom.toDate()\n : new Date(promo.rules.validFrom);\n const validUntil = promo.rules.validUntil.toDate\n ? promo.rules.validUntil.toDate()\n : new Date(promo.rules.validUntil);\n if (now < validFrom || now > validUntil) {\n return json(\n { error: \"El cupon aplicado ha expirado. Remuevelo y vuelve a intentar.\" },\n { status: 409 },\n );\n }\n\n if (promo.rules.maxTotalUses && promo.currentUses >= promo.rules.maxTotalUses) {\n return json(\n { error: \"El cupon aplicado ya alcanzo su limite de usos.\" },\n { status: 409 },\n );\n }\n\n if (promo.type === \"percentage\") {\n verifiedDiscount = verifiedSubtotal * (promo.value / 100);\n if (promo.maxDiscountAmount) {\n verifiedDiscount = Math.min(verifiedDiscount, promo.maxDiscountAmount);\n }\n } else if (promo.type === \"fixed_amount\") {\n verifiedDiscount = Math.min(promo.value, verifiedSubtotal);\n }\n verifiedDiscount = Math.round(verifiedDiscount * 100) / 100;\n }\n\n const verifiedDiscountedSubtotal = Math.max(0, verifiedSubtotal - verifiedDiscount);\n const verifiedVat = Math.round(verifiedDiscountedSubtotal * 0.15 * 100) / 100;\n const verifiedTotal = Math.round((verifiedDiscountedSubtotal + verifiedVat) * 100) / 100;\n if (verifiedTotal !== amount) {\n return json(\n {\n error: \"El monto no coincide con los precios actuales. Actualiza tu carrito.\",\n },\n { status: 409 },\n );\n }\n }\n\n // 10. Build termUrl for 3DS challenge callback. Required for 3DS2 — Nuvei's\n // SDK only sends browser_info when termUrl is also present (both go in\n // extra_params.threeDS2_data). If browserInfo is provided but termUrl\n // can't be built, 3DS will silently fail; we log loud so consumers can\n // diagnose config issues fast.\n const functionsBase =\n deps.cloudFunctionsBaseUrl ?? process.env.CLOUD_FUNCTIONS_BASE_URL;\n const termUrl = functionsBase\n ? `${functionsBase}/threeDSCallback?orderId=${orderId}`\n : undefined;\n\n if (browserInfo && !termUrl) {\n logger.error(\n \"[charge] browserInfo provided but cloudFunctionsBaseUrl is not configured. 3DS challenges will not initiate. Configure ChargeHandlerDeps.cloudFunctionsBaseUrl (or CLOUD_FUNCTIONS_BASE_URL env var) pointing to your 3DS callback endpoint.\",\n );\n }\n\n // 11. Inject client IP into browserInfo for Paymentez 3DS2\n const clientIp =\n request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ||\n request.headers.get(\"x-real-ip\") ||\n \"127.0.0.1\";\n const enrichedBrowserInfo = browserInfo\n ? { ...browserInfo, ip_address: clientIp }\n : undefined;\n\n // 12. Call Nuvei debit\n const discountedSubtotalForTax = amount - (vat ?? 0);\n const nuveiData = await debitWithToken({\n userId,\n userEmail,\n amount,\n description: description || deps.merchantName,\n devReference: orderId,\n cardToken: token,\n ...(cvc ? { cvc } : {}),\n vat: vat ?? 0,\n taxableAmount: discountedSubtotalForTax,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n ...(enrichedBrowserInfo && termUrl\n ? { browserInfo: enrichedBrowserInfo, termUrl }\n : {}),\n });\n logger.log(\"[charge] Nuvei debit response FULL:\", JSON.stringify(nuveiData));\n logger.log(\n \"[charge] Nuvei debit response summary:\",\n JSON.stringify({\n status: nuveiData.transaction?.status,\n status_detail: nuveiData.transaction?.status_detail,\n id: nuveiData.transaction?.id,\n \"3ds_auth\": nuveiData[\"3ds\"]?.authentication?.status,\n error: nuveiData.error,\n }),\n );\n\n // 13a. Success path\n if (\n nuveiData.transaction &&\n nuveiData.transaction.status === \"success\" &&\n nuveiData.transaction.status_detail === 3\n ) {\n const rawAuthCode = nuveiData.transaction.authorization_code;\n const hasValidAuthCode =\n typeof rawAuthCode === \"string\" &&\n rawAuthCode.trim().length > 0 &&\n rawAuthCode !== \"null\";\n\n const batch = db.batch();\n const orderRef = db.collection(\"orders\").doc(orderId);\n\n if (hasValidAuthCode) {\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: nuveiData.transaction.id,\n authorizationCode: rawAuthCode,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n } else {\n logger.error(\n `[AUDIT:MISSING_AUTH_CODE] orderId=${orderId} txId=${nuveiData.transaction.id} debitResponse=${JSON.stringify(nuveiData)}`,\n );\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: nuveiData.transaction.id,\n missingAuthCodeFlagged: true,\n missingAuthCodeLoggedAt: new Date(),\n emailPending: true,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n }\n\n // Atomically increment promotion usage if coupon was applied\n const orderSnap = await orderRef.get();\n const orderInfo = (orderSnap.data() ?? {}) as MinimalOrder;\n if (orderInfo.promotionId) {\n const promoRef = db.collection(\"promotions\").doc(orderInfo.promotionId);\n batch.update(promoRef, {\n currentUses: FieldValue.increment(1),\n });\n\n const usageRef = promoRef.collection(\"usages\").doc();\n batch.set(usageRef, {\n userId: orderInfo.userId,\n orderId,\n discountApplied: orderInfo.discount || 0,\n usedAt: new Date(),\n });\n }\n\n await batch.commit();\n\n // Post-success hook (consumer-specific side effects: enrollment, paymentLink tracking, fulfillment triggers, etc.)\n if (deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderInfo, id: orderId });\n } catch (err) {\n logger.error(\n `[charge] onPaymentSucceeded hook failed for order ${orderId}:`,\n err,\n );\n }\n }\n\n // Send confirmation email ONLY if we have a valid auth_code.\n // Otherwise webhook or timeout handler will deliver it.\n let emailSent = false;\n if (hasValidAuthCode) {\n const emailResult = await deps.email\n .sendPaymentConfirmation({\n to: userEmail,\n customerName: orderInfo.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: nuveiData.transaction.id,\n authorizationCode: rawAuthCode as string,\n items: orderInfo.items || [],\n subtotal: orderInfo.subtotal || amount,\n discount: orderInfo.discount || undefined,\n couponCode: orderInfo.couponCode,\n vat: orderInfo.vat || vat,\n total: amount,\n ...(orderInfo.postPurchaseNote\n ? { postPurchaseNote: orderInfo.postPurchaseNote }\n : {}),\n })\n .catch(() => ({ success: false }));\n emailSent = emailResult.success;\n if (emailSent) {\n await orderRef.update({ emailSentAt: new Date() });\n }\n }\n\n // Delete card from Nuvei if user opted out of saving\n if (body.deleteCardAfterPayment && token) {\n deleteCard(token, userId).catch((err) =>\n logger.error(\"[charge] Failed to delete card after payment:\", err),\n );\n }\n\n return json({\n success: true,\n transactionId: nuveiData.transaction.id,\n authorizationCode: hasValidAuthCode ? rawAuthCode : null,\n orderId,\n emailSent,\n });\n }\n\n // 13b. Review/pending (status_detail 1)\n if (\n nuveiData.transaction?.status === \"pending\" &&\n nuveiData.transaction?.status_detail === 1\n ) {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"processing\",\n paymentTransactionId: nuveiData.transaction.id || null,\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n return json({\n review: true,\n orderId,\n transactionId: nuveiData.transaction.id,\n });\n }\n\n // Persist the consumer's opt-out + the Nuvei token so the downstream\n // handler (3ds-complete or webhook BY_CRES) can call deleteCard after\n // the payment finishes. Original Pau code didn't persist these, which\n // broke the \"do not save card\" toggle for any 3DS/OTP flow.\n const persistDeleteOnPaid = body.deleteCardAfterPayment\n ? { deleteCardAfterPayment: true, paymentToken: token }\n : {};\n\n // 13c. 3DS device fingerprint (status_detail 35) — hidden iframe, frictionless\n if (nuveiData.transaction?.status_detail === 35) {\n const threeDSData = nuveiData[\"3ds\"];\n const hiddenIframeHtml = threeDSData?.browser_response?.hidden_iframe || \"\";\n\n await db.collection(\"orders\").doc(orderId).update({\n status: \"3ds-pending\",\n isDeviceFingerprint: true,\n nuveiTransactionId: nuveiData.transaction.id || null,\n ...persistDeleteOnPaid,\n updatedAt: new Date(),\n });\n return json({\n challenge: true,\n challengeHtml: hiddenIframeHtml,\n isDeviceFingerprint: true,\n orderId,\n nuveiTransactionId: nuveiData.transaction.id,\n statusDetail: 35,\n });\n }\n\n // 13d. OTP (status_detail 31)\n if (nuveiData.transaction?.status_detail === 31) {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"otp-pending\",\n nuveiTransactionId: nuveiData.transaction.id || null,\n ...persistDeleteOnPaid,\n updatedAt: new Date(),\n });\n return json({\n otpRequired: true,\n orderId,\n nuveiTransactionId: nuveiData.transaction.id,\n statusDetail: 31,\n });\n }\n\n // 13e. 3DS challenge (status_detail 36 or 37)\n if (\n nuveiData.transaction?.status_detail === 36 ||\n nuveiData.transaction?.status_detail === 37\n ) {\n const threeDSData = nuveiData[\"3ds\"];\n const challengeHtml =\n threeDSData?.browser_response?.challenge_request ||\n threeDSData?.browser_response?.hidden_iframe ||\n \"\";\n\n // Capture any CRES/value field for verify BY_CRES (Anthony at Nuvei: value\n // for verify is returned in debit response when status_detail = 36).\n const rawDebit = nuveiData as Record<string, unknown> & {\n \"3ds\"?: Record<string, unknown> & {\n authentication?: Record<string, unknown>;\n browser_response?: Record<string, unknown>;\n };\n transaction?: Record<string, unknown>;\n };\n const debitCres: string | null =\n (rawDebit[\"3ds\"]?.authentication?.[\"cres\"] as string) ||\n (rawDebit[\"3ds\"]?.browser_response?.[\"cres\"] as string) ||\n (rawDebit[\"3ds\"]?.[\"cres\"] as string) ||\n (rawDebit.transaction?.[\"cres\"] as string) ||\n (rawDebit[\"cres\"] as string) ||\n (rawDebit[\"value\"] as string) ||\n null;\n logger.log(\n `[charge] status ${nuveiData.transaction.status_detail} — debitCres captured: ${debitCres ? \"YES (len=\" + debitCres.length + \")\" : \"NO\"}`,\n );\n\n if (challengeHtml) {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"3ds-pending\",\n nuveiTransactionId: nuveiData.transaction?.id || null,\n ...(debitCres ? { threeDSCres: debitCres } : {}),\n ...persistDeleteOnPaid,\n updatedAt: new Date(),\n });\n return json({\n challenge: true,\n challengeHtml,\n isDeviceFingerprint: false,\n orderId,\n nuveiTransactionId: nuveiData.transaction?.id,\n statusDetail: nuveiData.transaction?.status_detail,\n });\n }\n }\n\n // 13f. 3DS frictionless failure\n const threeDSStatus = nuveiData[\"3ds\"]?.authentication?.status;\n if (threeDSStatus && THREEDS_AUTH_MESSAGES[threeDSStatus]) {\n const threeDSErrorMsg = THREEDS_AUTH_MESSAGES[threeDSStatus]!;\n const currentOrder = await db.collection(\"orders\").doc(orderId).get();\n const currentOrderData = (currentOrder.data() ?? {}) as MinimalOrder;\n if (currentOrderData.status === \"pending\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n }\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...currentOrderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: currentOrderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: threeDSErrorMsg,\n items: currentOrderData.items || [],\n total: currentOrderData.total || amount,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n return json({ error: threeDSErrorMsg }, { status: 400 });\n }\n\n // 13g. Generic charge failure\n const failedErrorMsg = getNuveiUserMessage(\n nuveiData.transaction?.status_detail,\n nuveiData.transaction?.message || nuveiData.error?.description,\n );\n\n const currentOrder = await db.collection(\"orders\").doc(orderId).get();\n const currentOrderData = (currentOrder.data() ?? {}) as MinimalOrder;\n // Only downgrade if webhook hasn't already set a final status\n if (currentOrderData.status === \"pending\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n }\n\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...currentOrderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: currentOrderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: failedErrorMsg,\n items: currentOrderData.items || [],\n total: currentOrderData.total || amount,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n\n return json({ error: failedErrorMsg }, { status: 400 });\n } catch (error) {\n logger.error(\"Payment charge error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/webhooks/nuvei/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Pau's \"pn_<contributionId>\" Plan Novios branching is externalized via the\n// `handleCustomDevReference` hook — consumers detect their own custom prefixes\n// and return a Response if they handle the webhook themselves. Course\n// enrollment post-success is delegated to `onPaymentSucceeded`.\n\nimport { json } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { deleteCard, verifyThreeDS } from \"../sdk.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n MinimalOrder,\n} from \"./types.js\";\n\n/**\n * Extract CRES from webhook payload. Tries multiple possible field paths\n * because Nuvei's webhook structure for 3DS callbacks is not fully documented.\n */\nfunction extractCres(payload: unknown): string | null {\n if (!payload || typeof payload !== \"object\") return null;\n const p = payload as Record<string, unknown> & {\n \"3ds\"?: Record<string, unknown> & {\n authentication?: Record<string, unknown>;\n browser_response?: Record<string, unknown>;\n };\n transaction?: Record<string, unknown> & {\n \"3ds\"?: { authentication?: Record<string, unknown> };\n };\n };\n const candidates = [\n p[\"cres\"],\n p[\"CRes\"],\n p[\"value\"],\n p[\"3ds\"]?.authentication?.[\"cres\"],\n p[\"3ds\"]?.browser_response?.[\"cres\"],\n p[\"3ds\"]?.[\"cres\"],\n p.transaction?.[\"cres\"],\n p.transaction?.[\"3ds\"]?.authentication?.[\"cres\"],\n ];\n for (const c of candidates) {\n if (typeof c === \"string\" && c.trim().length > 0) return c;\n }\n return null;\n}\n\ninterface NuveiWebhookPayload {\n transaction: {\n id: string;\n status: string;\n status_detail: number;\n dev_reference: string;\n amount: number;\n authorization_code: string | null;\n message: string | null;\n carrier_code: string | null;\n };\n user: {\n id: string;\n email: string;\n };\n}\n\n/** Dependencies the webhook handler factory needs. */\nexport interface WebhookHandlerDeps {\n firebase: FirebaseDeps;\n email: Pick<EmailService, \"sendPaymentConfirmation\" | \"sendPaymentPending\">;\n /** Optional post-success hook. Fires when the webhook transitions an order to \"paid\" (either via direct status_detail=3 or via verify BY_CRES). Used for enrollment, fulfillment triggers, paymentLink usage tracking, etc. */\n onPaymentSucceeded?: (\n order: MinimalOrder & { id: string },\n ) => Promise<void>;\n /** Optional custom dev_reference handler. If the webhook's `transaction.dev_reference` matches a custom format (e.g. \"pn_<id>\" for Plan Novios), the consumer returns a Response and the standard order flow is skipped. Return null to fall through to standard order processing. */\n handleCustomDevReference?: (\n devReference: string,\n transaction: NuveiWebhookPayload[\"transaction\"],\n payload: NuveiWebhookPayload,\n ) => Promise<Response | null>;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router POST handler for the Nuvei webhook callback.\n * Reference: https://developers.paymentez.com/api/#webhook\n */\nexport function createWebhookHandler(deps: WebhookHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n const payload: NuveiWebhookPayload = await request.json();\n logger.log(\"[webhook] Full payload:\", JSON.stringify(payload));\n\n const { transaction } = payload;\n if (!transaction?.id || !transaction?.dev_reference) {\n return json({ error: \"Payload inválido\" }, { status: 400 });\n }\n\n const incomingCres = extractCres(payload);\n if (incomingCres) {\n logger.log(\n `[webhook] CRES present in webhook payload (len=${incomingCres.length}) for txId=${transaction.id}`,\n );\n }\n\n const devRef = transaction.dev_reference;\n\n // Hook: consumer can intercept custom dev_reference formats (e.g. Plan Novios \"pn_*\").\n if (deps.handleCustomDevReference) {\n const customResponse = await deps.handleCustomDevReference(\n devRef,\n transaction,\n payload,\n );\n if (customResponse) return customResponse;\n }\n\n // --- Standard order webhook ---\n const orderId = devRef;\n const orderRef = db.collection(\"orders\").doc(orderId);\n const orderDoc = await orderRef.get();\n\n if (!orderDoc.exists) {\n logger.error(`Webhook: Order ${orderId} not found`);\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n // If webhook brings CRES AND order is still in 3ds-pending (verify never\n // called yet), complete the 3DS flow by calling verify with BY_CRES here.\n // Covers the case where browser-side postMessage never arrived but the\n // server-to-server webhook delivered the CRES.\n const orderDataEarly = (orderDoc.data() ?? {}) as MinimalOrder;\n if (\n incomingCres &&\n orderDataEarly.status === \"3ds-pending\" &&\n !orderDataEarly.verifyCalledAt\n ) {\n try {\n await db.runTransaction(async (tx) => {\n const doc = await tx.get(orderRef);\n if (doc.data()?.verifyCalledAt) throw new Error(\"ALREADY_CALLED\");\n tx.update(orderRef, {\n verifyCalledAt: new Date(),\n threeDSCres: incomingCres,\n });\n });\n\n logger.log(`[webhook] Calling verify BY_CRES for order ${orderId}`);\n const verifyResult = await verifyThreeDS({\n transactionId:\n (orderDataEarly.nuveiTransactionId as string) || transaction.id,\n userId: orderDataEarly.userId as string,\n type: \"BY_CRES\",\n value: incomingCres,\n });\n logger.log(`[webhook] verify response: ${JSON.stringify(verifyResult)}`);\n\n const raw = verifyResult as Record<string, unknown>;\n const vStatus = verifyResult.transaction?.status ?? raw[\"status\"];\n const vDetail =\n verifyResult.transaction?.status_detail ?? raw[\"status_detail\"];\n const vAuthCode =\n verifyResult.transaction?.authorization_code ??\n raw[\"authorization_code\"] ??\n null;\n const vTxId =\n verifyResult.transaction?.id ??\n raw[\"transaction_id\"] ??\n orderDataEarly.nuveiTransactionId ??\n transaction.id;\n const verifySuccess =\n (vStatus === \"success\" || vStatus === 1) && vDetail === 3;\n\n if (verifySuccess) {\n const hasAuth =\n typeof vAuthCode === \"string\" &&\n vAuthCode.trim().length > 0 &&\n vAuthCode !== \"null\";\n\n // Use a batch so the order update + promotion-usage increment land\n // atomically. Matches charge.ts and 3ds-complete.ts. Without this,\n // a coupon used on a payment that completed via this webhook path\n // (browser stalled / postMessage never arrived) would never have\n // its currentUses incremented and could be reused indefinitely.\n const batch = db.batch();\n\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: vTxId,\n ...(hasAuth\n ? { authorizationCode: vAuthCode }\n : {\n missingAuthCodeFlagged: true,\n missingAuthCodeLoggedAt: new Date(),\n emailPending: true,\n }),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n });\n\n if (orderDataEarly.promotionId) {\n const promoRef = db\n .collection(\"promotions\")\n .doc(orderDataEarly.promotionId);\n batch.update(promoRef, {\n currentUses: FieldValue.increment(1),\n });\n const usageRef = promoRef.collection(\"usages\").doc();\n batch.set(usageRef, {\n userId: orderDataEarly.userId,\n orderId,\n discountApplied: orderDataEarly.discount || 0,\n usedAt: new Date(),\n });\n }\n\n await batch.commit();\n\n if (hasAuth && orderDataEarly.userEmail) {\n await deps.email\n .sendPaymentConfirmation({\n to: orderDataEarly.userEmail as string,\n customerName: orderDataEarly.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: vTxId as string,\n authorizationCode: vAuthCode as string,\n items: orderDataEarly.items || [],\n subtotal:\n (orderDataEarly.subtotal as number) ||\n (orderDataEarly.total as number) ||\n 0,\n discount: (orderDataEarly.discount as number) || undefined,\n couponCode: orderDataEarly.couponCode as string | undefined,\n vat: (orderDataEarly.vat as number) || 0,\n total: (orderDataEarly.total as number) || 0,\n })\n .catch(() => ({ success: false }));\n await orderRef.update({ emailSentAt: new Date() });\n }\n\n // Honor \"do not save card\" opt-out. charge.ts persisted these\n // fields when the order entered 3DS — without this call, the\n // card stays saved on the webhook BY_CRES completion path.\n if (\n orderDataEarly.deleteCardAfterPayment &&\n orderDataEarly.paymentToken\n ) {\n deleteCard(\n orderDataEarly.paymentToken as string,\n orderDataEarly.userId as string,\n ).catch((err) =>\n logger.error(\n \"[webhook] Failed to delete card after payment:\",\n err,\n ),\n );\n }\n\n if (deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderDataEarly, id: orderId });\n } catch (err) {\n logger.error(\n `[webhook] onPaymentSucceeded hook failed for ${orderId}:`,\n err,\n );\n }\n }\n\n return json({ received: true, verifiedFromWebhook: true });\n }\n } catch (err) {\n if ((err as Error).message !== \"ALREADY_CALLED\") {\n logger.error(\n `[webhook] Failed to verify BY_CRES for order ${orderId}:`,\n err,\n );\n }\n }\n }\n\n const isApproved =\n transaction.status === \"success\" && transaction.status_detail === 3;\n\n const currentStatus = orderDoc.data()?.status;\n\n // Never downgrade a \"paid\" order — webhook is idempotent\n const finalStatuses = [\"paid\", \"delivered\", \"shipped\"];\n const shouldUpdateStatus =\n isApproved || !finalStatuses.includes(currentStatus);\n\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n const webhookAuthCode = transaction.authorization_code;\n const hasValidAuthCode =\n typeof webhookAuthCode === \"string\" &&\n webhookAuthCode.trim().length > 0 &&\n webhookAuthCode !== \"null\";\n\n const updatePayload: Record<string, unknown> = {\n ...(shouldUpdateStatus && {\n status: isApproved ? \"paid\" : \"cancelled\",\n }),\n paymentTransactionId: transaction.id,\n authorizationCode: webhookAuthCode || null,\n webhookStatus: transaction.status,\n webhookStatusDetail: transaction.status_detail,\n webhookReceivedAt: new Date(),\n updatedAt: new Date(),\n };\n\n // If email was pending (verify returned success without auth_code) and\n // webhook now brings the auth_code, send the confirmation email.\n const shouldSendPendingEmail =\n isApproved &&\n orderData.emailPending === true &&\n hasValidAuthCode &&\n orderData.userEmail;\n\n if (shouldSendPendingEmail) {\n updatePayload.emailPending = FieldValue.delete();\n updatePayload.missingAuthCodeFlagged = FieldValue.delete();\n updatePayload.emailSentAt = new Date();\n }\n\n await orderRef.update(updatePayload);\n\n if (shouldSendPendingEmail) {\n try {\n await deps.email.sendPaymentConfirmation({\n to: orderData.userEmail as string,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: transaction.id,\n authorizationCode: webhookAuthCode as string,\n items: orderData.items || [],\n subtotal:\n (orderData.subtotal as number) || (orderData.total as number) || 0,\n discount: (orderData.discount as number) || undefined,\n couponCode: orderData.couponCode as string | undefined,\n vat: (orderData.vat as number) || 0,\n total: (orderData.total as number) || 0,\n });\n logger.log(`[webhook] Pending confirmation email sent for order ${orderId}`);\n } catch (err) {\n logger.error(`[webhook] Failed to send pending confirmation email:`, err);\n }\n } else if (\n isApproved &&\n orderData.emailPending === true &&\n !hasValidAuthCode &&\n orderData.userEmail\n ) {\n // Webhook approved the order but still NO auth_code — send pending email\n // (not a success confirmation). Keep flag for audit.\n logger.error(\n `[AUDIT:EMAIL_SENT_WITHOUT_AUTH_CODE] orderId=${orderId} txId=${transaction.id}`,\n );\n try {\n await deps.email.sendPaymentPending({\n to: orderData.userEmail as string,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: transaction.id,\n items: orderData.items || [],\n subtotal:\n (orderData.subtotal as number) || (orderData.total as number) || 0,\n discount: (orderData.discount as number) || undefined,\n couponCode: orderData.couponCode as string | undefined,\n vat: (orderData.vat as number) || 0,\n total: (orderData.total as number) || 0,\n });\n await orderRef.update({\n emailPending: FieldValue.delete(),\n emailSentAt: new Date(),\n });\n } catch (err) {\n logger.error(`[webhook] Failed to send pending-status email:`, err);\n }\n }\n\n const newStatus = shouldUpdateStatus\n ? isApproved\n ? \"paid\"\n : \"cancelled\"\n : currentStatus;\n logger.log(\n `Webhook: Order ${orderId} → ${newStatus} (status_detail: ${transaction.status_detail})`,\n );\n\n // Post-success hook (consumer handles enrollment, paymentLink tracking, etc.)\n if (newStatus === \"paid\" && deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderData, id: orderId });\n } catch (err) {\n logger.error(\n `[webhook] onPaymentSucceeded hook failed for ${orderId}:`,\n err,\n );\n }\n }\n\n return json({ received: true });\n } catch (error) {\n logger.error(\"Webhook processing error:\", error);\n return json(\n { error: \"Error procesando webhook\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website (functions/index.js threeDSCallback +\n// src/app/api/payment/3ds-callback/route.ts). Framework-neutral.\n//\n// The ACS (Alignet/Paymentez) calls this endpoint after the 3DS challenge\n// completes. It extracts the `cres`, persists it on the order, and returns an\n// HTML page that postMessages to the parent checkout window (no redirect —\n// Firebase App Hosting blocks 303s from API routes).\n//\n// Hosting note: on Firebase App Hosting / Cloud Run the ACS's external POST is\n// 403'd before your code runs, so deploy this as a Cloud Function via\n// `toCloudFunction` (see ../adapters) and point cloudFunctionsBaseUrl at it.\n// On Vercel/etc. mount it directly as a Next.js route.\n//\n// Public endpoint — no auth required. Paymentez sets the URL via term_url.\n\nimport type { Firestore } from \"firebase-admin/firestore\";\n\n/** Dependencies the 3DS callback handler factory needs. */\nexport interface ThreeDSCallbackHandlerDeps {\n firebase: { db: Firestore };\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Find the CRES value across the many field names / casings issuers use.\n * Alignet/Paymentez have been seen sending `cres`, `CRes`, `value`,\n * `param.value`, etc.\n */\nfunction pickCres(src: Record<string, string>): string {\n for (const key of Object.keys(src)) {\n const k = key.toLowerCase();\n if (\n k === \"cres\" ||\n k === \"cres_value\" ||\n k === \"cresvalue\" ||\n k === \"value\" ||\n k === \"param.value\" ||\n k === \"paramvalue\"\n ) {\n const v = src[key];\n if (typeof v === \"string\" && v.length > 0) return v;\n }\n }\n return src.cres || src.CRes || src.CRES || src.value || \"\";\n}\n\n/**\n * Alignet does NOT send transStatus as a separate field — it's inside the CRES\n * (base64url-encoded JSON). Decode the payload to extract the real transStatus.\n * Returns the decoded transStatus or null if it can't be decoded.\n */\nfunction transStatusFromCres(\n cres: string,\n logger: Pick<Console, \"warn\">,\n): string | null {\n try {\n const base64 = cres.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const pad = base64.length % 4;\n const padded = pad ? base64 + \"=\".repeat(4 - pad) : base64;\n const decoded = JSON.parse(\n Buffer.from(padded, \"base64\").toString(\"utf-8\"),\n );\n if (decoded && typeof decoded.transStatus === \"string\") {\n return decoded.transStatus;\n }\n } catch (e) {\n logger.warn(\n \"[3ds-callback] Could not decode CRES payload:\",\n e instanceof Error ? e.message : e,\n );\n }\n return null;\n}\n\nfunction paramsToObject(params: URLSearchParams): Record<string, string> {\n const obj: Record<string, string> = {};\n for (const [k, v] of params.entries()) obj[k] = v;\n return obj;\n}\n\nfunction buildCompletionPage(orderId: string, transStatus: string): Response {\n // Sanitize before interpolating into HTML — only allow safe characters.\n const safeOrderId = String(orderId).replace(/[^a-zA-Z0-9_-]/g, \"\");\n const safeTransStatus = String(transStatus).replace(/[^a-zA-Z0-9]/g, \"\");\n const html = `<!DOCTYPE html>\n<html><head><meta charset=\"utf-8\"><title>3DS Verification</title></head>\n<body>\n<script>\n(function() {\n var message = {\n type: \"3DS_COMPLETE\",\n orderId: \"${safeOrderId}\",\n transStatus: \"${safeTransStatus}\"\n };\n try {\n if (window.parent && window.parent !== window) {\n window.parent.postMessage(message, \"*\");\n } else if (window.opener) {\n window.opener.postMessage(message, \"*\");\n }\n } catch(e) {}\n})();\n</script>\n<p style=\"font-family:sans-serif;color:#666;text-align:center;margin-top:40px\">\nVerificando autenticación...\n</p>\n</body></html>`;\n\n return new Response(html, {\n status: 200,\n headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n });\n}\n\n/**\n * Creates the 3DS callback route handlers. Returns `{ POST, GET }` because the\n * ACS may call either depending on bank/issuer.\n *\n * Usage (Next.js): export const { POST, GET } = create3dsCallbackHandler({ firebase: { db } });\n * Usage (Functions): const { POST } = create3dsCallbackHandler({ firebase: { db } });\n * exports.threeDSCallback = onRequest({ cors: true }, toCloudFunction(POST));\n */\nexport function create3dsCallbackHandler(deps: ThreeDSCallbackHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db } = deps.firebase;\n\n /**\n * Persist the 3DS result on the order — but ONLY while the order is in\n * `3ds-pending` (prevents tampering / out-of-order callbacks).\n */\n async function persist(orderId: string, cres: string, transStatus: string) {\n if (!orderId) return;\n try {\n const ref = db.collection(\"orders\").doc(orderId);\n const snap = await ref.get();\n const status = (snap.data() as { status?: string } | undefined)?.status;\n if (!snap.exists || status !== \"3ds-pending\") {\n logger.warn(\n \"[3ds-callback] rejected: order not in 3ds-pending state\",\n { orderId, status },\n );\n return;\n }\n const update: Record<string, unknown> = { updatedAt: new Date() };\n if (cres) update.threeDSCres = cres;\n if (transStatus) update.threeDSTransStatus = transStatus;\n await ref.update(update);\n } catch (err) {\n logger.error(\"[3ds-callback] failed to store cres on order:\", err);\n }\n }\n\n /** Resolve the final transStatus: prefer the value decoded from the CRES. */\n function resolveTransStatus(cres: string, fallback: string): string {\n if (cres) {\n const fromCres = transStatusFromCres(cres, logger);\n if (fromCres) return fromCres;\n }\n return fallback;\n }\n\n const POST = async function POST(request: Request): Promise<Response> {\n const orderId = new URL(request.url).searchParams.get(\"orderId\") || \"\";\n let transStatus = \"U\";\n let cres = \"\";\n\n try {\n const contentType = request.headers.get(\"content-type\") || \"\";\n const raw = await request.text();\n\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const obj = paramsToObject(new URLSearchParams(raw));\n transStatus = obj.transStatus || obj.TransStatus || \"U\";\n cres = pickCres(obj);\n } else {\n try {\n const body = JSON.parse(raw) as Record<string, string>;\n transStatus = body.transStatus || body.TransStatus || \"U\";\n cres = pickCres(body);\n } catch {\n // Not JSON — fall through to the urlencoded fallback below.\n }\n }\n\n // Last-resort fallback: some issuers POST urlencoded without the header.\n if (!cres && raw) {\n cres = pickCres(paramsToObject(new URLSearchParams(raw)));\n }\n } catch {\n // If we can't read the body, default to U (unknown).\n }\n\n transStatus = resolveTransStatus(cres, transStatus);\n await persist(orderId, cres, transStatus);\n return buildCompletionPage(orderId, transStatus);\n };\n\n const GET = async function GET(request: Request): Promise<Response> {\n const params = new URL(request.url).searchParams;\n const orderId = params.get(\"orderId\") || \"\";\n const cres = params.get(\"cres\") || params.get(\"CRes\") || params.get(\"value\") || \"\";\n const transStatus = resolveTransStatus(cres, params.get(\"transStatus\") || \"Y\");\n\n await persist(orderId, cres, transStatus);\n return buildCompletionPage(orderId, transStatus);\n };\n\n return { POST, GET };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/payment/3ds-complete/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Called by the client after 3DS challenge completion (via postMessage from\n// the iframe set up by the 3DS callback handler). Calls Nuvei verify API\n// (BY_CRES, BY_OTP, or AUTHENTICATION_CONTINUE), updates order status,\n// triggers post-success hook for consumer-specific side effects.\n\nimport { json, getCookie } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { z } from \"zod\";\nimport { verifyThreeDS, deleteCard } from \"../sdk.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n MinimalOrder,\n} from \"./types.js\";\n\nconst ThreeDSCompleteSchema = z.object({\n orderId: z.string().min(1),\n userId: z.string().min(1),\n type: z.enum([\"AUTHENTICATION_CONTINUE\", \"BY_CRES\", \"BY_OTP\"]),\n nuveiTransactionId: z.string().optional(),\n otpCode: z.string().optional(),\n});\n\n/** Dependencies the 3DS complete handler factory needs. */\nexport interface ThreeDSCompleteHandlerDeps {\n firebase: FirebaseDeps;\n email: Pick<EmailService, \"sendPaymentConfirmation\" | \"sendPaymentFailed\">;\n /** Optional post-success hook for consumer-specific side effects after verify succeeds. */\n onPaymentSucceeded?: (\n order: MinimalOrder & { id: string },\n ) => Promise<void>;\n /** Optional retry URL builder for payment-failed emails sent when 3DS verification fails or the auth status is rejected. If omitted, the consumer's email template default is used. */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router POST handler for the 3DS complete endpoint.\n * Called by the client after challenge completion to finalize the payment.\n */\nexport function create3dsCompleteHandler(deps: ThreeDSCompleteHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesion invalida\" }, { status: 401 });\n }\n\n const rawBody = await request.json();\n const parsed = ThreeDSCompleteSchema.safeParse(rawBody);\n if (!parsed.success) {\n return json({ error: \"Datos incompletos\" }, { status: 400 });\n }\n\n const { orderId, userId, type, nuveiTransactionId: bodyTxId, otpCode } =\n parsed.data;\n\n if (decodedToken.uid !== userId) {\n return json({ error: \"Usuario no coincide\" }, { status: 403 });\n }\n\n const orderDoc = await db.collection(\"orders\").doc(orderId).get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n\n // Idempotency: already paid → return success with stored data\n if (orderData.status === \"paid\") {\n return json({\n success: true,\n transactionId: orderData.paymentTransactionId,\n authorizationCode: orderData.authorizationCode || null,\n orderId,\n });\n }\n\n // Strong idempotency: prevent concurrent verify calls (postMessage + polling race)\n if (orderData.verifyCalledAt) {\n logger.log(\n `[3ds-complete] verify already called for order ${orderId}, returning current state`,\n );\n return json({ error: \"Pago ya procesado\" }, { status: 409 });\n }\n\n if (orderData.status !== \"3ds-pending\" && orderData.status !== \"otp-pending\") {\n return json(\n { error: \"Esta orden ya fue procesada\" },\n { status: 409 },\n );\n }\n\n // Check if the 3DS callback stored a failed transStatus\n const storedTransStatus = orderData.threeDSTransStatus as string | undefined;\n if (storedTransStatus && storedTransStatus !== \"Y\" && storedTransStatus !== \"A\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n const msg =\n storedTransStatus === \"N\"\n ? \"Autenticación 3DS rechazada por tu banco.\"\n : storedTransStatus === \"R\"\n ? \"Tu banco rechazó la autenticación 3DS.\"\n : \"No se pudo verificar la autenticación 3DS.\";\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...orderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: msg,\n items: orderData.items || [],\n total: orderData.total || 0,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n return json({ error: msg }, { status: 400 });\n }\n\n // Get transaction ID from order (preferred) or request body (fallback)\n const transactionId =\n (orderData.nuveiTransactionId as string | undefined) || bodyTxId;\n if (!transactionId) {\n return json(\n { error: \"No se encontró el ID de transacción para verificar\" },\n { status: 400 },\n );\n }\n\n // For status 36/37, verify MUST be called with BY_CRES + value. If CRES\n // hasn't arrived yet, return stillPending so the client keeps polling.\n // Device fingerprint (status 35) is allowed to call AUTHENTICATION_CONTINUE\n // without CRES because Nuvei completes it internally.\n if (\n type === \"AUTHENTICATION_CONTINUE\" &&\n !orderData.threeDSCres &&\n !orderData.isDeviceFingerprint\n ) {\n logger.log(`[3ds-complete] No CRES yet for order ${orderId} — still pending`);\n return json({ stillPending: true });\n }\n\n // Upgrade AUTHENTICATION_CONTINUE to BY_CRES if we have the CRES.\n const actualType =\n type === \"AUTHENTICATION_CONTINUE\" && orderData.threeDSCres\n ? (\"BY_CRES\" as const)\n : type;\n\n const cresValue =\n actualType === \"BY_CRES\"\n ? (orderData.threeDSCres as string | undefined)\n : undefined;\n if (actualType === \"BY_CRES\" && !cresValue) {\n return json(\n { error: \"No se encontró el valor de autenticación 3DS (cres)\" },\n { status: 400 },\n );\n }\n\n if (type === \"BY_OTP\" && !otpCode) {\n return json(\n { error: \"Debes ingresar el código OTP\" },\n { status: 400 },\n );\n }\n\n const verifyValue = type === \"BY_OTP\" ? otpCode : cresValue;\n\n const orderRef = db.collection(\"orders\").doc(orderId);\n await orderRef.update({ lastVerifyAttemptAt: new Date() });\n\n logger.log(\n `[3ds-complete] BEFORE verify: orderId=${orderId}, type=${actualType}, hasValue=${!!verifyValue}`,\n );\n const verifyResult = await verifyThreeDS({\n transactionId,\n userId,\n type: actualType,\n value: verifyValue,\n });\n logger.log(\n `[3ds-complete] AFTER verify: authCode=${verifyResult.transaction?.authorization_code ?? \"MISSING\"} status=${verifyResult.transaction?.status} detail=${verifyResult.transaction?.status_detail}`,\n );\n\n // Normalize nested vs flat response shape\n const raw = verifyResult as Record<string, unknown>;\n const txStatus = verifyResult.transaction?.status ?? raw[\"status\"];\n const txStatusDetail =\n verifyResult.transaction?.status_detail ?? raw[\"status_detail\"];\n const txId =\n verifyResult.transaction?.id ?? raw[\"transaction_id\"] ?? transactionId;\n const txAuthCode =\n verifyResult.transaction?.authorization_code ??\n raw[\"authorization_code\"] ??\n null;\n\n const isSuccess =\n (txStatus === \"success\" || txStatus === 1) && txStatusDetail === 3;\n\n const isStillPending =\n !isSuccess &&\n (txStatusDetail === 36 ||\n txStatusDetail === 37 ||\n txStatus === \"pending\");\n\n if (isStillPending) {\n logger.log(\n `[3ds-complete] Still pending: txStatus=${txStatus} detail=${txStatusDetail}. Polling continues.`,\n );\n return json({ stillPending: true });\n }\n\n if (isSuccess) {\n const hasValidAuthCode =\n typeof txAuthCode === \"string\" &&\n txAuthCode.trim().length > 0 &&\n txAuthCode !== \"null\";\n\n const batch = db.batch();\n\n if (hasValidAuthCode) {\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: txId,\n authorizationCode: txAuthCode,\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n isDeviceFingerprint: FieldValue.delete(),\n });\n } else {\n logger.error(\n `[AUDIT:MISSING_AUTH_CODE] orderId=${orderId} txId=${txId} verifyResponse=${JSON.stringify(verifyResult)}`,\n );\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: txId,\n missingAuthCodeFlagged: true,\n missingAuthCodeLoggedAt: new Date(),\n emailPending: true,\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n isDeviceFingerprint: FieldValue.delete(),\n });\n }\n\n if (orderData.promotionId) {\n const promoRef = db.collection(\"promotions\").doc(orderData.promotionId);\n batch.update(promoRef, {\n currentUses: FieldValue.increment(1),\n });\n const usageRef = promoRef.collection(\"usages\").doc();\n batch.set(usageRef, {\n userId: orderData.userId,\n orderId,\n discountApplied: orderData.discount || 0,\n usedAt: new Date(),\n });\n }\n\n await batch.commit();\n\n // Post-success hook (consumer side effects)\n if (deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderData, id: orderId });\n } catch (err) {\n logger.error(\n `[3ds-complete] onPaymentSucceeded hook failed for ${orderId}:`,\n err,\n );\n }\n }\n\n // Email confirmation only if auth_code present\n let emailSent = false;\n if (hasValidAuthCode) {\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n const emailResult = await deps.email\n .sendPaymentConfirmation({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: txId as string,\n authorizationCode: txAuthCode as string,\n items: orderData.items || [],\n subtotal: (orderData.subtotal as number) || (orderData.total as number) || 0,\n discount: (orderData.discount as number) || undefined,\n couponCode: orderData.couponCode as string | undefined,\n vat: (orderData.vat as number) || 0,\n total: (orderData.total as number) || 0,\n })\n .catch(() => ({ success: false }));\n emailSent = emailResult.success;\n if (emailSent) {\n await orderRef.update({ emailSentAt: new Date() });\n }\n }\n\n // Delete card from Nuvei if user opted out of saving\n if (orderData.deleteCardAfterPayment && orderData.paymentToken) {\n deleteCard(\n orderData.paymentToken as string,\n orderData.userId as string,\n ).catch((err) =>\n logger.error(\"[3ds-complete] Failed to delete card after payment:\", err),\n );\n }\n\n return json({\n success: true,\n transactionId: txId,\n authorizationCode: hasValidAuthCode ? txAuthCode : null,\n emailSent,\n orderId,\n });\n }\n\n // Escalation: verify after status 35 returned 36 (challenge required)\n if (txStatusDetail === 36 || txStatusDetail === 37) {\n const threeDSData = verifyResult[\"3ds\"];\n const challengeHtml =\n threeDSData?.browser_response?.challenge_request ||\n threeDSData?.browser_response?.hidden_iframe ||\n \"\";\n\n if (challengeHtml) {\n await db.collection(\"orders\").doc(orderId).update({\n nuveiTransactionId: txId,\n isDeviceFingerprint: FieldValue.delete(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n });\n\n return json({\n challenge: true,\n challengeHtml,\n isDeviceFingerprint: false,\n orderId,\n nuveiTransactionId: txId,\n statusDetail: txStatusDetail,\n });\n }\n }\n\n // Failure\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n });\n\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...orderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: \"Pago rechazado tras autenticación 3DS.\",\n items: orderData.items || [],\n total: orderData.total || 0,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n\n return json(\n { error: \"Pago rechazado tras autenticación 3DS.\" },\n { status: 400 },\n );\n } catch (error) {\n logger.error(\"3DS complete error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/payment/3ds-timeout/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Called by the frontend when the 3DS challenge times out (no postMessage\n// from the bank's ACS within ~3 minutes). Marks the order as failed and\n// sends a \"payment not completed\" email so the user knows what happened.\n// Nuvei auto-reverses the transaction server-side so no money is charged.\n\nimport { json, getCookie } from \"../http.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n MinimalOrder,\n} from \"./types.js\";\n\n/** Dependencies the 3DS timeout handler factory needs. */\nexport interface ThreeDSTimeoutHandlerDeps {\n firebase: FirebaseDeps;\n email: Pick<EmailService, \"sendPaymentFailed\">;\n /** Optional retry URL builder. Default: \"/checkout\". */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function create3dsTimeoutHandler(deps: ThreeDSTimeoutHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesion invalida\" }, { status: 401 });\n }\n\n const { orderId } = await request.json();\n if (!orderId || typeof orderId !== \"string\") {\n return json({ error: \"orderId requerido\" }, { status: 400 });\n }\n\n const orderRef = db.collection(\"orders\").doc(orderId);\n const orderDoc = await orderRef.get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n\n if (decodedToken.uid !== orderData.userId) {\n return json({ error: \"Usuario no coincide\" }, { status: 403 });\n }\n\n // Only mark as failed if still in 3ds-pending (don't override completed orders)\n if (orderData.status !== \"3ds-pending\") {\n return json({ alreadyResolved: true });\n }\n\n await orderRef.update({\n status: \"failed\",\n failureReason: \"3ds-timeout\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...orderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage:\n \"No completaste la verificación 3DS a tiempo. Tu pago no fue procesado. Intenta de nuevo.\",\n items: orderData.items || [],\n total: orderData.total || 0,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch((err) => logger.error(\"[3ds-timeout] Failed to send email:\", err));\n }\n\n return json({ ok: true });\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/payment/refund/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Customer-initiated refund. Only the order owner can refund their own\n// paid orders. Admin-side refunds (operator triggers a refund for any order)\n// can be built on top of refundTransaction() from the SDK directly.\n\nimport { json, getCookie } from \"../http.js\";\nimport { refundTransaction } from \"../sdk.js\";\nimport type { FirebaseDeps, MinimalOrder } from \"./types.js\";\n\n/** Dependencies the refund handler factory needs. */\nexport interface RefundHandlerDeps {\n firebase: FirebaseDeps;\n /** Optional hook after a successful refund (e.g. revoke course access, send email). */\n onRefundSucceeded?: (\n order: MinimalOrder & { id: string },\n ) => Promise<void>;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createRefundHandler(deps: RefundHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n const { orderId } = await request.json();\n if (!orderId) {\n return json({ error: \"orderId requerido\" }, { status: 400 });\n }\n\n const orderDoc = await db.collection(\"orders\").doc(orderId).get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n const order = (orderDoc.data() ?? {}) as MinimalOrder;\n\n // Only the order owner can request a refund\n if (order.userId !== decodedToken.uid) {\n return json(\n { error: \"No autorizado para esta orden\" },\n { status: 403 },\n );\n }\n\n if (order.status !== \"paid\") {\n return json(\n { error: \"Solo se pueden reembolsar órdenes pagadas\" },\n { status: 400 },\n );\n }\n\n const paymentTransactionId = order.paymentTransactionId as string | undefined;\n if (!paymentTransactionId) {\n return json(\n { error: \"No se encontró ID de transacción\" },\n { status: 400 },\n );\n }\n\n const result = await refundTransaction(paymentTransactionId);\n\n if (result.status === \"success\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"cancelled\",\n refundedAt: new Date(),\n updatedAt: new Date(),\n });\n\n if (deps.onRefundSucceeded) {\n try {\n await deps.onRefundSucceeded({ ...order, id: orderId });\n } catch (err) {\n logger.error(\n `[refund] onRefundSucceeded hook failed for order ${orderId}:`,\n err,\n );\n }\n }\n\n return json({ success: true, detail: result.detail });\n }\n\n return json(\n { error: result.detail || \"Error al procesar reembolso\" },\n { status: 400 },\n );\n } catch (error) {\n logger.error(\"Refund error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/init-checkout/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Initializes a Nuvei checkout reference for the PaymentCheckout modal flow.\n// Branding (theme colors, description) is now configurable per consumer.\n\nimport { json, getCookie } from \"../http.js\";\nimport crypto from \"crypto\";\nimport type { Auth } from \"firebase-admin/auth\";\nimport { nuveiRequest } from \"../sdk.js\";\n\n/** Dependencies the init-checkout handler factory needs. */\nexport interface InitCheckoutHandlerDeps {\n firebase: { auth: Auth };\n /** Default description shown to the customer in the Nuvei checkout if the request body doesn't provide one. Use the merchant name (e.g. \"Pago Acme Shop\"). */\n defaultDescription: string;\n /** Theme colors for the Nuvei checkout modal. */\n themeColors: {\n primary: string;\n secondary: string;\n };\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createInitCheckoutHandler(deps: InitCheckoutHandlerDeps) {\n const logger = deps.logger ?? console;\n const { auth } = deps.firebase;\n\n return async function POST(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n try {\n const { amount, vat, description, devReference } = await request.json();\n\n if (!amount || !devReference) {\n return json(\n { error: \"amount y devReference son requeridos\" },\n { status: 400 },\n );\n }\n\n const sessionId = crypto.randomBytes(16).toString(\"hex\");\n\n const result = await nuveiRequest<{\n reference?: string;\n checkout_url?: string;\n error?: {\n type: string;\n help: string;\n description: string;\n };\n }>(\"/v2/transaction/init_reference/\", \"POST\", {\n locale: \"es\",\n session_id: sessionId,\n order: {\n amount,\n description: description || deps.defaultDescription,\n vat: vat ?? 0,\n dev_reference: devReference,\n installments_type: 0,\n },\n user: {\n id: decodedToken.uid,\n email: decodedToken.email || \"\",\n },\n conf: {\n theme: {\n primary_color: deps.themeColors.primary,\n secondary_color: deps.themeColors.secondary,\n },\n },\n });\n\n if (result.error) {\n return json(\n { error: result.error.description || \"Error al inicializar checkout\" },\n { status: 400 },\n );\n }\n\n if (!result.reference) {\n return json(\n { error: \"No se recibió referencia de checkout\" },\n { status: 500 },\n );\n }\n\n return json({\n reference: result.reference,\n checkoutUrl: result.checkout_url,\n });\n } catch (error) {\n logger.error(\"Init checkout error:\", error);\n return json(\n { error: \"Error al inicializar checkout\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/cards/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// GET: list saved cards for the current user.\n// DELETE: delete a saved card.\n//\n// Both honor an optional \"verifiedCards\" subcollection at\n// users/{uid}/verifiedCards/{token} for cards that Nuvei still reports as\n// \"review\" status after local verification (Diners/Pichincha flow).\n\nimport { json, getCookie } from \"../http.js\";\nimport { listCards, deleteCard } from \"../sdk.js\";\nimport type { FirebaseDeps } from \"./types.js\";\n\n/** Dependencies the cards handler factory needs. */\nexport interface CardsHandlerDeps {\n firebase: FirebaseDeps;\n /** Whether to consult users/{uid}/verifiedCards to upgrade \"review\" status to \"valid\" client-side. Defaults to true. Set false if your client doesn't use the Diners/Pichincha verify flow. */\n enableVerifiedCardsTracking?: boolean;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router route module for the cards endpoint.\n * Returns `{ GET, DELETE }` to be re-exported by the consumer's route.ts.\n *\n * Usage:\n * export const { GET, DELETE } = createCardsHandler({ firebase: { db, auth } });\n */\nexport function createCardsHandler(deps: CardsHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n const verifiedCardsEnabled = deps.enableVerifiedCardsTracking !== false;\n\n async function verifySession(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) return null;\n try {\n return await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return null;\n }\n }\n\n const GET = async function GET(request: Request) {\n const decoded = await verifySession(request);\n if (!decoded) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n try {\n const result = await listCards(decoded.uid);\n\n logger.log(\n \"[cards/GET] Raw Nuvei response:\",\n JSON.stringify(\n result.cards?.map((c) => ({\n token: c.token?.slice(-6),\n status: c.status,\n type: c.type,\n number: c.number,\n })),\n ),\n );\n\n const cards = (result.cards || []).filter(\n (c) =>\n c.status === \"valid\" || c.status === \"review\" || c.status === \"pending\",\n );\n\n if (verifiedCardsEnabled && cards.some((c) => c.status === \"review\")) {\n const verifiedDoc = await db\n .collection(\"users\")\n .doc(decoded.uid)\n .collection(\"verifiedCards\")\n .get();\n const verifiedTokens = new Set(verifiedDoc.docs.map((d) => d.id));\n\n const enrichedCards = cards.map((c) =>\n c.status === \"review\" && verifiedTokens.has(c.token)\n ? { ...c, status: \"valid\" as const }\n : c,\n );\n return json({ cards: enrichedCards });\n }\n\n return json({ cards });\n } catch (error) {\n logger.error(\"Error listing cards:\", error);\n return json(\n { error: \"Error al obtener tarjetas\" },\n { status: 500 },\n );\n }\n };\n\n const DELETE = async function DELETE(request: Request) {\n const decoded = await verifySession(request);\n if (!decoded) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n try {\n const { token } = await request.json();\n if (!token) {\n return json(\n { error: \"Token de tarjeta requerido\" },\n { status: 400 },\n );\n }\n\n const result = await deleteCard(token, decoded.uid);\n logger.log(\"[cards/DELETE] Nuvei response:\", JSON.stringify(result));\n\n const resultWithError = result as { error?: unknown };\n if (resultWithError.error) {\n logger.error(\"[cards/DELETE] Nuvei delete failed:\", JSON.stringify(result));\n return json(\n { error: \"No se pudo eliminar la tarjeta en Nuvei\", detail: result },\n { status: 400 },\n );\n }\n\n if (verifiedCardsEnabled) {\n try {\n await db\n .collection(\"users\")\n .doc(decoded.uid)\n .collection(\"verifiedCards\")\n .doc(token)\n .delete();\n } catch {\n /* ignore if doesn't exist */\n }\n }\n\n return json(result);\n } catch (error) {\n logger.error(\"Error deleting card:\", error);\n return json(\n { error: \"Error al eliminar tarjeta\" },\n { status: 500 },\n );\n }\n };\n\n return { GET, DELETE };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/verify/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Verifies a tokenized card via the Nuvei micro-charge flow (required for\n// Diners/Pichincha). The user receives a small charge and inputs the value\n// to confirm card ownership.\n\nimport { json, getCookie } from \"../http.js\";\nimport { verifyCard } from \"../sdk.js\";\nimport type { FirebaseDeps } from \"./types.js\";\n\n/** Dependencies the verify handler factory needs. */\nexport interface VerifyHandlerDeps {\n firebase: FirebaseDeps;\n /** Whether to persist verification in users/{uid}/verifiedCards/{token}. Defaults to true. */\n enableVerifiedCardsTracking?: boolean;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createVerifyHandler(deps: VerifyHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n const verifiedCardsEnabled = deps.enableVerifiedCardsTracking !== false;\n\n return async function POST(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n try {\n const { cardToken, transactionReference, value } = await request.json();\n\n if ((!cardToken && !transactionReference) || !value) {\n return json(\n { error: \"transactionReference y value son requeridos\" },\n { status: 400 },\n );\n }\n\n const result = await verifyCard({\n userId: decodedToken.uid,\n transactionReference: transactionReference || cardToken,\n value,\n });\n\n if (result.error) {\n return json(\n { error: result.error.description || \"Error de verificación\" },\n { status: 400 },\n );\n }\n\n if (verifiedCardsEnabled && cardToken) {\n try {\n await db\n .collection(\"users\")\n .doc(decodedToken.uid)\n .collection(\"verifiedCards\")\n .doc(cardToken)\n .set({ verifiedAt: new Date() });\n } catch (err) {\n logger.error(\"Failed to persist verified card:\", err);\n }\n }\n\n return json({\n success: true,\n transaction: result.transaction,\n });\n } catch (error) {\n logger.error(\"Card verify error:\", error);\n return json(\n { error: \"Error al verificar tarjeta\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/test-charge/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Test-only endpoint: charges a tokenized card WITHOUT Firestore order\n// validation. Blocked when NUVEI_ENV=prod. Intended for dev/QA only.\n\nimport { json, getCookie } from \"../http.js\";\nimport type { Auth } from \"firebase-admin/auth\";\nimport { debitWithToken } from \"../sdk.js\";\n\n/** Dependencies the test-charge handler factory needs. */\nexport interface TestChargeHandlerDeps {\n firebase: { auth: Auth };\n /** Default description shown in Nuvei when the request body omits one. Defaults to \"Test charge\". */\n defaultDescription?: string;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createTestChargeHandler(deps: TestChargeHandlerDeps) {\n const logger = deps.logger ?? console;\n const { auth } = deps.firebase;\n const defaultDescription = deps.defaultDescription ?? \"Test charge\";\n\n return async function POST(request: Request) {\n if (process.env.NUVEI_ENV === \"prod\") {\n return json({ error: \"Not available\" }, { status: 404 });\n }\n\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n try {\n const { token, amount, vat, description, devReference } =\n await request.json();\n\n if (!token || !amount || !devReference) {\n return json(\n { error: \"token, amount y devReference son requeridos\" },\n { status: 400 },\n );\n }\n\n const result = await debitWithToken({\n userId: decodedToken.uid,\n userEmail: decodedToken.email || \"\",\n amount,\n description: description || defaultDescription,\n devReference,\n cardToken: token,\n vat: vat ?? 0,\n });\n\n logger.log(\"Test charge result:\", JSON.stringify(result, null, 2));\n\n if (\n result.transaction &&\n result.transaction.status === \"success\" &&\n result.transaction.status_detail === 3\n ) {\n return json({\n success: true,\n transaction: result.transaction,\n card: result.card,\n });\n }\n\n return json(\n {\n success: false,\n error:\n result.transaction?.message ||\n result.error?.description ||\n \"Pago rechazado\",\n detail: result,\n },\n { status: 400 },\n );\n } catch (error) {\n logger.error(\"Test charge error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Nuvei API proxy — framework-neutral handler.\n//\n// Some hosts can't reach Nuvei's API directly (notably Firebase App Hosting /\n// Cloud Run, which 500s on the egress). The SDK routes through a proxy when\n// the NUVEI_PROXY_URL env is set; THIS handler is the other side of that hop —\n// deploy it where egress to Nuvei works (e.g. a Cloud Function via\n// `toCloudFunction`) and point NUVEI_PROXY_URL at it.\n//\n// Ported from pauhenriques-website/functions/index.js (nuveiProxy).\n\nimport { json } from \"../http.js\";\n\nexport interface NuveiProxyHandlerDeps {\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\ninterface ProxyBody {\n path?: string;\n method?: string;\n body?: Record<string, unknown>;\n}\n\n/**\n * Creates a Web-standard POST handler that forwards `{ path, method, body }` to\n * Nuvei's REST API, attaching the caller-supplied `x-nuvei-auth-token` as the\n * `Auth-Token` header and selecting prod/stg from `x-nuvei-env`.\n *\n * Usage (Next.js): export const POST = createNuveiProxyHandler();\n * Usage (Functions): exports.nuveiProxy = onRequest({ cors: true },\n * toCloudFunction(createNuveiProxyHandler()));\n */\nexport function createNuveiProxyHandler(deps: NuveiProxyHandlerDeps = {}) {\n const logger = deps.logger ?? console;\n\n return async function POST(request: Request): Promise<Response> {\n if (request.method !== \"POST\") {\n return json({ error: \"Method not allowed\" }, { status: 405 });\n }\n\n let parsed: ProxyBody;\n try {\n parsed = (await request.json()) as ProxyBody;\n } catch {\n return json({ error: \"Invalid JSON body\" }, { status: 400 });\n }\n\n const { path, method, body: nuveiBody } = parsed;\n const authToken = request.headers.get(\"x-nuvei-auth-token\");\n\n if (!path || !method || !authToken) {\n return json(\n { error: \"Missing path, method, or x-nuvei-auth-token header\" },\n { status: 400 },\n );\n }\n\n const env = request.headers.get(\"x-nuvei-env\") || \"prod\";\n const baseUrl =\n env === \"prod\"\n ? \"https://ccapi.paymentez.com\"\n : \"https://ccapi-stg.paymentez.com\";\n const url = `${baseUrl}${path}`;\n\n try {\n const options: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Auth-Token\": authToken,\n },\n };\n if (nuveiBody && method === \"POST\") {\n options.body = JSON.stringify(nuveiBody);\n }\n\n const response = await fetch(url, options);\n const responseBody = await response.text();\n\n return new Response(responseBody, {\n status: response.status,\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n });\n } catch (err) {\n logger.error(\"[nuveiProxy] Error:\", err);\n return json(\n { error: \"Proxy error: \" + (err instanceof Error ? err.message : String(err)) },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/http.ts","../../src/sdk.ts","../../src/handlers/charge.ts","../../src/handlers/webhook.ts","../../src/handlers/3ds-callback.ts","../../src/handlers/3ds-complete.ts","../../src/handlers/3ds-timeout.ts","../../src/handlers/refund.ts","../../src/handlers/init-checkout.ts","../../src/handlers/cards.ts","../../src/handlers/verify.ts","../../src/handlers/test-charge.ts","../../src/handlers/proxy.ts"],"names":["currentOrder","currentOrderData","FieldValue","POST","GET","userEmail","crypto","DELETE"],"mappings":"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","file":"index.js","sourcesContent":["// Web-standard HTTP helpers — no framework coupling.\n//\n// The handlers operate on the Fetch API `Request`/`Response` types so they run\n// on any runtime that speaks them: Next.js App Router (NextRequest/NextResponse\n// are subtypes, so handlers drop in unchanged), Cloud Functions v2 / Express\n// (via the adapters in ./adapters), Vercel, Deno, Bun, plain Node 18+.\n\n/**\n * Build a JSON `Response`. Drop-in replacement for `NextResponse.json(data, init)`.\n * Uses manual serialization (not `Response.json`) for broadest runtime support.\n */\nexport function json(data: unknown, init?: ResponseInit): Response {\n const headers = new Headers(init?.headers);\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json; charset=utf-8\");\n }\n return new Response(JSON.stringify(data), { ...init, headers });\n}\n\n/**\n * Read a cookie value from a request's `Cookie` header. Replaces\n * `request.cookies.get(name)?.value` (which is Next-specific).\n */\nexport function getCookie(request: Request, name: string): string | undefined {\n const header = request.headers.get(\"cookie\");\n if (!header) return undefined;\n for (const part of header.split(\";\")) {\n const eq = part.indexOf(\"=\");\n if (eq === -1) continue;\n const key = part.slice(0, eq).trim();\n if (key === name) {\n return decodeURIComponent(part.slice(eq + 1).trim());\n }\n }\n return undefined;\n}\n","// Source: pauhenriques-website/src/lib/nuvei.ts\n// Phase 1 step 1.2: verbatim copy. Refactor to factory pattern (createNuveiClient) happens in step 1.3.\n\nimport crypto from \"crypto\";\n\nconst NUVEI_DOMAIN = \"paymentez.com\";\n\nfunction getBaseUrl(): string {\n const env = process.env.NUVEI_ENV === \"prod\" ? \"prod\" : \"stg\";\n return env === \"prod\"\n ? `https://ccapi.${NUVEI_DOMAIN}`\n : `https://ccapi-stg.${NUVEI_DOMAIN}`;\n}\n\n\nfunction getServerCredentials() {\n const appCode = process.env.NUVEI_SERVER_APP_CODE;\n const appKey = process.env.NUVEI_SERVER_APP_KEY;\n if (!appCode || !appKey) {\n throw new Error(\"Nuvei server credentials not configured\");\n }\n return { appCode, appKey };\n}\n\nexport function generateAuthToken(): string {\n const { appCode, appKey } = getServerCredentials();\n const timestamp = Math.floor(Date.now() / 1000);\n const uniqToken = crypto\n .createHash(\"sha256\")\n .update(`${appKey}${timestamp}`)\n .digest(\"hex\");\n return Buffer.from(`${appCode};${timestamp};${uniqToken}`).toString(\n \"base64\",\n );\n}\n\nfunction getProxyUrl(): string | null {\n return process.env.NUVEI_PROXY_URL || null;\n}\n\nexport async function nuveiRequest<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body?: Record<string, unknown>,\n): Promise<T> {\n const authToken = generateAuthToken();\n const proxyUrl = getProxyUrl();\n\n // Use Cloud Function proxy if configured (workaround for Cloud Run / Nuvei incompatibility)\n if (proxyUrl) {\n console.log(`[nuvei] ${method} ${path} via proxy`);\n const proxyResponse = await fetch(proxyUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-nuvei-auth-token\": authToken,\n \"x-nuvei-env\": process.env.NUVEI_ENV || \"stg\",\n },\n body: JSON.stringify({ path, method, body }),\n });\n if (!proxyResponse.ok) {\n const errorBody = await proxyResponse.text();\n console.error(`[nuvei] ${method} ${path} proxy failed with status ${proxyResponse.status}. Body: ${errorBody}`);\n try {\n return JSON.parse(errorBody) as T;\n } catch {\n throw new Error(`Nuvei proxy ${method} ${path} failed: ${proxyResponse.status}`);\n }\n }\n return proxyResponse.json() as Promise<T>;\n }\n\n // Direct call\n const url = `${getBaseUrl()}${path}`;\n\n const options: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Auth-Token\": authToken,\n },\n };\n\n if (body && method === \"POST\") {\n options.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, options);\n const responseText = await response.text();\n console.log(`[nuvei] ${method} ${path} → ${response.status} | body: ${responseText.slice(0, 300)}`);\n\n if (!response.ok) {\n console.error(`[nuvei] ${method} ${path} failed with status ${response.status}`);\n try {\n return JSON.parse(responseText) as T;\n } catch {\n throw new Error(`Nuvei ${method} ${path} failed: ${response.status}`);\n }\n }\n\n try {\n return JSON.parse(responseText) as T;\n } catch {\n throw new Error(`Nuvei ${method} ${path}: invalid JSON response`);\n }\n}\n\nexport async function listCards(uid: string) {\n return nuveiRequest<{\n cards: Array<{\n bin: string;\n status: string;\n token: string;\n holder_name: string;\n expiry_year: string;\n expiry_month: string;\n transaction_reference: string;\n type: string;\n number: string;\n }>;\n result_size: number;\n }>(`/v2/card/list?uid=${encodeURIComponent(uid)}`, \"GET\");\n}\n\nexport async function deleteCard(token: string, uid: string) {\n return nuveiRequest<{ message: string }>(\"/v2/card/delete/\", \"POST\", {\n card: { token },\n user: { id: uid },\n });\n}\n\nexport async function refundTransaction(transactionId: string) {\n return nuveiRequest<{\n status: string;\n detail: string;\n }>(\"/v2/transaction/refund/\", \"POST\", {\n transaction: { id: transactionId },\n });\n}\n\nexport async function verifyCard(params: {\n userId: string;\n transactionReference: string;\n value: string;\n}) {\n return nuveiRequest<{\n transaction?: {\n status: string;\n status_detail: number;\n id: string;\n message: string | null;\n };\n error?: {\n type: string;\n help: string;\n description: string;\n };\n }>(\"/v2/transaction/verify/\", \"POST\", {\n user: {\n id: params.userId,\n },\n transaction: {\n id: params.transactionReference,\n },\n type: \"BY_AMOUNT\",\n value: params.value,\n });\n}\n\nexport interface ThreeDSResponse {\n authentication: {\n status: string;\n return_code: string;\n return_message?: string;\n cavv?: string;\n eci?: string;\n xid?: string;\n reference_id?: string;\n };\n browser_response: {\n hidden_iframe?: string;\n challenge_request?: string;\n };\n sdk_response?: {\n acs_trans_id?: string;\n acs_reference_number?: string;\n };\n}\n\nexport interface DebitResponse {\n transaction?: {\n status: string;\n current_status: string;\n id: string;\n message: string | null;\n status_detail: number;\n authorization_code: string | null;\n };\n card?: {\n bin: string;\n type: string;\n number: string;\n };\n \"3ds\"?: ThreeDSResponse;\n error?: {\n type: string;\n help: string;\n description: string;\n };\n}\n\nexport async function debitWithToken(params: {\n userId: string;\n userEmail: string;\n amount: number;\n description: string;\n devReference: string;\n cardToken: string;\n cvc?: string;\n vat?: number;\n taxableAmount?: number;\n installments?: number;\n installmentsType?: number;\n browserInfo?: {\n accept_header: string;\n user_agent: string;\n language: string;\n timezone_offset: number;\n screen_width: number;\n screen_height: number;\n color_depth: number;\n js_enabled: boolean;\n java_enabled: boolean;\n ip_address?: string;\n };\n termUrl?: string;\n}) {\n const order: Record<string, unknown> = {\n amount: params.amount,\n description: params.description,\n dev_reference: params.devReference,\n vat: params.vat ?? 0,\n taxable_amount: params.taxableAmount ?? (params.amount - (params.vat ?? 0)),\n tax_percentage: 15,\n };\n\n if (params.installments && params.installments > 0) {\n order.installments = params.installments;\n order.installments_type = params.installmentsType ?? 0;\n }\n\n const body: Record<string, unknown> = {\n user: {\n id: params.userId,\n email: params.userEmail,\n },\n order,\n card: {\n token: params.cardToken,\n ...(params.cvc ? { cvc: params.cvc } : {}),\n },\n };\n\n if (params.browserInfo && params.termUrl) {\n body.extra_params = {\n threeDS2_data: {\n term_url: params.termUrl,\n device_type: \"browser\",\n },\n browser_info: params.browserInfo,\n };\n }\n\n return nuveiRequest<DebitResponse>(\"/v2/transaction/debit/\", \"POST\", body);\n}\n\n// --- 3DS Verify API ---\n\nexport interface VerifyThreeDSParams {\n transactionId: string;\n userId: string;\n type: \"AUTHENTICATION_CONTINUE\" | \"BY_CRES\" | \"BY_OTP\";\n value?: string;\n}\n\nexport async function verifyThreeDS(params: VerifyThreeDSParams): Promise<DebitResponse> {\n const body: Record<string, unknown> = {\n user: {\n id: params.userId,\n },\n transaction: { id: params.transactionId },\n type: params.type,\n value: params.value ?? \"\",\n more_info: true,\n };\n return nuveiRequest<DebitResponse>(\"/v2/transaction/verify/\", \"POST\", body);\n}\n","// Source: pauhenriques-website/src/app/api/payment/charge/route.ts\n// Phase 1 step 1.3: refactored to factory pattern createChargeHandler(deps).\n//\n// All Pau-specific logic (course retry paths, paymentLink branch, tallerId branch,\n// course enrollment) is now externalized as injectable callbacks. Consumers (Pau,\n// whitelabel clients, future custom-made sites) provide their own implementations\n// while the core charge flow (rate limit, turnstile, order validation, Nuvei debit,\n// 3DS/OTP handling, Firestore updates, email dispatch) lives here.\n\nimport { json, getCookie } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { debitWithToken, deleteCard } from \"../sdk.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n GetPriceDisplayFn,\n MinimalOrder,\n RateLimitFn,\n TurnstileFn,\n ValidateCustomOrderFn,\n} from \"./types.js\";\n\n// --- Static error message tables (Nuvei-specific, no parametrization needed) ---\n\nconst NUVEI_ERROR_MESSAGES: Record<number, string> = {\n 0: \"Error del procesador de pagos. Intenta de nuevo.\",\n // 1 = review/pending — handled separately, not shown as error\n 2: \"Error en la validación del banco. Verifica los datos de tu tarjeta.\",\n // 3 = success, not used here\n 4: \"Tarjeta rechazada por el banco. Intenta con otra tarjeta.\",\n 5: \"Transacción no permitida por el banco emisor.\",\n 6: \"Error de comunicación con el banco. Intenta en unos minutos.\",\n 7: \"Tarjeta reportada como perdida o robada. Contacta a tu banco.\",\n 8: \"Tarjeta rechazada por seguridad antifraude.\",\n 9: \"Transacción denegada por el banco. Contacta a tu banco o intenta con otra tarjeta.\",\n 10: \"La tarjeta no pudo ser procesada. Intenta con otra tarjeta.\",\n 11: \"Transacción rechazada por el sistema antifraude.\",\n 12: \"Tarjeta en lista restringida. Contacta a tu banco.\",\n 13: \"Tarjeta inválida o deshabilitada. Contacta a tu banco.\",\n 14: \"El monto excede el límite permitido por tu tarjeta.\",\n 19: \"Transacción rechazada por filtro antifraude.\",\n 20: \"Tarjeta vencida. Actualiza tu método de pago.\",\n 21: \"Código de seguridad (CVV) incorrecto.\",\n 22: \"Tipo de tarjeta no soportado para esta transacción.\",\n 23: \"Transacción rechazada. Intenta de nuevo más tarde.\",\n 31: \"Tu banco requiere verificación OTP. Ingresa el código enviado a tu teléfono.\",\n 36: \"Tu banco requiere verificación adicional 3DS. Completa el proceso en la ventana emergente.\",\n 37: \"Tu banco requiere verificación adicional 3DS. Completa el proceso en la ventana emergente.\",\n};\n\nconst THREEDS_AUTH_MESSAGES: Record<string, string> = {\n N: \"Autenticación 3DS rechazada por tu banco. Intenta con otra tarjeta.\",\n R: \"Tu banco rechazó la autenticación 3DS.\",\n U: \"No se pudo verificar la autenticación 3DS. Intenta de nuevo.\",\n};\n\nfunction getNuveiUserMessage(\n statusDetail?: number,\n rawMessage?: string | null,\n): string {\n if (statusDetail !== undefined && NUVEI_ERROR_MESSAGES[statusDetail]) {\n return NUVEI_ERROR_MESSAGES[statusDetail];\n }\n if (rawMessage?.toLowerCase().includes(\"insufficient\")) {\n return NUVEI_ERROR_MESSAGES[9]!;\n }\n if (rawMessage?.toLowerCase().includes(\"expired\")) {\n return NUVEI_ERROR_MESSAGES[20]!;\n }\n if (rawMessage?.toLowerCase().includes(\"cvv\")) {\n return NUVEI_ERROR_MESSAGES[21]!;\n }\n return \"No se pudo procesar el pago. Verifica los datos de tu tarjeta o intenta con otra.\";\n}\n\n// --- Public types ---\n\ninterface BrowserInfo {\n accept_header: string;\n user_agent: string;\n language: string;\n timezone_offset: number;\n screen_width: number;\n screen_height: number;\n color_depth: number;\n js_enabled: boolean;\n java_enabled: boolean;\n ip_address?: string;\n}\n\ninterface ChargeRequestBody {\n token: string;\n cvc?: string;\n orderId: string;\n amount: number;\n vat: number;\n description: string;\n userId: string;\n userEmail: string;\n browserInfo?: BrowserInfo;\n installments?: number;\n installmentsType?: number;\n deleteCardAfterPayment?: boolean;\n turnstileToken?: string;\n}\n\n/** Dependencies the charge handler factory needs. */\nexport interface ChargeHandlerDeps {\n /** Firebase Admin services. Provided by the consumer (so the package never owns its own Firebase init). */\n firebase: FirebaseDeps;\n /** Email service. Consumer wires up Resend (or any provider) with their own branding/templates. */\n email: EmailService;\n /** Pricing function — receives product fields and returns the effective final subtotal. Consumer-specific because pricing rules vary per business. */\n getPriceDisplay: GetPriceDisplayFn;\n /** Merchant name. Used as fallback for the Nuvei transaction description when the request body doesn't provide one (visible to the cardholder in their bank statement). */\n merchantName: string;\n /** Optional rate limit check. If omitted, no rate limiting is applied. */\n rateLimit?: RateLimitFn;\n /** Optional Turnstile (Cloudflare bot protection) verification. If omitted, the turnstileToken from the body is ignored. */\n turnstile?: TurnstileFn;\n /** Optional Cloud Functions base URL for the 3DS challenge callback (termUrl). If omitted, falls back to `process.env.CLOUD_FUNCTIONS_BASE_URL`. */\n cloudFunctionsBaseUrl?: string;\n /** Optional custom order validator — used for non-standard order flows (e.g. paymentLinks, taller-specific orders). If returned result is `{ handled: false }` the handler runs standard product/promotion validation. */\n validateCustomOrder?: ValidateCustomOrderFn;\n /** Optional post-success hook — runs after the order is marked paid and the Firestore batch commits. Use this for course enrollment, paymentLink usage tracking, fulfillment triggers, etc. Errors are caught and logged but don't fail the response. */\n onPaymentSucceeded?: (order: MinimalOrder & { id: string }) => Promise<void>;\n /** Optional retry URL builder for payment-failed emails. Receives the order, returns the URL the customer should be sent to. Default: `https://${request.host}/checkout`. */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n /** Optional logger (defaults to console). */\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router POST handler for the `/api/payment/charge` endpoint.\n *\n * Performs: session verification, rate limiting, Turnstile, order/stock/price/coupon\n * validation, Nuvei debit call, 3DS/OTP handling, Firestore order updates, email\n * dispatch, and optional post-success side effects via `onPaymentSucceeded`.\n */\nexport function createChargeHandler(deps: ChargeHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n // 1. Verify session\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesion invalida\" }, { status: 401 });\n }\n\n // 2. Client IP (used for rate limit + Turnstile remoteip hint)\n const clientIpForLimit =\n request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ||\n request.headers.get(\"x-real-ip\") ||\n \"unknown\";\n\n // 3. Rate limit (optional)\n if (deps.rateLimit) {\n const allowed = await deps.rateLimit(\n `charge:${clientIpForLimit}`,\n 10,\n 15 * 60 * 1000,\n );\n if (!allowed) {\n return json(\n { error: \"Demasiados intentos. Intentá de nuevo en unos minutos.\" },\n { status: 429 },\n );\n }\n }\n\n // 4. Parse body\n const body: ChargeRequestBody = await request.json();\n\n // 5. Turnstile (optional, but if configured, fail-closed)\n if (deps.turnstile) {\n const turnstileToken = body.turnstileToken;\n if (!turnstileToken) {\n return json(\n { error: \"Verificación de seguridad faltante. Recargá la página.\" },\n { status: 403 },\n );\n }\n const turnstileResult = await deps.turnstile(\n turnstileToken,\n clientIpForLimit === \"unknown\" ? undefined : clientIpForLimit,\n );\n if (!turnstileResult.success) {\n return json(\n { error: \"No pudimos verificar que sos humano. Recargá la página.\" },\n { status: 403 },\n );\n }\n }\n\n const {\n token,\n cvc,\n orderId,\n amount,\n vat,\n description,\n userId,\n userEmail,\n browserInfo,\n installments,\n installmentsType,\n } = body;\n\n logger.log(\"[charge] Request:\", {\n token: token?.substring(0, 10) + \"...\",\n orderId,\n amount,\n userId: userId?.substring(0, 8) + \"...\",\n });\n\n if (!token || !orderId || !amount) {\n return json({ error: \"Datos incompletos\" }, { status: 400 });\n }\n\n // 6. Verify user matches session\n if (decodedToken.uid !== userId) {\n return json({ error: \"Usuario no coincide\" }, { status: 403 });\n }\n\n // 7. Order existence + pending status\n const orderDoc = await db.collection(\"orders\").doc(orderId).get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n if (orderData.status !== \"pending\") {\n return json(\n { error: \"Esta orden ya fue procesada\" },\n { status: 409 },\n );\n }\n\n // 8. Custom order validation hook (e.g. paymentLink, tallerId flows)\n // If the consumer handles this order via a custom flow, skip standard\n // product/promotion validation entirely.\n let runStandardValidation = true;\n if (deps.validateCustomOrder) {\n const customResult = await deps.validateCustomOrder({\n orderId,\n orderData,\n amount,\n });\n if (customResult.handled) {\n if (!customResult.valid) {\n return json(\n { error: customResult.error },\n { status: customResult.status },\n );\n }\n runStandardValidation = false;\n }\n }\n\n // 9. Standard validation: stock, price, coupon\n if (runStandardValidation) {\n const orderItems = orderData.items ?? [];\n let verifiedSubtotal = 0;\n for (const item of orderItems) {\n const productDoc = await db\n .collection(\"products\")\n .doc(item.productId)\n .get();\n if (!productDoc.exists || !productDoc.data()?.isActive) {\n return json(\n { error: `El producto \"${item.name}\" ya no está disponible` },\n { status: 409 },\n );\n }\n const productData = productDoc.data()!;\n const isDigital = productData.isDigital === true;\n const stock = productData.stock ?? 0;\n if (!isDigital && stock < item.quantity) {\n return json(\n {\n error: `Stock insuficiente para \"${item.name}\" (disponible: ${stock})`,\n },\n { status: 409 },\n );\n }\n const display = deps.getPriceDisplay({\n price: productData.price ?? 0,\n autoDiscounts: productData.autoDiscounts,\n });\n const expectedItemSubtotal = display.finalSubtotal;\n if (Math.abs(expectedItemSubtotal - item.price) > 0.02) {\n return json(\n {\n error: `El precio de \"${item.name}\" cambió. Recargá la página para ver el precio actualizado.`,\n },\n { status: 409 },\n );\n }\n verifiedSubtotal += expectedItemSubtotal * item.quantity;\n }\n\n // Re-validate coupon if applied\n let verifiedDiscount = 0;\n const orderDiscount = orderData.discount ?? 0;\n const orderPromotionId = orderData.promotionId;\n\n if (orderPromotionId && orderDiscount > 0) {\n const promoDoc = await db\n .collection(\"promotions\")\n .doc(orderPromotionId)\n .get();\n if (!promoDoc.exists || !promoDoc.data()?.isActive) {\n return json(\n { error: \"El cupon aplicado ya no es valido. Remuevelo y vuelve a intentar.\" },\n { status: 409 },\n );\n }\n const promo = promoDoc.data()!;\n\n const now = new Date();\n const validFrom = promo.rules.validFrom.toDate\n ? promo.rules.validFrom.toDate()\n : new Date(promo.rules.validFrom);\n const validUntil = promo.rules.validUntil.toDate\n ? promo.rules.validUntil.toDate()\n : new Date(promo.rules.validUntil);\n if (now < validFrom || now > validUntil) {\n return json(\n { error: \"El cupon aplicado ha expirado. Remuevelo y vuelve a intentar.\" },\n { status: 409 },\n );\n }\n\n if (promo.rules.maxTotalUses && promo.currentUses >= promo.rules.maxTotalUses) {\n return json(\n { error: \"El cupon aplicado ya alcanzo su limite de usos.\" },\n { status: 409 },\n );\n }\n\n if (promo.type === \"percentage\") {\n verifiedDiscount = verifiedSubtotal * (promo.value / 100);\n if (promo.maxDiscountAmount) {\n verifiedDiscount = Math.min(verifiedDiscount, promo.maxDiscountAmount);\n }\n } else if (promo.type === \"fixed_amount\") {\n verifiedDiscount = Math.min(promo.value, verifiedSubtotal);\n }\n verifiedDiscount = Math.round(verifiedDiscount * 100) / 100;\n }\n\n const verifiedDiscountedSubtotal = Math.max(0, verifiedSubtotal - verifiedDiscount);\n const verifiedVat = Math.round(verifiedDiscountedSubtotal * 0.15 * 100) / 100;\n const verifiedTotal = Math.round((verifiedDiscountedSubtotal + verifiedVat) * 100) / 100;\n if (verifiedTotal !== amount) {\n return json(\n {\n error: \"El monto no coincide con los precios actuales. Actualiza tu carrito.\",\n },\n { status: 409 },\n );\n }\n }\n\n // 10. Build termUrl for 3DS challenge callback. Required for 3DS2 — Nuvei's\n // SDK only sends browser_info when termUrl is also present (both go in\n // extra_params.threeDS2_data). If browserInfo is provided but termUrl\n // can't be built, 3DS will silently fail; we log loud so consumers can\n // diagnose config issues fast.\n const functionsBase =\n deps.cloudFunctionsBaseUrl ?? process.env.CLOUD_FUNCTIONS_BASE_URL;\n const termUrl = functionsBase\n ? `${functionsBase}/threeDSCallback?orderId=${orderId}`\n : undefined;\n\n if (browserInfo && !termUrl) {\n logger.error(\n \"[charge] browserInfo provided but cloudFunctionsBaseUrl is not configured. 3DS challenges will not initiate. Configure ChargeHandlerDeps.cloudFunctionsBaseUrl (or CLOUD_FUNCTIONS_BASE_URL env var) pointing to your 3DS callback endpoint.\",\n );\n }\n\n // 11. Inject client IP into browserInfo for Paymentez 3DS2\n const clientIp =\n request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ||\n request.headers.get(\"x-real-ip\") ||\n \"127.0.0.1\";\n const enrichedBrowserInfo = browserInfo\n ? { ...browserInfo, ip_address: clientIp }\n : undefined;\n\n // 12. Call Nuvei debit\n const discountedSubtotalForTax = amount - (vat ?? 0);\n const nuveiData = await debitWithToken({\n userId,\n userEmail,\n amount,\n description: description || deps.merchantName,\n devReference: orderId,\n cardToken: token,\n ...(cvc ? { cvc } : {}),\n vat: vat ?? 0,\n taxableAmount: discountedSubtotalForTax,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n ...(enrichedBrowserInfo && termUrl\n ? { browserInfo: enrichedBrowserInfo, termUrl }\n : {}),\n });\n logger.log(\"[charge] Nuvei debit response FULL:\", JSON.stringify(nuveiData));\n logger.log(\n \"[charge] Nuvei debit response summary:\",\n JSON.stringify({\n status: nuveiData.transaction?.status,\n status_detail: nuveiData.transaction?.status_detail,\n id: nuveiData.transaction?.id,\n \"3ds_auth\": nuveiData[\"3ds\"]?.authentication?.status,\n error: nuveiData.error,\n }),\n );\n\n // 13a. Success path\n if (\n nuveiData.transaction &&\n nuveiData.transaction.status === \"success\" &&\n nuveiData.transaction.status_detail === 3\n ) {\n const rawAuthCode = nuveiData.transaction.authorization_code;\n const hasValidAuthCode =\n typeof rawAuthCode === \"string\" &&\n rawAuthCode.trim().length > 0 &&\n rawAuthCode !== \"null\";\n\n const batch = db.batch();\n const orderRef = db.collection(\"orders\").doc(orderId);\n\n if (hasValidAuthCode) {\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: nuveiData.transaction.id,\n authorizationCode: rawAuthCode,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n } else {\n logger.error(\n `[AUDIT:MISSING_AUTH_CODE] orderId=${orderId} txId=${nuveiData.transaction.id} debitResponse=${JSON.stringify(nuveiData)}`,\n );\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: nuveiData.transaction.id,\n missingAuthCodeFlagged: true,\n missingAuthCodeLoggedAt: new Date(),\n emailPending: true,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n }\n\n // Atomically increment promotion usage if coupon was applied\n const orderSnap = await orderRef.get();\n const orderInfo = (orderSnap.data() ?? {}) as MinimalOrder;\n if (orderInfo.promotionId) {\n const promoRef = db.collection(\"promotions\").doc(orderInfo.promotionId);\n batch.update(promoRef, {\n currentUses: FieldValue.increment(1),\n });\n\n const usageRef = promoRef.collection(\"usages\").doc();\n batch.set(usageRef, {\n userId: orderInfo.userId,\n orderId,\n discountApplied: orderInfo.discount || 0,\n usedAt: new Date(),\n });\n }\n\n await batch.commit();\n\n // Post-success hook (consumer-specific side effects: enrollment, paymentLink tracking, fulfillment triggers, etc.)\n if (deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderInfo, id: orderId });\n } catch (err) {\n logger.error(\n `[charge] onPaymentSucceeded hook failed for order ${orderId}:`,\n err,\n );\n }\n }\n\n // Send confirmation email ONLY if we have a valid auth_code.\n // Otherwise webhook or timeout handler will deliver it.\n let emailSent = false;\n if (hasValidAuthCode) {\n const emailResult = await deps.email\n .sendPaymentConfirmation({\n to: userEmail,\n customerName: orderInfo.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: nuveiData.transaction.id,\n authorizationCode: rawAuthCode as string,\n items: orderInfo.items || [],\n subtotal: orderInfo.subtotal || amount,\n discount: orderInfo.discount || undefined,\n couponCode: orderInfo.couponCode,\n vat: orderInfo.vat || vat,\n total: amount,\n ...(orderInfo.postPurchaseNote\n ? { postPurchaseNote: orderInfo.postPurchaseNote }\n : {}),\n })\n .catch(() => ({ success: false }));\n emailSent = emailResult.success;\n if (emailSent) {\n await orderRef.update({ emailSentAt: new Date() });\n }\n }\n\n // Delete card from Nuvei if user opted out of saving\n if (body.deleteCardAfterPayment && token) {\n deleteCard(token, userId).catch((err) =>\n logger.error(\"[charge] Failed to delete card after payment:\", err),\n );\n }\n\n return json({\n success: true,\n transactionId: nuveiData.transaction.id,\n authorizationCode: hasValidAuthCode ? rawAuthCode : null,\n orderId,\n emailSent,\n });\n }\n\n // 13b. Review/pending (status_detail 1)\n if (\n nuveiData.transaction?.status === \"pending\" &&\n nuveiData.transaction?.status_detail === 1\n ) {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"processing\",\n paymentTransactionId: nuveiData.transaction.id || null,\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n return json({\n review: true,\n orderId,\n transactionId: nuveiData.transaction.id,\n });\n }\n\n // Persist the consumer's opt-out + the Nuvei token so the downstream\n // handler (3ds-complete or webhook BY_CRES) can call deleteCard after\n // the payment finishes. Original Pau code didn't persist these, which\n // broke the \"do not save card\" toggle for any 3DS/OTP flow.\n const persistDeleteOnPaid = body.deleteCardAfterPayment\n ? { deleteCardAfterPayment: true, paymentToken: token }\n : {};\n\n // 13c. 3DS device fingerprint (status_detail 35) — hidden iframe, frictionless\n if (nuveiData.transaction?.status_detail === 35) {\n const threeDSData = nuveiData[\"3ds\"];\n const hiddenIframeHtml = threeDSData?.browser_response?.hidden_iframe || \"\";\n\n await db.collection(\"orders\").doc(orderId).update({\n status: \"3ds-pending\",\n isDeviceFingerprint: true,\n nuveiTransactionId: nuveiData.transaction.id || null,\n ...persistDeleteOnPaid,\n updatedAt: new Date(),\n });\n return json({\n challenge: true,\n challengeHtml: hiddenIframeHtml,\n isDeviceFingerprint: true,\n orderId,\n nuveiTransactionId: nuveiData.transaction.id,\n statusDetail: 35,\n });\n }\n\n // 13d. OTP (status_detail 31)\n if (nuveiData.transaction?.status_detail === 31) {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"otp-pending\",\n nuveiTransactionId: nuveiData.transaction.id || null,\n ...persistDeleteOnPaid,\n updatedAt: new Date(),\n });\n return json({\n otpRequired: true,\n orderId,\n nuveiTransactionId: nuveiData.transaction.id,\n statusDetail: 31,\n });\n }\n\n // 13e. 3DS challenge (status_detail 36 or 37)\n if (\n nuveiData.transaction?.status_detail === 36 ||\n nuveiData.transaction?.status_detail === 37\n ) {\n const threeDSData = nuveiData[\"3ds\"];\n const challengeHtml =\n threeDSData?.browser_response?.challenge_request ||\n threeDSData?.browser_response?.hidden_iframe ||\n \"\";\n\n // Capture any CRES/value field for verify BY_CRES (Anthony at Nuvei: value\n // for verify is returned in debit response when status_detail = 36).\n const rawDebit = nuveiData as Record<string, unknown> & {\n \"3ds\"?: Record<string, unknown> & {\n authentication?: Record<string, unknown>;\n browser_response?: Record<string, unknown>;\n };\n transaction?: Record<string, unknown>;\n };\n const debitCres: string | null =\n (rawDebit[\"3ds\"]?.authentication?.[\"cres\"] as string) ||\n (rawDebit[\"3ds\"]?.browser_response?.[\"cres\"] as string) ||\n (rawDebit[\"3ds\"]?.[\"cres\"] as string) ||\n (rawDebit.transaction?.[\"cres\"] as string) ||\n (rawDebit[\"cres\"] as string) ||\n (rawDebit[\"value\"] as string) ||\n null;\n logger.log(\n `[charge] status ${nuveiData.transaction.status_detail} — debitCres captured: ${debitCres ? \"YES (len=\" + debitCres.length + \")\" : \"NO\"}`,\n );\n\n if (challengeHtml) {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"3ds-pending\",\n nuveiTransactionId: nuveiData.transaction?.id || null,\n ...(debitCres ? { threeDSCres: debitCres } : {}),\n ...persistDeleteOnPaid,\n updatedAt: new Date(),\n });\n return json({\n challenge: true,\n challengeHtml,\n isDeviceFingerprint: false,\n orderId,\n nuveiTransactionId: nuveiData.transaction?.id,\n statusDetail: nuveiData.transaction?.status_detail,\n });\n }\n }\n\n // 13f. 3DS frictionless failure\n const threeDSStatus = nuveiData[\"3ds\"]?.authentication?.status;\n if (threeDSStatus && THREEDS_AUTH_MESSAGES[threeDSStatus]) {\n const threeDSErrorMsg = THREEDS_AUTH_MESSAGES[threeDSStatus]!;\n const currentOrder = await db.collection(\"orders\").doc(orderId).get();\n const currentOrderData = (currentOrder.data() ?? {}) as MinimalOrder;\n if (currentOrderData.status === \"pending\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n }\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...currentOrderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: currentOrderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: threeDSErrorMsg,\n items: currentOrderData.items || [],\n total: currentOrderData.total || amount,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n return json({ error: threeDSErrorMsg }, { status: 400 });\n }\n\n // 13g. Generic charge failure\n const failedErrorMsg = getNuveiUserMessage(\n nuveiData.transaction?.status_detail,\n nuveiData.transaction?.message || nuveiData.error?.description,\n );\n\n const currentOrder = await db.collection(\"orders\").doc(orderId).get();\n const currentOrderData = (currentOrder.data() ?? {}) as MinimalOrder;\n // Only downgrade if webhook hasn't already set a final status\n if (currentOrderData.status === \"pending\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n }\n\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...currentOrderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: currentOrderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: failedErrorMsg,\n items: currentOrderData.items || [],\n total: currentOrderData.total || amount,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n\n return json({ error: failedErrorMsg }, { status: 400 });\n } catch (error) {\n logger.error(\"Payment charge error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/webhooks/nuvei/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Pau's \"pn_<contributionId>\" Plan Novios branching is externalized via the\n// `handleCustomDevReference` hook — consumers detect their own custom prefixes\n// and return a Response if they handle the webhook themselves. Course\n// enrollment post-success is delegated to `onPaymentSucceeded`.\n\nimport { json } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { deleteCard, verifyThreeDS } from \"../sdk.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n MinimalOrder,\n} from \"./types.js\";\n\n/**\n * Extract CRES from webhook payload. Tries multiple possible field paths\n * because Nuvei's webhook structure for 3DS callbacks is not fully documented.\n */\nfunction extractCres(payload: unknown): string | null {\n if (!payload || typeof payload !== \"object\") return null;\n const p = payload as Record<string, unknown> & {\n \"3ds\"?: Record<string, unknown> & {\n authentication?: Record<string, unknown>;\n browser_response?: Record<string, unknown>;\n };\n transaction?: Record<string, unknown> & {\n \"3ds\"?: { authentication?: Record<string, unknown> };\n };\n };\n const candidates = [\n p[\"cres\"],\n p[\"CRes\"],\n p[\"value\"],\n p[\"3ds\"]?.authentication?.[\"cres\"],\n p[\"3ds\"]?.browser_response?.[\"cres\"],\n p[\"3ds\"]?.[\"cres\"],\n p.transaction?.[\"cres\"],\n p.transaction?.[\"3ds\"]?.authentication?.[\"cres\"],\n ];\n for (const c of candidates) {\n if (typeof c === \"string\" && c.trim().length > 0) return c;\n }\n return null;\n}\n\ninterface NuveiWebhookPayload {\n transaction: {\n id: string;\n status: string;\n status_detail: number;\n dev_reference: string;\n amount: number;\n authorization_code: string | null;\n message: string | null;\n carrier_code: string | null;\n };\n user: {\n id: string;\n email: string;\n };\n}\n\n/** Dependencies the webhook handler factory needs. */\nexport interface WebhookHandlerDeps {\n firebase: FirebaseDeps;\n email: Pick<EmailService, \"sendPaymentConfirmation\" | \"sendPaymentPending\">;\n /** Optional post-success hook. Fires when the webhook transitions an order to \"paid\" (either via direct status_detail=3 or via verify BY_CRES). Used for enrollment, fulfillment triggers, paymentLink usage tracking, etc. */\n onPaymentSucceeded?: (\n order: MinimalOrder & { id: string },\n ) => Promise<void>;\n /** Optional custom dev_reference handler. If the webhook's `transaction.dev_reference` matches a custom format (e.g. \"pn_<id>\" for Plan Novios), the consumer returns a Response and the standard order flow is skipped. Return null to fall through to standard order processing. */\n handleCustomDevReference?: (\n devReference: string,\n transaction: NuveiWebhookPayload[\"transaction\"],\n payload: NuveiWebhookPayload,\n ) => Promise<Response | null>;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router POST handler for the Nuvei webhook callback.\n * Reference: https://developers.paymentez.com/api/#webhook\n */\nexport function createWebhookHandler(deps: WebhookHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n const payload: NuveiWebhookPayload = await request.json();\n logger.log(\"[webhook] Full payload:\", JSON.stringify(payload));\n\n const { transaction } = payload;\n if (!transaction?.id || !transaction?.dev_reference) {\n return json({ error: \"Payload inválido\" }, { status: 400 });\n }\n\n const incomingCres = extractCres(payload);\n if (incomingCres) {\n logger.log(\n `[webhook] CRES present in webhook payload (len=${incomingCres.length}) for txId=${transaction.id}`,\n );\n }\n\n const devRef = transaction.dev_reference;\n\n // Hook: consumer can intercept custom dev_reference formats (e.g. Plan Novios \"pn_*\").\n if (deps.handleCustomDevReference) {\n const customResponse = await deps.handleCustomDevReference(\n devRef,\n transaction,\n payload,\n );\n if (customResponse) return customResponse;\n }\n\n // --- Standard order webhook ---\n const orderId = devRef;\n const orderRef = db.collection(\"orders\").doc(orderId);\n const orderDoc = await orderRef.get();\n\n if (!orderDoc.exists) {\n logger.error(`Webhook: Order ${orderId} not found`);\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n // If webhook brings CRES AND order is still in 3ds-pending (verify never\n // called yet), complete the 3DS flow by calling verify with BY_CRES here.\n // Covers the case where browser-side postMessage never arrived but the\n // server-to-server webhook delivered the CRES.\n const orderDataEarly = (orderDoc.data() ?? {}) as MinimalOrder;\n if (\n incomingCres &&\n orderDataEarly.status === \"3ds-pending\" &&\n !orderDataEarly.verifyCalledAt\n ) {\n try {\n await db.runTransaction(async (tx) => {\n const doc = await tx.get(orderRef);\n if (doc.data()?.verifyCalledAt) throw new Error(\"ALREADY_CALLED\");\n tx.update(orderRef, {\n verifyCalledAt: new Date(),\n threeDSCres: incomingCres,\n });\n });\n\n logger.log(`[webhook] Calling verify BY_CRES for order ${orderId}`);\n const verifyResult = await verifyThreeDS({\n transactionId:\n (orderDataEarly.nuveiTransactionId as string) || transaction.id,\n userId: orderDataEarly.userId as string,\n type: \"BY_CRES\",\n value: incomingCres,\n });\n logger.log(`[webhook] verify response: ${JSON.stringify(verifyResult)}`);\n\n const raw = verifyResult as Record<string, unknown>;\n const vStatus = verifyResult.transaction?.status ?? raw[\"status\"];\n const vDetail =\n verifyResult.transaction?.status_detail ?? raw[\"status_detail\"];\n const vAuthCode =\n verifyResult.transaction?.authorization_code ??\n raw[\"authorization_code\"] ??\n null;\n const vTxId =\n verifyResult.transaction?.id ??\n raw[\"transaction_id\"] ??\n orderDataEarly.nuveiTransactionId ??\n transaction.id;\n const verifySuccess =\n (vStatus === \"success\" || vStatus === 1) && vDetail === 3;\n\n if (verifySuccess) {\n const hasAuth =\n typeof vAuthCode === \"string\" &&\n vAuthCode.trim().length > 0 &&\n vAuthCode !== \"null\";\n\n // Use a batch so the order update + promotion-usage increment land\n // atomically. Matches charge.ts and 3ds-complete.ts. Without this,\n // a coupon used on a payment that completed via this webhook path\n // (browser stalled / postMessage never arrived) would never have\n // its currentUses incremented and could be reused indefinitely.\n const batch = db.batch();\n\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: vTxId,\n ...(hasAuth\n ? { authorizationCode: vAuthCode }\n : {\n missingAuthCodeFlagged: true,\n missingAuthCodeLoggedAt: new Date(),\n emailPending: true,\n }),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n });\n\n if (orderDataEarly.promotionId) {\n const promoRef = db\n .collection(\"promotions\")\n .doc(orderDataEarly.promotionId);\n batch.update(promoRef, {\n currentUses: FieldValue.increment(1),\n });\n const usageRef = promoRef.collection(\"usages\").doc();\n batch.set(usageRef, {\n userId: orderDataEarly.userId,\n orderId,\n discountApplied: orderDataEarly.discount || 0,\n usedAt: new Date(),\n });\n }\n\n await batch.commit();\n\n if (hasAuth && orderDataEarly.userEmail) {\n await deps.email\n .sendPaymentConfirmation({\n to: orderDataEarly.userEmail as string,\n customerName: orderDataEarly.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: vTxId as string,\n authorizationCode: vAuthCode as string,\n items: orderDataEarly.items || [],\n subtotal:\n (orderDataEarly.subtotal as number) ||\n (orderDataEarly.total as number) ||\n 0,\n discount: (orderDataEarly.discount as number) || undefined,\n couponCode: orderDataEarly.couponCode as string | undefined,\n vat: (orderDataEarly.vat as number) || 0,\n total: (orderDataEarly.total as number) || 0,\n })\n .catch(() => ({ success: false }));\n await orderRef.update({ emailSentAt: new Date() });\n }\n\n // Honor \"do not save card\" opt-out. charge.ts persisted these\n // fields when the order entered 3DS — without this call, the\n // card stays saved on the webhook BY_CRES completion path.\n if (\n orderDataEarly.deleteCardAfterPayment &&\n orderDataEarly.paymentToken\n ) {\n deleteCard(\n orderDataEarly.paymentToken as string,\n orderDataEarly.userId as string,\n ).catch((err) =>\n logger.error(\n \"[webhook] Failed to delete card after payment:\",\n err,\n ),\n );\n }\n\n if (deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderDataEarly, id: orderId });\n } catch (err) {\n logger.error(\n `[webhook] onPaymentSucceeded hook failed for ${orderId}:`,\n err,\n );\n }\n }\n\n return json({ received: true, verifiedFromWebhook: true });\n }\n } catch (err) {\n if ((err as Error).message !== \"ALREADY_CALLED\") {\n logger.error(\n `[webhook] Failed to verify BY_CRES for order ${orderId}:`,\n err,\n );\n }\n }\n }\n\n const isApproved =\n transaction.status === \"success\" && transaction.status_detail === 3;\n\n const currentStatus = orderDoc.data()?.status;\n\n // Never downgrade a \"paid\" order — webhook is idempotent\n const finalStatuses = [\"paid\", \"delivered\", \"shipped\"];\n const shouldUpdateStatus =\n isApproved || !finalStatuses.includes(currentStatus);\n\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n const webhookAuthCode = transaction.authorization_code;\n const hasValidAuthCode =\n typeof webhookAuthCode === \"string\" &&\n webhookAuthCode.trim().length > 0 &&\n webhookAuthCode !== \"null\";\n\n const updatePayload: Record<string, unknown> = {\n ...(shouldUpdateStatus && {\n status: isApproved ? \"paid\" : \"cancelled\",\n }),\n paymentTransactionId: transaction.id,\n authorizationCode: webhookAuthCode || null,\n webhookStatus: transaction.status,\n webhookStatusDetail: transaction.status_detail,\n webhookReceivedAt: new Date(),\n updatedAt: new Date(),\n };\n\n // If email was pending (verify returned success without auth_code) and\n // webhook now brings the auth_code, send the confirmation email.\n const shouldSendPendingEmail =\n isApproved &&\n orderData.emailPending === true &&\n hasValidAuthCode &&\n orderData.userEmail;\n\n if (shouldSendPendingEmail) {\n updatePayload.emailPending = FieldValue.delete();\n updatePayload.missingAuthCodeFlagged = FieldValue.delete();\n updatePayload.emailSentAt = new Date();\n }\n\n await orderRef.update(updatePayload);\n\n if (shouldSendPendingEmail) {\n try {\n await deps.email.sendPaymentConfirmation({\n to: orderData.userEmail as string,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: transaction.id,\n authorizationCode: webhookAuthCode as string,\n items: orderData.items || [],\n subtotal:\n (orderData.subtotal as number) || (orderData.total as number) || 0,\n discount: (orderData.discount as number) || undefined,\n couponCode: orderData.couponCode as string | undefined,\n vat: (orderData.vat as number) || 0,\n total: (orderData.total as number) || 0,\n });\n logger.log(`[webhook] Pending confirmation email sent for order ${orderId}`);\n } catch (err) {\n logger.error(`[webhook] Failed to send pending confirmation email:`, err);\n }\n } else if (\n isApproved &&\n orderData.emailPending === true &&\n !hasValidAuthCode &&\n orderData.userEmail\n ) {\n // Webhook approved the order but still NO auth_code — send pending email\n // (not a success confirmation). Keep flag for audit.\n logger.error(\n `[AUDIT:EMAIL_SENT_WITHOUT_AUTH_CODE] orderId=${orderId} txId=${transaction.id}`,\n );\n try {\n await deps.email.sendPaymentPending({\n to: orderData.userEmail as string,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: transaction.id,\n items: orderData.items || [],\n subtotal:\n (orderData.subtotal as number) || (orderData.total as number) || 0,\n discount: (orderData.discount as number) || undefined,\n couponCode: orderData.couponCode as string | undefined,\n vat: (orderData.vat as number) || 0,\n total: (orderData.total as number) || 0,\n });\n await orderRef.update({\n emailPending: FieldValue.delete(),\n emailSentAt: new Date(),\n });\n } catch (err) {\n logger.error(`[webhook] Failed to send pending-status email:`, err);\n }\n }\n\n const newStatus = shouldUpdateStatus\n ? isApproved\n ? \"paid\"\n : \"cancelled\"\n : currentStatus;\n logger.log(\n `Webhook: Order ${orderId} → ${newStatus} (status_detail: ${transaction.status_detail})`,\n );\n\n // Post-success hook (consumer handles enrollment, paymentLink tracking, etc.).\n // IDEMPOTENCY: fire ONLY on the real transition INTO \"paid\" from a\n // non-final state. Nuvei retries webhooks, so a retry on an already-paid\n // (or delivered/shipped) order must NOT re-run the side effects, or the\n // consumer would double-enroll / double-fulfill / double-count usage.\n // `currentStatus` is the order's status as read at the top of this\n // invocation (before the update above). The verify-BY_CRES branch above\n // is separately guarded by `verifyCalledAt` and returns early.\n const transitionedToPaid =\n newStatus === \"paid\" && !finalStatuses.includes(currentStatus);\n if (transitionedToPaid && deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderData, id: orderId });\n } catch (err) {\n logger.error(\n `[webhook] onPaymentSucceeded hook failed for ${orderId}:`,\n err,\n );\n }\n }\n\n return json({ received: true });\n } catch (error) {\n logger.error(\"Webhook processing error:\", error);\n return json(\n { error: \"Error procesando webhook\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website (functions/index.js threeDSCallback +\n// src/app/api/payment/3ds-callback/route.ts). Framework-neutral.\n//\n// The ACS (Alignet/Paymentez) calls this endpoint after the 3DS challenge\n// completes. It extracts the `cres`, persists it on the order, and returns an\n// HTML page that postMessages to the parent checkout window (no redirect —\n// Firebase App Hosting blocks 303s from API routes).\n//\n// Hosting note: on Firebase App Hosting / Cloud Run the ACS's external POST is\n// 403'd before your code runs, so deploy this as a Cloud Function via\n// `toCloudFunction` (see ../adapters) and point cloudFunctionsBaseUrl at it.\n// On Vercel/etc. mount it directly as a Next.js route.\n//\n// Public endpoint — no auth required. Paymentez sets the URL via term_url.\n\nimport type { Firestore } from \"firebase-admin/firestore\";\n\n/** Dependencies the 3DS callback handler factory needs. */\nexport interface ThreeDSCallbackHandlerDeps {\n firebase: { db: Firestore };\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Find the CRES value across the many field names / casings issuers use.\n * Alignet/Paymentez have been seen sending `cres`, `CRes`, `value`,\n * `param.value`, etc.\n */\nfunction pickCres(src: Record<string, string>): string {\n for (const key of Object.keys(src)) {\n const k = key.toLowerCase();\n if (\n k === \"cres\" ||\n k === \"cres_value\" ||\n k === \"cresvalue\" ||\n k === \"value\" ||\n k === \"param.value\" ||\n k === \"paramvalue\"\n ) {\n const v = src[key];\n if (typeof v === \"string\" && v.length > 0) return v;\n }\n }\n return src.cres || src.CRes || src.CRES || src.value || \"\";\n}\n\n/**\n * Alignet does NOT send transStatus as a separate field — it's inside the CRES\n * (base64url-encoded JSON). Decode the payload to extract the real transStatus.\n * Returns the decoded transStatus or null if it can't be decoded.\n */\nfunction transStatusFromCres(\n cres: string,\n logger: Pick<Console, \"warn\">,\n): string | null {\n try {\n const base64 = cres.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const pad = base64.length % 4;\n const padded = pad ? base64 + \"=\".repeat(4 - pad) : base64;\n const decoded = JSON.parse(\n Buffer.from(padded, \"base64\").toString(\"utf-8\"),\n );\n if (decoded && typeof decoded.transStatus === \"string\") {\n return decoded.transStatus;\n }\n } catch (e) {\n logger.warn(\n \"[3ds-callback] Could not decode CRES payload:\",\n e instanceof Error ? e.message : e,\n );\n }\n return null;\n}\n\nfunction paramsToObject(params: URLSearchParams): Record<string, string> {\n const obj: Record<string, string> = {};\n for (const [k, v] of params.entries()) obj[k] = v;\n return obj;\n}\n\nfunction buildCompletionPage(orderId: string, transStatus: string): Response {\n // Sanitize before interpolating into HTML — only allow safe characters.\n const safeOrderId = String(orderId).replace(/[^a-zA-Z0-9_-]/g, \"\");\n const safeTransStatus = String(transStatus).replace(/[^a-zA-Z0-9]/g, \"\");\n const html = `<!DOCTYPE html>\n<html><head><meta charset=\"utf-8\"><title>3DS Verification</title></head>\n<body>\n<script>\n(function() {\n var message = {\n type: \"3DS_COMPLETE\",\n orderId: \"${safeOrderId}\",\n transStatus: \"${safeTransStatus}\"\n };\n try {\n if (window.parent && window.parent !== window) {\n window.parent.postMessage(message, \"*\");\n } else if (window.opener) {\n window.opener.postMessage(message, \"*\");\n }\n } catch(e) {}\n})();\n</script>\n<p style=\"font-family:sans-serif;color:#666;text-align:center;margin-top:40px\">\nVerificando autenticación...\n</p>\n</body></html>`;\n\n return new Response(html, {\n status: 200,\n headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n });\n}\n\n/**\n * Creates the 3DS callback route handlers. Returns `{ POST, GET }` because the\n * ACS may call either depending on bank/issuer.\n *\n * Usage (Next.js): export const { POST, GET } = create3dsCallbackHandler({ firebase: { db } });\n * Usage (Functions): const { POST } = create3dsCallbackHandler({ firebase: { db } });\n * exports.threeDSCallback = onRequest({ cors: true }, toCloudFunction(POST));\n */\nexport function create3dsCallbackHandler(deps: ThreeDSCallbackHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db } = deps.firebase;\n\n /**\n * Persist the 3DS result on the order — but ONLY while the order is in\n * `3ds-pending` (prevents tampering / out-of-order callbacks).\n */\n async function persist(orderId: string, cres: string, transStatus: string) {\n if (!orderId) return;\n try {\n const ref = db.collection(\"orders\").doc(orderId);\n const snap = await ref.get();\n const status = (snap.data() as { status?: string } | undefined)?.status;\n if (!snap.exists || status !== \"3ds-pending\") {\n logger.warn(\n \"[3ds-callback] rejected: order not in 3ds-pending state\",\n { orderId, status },\n );\n return;\n }\n const update: Record<string, unknown> = { updatedAt: new Date() };\n if (cres) update.threeDSCres = cres;\n if (transStatus) update.threeDSTransStatus = transStatus;\n await ref.update(update);\n } catch (err) {\n logger.error(\"[3ds-callback] failed to store cres on order:\", err);\n }\n }\n\n /** Resolve the final transStatus: prefer the value decoded from the CRES. */\n function resolveTransStatus(cres: string, fallback: string): string {\n if (cres) {\n const fromCres = transStatusFromCres(cres, logger);\n if (fromCres) return fromCres;\n }\n return fallback;\n }\n\n const POST = async function POST(request: Request): Promise<Response> {\n const orderId = new URL(request.url).searchParams.get(\"orderId\") || \"\";\n let transStatus = \"U\";\n let cres = \"\";\n\n try {\n const contentType = request.headers.get(\"content-type\") || \"\";\n const raw = await request.text();\n\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const obj = paramsToObject(new URLSearchParams(raw));\n transStatus = obj.transStatus || obj.TransStatus || \"U\";\n cres = pickCres(obj);\n } else {\n try {\n const body = JSON.parse(raw) as Record<string, string>;\n transStatus = body.transStatus || body.TransStatus || \"U\";\n cres = pickCres(body);\n } catch {\n // Not JSON — fall through to the urlencoded fallback below.\n }\n }\n\n // Last-resort fallback: some issuers POST urlencoded without the header.\n if (!cres && raw) {\n cres = pickCres(paramsToObject(new URLSearchParams(raw)));\n }\n } catch {\n // If we can't read the body, default to U (unknown).\n }\n\n transStatus = resolveTransStatus(cres, transStatus);\n await persist(orderId, cres, transStatus);\n return buildCompletionPage(orderId, transStatus);\n };\n\n const GET = async function GET(request: Request): Promise<Response> {\n const params = new URL(request.url).searchParams;\n const orderId = params.get(\"orderId\") || \"\";\n const cres = params.get(\"cres\") || params.get(\"CRes\") || params.get(\"value\") || \"\";\n const transStatus = resolveTransStatus(cres, params.get(\"transStatus\") || \"Y\");\n\n await persist(orderId, cres, transStatus);\n return buildCompletionPage(orderId, transStatus);\n };\n\n return { POST, GET };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/payment/3ds-complete/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Called by the client after 3DS challenge completion (via postMessage from\n// the iframe set up by the 3DS callback handler). Calls Nuvei verify API\n// (BY_CRES, BY_OTP, or AUTHENTICATION_CONTINUE), updates order status,\n// triggers post-success hook for consumer-specific side effects.\n\nimport { json, getCookie } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { z } from \"zod\";\nimport { verifyThreeDS, deleteCard } from \"../sdk.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n MinimalOrder,\n} from \"./types.js\";\n\nconst ThreeDSCompleteSchema = z.object({\n orderId: z.string().min(1),\n userId: z.string().min(1),\n type: z.enum([\"AUTHENTICATION_CONTINUE\", \"BY_CRES\", \"BY_OTP\"]),\n nuveiTransactionId: z.string().optional(),\n otpCode: z.string().optional(),\n});\n\n/** Dependencies the 3DS complete handler factory needs. */\nexport interface ThreeDSCompleteHandlerDeps {\n firebase: FirebaseDeps;\n email: Pick<EmailService, \"sendPaymentConfirmation\" | \"sendPaymentFailed\">;\n /** Optional post-success hook for consumer-specific side effects after verify succeeds. */\n onPaymentSucceeded?: (\n order: MinimalOrder & { id: string },\n ) => Promise<void>;\n /** Optional retry URL builder for payment-failed emails sent when 3DS verification fails or the auth status is rejected. If omitted, the consumer's email template default is used. */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router POST handler for the 3DS complete endpoint.\n * Called by the client after challenge completion to finalize the payment.\n */\nexport function create3dsCompleteHandler(deps: ThreeDSCompleteHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesion invalida\" }, { status: 401 });\n }\n\n const rawBody = await request.json();\n const parsed = ThreeDSCompleteSchema.safeParse(rawBody);\n if (!parsed.success) {\n return json({ error: \"Datos incompletos\" }, { status: 400 });\n }\n\n const { orderId, userId, type, nuveiTransactionId: bodyTxId, otpCode } =\n parsed.data;\n\n if (decodedToken.uid !== userId) {\n return json({ error: \"Usuario no coincide\" }, { status: 403 });\n }\n\n const orderDoc = await db.collection(\"orders\").doc(orderId).get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n\n // Idempotency: already paid → return success with stored data\n if (orderData.status === \"paid\") {\n return json({\n success: true,\n transactionId: orderData.paymentTransactionId,\n authorizationCode: orderData.authorizationCode || null,\n orderId,\n });\n }\n\n // Strong idempotency: prevent concurrent verify calls (postMessage + polling race)\n if (orderData.verifyCalledAt) {\n logger.log(\n `[3ds-complete] verify already called for order ${orderId}, returning current state`,\n );\n return json({ error: \"Pago ya procesado\" }, { status: 409 });\n }\n\n if (orderData.status !== \"3ds-pending\" && orderData.status !== \"otp-pending\") {\n return json(\n { error: \"Esta orden ya fue procesada\" },\n { status: 409 },\n );\n }\n\n // Check if the 3DS callback stored a failed transStatus\n const storedTransStatus = orderData.threeDSTransStatus as string | undefined;\n if (storedTransStatus && storedTransStatus !== \"Y\" && storedTransStatus !== \"A\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n const msg =\n storedTransStatus === \"N\"\n ? \"Autenticación 3DS rechazada por tu banco.\"\n : storedTransStatus === \"R\"\n ? \"Tu banco rechazó la autenticación 3DS.\"\n : \"No se pudo verificar la autenticación 3DS.\";\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...orderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: msg,\n items: orderData.items || [],\n total: orderData.total || 0,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n return json({ error: msg }, { status: 400 });\n }\n\n // Get transaction ID from order (preferred) or request body (fallback)\n const transactionId =\n (orderData.nuveiTransactionId as string | undefined) || bodyTxId;\n if (!transactionId) {\n return json(\n { error: \"No se encontró el ID de transacción para verificar\" },\n { status: 400 },\n );\n }\n\n // For status 36/37, verify MUST be called with BY_CRES + value. If CRES\n // hasn't arrived yet, return stillPending so the client keeps polling.\n // Device fingerprint (status 35) is allowed to call AUTHENTICATION_CONTINUE\n // without CRES because Nuvei completes it internally.\n if (\n type === \"AUTHENTICATION_CONTINUE\" &&\n !orderData.threeDSCres &&\n !orderData.isDeviceFingerprint\n ) {\n logger.log(`[3ds-complete] No CRES yet for order ${orderId} — still pending`);\n return json({ stillPending: true });\n }\n\n // Upgrade AUTHENTICATION_CONTINUE to BY_CRES if we have the CRES.\n const actualType =\n type === \"AUTHENTICATION_CONTINUE\" && orderData.threeDSCres\n ? (\"BY_CRES\" as const)\n : type;\n\n const cresValue =\n actualType === \"BY_CRES\"\n ? (orderData.threeDSCres as string | undefined)\n : undefined;\n if (actualType === \"BY_CRES\" && !cresValue) {\n return json(\n { error: \"No se encontró el valor de autenticación 3DS (cres)\" },\n { status: 400 },\n );\n }\n\n if (type === \"BY_OTP\" && !otpCode) {\n return json(\n { error: \"Debes ingresar el código OTP\" },\n { status: 400 },\n );\n }\n\n const verifyValue = type === \"BY_OTP\" ? otpCode : cresValue;\n\n const orderRef = db.collection(\"orders\").doc(orderId);\n await orderRef.update({ lastVerifyAttemptAt: new Date() });\n\n logger.log(\n `[3ds-complete] BEFORE verify: orderId=${orderId}, type=${actualType}, hasValue=${!!verifyValue}`,\n );\n const verifyResult = await verifyThreeDS({\n transactionId,\n userId,\n type: actualType,\n value: verifyValue,\n });\n logger.log(\n `[3ds-complete] AFTER verify: authCode=${verifyResult.transaction?.authorization_code ?? \"MISSING\"} status=${verifyResult.transaction?.status} detail=${verifyResult.transaction?.status_detail}`,\n );\n\n // Normalize nested vs flat response shape\n const raw = verifyResult as Record<string, unknown>;\n const txStatus = verifyResult.transaction?.status ?? raw[\"status\"];\n const txStatusDetail =\n verifyResult.transaction?.status_detail ?? raw[\"status_detail\"];\n const txId =\n verifyResult.transaction?.id ?? raw[\"transaction_id\"] ?? transactionId;\n const txAuthCode =\n verifyResult.transaction?.authorization_code ??\n raw[\"authorization_code\"] ??\n null;\n\n const isSuccess =\n (txStatus === \"success\" || txStatus === 1) && txStatusDetail === 3;\n\n const isStillPending =\n !isSuccess &&\n (txStatusDetail === 36 ||\n txStatusDetail === 37 ||\n txStatus === \"pending\");\n\n if (isStillPending) {\n logger.log(\n `[3ds-complete] Still pending: txStatus=${txStatus} detail=${txStatusDetail}. Polling continues.`,\n );\n return json({ stillPending: true });\n }\n\n if (isSuccess) {\n const hasValidAuthCode =\n typeof txAuthCode === \"string\" &&\n txAuthCode.trim().length > 0 &&\n txAuthCode !== \"null\";\n\n const batch = db.batch();\n\n if (hasValidAuthCode) {\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: txId,\n authorizationCode: txAuthCode,\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n isDeviceFingerprint: FieldValue.delete(),\n });\n } else {\n logger.error(\n `[AUDIT:MISSING_AUTH_CODE] orderId=${orderId} txId=${txId} verifyResponse=${JSON.stringify(verifyResult)}`,\n );\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: txId,\n missingAuthCodeFlagged: true,\n missingAuthCodeLoggedAt: new Date(),\n emailPending: true,\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n isDeviceFingerprint: FieldValue.delete(),\n });\n }\n\n if (orderData.promotionId) {\n const promoRef = db.collection(\"promotions\").doc(orderData.promotionId);\n batch.update(promoRef, {\n currentUses: FieldValue.increment(1),\n });\n const usageRef = promoRef.collection(\"usages\").doc();\n batch.set(usageRef, {\n userId: orderData.userId,\n orderId,\n discountApplied: orderData.discount || 0,\n usedAt: new Date(),\n });\n }\n\n await batch.commit();\n\n // Post-success hook (consumer side effects)\n if (deps.onPaymentSucceeded) {\n try {\n await deps.onPaymentSucceeded({ ...orderData, id: orderId });\n } catch (err) {\n logger.error(\n `[3ds-complete] onPaymentSucceeded hook failed for ${orderId}:`,\n err,\n );\n }\n }\n\n // Email confirmation only if auth_code present\n let emailSent = false;\n if (hasValidAuthCode) {\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n const emailResult = await deps.email\n .sendPaymentConfirmation({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n transactionId: txId as string,\n authorizationCode: txAuthCode as string,\n items: orderData.items || [],\n subtotal: (orderData.subtotal as number) || (orderData.total as number) || 0,\n discount: (orderData.discount as number) || undefined,\n couponCode: orderData.couponCode as string | undefined,\n vat: (orderData.vat as number) || 0,\n total: (orderData.total as number) || 0,\n })\n .catch(() => ({ success: false }));\n emailSent = emailResult.success;\n if (emailSent) {\n await orderRef.update({ emailSentAt: new Date() });\n }\n }\n\n // Delete card from Nuvei if user opted out of saving\n if (orderData.deleteCardAfterPayment && orderData.paymentToken) {\n deleteCard(\n orderData.paymentToken as string,\n orderData.userId as string,\n ).catch((err) =>\n logger.error(\"[3ds-complete] Failed to delete card after payment:\", err),\n );\n }\n\n return json({\n success: true,\n transactionId: txId,\n authorizationCode: hasValidAuthCode ? txAuthCode : null,\n emailSent,\n orderId,\n });\n }\n\n // Escalation: verify after status 35 returned 36 (challenge required)\n if (txStatusDetail === 36 || txStatusDetail === 37) {\n const threeDSData = verifyResult[\"3ds\"];\n const challengeHtml =\n threeDSData?.browser_response?.challenge_request ||\n threeDSData?.browser_response?.hidden_iframe ||\n \"\";\n\n if (challengeHtml) {\n await db.collection(\"orders\").doc(orderId).update({\n nuveiTransactionId: txId,\n isDeviceFingerprint: FieldValue.delete(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n });\n\n return json({\n challenge: true,\n challengeHtml,\n isDeviceFingerprint: false,\n orderId,\n nuveiTransactionId: txId,\n statusDetail: txStatusDetail,\n });\n }\n }\n\n // Failure\n await db.collection(\"orders\").doc(orderId).update({\n status: \"failed\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n threeDSCres: FieldValue.delete(),\n });\n\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...orderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage: \"Pago rechazado tras autenticación 3DS.\",\n items: orderData.items || [],\n total: orderData.total || 0,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch(() => {});\n }\n\n return json(\n { error: \"Pago rechazado tras autenticación 3DS.\" },\n { status: 400 },\n );\n } catch (error) {\n logger.error(\"3DS complete error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/payment/3ds-timeout/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Called by the frontend when the 3DS challenge times out (no postMessage\n// from the bank's ACS within ~3 minutes). Marks the order as failed and\n// sends a \"payment not completed\" email so the user knows what happened.\n// Nuvei auto-reverses the transaction server-side so no money is charged.\n\nimport { json, getCookie } from \"../http.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n MinimalOrder,\n} from \"./types.js\";\n\n/** Dependencies the 3DS timeout handler factory needs. */\nexport interface ThreeDSTimeoutHandlerDeps {\n firebase: FirebaseDeps;\n email: Pick<EmailService, \"sendPaymentFailed\">;\n /** Optional retry URL builder. Default: \"/checkout\". */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function create3dsTimeoutHandler(deps: ThreeDSTimeoutHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesion invalida\" }, { status: 401 });\n }\n\n const { orderId } = await request.json();\n if (!orderId || typeof orderId !== \"string\") {\n return json({ error: \"orderId requerido\" }, { status: 400 });\n }\n\n const orderRef = db.collection(\"orders\").doc(orderId);\n const orderDoc = await orderRef.get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n const orderData = (orderDoc.data() ?? {}) as MinimalOrder;\n\n if (decodedToken.uid !== orderData.userId) {\n return json({ error: \"Usuario no coincide\" }, { status: 403 });\n }\n\n // Only mark as failed if still in 3ds-pending (don't override completed orders)\n if (orderData.status !== \"3ds-pending\") {\n return json({ alreadyResolved: true });\n }\n\n await orderRef.update({\n status: \"failed\",\n failureReason: \"3ds-timeout\",\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n });\n\n const userEmail =\n (orderData.userEmail as string) || decodedToken.email || \"\";\n if (userEmail) {\n const retryUrl = deps.getRetryUrl?.({ ...orderData, id: orderId });\n deps.email\n .sendPaymentFailed({\n to: userEmail,\n customerName: orderData.shippingAddress?.fullName || \"\",\n orderId,\n errorMessage:\n \"No completaste la verificación 3DS a tiempo. Tu pago no fue procesado. Intenta de nuevo.\",\n items: orderData.items || [],\n total: orderData.total || 0,\n ...(retryUrl ? { retryUrl } : {}),\n })\n .catch((err) => logger.error(\"[3ds-timeout] Failed to send email:\", err));\n }\n\n return json({ ok: true });\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/payment/refund/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Customer-initiated refund. Only the order owner can refund their own\n// paid orders. Admin-side refunds (operator triggers a refund for any order)\n// can be built on top of refundTransaction() from the SDK directly.\n\nimport { json, getCookie } from \"../http.js\";\nimport { refundTransaction } from \"../sdk.js\";\nimport type { FirebaseDeps, MinimalOrder } from \"./types.js\";\n\n/** Dependencies the refund handler factory needs. */\nexport interface RefundHandlerDeps {\n firebase: FirebaseDeps;\n /** Optional hook after a successful refund (e.g. revoke course access, send email). */\n onRefundSucceeded?: (\n order: MinimalOrder & { id: string },\n ) => Promise<void>;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createRefundHandler(deps: RefundHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n\n return async function POST(request: Request) {\n try {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n const { orderId } = await request.json();\n if (!orderId) {\n return json({ error: \"orderId requerido\" }, { status: 400 });\n }\n\n const orderDoc = await db.collection(\"orders\").doc(orderId).get();\n if (!orderDoc.exists) {\n return json({ error: \"Orden no encontrada\" }, { status: 404 });\n }\n\n const order = (orderDoc.data() ?? {}) as MinimalOrder;\n\n // Only the order owner can request a refund\n if (order.userId !== decodedToken.uid) {\n return json(\n { error: \"No autorizado para esta orden\" },\n { status: 403 },\n );\n }\n\n if (order.status !== \"paid\") {\n return json(\n { error: \"Solo se pueden reembolsar órdenes pagadas\" },\n { status: 400 },\n );\n }\n\n const paymentTransactionId = order.paymentTransactionId as string | undefined;\n if (!paymentTransactionId) {\n return json(\n { error: \"No se encontró ID de transacción\" },\n { status: 400 },\n );\n }\n\n const result = await refundTransaction(paymentTransactionId);\n\n if (result.status === \"success\") {\n await db.collection(\"orders\").doc(orderId).update({\n status: \"cancelled\",\n refundedAt: new Date(),\n updatedAt: new Date(),\n });\n\n if (deps.onRefundSucceeded) {\n try {\n await deps.onRefundSucceeded({ ...order, id: orderId });\n } catch (err) {\n logger.error(\n `[refund] onRefundSucceeded hook failed for order ${orderId}:`,\n err,\n );\n }\n }\n\n return json({ success: true, detail: result.detail });\n }\n\n return json(\n { error: result.detail || \"Error al procesar reembolso\" },\n { status: 400 },\n );\n } catch (error) {\n logger.error(\"Refund error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/init-checkout/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Initializes a Nuvei checkout reference for the PaymentCheckout modal flow.\n// Branding (theme colors, description) is now configurable per consumer.\n\nimport { json, getCookie } from \"../http.js\";\nimport crypto from \"crypto\";\nimport type { Auth } from \"firebase-admin/auth\";\nimport { nuveiRequest } from \"../sdk.js\";\n\n/** Dependencies the init-checkout handler factory needs. */\nexport interface InitCheckoutHandlerDeps {\n firebase: { auth: Auth };\n /** Default description shown to the customer in the Nuvei checkout if the request body doesn't provide one. Use the merchant name (e.g. \"Pago Acme Shop\"). */\n defaultDescription: string;\n /** Theme colors for the Nuvei checkout modal. */\n themeColors: {\n primary: string;\n secondary: string;\n };\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createInitCheckoutHandler(deps: InitCheckoutHandlerDeps) {\n const logger = deps.logger ?? console;\n const { auth } = deps.firebase;\n\n return async function POST(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n try {\n const { amount, vat, description, devReference } = await request.json();\n\n if (!amount || !devReference) {\n return json(\n { error: \"amount y devReference son requeridos\" },\n { status: 400 },\n );\n }\n\n const sessionId = crypto.randomBytes(16).toString(\"hex\");\n\n const result = await nuveiRequest<{\n reference?: string;\n checkout_url?: string;\n error?: {\n type: string;\n help: string;\n description: string;\n };\n }>(\"/v2/transaction/init_reference/\", \"POST\", {\n locale: \"es\",\n session_id: sessionId,\n order: {\n amount,\n description: description || deps.defaultDescription,\n vat: vat ?? 0,\n dev_reference: devReference,\n installments_type: 0,\n },\n user: {\n id: decodedToken.uid,\n email: decodedToken.email || \"\",\n },\n conf: {\n theme: {\n primary_color: deps.themeColors.primary,\n secondary_color: deps.themeColors.secondary,\n },\n },\n });\n\n if (result.error) {\n return json(\n { error: result.error.description || \"Error al inicializar checkout\" },\n { status: 400 },\n );\n }\n\n if (!result.reference) {\n return json(\n { error: \"No se recibió referencia de checkout\" },\n { status: 500 },\n );\n }\n\n return json({\n reference: result.reference,\n checkoutUrl: result.checkout_url,\n });\n } catch (error) {\n logger.error(\"Init checkout error:\", error);\n return json(\n { error: \"Error al inicializar checkout\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/cards/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// GET: list saved cards for the current user.\n// DELETE: delete a saved card.\n//\n// Both honor an optional \"verifiedCards\" subcollection at\n// users/{uid}/verifiedCards/{token} for cards that Nuvei still reports as\n// \"review\" status after local verification (Diners/Pichincha flow).\n\nimport { json, getCookie } from \"../http.js\";\nimport { listCards, deleteCard } from \"../sdk.js\";\nimport type { FirebaseDeps } from \"./types.js\";\n\n/** Dependencies the cards handler factory needs. */\nexport interface CardsHandlerDeps {\n firebase: FirebaseDeps;\n /** Whether to consult users/{uid}/verifiedCards to upgrade \"review\" status to \"valid\" client-side. Defaults to true. Set false if your client doesn't use the Diners/Pichincha verify flow. */\n enableVerifiedCardsTracking?: boolean;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\n/**\n * Creates a Next.js App Router route module for the cards endpoint.\n * Returns `{ GET, DELETE }` to be re-exported by the consumer's route.ts.\n *\n * Usage:\n * export const { GET, DELETE } = createCardsHandler({ firebase: { db, auth } });\n */\nexport function createCardsHandler(deps: CardsHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n const verifiedCardsEnabled = deps.enableVerifiedCardsTracking !== false;\n\n async function verifySession(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) return null;\n try {\n return await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return null;\n }\n }\n\n const GET = async function GET(request: Request) {\n const decoded = await verifySession(request);\n if (!decoded) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n try {\n const result = await listCards(decoded.uid);\n\n logger.log(\n \"[cards/GET] Raw Nuvei response:\",\n JSON.stringify(\n result.cards?.map((c) => ({\n token: c.token?.slice(-6),\n status: c.status,\n type: c.type,\n number: c.number,\n })),\n ),\n );\n\n const cards = (result.cards || []).filter(\n (c) =>\n c.status === \"valid\" || c.status === \"review\" || c.status === \"pending\",\n );\n\n if (verifiedCardsEnabled && cards.some((c) => c.status === \"review\")) {\n const verifiedDoc = await db\n .collection(\"users\")\n .doc(decoded.uid)\n .collection(\"verifiedCards\")\n .get();\n const verifiedTokens = new Set(verifiedDoc.docs.map((d) => d.id));\n\n const enrichedCards = cards.map((c) =>\n c.status === \"review\" && verifiedTokens.has(c.token)\n ? { ...c, status: \"valid\" as const }\n : c,\n );\n return json({ cards: enrichedCards });\n }\n\n return json({ cards });\n } catch (error) {\n logger.error(\"Error listing cards:\", error);\n return json(\n { error: \"Error al obtener tarjetas\" },\n { status: 500 },\n );\n }\n };\n\n const DELETE = async function DELETE(request: Request) {\n const decoded = await verifySession(request);\n if (!decoded) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n try {\n const { token } = await request.json();\n if (!token) {\n return json(\n { error: \"Token de tarjeta requerido\" },\n { status: 400 },\n );\n }\n\n const result = await deleteCard(token, decoded.uid);\n logger.log(\"[cards/DELETE] Nuvei response:\", JSON.stringify(result));\n\n const resultWithError = result as { error?: unknown };\n if (resultWithError.error) {\n logger.error(\"[cards/DELETE] Nuvei delete failed:\", JSON.stringify(result));\n return json(\n { error: \"No se pudo eliminar la tarjeta en Nuvei\", detail: result },\n { status: 400 },\n );\n }\n\n if (verifiedCardsEnabled) {\n try {\n await db\n .collection(\"users\")\n .doc(decoded.uid)\n .collection(\"verifiedCards\")\n .doc(token)\n .delete();\n } catch {\n /* ignore if doesn't exist */\n }\n }\n\n return json(result);\n } catch (error) {\n logger.error(\"Error deleting card:\", error);\n return json(\n { error: \"Error al eliminar tarjeta\" },\n { status: 500 },\n );\n }\n };\n\n return { GET, DELETE };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/verify/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Verifies a tokenized card via the Nuvei micro-charge flow (required for\n// Diners/Pichincha). The user receives a small charge and inputs the value\n// to confirm card ownership.\n\nimport { json, getCookie } from \"../http.js\";\nimport { verifyCard } from \"../sdk.js\";\nimport type { FirebaseDeps } from \"./types.js\";\n\n/** Dependencies the verify handler factory needs. */\nexport interface VerifyHandlerDeps {\n firebase: FirebaseDeps;\n /** Whether to persist verification in users/{uid}/verifiedCards/{token}. Defaults to true. */\n enableVerifiedCardsTracking?: boolean;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createVerifyHandler(deps: VerifyHandlerDeps) {\n const logger = deps.logger ?? console;\n const { db, auth } = deps.firebase;\n const verifiedCardsEnabled = deps.enableVerifiedCardsTracking !== false;\n\n return async function POST(request: Request) {\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n try {\n const { cardToken, transactionReference, value } = await request.json();\n\n if ((!cardToken && !transactionReference) || !value) {\n return json(\n { error: \"transactionReference y value son requeridos\" },\n { status: 400 },\n );\n }\n\n const result = await verifyCard({\n userId: decodedToken.uid,\n transactionReference: transactionReference || cardToken,\n value,\n });\n\n if (result.error) {\n return json(\n { error: result.error.description || \"Error de verificación\" },\n { status: 400 },\n );\n }\n\n if (verifiedCardsEnabled && cardToken) {\n try {\n await db\n .collection(\"users\")\n .doc(decodedToken.uid)\n .collection(\"verifiedCards\")\n .doc(cardToken)\n .set({ verifiedAt: new Date() });\n } catch (err) {\n logger.error(\"Failed to persist verified card:\", err);\n }\n }\n\n return json({\n success: true,\n transaction: result.transaction,\n });\n } catch (error) {\n logger.error(\"Card verify error:\", error);\n return json(\n { error: \"Error al verificar tarjeta\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Source: pauhenriques-website/src/app/api/nuvei/test-charge/route.ts\n// Phase 1 step 1.3: refactored to factory pattern.\n//\n// Test-only endpoint: charges a tokenized card WITHOUT Firestore order\n// validation. Blocked when NUVEI_ENV=prod. Intended for dev/QA only.\n\nimport { json, getCookie } from \"../http.js\";\nimport type { Auth } from \"firebase-admin/auth\";\nimport { debitWithToken } from \"../sdk.js\";\n\n/** Dependencies the test-charge handler factory needs. */\nexport interface TestChargeHandlerDeps {\n firebase: { auth: Auth };\n /** Default description shown in Nuvei when the request body omits one. Defaults to \"Test charge\". */\n defaultDescription?: string;\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport function createTestChargeHandler(deps: TestChargeHandlerDeps) {\n const logger = deps.logger ?? console;\n const { auth } = deps.firebase;\n const defaultDescription = deps.defaultDescription ?? \"Test charge\";\n\n return async function POST(request: Request) {\n if (process.env.NUVEI_ENV === \"prod\") {\n return json({ error: \"Not available\" }, { status: 404 });\n }\n\n const sessionCookie = getCookie(request, \"__session\");\n if (!sessionCookie || !auth) {\n return json({ error: \"No autorizado\" }, { status: 401 });\n }\n\n let decodedToken;\n try {\n decodedToken = await auth.verifySessionCookie(sessionCookie, true);\n } catch {\n return json({ error: \"Sesión inválida\" }, { status: 401 });\n }\n\n try {\n const { token, amount, vat, description, devReference } =\n await request.json();\n\n if (!token || !amount || !devReference) {\n return json(\n { error: \"token, amount y devReference son requeridos\" },\n { status: 400 },\n );\n }\n\n const result = await debitWithToken({\n userId: decodedToken.uid,\n userEmail: decodedToken.email || \"\",\n amount,\n description: description || defaultDescription,\n devReference,\n cardToken: token,\n vat: vat ?? 0,\n });\n\n logger.log(\"Test charge result:\", JSON.stringify(result, null, 2));\n\n if (\n result.transaction &&\n result.transaction.status === \"success\" &&\n result.transaction.status_detail === 3\n ) {\n return json({\n success: true,\n transaction: result.transaction,\n card: result.card,\n });\n }\n\n return json(\n {\n success: false,\n error:\n result.transaction?.message ||\n result.error?.description ||\n \"Pago rechazado\",\n detail: result,\n },\n { status: 400 },\n );\n } catch (error) {\n logger.error(\"Test charge error:\", error);\n return json(\n { error: \"Error interno del servidor\" },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n","// Nuvei API proxy — framework-neutral handler.\n//\n// Some hosts can't reach Nuvei's API directly (notably Firebase App Hosting /\n// Cloud Run, which 500s on the egress). The SDK routes through a proxy when\n// the NUVEI_PROXY_URL env is set; THIS handler is the other side of that hop —\n// deploy it where egress to Nuvei works (e.g. a Cloud Function via\n// `toCloudFunction`) and point NUVEI_PROXY_URL at it.\n//\n// Ported from pauhenriques-website/functions/index.js (nuveiProxy).\n\nimport { json } from \"../http.js\";\n\nexport interface NuveiProxyHandlerDeps {\n logger?: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\ninterface ProxyBody {\n path?: string;\n method?: string;\n body?: Record<string, unknown>;\n}\n\n/**\n * Creates a Web-standard POST handler that forwards `{ path, method, body }` to\n * Nuvei's REST API, attaching the caller-supplied `x-nuvei-auth-token` as the\n * `Auth-Token` header and selecting prod/stg from `x-nuvei-env`.\n *\n * Usage (Next.js): export const POST = createNuveiProxyHandler();\n * Usage (Functions): exports.nuveiProxy = onRequest({ cors: true },\n * toCloudFunction(createNuveiProxyHandler()));\n */\nexport function createNuveiProxyHandler(deps: NuveiProxyHandlerDeps = {}) {\n const logger = deps.logger ?? console;\n\n return async function POST(request: Request): Promise<Response> {\n if (request.method !== \"POST\") {\n return json({ error: \"Method not allowed\" }, { status: 405 });\n }\n\n let parsed: ProxyBody;\n try {\n parsed = (await request.json()) as ProxyBody;\n } catch {\n return json({ error: \"Invalid JSON body\" }, { status: 400 });\n }\n\n const { path, method, body: nuveiBody } = parsed;\n const authToken = request.headers.get(\"x-nuvei-auth-token\");\n\n if (!path || !method || !authToken) {\n return json(\n { error: \"Missing path, method, or x-nuvei-auth-token header\" },\n { status: 400 },\n );\n }\n\n const env = request.headers.get(\"x-nuvei-env\") || \"prod\";\n const baseUrl =\n env === \"prod\"\n ? \"https://ccapi.paymentez.com\"\n : \"https://ccapi-stg.paymentez.com\";\n const url = `${baseUrl}${path}`;\n\n try {\n const options: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Auth-Token\": authToken,\n },\n };\n if (nuveiBody && method === \"POST\") {\n options.body = JSON.stringify(nuveiBody);\n }\n\n const response = await fetch(url, options);\n const responseBody = await response.text();\n\n return new Response(responseBody, {\n status: response.status,\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n });\n } catch (err) {\n logger.error(\"[nuveiProxy] Error:\", err);\n return json(\n { error: \"Proxy error: \" + (err instanceof Error ? err.message : String(err)) },\n { status: 500 },\n );\n }\n };\n}\n\nexport const dynamic = \"force-dynamic\";\n"]}
|