OI Payments Docs
Core concepts

Application isolation

Every record is scoped to an app_id, enforced server-side from the authenticated principal.

Alongside mode, every record carries an app_id. All reads and writes are scoped to the application that authenticated the request — resolved from your credential, never from a parameter you supply. The mode (TEST or LIVE) is derived from the API credential that authenticated the request — never from the request body.

What's scoped

Every persisted record is tagged with both an application_id and a mode, and every query is filtered on that pair. This is not limited to money movement — it covers the entire catalog and billing surface added in v2:

  • Payments, invoices, refunds, and webhooks — your money-movement records and their delivery attempts.
  • Products and prices — the catalog you sell from.
  • Benefits and coupons — the entitlements products grant and the discounts you offer.
  • Subscriptions and one-time purchases — the recurring and single-charge agreements customers hold with your app.
  • Derived entitlementsGET /entitlements/check resolves access purely from your app's purchases and subscriptions, so another app's grants can never leak in.

In short: products, prices, benefits, coupons, subscriptions, one-time purchases, and derived entitlements are all app_id + mode scoped, exactly like payments, invoices, refunds, and webhooks.

What this means for you

  • You only ever see your own app's records — across every resource listed above.
  • There is no caller-supplied "act as app X" override on the app API. Scope is derived from the principal.
  • Resource ids are only meaningful within your app; a GET /payments/{id} (or GET /products/{id}, GET /subscriptions/{id}, …) for an id that belongs to another app returns RESOURCE_NOT_FOUND, not the record.
  • Test and live data are fully isolated: a TEST credential never sees LIVE rows and vice versa, even within the same app.

Admin scope is different

Operators in the dashboard may have cross-app visibility, but even there access is governed by RBAC: a permission can be granted globally or scoped to specific apps. Cross-app search endpoints still narrow results to the apps the operator's grants cover.

Customer references are yours

customerReference (on payments and invoices) is your identifier for the customer. The service stores and echoes it but never interprets it, so use whatever key your system already has. It is the field you filter on with GET /payments?customerReference=….

On this page