Stripe Adapter

The Stripe adapter provides access to payment data including customers, charges, and subscriptions with API key authentication.

Installation

npm install @openetl/stripe

Features

  • API Key Authentication - Simple, secure authentication
  • Payment Data - Access customers, charges, subscriptions, and more
  • Cursor Pagination - Efficient pagination for large datasets
  • Full CRUD Support - Download and upload operations

Authentication

The Stripe adapter uses api_key authentication:

const vault = {
  'stripe-auth': {
    id: 'stripe-auth',
    type: 'api_key',
    credentials: {
      api_key: process.env.STRIPE_SECRET_KEY,
    },
  },
};

Security: Use your secret key (sk_live_... or sk_test_...), not the publishable key.

Quick Start

import { Orchestrator } from 'openetl';
import { stripe } from '@openetl/stripe';

const vault = {
  'stripe-auth': {
    id: 'stripe-auth',
    type: 'api_key',
    credentials: {
      api_key: process.env.STRIPE_SECRET_KEY,
    },
  },
};

const etl = Orchestrator(vault, { stripe });

const pipeline = {
  id: 'export-customers',
  source: {
    id: 'customers-source',
    adapter_id: 'stripe',
    endpoint_id: 'customers',
    credential_id: 'stripe-auth',
    fields: ['id', 'email', 'name', 'created', 'metadata'],
    pagination: { type: 'cursor', itemsPerPage: 100 },
  },
};

const result = await etl.runPipeline(pipeline);
console.log(`Exported ${result.data.length} customers`);

Endpoints

customers

Retrieve or create Stripe customers.

const connector = {
  adapter_id: 'stripe',
  endpoint_id: 'customers',
  credential_id: 'stripe-auth',
  fields: ['id', 'email', 'name', 'phone', 'created', 'metadata'],
  pagination: { type: 'cursor', itemsPerPage: 100 },
};

Common customer fields:

  • id - Customer ID (cus_xxx)
  • email - Email address
  • name - Customer name
  • phone - Phone number
  • created - Creation timestamp
  • metadata - Custom metadata

charges

Retrieve payment charges.

const connector = {
  adapter_id: 'stripe',
  endpoint_id: 'charges',
  credential_id: 'stripe-auth',
  fields: ['id', 'amount', 'currency', 'status', 'customer', 'created'],
  pagination: { type: 'cursor', itemsPerPage: 100 },
};

Common charge fields:

  • id - Charge ID (ch_xxx)
  • amount - Amount in cents
  • currency - Currency code (usd, eur, etc.)
  • status - succeeded, pending, failed
  • customer - Customer ID
  • created - Creation timestamp

subscriptions

Retrieve subscription data.

const connector = {
  adapter_id: 'stripe',
  endpoint_id: 'subscriptions',
  credential_id: 'stripe-auth',
  fields: ['id', 'customer', 'status', 'current_period_start', 'current_period_end', 'items'],
  pagination: { type: 'cursor', itemsPerPage: 100 },
};

Common subscription fields:

  • id - Subscription ID (sub_xxx)
  • customer - Customer ID
  • status - active, canceled, past_due, etc.
  • current_period_start - Current period start
  • current_period_end - Current period end
  • items - Subscription items/products

Pagination

Stripe uses cursor-based pagination:

pagination: {
  type: 'cursor',
  itemsPerPage: 100,  // Max 100 per request
}

The adapter automatically handles pagination cursors and fetches all records.

Filtering

Filter by customer or other fields:

filters: [
  { field: 'customer', operator: '=', value: 'cus_xxx' },
  { field: 'status', operator: '=', value: 'succeeded' },
]

Complete Example

import { Orchestrator, Pipeline } from 'openetl';
import { stripe } from '@openetl/stripe';
import { postgresql } from '@openetl/postgresql';

const vault = {
  'stripe-auth': {
    id: 'stripe-auth',
    type: 'api_key',
    credentials: {
      api_key: process.env.STRIPE_SECRET_KEY,
    },
  },
  'warehouse': {
    id: 'warehouse',
    type: 'basic',
    credentials: {
      host: 'localhost',
      database: 'analytics',
      username: 'etl',
      password: process.env.DB_PASSWORD,
    },
  },
};

const etl = Orchestrator(vault, { stripe, postgresql });

const pipeline: Pipeline = {
  id: 'sync-charges',
  source: {
    id: 'charges-source',
    adapter_id: 'stripe',
    endpoint_id: 'charges',
    credential_id: 'stripe-auth',
    fields: ['id', 'amount', 'currency', 'status', 'customer', 'created'],
    filters: [
      { field: 'status', operator: '=', value: 'succeeded' },
    ],
    pagination: { type: 'cursor', itemsPerPage: 100 },
  },
  target: {
    id: 'charges-target',
    adapter_id: 'postgresql',
    endpoint_id: 'table_insert',
    credential_id: 'warehouse',
    config: { schema: 'payments', table: 'stripe_charges' },
    fields: ['charge_id', 'amount', 'currency', 'status', 'customer_id', 'created_at'],
  },
  error_handling: {
    max_retries: 3,
    retry_interval: 1000,
    fail_on_error: true,
  },
};

const result = await etl.runPipeline(pipeline);
console.log(`Synced ${result.data.length} charges`);

Transformations

Convert amount from cents to dollars:

source: {
  // ...
  transform: [
    {
      type: 'toNumber',
      options: { field: 'amount' },
    },
  ],
},
// Then divide by 100 in your target or post-processing

Rate Limiting

Stripe has rate limits (typically 100 requests/second in live mode, 25 in test mode). The adapter handles rate limit responses (HTTP 429) with automatic retry.

error_handling: {
  max_retries: 5,
  retry_interval: 1000,
  fail_on_error: true,
}

Resources

Related