Data Flow
Firmly sits between the destination (where the user expresses purchase intent) and the merchant (where the order is fulfilled). This page covers what data flows in each direction, where it lives in motion, and what Firmly persists vs passes through.
The three actors and what each holds
| Actor |
Holds |
Doesn’t hold |
| Destination |
User identity, conversation/page context, App ID, short-lived session JWT, attribution params (UTM, click-IDs) |
Cleartext PAN at rest, merchant catalog data persistently, order fulfillment state |
| Firmly |
Cart state during checkout, session identity (device_id), encrypted payment payload (in motion), order placement record |
Cleartext PAN at rest, destination’s internal user model, the merchant’s authoritative catalog and inventory (those stay with the merchant) |
| Merchant |
Full product catalog, inventory, customer order records, payment processing relationship with PSP, post-order fulfillment |
Destination’s internal user identity, the destination’s session data |
Data in motion — the canonical purchase
Trace the data on a single purchase from intent to order placement:
| Step |
What flows |
Path |
| 1. Auth bootstrap |
App ID |
Destination → Firmly |
| 1. Auth bootstrap |
JWT (access_token) |
Firmly → Destination |
| 2. Discovery |
Search query |
Destination → Firmly |
| 2. Discovery |
Catalog query |
Firmly → Merchant |
| 2. Discovery |
Product results |
Merchant → Firmly → Destination |
| 3. Cart create |
Product reference, quantity |
Destination → Firmly |
| 3. Cart create |
Cart state |
Firmly persists in its session store (~7 days) |
| 4. Shipping |
Address |
Destination → Firmly → Merchant |
| 4. Shipping |
Shipping methods + prices |
Merchant → Firmly → Destination |
| 5. Payment key |
RSA public key |
Firmly → Destination |
| 6. Card encryption |
Cleartext card payload |
Destination’s local memory only — never transmitted in cleartext |
| 6. Card encryption |
JWE payload |
Destination → Firmly |
| 7. Place order |
Encrypted card + cart + shipping |
Destination → Firmly |
| 7. Place order |
A $0 authorization against the card to validate it, before the order is placed |
Firmly → PSP |
| 7. Place order |
Decrypted card → PSP (which returns a token) or → merchant’s own platform, over TLS |
Firmly → PSP / merchant platform |
| 7. Place order |
Order metadata + line items |
Firmly → Merchant’s OMS |
| 7. Place order |
Merchant order ID |
Merchant → Firmly → Destination |
What lives at rest, where, and for how long
| Data |
Stored where |
Retention |
| Session JWT |
Destination’s session memory |
~1 hour (token lifetime) |
| Device identifier |
Destination + Firmly |
Session-scoped; Firmly retains session state ~7 days from last activity |
| Cart state |
Firmly’s session store |
7 days from last activity |
| Idempotency keys (UCP protocol bridge) |
Firmly internal |
24 hours |
| Order placement record |
Firmly internal + Merchant OMS |
Per merchant retention policy |
| Cleartext card PAN |
Nowhere at rest — the vault decrypts in memory and submits the card to the PSP or merchant platform over TLS |
Never persisted |
| Customer order |
Merchant OMS |
Per merchant policy (typically years) |
Attribution flow — separate from purchase data
Attribution data (UTM params, click-IDs, publisher identifiers) flows alongside the purchase data but goes to different destinations:
| Attribution data |
Captured at |
Flows to |
| UTM params |
Destination on page load / impression |
Order metadata → Merchant OMS, Destination’s analytics |
| Ad-platform click-ID |
Destination on click |
Order metadata, then ad-platform postback |
| Publisher identifier |
Destination’s session |
Firmly affiliate service → Merchant OMS, Publisher’s payout system |
| Marketplace operator ID |
Destination’s session |
Firmly attribution → Merchant OMS, Operator’s reconciliation system |
What Firmly does NOT see
- Destination’s own user identity — Firmly tracks a session device ID, not the destination’s user model
- Cleartext PAN at rest — see Security Model
- Destination’s full conversation / page context — only the intent that arrives at the API (search query, product reference, address, payment)
- The authoritative catalog, inventory, and pricing — these stay with the merchant. Firmly reads them live from the merchant’s commerce backend at request time, and the merchant’s store remains the source of truth. Firmly does maintain a discovery index so search can span the merchant network — so this is not a claim that Firmly holds no catalog data, only that it does not hold the system of record. Use
include_realtime on search when you need a result re-checked against the store.