2
0
Source

Debug, edit, and fix billing endpoints. Covers legacy endpoints (attach/checkout/cancel) and the new v2 4-layer architecture (setup, compute, evaluate, execute). Use when working on billing, subscription, invoicing, or Stripe integration code.

Install

mkdir -p .claude/skills/billing && curl -L -o skill.zip "https://mcp.directory/api/skills/download/3339" && unzip -o skill.zip -d .claude/skills/billing && rm skill.zip

Installs to .claude/skills/billing

About this skill

Billing Operations Guide

When to Use This Skill

  • Debugging billing issues (double charges, missing invoices, wrong subscription items)
  • Adding new billing actions
  • Understanding how Autumn state maps to Stripe
  • Fixing subscription update/cancel/attach flows
  • Working with subscription schedules (future changes)
  • Understanding allocated invoice (mid-cycle usage-based invoicing)

V2 Billing Actions

All billing logic is orchestrated through billingActions (billing/v2/actions/index.ts). Handlers are thin — they call an action, then format the response.

// billing/v2/actions/index.ts
export const billingActions = {
  attach,              // Single product attach
  multiAttach,         // Attach multiple products atomically
  setupPayment,        // Setup payment method (+ optional plan validation)
  updateSubscription,  // Update quantity, cancel, uncancel, custom plan
  migrate,             // Programmatic product migration (not HTTP-exposed)

  legacy: {            // V1→V2 bridge adapters (backward compat)
    attach: legacyAttach,
    updateQuantity,
    renew,
  },
} as const;

Two additional billing operations live outside billingActions but use the same evaluate+execute pipeline:

  • createAllocatedInvoice — mid-cycle invoicing triggered by balance deduction
  • createCustomerWithDefaults — customer creation with default products

Action Quick Reference

ActionTriggerWhat It Does
attachHTTP billing.attachAdd/upgrade/downgrade a single product. Handles transitions, prorations, trials, checkout mode
multiAttachHTTP billing.multi_attachAttach multiple products atomically. At most one transition allowed
updateSubscriptionHTTP billing.updateChange quantity, cancel (immediate/end-of-cycle), uncancel, update custom plan items
setupPaymentHTTP billing.setup_paymentCreate Stripe setup checkout. Optionally validates a plan via preview first
createAllocatedInvoiceProgrammatic (balance deduction)Invoice for allocated usage changes (prepaid overages, usage upgrades/downgrades)
createCustomerWithDefaultsProgrammatic (customer creation)Two-phase: create customer + products in DB, then create Stripe subscription for paid defaults

Each HTTP action also has a preview variant (billing.preview_attach, billing.preview_multi_attach, billing.preview_update) that runs setup+compute+evaluate but skips execution.

The legacy V1 attach (POST /attach) still exists and delegates to billingActions.legacy.attach, which converts old AttachParams format into V2 billing context overrides. Similarly legacyUpdateQuantity and legacyRenew bridge old flows to V2.

Handler Pattern

Handlers are thin wrappers — they parse params, call the action, format response:

// billing/v2/handlers/handleAttachV2.ts
export const handleAttachV2 = createRoute({
  versionedBody: { latest: AttachParamsV1Schema, [ApiVersion.V1_Beta]: AttachParamsV0Schema },
  resource: AffectedResource.Attach,
  lock: { /* distributed lock per customer */ },
  handler: async (c) => {
    const ctx = c.get("ctx");
    const body = c.req.valid("json");

    const { billingContext, billingResult } = await billingActions.attach({
      ctx,
      params: body,
      preview: false,
    });

    return c.json(billingResultToResponse({ billingContext, billingResult }), 200);
  },
});

The 4-Layer Pattern (Inside Each Action)

Every action follows: Setup → Compute → Evaluate → Execute

// billing/v2/actions/attach/attach.ts (simplified)
export async function attach({ ctx, params, preview }) {
  // 1. SETUP — Fetch all context (customer, Stripe, products, trial, cycle anchors)
  const billingContext = await setupAttachBillingContext({ ctx, params });

  // 2. COMPUTE — Determine Autumn state changes (new products, transitions, line items)
  const autumnBillingPlan = computeAttachPlan({ ctx, attachBillingContext: billingContext, params });

  // 3. EVALUATE — Map Autumn changes → Stripe actions (UNIFIED across all actions)
  const stripeBillingPlan = await evaluateStripeBillingPlan({ ctx, billingContext, autumnBillingPlan });

  // 4. ERRORS — Validate before execution
  handleAttachV2Errors({ ctx, billingContext, billingPlan, params });

  if (preview) return { billingContext, billingPlan };

  // 5. EXECUTE — Run Stripe first, then Autumn DB (UNIFIED across all actions)
  const billingResult = await executeBillingPlan({ ctx, billingContext, billingPlan });
  return { billingContext, billingPlan, billingResult };
}

Key principle: evaluateStripeBillingPlan and executeBillingPlan are UNIFIED across all actions. Only modify them when adding new Stripe action types.

See V2 Four-Layer Pattern Deep Dive for detailed explanation.

Allocated Invoice

Not an HTTP endpoint — triggered during executePostgresDeduction when allocated (prepaid) usage changes.

File: server/src/internal/balances/utils/allocatedInvoice/createAllocatedInvoice.ts

When it fires: A customer with usage-based allocated pricing (e.g., prepaid seats) has their usage change. The system needs to invoice for the delta.

Flow:

  1. Setup (setupAllocatedInvoiceContext) — re-fetches full customer, computes previous/new usage and overage from entitlement snapshots
  2. Compute (computeAllocatedInvoicePlan) — builds refund line item for previous usage + charge line item for new usage. Handles upgrade (delete replaceables) and downgrade (create replaceables) scenarios
  3. Evaluate + Execute — standard unified pipeline (evaluateStripeBillingPlanexecuteBillingPlan)
  4. Post-execute — if Stripe invoice payment fails, voids invoice and throws PayInvoiceFailed
  5. Mutation — calls refreshDeductionUpdate to mutate the deduction update with replaceable and balance changes

Key difference from other actions: Produces only updateCustomerEntitlements + lineItems (no insertCustomerProducts). The AutumnBillingPlan is minimal since the customer product already exists.

Two Critical Stripe Mappings

Getting billing right means getting these two mappings right:

1. Subscription Items (Immediate Changes)

When: Updating a subscription right now (add/remove/change items immediately)

Key function: buildStripeSubscriptionItemsUpdate

Flow:

FullCusProduct[] 
  → filter by subscription ID
  → filter by active statuses  
  → customerProductToStripeItemSpecs() 
  → diff against current subscription
  → Stripe.SubscriptionUpdateParams.Item[]

See Stripe Subscription Items Reference for details.

2. Schedule Phases (Future Changes)

When: Scheduling changes for the future (downgrades at cycle end, scheduled cancellations)

Key function: buildStripePhasesUpdate

Flow:

FullCusProduct[]
  → normalize timestamps to seconds
  → buildTransitionPoints() (find all start/end times)
  → for each period: filter active products
  → customerProductsToPhaseItems()
  → Stripe.SubscriptionScheduleUpdateParams.Phase[]

See Stripe Schedule Phases Reference for details.

Stripe Invoice Decision Tree

Critical: Stripe sometimes forces invoice creation. If you also create a manual invoice, customer gets double-charged.

Does Stripe force-create an invoice?
├── Creating a new subscription? 
│   └── YES → Stripe creates invoice. DO NOT create manual invoice.
│
├── Removing trial from subscription? (isTrialing && !willBeTrialing)
│   └── YES → Stripe creates invoice. DO NOT create manual invoice.
│
└── Otherwise
    └── NO → We create manual invoice using buildStripeInvoiceAction()

Key functions:

  • shouldCreateManualStripeInvoice() - Returns true if WE should create invoice
  • willStripeSubscriptionUpdateCreateInvoice() - Returns true if STRIPE will create invoice

See Stripe Invoice Rules Reference for full decision tree.

Common Issues & Fixes

SymptomLikely CauseQuick Fix
Double invoice chargeCreated manual invoice when Stripe already didCheck shouldCreateManualStripeInvoice()
Subscription items wrongcustomerProductToStripeItemSpecs output incorrectDebug spec generation, check quantity rules
Schedule phases wrongTransition points incorrectCheck buildTransitionPoints, run schedule phases tests
Trial not endingtrialContext not set up correctlyCheck setupTrialContext
Quantities wrongMetered vs licensed confusionundefined = metered, 0 = entity placeholder, N = licensed
Allocated invoice failsStripe payment failed for usage deltaInvoice is voided, PayInvoiceFailed thrown

See Common Bugs Reference for detailed debugging steps.

Adding a New Billing Action

  1. Create action function: billing/v2/actions/myAction/myAction.ts

    • Follow the attach.ts pattern: setup → compute → evaluate → errors → execute
    • Return { billingContext, billingPlan, billingResult }
  2. Create setup function: billing/v2/actions/myAction/setup/setupMyActionBillingContext.ts

    • Extend BillingContext interface if needed
    • Use shared setup functions (setupFullCustomerContext, setupStripeBillingContext, etc.)
  3. Create compute function: billing/v2/actions/myAction/compute/computeMyActionPlan.ts

    • Return AutumnBillingPlan with insertCustomerProducts, lineItems, etc.
  4. Create error handler: billing/v2/actions/myAction/errors/handleMyActionErrors.ts

  5. Register in billingActions: billing/v2/actions/index.ts

  6. Create handler (if HTTP-exposed): billing/v2/handlers/handleMyAction.ts

    • Thin wrapper calling `bill

Content truncated.

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

643969

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

591705

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

318399

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

340397

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

452339

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

304231

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.