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

# Read the Financial Record of a Sale

> Understand the transaction record behind purchases, renewals, invoices, and receipts

export const RubaSocials = () => {
  if (typeof document === "undefined") {
    return null;
  }
  const inject = () => {
    const footer = document.getElementById("footer");
    if (!footer || document.getElementById("ruba-socials")) {
      return false;
    }
    const isDark = document.querySelector("html.dark") || document.querySelector('html[class*="dark"]');
    const lineColor = isDark ? "#383838" : "#e8e8ed";
    const iconColor = isDark ? "#8e8e93" : "#86868b";
    const markColor = isDark ? "#ffffff" : "#08080c";
    const hoverColor = "#0071e3";
    const div = document.createElement("div");
    div.id = "ruba-socials";
    div.style.cssText = `display:flex;align-items:center;gap:20px;padding-top:20px;margin-top:20px;border-top:1px solid ${lineColor};width:100%`;
    const logo = `<a href="https://getruba.com" style="display:inline-flex;height:24px;align-items:center;gap:8px;text-decoration:none;color:${markColor};line-height:1;"><svg width="24" height="24" viewBox="0 0 120 120" aria-hidden="true" style="display:block;flex:none;"><g transform="translate(2.5 0)"><path d="M19 25h59L65.43 47H19a4 4 0 0 1-4-4V29a4 4 0 0 1 4-4Z" fill="${markColor}"/><path d="M19 73h31.57L38 95H19a4 4 0 0 1-4-4V77a4 4 0 0 1 4-4Z" fill="${markColor}"/><path d="M85 25h25L70 95H45Z" fill="#007AFF"/></g></svg><span style="display:inline-flex;height:24px;align-items:center;font-weight:600;font-size:15px;color:${markColor};letter-spacing:-0.01em;line-height:1;">Ruba</span></a>`;
    const spacer = `<div style="flex:1"></div>`;
    const ig = `<a href="https://instagram.com/getruba" target="_blank" rel="noopener" aria-label="Instagram" style="display:flex;align-items:center;color:${iconColor};transition:color 0.15s ease;" onmouseover="this.style.color='${hoverColor}'" onmouseout="this.style.color='${iconColor}'"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg></a>`;
    const li = `<a href="https://linkedin.com/company/getruba" target="_blank" rel="noopener" aria-label="LinkedIn" style="display:flex;align-items:center;color:${iconColor};transition:color 0.15s ease;" onmouseover="this.style.color='${hoverColor}'" onmouseout="this.style.color='${iconColor}'"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"/><rect x="2" y="9" width="4" height="12"/><circle cx="4" cy="4" r="2"/></svg></a>`;
    const x = `<a href="https://x.com/getruba" target="_blank" rel="noopener" aria-label="X" style="display:flex;align-items:center;color:${iconColor};transition:color 0.15s ease;" onmouseover="this.style.color='${hoverColor}'" onmouseout="this.style.color='${iconColor}'"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg></a>`;
    const github = `<a href="https://github.com/rubadot" target="_blank" rel="noopener" aria-label="GitHub" style="display:flex;align-items:center;color:${iconColor};transition:color 0.15s ease;" onmouseover="this.style.color='${hoverColor}'" onmouseout="this.style.color='${iconColor}'"><svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .7a11.5 11.5 0 0 0-3.64 22.4c.58.1.79-.25.79-.56v-2.24c-3.22.7-3.9-1.37-3.9-1.37-.53-1.34-1.29-1.7-1.29-1.7-1.05-.72.08-.71.08-.71 1.16.08 1.78 1.2 1.78 1.2 1.04 1.77 2.72 1.26 3.38.96.1-.75.4-1.26.74-1.55-2.57-.3-5.27-1.29-5.27-5.69 0-1.26.45-2.29 1.19-3.09-.12-.29-.52-1.47.11-3.05 0 0 .97-.31 3.16 1.18A10.96 10.96 0 0 1 12 6.09c.98 0 1.94.13 2.86.39 2.2-1.49 3.16-1.18 3.16-1.18.63 1.58.23 2.76.11 3.05.74.8 1.19 1.83 1.19 3.09 0 4.42-2.7 5.39-5.28 5.68.42.36.79 1.06.79 2.14v3.28c0 .31.21.67.8.56A11.5 11.5 0 0 0 12 .7Z"/></svg></a>`;
    div.innerHTML = logo + spacer + ig + li + x + github;
    footer.appendChild(div);
    return true;
  };
  if (!document.documentElement.dataset.rubaSocialsObserver) {
    document.documentElement.dataset.rubaSocialsObserver = "true";
    const observer = new MutationObserver(() => {
      if (!document.getElementById("ruba-socials")) {
        inject();
      }
    });
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }
  setTimeout(() => {
    if (!inject()) {
      const interval = setInterval(() => {
        if (inject()) {
          clearInterval(interval);
        }
      }, 500);
      setTimeout(() => clearInterval(interval), 10000);
    }
  }, 300);
  return null;
};

<link rel="stylesheet" href="/style.css" />

<RubaSocials />

An order is one financial event. A subscription describes an ongoing commercial relationship; each initial payment, renewal, or billed change inside that relationship becomes a separate order.

## Identify why it exists

The `billing_reason` places an order in its business context:

| Value                 | Source                                               |
| --------------------- | ---------------------------------------------------- |
| `purchase`            | A one-time checkout                                  |
| `subscription_create` | The first subscription payment                       |
| `subscription_cycle`  | A recurring renewal                                  |
| `subscription_update` | An immediately invoiced prorated subscription change |

Every order ties money, discount, tax, customer, product, optional subscription, custom checkout fields, and the resulting invoice together.

## Track collection state

| State                | Interpretation                                                              |
| -------------------- | --------------------------------------------------------------------------- |
| `pending`            | Collection is underway                                                      |
| `paid`               | Payment completed, including zero-total orders that require no payment step |
| `partially_refunded` | Some of the paid amount was returned                                        |
| `refunded`           | The paid amount was fully returned                                          |
| `void`               | Ruba will no longer attempt collection                                      |

## Charge a saved method without checkout

<Note>Off-session charges are a paid-plan preview feature.</Note>

Use this flow for a manual service fee, top-up, or other amount that should be charged to an existing customer's saved payment method. It requires `orders:write` and organization sales-management permission.

<Steps>
  <Step title="Create a draft">
    Send `POST /v1/orders/` with an existing customer and a one-time fixed-price or free product. The customer must have a complete billing address and at least one saved payment method.

    | Field             | Requirement                                                          |
    | ----------------- | -------------------------------------------------------------------- |
    | `customer_id`     | Required; customer must belong to the organization                   |
    | `product_id`      | Required; one-time fixed or free product                             |
    | `amount`          | Optional smallest-currency-unit override, such as `2500` for \$25.00 |
    | `currency`        | Optional lowercase ISO 4217 value; defaults to organization currency |
    | `description`     | Optional invoice and receipt line text; defaults to product name     |
    | `organization_id` | Required unless the credential is an organization token              |

    ```bash theme={"system"}
    curl --request POST \
      --url https://api.getruba.com/v1/orders/ \
      --header 'Authorization: Bearer <YOUR_BEARER_TOKEN_HERE>' \
      --header 'Content-Type: application/json' \
      --data '{
        "customer_id": "<customer_id>",
        "product_id": "<product_id>",
        "amount": 2500,
        "description": "5,000 extra tokens"
      }'
    ```

    This creates `order.created`, but assigns no invoice number and sends no customer email.
  </Step>

  <Step title="Finalize the draft">
    Send `POST /v1/orders/{id}/finalize`. Ruba uses the default saved method unless `payment_method_id` selects another.

    ```bash theme={"system"}
    curl --request POST \
      --url https://api.getruba.com/v1/orders/<order_id>/finalize \
      --header 'Authorization: Bearer <YOUR_BEARER_TOKEN_HERE>' \
      --header 'Content-Type: application/json' \
      --data '{}'
    ```
  </Step>
</Steps>

Success changes the order to `paid`, assigns the invoice number, grants product benefits, emails confirmation, and emits `order.paid`. A failed charge returns the order to `draft` without consuming an invoice number: `402` covers declines, missing methods, or an off-session 3DS/SCA requirement; `403` means the feature or account cannot accept the charge; `412` means the order is no longer a draft.

## Invoice and receipt are different

The invoice describes what was sold, including line items, billing identity, tax, and totals. Ruba creates a PDF invoice for every paid order. Generate or retrieve it with the [invoice endpoints](/api-reference/orders/post-invoice), or let the customer edit billing identity and download it from the portal. Once generated, merchant-side billing details are frozen; a customer correction regenerates it through the portal.

The receipt proves collection. It includes payment method, date, paid amount, applied customer balance, later refunds, and the linked invoice number. Receipt numbers follow `RCPT-{customer-id}-{NNNN}`. Retrieve one through the [merchant endpoint](/api-reference/orders/get-receipt) or [portal endpoint](/api-reference/customer-portal/orders/get-receipt). The first request may return `202 Accepted` while the PDF renders; retry for the presigned URL.

## React to state changes

* [`order.created`](/api-reference/webhooks/order.created) means the record exists, not that it is paid.
* [`order.paid`](/api-reference/webhooks/order.paid) is the fulfillment signal most integrations need.
* [`order.updated`](/api-reference/webhooks/order.updated) reports a later mutation.
* [`order.refunded`](/api-reference/webhooks/order.refunded) reports money returned against it.

Full and partial refunds use a separate resource linked to the order. [Review refund rules →](/features/refunds)
