Skip to main content
An order is the record of a single paid transaction on Polar. Every successful checkout, subscription cycle, and subscription change generates an order — it’s where the money, the tax, the invoice, and the link back to the product and customer live. If subscriptions are the relationship with a customer, orders are the individual payments inside that relationship.

When orders are created

Polar creates an order in all of these cases:
  • One-time purchase — when a customer checks out a non-recurring product.
  • Subscription created — the initial order generated when a customer subscribes.
  • Subscription renewal — every billing cycle of an active subscription.
  • Subscription change — when a plan or seat update is prorated with invoice behavior and charges the difference immediately. See Proration.
Each order carries a billing_reason that tells you which of these it is: purchase, subscription_create, subscription_cycle, or subscription_update.

Arbitrary charges

Sometimes you need to charge a customer an amount that doesn’t originate from a checkout or a subscription renewal — a usage overage, a one-off professional-services fee, or a manual top-up. Polar lets you run these off-session charges against a customer’s saved payment method, without the customer being present.
Off-session charges are currently in preview. You’ll only be able to run off-session charges if you are on a paid plan.
An off-session charge is a two-step flow: you create a draft order, then finalize it to attempt the charge. Both endpoints require the orders:write scope and the sales-management permission on the organization.

1. Create a draft order

POST /v1/orders/ creates an order in draft status with no invoice number — nothing is charged yet. You reference an existing customer and a one-time product, and optionally override the amount and description:
FieldRequiredDescription
customer_idYesThe customer to charge. Must belong to the organization.
product_idYesA one-time product to charge for. Only fixed-price and free products are supported.
amountNoA custom amount in the smallest currency unit (e.g. 2500 for $25.00). Overrides the product’s price; defaults to it.
currencyNoISO 4217, lowercase (e.g. usd). Defaults to the organization’s currency.
descriptionNoThe line-item text shown on the invoice and receipt. Defaults to the product name.
organization_idNoRequired unless you authenticate with an organization token.
The customer must have a complete billing address (so Polar can calculate tax) and at least one saved payment method.
cURL
curl --request POST \
  --url https://api.polar.sh/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"
  }'
The response is the draft order, including its id. Creating a draft fires the order.created webhook but does not yet email the customer.

2. Finalize and charge

POST /v1/orders/{id}/finalize synchronously attempts the off-session charge. By default it uses the customer’s default payment method; pass payment_method_id to charge a specific one.
cURL
curl --request POST \
  --url https://api.polar.sh/v1/orders/<order_id>/finalize \
  --header 'Authorization: Bearer <YOUR_BEARER_TOKEN_HERE>' \
  --header 'Content-Type: application/json' \
  --data '{}'
On success, the order transitions to paid, an invoice number is assigned, any benefits attached to the product are granted, the customer is emailed their confirmation, and the order.paid webhook fires. If the charge fails, the API returns an error and the order is reverted to draft so you can fix the problem and finalize the same order again — no invoice number is consumed by a failed attempt:
StatusWhen
402The card was declined, the customer has no payment method, or the charge needs a 3DS / SCA challenge that can’t be completed off-session.
403Off-session charges aren’t enabled for the organization, or its account can’t currently accept payments.
412The order is no longer in draft status (for example, it was already finalized).

Order status

An order moves through a small set of statuses over its lifetime:
StatusMeaning
pendingThe order has been created and Polar is attempting to collect payment.
paidThe payment succeeded.
refundedThe order has been fully refunded.
partially_refundedPart of the order has been refunded. See Refunds.
voidThe order will not be collected (for example, it’s been voided after repeated failures).
Free orders — those with a total of zero, typically from a $0 subscription or a 100% discount — are marked paid immediately with no payment step.

What’s on an order

Every order carries:
  • Amounts: subtotal, discount, tax, net, and total, with the currency it was billed in.
  • Billing details: customer billing name and address (editable until the invoice is generated).
  • Tax details: taxability reason, tax rate, and the amount collected — useful if you’re operating as merchant of record on your own, or reconciling against Polar’s MoR tax handling.
  • A link to the product and customer, and to the subscription if the order came from a subscription.
  • The invoice, once it’s been generated.
  • Custom field data captured at checkout.

Invoices

Polar generates a PDF invoice for every paid order. You can: Customers can download and edit their own invoices — adding a company name, VAT number, or billing address — from the Customer Portal, without pulling you into a support thread.
Once an invoice has been generated, its billing details are frozen. If you need to correct a name or address after the fact, the customer should edit their invoice from the Customer Portal, which regenerates it.

Receipts

A receipt is the proof of payment for an order — what was charged, how, and what’s been refunded since. Polar issues one for every paid order and assigns a per-customer number in the form RCPT-{customer-id}-{NNNN}. Each receipt includes:
  • The payment method used (e.g. Visa — 4242), the date paid, and the amount.
  • Any customer balance applied to the order.
  • Any refunds issued against the order, with dates and amounts.
  • The same line items, taxes, totals, and linked invoice number as the order’s invoice.
Customers download receipts from the Customer Portal — a Download Receipt button appears on each paid order. Programmatically, use Get Order Receipt for the merchant API or its customer-portal counterpart. The first request for a given order may return 202 Accepted while the PDF renders. Retry shortly after for a presigned download URL. The Customer Portal handles this for you.

Refunds

Orders can be refunded in full or in part from the dashboard, or programmatically via the Refunds API. Refunds are a separate resource linked to the order — see Refunds for the rules around what’s refundable and how it interacts with payouts.

Webhooks

If you’re integrating orders into your own system, Polar emits an event on every state transition:
  • order.created — a new order exists (not necessarily paid yet).
  • order.paid — the order has been collected. This is the one most integrations care about.
  • order.updated — something changed on the order.
  • order.refunded — a refund was issued against the order.

Next steps

Subscriptions

The recurring relationship that generates most orders.

Refunds

How to refund an order, fully or partially.

Orders API

List and fetch orders, update billing details, and generate invoices.

Customer Portal

Where customers view their own orders and download invoices and receipts.