Connector lifecycle
How the Marketplace API verifies, normalizes, and reconciles a billing connector's events into the unified ledger.
Every billing connector runs the same pipeline, from an inbound provider webhook to a row in your unified revenue ledger. Understanding it makes the connectors predictable and debuggable.
The state machine#
A connection moves through these states:
| State | Meaning |
|---|---|
pending | Created, no credentials yet. |
connected | Credentials stored; webhook URL issued. |
active | Validated and live, so events flow into the ledger. |
paused | Temporarily stopped; credentials retained. |
error | Validation or delivery failed; see lastError. |
disconnected | Turned off; credentials wiped. |
Inbound: from webhook to ledger#
The provider POSTs to a per-connection URL that carries an unguessable ingest token in its path, the first gate, exactly like the App Store notification URL.
The provider's signature is checked over the exact received bytes,
Stripe's t=…,v1=…, Paddle's ts=…;h1=…, Lemon Squeezy's X-Signature,
Polar's Standard-Webhooks, Recurly/Chargebee Basic auth. A bad signature is
rejected with 401.
The event is recorded under a unique (connection, providerEventId) key, so
a provider's retries collapse onto one row. The service acks 200
immediately and processes asynchronously.
The provider's event is mapped to a canonical revenue event (a purchase, renewal, cancellation, or refund) and the provider's price/plan id is resolved to your CashSDK product and entitlement via the catalog mapping.
The normalized event is written to the unified ledger with the same shape as a store purchase. It appears in the same MRR, churn, and cohort analytics, keyed to the customer, so it unifies with their mobile entitlements.
Nothing is trusted on the client, and nothing is recorded from an unverified webhook in production. Signature verification fails closed: a connector refuses events it can't authenticate.
Outbound: from event to destination#
Integration connectors run the reverse path. When a revenue event occurs, the
Marketplace API transforms it for each active destination (a Slack message, a
Segment track call, a normalized collector POST) and delivers it with retries
and exponential backoff. Delivery targets are validated against SSRF, so a
destination can never point at a private or internal address.
Idempotency & retries#
- Inbound events are deduplicated by provider event id; reprocessing is a no-op once an event is marked done.
- Ledger writes upsert on
(app, transactionId), so a replay never double-counts revenue. - Outbound deliveries retry with exponential backoff until a
2xx, then stop; each attempt is logged with its status.