> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withgale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom API Integration

> Full control over checkout experience with complete API access - perfect for mobile apps and custom platforms

# Custom API Integration

Build your own checkout experience with complete control using Gale's APIs. Perfect for mobile apps, custom platforms, and merchants who need full flexibility.

## When to Use Custom API

<Check>Perfect for you if:</Check>

* You're building a mobile app (iOS, Android, React Native)
* You need complete UI control over checkout
* You want to manage subscriptions externally
* You require advanced features (batch operations, custom flows)
* You have development resources for custom implementation

## Architecture Overview

The custom API integration follows this flow:

1. **Create Products** - Sync your products with Gale's Product API
2. **Check Eligibility** - Verify HSA/FSA eligibility via Eligibility API
3. **Create Checkout** - Create checkout session via Checkout API
4. **Redirect/Open** - Send customer to Gale's hosted checkout page
5. **Process Payment** - Gale processes payment securely
6. **Webhook** - Receive webhook notification when payment completes
7. **Fulfill Order** - Your backend fulfills the order

## Implementation Guide

### Step 1: Product Management

Sync your products with Gale and verify HSA/FSA eligibility:

```bash theme={null}
POST /api/v2/products
```

```json theme={null}
{
  "name": "Digital Blood Pressure Monitor",
  "description": "FDA-approved automatic BP monitor with Bluetooth connectivity and memory storage for tracking health metrics.",
  "price": 4995,
  "currency": "USD",
  "merchant_product_id": "BP-MONITOR-001",
  "upc_code_or_gtin": "14567890123456",
  "images": [
    "https://yourcdn.com/bp-monitor-front.jpg",
    "https://yourcdn.com/bp-monitor-side.jpg"
  ],
  "metadata": {
    "category": "medical_devices",
    "brand": "HealthTech Pro"
  }
}
```

**Response includes automatic eligibility:**

```json theme={null}
{
  "success": true,
  "data": {
    "id": 12345,
    "name": "Digital Blood Pressure Monitor",
    "eligibility": {
      "hsa_fsa_eligible": true,
      "message": "HSA/FSA accepted"
    },
    "price": 4995
  }
}
```

[Product API Reference →](/api-reference/endpoint/create-product-v2)

### Step 2: Check Eligibility (Optional)

Verify eligibility before adding to cart:

```bash theme={null}
POST /api/v2/products/check-eligibility
```

```json theme={null}
{
  "merchant_product_id": "BP-MONITOR-001"
}
```

**Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "product_id": "BP-MONITOR-001",
    "hsa_fsa_eligible": true,
    "message": "HSA/FSA accepted"
  }
}
```

### Step 3: Create Checkout Session

When customer checks out, create a checkout session:

```bash theme={null}
POST /api/v2/checkout
```

```json theme={null}
{
  "reference_id": "mobile-cart-uuid-123",
  "customer": {
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "phone": "+1-555-123-4567"
  },
  "line_items": [
    {
      "product_id": "BP-MONITOR-001",
      "name": "Digital Blood Pressure Monitor",
      "quantity": 1,
      "price": 4995,
      "currency": "USD"
    }
  ],
  "shipping_info": {
    "address_line_1": "123 Main St",
    "address_line_2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "shipping": 995,
  "tax": 410,
  "success_url": "myapp://checkout/success",
  "failure_url": "myapp://checkout/cancel",
  "metadata": {
    "platform": "mobile_app"
  }
}
```

**Response:**

```json theme={null}
{
  "success": true,
  "message": "Checkout created",
  "data": {
    "checkout_id": "cs_a1b2c3...",
    "checkout_url": "https://checkout.withgale.com/checkout/cs_a1b2c3...?token=...",
    "status": "open",
    "expires_at": "2026-02-26T14:30:00Z"
  },
  "metadata": { "request_id": "..." }
}
```

[Checkout API Reference →](/api-reference/endpoint/create-checkout-v2)

### Step 4: Handle Checkout

**Option A: Use Gale's Hosted Checkout (Recommended)**

Redirect to `checkout_url` for payment. Customer completes payment on Gale's secure page.

**Option B: Embedded Checkout (Alternative)**

For a more seamless experience, embed the checkout in a webview or iframe within your app. See [Embedded Checkout Guide](/integration/embedded-checkout).

### Step 5: Handle Payment Confirmation

Use webhooks to receive real-time payment confirmation (recommended) or poll the Order API if needed:

```bash theme={null}
GET /api/v2/orders/{order_id}
```

**Response:**

```json theme={null}
{
  "id": "ord_abc123",
  "status": "completed",
  "customer": {
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  },
  "line_items": [...],
  "total": 6400,
  "created_at": "2025-10-18T15:30:00Z"
}
```

### Step 6: Handle Webhooks

Configure webhook endpoint to receive real-time updates:

```javascript theme={null}
// Node.js/Express example
app.post('/webhooks/gale', async (req, res) => {
  const event = req.body;

  // Authenticate the delivery: Gale sends your endpoint secret as a Bearer token
  const token = req.headers['authorization']?.replace('Bearer ', '');
  if (token !== process.env.GALE_WEBHOOK_SECRET) {
    return res.status(401).send('Invalid webhook token');
  }

  switch (event.type) {
    case 'order.completed':
      await handleOrderCompleted(event.data);
      break;

    case 'order.failed':
      await handleOrderFailure(event.data);
      break;

    case 'refund.succeeded':
      await handleRefundSucceeded(event.data);
      break;
  }

  res.status(200).send('OK');
});
```

[Webhook Documentation →](/developer-manual/webhooks)

## Subscription Support

Gale handles subscriptions for you. When creating a checkout session, pass subscription parameters:

```json theme={null}
{
  "reference_id": "sub-vitamins-123",
  "customer": {...},
  "line_items": [{
    "product_id": "MONTHLY_VITAMINS",
    "name": "Monthly Vitamin Subscription",
    "quantity": 1,
    "price": 2999,
    "currency": "USD"
  }],
  "payment_type": "subscription",
  "subscription": {
    "interval": "monthly",
    "interval_count": 1,
    "trial_period_days": 7
  }
}
```

<Note>Subscription checkout is currently in Beta.</Note>

Gale will automatically:

* Collect payment method
* Charge customer monthly
* Send webhooks for each payment
* Handle failed payments and retries

See [Subscription API Reference](/api-reference/endpoint/create-subscription) for more details.

## Batch Operations

### Batch Eligibility Check

Check multiple products at once:

```bash theme={null}
POST /api/v2/products/batch-eligibility
```

See [Check Eligibility API](/api-reference/endpoint/check-eligibility) for details.

## Advanced Features

### Idempotency

Prevent duplicate operations using idempotency keys:

```bash theme={null}
POST /api/v2/checkout
Idempotency-Key: unique-checkout-12345
```

### Rate Limiting

See [Rate Limits](/developer-manual/rate-limits) for handling rate limits.

## Best Practices

<CardGroup cols={2}>
  <Card title="Secure API Keys" icon="key">
    Never hardcode API keys in mobile apps. Proxy through your backend.
  </Card>

  <Card title="Handle Errors" icon="exclamation-triangle">
    Implement proper error handling for all API calls
  </Card>

  <Card title="Use Webhooks" icon="bell">
    Don't rely solely on polling - use webhooks for reliability
  </Card>

  <Card title="Cache Eligibility" icon="database">
    Cache product eligibility to reduce API calls
  </Card>
</CardGroup>

## Error Handling

```javascript theme={null}
try {
  const response = await fetch('https://api.withgale.com/api/v2/checkout', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
    body: JSON.stringify(checkoutData)
  });

  if (!response.ok) {
    const error = await response.json();

    switch (error.error.code) {
      case 'validation_error':
        // Handle validation errors
        console.error('Validation failed:', error.errors);
        break;

      case 'checkout_expired':
        // Checkout expired - create new one
        break;

      case 'product_not_eligible':
        // Product not HSA/FSA eligible
        break;

      default:
        console.error('API Error:', error.error.message);
    }
  }

  return response.json();
} catch (error) {
  console.error('Network error:', error);
}
```

## Testing

### Test Environment

Always use test keys during development:

```
Authorization: Bearer glm_test_YOUR_TEST_KEY
```

### Test Scenarios

1. **Successful payment**: Use test card `4111111111111111`
2. **Card declined**: Use test card `4000000000000002`
3. **Expired session**: Create checkout and wait 24+ hours
4. **Mixed eligibility**: Create checkout with eligible and non-eligible products

[See all test cards →](/resources/test-cards)

## API Reference

Complete API documentation:

* [Product APIs](/api-reference/endpoint/create-product-v2)
* [Checkout API](/api-reference/endpoint/create-checkout-v2)
* [Order APIs](/api-reference/endpoint/get-order)
* [Eligibility APIs](/api-reference/endpoint/check-eligibility)
* [Subscription APIs](/api-reference/endpoint/create-subscription)

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhook Guide" icon="bell" href="/developer-manual/webhooks">
    Set up webhook endpoints
  </Card>

  <Card title="Core Objects" icon="database" href="/api-reference/objects/order">
    Understand data structures
  </Card>

  <Card title="Test Cards" icon="credit-card" href="/resources/test-cards">
    Test payment scenarios
  </Card>

  <Card title="Error Codes" icon="exclamation-circle" href="/developer-manual/errors">
    Handle errors properly
  </Card>
</CardGroup>

## Support

Building a custom integration?

* 📧 Email: [support@withgale.com](mailto:support@withgale.com)
* 📚 [Full API Reference](/api-reference/introduction)
* 💬 [Contact Support](https://www.withgale.com/contact/support)
