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
The ID of the customer attaching to the plan.
The ID of the plan to attach.
The ID of the entity for entity-scoped plans (e.g., per-workspace billing).
Customize feature quantities (e.g., number of seats).featureQuantities: [
{ featureId: "seats", quantity: 5 },
{ featureId: "storage", quantity: 100 }
]
Override plan pricing, items, or trial configuration.customize: {
price: { amount: 2999, interval: "month" },
items: [{ featureId: "api_calls", included: 10000 }],
freeTrial: { durationLength: 14, durationType: "day" }
}
Apply promotional discounts or rewards.discounts: [
{ promotionCode: "LAUNCH50" },
{ rewardId: "reward_xyz" }
]
URL to redirect to after successful checkout (defaults to current page in frontend).
Control deferred invoicing behavior.invoiceMode: {
enabled: true,
enablePlanImmediately: true, // Grant access before payment
finalize: false // Don't auto-finalize invoice
}
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