Skip to main content
Billing methods run on your server with a secret key. Derive the Nozle customer from the authenticated application user or workspace.

List plans

The Plan type declares code, name, amount_cents, amount_currency, and interval. At runtime each item is the full plan object from the API, including charges, entitlements, taxes and credit_grant_rules, and the list includes trial, pay-in-arrears and pending-deletion plans. See the public plan catalog. With a pk_ key, all of it is readable by anyone who has the key.

Create checkout

checkout() requires an sk_ key. Handle every result discriminator explicitly: A paid upgrade returns plan_upgrade_intent_id instead of invoice_id on stripe and razorpay results. On scheduled, subscription_id is the pending subscription. The CheckoutResult type declares payment_source on completed results. pending_subscription_id was removed from the type in 0.10.0 because the API never returns it; earlier versions declared it. Use the exported CheckoutResult union instead of a reduced local type. Do not treat every non-Stripe response as a scheduled downgrade. React’s checkout components handle these result variants; see checkout components. Validate the exact HTTPS return origin on your server before passing it to Nozle.

Checkout errors

See Create checkout for the HTTP contract.
Nozle payment fulfillment is authoritative. A browser callback or redirect does not prove activation; Razorpay upgrades require capture and Stripe requires backend settlement.

Manage a payment method

Stripe only. Requires an sk_ key. A pk_ key is refused with 403 (no error code, only a message). Nozle stores no card data: the customer changes their payment method in the Stripe Billing Portal. Razorpay customers pay each invoice through a Razorpay payment link, so for them the call fails with 422 razorpay_pays_by_link. See Manage Payment Method for the HTTP contract and error codes.

Direct subscription

subscribe() requires an sk_ key and returns SubscribeResult. The customer must already exist, so call customers.upsert() first. An unknown customer returns 404 customer_not_found and nothing is created. Calling subscribe() again for the same customer and plan returns the same subscription. It accepts a paid plan without collecting payment. Use checkout for payment-gated plan changes; use direct subscription only where your configured product flow does not require an interactive payment.
subscribe() to another plan adds a second active subscription. It does not replace the first, and plan credit grants are granted again. To move a customer, call checkout() with subscriptionId (needs a transition policy), or cancel and then subscribe. Pass the new subscription ID to track(): cached clients keep the old ID.

Cancellation

The policy defaults to end_of_period and also accepts immediate.

Subscription self-service

The following subscription-management methods are available from @nozle-js/node 0.10.0. The matching hosted endpoints are available; see the Node merchant example for a complete integration.
These methods power the React billing portal. Use a customer ID derived from your authenticated application session and validate the selected external subscription ID. A Core subscription UUID is not interchangeable with that external ID.
Changing an existing subscription’s plan needs a transition policy for that source and target plan pair. Without one, preview, checkout, and transitions return 422 plan_transition_policy_required. Exception: from a $0 plan to a paid plan, the organization’s free-to-paid default applies without a pair policy.

Load eligible plans and preview a quote

options includes the current subscription, pending_change, policy-authorized eligible_plans, and an optional latest checkout summary. Plans contain code, name, amount_cents, currency, and interval; eligible plans add direction and timing. A pending change has its own internal id and effective_at. The quote includes quote_id, transition_direction, timing, currency, credit_amount_cents, debit_amount_cents, net_amount_cents, amount_due_now_cents, amount_due_at_effective_cents, effective_at, and renewal_at. The API also returns transition_policy, billing_anchor, proration_behavior, and credit_action, which the SDK type omits. Present these exact amounts and dates before confirmation. Monetary values are integer minor units and may be strings; preserve their precision. Do not choose a target solely from the public catalog or by comparing prices.

Confirm a paid upgrade

After the customer confirms, use the saved quote and a stable action key:
quoteId requires an explicit subscriptionId. A quote expires after five minutes or becomes invalid when its bound state changes. HTTP 409 requires a fresh preview and confirmation. For an uncertain response, retry the same confirmed request with the same key; an accepted request can replay after its quote expires. A $0 to $0 immediate upgrade returns completed with payment_source: "credits" and creates a $0 invoice. An upgrade checkout to a pay-in-arrears plan returns 422 plan_upgrade_invoice_missing.

Schedule or withdraw a downgrade

For a confirmed quote whose transition_direction is downgrade:
Reload options to show the pending plan separately from the active plan. To withdraw it, retain the exact pending_change.id that the customer confirmed removing:
The result is {subscription: {id, external_id, plan_code, status}, withdrawn_pending_subscription_id, replayed}. The same key returns the same body with replayed: true. The active plan is preserved. A new scheduled change while a change is pending replaces it with a new pending ID. A paid upgrade checkout is refused with 409 subscription_change_pending while a downgrade or cancellation is scheduled: withdraw the downgrade, or keep the subscription, first. Scheduling a change or cancelling at period end cancels an open upgrade checkout. Withdrawing the replaced ID returns 409 pending_subscription_changed. An unknown ID returns 404 pending_subscription_not_found.

Cancel at period end and Keep

Preview cancellation through the existing transition API:
After displaying and confirming the ending date, apply it with its exact timestamp:
Keep reuses the existing uncancel operation with a separate confirmed action key:
Keep accepts no settlement overrides and is available only before the ending is due. Cancellation clears a pending downgrade; Keep does not recreate it. Do not reformat the preview timestamp before passing expectedEffectiveAt.

Scope payment recovery and verification

razorpayVerification is the genuine browser callback containing razorpay_order_id, razorpay_payment_id, and razorpay_signature. verifyCheckout() posts these fields to the API; the SDK does not check the signature locally. Supply both scope fields when recovering a customer’s payment. Existing unscoped calls remain compatible, but do not provide the selected-customer/subscription constraint. An unknown checkout ID returns 404 checkout_session_not_found. Errors from checkoutStatus(), verifyCheckout() and checkoutInvoice() start with the method name, for example checkoutStatus failed: 404 Not Found. Before 0.10.0 they were labelled checkout failed: <status>; branch on NozleApiError status and code instead of the message. See errors. The status distinguishes awaiting_payment, processing, succeeded, failed, expired, and needs_review, with separate fulfillment_status. Reload the selected subscription before reporting activation. Reuse recoverable checkout IDs; do not start another collection for an uncertain payment. The merchant example maps SDK responses to React’s camelCase action types and persists retry context. Replace its demo login/file store with your application authentication and transactional storage for production workers. See the HTTP contract.

Entity subscriptions

Use Entity subscriptions when users, agents, projects, or workspaces under one paying customer can have different plans.
Change or cancel only that Entity:
Every method requires an sk_ key. See Entity Subscriptions for lifecycle and payment behavior.
  • billingTime accepts only calendar or anniversary.
  • Single Entity checkout also accepts free, trial, and pay-in-arrears plans. It returns completed with payment_source: "none".
  • changePlan() needs a transition policy for the plan pair and takes no billingTime. It returns scheduled or completed, plus external_entity_id and external_subscription_id.
  • cancel() on a pay-in-arrears plan without creditAction returns 422 with credit_action: not_supported_for_pay_in_arrears.
  • remove() on an Entity with billing history returns 403 entity_subscription_has_billing_history.
  • Entity subscriptions also return billing_authority and credit_import_completed_at, which the EntitySubscription type omits.

Buy several Entity plans together

checkoutMany() buys plans for several Entities with one payment. Do not loop over entitySubscriptions.checkout(): that creates separate invoices and payments.
The result contains id, type (stripe, razorpay, processing, or completed), status (pending, open, completed, failed, or expired), client_secret, invoice_id, amount_cents, currency, replayed, expires_at, and items[] with external_entity_id, external_subscription_id, plan_code, and subscription_status. Razorpay results add the Razorpay fields.
  • Send 1 to 100 unique externalEntityId values. The SDK checks this before any request.
  • idempotencyKey is required, up to 255 bytes, and sent as the Idempotency-Key header. The same key and request returns replayed: true and reuses the open session. Replaying a failed or expired batch returns checkout_not_available.
  • The checkout expires after 23 hours.
  • Every plan must require up-front payment: pay in advance with an amount above 0 and no trial, or pay-in-advance fixed charges. Otherwise the whole batch fails with 422 validation_errors and error_details.items: ["paid_plan_required"]. Other item errors are mixed_currencies and mixed_intervals.
  • An untrusted returnUrl returns 422 with return_url: invalid_or_untrusted.
  • With no payment provider connected, the call returns 422 payment_provider_required, as single checkout does.
See bulk Entity checkout.

Settlement transitions

Preview and apply merchant-configurable cancellation, downgrade, and uncancel operations:
Apply requires an idempotency key up to 255 bytes. These methods use the timing you pass even when the pair’s transition policy says otherwise; checkout always follows the policy. A downgrade on a pair whose policy direction is upgrade returns 422 target_plan_is_not_a_downgrade. See Subscriptions for settlement options and validation rules.

Customer creation

Create or update the customer before subscribing when needed:
See Customers and Entities for lifecycle methods.

Read usage

Requires @nozle-js/node 0.13.0.
Each period has from_datetime, to_datetime, currency, amount_cents, total_amount_cents and charges_usage (units and amount per charge and feature). Pass { subscriptionId } to read a specific subscription. Without a subscription ID, the customer’s one active subscription is used, and a customer with none or several gets an error. getSubscriptions(customerId) lists the customer’s active subscriptions from Core, so you can pick the external_id to pass as subscriptionId:

Invoices

Requires @nozle-js/node 0.13.0.
invoices.list returns the newest invoices first and takes these options:
Pay an open invoice with checkoutInvoice. A PDF is generated the first time it is asked for, so the download call returns no URL until it exists; ask again a few seconds later, or wait for the invoice.generated webhook.

Alerts

Requires @nozle-js/node 0.13.0.
Usage alert types are current_usage_amount, feature_current_usage_amount and feature_current_usage_units (the feature_* ones need a feature code). Wallet alert types are wallet_balance_amount, wallet_credits_balance, wallet_ongoing_balance_amount and wallet_credits_ongoing_balance. Threshold values are cents, units or credits by type, and at most one threshold is recurring. Nozle sends the alert.triggered webhook when a threshold is crossed; verify it before acting.