The package includes demo routes and utilities to help you test your integration without making real payments.
Demo routes
Demo routes are special endpoints that only work in local and testing environments. They’re disabled automatically in production for security.
Enabling demo routes
Set these environment variables:
APP_ENV =local
MERCADOPAGO_ENABLE_DEMO_ROUTES =true
Demo routes automatically disable in production (APP_ENV=production) regardless of the ENABLE_DEMO_ROUTES setting.
Available demo routes
All routes use the configured prefix (default: /api/mercadopago):
Method Route Purpose GET/healthVerify configuration GET/payment-methodsList available payment methods POST/preferencesCreate payment preference POST/paymentsCreate direct payment GET/payments/{id}Get payment details POST/payments/{id}/refundsRefund payment POST/customersCreate customer GET/customers/{id}Get customer details POST/customers/{id}/cardsAdd card to customer DELETE/customers/{id}/cards/{cardId}Delete customer card POST/test-usersCreate test user
Verifying demo routes
Check that routes are registered:
php artisan route:list --name=mercadopago
Expected output:
GET|HEAD api/mercadopago/health ................ mercadopago.health
GET|HEAD api/mercadopago/payment-methods ....... mercadopago.payment-methods.index
POST api/mercadopago/preferences ........... mercadopago.preferences.store
POST api/mercadopago/payments .............. mercadopago.payments.store
GET|HEAD api/mercadopago/payments/{paymentId} .. mercadopago.payments.show
POST api/mercadopago/payments/{id}/refunds . mercadopago.payments.refund
POST api/mercadopago/customers ............. mercadopago.customers.store
GET|HEAD api/mercadopago/customers/{id} ........ mercadopago.customers.show
POST api/mercadopago/customers/{id}/cards .. mercadopago.customers.cards.store
DELETE api/mercadopago/customers/{id}/cards/.. mercadopago.customers.cards.destroy
POST api/mercadopago/test-users ............ mercadopago.test-users.store
POST api/mercadopago/webhooks .............. mercadopago.webhooks.store
Testing with cURL
Health check
Verify credentials are configured:
curl http://localhost:8000/api/mercadopago/health
Response:
{
"ok" : true ,
"data" : {
"configured" : true ,
"has_public_key" : true ,
"has_webhook_secret" : true ,
"environment" : "local"
},
"meta" : []
}
Create preference
curl --request POST \
--url http://localhost:8000/api/mercadopago/preferences \
--header 'Content-Type: application/json' \
--data '{
"items": [
{
"title": "Test Product",
"quantity": 1,
"unit_price": 100
}
]
}'
Create payment
curl --request POST \
--url http://localhost:8000/api/mercadopago/payments \
--header 'Content-Type: application/json' \
--data '{
"transaction_amount": 100,
"token": "CARD_TOKEN",
"description": "Test payment",
"installments": 1,
"payment_method_id": "visa",
"payer": {
"email": "[email protected] "
}
}'
Get payment
curl http://localhost:8000/api/mercadopago/payments/123456789
Create refund
# Full refund
curl --request POST \
--url http://localhost:8000/api/mercadopago/payments/123456789/refunds \
--header 'Content-Type: application/json' \
--data '{}'
# Partial refund
curl --request POST \
--url http://localhost:8000/api/mercadopago/payments/123456789/refunds \
--header 'Content-Type: application/json' \
--data '{ "amount": 50 }'
Test users
MercadoPago provides test user accounts for integration testing. Create them using the demo endpoint:
curl --request POST \
--url http://localhost:8000/api/mercadopago/test-users \
--header 'Content-Type: application/json' \
--data '{
"site_id": "MLA",
"description": "Test user for QA"
}'
Supported site IDs
Create test users for different countries:
Site ID Country MLAArgentina MLBBrazil MLCChile MLMMexico MLUUruguay MCOColombia MPEPeru
Site ID validation is defined in src/Http/Requests/CreateTestUserRequest.php
Test user response
{
"ok" : true ,
"data" : {
"id" : 123456789 ,
"nickname" : "TESTUSER123456" ,
"password" : "qatest1234" ,
"site_status" : "active" ,
"email" : "[email protected] "
},
"meta" : []
}
Use these credentials to:
Log into MercadoPago’s sandbox
Create test payments
Test checkout flows
Testing webhooks locally
Webhooks require a publicly accessible URL. Use tunneling services to expose your local server:
You’ll get a public URL like:
Register your tunnel URL in MercadoPago:
https://abc123.ngrok.io/api/mercadopago/webhooks
Or set it per preference/payment:
curl --request POST \
--url http://localhost:8000/api/mercadopago/preferences \
--header 'Content-Type: application/json' \
--data '{
"items": [...],
"notification_url": "https://abc123.ngrok.io/api/mercadopago/webhooks"
}'
Manual webhook simulation
Test your webhook endpoint without MercadoPago:
curl --request POST \
--url http://localhost:8000/api/mercadopago/webhooks \
--header 'Content-Type: application/json' \
--header 'x-request-id: test-request-123' \
--data '{
"type": "payment",
"data": {
"id": "123456789"
}
}'
Without a valid signature, webhooks are marked as validated: false. For production testing, ensure MERCADOPAGO_WEBHOOK_SECRET is configured.
Automated testing
Feature tests
Test your integration with Laravel’s HTTP testing:
use Tests\ TestCase ;
use Fitodac\LaravelMercadoPago\Services\ PreferenceService ;
class PreferenceTest extends TestCase
{
public function test_creates_preference ()
{
$response = $this -> postJson ( '/api/mercadopago/preferences' , [
'items' => [
[
'title' => 'Test Product' ,
'quantity' => 1 ,
'unit_price' => 100 ,
],
],
]);
$response -> assertStatus ( 201 )
-> assertJsonStructure ([
'ok' ,
'data' => [ 'id' , 'init_point' ],
]);
}
}
Mocking services
Mock MercadoPago services in tests:
use Fitodac\LaravelMercadoPago\Services\ PaymentService ;
public function test_processes_payment ()
{
$this -> mock ( PaymentService :: class , function ( $mock ) {
$mock -> shouldReceive ( 'create' )
-> once ()
-> andReturn ([
'id' => 123456789 ,
'status' => 'approved' ,
'status_detail' => 'accredited' ,
]);
});
$response = $this -> postJson ( '/checkout/payment' , [
'amount' => 100 ,
'card_token' => 'CARD_TOKEN' ,
]);
$response -> assertStatus ( 201 )
-> assertJson ([ 'status' => 'approved' ]);
}
Testing webhooks
Test webhook handling:
use Fitodac\LaravelMercadoPago\Services\ WebhookService ;
public function test_handles_webhook ()
{
$response = $this -> postJson ( '/api/mercadopago/webhooks' , [
'type' => 'payment' ,
'data' => [ 'id' => '123456789' ],
]);
$response -> assertStatus ( 200 )
-> assertJson ([ 'ok' => true ]);
}
public function test_validates_webhook_signature ()
{
config ([ 'mercadopago.webhook_secret' => 'test-secret' ]);
$response = $this -> postJson ( '/api/mercadopago/webhooks' , [
'type' => 'payment' ,
'data' => [ 'id' => '123456789' ],
], [
'x-signature' => 'invalid' ,
'x-request-id' => 'test-123' ,
]);
$response -> assertStatus ( 401 );
}
Testing strategies
Smoke tests
Minimal tests to verify setup:
# 1. Check routes are registered
php artisan route:list --name=mercadopago
# 2. Verify configuration
curl http://localhost:8000/api/mercadopago/health
# 3. Test payment methods endpoint
curl http://localhost:8000/api/mercadopago/payment-methods
Integration tests
Test full payment flows:
Create preference
curl -X POST http://localhost:8000/api/mercadopago/preferences \
-H 'Content-Type: application/json' \
-d '{"items": [{"title": "Test", "quantity": 1, "unit_price": 100}]}'
Open checkout URL
Use the sandbox_init_point URL in a browser to complete test payment
Verify webhook
Check your webhook endpoint receives notification
Query payment status
curl http://localhost:8000/api/mercadopago/payments/PAYMENT_ID
Test data
Use consistent test data for reproducibility:
class TestData
{
public static function preference () : array
{
return [
'items' => [
[
'title' => 'Test Product' ,
'quantity' => 1 ,
'unit_price' => 100.50 ,
],
],
'payer' => [
'email' => '[email protected] ' ,
],
'external_reference' => 'TEST-' . time (),
];
}
public static function payment () : array
{
return [
'transaction_amount' => 100.50 ,
'token' => 'CARD_TOKEN' ,
'description' => 'Test payment' ,
'installments' => 1 ,
'payment_method_id' => 'visa' ,
'payer' => [
'email' => '[email protected] ' ,
],
];
}
}
Test cards
MercadoPago provides test card numbers. Consult their official documentation for:
Test card numbers that simulate approved payments
Test card numbers that simulate rejected payments
Test card numbers for different rejection reasons
CVV and expiration dates for testing
Never use real card numbers in testing environments. Always use official test cards provided by MercadoPago.
Debugging
Enable query logging
Log all API calls during testing:
\ Log :: info ( 'Creating payment' , $payload );
$payment = $paymentService -> create ( $payload );
\ Log :: info ( 'Payment created' , $payment );
Check Laravel logs
tail -f storage/logs/laravel.log
Verify environment
Ensure correct environment configuration:
php artisan config:clear
php artisan config:cache
php artisan tinker
>>> config( 'mercadopago.access_token' )
>>> config( 'mercadopago.enable_demo_routes' )
>>> app () ->environment ()
Common testing issues
404 on demo routes
Cause : Demo routes disabled in production or not enabled
Solution :
# Check environment
php artisan tinker
>>> app () ->environment () # Must be 'local' or 'testing'
>>> config( 'mercadopago.enable_demo_routes' ) # Must be true
Webhook returns 401
Cause : Invalid signature validation
Solution : Either configure valid MERCADOPAGO_WEBHOOK_SECRET or test without signature headers
Routes not found
Cause : Package not auto-discovered
Solution :
composer dump-autoload
php artisan package:discover
php artisan route:clear
php artisan route:cache
Production testing checklist
Before deploying to production:
✅ Demo routes are disabled (ENABLE_DEMO_ROUTES=false)
✅ Production credentials configured
✅ Webhook secret configured
✅ HTTPS enabled
✅ Webhook URL registered in MercadoPago
✅ Error logging configured
✅ Test payment processed successfully
✅ Webhook received and processed
✅ Refund tested
Next steps
Quickstart Get started with your first integration
Handling Webhooks Set up production webhook handling
API Reference Explore all available services