Error Handling
Effective error handling is crucial for building robust integrations with the Localpayment API. Understanding the different error types and their corresponding codes will help you diagnose issues promptly and implement appropriate solutions.
Localpayment provides comprehensive error handling through standardized HTTP status codes and detailed error responses. This guide explains how to effectively handle errors in your integration to build resilient and user-friendly applications.
Overview
Proper error handling is crucial for creating reliable payment integrations. Localpayment uses a consistent error structure across all API endpoints to help you quickly identify and resolve issues.
Standardized Codes
Consistent error codes across all API endpoints and payment methods
Detailed Messages
Human-readable descriptions with specific error details
Best Practices
Proven strategies for handling errors in production environments
HTTP Response Codes
Localpayment utilizes standard HTTP status codes to indicate the success or failure of API requests:
| HTTP Code | Status | Description |
|---|---|---|
| 200 | OK | The request was successful and the response contains the requested data. |
| 201 | Created | The resource was successfully created (e.g., new payment initiated). |
| 400 | Bad Request | The request was malformed, contained invalid parameters, or missing required fields. |
| 401 | Unauthorized | Authentication failed, invalid credentials, or access token missing/expired. |
| 403 | Forbidden | The request is understood but has been refused due to insufficient permissions. |
| 404 | Not Found | The requested resource could not be found (e.g., invalid endpoint or transaction ID). |
| 409 | Conflict | The request conflicts with the current state of the resource (e.g., duplicate transaction). |
| 429 | Too Many Requests | Rate limit exceeded. Too many requests made in a given time frame. |
| 500 | Internal Server Error | An unexpected error occurred on Localpayment's servers. |
Error Response Structure
When an error occurs, Localpayment returns a JSON object with detailed error information:
{
"status": {
"code": "300",
"description": "REJECTED",
"detail": "Invalid param + [paymentMethod] + [Is mandatory]"
},
"errors": [
{
"code": "300",
"description": "REJECTED",
"detail": "Invalid param + [paymentMethod] + [Is mandatory]"
}
]
}Error Response Fields
| Field | Type | Description | Example |
|---|---|---|---|
| status.code | string | Localpayment-specific status code | 300 |
| status.description | string | Brief error description | REJECTED |
| status.detail | string | Detailed error message | Invalid param [paymentMethod] |
| errors[] | array | Array of specific error objects | See below |
| errors[].code | string | Localpayment-specific error code | 300 |
Common Error Scenarios
Authentication Errors
{
"detail": "Given token not valid for any token type",
"code": "token_not_valid",
"messages": [
{
"token_class": "AccessToken",
"token_type": "access",
"message": "Token is invalid or expired"
}
]
}Solution: Check your API credentials and ensure your access token is valid. Use the token refresh endpoint if needed.
Validation Errors
{
"externalId": "46014bdc-c3a7-1b15-8dcf-c7050c1c8199",
"internalId": "caa4e9aa-f634-497c-ba75-7f88b005ca62",
"status": {
"code": "801",
"description": "REJECTED",
"detail": "Params error"
},
"errors": [
{
"code": "300",
"detail": "Invalid param + [paymentMethod] + doesn´t exists for MEX"
},
{
"code": "300",
"detail": "Invalid param + [payer.bank.account.[number, type | alias]] + must not be null"
},
{
"code": "300",
"detail": "Invalid param + [payer.document.type] + is invalid for country MEX"
},
{
"code": "300",
"detail": "Invalid param + [payer.document] + is invalid for payer type"
},
{
"code": "701",
"detail": "IncorrectAccountNumber"
}
]
}Solution: Review the
errorsarray for specific field validation issues. Check API documentation for required fields and format specifications.
Business Logic Errors
{
"externalId": "8c0b537a-e907-4d87-93db-5dab9807e093",
"internalId": "dddfde6c-b61c-4b0e-8916-d88886133c4d",
"status": {
"code": "701",
"description": "REJECTED"
},
"errors": [
{
"code": "701",
"detail": "Invalid bank account number. Account number verification failed."
}
]
}Solution: These errors require business-level resolution. Check account balances, transaction limits, or contact support for specific restrictions.
Best Practices for Error Handling
1. Implement Comprehensive Logging
function handleApiError(error, context) {
const logEntry = {
timestamp: new Date().toISOString(),
context: context,
errorCode: error.status?.code,
errorDescription: error.status?.description,
errorDetail: error.status?.detail,
externalId: error.externalId,
httpStatus: error.httpStatus
};
console.error('Localpayment API Error:', logEntry);
// Send to your monitoring system
sendToMonitoring(logEntry);
}2. User-Friendly Error Messages
Create a mapping from technical error codes to user-friendly messages:
const errorMessages = {
'300': 'Please check your information and try again.',
'701': 'Your payment was declined. Please use a different payment method.',
'702': 'Payment authorization expired. Please try again.',
'703': 'Temporary system issue. Please try again in a few minutes.',
'default': 'An unexpected error occurred. Please contact support.'
};
function getUserMessage(errorCode) {
return errorMessages[errorCode] || errorMessages['default'];
}3. Retry Mechanism with Exponential Backoff
async function makeRequestWithRetry(apiCall, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await apiCall();
} catch (error) {
// Only retry on certain errors
if (!isRetryableError(error)) {
throw error;
}
if (attempt === maxRetries) {
throw error;
}
// Exponential backoff
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
function isRetryableError(error) {
const retryableCodes = ['500', '502', '503', '504', '800'];
return retryableCodes.includes(error.status?.code);
}4. Circuit Breaker Pattern
Implement a circuit breaker to prevent cascading failures:
class CircuitBreaker {
constructor(failureThreshold = 5, resetTimeout = 60000) {
this.failureThreshold = failureThreshold;
this.resetTimeout = resetTimeout;
this.failureCount = 0;
this.lastFailureTime = null;
this.state = 'CLOSED';
}
async call(apiFunction) {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime > this.resetTimeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await apiFunction();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
onSuccess() {
this.failureCount = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.failureCount >= this.failureThreshold) {
this.state = 'OPEN';
}
}
}Next Steps
API Reference
Complete list of error codes with detailed explanations
Testing Guide
Learn how to test error scenarios in sandbox
Support Contact
Get help with specific error scenarios
Pro Tip: Implement structured logging from day one. Include correlation IDs, error codes, and context information to make debugging much easier when issues occur in production.
Updated 4 days ago
