Integration models
Two patterns. Pick one before you start building. You can migrate from B to A later, but not the other way around without churn.
Side-by-side comparison
| Dimension | Pattern A — Full integration | Pattern B — Push mode |
|---|---|---|
| Shape | Bidirectional: you emit signed webhooks; Paperless calls back to fetch full orders. | One-way: you POST a complete signed receipt to Paperless. No callbacks. |
| Merchant connect | OAuth 2.0 authorization-code flow. Merchant clicks "Connect" in Paperless and is redirected to your platform to consent. | Out of band. Paperless ops provisions the merchant manually using credentials you supply. |
| What you host | /oauth/authorize, /oauth/token, /oauth/revoke, /locations, /orders/{id}, /customers/{id}. |
Webhook emitter only. Optional /customers/{id} if you want email/phone fallback matching. |
| What Paperless hosts | POST /webhooks/{provider} + OAuth callback URL. |
POST /ingest/{provider}/receipts. |
| Token management | You mint access + refresh tokens. Paperless refreshes daily. | None. A static, rotatable API key authenticates your push requests. |
| Latency from sale to receipt | ~1–3 s (webhook + order fetch + processing). | ~300 ms–1 s (single POST + processing). |
| Payload size per sale | Webhook is small (~1 KB); fetch retrieves the rest. | Single POST carries the full receipt (~2–10 KB). |
| Retry semantics | Webhook retried by you (3×, exp. backoff). Order fetch retried by Paperless. | You retry the POST (3×, exp. backoff). No second leg. |
| Customer matching | Full chain: barcode → mapping → email/phone fallback → unmatched. | Barcode → email/phone in payload → unmatched. No mapping cache unless you implement /customers/{id}. |
| Multi-location support | Native: locations are first-class via GET /locations. |
You include location_id + address inline on every receipt. |
| Schema changes | You can extend the order shape freely; Paperless picks up new fields on next fetch. | Schema is locked by this spec; new fields require a coordinated release. |
| Effort to implement | ~3–6 engineer-weeks (OAuth server is the long pole). | ~1–2 engineer-weeks. |
| Status | Production | Available (target endpoint exists on Paperless side) |
How to choose
- You already run an OAuth 2.0 server (or have one trivially available).
- Your order data is rich: line items, taxes, multiple tenders, custom attributes.
- Merchants have multiple locations you want kept in sync.
- You want the platform to scale to other partners besides Paperless without re-engineering.
- You prefer to keep the source of truth on your side and have Paperless pull on demand.
- Standing up an OAuth server is a heavy lift for your team.
- You can produce a complete receipt synchronously at checkout (you do not need a callback to enrich it).
- Your merchants are mostly single-location.
- You want the smallest possible time-to-launch.
- You are okay with the locked schema and accept that future enrichment fields may need coordinated releases.
Recommendation
For most banks and large POS platforms, Pattern A is the right call. It matches the production integrations we already run with Square, Clover, and Lightspeed, isolates schema evolution to your side, and gives you a path to expose the same APIs to other partners later. Pick Pattern B only when your team explicitly cannot host an OAuth server inside the timeline you have.
Can I migrate later?
B → A: yes, but it requires a coordinated cutover. Merchants connected under Pattern B must re-consent via OAuth, and historical receipts already pushed under B remain in place untouched.
A → B: not supported. The full integration is a superset; there is no reason to walk back to push mode.