Skip to main content

Overview

The /attach endpoint is Autumn’s unified purchase flow handler. With one function call, you can:
  • Create new subscriptions with Stripe Checkout
  • Handle upgrades and downgrades between plans
  • Apply discounts, free trials, and custom pricing
  • Process immediate or deferred billing

Quick Start

import { useCustomer } from '@useautumn/autumn-js/react';

function UpgradeButton() {
  const { attach } = useCustomer();

  const handleUpgrade = async () => {
    await attach({ 
      planId: "pro" 
    });
    // User is automatically redirected to checkout if payment is needed
  };

  return <button onClick={handleUpgrade}>Upgrade to Pro</button>;
}

Parameters

customerId
string
required
The ID of the customer attaching to the plan.
planId
string
required
The ID of the plan to attach.
entityId
string
The ID of the entity for entity-scoped plans (e.g., per-workspace billing).
featureQuantities
array
Customize feature quantities (e.g., number of seats).
featureQuantities: [
  { featureId: "seats", quantity: 5 },
  { featureId: "storage", quantity: 100 }
]
customize
object
Override plan pricing, items, or trial configuration.
customize: {
  price: { amount: 2999, interval: "month" },
  items: [{ featureId: "api_calls", included: 10000 }],
  freeTrial: { durationLength: 14, durationType: "day" }
}
discounts
array
Apply promotional discounts or rewards.
discounts: [
  { promotionCode: "LAUNCH50" },
  { rewardId: "reward_xyz" }
]
successUrl
string
URL to redirect to after successful checkout (defaults to current page in frontend).
invoiceMode
object
Control deferred invoicing behavior.
invoiceMode: {
  enabled: true,
  enablePlanImmediately: true,  // Grant access before payment
  finalize: false                // Don't auto-finalize invoice
}
prorationBehavior
string
How to handle prorations on upgrades/downgrades: "create_prorations" (default), "none", or "always_invoice".

Response

interface AttachResponse {
  customerId: string;           // The customer ID
  entityId?: string;            // The entity ID (if entity-scoped)
  paymentUrl: string | null;    // Checkout URL (null if no payment needed)
  invoice?: {                   // Invoice details (if created)
    stripeId: string;
    total: number;
    currency: string;
    status: string;
    hostedInvoiceUrl: string | null;
  };
  requiredAction?: {            // Action needed (e.g., payment required)
    code: string;
    reason: string;
  };
}

Common Use Cases

New Subscription with Free Trial

const { attach } = useCustomer();

await attach({
  planId: "pro",
  customize: {
    freeTrial: {
      durationLength: 14,
      durationType: "day",
      cardRequired: true  // Require card upfront
    }
  }
});

Seat-Based Plan with Custom Quantity

const { attach } = useCustomer();

await attach({
  planId: "team",
  featureQuantities: [
    { featureId: "seats", quantity: 10 }
  ]
});

Custom Pricing for Enterprise Customer

const { attach } = useCustomer();

await attach({
  planId: "enterprise",
  customize: {
    price: {
      amount: 49900,      // $499/month
      interval: "month"
    },
    items: [
      { featureId: "api_calls", unlimited: true },
      { featureId: "seats", included: 50 }
    ]
  }
});

Error Handling

import { AutumnClientError } from '@useautumn/autumn-js/react';

const { attach } = useCustomer();

try {
  await attach({ planId: "pro" });
} catch (error) {
  if (error instanceof AutumnClientError) {
    if (error.code === "payment_method_required") {
      // Customer needs to add payment method
      console.log("Please add a payment method");
    } else if (error.code === "plan_not_found") {
      // Plan doesn't exist
      console.log("Invalid plan selected");
    }
  }
}

Preview Before Attaching

Use previewAttach to show customers what they’ll be charged before confirming:
const { previewAttach } = useCustomer();

const preview = await previewAttach({ planId: "pro" });

// Show line items and total
preview.lineItems.forEach(item => {
  console.log(`${item.description}: $${item.amount / 100}`);
});
console.log(`Total: $${preview.total / 100}`);

Next Steps

Check Access

Learn how to verify customer access to features

Track Usage

Record usage events for metered billing

Build docs developers (and LLMs) love