Building apps

An app adds a section to a merchant’s Paysio dashboard. It appears in their sidebar under Apps, opens inside the dashboard like any other page, and works on the merchant’s own data with the permissions they granted it. You build it as a normal web app on your own stack and host it yourself; Paysio frames it, signs the merchant in, styles it, and gives it a scoped credential for the API.

The idea: extensions, not integrations

Most platforms offer “integrations”: a separate product with its own login, its own look and a settings page that links out. Paysio apps are built on a stricter premise. An app is an extension of the dashboard. A merchant who opens one should not be able to tell where Paysio ends and the app begins — not from the header, not from a button, not from a popup, not from a loading state.

Everything in the platform follows from that premise:

  • The dashboard is the chrome. The header bar above your app, its crumbs and actions, the popups your app opens, the toasts it shows — all drawn by the dashboard with its own components, from a description your app sends. They cannot look anything but native.
  • Folio is the design library. The dashboard’s own components and rules, packaged for apps. The React starter ships them as source; a plain-HTML app links one stylesheet. Either way your controls are the dashboard’s controls.
  • The merchant is already signed in. There is no login screen inside an app, no landing page, no onboarding carousel. The first screen is the work.
  • Sandbox is part of the app. The merchant’s sandbox toggle switches your app too, and the platform makes it physically impossible for a test session to touch live data.
  • Permissions are the contract. You declare scopes, the merchant approves them, we enforce them on every call. Widening them is the one thing a human always reviews.

What this means for you

Build the screens a merchant needs and nothing around them. No header of your own, no login, no branding frame. If you find yourself drawing chrome, the platform probably already draws it for you — check the App Bridge section.

What you can build

An app can read and write anything the merchant grants it through /v1, receive webhooks for the events it cares about, store per-install settings with us, and put content in front of the merchant’s customers on the confirmation page, the customer portal and the receipt email. Some shapes that fit well:

  • Fulfilment and delivery — licence keys, downloads, bookings, shipping labels, delivered the moment a payment succeeds.
  • Operations — inventory sync, accounting export, reconciliation, tax reporting.
  • Growth — loyalty, referrals, reviews, abandoned-cart recovery, campaigns.
  • Risk — fraud scoring, dispute evidence assembly, chargeback alerts.
  • Connectors — a two-way bridge to a CRM, a helpdesk, a warehouse, a spreadsheet.

How it works

1

The merchant installs your app

From the store, they read your listing and approve the scopes you declared. That creates an install: the relationship between your app and their workspace, carrying exactly the permissions they granted.

2

They open it

The dashboard frames your URL in an iframe and passes it a signed identity: a 60-second ID token naming the workspace, the member and the mode, plus an HMAC over the whole parameter set.

3

Your page talks to the dashboard

Through the App Bridge, a small postMessage API: read the context, get fresh tokens, declare the header bar, open popups, follow the theme and the sandbox toggle.

4

Your server talks to the API

It verifies the ID token, exchanges it for a pat_ access token bound to that install and mode, and calls /v1 with it. Every call is checked against the granted scopes.

5

The platform keeps you in the loop

Webhooks tell you about payments, disputes, payouts and subscriptions in the workspaces that installed you, and about the install itself: app/uninstalled and app/scopes_update.

Quick start

Shell
npm install -g paysio
paysio login

paysio apps init my-app     # creates the app + writes the React starter (Folio + the bridge, typed)
cd my-app && bun install
paysio apps dev             # runs it behind an https tunnel, inside YOUR dashboard

apps init creates the app record, prints your client secret once, and writes the starter: a blank welcome page, a /components reference with every Folio component live, popup and header-bar examples, and the bridge typed. apps dev runs the app behind a tunnel registered to your user only — no merchant ever sees your laptop — and prints the dashboard link to open.

Not on React? paysio apps init my-app --template static writes one HTML file that proves the handshake, and apps dev serves it from public/.

The anatomy of an app

Two things define an app: a URL and a paysio.app.json. The file is the source of truth for everything reviewable; apps deploy and apps submit read it.

paysio.app.json
JSON
{
  "handle": "digital-deliveries",            // stable, lowercase, hyphenated; your URL slug in the store
  "name": "Digital Deliveries",              // 30 characters or fewer
  "client_id": "app_496a2bc87bbe7d31...",   // written by apps init; the secret is never stored here
  "application_url": "https://app.example.com",   // https; set by apps deploy --url
  "embedded": true,
  "scopes": ["transactions:read", "products:read", "inventory:write", "fulfillments:write"],
  "optional_scopes": ["emails:send"],        // declinable at install; ask later with requestScope()
  "webhooks": {
    "url": "https://app.example.com/hooks",
    "topics": ["payment.completed", "payment.refunded"]
  }
}
handlestringrequired
The permanent identifier. Choose it once; it is in every URL.
namestringrequired
Shown in the store, the sidebar and the header crumb. 30 characters or fewer, no “for Paysio” suffix.
client_idstring
Your app’s public identifier, the aud of every ID token. The matching client_secret is shown once at creation and again only by apps rotate-secret.
application_urlstring
The https page we frame. Reviewed: merchants keep loading the approved origin until a new one is approved.
scopesstring[]required
What the app needs to function. Approved at install. See Permissions.
optional_scopesstring[]
A subset of scopes the merchant may decline. Requested later with paysio.requestScope().
webhooks.urlstring
Where we deliver events. One endpoint per installing workspace is provisioned for you. See Storage & webhooks.
webhooks.topicsstring[]
Business topics to receive. Each costs the matching read scope. app/uninstalled and app/scopes_update are always on.

The listing — tagline, description, features, icon, screenshots, support email, privacy policy — is edited on your app’s page under Apps › Develop in the dashboard, and is part of what review looks at.

The lifecycle

StageCommandWhat happens
Createapps initApp record + client credentials + starter files. Status draft.
Developapps devYour local app, behind a tunnel, in your dashboard only. While the tunnel is registered, your dashboard’s bottom bar shows a Dev URL / Live URL switch beside Sandbox / Live, so you can check the deployed app without stopping the tunnel.
Deployapps deploy --urlSets the production URL. Not yet visible to merchants.
Checkapps checkThe reviewer’s checklist, run locally. Non-zero exit on failure, for CI.
Submitapps submit --changelogA version snapshots your configuration and queues for review.
ReviewA person checks the listing, the scopes and the origin, and exercises the app in sandbox.
PublishedIn the store. Code behind your URL ships freely from here on.
Updateapps submitOnly scope additions, origin changes and listing edits wait for approval. A scope addition is inert until approved.

Where to go next

  • Authentication — the embed parameters, every ID token claim, verification, and the token exchange.
  • App Bridge — every method your page can call, and every message the dashboard sends.
  • Folio design library — the components, the design language, and where your app lives.
  • Permissions — the full scope vocabulary, tiers, enforcement, and changing what you need.
  • Storage & webhooks — per-install settings storage, and every event you can receive.
  • Customer blocks — putting your output in front of the buyer, not just the merchant.
  • Review & publishing — the checklist, the guidelines, what re-review gates, and suspension.