> ## Documentation Index
> Fetch the complete documentation index at: https://docs.staging.metronome.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment gate a subscription

This page describes how to require payment before granting access to a subscription or its recurring credits. Payment gating lets Metronome track the paid subscription quantity, release attached credits according to payment status, and notify your application when the entitlement state changes.

<Info>
  **Private preview**

  This page documents a private preview. Contact your Metronome representative to confirm access before using these provisional fields and endpoints. The API can change during the preview.
</Info>

Use payment gating to reduce fraud risk and ensure that you collect payment before granting customers access to your products or credits. This is especially important for AI companies, where unpaid usage can incur substantial compute costs. For example, if you sell a \$10 monthly subscription that includes 100 AI credits, payment gating lets you easily withhold credit access until the initial payment succeeds and after each corresponding renewal invoice is paid.

## How payment-gated subscriptions work

Payment-gated subscriptions introduce a `status` field that reflects subscription payment outcomes and helps your application manage entitlements. Metronome handles invoicing, payment-status tracking, and linked credit releases. Metronome also releases webhooks to enable you to grant or revoke access to your product.

1. **Metronome initiates payment.** On the scheduled invoice date, Metronome creates and finalizes the subscription invoice, sends it to Stripe Invoicing, and triggers an immediate payment attempt.
2. **Metronome updates the subscription state.** If payment succeeds, Metronome sets the subscription status to `ACTIVE`, updates the paid quantity of the subscription, sends a `subscription.payment_gate_status` webhook, and releases linked recurring credits according to their access policy. If payment fails, Metronome withholds credit release and sends a corresponding webhook.
3. **Your application updates entitlements.** Use Metronome webhooks and status reads to grant access for the paid quantity or block or suspend access after payment failure. Metronome updates the subscription's billing state; it doesn't directly enable or disable users in your application. Listen to Stripe webhooks for detailed payment failure reasons.

## Before you begin

* [Set up your subscription pricing](/guides/pricing-packaging/subscription/define-subscription-pricing).
* Configure your Stripe integration. Payment-gated subscriptions currently support only Stripe Invoicing. Ensure that each Stripe customer has a default payment method and a valid stored customer address. Without these, payment attempts fail.
* Set up your webhook listeners. Listen for Metronome subscription status webhooks to manage entitlements. Also listen to Stripe webhooks for detailed PaymentIntent actions, such as 3DS authentication, and payment failure details.

## Configure payment gating

For a hybrid pricing model that combines a subscription with recurring credits, configure two parts:

* **Subscription payment gate:** Set `payment_gate_config` on the subscription. Metronome automatically tracks payment status on the subscription invoice and updates the subscription status so your application can manage access and quantity changes. You can configure a subscription payment gate with or without recurring credits.
* **Recurring credit access policy:** Set `subscription_config.access_policy` on the linked recurring credit. Metronome manages credit releases based on subscription payment status and the policy you choose: require payment for each billing period, only the initial billing period, or neither. The linked subscription must have a payment gate configured.

### Create a payment-gated subscription

Create a payment-gated subscription in the Metronome app or through the API, either when creating a new contract or when adding a subscription to an existing contract.

Ensure that both the customer and the contract in Metronome have a valid Stripe billing provider configuration or subscription creation will fail.

Consider an AI company that offers a \$10 monthly subscription with 100 AI credits included. The company bills the subscription at the start of each month and grants that month's credits only after payment succeeds. The following API call creates a contract for a new customer with a payment-gated subscription and linked recurring credits.

```bash cURL theme={null}
curl --request POST \
  --url https://api.metronome.com/v1/contracts/create \
  --header "Authorization: Bearer $METRONOME_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "customer_id": "4c09936b-455d-4c72-a120-d71b600a7546",
    "rate_card_id": "740a2ca1-64f6-417d-807a-05f154b3b1fe",
    "starting_at": "2026-10-01T00:00:00Z",
    "billing_provider_configuration": {
      "billing_provider_configuration_id": "e045c62b-65e7-4e84-a924-3f06f8b621d0"
    },
    "subscriptions": [
      {
        "temporary_id": "ai_starter_monthly",
        "name": "AI Starter",
        "collection_schedule": "advance",
        "initial_quantity": 1,
        "subscription_rate": {
          "billing_frequency": "monthly",
          "product_id": "ed518bcb-acc1-4cd8-85dd-880c2eb38994"
        },
        "proration": {
          "invoice_behavior": "bill_immediately",
          "is_prorated": true
        },
        "payment_gate_config": {
          "payment_gate_type": "STRIPE",
          "tax_type": "STRIPE"
        }
      }
    ],
    "recurring_credits": [
      {
        "access_amount": {
          "credit_type_id": "d3cb2827-dcb5-44af-9354-947a7197b9a6",
          "unit_price": 100
        },
        "subscription_config": {
          "subscription_id": "ai_starter_monthly",
          "access_policy": "BILLING_PERIOD_PAID"
        }
      }
    ]
  }'
```

Metronome creates and finalizes the subscription invoice and sends it to Stripe for a payment attempt. Metronome updates the subscription status when the payment succeeds or fails. While payment is pending or in flight, the subscription status remains unchanged. Use the [`getSubscriptionStatus` API](#read-subscription-state-through-the-api) to inspect pending updates in `open_invoices`. Don't grant access based on invoice creation or an in-progress payment. See [Manage entitlements](#manage-entitlements) for more detail.

## Choose when to release recurring credits

As shown in the API call above, attach a recurring credit or commit through `subscription_config.subscription_id`. When you create the subscription and credit in the same request, use the subscription's `temporary_id`.

Set `subscription_config.access_policy` to control whether payment gates the credit release. This field is required when the recurring credit or commit is linked to a payment-gated subscription.

| Access policy | Definition | Use when |
| - | - | - |
| `BILLING_PERIOD_PAID` | Metronome releases each period's credits after payment for that period succeeds. The initial payment and every renewal gate their corresponding credits. | Use if you are a company with high fraud risk and need to ensure payment each billing period regardless of customer history. |
| `INITIAL_BILLING_PERIOD_PAID_ONLY` | Metronome releases credits after the initial subscription payment succeeds. Later releases don't wait for renewal payment. | Use when the highest risk vector is on initial sign-up or when you want to to avoid disruptive product experiences upon payment failure for customers with an existing payment history. |

<Info>
  **First-of-month processing**

  A recurring credit gated on billing-period payment can take several hours to release when many subscriptions renew on the first day of the month. Gate only on initial billing period if you want to customers to have access to credits immediately when the new billing period begins.
</Info>

## Change subscription quantity

Suppose the AI company above adds a team plan where each seat costs \$10 per month and includes 100 AI credits. A customer with one paid seat requests a second seat halfway through the month. Use the [edit contract API](/api-reference/contracts/edit-a-contract) to increase the subscription quantity by one, as shown below. See [Manage seats](/guides/pricing-packaging/subscription/manage-seats) for more information about quantity changes and linked credit behavior.

Metronome creates an invoice for the additional seat and triggers payment in Stripe. With the example's proration settings, the charge is prorated for the remaining billing period. While payment is pending, `paid_quantity` remains `1`; don't grant access to the additional seat yet.

```bash cURL theme={null}
curl --request POST \
  --url https://api.metronome.com/v2/contracts/edit \
  --header "Authorization: Bearer $METRONOME_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "customer_id": "4c09936b-455d-4c72-a120-d71b600a7546",
    "contract_id": "7f865c1b-1c08-40e8-9c09-b3238fd3b50d",
    "update_subscriptions": [
      {
        "subscription_id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
        "quantity_updates": [
          {
            "quantity_delta": 1,
            "starting_at": "2026-10-15T12:00:00Z"
          }
        ]
      }
    ]
  }'
```

If payment succeeds, Metronome automatically updates the subscription quantity and releases additional linked credits. Metronome sends a webhook that your application can use to grant access to the second seat.

If payment fails, Metronome automatically voids the quantity-change invoices in both Stripe and Metronome and doesn't apply the seat increase. The original paid seat remains available. After the customer resolves the payment issue, retry by requesting the additional seat again; Metronome creates a new invoice and payment attempt.

<Info>
  **One pending quantity change at a time**

  Only one quantity change can be pending for a subscription at a time. While it is pending, no further changes are allowed except removing the pending change or ending the subscription. If a pending quantity change is not paid within one hour, Metronome automatically rolls back the quantity change and voids the corresponding invoices.
</Info>

## Manage entitlements

Use subscription status and paid quantity to determine product access, and use webhooks to keep your application's entitlements up to date.

### Subscription statuses

| Status | Definition | Entitlement behavior |
| - | - | - |
| `NOT_STARTED` | The subscription hasn't reached its start date or its initial payment hasn't completed. | Don't grant access. |
| `INCOMPLETE` | The initial subscription payment failed. No new invoices will be generated and subscription quantity cannot be changed. | Don't grant access, potentially kick-off additional fraud prevention flows. |
| `ACTIVE` | The latest subscription-cycle payment succeeded. Pending quantity increases don't change the paid quantity until payment succeeds. | Grant access for `paid_quantity`. |
| `UNPAID` | A recurring subscription payment failed. If subscription is not ended, renewal invoices will continue to be generated, but subscription quantity cannot be changed. | Revoke or suspend access according to your product policy. If the latest renewal invoice is paid, access can be regranted for the current billing period. |
| `ENDED` | The subscription has ended. This status is terminal. | Revoke access. Create a new subscription or contract if the customer restarts. |

### Handle subscription webhooks

Use Metronome webhooks to understand when payment is updated and manage product access. Metronome sends `subscription.payment_gate_status` whenever the paid quantity, subscription status, or external invoice is updated, except for the transition to `ENDED`. This includes successful renewals and quantity changes even when the subscription remains `ACTIVE`. Enable lifecycle events separately to handle subscription endings.

Treat Metronome as the source of truth for entitlement state and Stripe as the source of truth for payment actions.

1. Listen for `subscription.payment_gate_status` and enabled lifecycle events.
2. Read the updated `status` and `paid_quantity` to determine the customer's entitlement.
3. Grant or update access for the paid quantity when the subscription is `ACTIVE`.
4. Block or suspend access after an unsuccessful initial or renewal payment, according to your product policy. Remove access when the subscription ends.
5. Make webhook handlers idempotent and use webhook delivery retries to recover from failed processing.

The following example shows a successful payment for an initial sign-up of one subscription seat.

```json theme={null}
{
  "id": "dba7c77a-4ccb-4280-a45b-8d43fc6ae3d0",
  "type": "subscription.payment_gate_status",
  "properties": {
    "customer_id": "4c09936b-455d-4c72-a120-d71b600a7546",
    "contract_id": "7f865c1b-1c08-40e8-9c09-b3238fd3b50d",
    "subscription_id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
    "status": "ACTIVE",
    "paid_quantity": 1,
    "invoice_id": "0f159078-7915-4b3c-97ea-9a6bb7a8d638",
    "changes": [
      "status",
      "paid_quantity",
      "invoice_id",
      "external_invoice.invoice_id",
      "external_invoice.external_status",
      "external_invoice.payment_intent_id"
    ],
    "external_invoice": {
      "invoice_id": "in_123",
      "payment_intent_id": "pi_123",
      "external_status": "PAID"
    }
  }
}
```

Use `changes` to understand why an event arrived, but use the updated `status` and `paid_quantity` to set entitlements. Note that a successful renewal can update the invoice fields without changing the subscription's status or paid quantity.

<Warning>
  **Enable lifecycle events**

  [Lifecycle events](https://docs.metronome.com/guides/customers-billing/set-up-notifications/system-notifications) aren't enabled automatically. Enable them for your webhook destination. An `ENDED` subscription doesn't produce a `subscription.payment_gate_status` event. Use lifecycle events to remove access at the subscription end date.
</Warning>

### Read subscription state through the API

Use the `getSubscriptionStatus` API to programmatically view subscription state, reconcile entitlements, or check whether a payment is still pending. Pending or in-flight payments don't update subscription status; inspect `open_invoices` for payable invoices and pending quantity changes. Don't grant access based on an entry in `open_invoices`.

The response includes the following fields:

* `status` represents the subscription's current payment-backed lifecycle state.
* `paid_quantity` is the quantity your application can entitle. During a pending quantity increase, it remains at the last successfully paid quantity.
* `latest_cycle_invoice` describes the latest subscription-cycle invoice with a conclusive payment outcome, whether successful or unsuccessful. It doesn't represent a mid-period quantity-change invoice.
* `open_invoices` lists payable subscription-cycle and quantity-change invoices that haven't reached a terminal state. Use this field for diagnostics, not to grant access.

```bash cURL theme={null}
curl --request POST \
  --url https://api.metronome.com/v1/subscriptions/getStatus \
  --header "Authorization: Bearer $METRONOME_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "customer_id": "4c09936b-455d-4c72-a120-d71b600a7546",
    "contract_id": "7f865c1b-1c08-40e8-9c09-b3238fd3b50d",
    "subscription_id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2"
  }'
```

For example, a customer has paid for one seat and requests a second seat. While payment for the additional seat is pending, the response shows the original paid quantity and an open quantity-change invoice:

```json theme={null}
{
  "status": "ACTIVE",
  "paid_quantity": 1,
  "latest_cycle_invoice": {
    "id": "0f159078-7915-4b3c-97ea-9a6bb7a8d638",
    "starting_at": "2026-10-01T00:00:00Z",
    "ending_before": "2026-11-01T00:00:00Z",
    "quantity": 1,
    "external_invoice": {
      "invoice_id": "in_123",
      "external_status": "PAID"
    }
  },
  "open_invoices": [
    {
      "id": "7f7c8958-83c6-4efa-91fd-593a50c9e196",
      "starting_at": "2026-10-15T12:00:00Z",
      "ending_before": "2026-11-01T00:00:00Z",
      "quantity": 1,
      "reason": "subscription_quantity_update",
      "external_invoice": {
        "invoice_id": "in_seat_upgrade_123",
        "external_status": "OPEN"
      }
    }
  ]
}
```

In the preceding response, a subscription quantity-update invoice is still in flight. Metronome has sent it to Stripe, but payment hasn't succeeded, so the Stripe invoice status remains `OPEN`.

## Handle payment failures

Listen to Stripe invoice and PaymentIntent webhooks to handle detailed payment failures and customer actions such as 3DS authentication. For example, `invoice.payment_action_required` indicates that the customer must complete an authentication action. Use Metronome subscription webhooks to manage product access and Stripe webhooks to guide the customer through resolving the payment issue.

### Recover initial and renewal payments

Initial and renewal invoices have a 13-day payment window to accommodate payment methods such as ACH and give you time to handle payment recovery. This window isn't an entitlement grace period: a failed payment still updates subscription status so your application can block or suspend access. Unlike failed quantity-change invoices, initial and renewal invoices remain payable during this window.

For example, if a renewal payment fails:

1. Metronome sends a `subscription.payment_gate_status` webhook with status `UNPAID`. Your application suspends access according to your product policy.
2. Stripe sends a payment-failure notification. Your application prompts the customer to update their payment method or complete a required authentication action.
3. The customer resolves the issue and the invoice is paid within the payment window.
4. Metronome updates the subscription to `ACTIVE`, sends a webhook, and releases credits as applicable. Your application restores access for `paid_quantity`.

If an initial payment fails, the same recovery flow applies with status `INCOMPLETE` instead of `UNPAID`.

### Invoice expiration

If payment doesn't succeed within 13 days, Metronome automatically voids the Stripe invoice, which also voids the corresponding Metronome invoice. All open invoices expire at the end of their billing period, even if the 13-day window hasn't elapsed. The effective deadline is the earlier of the 13-day payment deadline and the billing-period end.

Your Stripe payment recovery settings, including Smart Retries, continue to apply automatically while the invoice remains open. Use Stripe webhooks to handle payment recovery actions. Failed quantity-change invoices don't use this recovery window: retry those by requesting the seat increase again.

## Private preview limits

The following configuration limits apply during the private preview:

* Quantity-based subscriptions only. Seat-based subscriptions that track individual seat IDs aren't supported yet.
* Payment gated subscriptions must be billed in-advance (`collection_schedule: "advance"`) and quantity updates billed immediately  (`proration.invoice_behavior: "bill_immediately"`).
* Stripe Tax and Stripe Invoicing are the only supported downstream tax and invoicing systems.
* Invoice placement must be set on the scheduled invoice and cannot be combined with usage invoices.
