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

# Billing → Payment: methods, subscription, tax, outcome pricing

> Walk through the consolidated Billing → Payment page — add or replace the default payment method auto-top-up charges from, recover a past-due subscription, map Stripe Tax jurisdiction and tax ID to invoices, and read the outcome-pricing section.

# Billing → Payment: methods, subscription, tax, and outcome pricing

The **Billing → Payment** page (`/billing/payment`) consolidates every
Stripe-adjacent surface on one screen: the payment method on file, the
subscription lifecycle card, the auto-top-up rule, outcome-based billing, and
the tax-info section. Use it when you need to change *how Orbit charges you*
— which card or bank account it draws from, whether a subscription renews,
and how tax lands on invoices — rather than *what you have spent* (that is
the [Billing overview](/billing/overview) surface).

Access is role-gated: only the `owner`, `admin`, or `billing` role can open
the page. Members and viewers see nothing here; the same roles gate every
endpoint named below.

## 1. Payment method on file

The **Payment method** card shows the org's default payment method — brand,
last four, and expiry — or the empty state when nothing is saved. A warning
appears inside the row once the card is within two months of its expiry, so
you can update it before recurring charges start failing.

Add or replace the method from the dashboard:

1. Click **Add payment method** (empty state) or **Update method** (card on
   file). This opens the Stripe Customer Portal in a new tab.
2. In the portal, save a card or complete an ACH bank-add flow. Bank debits
   appear as the default method once they are approved.
3. Return to the dashboard. The card re-reads the method and shows the new
   brand and last four.

The same read is exposed for integrations via
`GET /api/v1/billing/payment-method`:

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.orbit.devotel.io/api/v1/billing/payment-method \
    -H "X-API-Key: $ORBIT_API_KEY"
  ```

  ```typescript Node.js theme={null}
  // No typed payment-method helper in the SDK — plain fetch.
  const res = await fetch(
    'https://api.orbit.devotel.io/api/v1/billing/payment-method',
    { headers: { 'X-API-Key': process.env.ORBIT_API_KEY! } },
  );
  const { data } = await res.json();
  console.log(data.brand, data.last4, data.exp_month, data.exp_year);
  ```

  ```python Python theme={null}
  import os, requests

  r = requests.get(
      "https://api.orbit.devotel.io/api/v1/billing/payment-method",
      headers={"X-API-Key": os.environ["ORBIT_API_KEY"]},
  )
  body = r.json()["data"]
  print(body.get("brand"), body.get("last4"))
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "brand": "visa",
    "last4": "4242",
    "exp_month": 12,
    "exp_year": 2028
  },
  "meta": {
    "request_id": "req_01HZY8EXAMPLE",
    "timestamp": "2026-09-08T11:21:18.901Z"
  }
}
```

An **empty `data` object** means no method is saved (or the billing provider
is briefly unavailable) — the dashboard card self-hides in that case. There
is no `PUT /billing/payment-method` endpoint: a payment method carries card
or bank credentials, so the write path always lives on Stripe's hosted
Customer Portal (`POST /api/v1/billing/portal` returns the portal URL), never
on the Orbit API. To change the method programmatically, mint a portal
session and hand the URL to the payer.

**Why it matters:** the default method is the fallback auto-top-up charges
from. When [wallet auto-top-up](/guides/billing-auto-topup) triggers, it
charges this card off-session; when the method is missing, declined, or
needs authentication, the rule self-pauses with a recorded `last_error` and
sending pauses when the wallet empties. Keep a valid method on file before
arming auto-top-up.

## 2. Subscription card

The subscription card manages the org's Stripe subscription lifecycle
`GET /api/v1/billing/subscription` (read posture, same roles) returns the
live snapshot:

```json theme={null}
{
  "data": {
    "status": "active",
    "cancel_at_period_end": false,
    "current_period_end": "2026-10-01T00:00:00.000Z"
  },
  "meta": {
    "request_id": "req_01HZY8EXAMPLE",
    "timestamp": "2026-09-08T11:21:18.901Z"
  }
}
```

The card follows the provider's state machine:

* **`active`** — renews on `current_period_end`. The card shows the renewal
  date and a destructive **Cancel subscription** button.
* **`past_due`** — a renewal charge failed. Recover it by updating the
  payment method (section 1), then retrying the charge from the Stripe
  Customer Portal; the subscription returns to `active` once the invoice is
  paid. When dunning fails three consecutive times the account's outbound
  sending pauses — restore it by getting a working card on file (see the
  [Billing overview](/billing/overview) balance flags).
* **Cancels at period end** — you confirmed a cancel; the card swaps to a
  **Reactivate** action and shows the date access ends. Everything keeps
  working until `current_period_end`; the subscription simply does not
  renew.
* **Canceled / no status** — `status` is `null` and the card self-hides.
  Pay-as-you-go-only tenants (no subscription on file) always see the
  null branch, so useless cancel controls never render.

**Cancel flow.** Clicking **Cancel subscription** opens a confirmation
dialog that echoes the exact period-end date access runs until, plus an
optional *Tell us why you're leaving* picklist. Confirming issues
`POST /api/v1/billing/subscription` with `action: "cancel"` — the provider
marks `cancel_at_period_end: true` and the reason lands in the audit log.
The dialog stays open while the request is in flight so a double-click can
never re-POST. Until the period ends you can undo it with the same endpoint
(`action: "reactivate"`) from the card's Reactivate button.

## 3. Tax info

The **Tax info** section explains how consumption tax lands on invoices and
hands you off to the Stripe Customer Portal for anything writable.

* **Jurisdiction is resolved by Stripe Tax.** Orbit derives the applicable
  rate from your billing address (country + postal code) at invoice
  finalization. There is no in-app rate selector — the calculation is the
  provider's, and the tile is read-only by design.
* **Set a tax ID before the next invoice.** Click **Manage tax info** to
  open the portal, where you update the billing address or add a business
  tax ID (VAT, GST, ABN, and the local equivalents). Changes apply to
  invoices issued after the update; they are never retroactive. EU B2B
  accounts with a verified VAT ID are reverse-charged automatically — the
  invoice shows a zero-VAT line instead of a charge.
* **What shows on invoices.** Each invoice carries the resolved tax
  jurisdiction, the applied rate, and the tax ID on file. Read them from
  [Invoices, statements, and pay-by-link](/guides/billing-invoices-statements-and-pay-by-link)
  or `GET /api/v1/billing/invoices`.

Set the tax ID **before** the next top-up or renewal: invoices finalized
before the ID exists cannot be re-issued with it.

## 4. Outcome-pricing section

The **Outcome-based billing** section is the self-serve opt-in for
per-outcome pricing. When enabled, your workspace is charged per *resolved
outcome* — a resolved ticket, a booked appointment, a verified identity —
rather than per token or per minute, on top of your existing usage. Charges
fire only when your AI agent's rubric marks a conversation resolved.

The section carries:

* **A toggle** that arms outcome metering. Turning it ON opens a
  confirmation dialog — enabling a charge model is an explicit decision —
  before the config saves. Turning it OFF persists immediately and stops
  outcome charges from the next resolution.
* **A default rate per outcome** in USD, with sub-cent precision (the
  industry benchmark is $0.005). Rates are integer micro-cents on the wire
  (100 micro-cents = $0.0001) with a \$10.00 per-outcome ceiling — the config
  is read on `GET /api/v1/billing/outcome-pricing` and written on the
  matching `PUT` (owner/admin/billing role, audit-logged).
* **Per-outcome overrides** — a mapping from outcome name (matched to the
  rubric name) to its own rate. Outcomes without an override use the
  default. Each key must be unique and 200 characters or fewer; the form
  validates before any PUT so a bad draft never reaches a 422.

Note that the outcome catalog itself is curated: the *names* you can charge
against are defined by the resolution rubric for your enrolled AI agents —
an override for a name the rubric never emits simply never matches. If your
organization is enrolled in outcome pricing through a negotiated contract,
this section reflects the agreed rates instead of a self-serve draft.

## Where next

* [Billing overview](/billing/overview) — the whole wallet, plans, invoices,
  usage, and alerts map with API samples.
* [Configure wallet auto-top-up](/guides/billing-auto-topup) — the rule that
  charges the payment method above when the balance crosses a threshold.
* [Invoices, statements, and pay-by-link](/guides/billing-invoices-statements-and-pay-by-link)
  — where the tax ID resolved above actually appears.
* [Billing API reference](/api-reference/billing) — request/response detail
  for every endpoint named here.
