Skip to content

API Integration

Overview

Zafira provides a comprehensive RESTful API for seamless integration with external applications, services, and platforms. This section covers all aspects of API integration and usage.

API Architecture

RESTful Design

  • REST Principles: Follows REST architectural principles
  • HTTP Methods: Standard HTTP methods (GET, POST, PUT, DELETE)
  • JSON Format: Consistent JSON request/response format
  • Status Codes: Proper HTTP status codes for all operations

Authentication

  • Laravel Sanctum: Token-based authentication system
  • Bearer Tokens: Secure API access with bearer tokens
  • Token Management: Token creation, validation, and revocation
  • Rate Limiting: Built-in rate limiting to prevent abuse

API Endpoints

Core Endpoints

  • Wallet Management: Complete wallet CRUD operations
  • Transaction Management: Transaction creation and monitoring
  • Charge Management: Payment charge creation and tracking
  • Webhook Management: Webhook configuration and management
  • Token Management: Token information and balance tracking

Response Format

All API responses follow a consistent format:

json
{
  "status": "success|error",
  "message": "Human-readable message",
  "data": {
    // Response data or null for errors
  }
}

Authentication Integration

Getting API Token

bash
curl -X POST https://zafira-app.vratts.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password"
  }'

Using API Token

bash
curl -H "Authorization: Bearer your-token" \
     https://zafira-app.vratts.com/api/wallet/1

Token Management

  • Token Expiration: Tokens expire after configured time
  • Token Refresh: Refresh expired tokens
  • Token Revocation: Revoke tokens when needed
  • Multiple Tokens: Support for multiple active tokens

SDK Integration

JavaScript SDK

javascript
class ZafiraAPI {
  constructor(baseURL, token) {
    this.baseURL = baseURL;
    this.token = token;
  }

  async request(endpoint, options = {}) {
    const response = await fetch(`${this.baseURL}${endpoint}`, {
      ...options,
      headers: {
        'Authorization': `Bearer ${this.token}`,
        'Content-Type': 'application/json',
        ...options.headers
      }
    });
    
    return response.json();
  }
}

Python SDK

python
import requests

class ZafiraAPI:
    def __init__(self, base_url, token):
        self.base_url = base_url
        self.token = token
        self.headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }

    def request(self, endpoint, method='GET', data=None):
        url = f"{self.base_url}{endpoint}"
        
        if method == 'GET':
            response = requests.get(url, headers=self.headers)
        elif method == 'POST':
            response = requests.post(url, headers=self.headers, json=data)
        
        return response.json()

PHP SDK

php
class ZafiraAPI {
    private $baseUrl;
    private $token;
    
    public function __construct($baseUrl, $token) {
        $this->baseUrl = $baseUrl;
        $this->token = $token;
    }
    
    public function request($endpoint, $method = 'GET', $data = null) {
        $url = $this->baseUrl . $endpoint;
        
        $headers = [
            'Authorization: Bearer ' . $this->token,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        }
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return json_decode($response, true);
    }
}

Webhook Integration

Webhook Setup

bash
curl -X POST \
     -H "Authorization: Bearer {token}" \
     -H "Content-Type: application/json" \
     -d '{
       "url": "https://your-app.com/webhooks/zafira",
       "type": "charge",
       "events": ["created", "paid", "expired"],
       "signature": "your-webhook-secret"
     }' \
     https://zafira-app.vratts.com/api/wallet/1/webhook/create

Webhook Handler

javascript
app.post('/webhooks/zafira', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);
  
  // Verify signature
  if (!verifyWebhookSignature(payload, signature, secret)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  const { event, data } = req.body;
  
  switch (event) {
    case 'charge.paid':
      // Handle successful payment
      break;
    case 'transaction.confirmed':
      // Handle transaction confirmation
      break;
  }
  
  res.status(200).json({ received: true });
});

Error Handling

HTTP Status Codes

  • 200 - Success
  • 400 - Bad Request (validation errors)
  • 401 - Unauthorized (invalid token)
  • 404 - Not Found (resource not found)
  • 422 - Unprocessable Entity (validation failed)
  • 429 - Too Many Requests (rate limited)
  • 500 - Internal Server Error

Error Response Format

json
{
  "status": "error",
  "message": "Error description",
  "data": null
}

Retry Logic

javascript
async function apiCallWithRetry(apiCall, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await apiCall();
    } catch (error) {
      if (attempt === maxRetries) {
        throw error;
      }
      
      // Exponential backoff
      await new Promise(resolve => 
        setTimeout(resolve, Math.pow(2, attempt) * 1000)
      );
    }
  }
}

Rate Limiting

Rate Limit Headers

http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1640995200

Handling Rate Limits

javascript
async function handleRateLimit(apiCall) {
  try {
    return await apiCall();
  } catch (error) {
    if (error.status === 429) {
      const retryAfter = error.headers['retry-after'] || 60;
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      return apiCall();
    }
    throw error;
  }
}

Security Best Practices

API Security

  • HTTPS Only: Always use HTTPS for API calls
  • Token Security: Store tokens securely
  • Input Validation: Validate all input data
  • Error Handling: Don't expose sensitive information in errors

Data Protection

  • Encryption: Use encryption for sensitive data
  • Access Control: Implement proper access controls
  • Audit Logging: Log all API access
  • Regular Updates: Keep API client libraries updated

Testing Integration

Unit Testing

javascript
describe('ZafiraAPI', () => {
  let api;
  
  beforeEach(() => {
    api = new ZafiraAPI('https://test-domain.com', 'test-token');
  });
  
  it('should create a charge', async () => {
    const charge = await api.createCharge(1, 'ETH', 0.1);
    expect(charge.status).toBe('success');
    expect(charge.data.amount).toBe('0.100000000000000000');
  });
});

Integration Testing

javascript
describe('API Integration', () => {
  it('should handle complete payment flow', async () => {
    // Create charge
    const charge = await api.createCharge(1, 'ETH', 0.1);
    
    // Simulate payment
    await simulatePayment(charge.data.uuid);
    
    // Verify payment
    const updatedCharge = await api.getCharge(1, charge.data.id);
    expect(updatedCharge.data.status).toBe('confirmed');
  });
});

Performance Optimization

Caching

javascript
class ZafiraAPICached extends ZafiraAPI {
  constructor(baseURL, token, cache = new Map()) {
    super(baseURL, token);
    this.cache = cache;
  }
  
  async getWallet(walletId) {
    const cacheKey = `wallet:${walletId}`;
    
    if (this.cache.has(cacheKey)) {
      return this.cache.get(cacheKey);
    }
    
    const result = await super.getWallet(walletId);
    this.cache.set(cacheKey, result);
    
    return result;
  }
}

Batch Operations

javascript
async function batchCreateCharges(walletId, charges) {
  const promises = charges.map(charge => 
    api.createCharge(walletId, charge.token, charge.amount)
  );
  
  return Promise.all(promises);
}

Monitoring and Analytics

API Usage Tracking

javascript
class ZafiraAPIMonitored extends ZafiraAPI {
  async request(endpoint, options = {}) {
    const startTime = Date.now();
    
    try {
      const result = await super.request(endpoint, options);
      
      // Log successful request
      this.logRequest(endpoint, Date.now() - startTime, true);
      
      return result;
    } catch (error) {
      // Log failed request
      this.logRequest(endpoint, Date.now() - startTime, false, error);
      
      throw error;
    }
  }
  
  logRequest(endpoint, duration, success, error = null) {
    console.log({
      endpoint,
      duration,
      success,
      error: error?.message,
      timestamp: new Date().toISOString()
    });
  }
}

Next Steps

Released under the MIT License.