Architecture

The system at a glance: which component lives where, who calls whom, and what each side is responsible for.

End-to-end data flow

┌────────────────────────────── Your platform ─────────────────────────────┐ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ POS terminal │───▶│ Transaction │───▶│ Webhook emitter │ │ │ │ / cashier │ │ service │ │ (signs + sends) │ │ │ └──────────────┘ └──────────────┘ └────────┬─────────┘ │ │ ▲ │ │ │ │ │ HTTPS POST │ │ ┌──────────────┐ │ X-Provider-Signature │ │ │ OAuth server │◀──── Pattern A only │ │ │ │ Order API │ │ │ │ └──────┬───────┘ │ │ │ │ │ │ └─────────┼─────────────────────────────────────────┼──────────────────────┘ │ │ │ GET /orders/{id} │ POST /webhooks/{provider} │ Authorization: Bearer ... │ │ ▼ ┌─────────┼─────────────────────────────── Paperless ─────────────────────┐ │ │ ┌──────────────────┐ │ │ │ │ Webhook ingest │ │ │ │ │ (verify, store, │ │ │ │ │ enqueue) │ │ │ │ └────────┬─────────┘ │ │ │ │ │ │ │ ▼ │ │ │ ┌──────────────────┐ │ │ └─────────────────────────────▶│ Worker (Celery) │ │ │ │ - fetch order │ │ │ │ - resolve cust. │ │ │ │ - write receipt │ │ │ └────────┬─────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ PostgreSQL │ │ │ │ - receipts │ │ │ │ - customers │ │ │ │ - integrations │ │ │ └────────┬─────────┘ │ │ │ │ └─────────────────────────────────────────────────┼───────────────────────┘ │ ▼ Customer mobile / web apps

What each side owns

ComponentYour platformPaperless
OAuth 2.0 server You host /oauth/authorize and /oauth/token (Pattern A only). Initiates the authorization-code flow. Stores encrypted tokens.
Merchant directory You issue and own the canonical merchant ID. Maps your merchant ID to a Paperless merchant record.
Location sync You expose GET /locations (Pattern A only). Pulls locations on connect and on demand.
Order / receipt data You own the source of truth and expose it via webhook + fetch (A) or push (B). Snapshots the order into an immutable Receipt row.
Customer identifier You stamp paperless_customer_id onto the order, or expose email/phone lookup. Resolves the identifier against its own customer DB.
Webhook signing key You store the signing secret in a vault and sign every webhook. Stores the same secret, verifies every webhook.
Idempotency You must supply a stable, globally-unique external_id per order. Enforces uniqueness; duplicate deliveries are deduped silently.
Retry on delivery failure You must retry non-2xx responses with exponential backoff. Returns 5xx briefly during overload; safe to retry.

Glossary

TermMeaning
merchantA business that uses your POS. One merchant may have many locations.
locationA physical or logical store. One location belongs to exactly one merchant.
order / transactionA single completed sale. The unit of work Paperless ingests.
receiptPaperless's immutable snapshot of an order, attached to a customer.
external_idYour stable, globally-unique identifier for an order. Idempotency key.
external_event_idYour stable, globally-unique identifier for a webhook delivery (not the order).
paperless_customer_idA UUID issued by Paperless that identifies a customer. Stamped on orders.
tenderA payment instrument applied to an order (card, cash, gift card, etc.).
line itemOne product or service row on an order.
taxA tax row on an order. ADDITIVE taxes are added on top; INCLUSIVE taxes are already in the line price.
KMSKey Management Service. Paperless encrypts every OAuth token at rest before storing it.
DLQDead-letter queue. Where webhook deliveries land after they exhaust their retry budget.

Identifiers and their lifetimes

IDIssued byStable?Used as
merchant_idYouForeverForeign key on every webhook and order.
location_idYouForeverWhere the sale happened.
external_id (order)YouForeverIdempotency key. If you re-deliver the same order, Paperless will silently dedupe.
external_event_idYouForeverIdempotency key for the webhook delivery itself.
access_tokenYou (OAuth server)Short-livedBearer token Paperless uses on Order API. Pattern A only.
refresh_tokenYou (OAuth server)Long-lived, rotatesUsed to mint new access tokens. Pattern A only.
paperless_customer_idPaperlessForeverUUID. Stamped on the order so the receipt finds its owner.

Constraints that apply to every integration