better-auth-mercadopago 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +3 -3
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +2 -2
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../security.ts","../client.ts"],"sourcesContent":["import { type BetterAuthPlugin, generateId } from \"better-auth\";\nimport { APIError, createAuthEndpoint } from \"better-auth/api\";\nimport {\n\tCustomer,\n\tMercadoPagoConfig,\n\tPayment,\n\tPreApproval,\n\tPreApprovalPlan,\n\tPreference,\n} from \"mercadopago\";\n\nimport type { PreApprovalCreateData } from \"mercadopago/dist/clients/preApproval/create/types\";\nimport type { PreApprovalPlanCreateData } from \"mercadopago/dist/clients/preApprovalPlan/create/types\";\nimport type { PreferenceCreateData } from \"mercadopago/dist/clients/preference/create/types\";\nimport { z } from \"zod\";\nimport {\n\thandleMercadoPagoError,\n\tidempotencyStore,\n\tisValidWebhookTopic,\n\trateLimiter,\n\tsanitizeMetadata,\n\tValidationRules,\n\tvalidateCallbackUrl,\n\tvalidateIdempotencyKey,\n\tvalidatePaymentAmount,\n\tverifyWebhookSignature,\n} from \"./security\";\n\nimport type {\n\tMercadoPagoCustomerRecord,\n\tMercadoPagoPaymentRecord,\n\tMercadoPagoPaymentResponse,\n\tMercadoPagoPluginOptions,\n\tMercadoPagoPreApprovalResponse,\n\tMercadoPagoSubscriptionRecord,\n} from \"./types\";\n\nexport const mercadoPagoPlugin = (options: MercadoPagoPluginOptions) => {\n\tconst client = new MercadoPagoConfig({\n\t\taccessToken: options.accessToken,\n\t});\n\n\tconst preferenceClient = new Preference(client);\n\tconst paymentClient = new Payment(client);\n\tconst customerClient = new Customer(client);\n\n\tconst preApprovalClient = new PreApproval(client);\n\tconst preApprovalPlanClient = new PreApprovalPlan(client);\n\n\treturn {\n\t\tid: \"mercadopago\",\n\n\t\tschema: {\n\t\t\t// Customer table - stores MP customer info\n\t\t\tmercadoPagoCustomer: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\tmercadoPagoId: { type: \"string\", required: true, unique: true },\n\t\t\t\t\temail: { type: \"string\", required: true },\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Payment table - one-time payments\n\t\t\tmercadoPagoPayment: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\tmercadoPagoPaymentId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tunique: true,\n\t\t\t\t\t},\n\t\t\t\t\tpreferenceId: { type: \"string\", required: true },\n\t\t\t\t\tstatus: { type: \"string\", required: true }, // pending, approved, authorized, rejected, cancelled, refunded, charged_back\n\t\t\t\t\tstatusDetail: { type: \"string\" }, // accredited, pending_contingency, pending_review_manual, cc_rejected_*, etc\n\t\t\t\t\tamount: { type: \"number\", required: true },\n\t\t\t\t\tcurrency: { type: \"string\", required: true },\n\t\t\t\t\tpaymentMethodId: { type: \"string\" }, // visa, master, pix, etc\n\t\t\t\t\tpaymentTypeId: { type: \"string\" }, // credit_card, debit_card, ticket, etc\n\t\t\t\t\tmetadata: { type: \"string\" }, // JSON stringified\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Subscription table\n\t\t\tmercadoPagoSubscription: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\tmercadoPagoSubscriptionId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tunique: true,\n\t\t\t\t\t},\n\t\t\t\t\tplanId: { type: \"string\", required: true },\n\t\t\t\t\tstatus: { type: \"string\", required: true }, // authorized, paused, cancelled, pending\n\t\t\t\t\treason: { type: \"string\" }, // Reason for status (e.g., payment_failed, user_cancelled)\n\t\t\t\t\tnextPaymentDate: { type: \"date\" },\n\t\t\t\t\tlastPaymentDate: { type: \"date\" },\n\t\t\t\t\tsummarized: { type: \"string\" }, // JSON with charges, charged_amount, pending_charge_amount\n\t\t\t\t\tmetadata: { type: \"string\" }, // JSON stringified\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Preapproval Plan table (reusable subscription plans)\n\t\t\tmercadoPagoPreapprovalPlan: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tmercadoPagoPlanId: { type: \"string\", required: true, unique: true },\n\t\t\t\t\treason: { type: \"string\", required: true }, // Plan description\n\t\t\t\t\tfrequency: { type: \"number\", required: true },\n\t\t\t\t\tfrequencyType: { type: \"string\", required: true }, // days, months\n\t\t\t\t\ttransactionAmount: { type: \"number\", required: true },\n\t\t\t\t\tcurrencyId: { type: \"string\", required: true },\n\t\t\t\t\trepetitions: { type: \"number\" }, // null = infinite\n\t\t\t\t\tfreeTrial: { type: \"string\" }, // JSON with frequency and frequency_type\n\t\t\t\t\tmetadata: { type: \"string\" }, // JSON stringified\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Split payments table (for marketplace)\n\t\t\tmercadoPagoMarketplaceSplit: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tpaymentId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: {\n\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\tonDelete: \"cascade\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t// Changed naming to be more clear\n\t\t\t\t\tcollectorId: { type: \"string\", required: true }, // MP User ID who receives the money (seller)\n\t\t\t\t\tcollectorEmail: { type: \"string\", required: true }, // Email of who receives money\n\t\t\t\t\tapplicationFeeAmount: { type: \"number\" }, // Platform commission in absolute value\n\t\t\t\t\tapplicationFeePercentage: { type: \"number\" }, // Platform commission percentage\n\t\t\t\t\tnetAmount: { type: \"number\", required: true }, // Amount that goes to collector (seller)\n\t\t\t\t\tmetadata: { type: \"string\" },\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// OAuth tokens for marketplace (to make payments on behalf of sellers)\n\t\t\tmercadoPagoOAuthToken: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\taccessToken: { type: \"string\", required: true },\n\t\t\t\t\trefreshToken: { type: \"string\", required: true },\n\t\t\t\t\tpublicKey: { type: \"string\", required: true },\n\t\t\t\t\tmercadoPagoUserId: { type: \"string\", required: true, unique: true },\n\t\t\t\t\texpiresAt: { type: \"date\", required: true },\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\n\t\tendpoints: {\n\t\t\t// Get or create customer automatically\n\t\t\tgetOrCreateCustomer: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/customer\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\temail: z.string().email().optional(),\n\t\t\t\t\t\tfirstName: z.string().optional(),\n\t\t\t\t\t\tlastName: z.string().optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"You must be logged in\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { email, firstName, lastName } = ctx.body;\n\t\t\t\t\tconst userEmail = email || session.user.email;\n\n\t\t\t\t\t// Check if customer already exists\n\t\t\t\t\tconst existingCustomer = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (existingCustomer) {\n\t\t\t\t\t\treturn ctx.json({ customer: existingCustomer });\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create customer in Mercado Pago\n\t\t\t\t\tconst mpCustomer = await customerClient.create({\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\temail: userEmail,\n\t\t\t\t\t\t\tfirst_name: firstName,\n\t\t\t\t\t\t\tlast_name: lastName,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\t// Save to database\n\t\t\t\t\tconst customer = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tmercadoPagoId: mpCustomer.id,\n\t\t\t\t\t\t\temail: userEmail,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ customer });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// OAuth: Get authorization URL for marketplace sellers\n\t\t\tgetOAuthUrl: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/oauth/authorize\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tquery: z.object({\n\t\t\t\t\t\tredirectUri: z.string().url(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!options.appId) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"OAuth not configured. Please provide appId in plugin options\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { redirectUri } = ctx.query;\n\n\t\t\t\t\t// Validate redirect URI is trusted\n\t\t\t\t\tif (!ctx.context.isTrustedOrigin(redirectUri)) {\n\t\t\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\t\t\tmessage: \"Redirect URI not in trusted origins\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst authUrl = `https://auth.mercadopago.com/authorization?client_id=${options.appId}&response_type=code&platform_id=mp&state=${session.user.id}&redirect_uri=${encodeURIComponent(redirectUri)}`;\n\n\t\t\t\t\treturn ctx.json({ authUrl });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// OAuth: Exchange code for access token\n\t\t\texchangeOAuthCode: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/oauth/callback\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\tcode: z.string(),\n\t\t\t\t\t\tredirectUri: z.string().url(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!options.appId || !options.appSecret) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"OAuth not configured\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { code, redirectUri } = ctx.body;\n\n\t\t\t\t\t// Exchange code for token\n\t\t\t\t\tconst tokenResponse = await fetch(\n\t\t\t\t\t\t\"https://api.mercadopago.com/oauth/token\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\t\tclient_id: options.appId,\n\t\t\t\t\t\t\t\tclient_secret: options.appSecret,\n\t\t\t\t\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\t\tredirect_uri: redirectUri,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!tokenResponse.ok) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Failed to exchange OAuth code\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tokenData = await tokenResponse.json();\n\n\t\t\t\t\t// Save OAuth token\n\t\t\t\t\tconst oauthToken = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoOAuthToken\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\taccessToken: tokenData.access_token,\n\t\t\t\t\t\t\trefreshToken: tokenData.refresh_token,\n\t\t\t\t\t\t\tpublicKey: tokenData.public_key,\n\t\t\t\t\t\t\tmercadoPagoUserId: tokenData.user_id.toString(),\n\t\t\t\t\t\t\texpiresAt: new Date(Date.now() + tokenData.expires_in * 1000),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\toauthToken: {\n\t\t\t\t\t\t\tid: oauthToken.id,\n\t\t\t\t\t\t\tmercadoPagoUserId: oauthToken.mercadoPagoUserId,\n\t\t\t\t\t\t\texpiresAt: oauthToken.expiresAt,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Create a reusable preapproval plan (subscription plan)\n\t\t\tcreatePreapprovalPlan: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/plan/create\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\treason: z.string(), // Plan description (e.g., \"Premium Monthly\")\n\t\t\t\t\t\tautoRecurring: z.object({\n\t\t\t\t\t\t\tfrequency: z.number(), // 1, 7, 30, etc\n\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\ttransactionAmount: z.number(),\n\t\t\t\t\t\t\tcurrencyId: z.string().default(\"ARS\"),\n\t\t\t\t\t\t\tfreeTrial: z\n\t\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\t\tfrequency: z.number(),\n\t\t\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\trepetitions: z.number().optional(), // null = infinite\n\t\t\t\t\t\tbackUrl: z.string().optional(),\n\t\t\t\t\t\tmetadata: z.record(z.any()).optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { reason, autoRecurring, repetitions, backUrl, metadata } =\n\t\t\t\t\t\tctx.body;\n\n\t\t\t\t\tconst baseUrl = options.baseUrl || ctx.context.baseURL;\n\n\t\t\t\t\t// Create preapproval plan\n\t\t\t\t\tconst planBody: PreApprovalPlanCreateData[\"body\"] = {\n\t\t\t\t\t\treason,\n\t\t\t\t\t\tauto_recurring: {\n\t\t\t\t\t\t\tfrequency: autoRecurring.frequency,\n\t\t\t\t\t\t\tfrequency_type: autoRecurring.frequencyType,\n\t\t\t\t\t\t\ttransaction_amount: autoRecurring.transactionAmount,\n\t\t\t\t\t\t\tcurrency_id: autoRecurring.currencyId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tback_url: backUrl || `${baseUrl}/plan/created`,\n\t\t\t\t\t};\n\n\t\t\t\t\tif (repetitions && planBody.auto_recurring) {\n\t\t\t\t\t\tplanBody.auto_recurring.repetitions = repetitions;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (autoRecurring.freeTrial && planBody.auto_recurring) {\n\t\t\t\t\t\tplanBody.auto_recurring.free_trial = {\n\t\t\t\t\t\t\tfrequency: autoRecurring.freeTrial.frequency,\n\t\t\t\t\t\t\tfrequency_type: autoRecurring.freeTrial.frequencyType,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst mpPlan = await preApprovalPlanClient.create({ body: planBody });\n\n\t\t\t\t\t// Save plan to database\n\t\t\t\t\tconst plan = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoPreapprovalPlan\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tmercadoPagoPlanId: mpPlan.id,\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tfrequency: autoRecurring.frequency,\n\t\t\t\t\t\t\tfrequencyType: autoRecurring.frequencyType,\n\t\t\t\t\t\t\ttransactionAmount: autoRecurring.transactionAmount,\n\t\t\t\t\t\t\tcurrencyId: autoRecurring.currencyId,\n\t\t\t\t\t\t\trepetitions: repetitions || null,\n\t\t\t\t\t\t\tfreeTrial: autoRecurring.freeTrial\n\t\t\t\t\t\t\t\t? JSON.stringify(autoRecurring.freeTrial)\n\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\tmetadata: JSON.stringify(metadata || {}),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ plan });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// List all preapproval plans\n\t\t\tlistPreapprovalPlans: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/plans\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst plans = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"mercadoPagoPreapprovalPlan\",\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ plans });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Create payment preference\n\t\t\tcreatePayment: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/payment/create\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\titems: z\n\t\t\t\t\t\t\t.array(\n\t\t\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\t\t\tid: z.string(),\n\t\t\t\t\t\t\t\t\ttitle: z.string().min(1).max(256),\n\t\t\t\t\t\t\t\t\tquantity: z.number().int().min(1).max(10000),\n\t\t\t\t\t\t\t\t\tunitPrice: z.number().positive().max(999999999),\n\t\t\t\t\t\t\t\t\tcurrencyId: z.string().default(\"ARS\"),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.min(1)\n\t\t\t\t\t\t\t.max(100),\n\t\t\t\t\t\tmetadata: z.record(z.any()).optional(),\n\t\t\t\t\t\tmarketplace: z\n\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\tcollectorId: z.string(),\n\t\t\t\t\t\t\t\tapplicationFee: z.number().positive().optional(),\n\t\t\t\t\t\t\t\tapplicationFeePercentage: z.number().min(0).max(100).optional(),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\tsuccessUrl: z.string().url().optional(),\n\t\t\t\t\t\tfailureUrl: z.string().url().optional(),\n\t\t\t\t\t\tpendingUrl: z.string().url().optional(),\n\t\t\t\t\t\tidempotencyKey: z.string().optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\t// Rate limiting: 10 payment creations per minute per user\n\t\t\t\t\tconst rateLimitKey = `payment:create:${session.user.id}`;\n\t\t\t\t\tif (!rateLimiter.check(rateLimitKey, 10, 60 * 1000)) {\n\t\t\t\t\t\tthrow new APIError(\"TOO_MANY_REQUESTS\", {\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"Too many payment creation attempts. Please try again later.\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tmarketplace,\n\t\t\t\t\t\tsuccessUrl,\n\t\t\t\t\t\tfailureUrl,\n\t\t\t\t\t\tpendingUrl,\n\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t} = ctx.body;\n\n\t\t\t\t\t// Idempotency check\n\t\t\t\t\tif (idempotencyKey) {\n\t\t\t\t\t\tif (!validateIdempotencyKey(idempotencyKey)) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"Invalid idempotency key format\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst cachedResult = idempotencyStore.get(idempotencyKey);\n\t\t\t\t\t\tif (cachedResult) {\n\t\t\t\t\t\t\treturn ctx.json(cachedResult);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate URLs if provided\n\t\t\t\t\tif (options.trustedOrigins) {\n\t\t\t\t\t\tconst urls = [successUrl, failureUrl, pendingUrl].filter(\n\t\t\t\t\t\t\tBoolean,\n\t\t\t\t\t\t) as string[];\n\t\t\t\t\t\tfor (const url of urls) {\n\t\t\t\t\t\t\tif (!validateCallbackUrl(url, options.trustedOrigins)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\t\t\t\t\tmessage: `URL ${url} is not in trusted origins`,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate currency\n\t\t\t\t\tif (\n\t\t\t\t\t\titems.some((item) => !ValidationRules.currency(item.currencyId))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Invalid currency code\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Sanitize metadata\n\t\t\t\t\tconst sanitizedMetadata = metadata ? sanitizeMetadata(metadata) : {};\n\n\t\t\t\t\t// Ensure customer exists\n\t\t\t\t\tlet customer: MercadoPagoCustomerRecord | null =\n\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (!customer) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst mpCustomer = await customerClient.create({\n\t\t\t\t\t\t\t\tbody: { email: session.user.email },\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tcustomer = await ctx.context.adapter.create({\n\t\t\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\t\tmercadoPagoId: mpCustomer.id,\n\t\t\t\t\t\t\t\t\temail: session.user.email,\n\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\thandleMercadoPagoError(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst baseUrl = options.baseUrl || ctx.context.baseURL;\n\n\t\t\t\t\t// Calculate total amount\n\t\t\t\t\tconst totalAmount = items.reduce(\n\t\t\t\t\t\t(sum, item) => sum + item.unitPrice * item.quantity,\n\t\t\t\t\t\t0,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Validate total amount\n\t\t\t\t\tif (!ValidationRules.amount(totalAmount)) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Invalid payment amount\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Calculate marketplace fees\n\t\t\t\t\tlet applicationFeeAmount = 0;\n\t\t\t\t\tif (marketplace) {\n\t\t\t\t\t\tif (marketplace.applicationFee) {\n\t\t\t\t\t\t\tapplicationFeeAmount = marketplace.applicationFee;\n\t\t\t\t\t\t} else if (marketplace.applicationFeePercentage) {\n\t\t\t\t\t\t\tapplicationFeeAmount =\n\t\t\t\t\t\t\t\t(totalAmount * marketplace.applicationFeePercentage) / 100;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Validate fee doesn't exceed total\n\t\t\t\t\t\tif (applicationFeeAmount >= totalAmount) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"Application fee cannot exceed total amount\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create preference with marketplace config\n\t\t\t\t\tconst preferenceBody: PreferenceCreateData[\"body\"] = {\n\t\t\t\t\t\titems: items.map((item) => ({\n\t\t\t\t\t\t\tid: item.id,\n\t\t\t\t\t\t\ttitle: item.title,\n\t\t\t\t\t\t\tquantity: item.quantity,\n\t\t\t\t\t\t\tunit_price: item.unitPrice,\n\t\t\t\t\t\t\tcurrency_id: item.currencyId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tpayer: {\n\t\t\t\t\t\t\temail: session.user.email,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tback_urls: {\n\t\t\t\t\t\t\tsuccess: successUrl || `${baseUrl}/payment/success`,\n\t\t\t\t\t\t\tfailure: failureUrl || `${baseUrl}/payment/failure`,\n\t\t\t\t\t\t\tpending: pendingUrl || `${baseUrl}/payment/pending`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnotification_url: `${baseUrl}/api/auth/mercado-pago/webhook`,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t...sanitizedMetadata,\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tcustomerId: customer?.id,\n\t\t\t\t\t\t},\n\t\t\t\t\t\texpires: true,\n\t\t\t\t\t\texpiration_date_from: new Date().toISOString(),\n\t\t\t\t\t\texpiration_date_to: new Date(\n\t\t\t\t\t\t\tDate.now() + 30 * 24 * 60 * 60 * 1000,\n\t\t\t\t\t\t).toISOString(), // 30 days\n\t\t\t\t\t};\n\n\t\t\t\t\t// Add marketplace config if provided\n\t\t\t\t\tif (marketplace) {\n\t\t\t\t\t\tpreferenceBody.marketplace = marketplace.collectorId;\n\t\t\t\t\t\tpreferenceBody.marketplace_fee = applicationFeeAmount;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet preference:\n\t\t\t\t\t\t| Awaited<ReturnType<typeof preferenceClient.create>>\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpreference = await preferenceClient.create({\n\t\t\t\t\t\t\tbody: preferenceBody,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\thandleMercadoPagoError(error);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Save payment to database\n\t\t\t\t\tconst payment = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tmercadoPagoPaymentId: preference.id,\n\t\t\t\t\t\t\tpreferenceId: preference.id,\n\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\tamount: totalAmount,\n\t\t\t\t\t\t\tcurrency: items[0].currencyId,\n\t\t\t\t\t\t\tmetadata: JSON.stringify(sanitizedMetadata),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\t// Save marketplace split info if provided\n\t\t\t\t\tif (marketplace) {\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoMarketplaceSplit\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\t\tpaymentId: payment.id,\n\t\t\t\t\t\t\t\tcollectorId: marketplace.collectorId,\n\t\t\t\t\t\t\t\tcollectorEmail: \"\", // Will be updated via webhook\n\t\t\t\t\t\t\t\tapplicationFeeAmount,\n\t\t\t\t\t\t\t\tapplicationFeePercentage: marketplace.applicationFeePercentage,\n\t\t\t\t\t\t\t\tnetAmount: totalAmount - applicationFeeAmount,\n\t\t\t\t\t\t\t\tmetadata: JSON.stringify({}),\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = {\n\t\t\t\t\t\tcheckoutUrl: preference.init_point,\n\t\t\t\t\t\tpreferenceId: preference.id,\n\t\t\t\t\t\tpayment,\n\t\t\t\t\t};\n\n\t\t\t\t\t// Store in idempotency cache\n\t\t\t\t\tif (idempotencyKey) {\n\t\t\t\t\t\tidempotencyStore.set(idempotencyKey, result);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json(result);\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Create subscription (supports both with and without preapproval plan)\n\t\t\tcreateSubscription: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/subscription/create\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\t// Option 1: Use existing preapproval plan\n\t\t\t\t\t\tpreapprovalPlanId: z.string().optional(),\n\n\t\t\t\t\t\t// Option 2: Create subscription directly without plan\n\t\t\t\t\t\treason: z.string().optional(), // Description of subscription\n\t\t\t\t\t\tautoRecurring: z\n\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\tfrequency: z.number(), // 1 for monthly\n\t\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\t\ttransactionAmount: z.number(),\n\t\t\t\t\t\t\t\tcurrencyId: z.string().default(\"ARS\"),\n\t\t\t\t\t\t\t\tstartDate: z.string().optional(), // ISO date\n\t\t\t\t\t\t\t\tendDate: z.string().optional(), // ISO date\n\t\t\t\t\t\t\t\tfreeTrial: z\n\t\t\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\t\t\tfrequency: z.number(),\n\t\t\t\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\tbackUrl: z.string().optional(),\n\t\t\t\t\t\tmetadata: z.record(z.any()).optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\tpreapprovalPlanId,\n\t\t\t\t\t\treason,\n\t\t\t\t\t\tautoRecurring,\n\t\t\t\t\t\tbackUrl,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t} = ctx.body;\n\n\t\t\t\t\t// Validate: must provide either preapprovalPlanId OR (reason + autoRecurring)\n\t\t\t\t\tif (!preapprovalPlanId) {\n\t\t\t\t\t\tif (!reason || !autoRecurring) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\"Must provide either preapprovalPlanId or (reason + autoRecurring)\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure customer exists\n\t\t\t\t\tlet customer = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!customer) {\n\t\t\t\t\t\tconst mpCustomer = await customerClient.create({\n\t\t\t\t\t\t\tbody: { email: session.user.email },\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tcustomer = await ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\tmercadoPagoId: mpCustomer.id,\n\t\t\t\t\t\t\t\temail: session.user.email,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst baseUrl = options.baseUrl || ctx.context.baseURL;\n\n\t\t\t\t\tconst subscriptionId = generateId();\n\t\t\t\t\tlet preapproval:\n\t\t\t\t\t\t| Awaited<ReturnType<typeof preApprovalClient.create>>\n\t\t\t\t\t\t| undefined;\n\n\t\t\t\t\t// Option 1: Use existing preapproval plan\n\t\t\t\t\tif (preapprovalPlanId) {\n\t\t\t\t\t\tpreapproval = await preApprovalClient.create({\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tpreapproval_plan_id: preapprovalPlanId,\n\t\t\t\t\t\t\t\tpayer_email: session.user.email,\n\t\t\t\t\t\t\t\tcard_token_id: undefined, // Will be provided in checkout\n\t\t\t\t\t\t\t\tback_url: backUrl || `${baseUrl}/subscription/success`,\n\t\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\t\texternal_reference: subscriptionId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Option 2: Create subscription directly without plan\n\t\t\t\t\telse if (autoRecurring) {\n\t\t\t\t\t\t// We verified autoRecurring is defined in the validation step above\n\t\t\t\t\t\tconst ar = autoRecurring;\n\t\t\t\t\t\tconst autoRecurringBody: PreApprovalCreateData[\"body\"][\"auto_recurring\"] =\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfrequency: ar.frequency,\n\t\t\t\t\t\t\t\tfrequency_type: ar.frequencyType,\n\t\t\t\t\t\t\t\ttransaction_amount: ar.transactionAmount,\n\t\t\t\t\t\t\t\tcurrency_id: ar.currencyId,\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (ar.startDate) {\n\t\t\t\t\t\t\tautoRecurringBody.start_date = ar.startDate;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ar.endDate) {\n\t\t\t\t\t\t\tautoRecurringBody.end_date = ar.endDate;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ar.freeTrial) {\n\t\t\t\t\t\t\t// @ts-expect-error SDK type definition is missing free_trial\n\t\t\t\t\t\t\tautoRecurringBody.free_trial = {\n\t\t\t\t\t\t\t\tfrequency: ar.freeTrial.frequency,\n\t\t\t\t\t\t\t\tfrequency_type: ar.freeTrial.frequencyType,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpreapproval = await preApprovalClient.create({\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\t\tauto_recurring: autoRecurringBody,\n\t\t\t\t\t\t\t\tpayer_email: session.user.email,\n\t\t\t\t\t\t\t\tback_url: backUrl || `${baseUrl}/subscription/success`,\n\t\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\t\texternal_reference: subscriptionId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure preapproval was created\n\t\t\t\t\tif (!preapproval) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Failed to create subscription\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Save subscription\n\t\t\t\t\tconst subscription = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: subscriptionId,\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tmercadoPagoSubscriptionId: preapproval.id,\n\t\t\t\t\t\t\tplanId: preapprovalPlanId || reason || \"direct\",\n\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\tmetadata: JSON.stringify(metadata || {}),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tcheckoutUrl: preapproval.init_point,\n\t\t\t\t\t\tsubscription,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Cancel subscription\n\t\t\tcancelSubscription: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/subscription/cancel\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\tsubscriptionId: z.string(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { subscriptionId } = ctx.body;\n\n\t\t\t\t\tconst subscription: MercadoPagoSubscriptionRecord | null =\n\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"id\", value: subscriptionId },\n\t\t\t\t\t\t\t\t{ field: \"userId\", value: session.user.id },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (!subscription) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"Subscription not found\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Cancel in Mercado Pago\n\t\t\t\t\tawait preApprovalClient.update({\n\t\t\t\t\t\tid: subscription.mercadoPagoSubscriptionId,\n\t\t\t\t\t\tbody: { status: \"cancelled\" },\n\t\t\t\t\t});\n\n\t\t\t\t\t// Update in database\n\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\twhere: [{ field: \"id\", value: subscriptionId }],\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tstatus: \"cancelled\",\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ success: true });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Get payment status\n\t\t\tgetPayment: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/payment/:id\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst paymentId = ctx.params.id;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst payment: MercadoPagoPaymentRecord | null =\n\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"id\", value: paymentId },\n\t\t\t\t\t\t\t\t{ field: \"userId\", value: session.user.id },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (!payment) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"Payment not found\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({ payment });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// List user payments\n\t\t\tlistPayments: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/payments\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tquery: z.object({\n\t\t\t\t\t\tlimit: z.coerce.number().optional().default(10),\n\t\t\t\t\t\toffset: z.coerce.number().optional().default(0),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tconst { limit, offset } = ctx.query;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst payments = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\toffset,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ payments });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// List user subscriptions\n\t\t\tlistSubscriptions: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/subscriptions\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subscriptions = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t});\n\t\t\t\t\treturn ctx.json({ subscriptions });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Webhook handler\n\t\t\twebhook: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/webhook\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\t// Rate limiting for webhooks: 1000 requests per minute\n\t\t\t\t\tconst webhookRateLimitKey = \"webhook:global\";\n\t\t\t\t\tif (!rateLimiter.check(webhookRateLimitKey, 1000, 60 * 1000)) {\n\t\t\t\t\t\tthrow new APIError(\"TOO_MANY_REQUESTS\", {\n\t\t\t\t\t\t\tmessage: \"Webhook rate limit exceeded\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tlet notification: {\n\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\tdata?: { id?: string };\n\t\t\t\t\t};\n\t\t\t\t\ttry {\n\t\t\t\t\t\tnotification = ctx.body;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Invalid JSON payload\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate webhook topic\n\t\t\t\t\tif (\n\t\t\t\t\t\t!notification.type ||\n\t\t\t\t\t\t!isValidWebhookTopic(notification.type) ||\n\t\t\t\t\t\t!notification.data?.id\n\t\t\t\t\t) {\n\t\t\t\t\t\tctx.context.logger.warn(\"Invalid webhook topic received\", {\n\t\t\t\t\t\t\ttype: notification.type,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn ctx.json({ received: true }); // Return 200 to avoid retries\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!ctx.request) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Missing request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Verify webhook signature\n\t\t\t\t\tif (options.webhookSecret) {\n\t\t\t\t\t\tconst xSignature = ctx.request.headers.get(\"x-signature\");\n\t\t\t\t\t\tconst xRequestId = ctx.request.headers.get(\"x-request-id\");\n\t\t\t\t\t\tconst dataId = notification.data?.id?.toString();\n\n\t\t\t\t\t\tif (!dataId) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"Missing data.id in webhook payload\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst isValid = verifyWebhookSignature({\n\t\t\t\t\t\t\txSignature,\n\t\t\t\t\t\t\txRequestId,\n\t\t\t\t\t\t\tdataId,\n\t\t\t\t\t\t\tsecret: options.webhookSecret,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\tctx.context.logger.error(\"Invalid webhook signature\", {\n\t\t\t\t\t\t\t\txSignature,\n\t\t\t\t\t\t\t\txRequestId,\n\t\t\t\t\t\t\t\tdataId,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Invalid webhook signature\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Idempotency: prevent duplicate webhook processing\n\t\t\t\t\tconst webhookId = `webhook:${notification.data?.id}:${notification.type}`;\n\t\t\t\t\tconst alreadyProcessed = idempotencyStore.get(webhookId);\n\t\t\t\t\tif (alreadyProcessed) {\n\t\t\t\t\t\tctx.context.logger.info(\"Webhook already processed\", { webhookId });\n\t\t\t\t\t\treturn ctx.json({ received: true });\n\t\t\t\t\t}\n\n\t\t\t\t\t// Mark as being processed\n\t\t\t\t\tidempotencyStore.set(webhookId, true, 24 * 60 * 60 * 1000); // 24 hours\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Handle payment notifications\n\t\t\t\t\t\tif (notification.type === \"payment\") {\n\t\t\t\t\t\t\tconst paymentId = notification.data.id;\n\n\t\t\t\t\t\t\tif (!paymentId) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Missing payment ID\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Fetch payment details from MP\n\t\t\t\t\t\t\tlet mpPayment: MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tmpPayment = (await paymentClient.get({\n\t\t\t\t\t\t\t\t\tid: paymentId,\n\t\t\t\t\t\t\t\t})) as unknown as MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tctx.context.logger.error(\"Failed to fetch payment from MP\", {\n\t\t\t\t\t\t\t\t\tpaymentId,\n\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Failed to fetch payment details\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Update payment in database\n\t\t\t\t\t\t\tconst existingPayment: MercadoPagoPaymentRecord | null =\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfield: \"mercadoPagoPaymentId\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: paymentId.toString(),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (existingPayment) {\n\t\t\t\t\t\t\t\t// Validate amount hasn't been tampered with\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t!validatePaymentAmount(\n\t\t\t\t\t\t\t\t\t\texistingPayment.amount,\n\t\t\t\t\t\t\t\t\t\tmpPayment.transaction_amount || 0,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tctx.context.logger.error(\"Payment amount mismatch\", {\n\t\t\t\t\t\t\t\t\t\texpected: existingPayment.amount,\n\t\t\t\t\t\t\t\t\t\treceived: mpPayment.transaction_amount,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\t\tmessage: \"Payment amount mismatch\",\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\t\t\twhere: [{ field: \"id\", value: existingPayment.id }],\n\t\t\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\t\t\tstatus: mpPayment.status,\n\t\t\t\t\t\t\t\t\t\tstatusDetail: mpPayment.status_detail || undefined,\n\t\t\t\t\t\t\t\t\t\tpaymentMethodId: mpPayment.payment_method_id || undefined,\n\t\t\t\t\t\t\t\t\t\tpaymentTypeId: mpPayment.payment_type_id || undefined,\n\t\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t// Execute callback if provided\n\t\t\t\t\t\t\t\tif (options.onPaymentUpdate) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tawait options.onPaymentUpdate({\n\t\t\t\t\t\t\t\t\t\t\tpayment: existingPayment,\n\t\t\t\t\t\t\t\t\t\t\tstatus: mpPayment.status,\n\t\t\t\t\t\t\t\t\t\t\tstatusDetail: mpPayment.status_detail || \"\",\n\t\t\t\t\t\t\t\t\t\t\tmpPayment: mpPayment,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\t\t\"Error in onPaymentUpdate callback\",\n\t\t\t\t\t\t\t\t\t\t\t{ error },\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// Don't throw - we still want to return 200\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle subscription (preapproval) notifications\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnotification.type === \"subscription_preapproval\" ||\n\t\t\t\t\t\t\tnotification.type === \"subscription_preapproval_plan\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst preapprovalId = notification.data.id;\n\n\t\t\t\t\t\t\tif (!preapprovalId) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Missing preapproval ID\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Fetch preapproval details\n\t\t\t\t\t\t\tlet mpPreapproval: MercadoPagoPreApprovalResponse;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tmpPreapproval = (await preApprovalClient.get({\n\t\t\t\t\t\t\t\t\tid: preapprovalId,\n\t\t\t\t\t\t\t\t})) as unknown as MercadoPagoPreApprovalResponse;\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\"Failed to fetch preapproval from MP\",\n\t\t\t\t\t\t\t\t\t{ preapprovalId, error },\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Failed to fetch subscription details\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst existingSubscription: MercadoPagoSubscriptionRecord | null =\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfield: \"mercadoPagoSubscriptionId\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: preapprovalId,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (existingSubscription) {\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\t\t\twhere: [{ field: \"id\", value: existingSubscription.id }],\n\t\t\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\t\t\tstatus: mpPreapproval.status,\n\t\t\t\t\t\t\t\t\t\treason: mpPreapproval.reason || undefined,\n\t\t\t\t\t\t\t\t\t\tnextPaymentDate: mpPreapproval.next_payment_date\n\t\t\t\t\t\t\t\t\t\t\t? new Date(mpPreapproval.next_payment_date)\n\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\tlastPaymentDate: mpPreapproval.last_modified\n\t\t\t\t\t\t\t\t\t\t\t? new Date(mpPreapproval.last_modified)\n\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\tsummarized: mpPreapproval.summarized\n\t\t\t\t\t\t\t\t\t\t\t? JSON.stringify(mpPreapproval.summarized)\n\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t// Execute callback if provided\n\t\t\t\t\t\t\t\tif (options.onSubscriptionUpdate) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tawait options.onSubscriptionUpdate({\n\t\t\t\t\t\t\t\t\t\t\tsubscription: existingSubscription,\n\t\t\t\t\t\t\t\t\t\t\tstatus: mpPreapproval.status,\n\t\t\t\t\t\t\t\t\t\t\treason: mpPreapproval.reason || \"\",\n\t\t\t\t\t\t\t\t\t\t\tmpPreapproval: mpPreapproval,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\t\t\"Error in onSubscriptionUpdate callback\",\n\t\t\t\t\t\t\t\t\t\t\t{ error },\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle authorized recurring payment\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(notification.type as string) ===\n\t\t\t\t\t\t\t\t\"subscription_authorized_payment\" ||\n\t\t\t\t\t\t\t(notification.type as string) === \"authorized_payment\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst paymentId = notification.data.id;\n\n\t\t\t\t\t\t\tif (!paymentId) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Missing payment ID\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Handle recurring payment from subscription\n\t\t\t\t\t\t\tlet mpPayment: MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Cast the response to our typed interface\n\t\t\t\t\t\t\t\tmpPayment = (await paymentClient.get({\n\t\t\t\t\t\t\t\t\tid: paymentId,\n\t\t\t\t\t\t\t\t})) as unknown as MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\"Failed to fetch authorized payment from MP\",\n\t\t\t\t\t\t\t\t\t{ paymentId, error },\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Failed to fetch payment details\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Link via external_reference (which contains the subscription ID)\n\t\t\t\t\t\t\tif (mpPayment.external_reference) {\n\t\t\t\t\t\t\t\tconst subscription: MercadoPagoSubscriptionRecord | null =\n\t\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\t\t\t\t\t\t// External reference holds the local subscription ID\n\t\t\t\t\t\t\t\t\t\t\t\tvalue: mpPayment.external_reference,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tif (subscription) {\n\t\t\t\t\t\t\t\t\t// Update subscription last payment date\n\t\t\t\t\t\t\t\t\t// Note: In real scenarios, you might want to create a payment record here too\n\t\t\t\t\t\t\t\t\t// or just rely on the webhook to create it if it doesn't exist.\n\t\t\t\t\t\t\t\t\t// For now, we update the subscription and trigger the callback.\n\n\t\t\t\t\t\t\t\t\tif (options.onSubscriptionPayment) {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tawait options.onSubscriptionPayment({\n\t\t\t\t\t\t\t\t\t\t\t\tsubscription,\n\n\t\t\t\t\t\t\t\t\t\t\t\t// In a real app, we should map this properly or align types\n\t\t\t\t\t\t\t\t\t\t\t\tpayment: mpPayment,\n\t\t\t\t\t\t\t\t\t\t\t\tstatus: mpPayment.status,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\t\t\t\"Error in onSubscriptionPayment callback\",\n\t\t\t\t\t\t\t\t\t\t\t\t{ error },\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tctx.context.logger.warn(\n\t\t\t\t\t\t\t\t\t\t\"Subscription not found for authorized payment\",\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tpaymentId,\n\t\t\t\t\t\t\t\t\t\t\texternalReference: mpPayment.external_reference,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Log error but return 200 to prevent MP from retrying\n\t\t\t\t\t\tctx.context.logger.error(\"Error processing webhook\", {\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\tnotification,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Only throw if it's a validation error that MP should know about\n\t\t\t\t\t\tif (error instanceof APIError) {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({ received: true });\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\n\t\t// Add trusted origins from options\n\t\t...(options.trustedOrigins && { trustedOrigins: options.trustedOrigins }),\n\t} satisfies BetterAuthPlugin;\n};\n\n// Re-export the client type for convenience\nexport type { MercadoPagoClient, MercadoPagoClientActions } from \"./client\";\nexport * from \"./client\";\nexport * from \"./types\";\n","import crypto from \"node:crypto\";\nimport type { Status } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\n/**\n * Verify Mercado Pago webhook signature\n * https://www.mercadopago.com/developers/en/docs/subscriptions/additional-content/security/signature\n */\nexport function verifyWebhookSignature(params: {\n\txSignature: string | null;\n\txRequestId: string | null;\n\tdataId: string;\n\tsecret: string;\n}): boolean {\n\tconst { xSignature, xRequestId, dataId, secret } = params;\n\n\tif (!xSignature || !xRequestId) {\n\t\treturn false;\n\t}\n\n\t// Parse x-signature header\n\t// Format: \"ts=1234567890,v1=hash\"\n\tconst parts = xSignature.split(\",\");\n\tconst ts = parts.find((p) => p.startsWith(\"ts=\"))?.split(\"=\")[1];\n\tconst hash = parts.find((p) => p.startsWith(\"v1=\"))?.split(\"=\")[1];\n\n\tif (!ts || !hash) {\n\t\treturn false;\n\t}\n\n\t// Build the manifest (exactly as MP does)\n\tconst manifest = `id:${dataId};request-id:${xRequestId};ts:${ts};`;\n\n\t// Create HMAC SHA256\n\tconst hmac = crypto.createHmac(\"sha256\", secret);\n\thmac.update(manifest);\n\tconst expectedHash = hmac.digest(\"hex\");\n\n\t// Compare hashes (constant-time comparison)\n\treturn crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(expectedHash));\n}\n\n/**\n * Rate limiting store (in-memory, use Redis in production)\n */\nclass RateLimiter {\n\tprivate attempts: Map<string, { count: number; resetAt: number }> = new Map();\n\n\tcheck(key: string, maxAttempts: number, windowMs: number): boolean {\n\t\tconst now = Date.now();\n\t\tconst record = this.attempts.get(key);\n\n\t\tif (!record || now > record.resetAt) {\n\t\t\tthis.attempts.set(key, {\n\t\t\t\tcount: 1,\n\t\t\t\tresetAt: now + windowMs,\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\n\t\tif (record.count >= maxAttempts) {\n\t\t\treturn false;\n\t\t}\n\n\t\trecord.count++;\n\t\treturn true;\n\t}\n\n\tcleanup() {\n\t\tconst now = Date.now();\n\t\tfor (const [key, record] of this.attempts.entries()) {\n\t\t\tif (now > record.resetAt) {\n\t\t\t\tthis.attempts.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const rateLimiter = new RateLimiter();\n\n// Cleanup every 5 minutes\nsetInterval(() => rateLimiter.cleanup(), 5 * 60 * 1000);\n\n/**\n * Validate payment amount to prevent manipulation\n */\nexport function validatePaymentAmount(\n\trequestedAmount: number,\n\tmpPaymentAmount: number,\n\ttolerance: number = 0.01,\n): boolean {\n\tconst diff = Math.abs(requestedAmount - mpPaymentAmount);\n\treturn diff <= tolerance;\n}\n\n/**\n * Sanitize metadata to prevent injection attacks\n */\nexport function sanitizeMetadata(\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tmetadata: Record<string, any>,\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n): Record<string, any> {\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tconst sanitized: Record<string, any> = {};\n\n\tfor (const [key, value] of Object.entries(metadata)) {\n\t\t// Prevent prototype pollution\n\t\tif (key === \"__proto__\" || key === \"constructor\" || key === \"prototype\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Limit metadata size\n\t\tif (typeof value === \"string\" && value.length > 5000) {\n\t\t\tsanitized[key] = value.substring(0, 5000);\n\t\t} else if (typeof value === \"object\" && value !== null) {\n\t\t\t// Recursively sanitize nested objects\n\t\t\tsanitized[key] = sanitizeMetadata(value);\n\t\t} else {\n\t\t\tsanitized[key] = value;\n\t\t}\n\t}\n\n\treturn sanitized;\n}\n\n/**\n * Validate callback URL to prevent open redirects\n */\nexport function validateCallbackUrl(\n\turl: string,\n\tallowedDomains: string[],\n): boolean {\n\ttry {\n\t\tconst parsed = new URL(url);\n\n\t\t// Only allow HTTPS in production\n\t\tif (process.env.NODE_ENV === \"production\" && parsed.protocol !== \"https:\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if domain is allowed\n\t\tconst hostname = parsed.hostname;\n\t\treturn allowedDomains.some((domain) => {\n\t\t\tif (domain.startsWith(\"*.\")) {\n\t\t\t\t// Wildcard subdomain\n\t\t\t\tconst baseDomain = domain.substring(2);\n\t\t\t\treturn hostname.endsWith(baseDomain);\n\t\t\t}\n\t\t\treturn hostname === domain;\n\t\t});\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Idempotency key validation\n */\nexport function validateIdempotencyKey(key: string): boolean {\n\t// UUID v4 format or custom format\n\tconst uuidRegex =\n\t\t/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\tconst customRegex = /^[a-zA-Z0-9_-]{8,64}$/;\n\n\treturn uuidRegex.test(key) || customRegex.test(key);\n}\n\n/**\n * Prevent timing attacks on webhook validation\n */\nexport function secureCompare(a: string, b: string): boolean {\n\tif (a.length !== b.length) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\treturn crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Error codes mapping\n */\nexport const MercadoPagoErrorCodes = {\n\t// Authentication\n\tINVALID_API_KEY: \"invalid_api_key\",\n\tUNAUTHORIZED: \"unauthorized\",\n\n\t// Payment errors\n\tINSUFFICIENT_FUNDS: \"cc_rejected_insufficient_amount\",\n\tINVALID_CARD: \"cc_rejected_bad_filled_card_number\",\n\tCARD_DISABLED: \"cc_rejected_card_disabled\",\n\tMAX_ATTEMPTS: \"cc_rejected_max_attempts\",\n\tDUPLICATED_PAYMENT: \"cc_rejected_duplicated_payment\",\n\n\t// Subscription errors\n\tSUBSCRIPTION_NOT_FOUND: \"subscription_not_found\",\n\tSUBSCRIPTION_ALREADY_CANCELLED: \"subscription_already_cancelled\",\n\n\t// General\n\tINVALID_PARAMETER: \"invalid_parameter\",\n\tRESOURCE_NOT_FOUND: \"resource_not_found\",\n\tINTERNAL_SERVER_ERROR: \"internal_server_error\",\n} as const;\n\n/**\n * Custom error class for Mercado Pago errors\n */\nexport class MercadoPagoError extends Error {\n\tconstructor(\n\t\tpublic code: string,\n\t\tpublic message: string,\n\t\tpublic statusCode: number = 400,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\t\tpublic details?: any,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MercadoPagoError\";\n\t}\n\n\ttoAPIError(): APIError {\n\t\tconst errorMap: Record<\n\t\t\tnumber,\n\t\t\t| \"OK\"\n\t\t\t| \"CREATED\"\n\t\t\t| \"ACCEPTED\"\n\t\t\t| \"NO_CONTENT\"\n\t\t\t| \"MULTIPLE_CHOICES\"\n\t\t\t| \"MOVED_PERMANENTLY\"\n\t\t\t| \"FOUND\"\n\t\t\t| \"SEE_OTHER\"\n\t\t\t| \"NOT_MODIFIED\"\n\t\t\t| \"TEMPORARY_REDIRECT\"\n\t\t\t| \"BAD_REQUEST\"\n\t\t\t| \"UNAUTHORIZED\"\n\t\t\t| \"PAYMENT_REQUIRED\"\n\t\t\t| \"FORBIDDEN\"\n\t\t\t| \"NOT_FOUND\"\n\t\t\t| \"METHOD_NOT_ALLOWED\"\n\t\t\t| \"NOT_ACCEPTABLE\"\n\t\t\t| \"PROXY_AUTHENTICATION_REQUIRED\"\n\t\t\t| \"REQUEST_TIMEOUT\"\n\t\t\t| \"CONFLICT\"\n\t\t\t| \"GONE\"\n\t\t\t| \"LENGTH_REQUIRED\"\n\t\t\t| \"PRECONDITION_FAILED\"\n\t\t\t| \"PAYLOAD_TOO_LARGE\"\n\t\t\t| \"URI_TOO_LONG\"\n\t\t\t| \"UNSUPPORTED_MEDIA_TYPE\"\n\t\t\t| \"RANGE_NOT_SATISFIABLE\"\n\t\t\t| \"EXPECTATION_FAILED\"\n\t\t\t| \"I'M_A_TEAPOT\"\n\t\t\t| \"MISDIRECTED_REQUEST\"\n\t\t\t| \"UNPROCESSABLE_ENTITY\"\n\t\t\t| \"LOCKED\"\n\t\t\t| \"FAILED_DEPENDENCY\"\n\t\t\t| \"TOO_EARLY\"\n\t\t\t| \"UPGRADE_REQUIRED\"\n\t\t\t| \"PRECONDITION_REQUIRED\"\n\t\t\t| \"TOO_MANY_REQUESTS\"\n\t\t\t| \"REQUEST_HEADER_FIELDS_TOO_LARGE\"\n\t\t\t| \"UNAVAILABLE_FOR_LEGAL_REASONS\"\n\t\t\t| \"INTERNAL_SERVER_ERROR\"\n\t\t\t| \"NOT_IMPLEMENTED\"\n\t\t\t| \"BAD_GATEWAY\"\n\t\t\t| \"SERVICE_UNAVAILABLE\"\n\t\t\t| \"GATEWAY_TIMEOUT\"\n\t\t\t| \"HTTP_VERSION_NOT_SUPPORTED\"\n\t\t\t| \"VARIANT_ALSO_NEGOTIATES\"\n\t\t\t| \"INSUFFICIENT_STORAGE\"\n\t\t\t| \"LOOP_DETECTED\"\n\t\t\t| \"NOT_EXTENDED\"\n\t\t\t| \"NETWORK_AUTHENTICATION_REQUIRED\"\n\t\t\t| Status\n\t\t\t| undefined\n\t\t> = {\n\t\t\t400: \"BAD_REQUEST\",\n\t\t\t401: \"UNAUTHORIZED\",\n\t\t\t403: \"FORBIDDEN\",\n\t\t\t404: \"NOT_FOUND\",\n\t\t\t429: \"TOO_MANY_REQUESTS\",\n\t\t\t500: \"INTERNAL_SERVER_ERROR\",\n\t\t};\n\n\t\tconst type = errorMap[this.statusCode] || \"BAD_REQUEST\";\n\n\t\treturn new APIError(type, {\n\t\t\tmessage: this.message,\n\t\t\tdetails: this.details,\n\t\t});\n\t}\n}\n\n/**\n * Handle Mercado Pago API errors\n */ // biome-ignore lint/suspicious/noExplicitAny: <necessary>\nexport function handleMercadoPagoError(error: any): never {\n\tif (error.status) {\n\t\tconst mpError = new MercadoPagoError(\n\t\t\terror.code || \"unknown_error\",\n\t\t\terror.message || \"An error occurred with Mercado Pago\",\n\t\t\terror.status,\n\t\t\terror.cause,\n\t\t);\n\t\tthrow mpError.toAPIError();\n\t}\n\n\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\tmessage: \"Failed to process Mercado Pago request\",\n\t});\n}\n\n/**\n * Webhook event types validation\n */\nexport const VALID_WEBHOOK_TOPICS = [\n\t\"payment\",\n\t\"merchant_order\",\n\t\"subscription_preapproval\",\n\t\"subscription_preapproval_plan\",\n\t\"subscription_authorized_payment\",\n\t\"point_integration_wh\",\n\t\"topic_claims_integration_wh\",\n\t\"topic_merchant_order_wh\",\n\t\"delivery_cancellation\",\n] as const;\n\nexport type WebhookTopic = (typeof VALID_WEBHOOK_TOPICS)[number];\n\nexport function isValidWebhookTopic(topic: string): topic is WebhookTopic {\n\treturn VALID_WEBHOOK_TOPICS.includes(topic as WebhookTopic);\n}\n\n/**\n * Idempotency store (in-memory, use Redis in production)\n */\nclass IdempotencyStore {\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tprivate store: Map<string, { result: any; expiresAt: number }> = new Map();\n\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tget(key: string): any | null {\n\t\tconst record = this.store.get(key);\n\t\tif (!record || Date.now() > record.expiresAt) {\n\t\t\tthis.store.delete(key);\n\t\t\treturn null;\n\t\t}\n\t\treturn record.result;\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tset(key: string, result: any, ttlMs: number = 24 * 60 * 60 * 1000) {\n\t\tthis.store.set(key, {\n\t\t\tresult,\n\t\t\texpiresAt: Date.now() + ttlMs,\n\t\t});\n\t}\n\n\tcleanup() {\n\t\tconst now = Date.now();\n\t\tfor (const [key, record] of this.store.entries()) {\n\t\t\tif (now > record.expiresAt) {\n\t\t\t\tthis.store.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const idempotencyStore = new IdempotencyStore();\n\n// Cleanup every hour\nsetInterval(() => idempotencyStore.cleanup(), 60 * 60 * 1000);\n\n/**\n * CSRF token validation\n */\nexport function validateCSRFToken(\n\ttoken: string,\n\texpectedToken: string,\n): boolean {\n\treturn secureCompare(token, expectedToken);\n}\n\n/**\n * Input validation helpers\n */\nexport const ValidationRules = {\n\temail: (email: string): boolean => {\n\t\tconst regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\t\treturn regex.test(email) && email.length <= 255;\n\t},\n\n\tamount: (amount: number): boolean => {\n\t\treturn amount > 0 && amount <= 999999999 && !Number.isNaN(amount);\n\t},\n\n\tcurrency: (currency: string): boolean => {\n\t\tconst validCurrencies = [\n\t\t\t\"ARS\",\n\t\t\t\"BRL\",\n\t\t\t\"CLP\",\n\t\t\t\"MXN\",\n\t\t\t\"COP\",\n\t\t\t\"PEN\",\n\t\t\t\"UYU\",\n\t\t\t\"USD\",\n\t\t];\n\t\treturn validCurrencies.includes(currency);\n\t},\n\n\tfrequency: (frequency: number): boolean => {\n\t\treturn frequency > 0 && frequency <= 365 && Number.isInteger(frequency);\n\t},\n\n\tuserId: (userId: string): boolean => {\n\t\t// UUID or custom ID format\n\t\treturn /^[a-zA-Z0-9_-]{1,100}$/.test(userId);\n\t},\n};\n","import type {\n\tBetterAuthClientPlugin,\n\tBetterFetchOption,\n} from \"better-auth/client\";\nimport type { mercadoPagoPlugin } from \"./index\";\nimport type {\n\tCreatePaymentParams,\n\tCreatePaymentResponse,\n\tCreatePreapprovalPlanParams,\n\tCreatePreapprovalPlanResponse,\n\tCreateSubscriptionParams,\n\tCreateSubscriptionResponse,\n\tMercadoPagoCustomerRecord,\n\tMercadoPagoPaymentRecord,\n\tMercadoPagoPreapprovalPlanRecord,\n\tMercadoPagoSubscriptionRecord,\n\tOAuthTokenResponse,\n\tOAuthUrlResponse,\n} from \"./types\";\n\nexport interface MercadoPagoClientActions {\n\t/**\n\t * Get or create a Mercado Pago customer for the authenticated user\n\t */\n\tgetOrCreateCustomer: (\n\t\tdata?: {\n\t\t\temail?: string;\n\t\t\tfirstName?: string;\n\t\t\tlastName?: string;\n\t\t},\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ customer: MercadoPagoCustomerRecord }>;\n\n\t/**\n\t * Create a payment and get checkout URL\n\t */\n\tcreatePayment: (\n\t\tdata: CreatePaymentParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreatePaymentResponse>;\n\n\t/**\n\t * Create a marketplace payment with automatic split\n\t */\n\tcreateMarketplacePayment: (\n\t\tdata: CreatePaymentParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreatePaymentResponse>;\n\n\t/**\n\t * Create a subscription with recurring payments\n\t */\n\tcreateSubscription: (\n\t\tdata: CreateSubscriptionParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreateSubscriptionResponse>;\n\n\t/**\n\t * Cancel a subscription\n\t */\n\tcancelSubscription: (\n\t\tdata: { subscriptionId: string },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ success: boolean }>;\n\n\t/**\n\t * Create a reusable preapproval plan (subscription template)\n\t */\n\tcreatePreapprovalPlan: (\n\t\tdata: CreatePreapprovalPlanParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreatePreapprovalPlanResponse>;\n\n\t/**\n\t * List all preapproval plans\n\t */\n\tlistPreapprovalPlans: (\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ plans: MercadoPagoPreapprovalPlanRecord[] }>;\n\n\t/**\n\t * Get payment by ID\n\t */\n\tgetPayment: (\n\t\tpaymentId: string,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ payment: MercadoPagoPaymentRecord }>;\n\n\t/**\n\t * List all payments for the authenticated user\n\t */\n\tlistPayments: (\n\t\tparams?: { limit?: number; offset?: number },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ payments: MercadoPagoPaymentRecord[] }>;\n\n\t/**\n\t * List all subscriptions for the authenticated user\n\t */\n\tlistSubscriptions: (\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ subscriptions: MercadoPagoSubscriptionRecord[] }>;\n\n\t/**\n\t * Get OAuth authorization URL for marketplace sellers\n\t */\n\tgetOAuthUrl: (\n\t\tparams: { redirectUri: string },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<OAuthUrlResponse>;\n\n\t/**\n\t * Exchange OAuth code for access token\n\t */\n\texchangeOAuthCode: (\n\t\tdata: { code: string; redirectUri: string },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<OAuthTokenResponse>;\n}\n\n// Export the actions type for Better Auth type inference\nexport type MercadoPagoClient = MercadoPagoClientActions;\n\nexport const mercadoPagoClient = () => {\n\treturn {\n\t\tid: \"mercadopago\",\n\t\t$InferServerPlugin: {} as ReturnType<typeof mercadoPagoPlugin>,\n\n\t\tgetActions: ($fetch: any): MercadoPagoClientActions => ({\n\t\t\t/**\n\t\t\t * Get or create a Mercado Pago customer for the authenticated user\n\t\t\t */\n\t\t\tgetOrCreateCustomer: async (\n\t\t\t\tdata?: {\n\t\t\t\t\temail?: string;\n\t\t\t\t\tfirstName?: string;\n\t\t\t\t\tlastName?: string;\n\t\t\t\t},\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/customer\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data || {},\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a payment and get checkout URL\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createPayment({\n\t\t\t * items: [{\n\t\t\t * title: \"Premium Plan\",\n\t\t\t * quantity: 1,\n\t\t\t * unitPrice: 99.90,\n\t\t\t * currencyId: \"ARS\"\n\t\t\t * }]\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Redirect user to checkout\n\t\t\t * window.location.href = data.checkoutUrl;\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreatePayment: async (\n\t\t\t\tdata: CreatePaymentParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/payment/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a marketplace payment with automatic split\n\t\t\t *\n\t\t\t * You need to have the seller's MP User ID (collector_id) which they get\n\t\t\t * after authorizing your app via OAuth.\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createPayment({\n\t\t\t * items: [{\n\t\t\t * title: \"Product from Seller\",\n\t\t\t * quantity: 1,\n\t\t\t * unitPrice: 100\n\t\t\t * }],\n\t\t\t * marketplace: {\n\t\t\t * collectorId: \"123456789\", // Seller's MP User ID\n\t\t\t * applicationFeePercentage: 10 // Platform keeps 10%\n\t\t\t * }\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreateMarketplacePayment: async (\n\t\t\t\tdata: CreatePaymentParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/payment/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a subscription with recurring payments\n\t\t\t *\n\t\t\t * Supports two modes:\n\t\t\t * 1. With preapproval plan (reusable): Pass preapprovalPlanId\n\t\t\t * 2. Direct subscription (one-off): Pass reason + autoRecurring\n\t\t\t *\n\t\t\t * @example With plan\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createSubscription({\n\t\t\t * preapprovalPlanId: \"plan_abc123\"\n\t\t\t * });\n\t\t\t * ```\n\t\t\t *\n\t\t\t * @example Direct (without plan)\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createSubscription({\n\t\t\t * reason: \"Premium Monthly Plan\",\n\t\t\t * autoRecurring: {\n\t\t\t * frequency: 1,\n\t\t\t * frequencyType: \"months\",\n\t\t\t * transactionAmount: 99.90,\n\t\t\t * currencyId: \"ARS\"\n\t\t\t * }\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreateSubscription: async (\n\t\t\t\tdata: CreateSubscriptionParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/subscription/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Cancel a subscription\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * await authClient.mercadoPago.cancelSubscription({\n\t\t\t * subscriptionId: \"sub_123\"\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tcancelSubscription: async (\n\t\t\t\tdata: { subscriptionId: string },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/subscription/cancel\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a reusable preapproval plan (subscription template)\n\t\t\t *\n\t\t\t * Plans can be reused for multiple subscriptions. Create once,\n\t\t\t * use many times with createSubscription({ preapprovalPlanId })\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createPreapprovalPlan({\n\t\t\t * reason: \"Premium Monthly\",\n\t\t\t * autoRecurring: {\n\t\t\t * frequency: 1,\n\t\t\t * frequencyType: \"months\",\n\t\t\t * transactionAmount: 99.90,\n\t\t\t * freeTrial: {\n\t\t\t * frequency: 7,\n\t\t\t * frequencyType: \"days\"\n\t\t\t * }\n\t\t\t * },\n\t\t\t * repetitions: 12 // 12 months, omit for infinite\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Use the plan\n\t\t\t * const planId = data.plan.mercadoPagoPlanId;\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreatePreapprovalPlan: async (\n\t\t\t\tdata: CreatePreapprovalPlanParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/plan/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * List all preapproval plans\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.listPreapprovalPlans();\n\t\t\t *\n\t\t\t * data.plans.forEach(plan => {\n\t\t\t * console.log(plan.reason); // \"Premium Monthly\"\n\t\t\t * console.log(plan.transactionAmount); // 99.90\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tlistPreapprovalPlans: async (fetchOptions?: BetterFetchOption) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/plans\", {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get payment by ID\n\t\t\t */\n\t\t\tgetPayment: async (\n\t\t\t\tpaymentId: string,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(`/mercado-pago/payment/${paymentId}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * List all payments for the authenticated user\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.listPayments({\n\t\t\t * limit: 20,\n\t\t\t * offset: 0\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tlistPayments: async (\n\t\t\t\tparams?: { limit?: number; offset?: number },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\tconst query = new URLSearchParams();\n\t\t\t\tif (params?.limit) query.set(\"limit\", params.limit.toString());\n\t\t\t\tif (params?.offset) query.set(\"offset\", params.offset.toString());\n\n\t\t\t\treturn await $fetch(`/mercado-pago/payments?${query.toString()}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * List all subscriptions for the authenticated user\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.listSubscriptions();\n\t\t\t * ```\n\t\t\t */\n\t\t\tlistSubscriptions: async (fetchOptions?: BetterFetchOption) => {\n\t\t\t\treturn await $fetch(`/mercado-pago/subscriptions`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get OAuth authorization URL for marketplace sellers\n\t\t\t *\n\t\t\t * This is Step 1 of OAuth flow. Redirect the seller to this URL so they\n\t\t\t * can authorize your app to process payments on their behalf.\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.getOAuthUrl({\n\t\t\t * redirectUri: \"https://myapp.com/oauth/callback\"\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Redirect seller to authorize\n\t\t\t * window.location.href = data.authUrl;\n\t\t\t * ```\n\t\t\t */\n\t\t\tgetOAuthUrl: async (\n\t\t\t\tparams: { redirectUri: string },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\tconst query = new URLSearchParams();\n\t\t\t\tquery.set(\"redirectUri\", params.redirectUri);\n\n\t\t\t\treturn await $fetch(\n\t\t\t\t\t`/mercado-pago/oauth/authorize?${query.toString()}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\t...fetchOptions,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Exchange OAuth code for access token\n\t\t\t *\n\t\t\t * This is Step 2 of OAuth flow. After the seller authorizes and MP redirects\n\t\t\t * them back with a code, exchange that code for an access token.\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * // In your /oauth/callback page:\n\t\t\t * const code = new URLSearchParams(window.location.search).get(\"code\");\n\t\t\t *\n\t\t\t * const { data } = await authClient.mercadoPago.exchangeOAuthCode({\n\t\t\t * code,\n\t\t\t * redirectUri: \"https://myapp.com/oauth/callback\"\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Now you have the seller's MP User ID\n\t\t\t * console.log(data.oauthToken.mercadoPagoUserId);\n\t\t\t * ```\n\t\t\t */\n\t\t\texchangeOAuthCode: async (\n\t\t\t\tdata: { code: string; redirectUri: string },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/oauth/callback\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t} satisfies BetterAuthClientPlugin;\n};\n"],"mappings":"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","names":["import_api","crypto"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts","../security.ts","../client.ts"],"sourcesContent":["import { type BetterAuthPlugin, generateId } from \"better-auth\";\nimport { APIError, createAuthEndpoint } from \"better-auth/api\";\nimport {\n\tCustomer,\n\tMercadoPagoConfig,\n\tPayment,\n\tPreApproval,\n\tPreApprovalPlan,\n\tPreference,\n} from \"mercadopago\";\n\nimport type { PreApprovalCreateData } from \"mercadopago/dist/clients/preApproval/create/types\";\nimport type { PreApprovalPlanCreateData } from \"mercadopago/dist/clients/preApprovalPlan/create/types\";\nimport type { PreferenceCreateData } from \"mercadopago/dist/clients/preference/create/types\";\nimport { z } from \"zod\";\nimport {\n\thandleMercadoPagoError,\n\tidempotencyStore,\n\tisValidWebhookTopic,\n\trateLimiter,\n\tsanitizeMetadata,\n\tValidationRules,\n\tvalidateCallbackUrl,\n\tvalidateIdempotencyKey,\n\tvalidatePaymentAmount,\n\tverifyWebhookSignature,\n} from \"./security\";\n\nimport type {\n\tMercadoPagoCustomerRecord,\n\tMercadoPagoPaymentRecord,\n\tMercadoPagoPaymentResponse,\n\tMercadoPagoPluginOptions,\n\tMercadoPagoPreApprovalResponse,\n\tMercadoPagoSubscriptionRecord,\n} from \"./types\";\n\nexport const mercadoPagoPlugin = (options: MercadoPagoPluginOptions) => {\n\tconst client = new MercadoPagoConfig({\n\t\taccessToken: options.accessToken,\n\t});\n\n\tconst preferenceClient = new Preference(client);\n\tconst paymentClient = new Payment(client);\n\tconst customerClient = new Customer(client);\n\n\tconst preApprovalClient = new PreApproval(client);\n\tconst preApprovalPlanClient = new PreApprovalPlan(client);\n\n\treturn {\n\t\tid: \"mercadopago\",\n\n\t\tschema: {\n\t\t\t// Customer table - stores MP customer info\n\t\t\tmercadoPagoCustomer: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\tmercadoPagoId: { type: \"string\", required: true, unique: true },\n\t\t\t\t\temail: { type: \"string\", required: true },\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Payment table - one-time payments\n\t\t\tmercadoPagoPayment: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\tmercadoPagoPaymentId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tunique: true,\n\t\t\t\t\t},\n\t\t\t\t\tpreferenceId: { type: \"string\", required: true },\n\t\t\t\t\tstatus: { type: \"string\", required: true }, // pending, approved, authorized, rejected, cancelled, refunded, charged_back\n\t\t\t\t\tstatusDetail: { type: \"string\" }, // accredited, pending_contingency, pending_review_manual, cc_rejected_*, etc\n\t\t\t\t\tamount: { type: \"number\", required: true },\n\t\t\t\t\tcurrency: { type: \"string\", required: true },\n\t\t\t\t\tpaymentMethodId: { type: \"string\" }, // visa, master, pix, etc\n\t\t\t\t\tpaymentTypeId: { type: \"string\" }, // credit_card, debit_card, ticket, etc\n\t\t\t\t\tmetadata: { type: \"string\" }, // JSON stringified\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Subscription table\n\t\t\tmercadoPagoSubscription: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\tmercadoPagoSubscriptionId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tunique: true,\n\t\t\t\t\t},\n\t\t\t\t\tplanId: { type: \"string\", required: true },\n\t\t\t\t\tstatus: { type: \"string\", required: true }, // authorized, paused, cancelled, pending\n\t\t\t\t\treason: { type: \"string\" }, // Reason for status (e.g., payment_failed, user_cancelled)\n\t\t\t\t\tnextPaymentDate: { type: \"date\" },\n\t\t\t\t\tlastPaymentDate: { type: \"date\" },\n\t\t\t\t\tsummarized: { type: \"string\" }, // JSON with charges, charged_amount, pending_charge_amount\n\t\t\t\t\tmetadata: { type: \"string\" }, // JSON stringified\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Preapproval Plan table (reusable subscription plans)\n\t\t\tmercadoPagoPreapprovalPlan: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tmercadoPagoPlanId: { type: \"string\", required: true, unique: true },\n\t\t\t\t\treason: { type: \"string\", required: true }, // Plan description\n\t\t\t\t\tfrequency: { type: \"number\", required: true },\n\t\t\t\t\tfrequencyType: { type: \"string\", required: true }, // days, months\n\t\t\t\t\ttransactionAmount: { type: \"number\", required: true },\n\t\t\t\t\tcurrencyId: { type: \"string\", required: true },\n\t\t\t\t\trepetitions: { type: \"number\" }, // null = infinite\n\t\t\t\t\tfreeTrial: { type: \"string\" }, // JSON with frequency and frequency_type\n\t\t\t\t\tmetadata: { type: \"string\" }, // JSON stringified\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Split payments table (for marketplace)\n\t\t\tmercadoPagoMarketplaceSplit: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tpaymentId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: {\n\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\tonDelete: \"cascade\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t// Changed naming to be more clear\n\t\t\t\t\tcollectorId: { type: \"string\", required: true }, // MP User ID who receives the money (seller)\n\t\t\t\t\tcollectorEmail: { type: \"string\", required: true }, // Email of who receives money\n\t\t\t\t\tapplicationFeeAmount: { type: \"number\" }, // Platform commission in absolute value\n\t\t\t\t\tapplicationFeePercentage: { type: \"number\" }, // Platform commission percentage\n\t\t\t\t\tnetAmount: { type: \"number\", required: true }, // Amount that goes to collector (seller)\n\t\t\t\t\tmetadata: { type: \"string\" },\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// OAuth tokens for marketplace (to make payments on behalf of sellers)\n\t\t\tmercadoPagoOAuthToken: {\n\t\t\t\tfields: {\n\t\t\t\t\tid: { type: \"string\", required: true },\n\t\t\t\t\tuserId: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\treferences: { model: \"user\", field: \"id\", onDelete: \"cascade\" },\n\t\t\t\t\t},\n\t\t\t\t\taccessToken: { type: \"string\", required: true },\n\t\t\t\t\trefreshToken: { type: \"string\", required: true },\n\t\t\t\t\tpublicKey: { type: \"string\", required: true },\n\t\t\t\t\tmercadoPagoUserId: { type: \"string\", required: true, unique: true },\n\t\t\t\t\texpiresAt: { type: \"date\", required: true },\n\t\t\t\t\tcreatedAt: { type: \"date\", required: true },\n\t\t\t\t\tupdatedAt: { type: \"date\", required: true },\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\n\t\tendpoints: {\n\t\t\t// Get or create customer automatically\n\t\t\tgetOrCreateCustomer: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/customer\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\temail: z.string().email().optional(),\n\t\t\t\t\t\tfirstName: z.string().optional(),\n\t\t\t\t\t\tlastName: z.string().optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"You must be logged in\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { email, firstName, lastName } = ctx.body;\n\t\t\t\t\tconst userEmail = email || session.user.email;\n\n\t\t\t\t\t// Check if customer already exists\n\t\t\t\t\tconst existingCustomer = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (existingCustomer) {\n\t\t\t\t\t\treturn ctx.json({ customer: existingCustomer });\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create customer in Mercado Pago\n\t\t\t\t\tconst mpCustomer = await customerClient.create({\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\temail: userEmail,\n\t\t\t\t\t\t\tfirst_name: firstName,\n\t\t\t\t\t\t\tlast_name: lastName,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\t// Save to database\n\t\t\t\t\tconst customer = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tmercadoPagoId: mpCustomer.id,\n\t\t\t\t\t\t\temail: userEmail,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ customer });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// OAuth: Get authorization URL for marketplace sellers\n\t\t\tgetOAuthUrl: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/oauth/authorize\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tquery: z.object({\n\t\t\t\t\t\tredirectUri: z.string().url(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!options.appId) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"OAuth not configured. Please provide appId in plugin options\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { redirectUri } = ctx.query;\n\n\t\t\t\t\t// Validate redirect URI is trusted\n\t\t\t\t\tif (!ctx.context.isTrustedOrigin(redirectUri)) {\n\t\t\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\t\t\tmessage: \"Redirect URI not in trusted origins\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst authUrl = `https://auth.mercadopago.com/authorization?client_id=${options.appId}&response_type=code&platform_id=mp&state=${session.user.id}&redirect_uri=${encodeURIComponent(redirectUri)}`;\n\n\t\t\t\t\treturn ctx.json({ authUrl });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// OAuth: Exchange code for access token\n\t\t\texchangeOAuthCode: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/oauth/callback\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\tcode: z.string(),\n\t\t\t\t\t\tredirectUri: z.string().url(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!options.appId || !options.appSecret) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"OAuth not configured\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { code, redirectUri } = ctx.body;\n\n\t\t\t\t\t// Exchange code for token\n\t\t\t\t\tconst tokenResponse = await fetch(\n\t\t\t\t\t\t\"https://api.mercadopago.com/oauth/token\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\t\tclient_id: options.appId,\n\t\t\t\t\t\t\t\tclient_secret: options.appSecret,\n\t\t\t\t\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\t\tredirect_uri: redirectUri,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!tokenResponse.ok) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Failed to exchange OAuth code\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tokenData = await tokenResponse.json();\n\n\t\t\t\t\t// Save OAuth token\n\t\t\t\t\tconst oauthToken = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoOAuthToken\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\taccessToken: tokenData.access_token,\n\t\t\t\t\t\t\trefreshToken: tokenData.refresh_token,\n\t\t\t\t\t\t\tpublicKey: tokenData.public_key,\n\t\t\t\t\t\t\tmercadoPagoUserId: tokenData.user_id.toString(),\n\t\t\t\t\t\t\texpiresAt: new Date(Date.now() + tokenData.expires_in * 1000),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\toauthToken: {\n\t\t\t\t\t\t\tid: oauthToken.id,\n\t\t\t\t\t\t\tmercadoPagoUserId: oauthToken.mercadoPagoUserId,\n\t\t\t\t\t\t\texpiresAt: oauthToken.expiresAt,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Create a reusable preapproval plan (subscription plan)\n\t\t\tcreatePreapprovalPlan: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/plan/create\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\treason: z.string(), // Plan description (e.g., \"Premium Monthly\")\n\t\t\t\t\t\tautoRecurring: z.object({\n\t\t\t\t\t\t\tfrequency: z.number(), // 1, 7, 30, etc\n\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\ttransactionAmount: z.number(),\n\t\t\t\t\t\t\tcurrencyId: z.string().default(\"ARS\"),\n\t\t\t\t\t\t\tfreeTrial: z\n\t\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\t\tfrequency: z.number(),\n\t\t\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\trepetitions: z.number().optional(), // null = infinite\n\t\t\t\t\t\tbackUrl: z.string().optional(),\n\t\t\t\t\t\tmetadata: z.record(z.any()).optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { reason, autoRecurring, repetitions, backUrl, metadata } =\n\t\t\t\t\t\tctx.body;\n\n\t\t\t\t\tconst baseUrl = options.baseUrl || ctx.context.baseURL;\n\n\t\t\t\t\t// Create preapproval plan\n\t\t\t\t\tconst planBody: PreApprovalPlanCreateData[\"body\"] = {\n\t\t\t\t\t\treason,\n\t\t\t\t\t\tauto_recurring: {\n\t\t\t\t\t\t\tfrequency: autoRecurring.frequency,\n\t\t\t\t\t\t\tfrequency_type: autoRecurring.frequencyType,\n\t\t\t\t\t\t\ttransaction_amount: autoRecurring.transactionAmount,\n\t\t\t\t\t\t\tcurrency_id: autoRecurring.currencyId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tback_url: backUrl || `${baseUrl}/plan/created`,\n\t\t\t\t\t};\n\n\t\t\t\t\tif (repetitions && planBody.auto_recurring) {\n\t\t\t\t\t\tplanBody.auto_recurring.repetitions = repetitions;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (autoRecurring.freeTrial && planBody.auto_recurring) {\n\t\t\t\t\t\tplanBody.auto_recurring.free_trial = {\n\t\t\t\t\t\t\tfrequency: autoRecurring.freeTrial.frequency,\n\t\t\t\t\t\t\tfrequency_type: autoRecurring.freeTrial.frequencyType,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst mpPlan = await preApprovalPlanClient.create({ body: planBody });\n\n\t\t\t\t\t// Save plan to database\n\t\t\t\t\tconst plan = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoPreapprovalPlan\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tmercadoPagoPlanId: mpPlan.id,\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tfrequency: autoRecurring.frequency,\n\t\t\t\t\t\t\tfrequencyType: autoRecurring.frequencyType,\n\t\t\t\t\t\t\ttransactionAmount: autoRecurring.transactionAmount,\n\t\t\t\t\t\t\tcurrencyId: autoRecurring.currencyId,\n\t\t\t\t\t\t\trepetitions: repetitions || null,\n\t\t\t\t\t\t\tfreeTrial: autoRecurring.freeTrial\n\t\t\t\t\t\t\t\t? JSON.stringify(autoRecurring.freeTrial)\n\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\tmetadata: JSON.stringify(metadata || {}),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ plan });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// List all preapproval plans\n\t\t\tlistPreapprovalPlans: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/plans\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst plans = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"mercadoPagoPreapprovalPlan\",\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ plans });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Create payment preference\n\t\t\tcreatePayment: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/payment/create\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\titems: z\n\t\t\t\t\t\t\t.array(\n\t\t\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\t\t\tid: z.string(),\n\t\t\t\t\t\t\t\t\ttitle: z.string().min(1).max(256),\n\t\t\t\t\t\t\t\t\tquantity: z.number().int().min(1).max(10000),\n\t\t\t\t\t\t\t\t\tunitPrice: z.number().positive().max(999999999),\n\t\t\t\t\t\t\t\t\tcurrencyId: z.string().default(\"ARS\"),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.min(1)\n\t\t\t\t\t\t\t.max(100),\n\t\t\t\t\t\tmetadata: z.record(z.any()).optional(),\n\t\t\t\t\t\tmarketplace: z\n\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\tcollectorId: z.string(),\n\t\t\t\t\t\t\t\tapplicationFee: z.number().positive().optional(),\n\t\t\t\t\t\t\t\tapplicationFeePercentage: z.number().min(0).max(100).optional(),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\tsuccessUrl: z.string().url().optional(),\n\t\t\t\t\t\tfailureUrl: z.string().url().optional(),\n\t\t\t\t\t\tpendingUrl: z.string().url().optional(),\n\t\t\t\t\t\tidempotencyKey: z.string().optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\t// Rate limiting: 10 payment creations per minute per user\n\t\t\t\t\tconst rateLimitKey = `payment:create:${session.user.id}`;\n\t\t\t\t\tif (!rateLimiter.check(rateLimitKey, 10, 60 * 1000)) {\n\t\t\t\t\t\tthrow new APIError(\"TOO_MANY_REQUESTS\", {\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"Too many payment creation attempts. Please try again later.\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tmarketplace,\n\t\t\t\t\t\tsuccessUrl,\n\t\t\t\t\t\tfailureUrl,\n\t\t\t\t\t\tpendingUrl,\n\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t} = ctx.body;\n\n\t\t\t\t\t// Idempotency check\n\t\t\t\t\tif (idempotencyKey) {\n\t\t\t\t\t\tif (!validateIdempotencyKey(idempotencyKey)) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"Invalid idempotency key format\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst cachedResult = idempotencyStore.get(idempotencyKey);\n\t\t\t\t\t\tif (cachedResult) {\n\t\t\t\t\t\t\treturn ctx.json(cachedResult);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate URLs if provided\n\t\t\t\t\tif (options.trustedOrigins) {\n\t\t\t\t\t\tconst urls = [successUrl, failureUrl, pendingUrl].filter(\n\t\t\t\t\t\t\tBoolean,\n\t\t\t\t\t\t) as string[];\n\t\t\t\t\t\tfor (const url of urls) {\n\t\t\t\t\t\t\tif (!validateCallbackUrl(url, options.trustedOrigins)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\t\t\t\t\tmessage: `URL ${url} is not in trusted origins`,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate currency\n\t\t\t\t\tif (\n\t\t\t\t\t\titems.some((item) => !ValidationRules.currency(item.currencyId))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Invalid currency code\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Sanitize metadata\n\t\t\t\t\tconst sanitizedMetadata = metadata ? sanitizeMetadata(metadata) : {};\n\n\t\t\t\t\t// Ensure customer exists\n\t\t\t\t\tlet customer: MercadoPagoCustomerRecord | null =\n\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (!customer) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst mpCustomer = await customerClient.create({\n\t\t\t\t\t\t\t\tbody: { email: session.user.email },\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tcustomer = await ctx.context.adapter.create({\n\t\t\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\t\tmercadoPagoId: mpCustomer.id,\n\t\t\t\t\t\t\t\t\temail: session.user.email,\n\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\thandleMercadoPagoError(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst baseUrl = options.baseUrl || ctx.context.baseURL;\n\n\t\t\t\t\t// Calculate total amount\n\t\t\t\t\tconst totalAmount = items.reduce(\n\t\t\t\t\t\t(sum, item) => sum + item.unitPrice * item.quantity,\n\t\t\t\t\t\t0,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Validate total amount\n\t\t\t\t\tif (!ValidationRules.amount(totalAmount)) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Invalid payment amount\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Calculate marketplace fees\n\t\t\t\t\tlet applicationFeeAmount = 0;\n\t\t\t\t\tif (marketplace) {\n\t\t\t\t\t\tif (marketplace.applicationFee) {\n\t\t\t\t\t\t\tapplicationFeeAmount = marketplace.applicationFee;\n\t\t\t\t\t\t} else if (marketplace.applicationFeePercentage) {\n\t\t\t\t\t\t\tapplicationFeeAmount =\n\t\t\t\t\t\t\t\t(totalAmount * marketplace.applicationFeePercentage) / 100;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Validate fee doesn't exceed total\n\t\t\t\t\t\tif (applicationFeeAmount >= totalAmount) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"Application fee cannot exceed total amount\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create preference with marketplace config\n\t\t\t\t\tconst preferenceBody: PreferenceCreateData[\"body\"] = {\n\t\t\t\t\t\titems: items.map((item) => ({\n\t\t\t\t\t\t\tid: item.id,\n\t\t\t\t\t\t\ttitle: item.title,\n\t\t\t\t\t\t\tquantity: item.quantity,\n\t\t\t\t\t\t\tunit_price: item.unitPrice,\n\t\t\t\t\t\t\tcurrency_id: item.currencyId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tpayer: {\n\t\t\t\t\t\t\temail: session.user.email,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tback_urls: {\n\t\t\t\t\t\t\tsuccess: successUrl || `${baseUrl}/payment/success`,\n\t\t\t\t\t\t\tfailure: failureUrl || `${baseUrl}/payment/failure`,\n\t\t\t\t\t\t\tpending: pendingUrl || `${baseUrl}/payment/pending`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnotification_url: `${baseUrl}/api/auth/mercado-pago/webhook`,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t...sanitizedMetadata,\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tcustomerId: customer?.id,\n\t\t\t\t\t\t},\n\t\t\t\t\t\texpires: true,\n\t\t\t\t\t\texpiration_date_from: new Date().toISOString(),\n\t\t\t\t\t\texpiration_date_to: new Date(\n\t\t\t\t\t\t\tDate.now() + 30 * 24 * 60 * 60 * 1000,\n\t\t\t\t\t\t).toISOString(), // 30 days\n\t\t\t\t\t};\n\n\t\t\t\t\t// Add marketplace config if provided\n\t\t\t\t\tif (marketplace) {\n\t\t\t\t\t\tpreferenceBody.marketplace = marketplace.collectorId;\n\t\t\t\t\t\tpreferenceBody.marketplace_fee = applicationFeeAmount;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet preference:\n\t\t\t\t\t\t| Awaited<ReturnType<typeof preferenceClient.create>>\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpreference = await preferenceClient.create({\n\t\t\t\t\t\t\tbody: preferenceBody,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\thandleMercadoPagoError(error);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Save payment to database\n\t\t\t\t\tconst payment = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tmercadoPagoPaymentId: preference.id,\n\t\t\t\t\t\t\tpreferenceId: preference.id,\n\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\tamount: totalAmount,\n\t\t\t\t\t\t\tcurrency: items[0].currencyId,\n\t\t\t\t\t\t\tmetadata: JSON.stringify(sanitizedMetadata),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\t// Save marketplace split info if provided\n\t\t\t\t\tif (marketplace) {\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoMarketplaceSplit\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\t\tpaymentId: payment.id,\n\t\t\t\t\t\t\t\tcollectorId: marketplace.collectorId,\n\t\t\t\t\t\t\t\tcollectorEmail: \"\", // Will be updated via webhook\n\t\t\t\t\t\t\t\tapplicationFeeAmount,\n\t\t\t\t\t\t\t\tapplicationFeePercentage: marketplace.applicationFeePercentage,\n\t\t\t\t\t\t\t\tnetAmount: totalAmount - applicationFeeAmount,\n\t\t\t\t\t\t\t\tmetadata: JSON.stringify({}),\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = {\n\t\t\t\t\t\tcheckoutUrl: preference.init_point,\n\t\t\t\t\t\tpreferenceId: preference.id,\n\t\t\t\t\t\tpayment,\n\t\t\t\t\t};\n\n\t\t\t\t\t// Store in idempotency cache\n\t\t\t\t\tif (idempotencyKey) {\n\t\t\t\t\t\tidempotencyStore.set(idempotencyKey, result);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json(result);\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Create subscription (supports both with and without preapproval plan)\n\t\t\tcreateSubscription: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/subscription/create\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\t// Option 1: Use existing preapproval plan\n\t\t\t\t\t\tpreapprovalPlanId: z.string().optional(),\n\n\t\t\t\t\t\t// Option 2: Create subscription directly without plan\n\t\t\t\t\t\treason: z.string().optional(), // Description of subscription\n\t\t\t\t\t\tautoRecurring: z\n\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\tfrequency: z.number(), // 1 for monthly\n\t\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\t\ttransactionAmount: z.number(),\n\t\t\t\t\t\t\t\tcurrencyId: z.string().default(\"ARS\"),\n\t\t\t\t\t\t\t\tstartDate: z.string().optional(), // ISO date\n\t\t\t\t\t\t\t\tendDate: z.string().optional(), // ISO date\n\t\t\t\t\t\t\t\tfreeTrial: z\n\t\t\t\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\t\t\t\tfrequency: z.number(),\n\t\t\t\t\t\t\t\t\t\tfrequencyType: z.enum([\"days\", \"months\"]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.optional(),\n\t\t\t\t\t\tbackUrl: z.string().optional(),\n\t\t\t\t\t\tmetadata: z.record(z.any()).optional(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\tpreapprovalPlanId,\n\t\t\t\t\t\treason,\n\t\t\t\t\t\tautoRecurring,\n\t\t\t\t\t\tbackUrl,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t} = ctx.body;\n\n\t\t\t\t\t// Validate: must provide either preapprovalPlanId OR (reason + autoRecurring)\n\t\t\t\t\tif (!preapprovalPlanId) {\n\t\t\t\t\t\tif (!reason || !autoRecurring) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\"Must provide either preapprovalPlanId or (reason + autoRecurring)\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure customer exists\n\t\t\t\t\tlet customer = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!customer) {\n\t\t\t\t\t\tconst mpCustomer = await customerClient.create({\n\t\t\t\t\t\t\tbody: { email: session.user.email },\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tcustomer = await ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoCustomer\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tid: generateId(),\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\tmercadoPagoId: mpCustomer.id,\n\t\t\t\t\t\t\t\temail: session.user.email,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst baseUrl = options.baseUrl || ctx.context.baseURL;\n\n\t\t\t\t\tconst subscriptionId = generateId();\n\t\t\t\t\tlet preapproval:\n\t\t\t\t\t\t| Awaited<ReturnType<typeof preApprovalClient.create>>\n\t\t\t\t\t\t| undefined;\n\n\t\t\t\t\t// Option 1: Use existing preapproval plan\n\t\t\t\t\tif (preapprovalPlanId) {\n\t\t\t\t\t\tpreapproval = await preApprovalClient.create({\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tpreapproval_plan_id: preapprovalPlanId,\n\t\t\t\t\t\t\t\tpayer_email: session.user.email,\n\t\t\t\t\t\t\t\tcard_token_id: undefined, // Will be provided in checkout\n\t\t\t\t\t\t\t\tback_url: backUrl || `${baseUrl}/subscription/success`,\n\t\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\t\texternal_reference: subscriptionId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Option 2: Create subscription directly without plan\n\t\t\t\t\telse if (autoRecurring) {\n\t\t\t\t\t\t// We verified autoRecurring is defined in the validation step above\n\t\t\t\t\t\tconst ar = autoRecurring;\n\t\t\t\t\t\tconst autoRecurringBody: PreApprovalCreateData[\"body\"][\"auto_recurring\"] =\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfrequency: ar.frequency,\n\t\t\t\t\t\t\t\tfrequency_type: ar.frequencyType,\n\t\t\t\t\t\t\t\ttransaction_amount: ar.transactionAmount,\n\t\t\t\t\t\t\t\tcurrency_id: ar.currencyId,\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (ar.startDate) {\n\t\t\t\t\t\t\tautoRecurringBody.start_date = ar.startDate;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ar.endDate) {\n\t\t\t\t\t\t\tautoRecurringBody.end_date = ar.endDate;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ar.freeTrial) {\n\t\t\t\t\t\t\t// @ts-expect-error SDK type definition is missing free_trial\n\t\t\t\t\t\t\tautoRecurringBody.free_trial = {\n\t\t\t\t\t\t\t\tfrequency: ar.freeTrial.frequency,\n\t\t\t\t\t\t\t\tfrequency_type: ar.freeTrial.frequencyType,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpreapproval = await preApprovalClient.create({\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\t\tauto_recurring: autoRecurringBody,\n\t\t\t\t\t\t\t\tpayer_email: session.user.email,\n\t\t\t\t\t\t\t\tback_url: backUrl || `${baseUrl}/subscription/success`,\n\t\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\t\texternal_reference: subscriptionId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure preapproval was created\n\t\t\t\t\tif (!preapproval) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Failed to create subscription\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Save subscription\n\t\t\t\t\tconst subscription = await ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tid: subscriptionId,\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tmercadoPagoSubscriptionId: preapproval.id,\n\t\t\t\t\t\t\tplanId: preapprovalPlanId || reason || \"direct\",\n\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\tmetadata: JSON.stringify(metadata || {}),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tcheckoutUrl: preapproval.init_point,\n\t\t\t\t\t\tsubscription,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Cancel subscription\n\t\t\tcancelSubscription: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/subscription/cancel\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\tsubscriptionId: z.string(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { subscriptionId } = ctx.body;\n\n\t\t\t\t\tconst subscription: MercadoPagoSubscriptionRecord | null =\n\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"id\", value: subscriptionId },\n\t\t\t\t\t\t\t\t{ field: \"userId\", value: session.user.id },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (!subscription) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"Subscription not found\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Cancel in Mercado Pago\n\t\t\t\t\tawait preApprovalClient.update({\n\t\t\t\t\t\tid: subscription.mercadoPagoSubscriptionId,\n\t\t\t\t\t\tbody: { status: \"cancelled\" },\n\t\t\t\t\t});\n\n\t\t\t\t\t// Update in database\n\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\twhere: [{ field: \"id\", value: subscriptionId }],\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tstatus: \"cancelled\",\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ success: true });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Get payment status\n\t\t\tgetPayment: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/payment/:id\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst paymentId = ctx.params.id;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst payment: MercadoPagoPaymentRecord | null =\n\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"id\", value: paymentId },\n\t\t\t\t\t\t\t\t{ field: \"userId\", value: session.user.id },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (!payment) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"Payment not found\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({ payment });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// List user payments\n\t\t\tlistPayments: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/payments\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tquery: z.object({\n\t\t\t\t\t\tlimit: z.coerce.number().optional().default(10),\n\t\t\t\t\t\toffset: z.coerce.number().optional().default(0),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tconst { limit, offset } = ctx.query;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst payments = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\toffset,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({ payments });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// List user subscriptions\n\t\t\tlistSubscriptions: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/subscriptions\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subscriptions = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", value: session.user.id }],\n\t\t\t\t\t});\n\t\t\t\t\treturn ctx.json({ subscriptions });\n\t\t\t\t},\n\t\t\t),\n\n\t\t\t// Webhook handler\n\t\t\twebhook: createAuthEndpoint(\n\t\t\t\t\"/mercado-pago/webhook\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\t// Rate limiting for webhooks: 1000 requests per minute\n\t\t\t\t\tconst webhookRateLimitKey = \"webhook:global\";\n\t\t\t\t\tif (!rateLimiter.check(webhookRateLimitKey, 1000, 60 * 1000)) {\n\t\t\t\t\t\tthrow new APIError(\"TOO_MANY_REQUESTS\", {\n\t\t\t\t\t\t\tmessage: \"Webhook rate limit exceeded\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tlet notification: {\n\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\tdata?: { id?: string };\n\t\t\t\t\t};\n\t\t\t\t\ttry {\n\t\t\t\t\t\tnotification = ctx.body;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Invalid JSON payload\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate webhook topic\n\t\t\t\t\tif (\n\t\t\t\t\t\t!notification.type ||\n\t\t\t\t\t\t!isValidWebhookTopic(notification.type) ||\n\t\t\t\t\t\t!notification.data?.id\n\t\t\t\t\t) {\n\t\t\t\t\t\tctx.context.logger.warn(\"Invalid webhook topic received\", {\n\t\t\t\t\t\t\ttype: notification.type,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn ctx.json({ received: true }); // Return 200 to avoid retries\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!ctx.request) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Missing request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Verify webhook signature\n\t\t\t\t\tif (options.webhookSecret) {\n\t\t\t\t\t\tconst xSignature = ctx.request.headers.get(\"x-signature\");\n\t\t\t\t\t\tconst xRequestId = ctx.request.headers.get(\"x-request-id\");\n\t\t\t\t\t\tconst dataId = notification.data?.id?.toString();\n\n\t\t\t\t\t\tif (!dataId) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"Missing data.id in webhook payload\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst isValid = verifyWebhookSignature({\n\t\t\t\t\t\t\txSignature,\n\t\t\t\t\t\t\txRequestId,\n\t\t\t\t\t\t\tdataId,\n\t\t\t\t\t\t\tsecret: options.webhookSecret,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\tctx.context.logger.error(\"Invalid webhook signature\", {\n\t\t\t\t\t\t\t\txSignature,\n\t\t\t\t\t\t\t\txRequestId,\n\t\t\t\t\t\t\t\tdataId,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Invalid webhook signature\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Idempotency: prevent duplicate webhook processing\n\t\t\t\t\tconst webhookId = `webhook:${notification.data?.id}:${notification.type}`;\n\t\t\t\t\tconst alreadyProcessed = idempotencyStore.get(webhookId);\n\t\t\t\t\tif (alreadyProcessed) {\n\t\t\t\t\t\tctx.context.logger.info(\"Webhook already processed\", { webhookId });\n\t\t\t\t\t\treturn ctx.json({ received: true });\n\t\t\t\t\t}\n\n\t\t\t\t\t// Mark as being processed\n\t\t\t\t\tidempotencyStore.set(webhookId, true, 24 * 60 * 60 * 1000); // 24 hours\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Handle payment notifications\n\t\t\t\t\t\tif (notification.type === \"payment\") {\n\t\t\t\t\t\t\tconst paymentId = notification.data.id;\n\n\t\t\t\t\t\t\tif (!paymentId) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Missing payment ID\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Fetch payment details from MP\n\t\t\t\t\t\t\tlet mpPayment: MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tmpPayment = (await paymentClient.get({\n\t\t\t\t\t\t\t\t\tid: paymentId,\n\t\t\t\t\t\t\t\t})) as unknown as MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tctx.context.logger.error(\"Failed to fetch payment from MP\", {\n\t\t\t\t\t\t\t\t\tpaymentId,\n\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Failed to fetch payment details\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Update payment in database\n\t\t\t\t\t\t\tconst existingPayment: MercadoPagoPaymentRecord | null =\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfield: \"mercadoPagoPaymentId\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: paymentId.toString(),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (existingPayment) {\n\t\t\t\t\t\t\t\t// Validate amount hasn't been tampered with\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t!validatePaymentAmount(\n\t\t\t\t\t\t\t\t\t\texistingPayment.amount,\n\t\t\t\t\t\t\t\t\t\tmpPayment.transaction_amount || 0,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tctx.context.logger.error(\"Payment amount mismatch\", {\n\t\t\t\t\t\t\t\t\t\texpected: existingPayment.amount,\n\t\t\t\t\t\t\t\t\t\treceived: mpPayment.transaction_amount,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\t\tmessage: \"Payment amount mismatch\",\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoPayment\",\n\t\t\t\t\t\t\t\t\twhere: [{ field: \"id\", value: existingPayment.id }],\n\t\t\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\t\t\tstatus: mpPayment.status,\n\t\t\t\t\t\t\t\t\t\tstatusDetail: mpPayment.status_detail || undefined,\n\t\t\t\t\t\t\t\t\t\tpaymentMethodId: mpPayment.payment_method_id || undefined,\n\t\t\t\t\t\t\t\t\t\tpaymentTypeId: mpPayment.payment_type_id || undefined,\n\t\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t// Execute callback if provided\n\t\t\t\t\t\t\t\tif (options.onPaymentUpdate) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tawait options.onPaymentUpdate({\n\t\t\t\t\t\t\t\t\t\t\tpayment: existingPayment,\n\t\t\t\t\t\t\t\t\t\t\tstatus: mpPayment.status,\n\t\t\t\t\t\t\t\t\t\t\tstatusDetail: mpPayment.status_detail || \"\",\n\t\t\t\t\t\t\t\t\t\t\tmpPayment: mpPayment,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\t\t\"Error in onPaymentUpdate callback\",\n\t\t\t\t\t\t\t\t\t\t\t{ error },\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// Don't throw - we still want to return 200\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle subscription (preapproval) notifications\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnotification.type === \"subscription_preapproval\" ||\n\t\t\t\t\t\t\tnotification.type === \"subscription_preapproval_plan\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst preapprovalId = notification.data.id;\n\n\t\t\t\t\t\t\tif (!preapprovalId) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Missing preapproval ID\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Fetch preapproval details\n\t\t\t\t\t\t\tlet mpPreapproval: MercadoPagoPreApprovalResponse;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tmpPreapproval = (await preApprovalClient.get({\n\t\t\t\t\t\t\t\t\tid: preapprovalId,\n\t\t\t\t\t\t\t\t})) as unknown as MercadoPagoPreApprovalResponse;\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\"Failed to fetch preapproval from MP\",\n\t\t\t\t\t\t\t\t\t{ preapprovalId, error },\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Failed to fetch subscription details\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst existingSubscription: MercadoPagoSubscriptionRecord | null =\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfield: \"mercadoPagoSubscriptionId\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: preapprovalId,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (existingSubscription) {\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\t\t\twhere: [{ field: \"id\", value: existingSubscription.id }],\n\t\t\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\t\t\tstatus: mpPreapproval.status,\n\t\t\t\t\t\t\t\t\t\treason: mpPreapproval.reason || undefined,\n\t\t\t\t\t\t\t\t\t\tnextPaymentDate: mpPreapproval.next_payment_date\n\t\t\t\t\t\t\t\t\t\t\t? new Date(mpPreapproval.next_payment_date)\n\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\tlastPaymentDate: mpPreapproval.last_modified\n\t\t\t\t\t\t\t\t\t\t\t? new Date(mpPreapproval.last_modified)\n\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\tsummarized: mpPreapproval.summarized\n\t\t\t\t\t\t\t\t\t\t\t? JSON.stringify(mpPreapproval.summarized)\n\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t// Execute callback if provided\n\t\t\t\t\t\t\t\tif (options.onSubscriptionUpdate) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tawait options.onSubscriptionUpdate({\n\t\t\t\t\t\t\t\t\t\t\tsubscription: existingSubscription,\n\t\t\t\t\t\t\t\t\t\t\tstatus: mpPreapproval.status,\n\t\t\t\t\t\t\t\t\t\t\treason: mpPreapproval.reason || \"\",\n\t\t\t\t\t\t\t\t\t\t\tmpPreapproval: mpPreapproval,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\t\t\"Error in onSubscriptionUpdate callback\",\n\t\t\t\t\t\t\t\t\t\t\t{ error },\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle authorized recurring payment\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(notification.type as string) ===\n\t\t\t\t\t\t\t\t\"subscription_authorized_payment\" ||\n\t\t\t\t\t\t\t(notification.type as string) === \"authorized_payment\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst paymentId = notification.data.id;\n\n\t\t\t\t\t\t\tif (!paymentId) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Missing payment ID\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Handle recurring payment from subscription\n\t\t\t\t\t\t\tlet mpPayment: MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Cast the response to our typed interface\n\t\t\t\t\t\t\t\tmpPayment = (await paymentClient.get({\n\t\t\t\t\t\t\t\t\tid: paymentId,\n\t\t\t\t\t\t\t\t})) as unknown as MercadoPagoPaymentResponse;\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\"Failed to fetch authorized payment from MP\",\n\t\t\t\t\t\t\t\t\t{ paymentId, error },\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Failed to fetch payment details\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Link via external_reference (which contains the subscription ID)\n\t\t\t\t\t\t\tif (mpPayment.external_reference) {\n\t\t\t\t\t\t\t\tconst subscription: MercadoPagoSubscriptionRecord | null =\n\t\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\t\tmodel: \"mercadoPagoSubscription\",\n\t\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\t\t\t\t\t\t// External reference holds the local subscription ID\n\t\t\t\t\t\t\t\t\t\t\t\tvalue: mpPayment.external_reference,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tif (subscription) {\n\t\t\t\t\t\t\t\t\t// Update subscription last payment date\n\t\t\t\t\t\t\t\t\t// Note: In real scenarios, you might want to create a payment record here too\n\t\t\t\t\t\t\t\t\t// or just rely on the webhook to create it if it doesn't exist.\n\t\t\t\t\t\t\t\t\t// For now, we update the subscription and trigger the callback.\n\n\t\t\t\t\t\t\t\t\tif (options.onSubscriptionPayment) {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tawait options.onSubscriptionPayment({\n\t\t\t\t\t\t\t\t\t\t\t\tsubscription,\n\n\t\t\t\t\t\t\t\t\t\t\t\t// In a real app, we should map this properly or align types\n\t\t\t\t\t\t\t\t\t\t\t\tpayment: mpPayment,\n\t\t\t\t\t\t\t\t\t\t\t\tstatus: mpPayment.status,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\t\t\t\t\"Error in onSubscriptionPayment callback\",\n\t\t\t\t\t\t\t\t\t\t\t\t{ error },\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tctx.context.logger.warn(\n\t\t\t\t\t\t\t\t\t\t\"Subscription not found for authorized payment\",\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tpaymentId,\n\t\t\t\t\t\t\t\t\t\t\texternalReference: mpPayment.external_reference,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Log error but return 200 to prevent MP from retrying\n\t\t\t\t\t\tctx.context.logger.error(\"Error processing webhook\", {\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\tnotification,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Only throw if it's a validation error that MP should know about\n\t\t\t\t\t\tif (error instanceof APIError) {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({ received: true });\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\n\t\t// Add trusted origins from options\n\t\t...(options.trustedOrigins && { trustedOrigins: options.trustedOrigins }),\n\t} satisfies BetterAuthPlugin;\n};\n\n// Re-export the client type for convenience\nexport type { MercadoPagoClient, MercadoPagoClientActions } from \"./client\";\nexport * from \"./client\";\nexport * from \"./types\";\n","import crypto from \"node:crypto\";\nimport type { Status } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\n/**\n * Verify Mercado Pago webhook signature\n * https://www.mercadopago.com/developers/en/docs/subscriptions/additional-content/security/signature\n */\nexport function verifyWebhookSignature(params: {\n\txSignature: string | null;\n\txRequestId: string | null;\n\tdataId: string;\n\tsecret: string;\n}): boolean {\n\tconst { xSignature, xRequestId, dataId, secret } = params;\n\n\tif (!xSignature || !xRequestId) {\n\t\treturn false;\n\t}\n\n\t// Parse x-signature header\n\t// Format: \"ts=1234567890,v1=hash\"\n\tconst parts = xSignature.split(\",\");\n\tconst ts = parts.find((p) => p.startsWith(\"ts=\"))?.split(\"=\")[1];\n\tconst hash = parts.find((p) => p.startsWith(\"v1=\"))?.split(\"=\")[1];\n\n\tif (!ts || !hash) {\n\t\treturn false;\n\t}\n\n\t// Build the manifest (exactly as MP does)\n\tconst manifest = `id:${dataId};request-id:${xRequestId};ts:${ts};`;\n\n\t// Create HMAC SHA256\n\tconst hmac = crypto.createHmac(\"sha256\", secret);\n\thmac.update(manifest);\n\tconst expectedHash = hmac.digest(\"hex\");\n\n\t// Compare hashes (constant-time comparison)\n\treturn crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(expectedHash));\n}\n\n/**\n * Rate limiting store (in-memory, use Redis in production)\n */\nclass RateLimiter {\n\tprivate attempts: Map<string, { count: number; resetAt: number }> = new Map();\n\n\tcheck(key: string, maxAttempts: number, windowMs: number): boolean {\n\t\tconst now = Date.now();\n\t\tconst record = this.attempts.get(key);\n\n\t\tif (!record || now > record.resetAt) {\n\t\t\tthis.attempts.set(key, {\n\t\t\t\tcount: 1,\n\t\t\t\tresetAt: now + windowMs,\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\n\t\tif (record.count >= maxAttempts) {\n\t\t\treturn false;\n\t\t}\n\n\t\trecord.count++;\n\t\treturn true;\n\t}\n\n\tcleanup() {\n\t\tconst now = Date.now();\n\t\tfor (const [key, record] of this.attempts.entries()) {\n\t\t\tif (now > record.resetAt) {\n\t\t\t\tthis.attempts.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const rateLimiter = new RateLimiter();\n\n// Cleanup every 5 minutes\nsetInterval(() => rateLimiter.cleanup(), 5 * 60 * 1000);\n\n/**\n * Validate payment amount to prevent manipulation\n */\nexport function validatePaymentAmount(\n\trequestedAmount: number,\n\tmpPaymentAmount: number,\n\ttolerance: number = 0.01,\n): boolean {\n\tconst diff = Math.abs(requestedAmount - mpPaymentAmount);\n\treturn diff <= tolerance;\n}\n\n/**\n * Sanitize metadata to prevent injection attacks\n */\nexport function sanitizeMetadata(\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tmetadata: Record<string, any>,\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n): Record<string, any> {\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tconst sanitized: Record<string, any> = {};\n\n\tfor (const [key, value] of Object.entries(metadata)) {\n\t\t// Prevent prototype pollution\n\t\tif (key === \"__proto__\" || key === \"constructor\" || key === \"prototype\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Limit metadata size\n\t\tif (typeof value === \"string\" && value.length > 5000) {\n\t\t\tsanitized[key] = value.substring(0, 5000);\n\t\t} else if (typeof value === \"object\" && value !== null) {\n\t\t\t// Recursively sanitize nested objects\n\t\t\tsanitized[key] = sanitizeMetadata(value);\n\t\t} else {\n\t\t\tsanitized[key] = value;\n\t\t}\n\t}\n\n\treturn sanitized;\n}\n\n/**\n * Validate callback URL to prevent open redirects\n */\nexport function validateCallbackUrl(\n\turl: string,\n\tallowedDomains: string[],\n): boolean {\n\ttry {\n\t\tconst parsed = new URL(url);\n\n\t\t// Only allow HTTPS in production\n\t\tif (process.env.NODE_ENV === \"production\" && parsed.protocol !== \"https:\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if domain is allowed\n\t\tconst hostname = parsed.hostname;\n\t\treturn allowedDomains.some((domain) => {\n\t\t\tif (domain.startsWith(\"*.\")) {\n\t\t\t\t// Wildcard subdomain\n\t\t\t\tconst baseDomain = domain.substring(2);\n\t\t\t\treturn hostname.endsWith(baseDomain);\n\t\t\t}\n\t\t\treturn hostname === domain;\n\t\t});\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Idempotency key validation\n */\nexport function validateIdempotencyKey(key: string): boolean {\n\t// UUID v4 format or custom format\n\tconst uuidRegex =\n\t\t/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\tconst customRegex = /^[a-zA-Z0-9_-]{8,64}$/;\n\n\treturn uuidRegex.test(key) || customRegex.test(key);\n}\n\n/**\n * Prevent timing attacks on webhook validation\n */\nexport function secureCompare(a: string, b: string): boolean {\n\tif (a.length !== b.length) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\treturn crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Error codes mapping\n */\nexport const MercadoPagoErrorCodes = {\n\t// Authentication\n\tINVALID_API_KEY: \"invalid_api_key\",\n\tUNAUTHORIZED: \"unauthorized\",\n\n\t// Payment errors\n\tINSUFFICIENT_FUNDS: \"cc_rejected_insufficient_amount\",\n\tINVALID_CARD: \"cc_rejected_bad_filled_card_number\",\n\tCARD_DISABLED: \"cc_rejected_card_disabled\",\n\tMAX_ATTEMPTS: \"cc_rejected_max_attempts\",\n\tDUPLICATED_PAYMENT: \"cc_rejected_duplicated_payment\",\n\n\t// Subscription errors\n\tSUBSCRIPTION_NOT_FOUND: \"subscription_not_found\",\n\tSUBSCRIPTION_ALREADY_CANCELLED: \"subscription_already_cancelled\",\n\n\t// General\n\tINVALID_PARAMETER: \"invalid_parameter\",\n\tRESOURCE_NOT_FOUND: \"resource_not_found\",\n\tINTERNAL_SERVER_ERROR: \"internal_server_error\",\n} as const;\n\n/**\n * Custom error class for Mercado Pago errors\n */\nexport class MercadoPagoError extends Error {\n\tconstructor(\n\t\tpublic code: string,\n\t\tpublic message: string,\n\t\tpublic statusCode: number = 400,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\t\tpublic details?: any,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MercadoPagoError\";\n\t}\n\n\ttoAPIError(): APIError {\n\t\tconst errorMap: Record<\n\t\t\tnumber,\n\t\t\t| \"OK\"\n\t\t\t| \"CREATED\"\n\t\t\t| \"ACCEPTED\"\n\t\t\t| \"NO_CONTENT\"\n\t\t\t| \"MULTIPLE_CHOICES\"\n\t\t\t| \"MOVED_PERMANENTLY\"\n\t\t\t| \"FOUND\"\n\t\t\t| \"SEE_OTHER\"\n\t\t\t| \"NOT_MODIFIED\"\n\t\t\t| \"TEMPORARY_REDIRECT\"\n\t\t\t| \"BAD_REQUEST\"\n\t\t\t| \"UNAUTHORIZED\"\n\t\t\t| \"PAYMENT_REQUIRED\"\n\t\t\t| \"FORBIDDEN\"\n\t\t\t| \"NOT_FOUND\"\n\t\t\t| \"METHOD_NOT_ALLOWED\"\n\t\t\t| \"NOT_ACCEPTABLE\"\n\t\t\t| \"PROXY_AUTHENTICATION_REQUIRED\"\n\t\t\t| \"REQUEST_TIMEOUT\"\n\t\t\t| \"CONFLICT\"\n\t\t\t| \"GONE\"\n\t\t\t| \"LENGTH_REQUIRED\"\n\t\t\t| \"PRECONDITION_FAILED\"\n\t\t\t| \"PAYLOAD_TOO_LARGE\"\n\t\t\t| \"URI_TOO_LONG\"\n\t\t\t| \"UNSUPPORTED_MEDIA_TYPE\"\n\t\t\t| \"RANGE_NOT_SATISFIABLE\"\n\t\t\t| \"EXPECTATION_FAILED\"\n\t\t\t| \"I'M_A_TEAPOT\"\n\t\t\t| \"MISDIRECTED_REQUEST\"\n\t\t\t| \"UNPROCESSABLE_ENTITY\"\n\t\t\t| \"LOCKED\"\n\t\t\t| \"FAILED_DEPENDENCY\"\n\t\t\t| \"TOO_EARLY\"\n\t\t\t| \"UPGRADE_REQUIRED\"\n\t\t\t| \"PRECONDITION_REQUIRED\"\n\t\t\t| \"TOO_MANY_REQUESTS\"\n\t\t\t| \"REQUEST_HEADER_FIELDS_TOO_LARGE\"\n\t\t\t| \"UNAVAILABLE_FOR_LEGAL_REASONS\"\n\t\t\t| \"INTERNAL_SERVER_ERROR\"\n\t\t\t| \"NOT_IMPLEMENTED\"\n\t\t\t| \"BAD_GATEWAY\"\n\t\t\t| \"SERVICE_UNAVAILABLE\"\n\t\t\t| \"GATEWAY_TIMEOUT\"\n\t\t\t| \"HTTP_VERSION_NOT_SUPPORTED\"\n\t\t\t| \"VARIANT_ALSO_NEGOTIATES\"\n\t\t\t| \"INSUFFICIENT_STORAGE\"\n\t\t\t| \"LOOP_DETECTED\"\n\t\t\t| \"NOT_EXTENDED\"\n\t\t\t| \"NETWORK_AUTHENTICATION_REQUIRED\"\n\t\t\t| Status\n\t\t\t| undefined\n\t\t> = {\n\t\t\t400: \"BAD_REQUEST\",\n\t\t\t401: \"UNAUTHORIZED\",\n\t\t\t403: \"FORBIDDEN\",\n\t\t\t404: \"NOT_FOUND\",\n\t\t\t429: \"TOO_MANY_REQUESTS\",\n\t\t\t500: \"INTERNAL_SERVER_ERROR\",\n\t\t};\n\n\t\tconst type = errorMap[this.statusCode] || \"BAD_REQUEST\";\n\n\t\treturn new APIError(type, {\n\t\t\tmessage: this.message,\n\t\t\tdetails: this.details,\n\t\t});\n\t}\n}\n\n/**\n * Handle Mercado Pago API errors\n */ // biome-ignore lint/suspicious/noExplicitAny: <necessary>\nexport function handleMercadoPagoError(error: any): never {\n\tif (error.status) {\n\t\tconst mpError = new MercadoPagoError(\n\t\t\terror.code || \"unknown_error\",\n\t\t\terror.message || \"An error occurred with Mercado Pago\",\n\t\t\terror.status,\n\t\t\terror.cause,\n\t\t);\n\t\tthrow mpError.toAPIError();\n\t}\n\n\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\tmessage: \"Failed to process Mercado Pago request\",\n\t});\n}\n\n/**\n * Webhook event types validation\n */\nexport const VALID_WEBHOOK_TOPICS = [\n\t\"payment\",\n\t\"merchant_order\",\n\t\"subscription_preapproval\",\n\t\"subscription_preapproval_plan\",\n\t\"subscription_authorized_payment\",\n\t\"point_integration_wh\",\n\t\"topic_claims_integration_wh\",\n\t\"topic_merchant_order_wh\",\n\t\"delivery_cancellation\",\n] as const;\n\nexport type WebhookTopic = (typeof VALID_WEBHOOK_TOPICS)[number];\n\nexport function isValidWebhookTopic(topic: string): topic is WebhookTopic {\n\treturn VALID_WEBHOOK_TOPICS.includes(topic as WebhookTopic);\n}\n\n/**\n * Idempotency store (in-memory, use Redis in production)\n */\nclass IdempotencyStore {\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tprivate store: Map<string, { result: any; expiresAt: number }> = new Map();\n\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tget(key: string): any | null {\n\t\tconst record = this.store.get(key);\n\t\tif (!record || Date.now() > record.expiresAt) {\n\t\t\tthis.store.delete(key);\n\t\t\treturn null;\n\t\t}\n\t\treturn record.result;\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: <necessary>\n\tset(key: string, result: any, ttlMs: number = 24 * 60 * 60 * 1000) {\n\t\tthis.store.set(key, {\n\t\t\tresult,\n\t\t\texpiresAt: Date.now() + ttlMs,\n\t\t});\n\t}\n\n\tcleanup() {\n\t\tconst now = Date.now();\n\t\tfor (const [key, record] of this.store.entries()) {\n\t\t\tif (now > record.expiresAt) {\n\t\t\t\tthis.store.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const idempotencyStore = new IdempotencyStore();\n\n// Cleanup every hour\nsetInterval(() => idempotencyStore.cleanup(), 60 * 60 * 1000);\n\n/**\n * CSRF token validation\n */\nexport function validateCSRFToken(\n\ttoken: string,\n\texpectedToken: string,\n): boolean {\n\treturn secureCompare(token, expectedToken);\n}\n\n/**\n * Input validation helpers\n */\nexport const ValidationRules = {\n\temail: (email: string): boolean => {\n\t\tconst regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\t\treturn regex.test(email) && email.length <= 255;\n\t},\n\n\tamount: (amount: number): boolean => {\n\t\treturn amount > 0 && amount <= 999999999 && !Number.isNaN(amount);\n\t},\n\n\tcurrency: (currency: string): boolean => {\n\t\tconst validCurrencies = [\n\t\t\t\"ARS\",\n\t\t\t\"BRL\",\n\t\t\t\"CLP\",\n\t\t\t\"MXN\",\n\t\t\t\"COP\",\n\t\t\t\"PEN\",\n\t\t\t\"UYU\",\n\t\t\t\"USD\",\n\t\t];\n\t\treturn validCurrencies.includes(currency);\n\t},\n\n\tfrequency: (frequency: number): boolean => {\n\t\treturn frequency > 0 && frequency <= 365 && Number.isInteger(frequency);\n\t},\n\n\tuserId: (userId: string): boolean => {\n\t\t// UUID or custom ID format\n\t\treturn /^[a-zA-Z0-9_-]{1,100}$/.test(userId);\n\t},\n};\n","import type {\n\tBetterAuthClientPlugin,\n\tBetterFetch,\n\tBetterFetchOption,\n} from \"better-auth/client\";\nimport type { mercadoPagoPlugin } from \"./index\";\nimport type {\n\tCreatePaymentParams,\n\tCreatePaymentResponse,\n\tCreatePreapprovalPlanParams,\n\tCreatePreapprovalPlanResponse,\n\tCreateSubscriptionParams,\n\tCreateSubscriptionResponse,\n\tMercadoPagoCustomerRecord,\n\tMercadoPagoPaymentRecord,\n\tMercadoPagoPreapprovalPlanRecord,\n\tMercadoPagoSubscriptionRecord,\n\tOAuthTokenResponse,\n\tOAuthUrlResponse,\n} from \"./types\";\n\nexport interface MercadoPagoClientActions {\n\t/**\n\t * Get or create a Mercado Pago customer for the authenticated user\n\t */\n\tgetOrCreateCustomer: (\n\t\tdata?: {\n\t\t\temail?: string;\n\t\t\tfirstName?: string;\n\t\t\tlastName?: string;\n\t\t},\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ customer: MercadoPagoCustomerRecord }>;\n\n\t/**\n\t * Create a payment and get checkout URL\n\t */\n\tcreatePayment: (\n\t\tdata: CreatePaymentParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreatePaymentResponse>;\n\n\t/**\n\t * Create a marketplace payment with automatic split\n\t */\n\tcreateMarketplacePayment: (\n\t\tdata: CreatePaymentParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreatePaymentResponse>;\n\n\t/**\n\t * Create a subscription with recurring payments\n\t */\n\tcreateSubscription: (\n\t\tdata: CreateSubscriptionParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreateSubscriptionResponse>;\n\n\t/**\n\t * Cancel a subscription\n\t */\n\tcancelSubscription: (\n\t\tdata: { subscriptionId: string },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ success: boolean }>;\n\n\t/**\n\t * Create a reusable preapproval plan (subscription template)\n\t */\n\tcreatePreapprovalPlan: (\n\t\tdata: CreatePreapprovalPlanParams,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<CreatePreapprovalPlanResponse>;\n\n\t/**\n\t * List all preapproval plans\n\t */\n\tlistPreapprovalPlans: (\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ plans: MercadoPagoPreapprovalPlanRecord[] }>;\n\n\t/**\n\t * Get payment by ID\n\t */\n\tgetPayment: (\n\t\tpaymentId: string,\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ payment: MercadoPagoPaymentRecord }>;\n\n\t/**\n\t * List all payments for the authenticated user\n\t */\n\tlistPayments: (\n\t\tparams?: { limit?: number; offset?: number },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ payments: MercadoPagoPaymentRecord[] }>;\n\n\t/**\n\t * List all subscriptions for the authenticated user\n\t */\n\tlistSubscriptions: (\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<{ subscriptions: MercadoPagoSubscriptionRecord[] }>;\n\n\t/**\n\t * Get OAuth authorization URL for marketplace sellers\n\t */\n\tgetOAuthUrl: (\n\t\tparams: { redirectUri: string },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<OAuthUrlResponse>;\n\n\t/**\n\t * Exchange OAuth code for access token\n\t */\n\texchangeOAuthCode: (\n\t\tdata: { code: string; redirectUri: string },\n\t\tfetchOptions?: BetterFetchOption,\n\t) => Promise<OAuthTokenResponse>;\n}\n\ntype mercadopagoPlugin = typeof mercadoPagoPlugin;\n\n// Export the actions type for Better Auth type inference\nexport type MercadoPagoClient = MercadoPagoClientActions;\n\nexport const mercadoPagoClientPlugin = () => {\n\treturn {\n\t\tid: \"mercadopago\",\n\t\t$InferServerPlugin: {} as ReturnType<mercadopagoPlugin>,\n\n\t\tgetActions: ($fetch: BetterFetch): MercadoPagoClientActions => ({\n\t\t\t/**\n\t\t\t * Get or create a Mercado Pago customer for the authenticated user\n\t\t\t */\n\t\t\tgetOrCreateCustomer: async (\n\t\t\t\tdata?: {\n\t\t\t\t\temail?: string;\n\t\t\t\t\tfirstName?: string;\n\t\t\t\t\tlastName?: string;\n\t\t\t\t},\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/customer\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data || {},\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a payment and get checkout URL\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createPayment({\n\t\t\t * items: [{\n\t\t\t * title: \"Premium Plan\",\n\t\t\t * quantity: 1,\n\t\t\t * unitPrice: 99.90,\n\t\t\t * currencyId: \"ARS\"\n\t\t\t * }]\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Redirect user to checkout\n\t\t\t * window.location.href = data.checkoutUrl;\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreatePayment: async (\n\t\t\t\tdata: CreatePaymentParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/payment/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a marketplace payment with automatic split\n\t\t\t *\n\t\t\t * You need to have the seller's MP User ID (collector_id) which they get\n\t\t\t * after authorizing your app via OAuth.\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createPayment({\n\t\t\t * items: [{\n\t\t\t * title: \"Product from Seller\",\n\t\t\t * quantity: 1,\n\t\t\t * unitPrice: 100\n\t\t\t * }],\n\t\t\t * marketplace: {\n\t\t\t * collectorId: \"123456789\", // Seller's MP User ID\n\t\t\t * applicationFeePercentage: 10 // Platform keeps 10%\n\t\t\t * }\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreateMarketplacePayment: async (\n\t\t\t\tdata: CreatePaymentParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/payment/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a subscription with recurring payments\n\t\t\t *\n\t\t\t * Supports two modes:\n\t\t\t * 1. With preapproval plan (reusable): Pass preapprovalPlanId\n\t\t\t * 2. Direct subscription (one-off): Pass reason + autoRecurring\n\t\t\t *\n\t\t\t * @example With plan\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createSubscription({\n\t\t\t * preapprovalPlanId: \"plan_abc123\"\n\t\t\t * });\n\t\t\t * ```\n\t\t\t *\n\t\t\t * @example Direct (without plan)\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createSubscription({\n\t\t\t * reason: \"Premium Monthly Plan\",\n\t\t\t * autoRecurring: {\n\t\t\t * frequency: 1,\n\t\t\t * frequencyType: \"months\",\n\t\t\t * transactionAmount: 99.90,\n\t\t\t * currencyId: \"ARS\"\n\t\t\t * }\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreateSubscription: async (\n\t\t\t\tdata: CreateSubscriptionParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/subscription/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Cancel a subscription\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * await authClient.mercadoPago.cancelSubscription({\n\t\t\t * subscriptionId: \"sub_123\"\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tcancelSubscription: async (\n\t\t\t\tdata: { subscriptionId: string },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/subscription/cancel\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Create a reusable preapproval plan (subscription template)\n\t\t\t *\n\t\t\t * Plans can be reused for multiple subscriptions. Create once,\n\t\t\t * use many times with createSubscription({ preapprovalPlanId })\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.createPreapprovalPlan({\n\t\t\t * reason: \"Premium Monthly\",\n\t\t\t * autoRecurring: {\n\t\t\t * frequency: 1,\n\t\t\t * frequencyType: \"months\",\n\t\t\t * transactionAmount: 99.90,\n\t\t\t * freeTrial: {\n\t\t\t * frequency: 7,\n\t\t\t * frequencyType: \"days\"\n\t\t\t * }\n\t\t\t * },\n\t\t\t * repetitions: 12 // 12 months, omit for infinite\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Use the plan\n\t\t\t * const planId = data.plan.mercadoPagoPlanId;\n\t\t\t * ```\n\t\t\t */\n\t\t\tcreatePreapprovalPlan: async (\n\t\t\t\tdata: CreatePreapprovalPlanParams,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/plan/create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * List all preapproval plans\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.listPreapprovalPlans();\n\t\t\t *\n\t\t\t * data.plans.forEach(plan => {\n\t\t\t * console.log(plan.reason); // \"Premium Monthly\"\n\t\t\t * console.log(plan.transactionAmount); // 99.90\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tlistPreapprovalPlans: async (fetchOptions?: BetterFetchOption) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/plans\", {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get payment by ID\n\t\t\t */\n\t\t\tgetPayment: async (\n\t\t\t\tpaymentId: string,\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(`/mercado-pago/payment/${paymentId}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * List all payments for the authenticated user\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.listPayments({\n\t\t\t * limit: 20,\n\t\t\t * offset: 0\n\t\t\t * });\n\t\t\t * ```\n\t\t\t */\n\t\t\tlistPayments: async (\n\t\t\t\tparams?: { limit?: number; offset?: number },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\tconst query = new URLSearchParams();\n\t\t\t\tif (params?.limit) query.set(\"limit\", params.limit.toString());\n\t\t\t\tif (params?.offset) query.set(\"offset\", params.offset.toString());\n\n\t\t\t\treturn await $fetch(`/mercado-pago/payments?${query.toString()}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * List all subscriptions for the authenticated user\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.listSubscriptions();\n\t\t\t * ```\n\t\t\t */\n\t\t\tlistSubscriptions: async (fetchOptions?: BetterFetchOption) => {\n\t\t\t\treturn await $fetch(`/mercado-pago/subscriptions`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get OAuth authorization URL for marketplace sellers\n\t\t\t *\n\t\t\t * This is Step 1 of OAuth flow. Redirect the seller to this URL so they\n\t\t\t * can authorize your app to process payments on their behalf.\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * const { data } = await authClient.mercadoPago.getOAuthUrl({\n\t\t\t * redirectUri: \"https://myapp.com/oauth/callback\"\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Redirect seller to authorize\n\t\t\t * window.location.href = data.authUrl;\n\t\t\t * ```\n\t\t\t */\n\t\t\tgetOAuthUrl: async (\n\t\t\t\tparams: { redirectUri: string },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\tconst query = new URLSearchParams();\n\t\t\t\tquery.set(\"redirectUri\", params.redirectUri);\n\n\t\t\t\treturn await $fetch(\n\t\t\t\t\t`/mercado-pago/oauth/authorize?${query.toString()}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\t...fetchOptions,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Exchange OAuth code for access token\n\t\t\t *\n\t\t\t * This is Step 2 of OAuth flow. After the seller authorizes and MP redirects\n\t\t\t * them back with a code, exchange that code for an access token.\n\t\t\t *\n\t\t\t * @example\n\t\t\t * ```ts\n\t\t\t * // In your /oauth/callback page:\n\t\t\t * const code = new URLSearchParams(window.location.search).get(\"code\");\n\t\t\t *\n\t\t\t * const { data } = await authClient.mercadoPago.exchangeOAuthCode({\n\t\t\t * code,\n\t\t\t * redirectUri: \"https://myapp.com/oauth/callback\"\n\t\t\t * });\n\t\t\t *\n\t\t\t * // Now you have the seller's MP User ID\n\t\t\t * console.log(data.oauthToken.mercadoPagoUserId);\n\t\t\t * ```\n\t\t\t */\n\t\t\texchangeOAuthCode: async (\n\t\t\t\tdata: { code: string; redirectUri: string },\n\t\t\t\tfetchOptions?: BetterFetchOption,\n\t\t\t) => {\n\t\t\t\treturn await $fetch(\"/mercado-pago/oauth/callback\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: data,\n\t\t\t\t\t...fetchOptions,\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t} satisfies BetterAuthClientPlugin;\n};\n"],"mappings":"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","names":["import_api","crypto"]}
|
package/dist/index.mjs
CHANGED
|
@@ -220,7 +220,7 @@ var ValidationRules = {
|
|
|
220
220
|
};
|
|
221
221
|
|
|
222
222
|
// client.ts
|
|
223
|
-
var
|
|
223
|
+
var mercadoPagoClientPlugin = () => {
|
|
224
224
|
return {
|
|
225
225
|
id: "mercadopago",
|
|
226
226
|
$InferServerPlugin: {},
|
|
@@ -1614,7 +1614,7 @@ var mercadoPagoPlugin = (options) => {
|
|
|
1614
1614
|
};
|
|
1615
1615
|
};
|
|
1616
1616
|
export {
|
|
1617
|
-
|
|
1617
|
+
mercadoPagoClientPlugin,
|
|
1618
1618
|
mercadoPagoPlugin
|
|
1619
1619
|
};
|
|
1620
1620
|
//# sourceMappingURL=index.mjs.map
|