Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mercadopago/sdk-java/llms.txt

Use this file to discover all available pages before exploring further.

The Mercado Pago Subscriptions API lets you automate recurring charges on a payer’s payment method according to a defined billing schedule. The SDK exposes two complementary clients: PreApprovalPlanClient manages reusable plan templates that encode billing frequency, currency, and amount; PreapprovalClient manages individual subscriptions (preapprovals) that link a specific payer to one of those plans — or to standalone recurring configuration. Together they cover the full lifecycle from plan creation through subscriber management and status updates.
Set your access token once at application startup before using any client:
MercadoPagoConfig.setAccessToken("YOUR_ACCESS_TOKEN");

Subscription Plans (PreApprovalPlanClient)

A subscription plan is a reusable template that defines the billing rules (frequency, currency, amount) shared by every subscriber who signs up through it. Creating a plan first simplifies subscriber management because all subscribers inherit the same billing terms.

Create a plan

Build a PreApprovalPlanCreateRequest with a human-readable reason, a backUrl where subscribers are redirected after checkout, and an autoRecurring block that defines the billing cycle.
import com.mercadopago.MercadoPagoConfig;
import com.mercadopago.client.preapprovalplan.PreApprovalPlanAutoRecurringCreateRequest;
import com.mercadopago.client.preapprovalplan.PreApprovalPlanClient;
import com.mercadopago.client.preapprovalplan.PreApprovalPlanCreateRequest;
import com.mercadopago.resources.preapprovalplan.PreApprovalPlan;
import java.math.BigDecimal;

MercadoPagoConfig.setAccessToken("YOUR_ACCESS_TOKEN");

PreApprovalPlanClient client = new PreApprovalPlanClient();

PreApprovalPlanCreateRequest request = PreApprovalPlanCreateRequest.builder()
    .reason("Monthly yoga subscription")
    .backUrl("https://yourapp.com/subscription/back")
    .externalReference("PLAN-YOGA-MONTHLY-001")
    .autoRecurring(PreApprovalPlanAutoRecurringCreateRequest.builder()
        .frequency(1)
        .frequencyType("months")
        .currencyId("BRL")
        .transactionAmount(new BigDecimal("49.90"))
        .repetitions(12) // null for indefinite
        .build())
    .build();

PreApprovalPlan plan = client.create(request);
System.out.println("Plan ID:     " + plan.getId());
System.out.println("Init point:  " + plan.getInitPoint());
Share plan.getInitPoint() with prospective subscribers — it is the checkout URL where they authorise the recurring charge.

PreApprovalPlanAutoRecurringCreateRequest fields

FieldTypeDescription
frequencyTypeStringTime unit: "days" or "months"
frequencyIntegerNumber of frequencyType units between each billing cycle
currencyIdStringISO 4217 currency code (e.g. "BRL", "ARS", "MXN")
transactionAmountBigDecimalAmount charged on each cycle
repetitionsIntegerMaximum billing cycles; omit or set null for indefinite

Get a plan

PreApprovalPlanClient client = new PreApprovalPlanClient();

PreApprovalPlan plan = client.get("2c938084726fca480172750000000000");
System.out.println("Plan reason: " + plan.getReason());
System.out.println("Status:      " + plan.getStatus());

Update a plan

Use PreApprovalPlanUpdateRequest to change the plan’s title, back URL, status, or auto-recurring configuration. Only the fields you include are updated.
import com.mercadopago.client.preapprovalplan.PreApprovalPlanUpdateRequest;
import com.mercadopago.client.preapprovalplan.PreApprovalPlanAutoRecurringUpdateRequest;

PreApprovalPlanClient client = new PreApprovalPlanClient();

PreApprovalPlanUpdateRequest updateRequest = PreApprovalPlanUpdateRequest.builder()
    .reason("Monthly yoga subscription – updated price")
    .backUrl("https://yourapp.com/subscription/back-v2")
    .autoRecurring(PreApprovalPlanAutoRecurringUpdateRequest.builder()
        // add updated recurring fields here if needed
        .build())
    .build();

PreApprovalPlan updated = client.update("2c938084726fca480172750000000000", updateRequest);
System.out.println("Updated reason: " + updated.getReason());
To deactivate a plan, set status("cancelled") in the update request.

Search plans

PreApprovalPlanClient.search(MPSearchRequest) returns a paginated MPResultsResourcesPage<PreApprovalPlan>.
import com.mercadopago.net.MPSearchRequest;
import com.mercadopago.net.MPResultsResourcesPage;
import java.util.HashMap;
import java.util.Map;

PreApprovalPlanClient client = new PreApprovalPlanClient();

Map<String, Object> filters = new HashMap<>();
filters.put("status", "active");

MPSearchRequest searchRequest = MPSearchRequest.builder()
    .offset(0)
    .limit(20)
    .filters(filters)
    .build();

MPResultsResourcesPage<PreApprovalPlan> results = client.search(searchRequest);
System.out.println("Total plans found: " + results.getPaging().getTotal());
results.getResults().forEach(p -> System.out.println(p.getId() + " – " + p.getReason()));

Preapprovals (PreapprovalClient)

A preapproval represents an individual subscription — the binding agreement between a specific payer and a seller. Each preapproval has its own lifecycle (pending, authorized, paused, cancelled) and tracks the nextPaymentDate for the next automatic charge.

Create a preapproval

Provide the payer’s email, your collectorId, and an autoRecurring configuration.
import com.mercadopago.client.preapproval.PreApprovalAutoRecurringCreateRequest;
import com.mercadopago.client.preapproval.PreapprovalClient;
import com.mercadopago.client.preapproval.PreapprovalCreateRequest;
import com.mercadopago.resources.preapproval.Preapproval;
import java.math.BigDecimal;
import java.time.OffsetDateTime;

PreapprovalClient client = new PreapprovalClient();

PreapprovalCreateRequest request = PreapprovalCreateRequest.builder()
    .payerEmail("subscriber@example.com")
    .backUrl("https://yourapp.com/subscription/back")
    .reason("Monthly yoga class access")
    .externalReference("SUB-YOGA-2024-001")
    .status("pending")
    .autoRecurring(PreApprovalAutoRecurringCreateRequest.builder()
        .currencyId("BRL")
        .transactionAmount(new BigDecimal("49.90"))
        .frequency(1)
        .frequencyType("months")
        .startDate(OffsetDateTime.now().plusDays(1))
        .endDate(OffsetDateTime.now().plusYears(1))
        .build())
    .build();

Preapproval subscription = client.create(request);
System.out.println("Preapproval ID:   " + subscription.getId());
System.out.println("Status:           " + subscription.getStatus());
System.out.println("Checkout URL:     " + subscription.getInitPoint());
System.out.println("Next payment:     " + subscription.getNextPaymentDate());

PreapprovalCreateRequest fields

FieldTypeDescription
payerEmailStringEmail address of the subscriber
backUrlStringRedirect URL after the preapproval flow
collectorIdStringUnique ID of the seller (collector)
reasonStringTitle or description shown to the subscriber
externalReferenceStringYour internal reference for reconciliation
statusStringInitial status ("pending" or "authorized")
autoRecurringPreApprovalAutoRecurringCreateRequestBilling configuration (see below)

PreApprovalAutoRecurringCreateRequest fields

FieldTypeDescription
currencyIdStringISO 4217 currency code
transactionAmountBigDecimalAmount charged each cycle
frequencyIntegerNumber of frequencyType units per cycle
frequencyTypeString"days" or "months"
startDateOffsetDateTimeWhen billing starts
endDateOffsetDateTimeWhen billing ends (omit for open-ended)

Get a preapproval

PreapprovalClient client = new PreapprovalClient();

Preapproval subscription = client.get("2c938084726fca480172750000000001");
System.out.println("Status:         " + subscription.getStatus());
System.out.println("Payer email:    " + subscription.getPayerEmail());
System.out.println("Next payment:   " + subscription.getNextPaymentDate());
System.out.println("Init point:     " + subscription.getInitPoint());

Update a preapproval

PreapprovalUpdateRequest lets you change the back URL, reason, external reference, status, or billing configuration of an existing preapproval.
import com.mercadopago.client.preapproval.PreapprovalUpdateRequest;

PreapprovalClient client = new PreapprovalClient();

PreapprovalUpdateRequest pauseRequest = PreapprovalUpdateRequest.builder()
    .status("paused")
    .build();

Preapproval paused = client.update("2c938084726fca480172750000000001", pauseRequest);
System.out.println("New status: " + paused.getStatus());

Search preapprovals

import com.mercadopago.net.MPSearchRequest;
import com.mercadopago.net.MPResultsResourcesPage;
import com.mercadopago.resources.preapproval.Preapproval;
import java.util.HashMap;
import java.util.Map;

PreapprovalClient client = new PreapprovalClient();

Map<String, Object> filters = new HashMap<>();
filters.put("payer_email", "subscriber@example.com");
filters.put("status", "authorized");

MPSearchRequest searchRequest = MPSearchRequest.builder()
    .offset(0)
    .limit(10)
    .filters(filters)
    .build();

MPResultsResourcesPage<Preapproval> page = client.search(searchRequest);
System.out.println("Total: " + page.getPaging().getTotal());
page.getResults().forEach(s ->
    System.out.println(s.getId() + " | " + s.getStatus() + " | " + s.getNextPaymentDate())
);

Error handling

Both clients throw MPException for transport/SDK-level errors and MPApiException when the API returns a non-2xx status. Always handle both:
import com.mercadopago.exceptions.MPApiException;
import com.mercadopago.exceptions.MPException;

try {
    Preapproval subscription = client.create(request);
} catch (MPApiException e) {
    System.err.println("API error – status: " + e.getStatusCode());
    System.err.println("Message: "            + e.getMessage());
} catch (MPException e) {
    System.err.println("SDK error: " + e.getMessage());
}
Always validate payer consent before creating a preapproval. Sending the subscriber to initPoint is required for them to explicitly authorise the recurring charge.

Build docs developers (and LLMs) love