⚙️ Feature Type
Enhancement of existing feature
🎯 Problem to solve
As a developer integrating MercadoPago recurring subscriptions (preapproval) without an associated plan, I need the SDK / API to stop forcing me to provide a payer_email that is later cross-validated against the email the payer actually uses at checkout, because integrators cannot reliably guarantee that those two emails will match.
Why the current contract is impossible to satisfy
In my application (and in any application where users sign up with their own email), the email a user registers with on my platform is independent of the email they will use to pay in MercadoPago. The actual payer at the MP Checkout can be in one of two situations:
- Logged into their MercadoPago account, where the payer's identity is whatever MP email is associated with that account — frequently different from the one used on my app (work vs. personal email, alias, old account, etc.).
- Not logged into MercadoPago (guest checkout), where the checkout itself prompts the payer to enter an email. The payer can type any email and has no indication that it must match the one used during signup in my app.
In both cases the integrator has no lever to enforce a match: we don't know the payer's MP account email, and we cannot pre-fill, lock, or validate the email field shown by MP's guest checkout.
Official documentation that defines this behavior
Para crear una suscripción, es necesario vincularla con un correo electrónico. Esto permite obtener un identificador único para identificar al suscriptor. En el caso de suscripciones sin plan asociado, durante el proceso de pago, validamos si el correo electrónico proporcionado corresponde al utilizado por el pagador. Si esa validación no es exitosa, el pago será rechazado.
Source: https://www.mercadopago.com.ar/developers/es/reference/online-payments/subscriptions/create-preapproval/post
Inconsistent error reporting makes it worse
When the emails don't match, MercadoPago reports the failure in two different ways for the same root cause:
- In some cases, the checkout displays an explicit message: "Tu e-mail no coincide con el de la suscripción" ("Your email doesn't match the subscription's email"). This is at least actionable.
- In other cases, the payment is silently rejected with
cc_rejected_high_risk, indistinguishable from real fraud-risk rejections.
This inconsistency proves MP already has the information needed to detect the mismatch specifically — it does so in the first case — but folds it into a generic fraud rejection in the second. From the integrator's side, the same problem produces two completely different outcomes, neither of which we can act on programmatically.
Impact
- High rate of failed subscription conversions for legitimate users.
- Users assume their card was rejected and contact support.
- The only "workaround" available to end users is to guess the cause and create a duplicate account on my app using the email they have in MercadoPago — terrible UX and a real conversion blocker.
- Affects both logged-in MP payers and guest checkout payers, so forcing login is not a mitigation.
- No technical workaround exists on the integrator side.
💡 Proposed Solution
For preapprovals without an associated plan, I propose any of the following (in order of preference):
1. Make payer_email optional and let MP resolve the subscriber identity at checkout
The payer is always identified at the MP Checkout — either by being logged in, or by typing their email as a guest. MercadoPago is the system that knows (or collects) the real payer email, so the subscriber identity can be derived from the checkout itself instead of being declared up front by the integrator.
Suggested API behavior:
import { MercadoPagoConfig, PreApproval } from "mercadopago";
const client = new MercadoPagoConfig({ accessToken: process.env.MP_ACCESS_TOKEN });
const preapproval = new PreApproval(client);
// payer_email omitted — resolved from the checkout payer
await preapproval.create({
body: {
reason: "Monthly subscription",
auto_recurring: {
frequency: 1,
frequency_type: "months",
transaction_amount: 1000,
currency_id: "ARS",
},
back_url: "https://example.com/return",
status: "pending",
},
});
Once the payer completes the checkout, MP would set payer_email on the preapproval based on the real payer.
2. Treat payer_email as a hint / pre-fill, not a hard validation rule
If provided, MP would use it to pre-fill the guest checkout email field, but the payment would not be rejected on mismatch. The final payer_email stored on the preapproval would be the one the payer actually used.
🔄 Alternatives Considered
- Asking the user for their MercadoPago email before subscribing. Rejected: most users don't know off the top of their head which email is associated with their MP account, and we cannot verify it via API before creating the preapproval.
- Forcing users to log into MercadoPago before paying. Rejected: doesn't help, because (a) the logged-in MP email can still differ from the app email, and (b) it doesn't apply to guest checkout users at all.
- Pre-filling the MP checkout email field with the app's email. Not possible: guest checkout users can edit the email, and logged-in users use their MP account email regardless.
- Detecting the failure from the webhook / payment status and surfacing a friendly message. Not reliable: when MP returns the generic
cc_rejected_high_risk instead of the explicit "email doesn't match" message, the integrator cannot distinguish this case from a real fraud rejection.
- Telling users to register on the app with the same email they use on MP. Rejected: this requires the user to already understand the root cause, which they don't — the failure is opaque to them.
Reproduction (for context)
Case A — Logged-in MP payer
- User registers in my app with
userA@example.com.
- I create a preapproval with
payer_email: "userA@example.com".
- User pays in MP while logged into an MP account whose email is
userB@example.com.
- Payment is rejected — sometimes with the explicit "email doesn't match" message, sometimes silently with
cc_rejected_high_risk.
Case B — Guest checkout
- User registers in my app with
userA@example.com.
- I create a preapproval with
payer_email: "userA@example.com".
- User is not logged into MP and proceeds as guest.
- The MP checkout prompts for an email; the user enters
userB@example.com.
- Payment is rejected — same inconsistent reporting as Case A.
Environment
- SDK:
mercadopago (Node.js), version 2.12.0
- Country: Argentina (MLA)
- Flow: Preapproval (subscription) without associated plan
✅ Checklist
⚙️ Feature Type
Enhancement of existing feature
🎯 Problem to solve
As a developer integrating MercadoPago recurring subscriptions (preapproval) without an associated plan, I need the SDK / API to stop forcing me to provide a
payer_emailthat is later cross-validated against the email the payer actually uses at checkout, because integrators cannot reliably guarantee that those two emails will match.Why the current contract is impossible to satisfy
In my application (and in any application where users sign up with their own email), the email a user registers with on my platform is independent of the email they will use to pay in MercadoPago. The actual payer at the MP Checkout can be in one of two situations:
In both cases the integrator has no lever to enforce a match: we don't know the payer's MP account email, and we cannot pre-fill, lock, or validate the email field shown by MP's guest checkout.
Official documentation that defines this behavior
Source: https://www.mercadopago.com.ar/developers/es/reference/online-payments/subscriptions/create-preapproval/post
Inconsistent error reporting makes it worse
When the emails don't match, MercadoPago reports the failure in two different ways for the same root cause:
cc_rejected_high_risk, indistinguishable from real fraud-risk rejections.This inconsistency proves MP already has the information needed to detect the mismatch specifically — it does so in the first case — but folds it into a generic fraud rejection in the second. From the integrator's side, the same problem produces two completely different outcomes, neither of which we can act on programmatically.
Impact
💡 Proposed Solution
For preapprovals without an associated plan, I propose any of the following (in order of preference):
1. Make
payer_emailoptional and let MP resolve the subscriber identity at checkoutThe payer is always identified at the MP Checkout — either by being logged in, or by typing their email as a guest. MercadoPago is the system that knows (or collects) the real payer email, so the subscriber identity can be derived from the checkout itself instead of being declared up front by the integrator.
Suggested API behavior:
Once the payer completes the checkout, MP would set
payer_emailon the preapproval based on the real payer.2. Treat
payer_emailas a hint / pre-fill, not a hard validation ruleIf provided, MP would use it to pre-fill the guest checkout email field, but the payment would not be rejected on mismatch. The final
payer_emailstored on the preapproval would be the one the payer actually used.🔄 Alternatives Considered
cc_rejected_high_riskinstead of the explicit "email doesn't match" message, the integrator cannot distinguish this case from a real fraud rejection.Reproduction (for context)
Case A — Logged-in MP payer
userA@example.com.payer_email: "userA@example.com".userB@example.com.cc_rejected_high_risk.Case B — Guest checkout
userA@example.com.payer_email: "userA@example.com".userB@example.com.Environment
mercadopago(Node.js), version2.12.0✅ Checklist