Mercado Pago
Payment and subscription flows with Mercado Pago
Beztack supports Mercado Pago as a first-class payment provider, including plan sync, subscriptions, checkout preference, direct payment processing, and webhook/event handling.
For an overview of the provider-agnostic payment system, see Payments Core.
When to use Mercado Pago
Use Mercado Pago when you need:
- Native Mercado Pago plans/subscriptions
- Direct card payment processing
- Mercado Pago webhook-driven state updates
- Real-time payment events for frontend UX
See also: Polar
Required environment variables
API (apps/api/.env)
MERCADO_PAGO_ACCESS_TOKEN=APP_USR-...
MERCADO_PAGO_WEBHOOK_SECRET=... # optional but recommended
MERCADO_PAGO_INTEGRATOR_ID=... # optional
PAYMENT_PROVIDER=mercadopago
APP_URL=http://localhost:3000UI (apps/ui/.env)
VITE_PAYMENT_PROVIDER=mercadopago
VITE_MERCADO_PAGO_PUBLIC_KEY=APP_USR-...
VITE_API_URL=http://localhost:3000Implementation references:
- Env schemas:
packages/env/src/api.ts,packages/env/src/ui.ts - Provider factory:
apps/api/lib/payments/index.ts - React provider wiring:
apps/ui/src/app.tsx
API Routes
Unified routes (shared across all providers)
These routes are provider-agnostic and work with whichever provider is active:
GET /api/subscriptions/products— List products/plans from the active provider.POST /api/subscriptions/checkout— Create a checkout session.GET /api/subscriptions— List subscriptions for the current user.GET /api/subscriptions/:id— Get a specific subscription.PATCH /api/subscriptions/:id— Update a subscription.DELETE /api/subscriptions/:id— Cancel a subscription.POST /api/subscriptions/webhooks— Process webhook payloads (unified handler).
MercadoPago-specific route
POST /api/payments/mercado-pago/webhook— Validate and process MercadoPago-specific webhook payloads.
Admin plan management routes
GET /api/admin/plans— List all plans from the local DB.POST /api/admin/plans— Create a new plan.POST /api/admin/plans/import— Import plans from the provider.POST /api/admin/plans/sync— Sync all plans from the provider into the local DB.GET /api/admin/plans/sync-status— Check the current sync status.PATCH /api/admin/plans/:id— Update a plan.DELETE /api/admin/plans/:id— Delete a plan.
Plan sync flow
Beztack keeps a local plan mirror in the plan table (provider-agnostic, with a
providerPlanId field linking to the remote product ID) to make plan selection
and checkout flows predictable in the app.
GET /api/admin/plansreads local plans.POST /api/admin/plans/syncperforms an explicit admin-triggered sync from the provider.POST /api/admin/plans/importimports plans from the provider into the local DB.GET /api/admin/plans/sync-statusreports the current sync state.
Client integration
In UI, Mercado Pago is enabled by environment flags and wrapped with
MercadoPagoProvider.
<MercadoPagoProvider apiBaseUrl={env.VITE_API_URL} publicKey={mpPublicKey}>
{children}
</MercadoPagoProvider>The package @beztack/mercadopago/react exposes:
- Provider + context
- Hooks (
usePlans,useSyncPlans,useSubscriptions, etc.) - Components for subscriptions, status badges, billing history, and bricks
Testing checklist
- Configure sandbox credentials and
VITE_MERCADO_PAGO_PUBLIC_KEY. - Test checkout via
POST /api/subscriptions/checkout. - Trigger/receive webhook events and verify local DB updates.
- Validate plan sync via admin routes (
/api/admin/plans/sync). - Verify SSE events in the UI (if using the events endpoint).
Troubleshooting
401/403on plan sync/create: verify admin session.- Missing webhook updates: verify
MERCADO_PAGO_WEBHOOK_SECRETand public URL. - Provider not active in UI: check
VITE_PAYMENT_PROVIDER=mercadopagoand public key presence. - Wrong API base: confirm
VITE_API_URLpoints to the running API.