> For the complete documentation index, see [llms.txt](https://plexo.gitbook.io/rest-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://plexo.gitbook.io/rest-api/tools/code-examples.md).

# Code Examples

Complete code examples for integrating with the Plexo Payment Gateway API in multiple programming languages.

## Overview

This guide provides production-ready code examples for common API operations. All examples include:

* ✅ Error handling
* ✅ Environment variable support
* ✅ Best practices
* ✅ Authentication
* ✅ Type safety (where applicable)

## Authentication

All API requests require Basic Authentication. Store credentials securely:

{% tabs %}
{% tab title="Environment Variables" %}

```bash
# .env file
PLEXO_USERNAME=your_username
PLEXO_PASSWORD=your_password
PLEXO_API_URL=https://api.plexo.com.uy
PLEXO_MERCHANT_ID=your_merchant_id
```

{% endtab %}

{% tab title="Never Hardcode" %}

```javascript
// ❌ DON'T DO THIS
const username = 'john@merchant.com';
const password = 'MyPassword123';

// ✅ DO THIS
const username = process.env.PLEXO_USERNAME;
const password = process.env.PLEXO_PASSWORD;
```

{% endtab %}
{% endtabs %}

***

## Language-Specific Examples

### JavaScript / TypeScript

#### Setup

```bash
npm install node-fetch dotenv
# or
npm install axios dotenv
```

#### Fetch API

```javascript
// plexo-client.js
import fetch from 'node-fetch';
import dotenv from 'dotenv';

dotenv.config();

class PlexoClient {
  constructor() {
    this.baseUrl = process.env.PLEXO_API_URL || 'https://api.plexo.com.uy';
    this.username = process.env.PLEXO_USERNAME;
    this.password = process.env.PLEXO_PASSWORD;
    this.merchantId = parseInt(process.env.PLEXO_MERCHANT_ID);

    if (!this.username || !this.password) {
      throw new Error('PLEXO_USERNAME and PLEXO_PASSWORD are required');
    }

    // Base64 encode credentials
    this.authHeader = 'Basic ' + Buffer.from(
      `${this.username}:${this.password}`
    ).toString('base64');
  }

  async request(method, path, body = null) {
    const url = `${this.baseUrl}${path}`;
    const headers = {
      'Authorization': this.authHeader,
      'Content-Type': 'application/json'
    };

    const options = {
      method,
      headers,
      ...(body && { body: JSON.stringify(body) })
    };

    try {
      const response = await fetch(url, options);
      const data = await response.json();

      if (!response.ok) {
        throw new Error(
          `API Error: ${data.message || response.statusText}`
        );
      }

      return data;
    } catch (error) {
      console.error('Request failed:', error);
      throw error;
    }
  }

  // Customer operations
  async createCustomer(customerData) {
    return this.request('POST', '/v1/customers', customerData);
  }

  async getCustomer(customerId) {
    return this.request('GET', `/v1/customers/${customerId}`);
  }

  async listCustomers(params = {}) {
    const query = new URLSearchParams(params).toString();
    const path = `/v1/customers${query ? '?' + query : ''}`;
    return this.request('GET', path);
  }

  // Session operations
  async createSession(sessionData) {
    return this.request('POST', '/v1/sessions', sessionData);
  }

  async getSession(sessionId) {
    return this.request('GET', `/v1/sessions/${sessionId}`);
  }

  // Payment operations
  async createPayment(paymentData) {
    return this.request('POST', '/v1/payments', paymentData);
  }

  async getPayment(paymentId) {
    return this.request('GET', `/v1/payments/${paymentId}`);
  }

  async capturePayment(paymentId, captureData) {
    return this.request(
      'POST',
      `/v1/payments/${paymentId}/captures`,
      captureData
    );
  }

  async cancelPayment(paymentId, cancellationData) {
    return this.request(
      'POST',
      `/v1/payments/${paymentId}/cancellations`,
      cancellationData
    );
  }

  async refundPayment(paymentId, refundData) {
    return this.request(
      'POST',
      `/v1/payments/${paymentId}/refunds`,
      refundData
    );
  }
}

// Usage example
async function main() {
  const client = new PlexoClient();

  try {
    // Create a customer
    const customer = await client.createCustomer({
      referenceId: `customer-${Date.now()}`,
      email: 'john.doe@example.com',
      firstName: 'John',
      lastName: 'Doe',
      phone: '+1-555-0123'
    });
    console.log('Customer created:', customer.id);

    // Create tokenization session
    const session = await client.createSession({
      merchantId: client.merchantId,
      type: 'tokenization',
      referenceId: `session-${Date.now()}`,
      customerId: customer.id,
      callbackUrl: 'https://yoursite.com/callback'
    });
    console.log('Session URL:', session.actions.find(a => a.rel === 'REDIRECT').href);

    // Later: Create payment with token
    const payment = await client.createPayment({
      merchantId: client.merchantId,
      amount: 100.00,
      currency: 'USD',
      customerId: customer.id,
      instrumentId: 'token-from-session',
      capture: true
    });
    console.log('Payment created:', payment.id);

  } catch (error) {
    console.error('Operation failed:', error.message);
    process.exit(1);
  }
}

main();
```

#### Axios

```javascript
import axios from 'axios';
import dotenv from 'dotenv';

dotenv.config();

const client = axios.create({
  baseURL: process.env.PLEXO_API_URL || 'https://api.plexo.com.uy',
  auth: {
    username: process.env.PLEXO_USERNAME,
    password: process.env.PLEXO_PASSWORD
  },
  headers: {
    'Content-Type': 'application/json'
  }
});

// Add response interceptor for error handling
client.interceptors.response.use(
  response => response.data,
  error => {
    const message = error.response?.data?.message || error.message;
    console.error('API Error:', message);
    return Promise.reject(new Error(message));
  }
);

// Usage
async function createCustomer(data) {
  return client.post('/v1/customers', data);
}

async function getPayment(paymentId) {
  return client.get(`/v1/payments/${paymentId}`);
}
```

***

### Python

#### Setup

```bash
pip install requests python-dotenv
```

#### requests

```python
# plexo_client.py
import os
import requests
from typing import Optional, Dict, Any
from dotenv import load_dotenv

load_dotenv()

class PlexoClient:
    def __init__(self):
        self.base_url = os.getenv('PLEXO_API_URL', 'https://api.plexo.com.uy')
        self.username = os.getenv('PLEXO_USERNAME')
        self.password = os.getenv('PLEXO_PASSWORD')
        self.merchant_id = int(os.getenv('PLEXO_MERCHANT_ID'))

        if not self.username or not self.password:
            raise ValueError('PLEXO_USERNAME and PLEXO_PASSWORD are required')

        self.auth = (self.username, self.password)
        self.headers = {'Content-Type': 'application/json'}

    def _request(
        self,
        method: str,
        path: str,
        data: Optional[Dict[str, Any]] = None,
        params: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Make HTTP request to Plexo API."""
        url = f'{self.base_url}{path}'

        try:
            response = requests.request(
                method=method,
                url=url,
                auth=self.auth,
                headers=self.headers,
                json=data,
                params=params
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.HTTPError as e:
            error_data = e.response.json() if e.response.text else {}
            error_msg = error_data.get('message', str(e))
            raise Exception(f'API Error: {error_msg}') from e
        except requests.exceptions.RequestException as e:
            raise Exception(f'Request failed: {str(e)}') from e

    # Customer operations
    def create_customer(self, customer_data: Dict[str, Any]) -> Dict[str, Any]:
        """Create a new customer."""
        return self._request('POST', '/v1/customers', data=customer_data)

    def get_customer(self, customer_id: str) -> Dict[str, Any]:
        """Get customer by ID."""
        return self._request('GET', f'/v1/customers/{customer_id}')

    def list_customers(
        self,
        page: int = 1,
        page_size: int = 20,
        **filters
    ) -> Dict[str, Any]:
        """List customers with pagination."""
        params = {'page': page, 'pageSize': page_size, **filters}
        return self._request('GET', '/v1/customers', params=params)

    # Session operations
    def create_session(self, session_data: Dict[str, Any]) -> Dict[str, Any]:
        """Create tokenization or checkout session."""
        return self._request('POST', '/v1/sessions', data=session_data)

    def get_session(self, session_id: str) -> Dict[str, Any]:
        """Get session by ID."""
        return self._request('GET', f'/v1/sessions/{session_id}')

    # Payment operations
    def create_payment(self, payment_data: Dict[str, Any]) -> Dict[str, Any]:
        """Create a payment."""
        return self._request('POST', '/v1/payments', data=payment_data)

    def get_payment(self, payment_id: str) -> Dict[str, Any]:
        """Get payment by ID."""
        return self._request('GET', f'/v1/payments/{payment_id}')

    def capture_payment(
        self,
        payment_id: str,
        capture_data: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Capture authorized payment."""
        return self._request(
            'POST',
        f'/v1/payments/{payment_id}/captures',
            data=capture_data or {}
        )

    def cancel_payment(
        self,
        payment_id: str,
        cancellation_data: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Cancel eligible payment."""
        return self._request(
            'POST',
            f'/v1/payments/{payment_id}/cancellations',
            data=cancellation_data
        )

    def refund_payment(
        self,
        payment_id: str,
        refund_data: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Refund captured payment."""
        return self._request(
            'POST',
        f'/v1/payments/{payment_id}/refunds',
            data=refund_data
        )

# Usage example
if __name__ == '__main__':
    client = PlexoClient()

    try:
        # Create customer
        customer = client.create_customer({
            'referenceId': f'customer-{int(time.time())}',
            'email': 'john.doe@example.com',
            'firstName': 'John',
            'lastName': 'Doe',
            'phone': '+1-555-0123'
        })
        print(f"Customer created: {customer['id']}")

        # Create tokenization session
        session = client.create_session({
            'merchantId': client.merchant_id,
            'type': 'tokenization',
            'referenceId': f'session-{int(time.time())}',
            'customerId': customer['id'],
            'callbackUrl': 'https://yoursite.com/callback'
        })
        redirect_url = next(
            a['href'] for a in session['actions'] if a['rel'] == 'REDIRECT'
        )
        print(f"Session URL: {redirect_url}")

        # Later: Create payment
        payment = client.create_payment({
            'merchantId': client.merchant_id,
            'amount': 100.00,
            'currency': 'USD',
            'customerId': customer['id'],
            'instrumentId': 'token-from-session',
            'capture': True
        })
        print(f"Payment created: {payment['id']}")

    except Exception as e:
        print(f"Operation failed: {e}")
        exit(1)
```

***

### C# / .NET

#### Setup

```bash
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Json
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
```

#### HttpClient

```csharp
// PlexoClient.cs
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;

public class PlexoClient : IDisposable
{
    private readonly HttpClient _client;
    private readonly int _merchantId;

    public PlexoClient(IConfiguration configuration)
    {
        var baseUrl = configuration["PLEXO_API_URL"] ?? "https://api.plexo.com.uy";
        var username = configuration["PLEXO_USERNAME"]
            ?? throw new ArgumentException("PLEXO_USERNAME is required");
        var password = configuration["PLEXO_PASSWORD"]
            ?? throw new ArgumentException("PLEXO_PASSWORD is required");
        _merchantId = int.Parse(configuration["PLEXO_MERCHANT_ID"]
            ?? throw new ArgumentException("PLEXO_MERCHANT_ID is required"));

        _client = new HttpClient
        {
            BaseAddress = new Uri(baseUrl)
        };

        var credentials = Convert.ToBase64String(
            Encoding.ASCII.GetBytes($"{username}:{password}")
        );
        _client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic", credentials);
        _client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json")
        );
    }

    // Customer operations
    public async Task<CustomerDto> CreateCustomerAsync(CreateCustomerRequest request)
    {
        var response = await _client.PostAsJsonAsync("/v1/customers", request);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<CustomerDto>();
    }

    public async Task<CustomerDto> GetCustomerAsync(string customerId)
    {
        var response = await _client.GetAsync($"/v1/customers/{customerId}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<CustomerDto>();
    }

    public async Task<PagedResult<CustomerDto>> ListCustomersAsync(
        int page = 1,
        int pageSize = 20)
    {
        var response = await _client.GetAsync(
            $"/v1/customers?page={page}&pageSize={pageSize}"
        );
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<PagedResult<CustomerDto>>();
    }

    // Session operations
    public async Task<SessionDto> CreateSessionAsync(CreateSessionRequest request)
    {
        var response = await _client.PostAsJsonAsync("/v1/sessions", request);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<SessionDto>();
    }

    public async Task<SessionDto> GetSessionAsync(Guid sessionId)
    {
        var response = await _client.GetAsync($"/v1/sessions/{sessionId}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<SessionDto>();
    }

    // Payment operations
    public async Task<PaymentDto> CreatePaymentAsync(CreatePaymentRequest request)
    {
        var response = await _client.PostAsJsonAsync("/v1/payments", request);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<PaymentDto>();
    }

    public async Task<PaymentDto> GetPaymentAsync(string paymentId)
    {
        var response = await _client.GetAsync($"/v1/payments/{paymentId}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<PaymentDto>();
    }

    public async Task<PaymentDto> CapturePaymentAsync(
        string paymentId,
        CaptureRequest captureRequest = null)
    {
        var response = await _client.PostAsJsonAsync(
        $"/v1/payments/{paymentId}/captures",
            captureRequest ?? new CaptureRequest()
        );
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<PaymentDto>();
    }

    public async Task<PaymentTransactionDto> CancelPaymentAsync(
        string paymentId,
        CancellationRequestDto cancellationRequest)
    {
        var response = await _client.PostAsJsonAsync(
        $"/v1/payments/{paymentId}/cancellations",
            cancellationRequest
        );
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<PaymentTransactionDto>();
    }

    public async Task<RefundDto> RefundPaymentAsync(
        string paymentId,
        RefundRequest refundRequest)
    {
        var response = await _client.PostAsJsonAsync(
        $"/v1/payments/{paymentId}/refunds",
            refundRequest
        );
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<RefundDto>();
    }

    public void Dispose()
    {
        _client?.Dispose();
    }
}

// Usage example
public class Program
{
    public static async Task Main(string[] args)
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: true)
            .AddEnvironmentVariables()
            .Build();

        using var client = new PlexoClient(configuration);

        try
        {
            // Create customer
            var customer = await client.CreateCustomerAsync(new CreateCustomerRequest
            {
                ReferenceId = $"customer-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
                Email = "john.doe@example.com",
                FirstName = "John",
                LastName = "Doe",
                Phone = "+1-555-0123"
            });
            Console.WriteLine($"Customer created: {customer.Id}");

            // Create tokenization session
            var session = await client.CreateSessionAsync(new CreateSessionRequest
            {
                MerchantId = client._merchantId,
                Type = "tokenization",
                ReferenceId = $"session-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
                CustomerId = customer.Id,
                CallbackUrl = "https://yoursite.com/callback"
            });
            var redirectUrl = session.Actions
                .FirstOrDefault(a => a.Rel == "REDIRECT")?.Href;
            Console.WriteLine($"Session URL: {redirectUrl}");

            // Later: Create payment
            var payment = await client.CreatePaymentAsync(new CreatePaymentRequest
            {
                MerchantId = client._merchantId,
                Amount = 100.00m,
                Currency = "USD",
                CustomerId = customer.Id,
                InstrumentId = "token-from-session",
                Capture = true
            });
            Console.WriteLine($"Payment created: {payment.Id}");
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"Request failed: {ex.Message}");
            Environment.Exit(1);
        }
    }
}
```

***

## Error Handling Best Practices

### JavaScript

```javascript
async function createPaymentWithRetry(client, paymentData, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await client.createPayment(paymentData);
    } catch (error) {
      // Check if error is retriable
      if (error.statusCode === 429 || error.statusCode >= 500) {
        if (attempt < maxRetries) {
          const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
          console.log(`Retry ${attempt}/${maxRetries} after ${delay}ms`);
          await new Promise(resolve => setTimeout(resolve, delay));
          continue;
        }
      }
      throw error; // Non-retriable or max retries reached
    }
  }
}
```

### Python

```python
import time
from typing import Callable, TypeVar, Any

T = TypeVar('T')

def retry_on_error(
    func: Callable[..., T],
    max_retries: int = 3,
    backoff_factor: int = 2
) -> T:
    """Retry function with exponential backoff."""
    for attempt in range(1, max_retries + 1):
        try:
            return func()
        except requests.exceptions.HTTPError as e:
            # Retry on rate limit or server errors
            if e.response.status_code in (429, 500, 502, 503, 504):
                if attempt < max_retries:
                    delay = backoff_factor ** attempt
                    print(f"Retry {attempt}/{max_retries} after {delay}s")
                    time.sleep(delay)
                    continue
            raise  # Non-retriable or max retries reached

# Usage
payment = retry_on_error(
    lambda: client.create_payment(payment_data),
    max_retries=3
)
```

### C\#

```csharp
public async Task<T> RetryOnErrorAsync<T>(
    Func<Task<T>> operation,
    int maxRetries = 3,
    int backoffFactor = 2)
{
    for (int attempt = 1; attempt <= maxRetries; attempt++)
    {
        try
        {
            return await operation();
        }
        catch (HttpRequestException ex)
        {
            // Retry on rate limit or server errors
            if (ex.StatusCode == HttpStatusCode.TooManyRequests ||
                (int)ex.StatusCode >= 500)
            {
                if (attempt < maxRetries)
                {
                    var delay = TimeSpan.FromSeconds(Math.Pow(backoffFactor, attempt));
                    Console.WriteLine($"Retry {attempt}/{maxRetries} after {delay.TotalSeconds}s");
                    await Task.Delay(delay);
                    continue;
                }
            }
            throw; // Non-retriable or max retries reached
        }
    }
    throw new InvalidOperationException("Should not reach here");
}

// Usage
var payment = await RetryOnErrorAsync(
    () => client.CreatePaymentAsync(paymentData),
    maxRetries: 3
);
```

***

## Complete Integration Example

### E-commerce Checkout Flow

```javascript
// complete-checkout.js
import { PlexoClient } from './plexo-client.js';

async function processCheckout(orderData) {
  const client = new PlexoClient();

  try {
    // Step 1: Create or retrieve customer
    let customer;
    if (orderData.existingCustomerId) {
      customer = await client.getCustomer(orderData.existingCustomerId);
    } else {
      customer = await client.createCustomer({
        referenceId: orderData.customerReference,
        email: orderData.email,
        firstName: orderData.firstName,
        lastName: orderData.lastName,
        phone: orderData.phone
      });
    }
    console.log(`✓ Customer: ${customer.id}`);

    // Step 2: Create tokenization session
    const session = await client.createSession({
      merchantId: client.merchantId,
      type: 'tokenization',
      referenceId: `checkout-${orderData.orderId}`,
      customerId: customer.id,
      callbackUrl: `${process.env.SITE_URL}/payment/callback`,
      metadata: {
        orderId: orderData.orderId
      }
    });
    const redirectUrl = session.actions.find(a => a.rel === 'REDIRECT').href;
    console.log(`✓ Session created: ${session.id}`);
    console.log(`  Redirect customer to: ${redirectUrl}`);

    // Return session info to frontend
    return {
      success: true,
      customerId: customer.id,
      sessionId: session.id,
      redirectUrl: redirectUrl
    };

  } catch (error) {
    console.error('Checkout failed:', error.message);
    return {
      success: false,
      error: error.message
    };
  }
}

async function processPayment(customerId, instrumentId, orderData) {
  const client = new PlexoClient();

  try {
    // Create payment with saved token
    const payment = await client.createPayment({
      merchantId: client.merchantId,
      customerId: customerId,
      instrumentId: instrumentId,
      amount: orderData.amount,
      currency: orderData.currency,
      capture: false, // Authorize only, capture after shipment
      metadata: {
        orderId: orderData.orderId,
        items: JSON.stringify(orderData.items)
      }
    });

    console.log(`✓ Payment authorized: ${payment.id}`);
    console.log(`  Status: ${payment.status}`);
    console.log(`  Amount: ${payment.amount} ${payment.currency}`);

    return {
      success: true,
      paymentId: payment.id,
      status: payment.status
    };

  } catch (error) {
    console.error('Payment failed:', error.message);
    return {
      success: false,
      error: error.message
    };
  }
}

async function capturePaymentAfterShipment(paymentId, trackingNumber) {
  const client = new PlexoClient();

  try {
    const payment = await client.capturePayment(paymentId, {
      metadata: {
        trackingNumber: trackingNumber,
        capturedAt: new Date().toISOString()
      }
    });

    console.log(`✓ Payment captured: ${payment.id}`);
    console.log(`  Final status: ${payment.status}`);

    return { success: true, payment };

  } catch (error) {
    console.error('Capture failed:', error.message);
    return {
      success: false,
      error: error.message
    };
  }
}

// Export functions
export { processCheckout, processPayment, capturePaymentAfterShipment };
```

***

## Additional Resources

* [API Reference](/rest-api/api-reference/api-reference.md) - Complete endpoint documentation
* [Getting Started Guide](/rest-api/payments/first-payment.md) - Step-by-step tutorial
* [Authentication Guide](/rest-api/getting-started/authentication.md) - Auth setup and best practices
* [Error Codes Reference](/rest-api/reference/error-codes.md) - Error codes and solutions
* [Postman Collection](/rest-api/tools/postman-collection.md) - Pre-built API collection

***

**Need Help?**

* **Email**: <soporte@plexo.com.uy>
* **Documentation**: [docs.plexo.com](https://docs.plexo.com)
* **GitHub**: [github.com/plexouy/gitbook-public-docs](https://github.com/plexouy/gitbook-public-docs)

***

**Last Updated**: December 11, 2025 **API Version**: v1
