@pandait.tech/payment-nuvei 1.1.2 → 1.1.4
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/http.ts","../../src/sdk.ts","../../src/handlers/charge/validate-order.ts","../../src/handlers/charge/finalize-success.ts","../../src/handlers/charge/error-messages.ts","../../src/handlers/charge/handle-3ds-results.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":["crypto","FieldValue","currentOrder","currentOrderData","POST","GET","z","userEmail","DELETE"],"mappings":"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","file":"index.cjs","sourcesContent":["// Web-standard HTTP helpers — no framework coupling.\n\nimport crypto from \"crypto\";\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 * Constant-time string comparison. Returns false for length mismatches without\n * leaking timing. Use for comparing secrets (e.g. webhook keys) to avoid\n * timing side-channels.\n */\nexport function timingSafeEqualStr(a: string, b: string): boolean {\n const ab = Buffer.from(a, \"utf8\");\n const bb = Buffer.from(b, \"utf8\");\n if (ab.length !== bb.length) {\n // Still run a comparison against a same-length buffer to keep timing flat.\n crypto.timingSafeEqual(ab, ab);\n return false;\n }\n return crypto.timingSafeEqual(ab, bb);\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","// Validación estándar de la orden: stock, precio por ítem y cupón/promoción.\n// Extraído de charge.ts (M1b) sin cambios de comportamiento.\n//\n// Devuelve una `Response` (vía json) cuando la validación falla — el orquestador\n// la retorna tal cual. Devuelve `null` cuando todo es válido y el flujo continúa.\n\nimport type { Firestore } from \"firebase-admin/firestore\";\nimport { json } from \"../../http.js\";\nimport type { GetPriceDisplayFn, MinimalOrder } from \"../types.js\";\n\nexport interface ValidateStandardOrderArgs {\n db: Firestore;\n getPriceDisplay: GetPriceDisplayFn;\n orderData: MinimalOrder;\n amount: number;\n}\n\nexport async function validateStandardOrder({\n db,\n getPriceDisplay,\n orderData,\n amount,\n}: ValidateStandardOrderArgs): Promise<Response | null> {\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 = 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 return null;\n}\n","// Finalización de una orden \"pagada\" (camino de éxito, status_detail 3).\n// Extraído de charge.ts (M1b) sin cambios de comportamiento.\n//\n// Concentra la lógica de dinero crítica: marca la orden como `paid` (con o sin\n// auth_code válido), incrementa el uso del cupón de forma atómica, ejecuta el\n// hook post-éxito, envía el email de confirmación y elimina la tarjeta si el\n// usuario optó por no guardarla. Devuelve los hechos computados; el orquestador\n// (charge.ts) arma la respuesta HTTP. Diseñado para que webhook.ts y\n// 3ds-complete.ts lo adopten en M1c (por eso no depende de la capa HTTP).\n\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport type { Firestore } from \"firebase-admin/firestore\";\nimport { deleteCard } from \"../../sdk.js\";\nimport type { EmailService, MinimalOrder } from \"../types.js\";\n\nexport interface FinalizePaidOrderDeps {\n db: Firestore;\n /** Solo se usa sendPaymentConfirmation aquí. */\n email: Pick<EmailService, \"sendPaymentConfirmation\">;\n /** Hook post-éxito opcional (enrollment, tracking de paymentLink, fulfillment, etc.). */\n onPaymentSucceeded?: (order: MinimalOrder & { id: string }) => Promise<void>;\n logger: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport interface FinalizePaidOrderCtx {\n orderId: string;\n /** id de la transacción Nuvei (nuveiData.transaction.id). */\n transactionId: string;\n /** authorization_code crudo devuelto por Nuvei. */\n rawAuthCode: string | null;\n /** Respuesta cruda (débito o verify) que se vuelca en el log de auditoría si falta el auth_code. */\n debitResponse?: unknown;\n /**\n * Etiqueta del objeto crudo en el log `[AUDIT:MISSING_AUTH_CODE]`. charge.ts usa\n * el default `\"debitResponse\"`; los flujos 3DS pasan `\"verifyResponse\"` para que\n * el log refleje de dónde vino la respuesta. No cambia el comportamiento de charge.\n */\n auditResponseLabel?: string;\n installments?: number;\n installmentsType?: number;\n userId: string;\n userEmail: string;\n vat: number;\n amount: number;\n token: string;\n deleteCardAfterPayment?: boolean;\n /**\n * Campos extra a fusionar en el `batch.update` de la orden (ambas ramas:\n * con y sin auth_code). El flujo 3DS los usa para limpiar el estado intermedio\n * (`threeDSCres`, `threeDSTransStatus`, `isDeviceFingerprint`). charge.ts no los\n * pasa → el batch queda idéntico al original.\n */\n extraOrderFields?: Record<string, unknown>;\n /**\n * Datos de la orden ya leídos por el caller. Si se pasan, se evita el re-read\n * desde Firestore (los flujos 3DS/webhook ya tienen la orden en mano). Si se\n * omite, finalize la lee (comportamiento original de charge.ts).\n */\n preReadOrder?: MinimalOrder;\n /**\n * Si es `false`, el email de confirmación NO incluye `postPurchaseNote` aunque\n * la orden lo tenga. Default `true` (comportamiento de charge.ts). El flujo 3DS\n * pasa `false` para conservar su comportamiento original.\n */\n includePostPurchaseNote?: boolean;\n}\n\nexport interface FinalizePaidOrderResult {\n transactionId: string;\n authorizationCode: string | null;\n emailSent: boolean;\n}\n\nexport async function finalizePaidOrder(\n deps: FinalizePaidOrderDeps,\n ctx: FinalizePaidOrderCtx,\n): Promise<FinalizePaidOrderResult> {\n const { db, logger } = deps;\n const {\n orderId,\n transactionId,\n rawAuthCode,\n debitResponse,\n auditResponseLabel,\n installments,\n installmentsType,\n userId,\n userEmail,\n vat,\n amount,\n token,\n deleteCardAfterPayment,\n extraOrderFields,\n preReadOrder,\n includePostPurchaseNote,\n } = ctx;\n\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: transactionId,\n authorizationCode: rawAuthCode,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n ...(extraOrderFields ?? {}),\n });\n } else {\n logger.error(\n `[AUDIT:MISSING_AUTH_CODE] orderId=${orderId} txId=${transactionId} ${auditResponseLabel ?? \"debitResponse\"}=${JSON.stringify(debitResponse)}`,\n );\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: transactionId,\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 ...(extraOrderFields ?? {}),\n });\n }\n\n // Atomically increment promotion usage if coupon was applied.\n // Reusa la orden ya leída por el caller (preReadOrder) cuando esté disponible;\n // de lo contrario la relee (comportamiento original de charge.ts).\n const orderInfo =\n preReadOrder ?? ((await orderRef.get()).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,\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 ...(includePostPurchaseNote !== false && 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 (deleteCardAfterPayment && token) {\n deleteCard(token, userId).catch((err) =>\n logger.error(\"[charge] Failed to delete card after payment:\", err),\n );\n }\n\n return {\n transactionId,\n authorizationCode: hasValidAuthCode ? rawAuthCode : null,\n emailSent,\n };\n}\n","// Tablas de mensajes de error de Nuvei + el mapeo de status_detail a mensaje de\n// usuario. Extraído de charge.ts (M1b) sin cambios de comportamiento.\n\n// --- Tablas estáticas de mensajes de error (específicas de Nuvei, sin parametrizar) ---\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\nexport const 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\nexport function 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","// Ruteo de todos los resultados de Nuvei que NO son el éxito directo (status_detail 3):\n// review/pending, fingerprint de dispositivo, OTP, challenge 3DS y los fallos\n// (frictionless y genérico). Extraído de charge.ts (M1b) sin cambios de\n// comportamiento. Siempre devuelve una `Response`.\n\nimport { json } from \"../../http.js\";\nimport type { Firestore } from \"firebase-admin/firestore\";\nimport type { DebitResponse } from \"../../sdk.js\";\nimport type { EmailService, MinimalOrder } from \"../types.js\";\nimport { THREEDS_AUTH_MESSAGES, getNuveiUserMessage } from \"./error-messages.js\";\n\nexport interface HandleNonSuccessDeps {\n db: Firestore;\n /** Solo se usa sendPaymentFailed en los caminos de fallo. */\n email: Pick<EmailService, \"sendPaymentFailed\">;\n /** Constructor opcional de la URL de reintento para el email de pago fallido. */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n logger: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport interface HandleNonSuccessCtx {\n nuveiData: DebitResponse;\n orderId: string;\n userEmail: string;\n amount: number;\n token: string;\n deleteCardAfterPayment?: boolean;\n}\n\nexport async function handleNonSuccessResult(\n deps: HandleNonSuccessDeps,\n ctx: HandleNonSuccessCtx,\n): Promise<Response> {\n const { db, logger } = deps;\n const { nuveiData, orderId, userEmail, amount, token, deleteCardAfterPayment } =\n ctx;\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 = 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}\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 { debitWithToken } from \"../sdk.js\";\nimport { validateStandardOrder } from \"./charge/validate-order.js\";\nimport { finalizePaidOrder } from \"./charge/finalize-success.js\";\nimport { handleNonSuccessResult } from \"./charge/handle-3ds-results.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n GetPriceDisplayFn,\n MinimalOrder,\n RateLimitFn,\n TurnstileFn,\n ValidateCustomOrderFn,\n} from \"./types.js\";\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 /** Taxed base, when part of `amount` is NOT subject to tax (e.g. shipping).\n * Nuvei rejects the debit unless `taxableAmount * tax_percentage === vat`.\n * Omit it and it falls back to `amount - vat`, which is only correct when\n * the whole amount is taxed. */\n taxableAmount?: 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 taxableAmount,\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 validationError = await validateStandardOrder({\n db,\n getPriceDisplay: deps.getPriceDisplay,\n orderData,\n amount,\n });\n if (validationError) {\n return validationError;\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 // `amount - vat` assumes every cent of the charge is taxed. That breaks as soon as\n // the order carries a non-taxable line (shipping, tips): Nuvei checks\n // `taxable_amount * tax_percentage === vat` and rejects the debit with\n // OperationNotAllowedError / \"order.vat Invalid\". Callers with such a line send\n // the taxed base explicitly.\n const discountedSubtotalForTax = taxableAmount ?? 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(\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 finalizeResult = await finalizePaidOrder(\n {\n db,\n email: deps.email,\n onPaymentSucceeded: deps.onPaymentSucceeded,\n logger,\n },\n {\n orderId,\n transactionId: nuveiData.transaction.id,\n rawAuthCode: nuveiData.transaction.authorization_code,\n debitResponse: nuveiData,\n installments,\n installmentsType,\n userId,\n userEmail,\n vat,\n amount,\n token,\n deleteCardAfterPayment: body.deleteCardAfterPayment,\n },\n );\n\n return json({\n success: true,\n transactionId: finalizeResult.transactionId,\n authorizationCode: finalizeResult.authorizationCode,\n orderId,\n emailSent: finalizeResult.emailSent,\n });\n }\n\n // 13b–13g. Resto de resultados Nuvei (review / fingerprint / OTP /\n // challenge / fallos). Siempre devuelve una Response.\n return handleNonSuccessResult(\n {\n db,\n email: deps.email,\n getRetryUrl: deps.getRetryUrl,\n logger,\n },\n {\n nuveiData,\n orderId,\n userEmail,\n amount,\n token,\n deleteCardAfterPayment: body.deleteCardAfterPayment,\n },\n );\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, timingSafeEqualStr } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { verifyThreeDS } from \"../sdk.js\";\nimport { finalizePaidOrder } from \"./charge/finalize-success.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 /**\n * Shared secret used to authenticate the incoming webhook. Paymentez/Nuvei\n * DMNs are NOT signed, so the only robust auth is a secret the merchant\n * embeds in the DMN URL configured in the Nuvei dashboard, e.g.\n * `https://shop.com/api/webhooks/nuvei?key=THE_SECRET` (also accepted as the\n * `x-webhook-key` header). Falls back to `process.env.NUVEI_WEBHOOK_SECRET`.\n *\n * If set, requests without a matching key are rejected with 401. If unset,\n * the handler logs a loud warning and processes anyway (the endpoint is then\n * forgeable — anyone who knows an orderId could fake a \"paid\" notification).\n * STRONGLY RECOMMENDED in production.\n */\n webhookSecret?: string;\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 const expectedSecret = deps.webhookSecret ?? process.env.NUVEI_WEBHOOK_SECRET;\n\n return async function POST(request: Request) {\n try {\n // Authenticate the webhook. Paymentez/Nuvei DMNs are unsigned, so the\n // only robust auth is a shared secret the merchant embeds in the DMN URL\n // (?key=...) or sends as the x-webhook-key header. Reject mismatches; if\n // no secret is configured, warn loudly and process (forgeable).\n if (expectedSecret) {\n const provided =\n new URL(request.url).searchParams.get(\"key\") ??\n request.headers.get(\"x-webhook-key\") ??\n \"\";\n if (!timingSafeEqualStr(provided, expectedSecret)) {\n logger.warn(\"[webhook] rejected: missing/invalid webhook secret\");\n return json({ error: \"Unauthorized\" }, { status: 401 });\n }\n } else {\n logger.warn(\n \"[webhook] NUVEI_WEBHOOK_SECRET is not configured — this endpoint is UNAUTHENTICATED and forgeable. Set a secret (deps.webhookSecret or env) and append it to your DMN URL as ?key=... before going to production.\",\n );\n }\n\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 // Adopta el modulo compartido finalizePaidOrder (mismo que charge.ts\n // y 3ds-complete.ts). Se le pasa la orden ya leida (preReadOrder)\n // para no releer Firestore, los campos extra threeDSCres/\n // threeDSTransStatus que este camino BY_CRES borraba inline, la\n // etiqueta de auditoria \"verifyResponse\" (la respuesta cruda es la\n // de verify, no la de debit) e includePostPurchaseNote=false (este\n // flujo nunca lo incluia). vat=0 y amount=total replican los\n // fallbacks del email original.\n await finalizePaidOrder(\n { db, email: deps.email, onPaymentSucceeded: deps.onPaymentSucceeded, logger },\n {\n orderId,\n transactionId: vTxId as string,\n rawAuthCode: (vAuthCode as string | null) ?? null,\n debitResponse: verifyResult,\n auditResponseLabel: \"verifyResponse\",\n userId: orderDataEarly.userId as string,\n userEmail: (orderDataEarly.userEmail as string) || \"\",\n vat: 0,\n amount: (orderDataEarly.total as number) || 0,\n token: orderDataEarly.paymentToken as string,\n deleteCardAfterPayment: orderDataEarly.deleteCardAfterPayment as boolean | undefined,\n preReadOrder: orderDataEarly,\n includePostPurchaseNote: false,\n extraOrderFields: {\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\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 // \"refunded\" belongs here too: refunding calls Nuvei, and Nuvei then sends a DMN for\n // the reversed transaction (status 2 / detail 7, current_status CANCELLED). That DMN\n // is not \"approved\", so without this the refund the merchant just issued gets\n // overwritten with \"cancelled\" seconds later — losing the difference between money\n // paid back and an order that never went through.\n const finalStatuses = [\"paid\", \"delivered\", \"shipped\", \"refunded\"];\n\n // Un DMN de \"autenticación pendiente\" no es un resultado: avisa que el cliente TODAVÍA\n // está en la pantalla de su banco. Tratarlo como \"no aprobado\" cancelaba el pedido a\n // mitad del challenge, y cuando el cliente terminaba de autenticarse ya no había pedido\n // que cobrar. Medido en el staging de Tálou el 2026-09-24: debit a las 20:56:09 con\n // status_detail 36, y el pedido en \"cancelled\" a las 20:56:28 — 19 segundos, con el\n // cliente aún en el banco.\n //\n // Number() a propósito: el débito devuelve status_detail numérico (3) pero el DMN lo\n // manda como string (\"36\"), y una comparación estricta no vería ninguno de los dos.\n const statusDetail = Number(transaction.status_detail);\n const isAuthPending = statusDetail === 36 || statusDetail === 37;\n\n const shouldUpdateStatus =\n isApproved || (!isAuthPending && !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 } from \"../sdk.js\";\nimport { finalizePaidOrder } from \"./charge/finalize-success.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 // Adopta el modulo compartido finalizePaidOrder (mismo que charge.ts).\n // Comportamiento identico al inline anterior: se le pasa la orden ya\n // leida (preReadOrder) para no releer Firestore, los campos extra para\n // limpiar el estado 3DS, la etiqueta de auditoria \"verifyResponse\" y\n // includePostPurchaseNote=false (este flujo nunca lo incluia). vat=0 y\n // amount=total replican los fallbacks del email original.\n const finalizeResult = await finalizePaidOrder(\n {\n db,\n email: deps.email,\n onPaymentSucceeded: deps.onPaymentSucceeded,\n logger,\n },\n {\n orderId,\n transactionId: txId as string,\n rawAuthCode: txAuthCode as string | null,\n debitResponse: verifyResult,\n auditResponseLabel: \"verifyResponse\",\n userId: orderData.userId as string,\n userEmail:\n (orderData.userEmail as string) || decodedToken.email || \"\",\n vat: 0,\n amount: (orderData.total as number) || 0,\n token: orderData.paymentToken as string,\n deleteCardAfterPayment: orderData.deleteCardAfterPayment,\n preReadOrder: orderData,\n includePostPurchaseNote: false,\n extraOrderFields: {\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n isDeviceFingerprint: FieldValue.delete(),\n },\n },\n );\n\n return json({\n success: true,\n transactionId: finalizeResult.transactionId,\n authorizationCode: finalizeResult.authorizationCode,\n emailSent: finalizeResult.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/validate-order.ts","../../src/handlers/charge/finalize-success.ts","../../src/handlers/charge/error-messages.ts","../../src/handlers/charge/handle-3ds-results.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":["crypto","FieldValue","currentOrder","currentOrderData","POST","GET","z","userEmail","DELETE"],"mappings":"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","file":"index.cjs","sourcesContent":["// Web-standard HTTP helpers — no framework coupling.\n\nimport crypto from \"crypto\";\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 * Constant-time string comparison. Returns false for length mismatches without\n * leaking timing. Use for comparing secrets (e.g. webhook keys) to avoid\n * timing side-channels.\n */\nexport function timingSafeEqualStr(a: string, b: string): boolean {\n const ab = Buffer.from(a, \"utf8\");\n const bb = Buffer.from(b, \"utf8\");\n if (ab.length !== bb.length) {\n // Still run a comparison against a same-length buffer to keep timing flat.\n crypto.timingSafeEqual(ab, ab);\n return false;\n }\n return crypto.timingSafeEqual(ab, bb);\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","// Validación estándar de la orden: stock, precio por ítem y cupón/promoción.\n// Extraído de charge.ts (M1b) sin cambios de comportamiento.\n//\n// Devuelve una `Response` (vía json) cuando la validación falla — el orquestador\n// la retorna tal cual. Devuelve `null` cuando todo es válido y el flujo continúa.\n\nimport type { Firestore } from \"firebase-admin/firestore\";\nimport { json } from \"../../http.js\";\nimport type { GetPriceDisplayFn, MinimalOrder } from \"../types.js\";\n\nexport interface ValidateStandardOrderArgs {\n db: Firestore;\n getPriceDisplay: GetPriceDisplayFn;\n orderData: MinimalOrder;\n amount: number;\n}\n\nexport async function validateStandardOrder({\n db,\n getPriceDisplay,\n orderData,\n amount,\n}: ValidateStandardOrderArgs): Promise<Response | null> {\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 = 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 return null;\n}\n","// Finalización de una orden \"pagada\" (camino de éxito, status_detail 3).\n// Extraído de charge.ts (M1b) sin cambios de comportamiento.\n//\n// Concentra la lógica de dinero crítica: marca la orden como `paid` (con o sin\n// auth_code válido), incrementa el uso del cupón de forma atómica, ejecuta el\n// hook post-éxito, envía el email de confirmación y elimina la tarjeta si el\n// usuario optó por no guardarla. Devuelve los hechos computados; el orquestador\n// (charge.ts) arma la respuesta HTTP. Diseñado para que webhook.ts y\n// 3ds-complete.ts lo adopten en M1c (por eso no depende de la capa HTTP).\n\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport type { Firestore } from \"firebase-admin/firestore\";\nimport { deleteCard } from \"../../sdk.js\";\nimport type { EmailService, MinimalOrder } from \"../types.js\";\n\nexport interface FinalizePaidOrderDeps {\n db: Firestore;\n /** Solo se usa sendPaymentConfirmation aquí. */\n email: Pick<EmailService, \"sendPaymentConfirmation\">;\n /** Hook post-éxito opcional (enrollment, tracking de paymentLink, fulfillment, etc.). */\n onPaymentSucceeded?: (order: MinimalOrder & { id: string }) => Promise<void>;\n logger: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport interface FinalizePaidOrderCtx {\n orderId: string;\n /** id de la transacción Nuvei (nuveiData.transaction.id). */\n transactionId: string;\n /** authorization_code crudo devuelto por Nuvei. */\n rawAuthCode: string | null;\n /** Respuesta cruda (débito o verify) que se vuelca en el log de auditoría si falta el auth_code. */\n debitResponse?: unknown;\n /**\n * Etiqueta del objeto crudo en el log `[AUDIT:MISSING_AUTH_CODE]`. charge.ts usa\n * el default `\"debitResponse\"`; los flujos 3DS pasan `\"verifyResponse\"` para que\n * el log refleje de dónde vino la respuesta. No cambia el comportamiento de charge.\n */\n auditResponseLabel?: string;\n installments?: number;\n installmentsType?: number;\n userId: string;\n userEmail: string;\n vat: number;\n amount: number;\n token: string;\n deleteCardAfterPayment?: boolean;\n /**\n * Campos extra a fusionar en el `batch.update` de la orden (ambas ramas:\n * con y sin auth_code). El flujo 3DS los usa para limpiar el estado intermedio\n * (`threeDSCres`, `threeDSTransStatus`, `isDeviceFingerprint`). charge.ts no los\n * pasa → el batch queda idéntico al original.\n */\n extraOrderFields?: Record<string, unknown>;\n /**\n * Datos de la orden ya leídos por el caller. Si se pasan, se evita el re-read\n * desde Firestore (los flujos 3DS/webhook ya tienen la orden en mano). Si se\n * omite, finalize la lee (comportamiento original de charge.ts).\n */\n preReadOrder?: MinimalOrder;\n /**\n * Si es `false`, el email de confirmación NO incluye `postPurchaseNote` aunque\n * la orden lo tenga. Default `true` (comportamiento de charge.ts). El flujo 3DS\n * pasa `false` para conservar su comportamiento original.\n */\n includePostPurchaseNote?: boolean;\n}\n\nexport interface FinalizePaidOrderResult {\n transactionId: string;\n authorizationCode: string | null;\n emailSent: boolean;\n}\n\nexport async function finalizePaidOrder(\n deps: FinalizePaidOrderDeps,\n ctx: FinalizePaidOrderCtx,\n): Promise<FinalizePaidOrderResult> {\n const { db, logger } = deps;\n const {\n orderId,\n transactionId,\n rawAuthCode,\n debitResponse,\n auditResponseLabel,\n installments,\n installmentsType,\n userId,\n userEmail,\n vat,\n amount,\n token,\n deleteCardAfterPayment,\n extraOrderFields,\n preReadOrder,\n includePostPurchaseNote,\n } = ctx;\n\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: transactionId,\n authorizationCode: rawAuthCode,\n ...(installments\n ? { installments, installmentsType: installmentsType ?? 0 }\n : {}),\n chargeResponseAt: new Date(),\n updatedAt: new Date(),\n ...(extraOrderFields ?? {}),\n });\n } else {\n logger.error(\n `[AUDIT:MISSING_AUTH_CODE] orderId=${orderId} txId=${transactionId} ${auditResponseLabel ?? \"debitResponse\"}=${JSON.stringify(debitResponse)}`,\n );\n batch.update(orderRef, {\n status: \"paid\",\n paymentTransactionId: transactionId,\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 ...(extraOrderFields ?? {}),\n });\n }\n\n // Atomically increment promotion usage if coupon was applied.\n // Reusa la orden ya leída por el caller (preReadOrder) cuando esté disponible;\n // de lo contrario la relee (comportamiento original de charge.ts).\n const orderInfo =\n preReadOrder ?? ((await orderRef.get()).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,\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 ...(includePostPurchaseNote !== false && 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 (deleteCardAfterPayment && token) {\n deleteCard(token, userId).catch((err) =>\n logger.error(\"[charge] Failed to delete card after payment:\", err),\n );\n }\n\n return {\n transactionId,\n authorizationCode: hasValidAuthCode ? rawAuthCode : null,\n emailSent,\n };\n}\n","// Tablas de mensajes de error de Nuvei + el mapeo de status_detail a mensaje de\n// usuario. Extraído de charge.ts (M1b) sin cambios de comportamiento.\n\n// --- Tablas estáticas de mensajes de error (específicas de Nuvei, sin parametrizar) ---\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\nexport const 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\nexport function 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","// Ruteo de todos los resultados de Nuvei que NO son el éxito directo (status_detail 3):\n// review/pending, fingerprint de dispositivo, OTP, challenge 3DS y los fallos\n// (frictionless y genérico). Extraído de charge.ts (M1b) sin cambios de\n// comportamiento. Siempre devuelve una `Response`.\n\nimport { json } from \"../../http.js\";\nimport type { Firestore } from \"firebase-admin/firestore\";\nimport type { DebitResponse } from \"../../sdk.js\";\nimport type { EmailService, MinimalOrder } from \"../types.js\";\nimport { THREEDS_AUTH_MESSAGES, getNuveiUserMessage } from \"./error-messages.js\";\n\nexport interface HandleNonSuccessDeps {\n db: Firestore;\n /** Solo se usa sendPaymentFailed en los caminos de fallo. */\n email: Pick<EmailService, \"sendPaymentFailed\">;\n /** Constructor opcional de la URL de reintento para el email de pago fallido. */\n getRetryUrl?: (order: MinimalOrder & { id: string }) => string;\n logger: Pick<Console, \"log\" | \"error\" | \"warn\">;\n}\n\nexport interface HandleNonSuccessCtx {\n nuveiData: DebitResponse;\n orderId: string;\n userEmail: string;\n amount: number;\n token: string;\n deleteCardAfterPayment?: boolean;\n}\n\nexport async function handleNonSuccessResult(\n deps: HandleNonSuccessDeps,\n ctx: HandleNonSuccessCtx,\n): Promise<Response> {\n const { db, logger } = deps;\n const { nuveiData, orderId, userEmail, amount, token, deleteCardAfterPayment } =\n ctx;\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 = 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}\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 { debitWithToken } from \"../sdk.js\";\nimport { validateStandardOrder } from \"./charge/validate-order.js\";\nimport { finalizePaidOrder } from \"./charge/finalize-success.js\";\nimport { handleNonSuccessResult } from \"./charge/handle-3ds-results.js\";\nimport type {\n EmailService,\n FirebaseDeps,\n GetPriceDisplayFn,\n MinimalOrder,\n RateLimitFn,\n TurnstileFn,\n ValidateCustomOrderFn,\n} from \"./types.js\";\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 /** Taxed base, when part of `amount` is NOT subject to tax (e.g. shipping).\n * Nuvei rejects the debit unless `taxableAmount * tax_percentage === vat`.\n * Omit it and it falls back to `amount - vat`, which is only correct when\n * the whole amount is taxed. */\n taxableAmount?: 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 taxableAmount,\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 validationError = await validateStandardOrder({\n db,\n getPriceDisplay: deps.getPriceDisplay,\n orderData,\n amount,\n });\n if (validationError) {\n return validationError;\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 // `amount - vat` assumes every cent of the charge is taxed. That breaks as soon as\n // the order carries a non-taxable line (shipping, tips): Nuvei checks\n // `taxable_amount * tax_percentage === vat` and rejects the debit with\n // OperationNotAllowedError / \"order.vat Invalid\". Callers with such a line send\n // the taxed base explicitly.\n const discountedSubtotalForTax = taxableAmount ?? 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(\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 finalizeResult = await finalizePaidOrder(\n {\n db,\n email: deps.email,\n onPaymentSucceeded: deps.onPaymentSucceeded,\n logger,\n },\n {\n orderId,\n transactionId: nuveiData.transaction.id,\n rawAuthCode: nuveiData.transaction.authorization_code,\n debitResponse: nuveiData,\n installments,\n installmentsType,\n userId,\n userEmail,\n vat,\n amount,\n token,\n deleteCardAfterPayment: body.deleteCardAfterPayment,\n },\n );\n\n return json({\n success: true,\n transactionId: finalizeResult.transactionId,\n authorizationCode: finalizeResult.authorizationCode,\n orderId,\n emailSent: finalizeResult.emailSent,\n });\n }\n\n // 13b–13g. Resto de resultados Nuvei (review / fingerprint / OTP /\n // challenge / fallos). Siempre devuelve una Response.\n return handleNonSuccessResult(\n {\n db,\n email: deps.email,\n getRetryUrl: deps.getRetryUrl,\n logger,\n },\n {\n nuveiData,\n orderId,\n userEmail,\n amount,\n token,\n deleteCardAfterPayment: body.deleteCardAfterPayment,\n },\n );\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, timingSafeEqualStr } from \"../http.js\";\nimport { FieldValue } from \"firebase-admin/firestore\";\nimport { verifyThreeDS } from \"../sdk.js\";\nimport { finalizePaidOrder } from \"./charge/finalize-success.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 /** Desenlace en texto: APPROVED, CANCELLED, EXPIRED, REJECTED o PENDING. */\n current_status?: string;\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 /**\n * Shared secret used to authenticate the incoming webhook. Paymentez/Nuvei\n * DMNs are NOT signed, so the only robust auth is a secret the merchant\n * embeds in the DMN URL configured in the Nuvei dashboard, e.g.\n * `https://shop.com/api/webhooks/nuvei?key=THE_SECRET` (also accepted as the\n * `x-webhook-key` header). Falls back to `process.env.NUVEI_WEBHOOK_SECRET`.\n *\n * If set, requests without a matching key are rejected with 401. If unset,\n * the handler logs a loud warning and processes anyway (the endpoint is then\n * forgeable — anyone who knows an orderId could fake a \"paid\" notification).\n * STRONGLY RECOMMENDED in production.\n */\n webhookSecret?: string;\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 const expectedSecret = deps.webhookSecret ?? process.env.NUVEI_WEBHOOK_SECRET;\n\n return async function POST(request: Request) {\n try {\n // Authenticate the webhook. Paymentez/Nuvei DMNs are unsigned, so the\n // only robust auth is a shared secret the merchant embeds in the DMN URL\n // (?key=...) or sends as the x-webhook-key header. Reject mismatches; if\n // no secret is configured, warn loudly and process (forgeable).\n if (expectedSecret) {\n const provided =\n new URL(request.url).searchParams.get(\"key\") ??\n request.headers.get(\"x-webhook-key\") ??\n \"\";\n if (!timingSafeEqualStr(provided, expectedSecret)) {\n logger.warn(\"[webhook] rejected: missing/invalid webhook secret\");\n return json({ error: \"Unauthorized\" }, { status: 401 });\n }\n } else {\n logger.warn(\n \"[webhook] NUVEI_WEBHOOK_SECRET is not configured — this endpoint is UNAUTHENTICATED and forgeable. Set a secret (deps.webhookSecret or env) and append it to your DMN URL as ?key=... before going to production.\",\n );\n }\n\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 // Adopta el modulo compartido finalizePaidOrder (mismo que charge.ts\n // y 3ds-complete.ts). Se le pasa la orden ya leida (preReadOrder)\n // para no releer Firestore, los campos extra threeDSCres/\n // threeDSTransStatus que este camino BY_CRES borraba inline, la\n // etiqueta de auditoria \"verifyResponse\" (la respuesta cruda es la\n // de verify, no la de debit) e includePostPurchaseNote=false (este\n // flujo nunca lo incluia). vat=0 y amount=total replican los\n // fallbacks del email original.\n await finalizePaidOrder(\n { db, email: deps.email, onPaymentSucceeded: deps.onPaymentSucceeded, logger },\n {\n orderId,\n transactionId: vTxId as string,\n rawAuthCode: (vAuthCode as string | null) ?? null,\n debitResponse: verifyResult,\n auditResponseLabel: \"verifyResponse\",\n userId: orderDataEarly.userId as string,\n userEmail: (orderDataEarly.userEmail as string) || \"\",\n vat: 0,\n amount: (orderDataEarly.total as number) || 0,\n token: orderDataEarly.paymentToken as string,\n deleteCardAfterPayment: orderDataEarly.deleteCardAfterPayment as boolean | undefined,\n preReadOrder: orderDataEarly,\n includePostPurchaseNote: false,\n extraOrderFields: {\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\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 // \"refunded\" belongs here too: refunding calls Nuvei, and Nuvei then sends a DMN for\n // the reversed transaction (status 2 / detail 7, current_status CANCELLED). That DMN\n // is not \"approved\", so without this the refund the merchant just issued gets\n // overwritten with \"cancelled\" seconds later — losing the difference between money\n // paid back and an order that never went through.\n const finalStatuses = [\"paid\", \"delivered\", \"shipped\", \"refunded\"];\n\n // Un DMN de \"autenticación pendiente\" no es un resultado: avisa que el cliente TODAVÍA\n // está en la pantalla de su banco. Tratarlo como \"no aprobado\" cancelaba el pedido a\n // mitad del challenge, y cuando el cliente terminaba de autenticarse ya no había pedido\n // que cobrar. Medido en el staging de Tálou el 2026-09-24: debit a las 20:56:09 con\n // status_detail 36, y el pedido en \"cancelled\" a las 20:56:28 — 19 segundos, con el\n // cliente aún en el banco.\n //\n // Number() a propósito: el débito devuelve status_detail numérico (3) pero el DMN lo\n // manda como string (\"36\"), y una comparación estricta no vería ninguno de los dos.\n const statusDetail = Number(transaction.status_detail);\n\n // Nuvei ya dice en `current_status` si el aviso es un RESULTADO o solo un parte de\n // avance. PENDING significa \"el cobro sigue en curso\": el cliente se está autenticando\n // (35 huella, 36/37 challenge), la transacción está en revisión manual (1), o espera un\n // OTP (31). Ninguno es un desenlace, y tratarlos como \"no aprobado\" mata el pedido\n // mientras todavía se podía cobrar.\n //\n // Se mira `current_status` y no una lista de números porque enumerar códigos es\n // perseguir síntomas: cubrimos 36 y 37 y se nos escapó el 35, que era el más frecuente.\n // APPROVED, CANCELLED, EXPIRED y REJECTED sí son desenlaces y siguen cancelando.\n //\n // La lista queda de respaldo por si un DMN llega sin `current_status` — son los mismos\n // detalles que el propio paquete ya trata como estados en curso al cobrar.\n const currentStatusRaw = transaction.current_status;\n const isPendingNotice =\n (typeof currentStatusRaw === \"string\" &&\n currentStatusRaw.toUpperCase() === \"PENDING\") ||\n [1, 31, 35, 36, 37].includes(statusDetail);\n\n const shouldUpdateStatus =\n isApproved || (!isPendingNotice && !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 } from \"../sdk.js\";\nimport { finalizePaidOrder } from \"./charge/finalize-success.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 // Adopta el modulo compartido finalizePaidOrder (mismo que charge.ts).\n // Comportamiento identico al inline anterior: se le pasa la orden ya\n // leida (preReadOrder) para no releer Firestore, los campos extra para\n // limpiar el estado 3DS, la etiqueta de auditoria \"verifyResponse\" y\n // includePostPurchaseNote=false (este flujo nunca lo incluia). vat=0 y\n // amount=total replican los fallbacks del email original.\n const finalizeResult = await finalizePaidOrder(\n {\n db,\n email: deps.email,\n onPaymentSucceeded: deps.onPaymentSucceeded,\n logger,\n },\n {\n orderId,\n transactionId: txId as string,\n rawAuthCode: txAuthCode as string | null,\n debitResponse: verifyResult,\n auditResponseLabel: \"verifyResponse\",\n userId: orderData.userId as string,\n userEmail:\n (orderData.userEmail as string) || decodedToken.email || \"\",\n vat: 0,\n amount: (orderData.total as number) || 0,\n token: orderData.paymentToken as string,\n deleteCardAfterPayment: orderData.deleteCardAfterPayment,\n preReadOrder: orderData,\n includePostPurchaseNote: false,\n extraOrderFields: {\n threeDSCres: FieldValue.delete(),\n threeDSTransStatus: FieldValue.delete(),\n isDeviceFingerprint: FieldValue.delete(),\n },\n },\n );\n\n return json({\n success: true,\n transactionId: finalizeResult.transactionId,\n authorizationCode: finalizeResult.authorizationCode,\n emailSent: finalizeResult.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"]}
|