npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@apexara/stripe

v1.0.3

Published

Stripe service layer and webhook dispatcher

Readme

@apexara/stripe

A typed Stripe service layer for Node.js. Wraps the official Stripe SDK into focused, independently injectable services with built-in webhook handling, idempotency, and affiliate payout math.

Contents


Installation

npm install @apexara/stripe

Express is an optional peer dependency — only required if you use StripeWebhookHandler:

npm install express

Requirements: Node.js 18+, TypeScript 5+


Quick Start

import { ApexStripe } from '@apexara/stripe';

const stripe = new ApexStripe(
  { secretKey: process.env.STRIPE_SECRET_KEY! },
  { currency: 'usd' },
);

// Create a customer
const customer = await stripe.customers.createCustomer('Jane', 'Doe', '[email protected]');

// Create a checkout session
const clientSecret = await stripe.checkout.createCheckoutSession({
  mode: 'payment',
  customerId: customer.id,
  name: 'Order #1234',
  cost: 4900,       // $49.00 in cents
  quantity: 1,
  returnUrl: 'https://example.com/payment-result',
});

// Access the raw Stripe client if needed
const balance = await stripe.client.balance.retrieve();

Configuration

StripeClientConfig

Passed as the first argument to ApexStripe. Controls how the Stripe SDK client is created.

interface StripeClientConfig {
  secretKey: string;
  apiVersion?: Stripe.LatestApiVersion; // Default: '2025-08-27.basil'
}

StripeServiceConfig

Passed as the second (optional) argument to ApexStripe. All fields are optional — defaults are applied for any field not provided.

interface StripeServiceConfig {
  // Stripe settings
  currency?: string;                    // Default: 'usd'

  // Payment methods per context
  orderPaymentMethods?: string[];       // Default: ['card', 'link', 'cashapp', 'klarna']
  subscriptionPaymentMethods?: string[]; // Default: ['card', 'link', 'cashapp']
  setupIntentPaymentMethods?: string[]; // Default: ['card']

  // Checkout behavior
  checkoutUiMode?: 'custom' | 'embedded' | 'hosted'; // Default: 'custom'
  allowPromotionCodes?: boolean;        // Default: true
  savePaymentMethod?: boolean;          // Default: true
  orderInvoiceCreation?: boolean;       // Default: true

  // Invoices
  invoiceCollectionMethod?: 'send_invoice' | 'charge_automatically'; // Default: 'send_invoice'
  invoiceDaysUntilDue?: number;         // Default: 3
  invoicePaymentMethodTypes?: string[]; // Default: ['card', 'link']

  // Connected accounts
  connectedAccountType?: 'express' | 'standard' | 'custom'; // Default: 'express'

}

Full example with all defaults overridden:

const stripe = new ApexStripe(
  { secretKey: process.env.STRIPE_SECRET_KEY! },
  {
    currency: 'eur',
    orderPaymentMethods: ['card'],
    subscriptionPaymentMethods: ['card'],
    setupIntentPaymentMethods: ['card'],
    checkoutUiMode: 'embedded',
    allowPromotionCodes: false,
    savePaymentMethod: false,
    orderInvoiceCreation: false,
    invoiceCollectionMethod: 'charge_automatically',
    invoiceDaysUntilDue: 7,
    invoicePaymentMethodTypes: ['card'],
    connectedAccountType: 'standard',
  },
);

Services

All services are available as properties on the ApexStripe instance. They can also be instantiated independently — see Advanced Usage.


CheckoutService

stripe.checkout

Handles Stripe Checkout sessions, Setup Intents, and affiliate payout calculations.


createCheckoutSession(params)

Creates a payment or subscription checkout session. Returns the client_secret for use with Stripe.js.

Payment mode:

const clientSecret = await stripe.checkout.createCheckoutSession({
  mode: 'payment',
  customerId: 'cus_xxx',
  name: 'Order #1234',
  cost: 4900,           // Amount in cents
  quantity: 1,
  returnUrl: 'https://example.com/result',
  metadata: { orderId: '1234' },
  // Optional: affiliate payout
  affiliate: {
    accountId: 'acct_xxx',  // Connected account ID
    amount: 490,             // Payout amount in cents
  },
});

Subscription mode:

const clientSecret = await stripe.checkout.createCheckoutSession({
  mode: 'subscription',
  customerId: 'cus_xxx',
  priceIds: ['price_xxx'],
  quantity: 1,
  returnUrl: 'https://example.com/result',
  metadata: { userId: 'user_123' },
  // Optional: affiliate payout
  affiliate: {
    transferData: { destination: 'acct_xxx', amount_percent: 19 },
    metadata: { affiliateId: 'aff_xxx' },
  },
});

createSetupIntentSession(customerId)

Creates a Setup Intent for saving a payment method without charging. Returns the client_secret.

const clientSecret = await stripe.checkout.createSetupIntentSession('cus_xxx');

expireCheckoutSession(sessionId)

Expires an open checkout session. Silently ignores sessions that are already expired — safe to call unconditionally.

await stripe.checkout.expireCheckoutSession('cs_xxx');

retrieveCheckoutSession(sessionId, options?)

Retrieves a checkout session with optional expansion.

const session = await stripe.checkout.retrieveCheckoutSession('cs_xxx', {
  expand: ['payment_intent.latest_charge', 'invoice'],
});

getPaymentIntent(paymentIntentId, options?)

Retrieves a payment intent.

const intent = await stripe.checkout.getPaymentIntent('pi_xxx');

CustomerService

stripe.customers


createCustomer(firstName, lastName, email)

Creates a Stripe customer. The full name is stored as ${firstName} ${lastName}.

const customer = await stripe.customers.createCustomer('Jane', 'Doe', '[email protected]');
// → Stripe.Customer

updateCustomerDefaultPaymentMethod(customerId, paymentMethodId)

Sets the default payment method on a customer's invoice settings.

await stripe.customers.updateCustomerDefaultPaymentMethod('cus_xxx', 'pm_xxx');

InvoiceService

stripe.invoices


createInvoice(params)

Creates an invoice with a single line item and either sends it or finalizes it, depending on invoiceCollectionMethod.

  • send_invoice — creates, adds line item, sends — customer receives an email with payment link
  • charge_automatically — creates, adds line item, finalizes — Stripe charges the default payment method
const invoice = await stripe.invoices.createInvoice({
  customerId: 'cus_xxx',
  amount: 2000,            // In cents
  description: 'Credit top-up — 500 records',
  metadata: { origin: 'admin', credits: '500' },
});
// → Stripe.Invoice (sent or finalized)

listInvoicePayments(invoiceId, params?)

Lists all payments recorded against an invoice.

const payments = await stripe.invoices.listInvoicePayments('in_xxx');
// → Stripe.ApiList<Stripe.InvoicePayment>

findPendingActivationInvoice(customerId)

Checks whether a customer has an open invoice from a subscription_create event whose subscription is still active or incomplete. Returns the invoice data or null.

Use this to prompt the user to pay their pending subscription invoice after an admin-created invoice-based subscription.

const pending = await stripe.invoices.findPendingActivationInvoice('cus_xxx');

if (pending) {
  // { subscriptionId: 'sub_xxx', hostedInvoiceUrl: 'https://...' }
  redirectToInvoice(pending.hostedInvoiceUrl);
}

Returns null when:

  • No open invoices exist
  • No invoice has billing_reason === 'subscription_create'
  • The subscription is canceled or incomplete_expired

PaymentLinkService

stripe.paymentLinks


createPaymentLink(params)

Creates a Stripe Price and Payment Link in one call. Returns the link ID, URL, and the underlying price/product IDs needed to archive later.

const link = await stripe.paymentLinks.createPaymentLink({
  name: 'Order #1234',
  cost: 4900,
  redirectUrl: 'https://example.com/result',
  metadata: { orderId: '1234' },
  // Optional: affiliate payout
  affiliate: {
    accountId: 'acct_xxx',
    amount: 490,
  },
});
// → { id, url, productId, priceId }

archivePaymentLink(linkId, productId, priceId)

Deactivates the payment link, product, and price so they no longer appear in Stripe or accept payments.

await stripe.paymentLinks.archivePaymentLink(
  link.id,
  link.productId,
  link.priceId,
);

PaymentMethodService

stripe.paymentMethods


getPaymentMethod(paymentMethodId)

const pm = await stripe.paymentMethods.getPaymentMethod('pm_xxx');
// → Stripe.PaymentMethod

listPaymentMethods(customerId)

Returns the customer's saved payment methods as a flat array.

const methods = await stripe.paymentMethods.listPaymentMethods('cus_xxx');
// → Stripe.PaymentMethod[]

attachPaymentMethod(paymentMethodId, customerId)

Attaches a payment method to a customer.

const pm = await stripe.paymentMethods.attachPaymentMethod('pm_xxx', 'cus_xxx');

setDefaultPaymentMethodForCustomerAndSubscription(customerId, subscriptionId, paymentMethodId)

Attaches the payment method, sets it as the customer's invoice default, and sets it as the subscription's default — all in one call.

await stripe.paymentMethods.setDefaultPaymentMethodForCustomerAndSubscription(
  'cus_xxx',
  'sub_xxx',
  'pm_xxx',
);

setDefaultPaymentMethod(subscriptionId, paymentMethodId)

Sets the subscription's default payment method unconditionally.

await stripe.paymentMethods.setDefaultPaymentMethod('sub_xxx', 'pm_xxx');

setDefaultPaymentMethodIfMissing(subscriptionId, paymentMethodId)

Sets the default only if the subscription has no default payment method currently set.

const { changed } = await stripe.paymentMethods.setDefaultPaymentMethodIfMissing('sub_xxx', 'pm_xxx');

removePaymentMethod(customerId, subscriptionId, paymentMethodId)

Removes a payment method safely. If it is the subscription's default, another payment method is assigned first. Throws if it is the only payment method on the customer.

const { newDefaultId } = await stripe.paymentMethods.removePaymentMethod(
  'cus_xxx',
  'sub_xxx',
  'pm_xxx',
);

PriceService

stripe.prices


createCustomSubscriptionPrice(params)

Creates a recurring price on an existing Stripe product.

const price = await stripe.prices.createCustomSubscriptionPrice({
  cost: 9900,                // In cents
  billingPeriod: 'month',
  billingIntervalCount: 1,
  label: 'Pro Monthly',
  stripeProductId: 'prod_xxx',
  metadata: { label: 'Pro Monthly', credits: '1000' },
});
// → Stripe.Price

billingPeriod accepts: 'day' | 'week' | 'month' | 'year'


archivePrice(priceId)

Sets a price to active: false so it can no longer be used for new subscriptions.

await stripe.prices.archivePrice('price_xxx');

ConnectedAccountService

stripe.connectedAccounts

Handles Stripe Connect for marketplace and affiliate payout scenarios.


createConnectedAccount(metadata?)

Creates a new connected account (type from config, defaults to 'express'). Returns the account ID.

const accountId = await stripe.connectedAccounts.createConnectedAccount({
  userId: 'user_123',
});
// → 'acct_xxx'

deleteConnectedAccount(accountId)

Permanently deletes a connected account.

await stripe.connectedAccounts.deleteConnectedAccount('acct_xxx');

createAccountLink(accountId, refreshUrl, returnUrl, type?)

Generates a Stripe-hosted onboarding or management URL for a connected account. Returns the URL string.

const url = await stripe.connectedAccounts.createAccountLink(
  'acct_xxx',
  'https://example.com/onboarding/refresh',
  'https://example.com/onboarding/return',
  // type defaults to 'account_onboarding'
);

type accepts: 'account_onboarding' | 'account_update'


createLoginLink(accountId)

Generates a single-use Express Dashboard login URL for a connected account. Returns the URL string.

const url = await stripe.connectedAccounts.createLoginLink('acct_xxx');

SubscriptionService

stripe.subscriptions

The most comprehensive service. Covers the full subscription lifecycle including scheduling, upgrades, downgrades, and payment method management.


Basic operations

// Get a subscription (expands items.data.price)
const sub = await stripe.subscriptions.getSubscriptionById('sub_xxx');

// Get all subscriptions for a customer (status: 'all', expands default_payment_method)
const subs = await stripe.subscriptions.getAllUserSubscriptions('cus_xxx');
// → Stripe.Subscription[] (empty array if customerId is falsy)

// Update a subscription
const updated = await stripe.subscriptions.updateSubscription('sub_xxx', {
  metadata: { userId: 'user_123' },
});

// Cancel immediately
const cancelled = await stripe.subscriptions.cancelSubscription('sub_xxx');

Lifecycle — cancel at period end / resume

// Schedule cancellation at end of billing period.
// Throws if status is not 'active' or 'past_due'.
const sub = await stripe.subscriptions.cancelSubscriptionAtPeriodEnd('sub_xxx');

// Undo a scheduled cancellation.
// Throws if cancel_at_period_end is false or status is not resumable.
const sub = await stripe.subscriptions.resumeSubscription('sub_xxx');

Plan switching and credits

Use applyPlanCredit to create a credit invoice item (a negative charge) before switching plans, so the customer is credited for unused days on their current plan:

await stripe.subscriptions.applyPlanCredit(
  'cus_xxx',
  'sub_xxx',
  3200,             // Amount in cents — stored as a negative invoice item
  'usd',
  'Credit for unused Pro plan days',  // Optional
  { type: 'upgrade_credit' },         // Optional metadata
);

Then switch the subscription to the new price immediately (billing cycle resets to now, no proration by default):

const updated = await stripe.subscriptions.switchSubscriptionPlan(
  'sub_xxx',
  'si_xxx',         // The subscription item being replaced
  'price_xxx',
  {
    quantity: 1,                // Optional, defaults to 1
    proration: 'none',          // Optional — pass 'create_prorations' to let Stripe calculate
  },
);

Downgrades (scheduled)

Downgrades are scheduled to take effect at the end of the current billing period using Stripe Subscription Schedules.

// Schedule a downgrade to a lower price at period end.
// Tags the schedule with { type: 'downgrade' } for later identification.
const schedule = await stripe.subscriptions.scheduleDowngrade(
  subscription,
  'price_lower_xxx',
  {
    transferData: { destination: 'acct_xxx', amount_percent: 19 }, // Optional
    phaseMetadata: { affiliateId: 'aff_xxx' },                     // Optional
    scheduleMetadata: { initiatedBy: 'user' },                     // Optional
  },
);

// Check if a downgrade is scheduled (returns null if not, or if the
// schedule is not tagged as a downgrade).
const schedule = await stripe.subscriptions.getDowngradeSchedule(subscription);
if (schedule) {
  // schedule.phases[1].items[0].price → the new lower price
}

// Cancel a scheduled downgrade (e.g. the user upgrades instead).
// Returns true if a downgrade schedule was found and released, false otherwise.
const released = await stripe.subscriptions.releaseScheduleIfDowngrade(subscription);

For more control, get or create the schedule directly:

const schedule = await stripe.subscriptions.getOrCreateSubscriptionSchedule(subscription);

Invoice-based subscriptions (admin-created)

Creates a subscription using send_invoice collection and immediately emails the invoice to the customer. Use this for admin-created subscriptions where the customer pays via an emailed link rather than through a checkout session.

const { subscription, invoiceId, invoiceUrl } =
  await stripe.subscriptions.createInvoiceBasedSubscription(
    'cus_xxx',
    'price_xxx',
    {
      daysUntilDue: 3,                         // Overrides config default
      paymentMethodTypes: ['card', 'link'],
      metadata: { adminId: 'admin_123', userId: 'user_456' },
      transferData: { destination: 'acct_xxx', amount_percent: 19 }, // Optional affiliate
      quantity: 1,
    },
  );

// invoiceUrl — the hosted_invoice_url to show the customer
// invoiceId  — the Stripe invoice ID

Utilities

// Extract fields needed to keep a local subscription document in sync.
// Falls back to provided values when the subscription has no items yet.
const fields = stripe.subscriptions.buildSubscriptionSyncFields(subscription, {
  currentPeriodStart: existingDoc.currentPeriodStart,
  currentPeriodEnd: existingDoc.currentPeriodEnd,
  itemId: existingDoc.itemId,
});
// → { status, cancelAtPeriodEnd, currentPeriodStart, currentPeriodEnd, itemId }

// Get the primary subscription item, preferring a known item ID.
const item = stripe.subscriptions.getPrimarySubscriptionItem(subscription, 'si_xxx');
// → Stripe.SubscriptionItem | null

Affiliate Payout Helpers

Two standalone functions are exported for calculating affiliate payouts after deducting Stripe processing fees. Both require a processingFees object ({ flat: number, percent: number }).

import {
  calculateAffiliatePaymentPayoutAmount,
  calculateAffiliateSubscriptionPayoutPercent,
} from '@apexara/stripe';

const fees = { flat: 30, percent: 0.029 }; // Standard Stripe rates

// One-time payment payout — returns flat amount in cents
// cost = 10000 ($100), affiliatePayoutPercent = 20
// stripeFee = round(10000 * 0.029 + 30) = 320
// payout = round((10000 - 320) * 0.20) = 1936 ($19.36)
const amount = calculateAffiliatePaymentPayoutAmount(10000, 20, fees);
// → 1936

// Subscription payout — returns percentage to pass to transfer_data.amount_percent
// subscriptionCost = 10000, payoutPercent = 0.20
// result = ((10000 - 320) * 0.20) / 10000 ≈ 0.19
const percent = calculateAffiliateSubscriptionPayoutPercent(10000, 0.20, fees);
// → 0.19

Webhooks

StripeWebhookHandler handles the main Stripe webhook and the connected account webhook. It performs signature verification, idempotency checks, and event dispatch.

Setup

import { StripeWebhookHandler, WebhookHooks, WebhookHandlerConfig } from '@apexara/stripe';

const config: WebhookHandlerConfig = {
  webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
  connectedWebhookSecret: process.env.STRIPE_WEBHOOK_CONNECTED_SECRET, // Optional
};

const hooks: WebhookHooks = {
  // Required: pluggable idempotency store
  eventStore: {
    tryInsert: async (eventId, type) => {
      // Return true if this is a new event (insert succeeded).
      // Return false if the event was already processed (duplicate).
      // Use a unique index to make this atomic.
      return db.stripeEvents.tryInsert({ eventId, type });
    },
  },

  // Optional: implement only the events you care about

  onCheckoutCompleted: async ({ session, metadata }) => {
    // session is pre-expanded: payment_intent.latest_charge + invoice
    await handleOrder(session, metadata);
  },

  onInvoicePaid: async ({ event, invoice }) => {
    await grantCredits(invoice);
  },

  onInvoicePaymentFailed: async ({ event, invoice, failReason }) => {
    // failReason is pre-extracted from the payment intent (decline_code or error code)
    await notifyUser(invoice, failReason);
  },

  onSubscriptionDeleted: async ({ event, subscription }) => {
    await deactivateSubscription(subscription.id);
  },

  onConnectedAccountUpdated: async ({ account }) => {
    await syncAffiliateStatus(account);
  },

  // Optional: called when a non-critical internal error occurs (e.g. fail reason extraction)
  onError: (context, error) => {
    logger.error(`Webhook error in ${context}`, error);
  },
};

const handler = new StripeWebhookHandler(
  hooks,
  stripeClient,    // Raw Stripe instance — use ApexStripe.client or createStripeClient()
  config,
  checkoutService, // ApexStripe.checkout or a standalone CheckoutService
  invoiceService,  // ApexStripe.invoices or a standalone InvoiceService
);

Express routes

The handler plugs directly into Express. The raw body must be available on req — register express.raw() before the webhook routes.

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

// Express mode — pass next to delegate errors to the app's error middleware
app.post('/stripe/webhook', (req, res, next) => handler.handle(req, res, next));
app.post('/stripe/webhook/connected', (req, res, next) => handler.handleConnected(req, res, next));

// Standalone mode — omit next and the handler manages error responses itself
app.post('/stripe/webhook', (req, res) => handler.handle(req, res));

Idempotency

Every incoming event is checked against the event store before being dispatched. If tryInsert returns false, the event is acknowledged with HTTP 200 and skipped — no hook is called. This prevents duplicate processing when Stripe retries delivery.

The tryInsert implementation must be atomic. Use a unique index (MongoDB, PostgreSQL) or a Redis SET NX to avoid race conditions when Stripe delivers the same event to multiple server instances simultaneously.

MongoDB example:

eventStore: {
  tryInsert: async (eventId, type) => {
    try {
      await StripeEventModel.create({ eventId, type, processedAt: new Date() });
      return true;
    } catch (err: any) {
      if (err.code === 11000) return false; // Duplicate key — already processed
      throw err;
    }
  },
},

Events dispatched

| Stripe event | Hook called | Notes | |---|---|---| | checkout.session.completed | onCheckoutCompleted | Session re-fetched and expanded with payment_intent.latest_charge and invoice before the hook is called | | invoice.paid | onInvoicePaid | Raw invoice from event data | | invoice.payment_failed | onInvoicePaymentFailed | Raw invoice + failReason pre-extracted from the payment intent (decline_code or code) | | customer.subscription.deleted | onSubscriptionDeleted | Raw subscription from event data | | account.updated (connected) | onConnectedAccountUpdated | Raw account from event data | | All other event types | — | Silently ignored — HTTP 200 returned. Throwing for unknown events would cause Stripe to retry for up to 72 hours. |


Advanced Usage

Using services independently

Every service can be instantiated on its own with an injected Stripe client. This is useful when you only need part of the package or when injecting the client from elsewhere.

import Stripe from 'stripe';
import { createStripeClient, SubscriptionService, InvoiceService } from '@apexara/stripe';

const client = createStripeClient({ secretKey: process.env.STRIPE_SECRET_KEY! });

// Services that need config
const subscriptions = new SubscriptionService(client, {
  currency: 'usd',
  invoiceDaysUntilDue: 7,
  invoiceCollectionMethod: 'send_invoice',
  invoicePaymentMethodTypes: ['card', 'link'],
  // All other StripeServiceConfig fields are required when constructing directly —
  // use ApexStripe to have defaults applied automatically.
});

// Services that only need the client
import { CustomerService, PaymentMethodService } from '@apexara/stripe';

const customers = new CustomerService(client);
const paymentMethods = new PaymentMethodService(client);

Using the raw Stripe client

The raw Stripe instance is accessible via ApexStripe.client:

const apex = new ApexStripe({ secretKey: '...' });

// Full Stripe SDK — use for anything not covered by the services
const products = await apex.client.products.list({ limit: 10 });

Or create it independently:

import { createStripeClient } from '@apexara/stripe';

const stripe = createStripeClient({
  secretKey: process.env.STRIPE_SECRET_KEY!,
  apiVersion: '2025-08-27.basil', // Optional
});

API Reference — Types

All types are exported from the package root.

Config

import {
  StripeClientConfig,
  StripeServiceConfig,
  StripeProcessingFees,
  WebhookHandlerConfig,
} from '@apexara/stripe';

Checkout

import {
  CreateCheckoutSessionParams,
  CreatePaymentCheckoutSessionParams,
  CreateSubscriptionCheckoutSessionParams,
  AffiliatePaymentParams,
  AffiliateSubscriptionParams,
} from '@apexara/stripe';

Subscriptions

import {
  ScheduleDowngradeOptions,
  SwitchSubscriptionPlanOptions,
  CreateInvoiceSubscriptionOptions,
  CreateInvoiceSubscriptionResult,
  SubscriptionSyncFields,
} from '@apexara/stripe';

Invoices

import {
  CreateInvoiceParams,
  PendingActivationInvoice,
} from '@apexara/stripe';

Payment links

import {
  CreatePaymentLinkParams,
  PaymentLinkResult,
} from '@apexara/stripe';

Prices

import { CreateCustomPriceParams } from '@apexara/stripe';

Webhooks

import {
  WebhookHooks,
  WebhookEventStore,
  CheckoutCompletedPayload,
  InvoicePaidPayload,
  InvoicePaymentFailedPayload,
  SubscriptionDeletedPayload,
  ConnectedAccountUpdatedPayload,
} from '@apexara/stripe';

Utilities

import { getBillingCycleLabel } from '@apexara/stripe';

getBillingCycleLabel('month', 1);  // → 'Monthly'
getBillingCycleLabel('year', 1);   // → 'Yearly'
getBillingCycleLabel('week', 1);   // → 'Weekly'
getBillingCycleLabel('day', 1);    // → 'Daily'
getBillingCycleLabel('month', 3);  // → 'Quarterly'
getBillingCycleLabel('month', 6);  // → 'Semi-Annually'
getBillingCycleLabel('month', 2);  // → 'Every 2 months'

Development

# Install dependencies
npm install

# Build
npm run build

# Build in watch mode
npm run build:watch

# Type check (no emit)
npm run type-check

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

Test stack: Vitest with v8 coverage. Tests live in src/tests/ and are excluded from the build output.

Stripe API version: 2025-08-27.basil — pinned in src/client.ts. To use a different version, pass apiVersion in StripeClientConfig.


License

ISC