Skip to content

[Feature Request / Discussion] Reconsider the mandatory "payer_email" requirement for preapproval #421

@agustinglez

Description

@agustinglez

⚙️ 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:

  1. 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.).
  2. 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

  1. User registers in my app with userA@example.com.
  2. I create a preapproval with payer_email: "userA@example.com".
  3. User pays in MP while logged into an MP account whose email is userB@example.com.
  4. Payment is rejected — sometimes with the explicit "email doesn't match" message, sometimes silently with cc_rejected_high_risk.

Case B — Guest checkout

  1. User registers in my app with userA@example.com.
  2. I create a preapproval with payer_email: "userA@example.com".
  3. User is not logged into MP and proceeds as guest.
  4. The MP checkout prompts for an email; the user enters userB@example.com.
  5. 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

  • I have searched existing issues and this feature has not been requested before
  • I have clearly described the problem I am trying to solve
  • I have proposed a concrete solution or API design
  • This feature would benefit other users, not just my specific use case
  • I have not included any sensitive information (tokens, credentials, real data)

Metadata

Metadata

Labels

enhancementImprovement or expansion of an existing feature.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions