External Shop POS bridge
If your campground shop runs on its own till — Lightspeed, Zettle, a custom Python script, anything — this bridge lets the till post each transaction to CampOne so the day’s totals (and the SAP daily journal, and the reports) capture all revenue, not just the front desk.
Unlike the other integrations, this one is inbound: the external POS calls CampOne, not the other way around. You don’t have a vendor account to configure here — instead, you mint a CampOne API key with the right scopes and paste it into the external system.
What it gives you
Section titled “What it gives you”- A public API at
/api/v1/public/pos/transactions/that accepts external transactions - Idempotent on
external_ref— retrying after a network blip never creates duplicates - Standard CampOne API key auth, with two new scopes:
pos:readandpos:write - A read-back endpoint for end-of-day reconciliation
- A products endpoint so the external POS can sync the catalogue
- Inbound activity log on the settings card
Prerequisites
Section titled “Prerequisites”None on the vendor side — you don’t need a Lightspeed contract or a Zettle account to enable the integration. You configure CampOne, then point your external system at it.
What you do need:
- An external POS system that can make HTTP requests with a Bearer token
- Knowledge of how to enter API URLs / tokens in that system
How to set it up
Section titled “How to set it up”Settings → Integrations → API Keys (the existing API-key surface, alongside the Vendor Adapters tab):
- Click Create new key.
- Give it a name (e.g.
Lightspeed shop till). - Tick
pos:readandpos:writescopes. - Click Generate. CampOne shows the raw token once — copy it now and save it in the external system.
- The token is hashed at rest; if you lose it, revoke and mint a new one.
Then, in your external POS, configure:
- API URL:
https://your-tenant.campone.ch/api/v1/public/pos/transactions/ - Auth:
Authorization: Bearer <the-token-you-just-copied>
What the external POS sends
Section titled “What the external POS sends”POST /api/v1/public/pos/transactions/Authorization: Bearer ck_…Content-Type: application/json
{ "external_ref": "lightspeed-2026-04-29-T-1234", "payment_method": "CASH", "total_amount": "12.50", "items": [ { "description": "Croissant", "quantity": 2, "unit_price": "3.50", "line_total": "7.00" }, { "description": "Coffee", "quantity": 1, "unit_price": "5.50", "line_total": "5.50" } ], "occurred_at": "2026-04-29T08:14:32Z"}The external_ref is your idempotency key — it must be unique per transaction in your system. CampOne enforces uniqueness per tenant, so retrying the same transaction returns a 200 with the existing record (instead of a 409 or a duplicate).
Reconciliation
Section titled “Reconciliation”End-of-day, the external system can GET /api/v1/public/pos/transactions/<external_ref>/ to confirm CampOne has the transaction. Or GET /api/v1/public/pos/products/ to refresh its catalogue.
Inside CampOne, transactions from external sources show in /kasse/transaktionen like any other POS transaction, with Source: External POS so you can filter.
Security
Section titled “Security”- API keys are hashed at rest with Django’s password hasher (Argon2 / bcrypt).
- Every API call is logged: method, path, status code, latency, key prefix.
- Keys can be revoked instantly. Revoked keys return 401 from the next call onwards.
- Scopes are enforced per endpoint — a
pos:read-only key can’t post transactions, even if you ask it to.
Limitations
Section titled “Limitations”- Live integrations against specific external POS vendors (Lightspeed, Zettle, Sumup) are not yet certified — the standard HTTP contract above is what they need to fit into. Roadmap: tested adapters per vendor.
- Refunds posted from the external POS appear in CampOne as separate transactions; CampOne doesn’t auto-link a refund to its original sale across systems.