Skip to main content

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

Perfect for you if:
  • 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:
POST /v2/products
{
  "name": "Digital Blood Pressure Monitor",
  "description": "FDA-approved automatic BP monitor with Bluetooth connectivity and memory storage for tracking health metrics.",
  "price_cents": 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:
{
  "success": true,
  "data": {
    "id": 12345,
    "name": "Digital Blood Pressure Monitor",
    "eligibility": {
      "hsa_fsa_eligible": true,
      "eligibility_type": "auto_substantiation",
      "reason": "SIGIS verified",
      "checked_at": "2025-10-18T14:30:00Z"
    },
    "price": {
      "cents": 4995,
      "formatted": "$49.95"
    }
  }
}
Product API Reference →

Step 2: Check Eligibility (Optional)

Verify eligibility before adding to cart:
POST /v2/products/check-eligibility
{
  "merchant_product_id": "BP-MONITOR-001"
}
Response:
{
  "success": true,
  "data": {
    "merchant_product_id": "BP-MONITOR-001",
    "is_eligible": true,
    "eligibility_type": "auto_substantiation",
    "product_code": "14567890123456"
  }
}

Step 3: Create Checkout Session

When customer checks out, create a checkout session:
POST /v2/checkout
{
  "customer": {
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "phone": "+1-555-123-4567"
  },
  "line_items": [
    {
      "merchant_product_id": "BP-MONITOR-001",
      "name": "Digital Blood Pressure Monitor",
      "quantity": 1,
      "price_cents": 4995
    }
  ],
  "shipping_info": {
    "address_line_1": "123 Main St",
    "address_line_2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    "country": "US"
  },
  "amounts": {
    "shipping_cents": 995,
    "tax_cents": 410
  },
  "success_url": "myapp://checkout/success",
  "cancel_url": "myapp://checkout/cancel",
  "metadata": {
    "internal_cart_id": "mobile-cart-uuid-123",
    "platform": "mobile_app"
  }
}
Response:
{
  "id": "checkout_abc123xyz",
  "checkout_url": "https://checkout.withgale.com/c/checkout_abc123xyz",
  "status": "open",
  "expires_at": "2025-10-19T14:30:00Z",
  "created_at": "2025-10-18T14:30:00Z"
}
Checkout API Reference →

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.

Step 5: Handle Payment Confirmation

Use webhooks to receive real-time payment confirmation (recommended) or poll the Order API if needed:
GET /v2/orders/{order_id}
Response:
{
  "id": "ord_abc123",
  "status": "completed",
  "customer": {
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  },
  "line_items": [...],
  "total_amount_cents": 6400,
  "created_at": "2025-10-18T15:30:00Z"
}

Step 6: Handle Webhooks

Configure webhook endpoint to receive real-time updates:
// Node.js/Express example
app.post('/webhooks/gale', async (req, res) => {
  const event = req.body;

  // Verify signature
  const signature = req.headers['x-gale-signature'];
  if (!verifySignature(event, signature)) {
    return res.status(401).send('Invalid signature');
  }

  switch (event.type) {
    case 'order.created':
      await handleOrderCreated(event.data);
      break;

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

    case 'subscription.created':
      await handleSubscriptionCreated(event.data);
      break;
  }

  res.status(200).send('OK');
});
Webhook Documentation →

Subscription Support

Gale handles subscriptions for you. When creating a checkout session, pass subscription parameters:
{
  "customer": {...},
  "line_items": [{
    "merchant_product_id": "MONTHLY_VITAMINS",
    "name": "Monthly Vitamin Subscription",
    "quantity": 1,
    "price_cents": 2999
  }],
  "payment_type": "subscription",
  "subscription": {
    "interval": "monthly",
    "interval_count": 1,
    "trial_period_days": 7
  }
}
Gale will automatically:
  • Collect payment method
  • Charge customer monthly
  • Send webhooks for each payment
  • Handle failed payments and retries
See Subscription API Reference for more details.

Batch Operations

Batch Eligibility Check

Check multiple products at once:
POST /v2/products/batch-eligibility
See Check Eligibility API for details.

Advanced Features

Idempotency

Prevent duplicate operations using idempotency keys:
POST /v2/checkout
Idempotency-Key: unique-checkout-12345

Rate Limiting

See Rate Limits for handling rate limits.

Best Practices

Secure API Keys

Never hardcode API keys in mobile apps. Proxy through your backend.

Handle Errors

Implement proper error handling for all API calls

Use Webhooks

Don’t rely solely on polling - use webhooks for reliability

Cache Eligibility

Cache product eligibility to reduce API calls

Error Handling

try {
  const response = await fetch('/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 →

API Reference

Complete API documentation:

Next Steps

Support

Building a custom integration?