# API Documentation

URL: https://all-ancillaries-9z82vkas5-britoncos-projects.vercel.app/docs/api
Updated: 2026-06-25

API reference for encrypted URLs, checkout integrations, and workflows.

# DepartCart API Reference

## Overview

DepartCart provides secure, white-label ancillary services for airlines and travel partners. Partners authenticate with an API key and secret to obtain a short-lived **bearer token**, then call the API with the raw booking details (PNR and passenger last name). DepartCart performs all encryption server-side, so partners never handle encryption keys.

## Table of Contents

1. [Authentication & Bearer Tokens](#authentication--bearer-tokens)
2. [Generate Seatmap Deeplink](#generate-seatmap-deeplink)
3. [Generate All Deeplinks](#generate-all-deeplinks)
4. [Seatmap Display](#seatmap-display)
5. [GTM Integration](#gtm-integration)
6. [Webhook Notifications](#webhook-notifications)
7. [Error Handling](#error-handling)
8. [Implementation Guide](#implementation-guide)

---

## Authentication & Bearer Tokens

All API calls are authenticated with a short-lived **bearer token**. You exchange your brand's API key and secret (issued during onboarding) for a token, then send it in the `Authorization` header on every request.

**Note**: Your API key and secret are provided during onboarding and differ from the examples shown here. Encryption is handled entirely server-side. Partners never receive or use encryption keys, passwords, or salts.

### Step 1. Request a bearer token

**Endpoint**: `POST /generate-bearer-token`

**Request Body**:
```json
{
  "api_key": "YOUR_API_KEY",
  "api_secret": "YOUR_API_SECRET",
  "duration_hours": 24
}
```

`duration_hours` is optional and defaults to `24`.

**Response**:
```json
{
  "success": true,
  "bearer_token": "your_brand:1718790000:1718876400:Ab12Cd...:9f8e7d...",
  "token_type": "Bearer",
  "expires_in": 86400,
  "expires_at": 1718876400,
  "brand": "your_brand"
}
```

### Step 2. Authenticate requests

Send the token in the `Authorization` header:

```text
Authorization: Bearer your_brand:1718790000:1718876400:Ab12Cd...:9f8e7d...
```

Tokens expire after `duration_hours`; a `401` response indicates an invalid or expired token. Cache and reuse a token until it is close to expiry rather than requesting a new one on every call.

---

## Generate Seatmap Deeplink

Create an encrypted seatmap URL for a booking. Send the raw `pnr` and `last_name`; DepartCart encrypts them server-side and returns the deeplink. The brand is taken from your bearer token.

**Endpoint**: `POST /api/generate-encrypted-seatmap-url`

**Headers**:
```text
Authorization: Bearer <token>
Content-Type: application/json
```

**Request Body**:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `pnr` | string | Yes | Booking reference / PNR (e.g. `ABC123`). |
| `last_name` | string | Yes | Passenger last name (e.g. `SMITH`). |
| `source` | string | No | Integration source identifier (e.g. `api`, `app`). Defaults to `cart`. |

```json
{
  "pnr": "ABC123",
  "last_name": "SMITH",
  "source": "api"
}
```

**Response**:
```json
{
  "success": true,
  "encrypted_id": "Z0FBQUFBQm9VQTE2...",
  "seatmap_url": "/seatmap?id=Z0FBQUFBQm9VQTE2...&source=api",
  "source": "api"
}
```

`seatmap_url` is a path on the DepartCart domain. Prepend `https://departcart.com` to build the full customer-facing deeplink:

```text
https://departcart.com/seatmap?id=Z0FBQUFBQm9VQTE2...&source=api
```

**Example Usage**:

<div class="code-example-container">
<div class="code-example" data-language="python">

```python
import requests

BASE_URL = "https://departcart.com"

# 1) Exchange API credentials for a bearer token
auth = requests.post(f"{BASE_URL}/generate-bearer-token", json={
    "api_key": "YOUR_API_KEY",
    "api_secret": "YOUR_API_SECRET",
}).json()
token = auth["bearer_token"]

# 2) Generate the seatmap deeplink for a booking
resp = requests.post(
    f"{BASE_URL}/api/generate-encrypted-seatmap-url",
    headers={"Authorization": f"Bearer {token}"},
    json={"pnr": "ABC123", "last_name": "SMITH", "source": "api"},
).json()

seatmap_deeplink = f"{BASE_URL}{resp['seatmap_url']}"
print(seatmap_deeplink)
```

</div>
<div class="code-example" data-language="javascript">

```javascript
const BASE_URL = 'https://departcart.com';

// 1) Exchange API credentials for a bearer token
const auth = await fetch(`${BASE_URL}/generate-bearer-token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        api_key: 'YOUR_API_KEY',
        api_secret: 'YOUR_API_SECRET',
    }),
}).then(r => r.json());

// 2) Generate the seatmap deeplink for a booking
const result = await fetch(`${BASE_URL}/api/generate-encrypted-seatmap-url`, {
    method: 'POST',
    headers: {
        'Authorization': `Bearer ${auth.bearer_token}`,
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({ pnr: 'ABC123', last_name: 'SMITH', source: 'api' }),
}).then(r => r.json());

const seatmapDeeplink = `${BASE_URL}${result.seatmap_url}`;
console.log(seatmapDeeplink);
```

</div>
<div class="code-example" data-language="csharp">

```csharp
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;

const string baseUrl = "https://departcart.com";
var client = new HttpClient();

// 1) Exchange API credentials for a bearer token
var authResp = await client.PostAsJsonAsync($"{baseUrl}/generate-bearer-token", new
{
    api_key = "YOUR_API_KEY",
    api_secret = "YOUR_API_SECRET",
});
var auth = await authResp.Content.ReadFromJsonAsync<Dictionary<string, object>>();
string token = auth["bearer_token"].ToString();

// 2) Generate the seatmap deeplink for a booking
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var resp = await client.PostAsJsonAsync($"{baseUrl}/api/generate-encrypted-seatmap-url", new
{
    pnr = "ABC123",
    last_name = "SMITH",
    source = "api",
});
var result = await resp.Content.ReadFromJsonAsync<Dictionary<string, object>>();
string seatmapDeeplink = $"{baseUrl}{result["seatmap_url"]}";
```

</div>
<div class="code-example" data-language="ruby">

```ruby
require 'net/http'
require 'uri'
require 'json'

BASE_URL = 'https://departcart.com'

def post_json(path, body, token = nil)
  uri = URI("#{BASE_URL}#{path}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Post.new(uri)
  req['Content-Type'] = 'application/json'
  req['Authorization'] = "Bearer #{token}" if token
  req.body = body.to_json
  JSON.parse(http.request(req).body)
end

# 1) Exchange API credentials for a bearer token
auth = post_json('/generate-bearer-token', {
  api_key: 'YOUR_API_KEY',
  api_secret: 'YOUR_API_SECRET'
})

# 2) Generate the seatmap deeplink for a booking
result = post_json('/api/generate-encrypted-seatmap-url',
  { pnr: 'ABC123', last_name: 'SMITH', source: 'api' },
  auth['bearer_token'])

seatmap_deeplink = "#{BASE_URL}#{result['seatmap_url']}"
puts seatmap_deeplink
```

</div>
</div>

---

## Generate All Deeplinks

Generate the **seatmap, cart, and checkout** deeplinks for a booking in a single call. As with the seatmap endpoint, encryption is performed server-side and the brand is taken from your bearer token. The difference is that this endpoint returns all three deeplinks as **absolute URLs**.

**Endpoint**: `POST /generate-encrypted-url`

**Headers**:
```text
Authorization: Bearer <token>
Content-Type: application/json
```

**Request Body**:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `pnr` | string | Yes | Booking reference / PNR. |
| `last_name` | string | Yes | Any passenger's last name from the booking. |
| `source` | string | No | Integration source identifier. Defaults to `cart`. |

```json
{
  "pnr": "ABC123",
  "last_name": "SMITH",
  "source": "cart"
}
```

**Response**:
```json
{
  "success": true,
  "encrypted_id": "Z0FBQUFBQm9VQTE2...",
  "seatmap_url": "https://departcart.com/seatmap?id=Z0FBQUFBQm9VQTE2...&source=cart",
  "cart_url": "https://departcart.com/cart?id=Z0FBQUFBQm9VQTE2...",
  "checkout_url": "https://departcart.com/checkout?id=Z0FBQUFBQm9VQTE2...",
  "source": "cart"
}
```

Use `seatmap_url` to drop the customer directly into seat selection, `cart_url` for the full ancillary cart, or `checkout_url` to jump straight to payment. These are absolute URLs and can be used as-is.

---

## Seatmap Display

**Endpoint**: `GET /seatmap`

**Parameters**:

- `id` (string): Encrypted passenger data ID
- `source` (string, optional): Integration source identifier (`api`, `gtm`, `cart`, etc.)

**Example**:
```text
https://departcart.com/seatmap?id=Z0FBQUFBQm9VQTE2...&source=api
```

---

## GTM Integration

### Lightweight Integration

For a quick, low-maintenance integration, use Google Tag Manager to inject seat selection panels into your confirmation or account pages.

**GTM Code Template**:
```javascript
<script>
(function() {
    // Ultra-minimal GTM injectable - just loads the script, no logic
    var script = document.createElement('script');
    script.src = 'https://departcart.com/static/loaders-dist/seat_selection_loader.js';
    script.setAttribute('data-gtm-source', 'true');
    document.head.appendChild(script);
})();
</script>
```

**Benefits**:

- **Minimal development**: Just add GTM code
- **Auto-detection**: Finds PNR/passenger data from page
- **Modal interface**: No page navigation required
- **Responsive design**: Works on all devices

**Setup Steps**:

1. Add the GTM code above to your tag manager
2. Configure trigger for confirmation/account pages
3. Ensure your pages have identifiable booking elements
4. Test with sample bookings

For detailed GTM integration instructions, see: [GTM Integration Guide](./GTM_INTEGRATION_GUIDE.md)

---

## Webhook Notifications

### Real-Time Transaction Updates

DepartCart sends webhook notifications for all transaction events to keep partners updated in real-time.

**Webhook URL Setup**: Configure your webhook endpoint during onboarding.

### Event Types

- `transaction.created` - New ancillary purchase initiated
- `transaction.completed` - Payment successful and services confirmed
- `transaction.failed` - Payment or service confirmation failed
- `transaction.refunded` - Full or partial refund processed

### Webhook Payload

```json
{
  "event_type": "transaction.completed",
  "event_id": "evt_1234567890",
  "timestamp": "2025-06-16T10:30:00Z",
  "brand": "your_brand_name",
  "transaction": {
    "id": "txn_abc123def456",
    "pnr": "ABC123",
    "status": "completed",
    "total_amount": 89.98,
    "currency": "USD",
    "payment": {
      "method": "stripe",
      "gateway_transaction_id": "pi_1234567890",
      "amount_charged": 89.98,
      "processing_fee": 2.70,
      "net_amount": 87.28
    },
    "passenger": {
      "first_name": "John",
      "last_name": "SMITH",
      "email": "john.smith@example.com"
    },
    "flight": {
      "airline_code": "AA",
      "flight_number": "1234",
      "departure_date": "2025-06-20",
      "departure_airport": "JFK",
      "arrival_airport": "LAX",
      "segment_id": "AA1234-20250620-JFKLAX"
    },
    "ancillaries": [
      {
        "type": "seat",
        "description": "Premium Economy Seat 12A",
        "seat_number": "12A",
        "price": 45.00,
        "cost": 15.00,
        "margin": 30.00
      },
      {
        "type": "baggage",
        "description": "Extra Baggage 23kg",
        "weight": "23kg",
        "price": 44.98,
        "cost": 25.00,
        "margin": 19.98
      }
    ],
    "fulfillment": {
      "seat_confirmation": "CONFIRMED",
      "baggage_confirmation": "CONFIRMED",
      "gds_record_locator": "ABC123",
      "updated_at": "2025-06-16T10:29:45Z"
    }
  }
}
```

### Webhook Implementation Examples

<div class="code-example-container">
<div class="code-example" data-language="python">

```python
from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)

@app.route('/webhook/departcart', methods=['POST'])
def handle_departcart_webhook():
    # Verify webhook signature (recommended)
    signature = request.headers.get('X-DepartCart-Signature')
    payload = request.get_data()
    
    if not verify_webhook_signature(payload, signature):
        return jsonify({'error': 'Invalid signature'}), 401
    
    # Process webhook data
    webhook_data = request.get_json()
    event_type = webhook_data['event_type']
    transaction = webhook_data['transaction']
    
    if event_type == 'transaction.completed':
        # Update your records
        update_booking_ancillaries(
            pnr=transaction['pnr'],
            ancillaries=transaction['ancillaries'],
            payment_info=transaction['payment']
        )
        
        # Send confirmation email
        send_purchase_confirmation(
            passenger=transaction['passenger'],
            flight=transaction['flight'],
            ancillaries=transaction['ancillaries']
        )
    
    elif event_type == 'transaction.refunded':
        # Process refund
        process_refund(
            transaction_id=transaction['id'],
            refund_amount=transaction['payment']['amount_charged']
        )
    
    return jsonify({'status': 'received'}), 200

def verify_webhook_signature(payload, signature):
    # Verify using your webhook secret
    webhook_secret = "your_webhook_secret_key"
    expected_signature = hmac.new(
        webhook_secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(f"sha256={expected_signature}", signature)
```

</div>
<div class="code-example" data-language="csharp">

```csharp
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

[ApiController]
[Route("webhook")]
public class WebhookController : ControllerBase
{
    [HttpPost("departcart")]
    public async Task<IActionResult> HandleDepartCartWebhook()
    {
        // Read webhook payload
        using var reader = new StreamReader(Request.Body);
        var payload = await reader.ReadToEndAsync();
        
        // Verify signature
        var signature = Request.Headers["X-DepartCart-Signature"].FirstOrDefault();
        if (!VerifyWebhookSignature(payload, signature))
        {
            return Unauthorized("Invalid signature");
        }
        
        // Parse webhook data
        var webhookData = JsonSerializer.Deserialize<WebhookPayload>(payload);
        
        switch (webhookData.event_type)
        {
            case "transaction.completed":
                await HandleTransactionCompleted(webhookData.transaction);
                break;
                
            case "transaction.refunded":
                await HandleTransactionRefunded(webhookData.transaction);
                break;
        }
        
        return Ok(new { status = "received" });
    }
    
    private bool VerifyWebhookSignature(string payload, string signature)
    {
        var webhookSecret = "your_webhook_secret_key";
        var keyBytes = Encoding.UTF8.GetBytes(webhookSecret);
        var payloadBytes = Encoding.UTF8.GetBytes(payload);
        
        using var hmac = new HMACSHA256(keyBytes);
        var computedHash = hmac.ComputeHash(payloadBytes);
        var expectedSignature = $"sha256={Convert.ToHexString(computedHash).ToLower()}";
        
        return string.Equals(expectedSignature, signature, StringComparison.OrdinalIgnoreCase);
    }
}
```

</div>
<div class="code-example" data-language="javascript">

```javascript
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.raw({ type: 'application/json' }));

app.post('/webhook/departcart', (req, res) => {
    const signature = req.headers['x-departcart-signature'];
    const payload = req.body;
    
    // Verify webhook signature
    if (!verifyWebhookSignature(payload, signature)) {
        return res.status(401).json({ error: 'Invalid signature' });
    }
    
    // Parse webhook data
    const webhookData = JSON.parse(payload);
    const { event_type, transaction } = webhookData;
    
    switch (event_type) {
        case 'transaction.completed':
            handleTransactionCompleted(transaction);
            break;
            
        case 'transaction.refunded':
            handleTransactionRefunded(transaction);
            break;
    }
    
    res.json({ status: 'received' });
});

function verifyWebhookSignature(payload, signature) {
    const webhookSecret = 'your_webhook_secret_key';
    const expectedSignature = crypto
        .createHmac('sha256', webhookSecret)
        .update(payload)
        .digest('hex');
    
    return crypto.timingSafeEqual(
        Buffer.from(`sha256=${expectedSignature}`),
        Buffer.from(signature)
    );
}

async function handleTransactionCompleted(transaction) {
    // Update booking records
    await updateBookingAncillaries(transaction);
    
    // Send confirmation email
    await sendPurchaseConfirmation(transaction);
}
```

</div>
<div class="code-example" data-language="java">

```java
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

@RestController
@RequestMapping("/webhook")
public class WebhookController {
    
    private static final String WEBHOOK_SECRET = "your_webhook_secret_key";
    
    @PostMapping("/departcart")
    public ResponseEntity<Map<String, String>> handleDepartCartWebhook(
            HttpServletRequest request, @RequestBody String payload) {
        
        try {
            // Verify signature
            String signature = request.getHeader("X-DepartCart-Signature");
            if (!verifyWebhookSignature(payload, signature)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(Map.of("error", "Invalid signature"));
            }
            
            // Parse webhook data
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> webhookData = mapper.readValue(payload, Map.class);
            String eventType = (String) webhookData.get("event_type");
            Map<String, Object> transaction = (Map<String, Object>) webhookData.get("transaction");
            
            switch (eventType) {
                case "transaction.completed":
                    handleTransactionCompleted(transaction);
                    break;
                    
                case "transaction.refunded":
                    handleTransactionRefunded(transaction);
                    break;
            }
            
            return ResponseEntity.ok(Map.of("status", "received"));
            
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Map.of("error", "Processing error"));
        }
    }
    
    private boolean verifyWebhookSignature(String payload, String signature) 
            throws NoSuchAlgorithmException, InvalidKeyException {
        
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(WEBHOOK_SECRET.getBytes(), "HmacSHA256");
        mac.init(secretKey);
        
        byte[] hash = mac.doFinal(payload.getBytes());
        StringBuilder expectedSignature = new StringBuilder("sha256=");
        for (byte b : hash) {
            expectedSignature.append(String.format("%02x", b));
        }
        
        return expectedSignature.toString().equals(signature);
    }
    
    private void handleTransactionCompleted(Map<String, Object> transaction) {
        // Update booking records and send confirmation email
        System.out.println("Transaction completed: " + transaction.get("id"));
    }
    
    private void handleTransactionRefunded(Map<String, Object> transaction) {
        // Process refund
        System.out.println("Transaction refunded: " + transaction.get("id"));
    }
}
```

</div>
<div class="code-example" data-language="ruby">

```ruby
require 'sinatra'
require 'json'
require 'openssl'

class WebhookController < Sinatra::Base
  WEBHOOK_SECRET = 'your_webhook_secret_key'
  
  post '/webhook/departcart' do
    # Read payload
    request.body.rewind
    payload = request.body.read
    
    # Verify signature
    signature = request.env['HTTP_X_DEPARTCART_SIGNATURE']
    unless verify_webhook_signature(payload, signature)
      status 401
      return { error: 'Invalid signature' }.to_json
    end
    
    # Parse webhook data
    webhook_data = JSON.parse(payload)
    event_type = webhook_data['event_type']
    transaction = webhook_data['transaction']
    
    case event_type
    when 'transaction.completed'
      handle_transaction_completed(transaction)
    when 'transaction.refunded'
      handle_transaction_refunded(transaction)
    end
    
    content_type :json
    { status: 'received' }.to_json
  end
  
  private
  
  def verify_webhook_signature(payload, signature)
    expected_signature = "sha256=#{OpenSSL::HMAC.hexdigest('SHA256', WEBHOOK_SECRET, payload)}"
    Rack::Utils.secure_compare(expected_signature, signature)
  end
  
  def handle_transaction_completed(transaction)
    # Update booking records and send confirmation email
    puts "Transaction completed: #{transaction['id']}"
  end
  
  def handle_transaction_refunded(transaction)
    # Process refund
    puts "Transaction refunded: #{transaction['id']}"
  end
end
```

</div>
</div>

---

## Error Handling

### HTTP Status Codes

- `200` - Success
- `400` - Bad Request (invalid parameters)
- `401` - Unauthorized (invalid or missing credentials)
- `403` - Forbidden (insufficient permissions)
- `404` - Not Found (resource doesn't exist)
- `422` - Unprocessable Entity (validation errors)
- `500` - Internal Server Error

### Error Response Format

```json
{
    "success": false,
    "error": {
        "code": "INVALID_PNR",
        "message": "The provided PNR could not be found or is invalid",
        "details": {
            "pnr": "ABC123",
            "brand": "your_brand_name"
        }
    }
}
```

### Common Error Codes

- `INVALID_PNR` - PNR not found or invalid format
- `ENCRYPTION_ERROR` - Failed to decrypt passenger data
- `BRAND_NOT_CONFIGURED` - Brand not set up for ancillary services
- `PAYMENT_FAILED` - Payment processing error
- `GDS_ERROR` - Unable to communicate with airline reservation system

---

## Implementation Guide

### 🚀 Quick Start Checklist

> Complete these steps to get your DepartCart integration up and running quickly.

---

#### 📋 **Phase 1: Onboarding Requirements**
*Essential setup items needed before development begins*

- [ ] 🎨 **Provide branding assets** (logos, color palette)
- [ ] 🔗 **Share GDS credentials** (Sabre/Amadeus access)
- [ ] 💳 **Configure payment gateway** (Stripe/Adyen)
- [ ] 🔐 **Receive API key, secret,** and webhook secrets
- [ ] 🌐 **Set up webhook endpoint**

---

#### ⚙️ **Phase 2: Integration Options**
*Choose your preferred integration approach*

- [ ] 🏃‍♂️ **GTM Integration** *(fastest)*: Add GTM code to confirmation pages
- [ ] 🛠️ **API Integration** *(custom)*: Implement bearer-token auth and direct API calls
- [ ] 🔄 **Hybrid Approach**: GTM for UI, API for custom workflows

---

#### 🧪 **Phase 3: Testing**
*Validate your integration before going live*

- [ ] 🔒 **Test bearer token retrieval** with sample data
- [ ] 🗺️ **Verify seatmap loads** correctly
- [ ] 📢 **Test webhook notifications**
- [ ] 💰 **Validate payment processing**

---

#### 🎯 **Phase 4: Go Live**
*Final steps for production deployment*

- [ ] 🏭 **Production credentials** configured
- [ ] 📊 **Webhook monitoring** set up
- [ ] 🚨 **Error handling** implemented
- [ ] 📞 **Support contact** established

---

#### ⏱️ **Estimated Timeline: 4-8 weeks total**

### Integration Timeline

| Phase | Duration | Activities |
|-------|----------|------------|
| **Setup** | 1-2 weeks | Onboarding, credentials, branding |
| **Development** | 2-4 weeks | Implement encryption, integrate APIs |
| **Testing** | 1-2 weeks | End-to-end testing, UAT |
| **Launch** | 1 week | Production deployment, monitoring |

For detailed implementation steps, see: [Partner Onboarding Guide](https://departcart.com/docs/onboarding)

---

## Support & Resources

### Documentation Links

- [Authentication & Bearer Tokens](https://departcart.com/docs/api#authentication--bearer-tokens)
- [GTM Integration Guide](./GTM_INTEGRATION_GUIDE.md)
- [Partner Onboarding Guide](https://departcart.com/docs/onboarding)

### Support Contacts
- **Technical Support**: [support@departcart.com](mailto:support@departcart.com)
- **Integration Team**: [integration@departcart.com](mailto:integration@departcart.com)
- **Account Management**: [accounts@departcart.com](mailto:accounts@departcart.com)

### Testing Tools
- **URL Generator**: [https://departcart.com/generate-encrypted-url](https://departcart.com/generate-encrypted-url)
- **Encryption Test**: [https://departcart.com/test-encryption](https://departcart.com/test-encryption)
- **API Documentation**: [https://departcart.com/api/docs](https://departcart.com/api/docs)

---

*This documentation is updated regularly. For the latest version, visit: [https://departcart.com/docs](https://departcart.com/docs)*
