# Stripe Subscription

> Stripe Subscription with status lifecycle, billing periods, and item details.

- Name: `stripe-subscription`
- Categories: stripe
- Depends on: `@open-types/stripe-shared`
- Detail page: https://open-types.dev/types/stripe-subscription

## Install

```bash
# Types only
npx shadcn add @open-types/stripe-subscription

# Types + Zod v4 validators
npx shadcn add @open-types/stripe-subscription-zod

# Types + real-world examples
npx shadcn add @open-types/stripe-subscription-examples
```

## Types

```typescript
import type { StripeMetadata } from "./stripe-shared";

export type StripeSubscriptionStatus =
  | "incomplete"
  | "incomplete_expired"
  | "trialing"
  | "active"
  | "past_due"
  | "canceled"
  | "unpaid"
  | "paused";

export interface StripeSubscriptionItem {
  id: string;
  object: "subscription_item";
  price: string;
  quantity: number;
}

export interface StripeSubscriptionItems {
  data: StripeSubscriptionItem[];
}

export interface StripeSubscription {
  id: string;
  object: "subscription";
  customer: string;
  status: StripeSubscriptionStatus;
  current_period_start: number;
  current_period_end: number;
  cancel_at_period_end: boolean;
  canceled_at: number | null;
  items: StripeSubscriptionItems;
  metadata: StripeMetadata;
  created: number;
  livemode: boolean;
}
```

## Zod validator

```typescript
import * as z from "zod";
import type {
  StripeSubscription,
  StripeSubscriptionItem,
  StripeSubscriptionItems,
  StripeSubscriptionStatus,
} from "../types/stripe-subscription";
import { stripeMetadataSchema } from "./stripe-shared";

export const stripeSubscriptionStatusSchema = z.enum([
  "incomplete",
  "incomplete_expired",
  "trialing",
  "active",
  "past_due",
  "canceled",
  "unpaid",
  "paused",
]) satisfies z.ZodType<StripeSubscriptionStatus>;

export const stripeSubscriptionItemSchema = z.object({
  id: z.string(),
  object: z.literal("subscription_item"),
  price: z.string(),
  quantity: z.number(),
}) satisfies z.ZodType<StripeSubscriptionItem>;

export const stripeSubscriptionItemsSchema = z.object({
  data: z.array(stripeSubscriptionItemSchema),
}) satisfies z.ZodType<StripeSubscriptionItems>;

export const stripeSubscriptionSchema = z.object({
  id: z.string(),
  object: z.literal("subscription"),
  customer: z.string(),
  status: stripeSubscriptionStatusSchema,
  current_period_start: z.number(),
  current_period_end: z.number(),
  cancel_at_period_end: z.boolean(),
  canceled_at: z.number().nullable(),
  items: stripeSubscriptionItemsSchema,
  metadata: stripeMetadataSchema,
  created: z.number(),
  livemode: z.boolean(),
}) satisfies z.ZodType<StripeSubscription>;

export type {
  StripeSubscription,
  StripeSubscriptionItem,
  StripeSubscriptionItems,
  StripeSubscriptionStatus,
} from "../types/stripe-subscription";
```

## Examples

```typescript
// Source: https://docs.stripe.com/api/subscriptions/object
// Captured: 2026-05
import type {
  StripeSubscriptionItem,
  StripeSubscriptionItems,
  StripeSubscription,
  StripeSubscriptionStatus,
} from "../types/stripe-subscription";
import { stripeIds } from "./shared/stripe.examples";

const itemPro = {
  id: stripeIds.subscriptionItem,
  object: "subscription_item",
  price: stripeIds.price,
  quantity: 2,
} as const satisfies StripeSubscriptionItem;

const itemAddon = {
  id: "si_Q7w8E9r0T1y2U3",
  object: "subscription_item",
  price: "price_1Ot90A2eZvKYlo2Caddon456",
  quantity: 5,
} as const satisfies StripeSubscriptionItem;

export const stripeSubscriptionItemExamples = {
  pro: itemPro,
  addon: itemAddon,
  single: { ...itemPro, quantity: 1 } satisfies StripeSubscriptionItem,
} as const;

export const stripeSubscriptionItemsExamples = {
  single: { data: [itemPro] } satisfies StripeSubscriptionItems,
  multiple: { data: [itemPro, itemAddon] } satisfies StripeSubscriptionItems,
  empty: { data: [] } satisfies StripeSubscriptionItems,
} as const;

export const stripeSubscriptionStatusExamples = {
  incomplete: "incomplete",
  incompleteExpired: "incomplete_expired",
  trialing: "trialing",
  active: "active",
  pastDue: "past_due",
  canceled: "canceled",
  unpaid: "unpaid",
  paused: "paused",
} as const satisfies Record<string, StripeSubscriptionStatus>;

const active = {
  id: stripeIds.subscription,
  object: "subscription",
  customer: stripeIds.customer,
  status: "active",
  current_period_start: 1712948400,
  current_period_end: 1715626800,
  cancel_at_period_end: false,
  canceled_at: null,
  items: { data: [itemPro] },
  metadata: { plan: "pro" },
  created: 1712948400,
  livemode: false,
} as const satisfies StripeSubscription;

export const stripeSubscriptionExamples = {
  active,
  trialing: { ...active, status: "trialing" } satisfies StripeSubscription,
  pastDue: { ...active, status: "past_due" } satisfies StripeSubscription,
  scheduledCancellation: {
    ...active,
    cancel_at_period_end: true,
  } satisfies StripeSubscription,
  canceled: {
    ...active,
    id: "sub_1Ot8y92eZvKYlo2Cend99999",
    status: "canceled",
    cancel_at_period_end: true,
    canceled_at: 1714000000,
  } satisfies StripeSubscription,
  multiItem: {
    ...active,
    id: "sub_1Ot8y92eZvKYlo2Cmulti0001",
    items: { data: [itemPro, itemAddon] },
  } satisfies StripeSubscription,
} as const;
```
