Skip to content

Payment Events (pyrx.payment)

Warning

Deprecated. pyrx.payment is the legacy billing provider. New workspaces use Lemon Squeezy for billing. The pyrx.payment webhook endpoint remains active for existing integrations but will be removed in a future release. Migrate to Lemon Squeezy billing events when possible.

Synapse receives subscription lifecycle events from pyrx.payment via webhooks. These events update your workspace's plan, limits, and status.


Webhook Endpoint

POST https://synapse-api.pyrx.tech/v1/webhooks/payment

This endpoint is secured by a shared secret in the X-Webhook-Secret header -- see Signature Verification. The secret supports comma-separated rotation (both old and new secrets accepted simultaneously).


Events

EventDescriptionSynapse Action
subscription.activatedNew subscription created or trial convertedUpdate plan, set new limits, set status to active
subscription.activeSubscription confirmed activeSame as subscription.activated
subscription.renewedRecurring payment succeededReset monthly_emails_sent and monthly_events_used to 0, update plan
payment.failedPayment attempt failedLogged as warning, workspace remains active
subscription.past_dueSubscription past dueLogged as warning, workspace remains active
subscription.cancelledSubscription endedDowngrade to free plan with free-tier limits, clear payment_subscription_id
subscription.pausedSubscription paused by adminSuspend workspace (status = suspended, suspended_reason set)

Payload Schema

All payment webhook events share a common envelope:

json
{
"event_type": "subscription.activated",
"timestamp": "2026-04-07T10:30:00Z",
"data": {
"subscription_id": "sub_8f14e45f-ceea-467f-a83c-01a01ba3c5db",
"customer_id": "cus_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_id": "synapse_growth",
"amount": 9900,
"currency": "USD",
"interval": "monthly",
"current_period_start": "2026-04-07T00:00:00Z",
"current_period_end": "2026-05-07T00:00:00Z",
"status": "active"
}
}

Common Fields

FieldTypeDescription
event_typestringThe event identifier
timestampstringISO 8601 timestamp of when the event occurred
data.subscription_idstringpyrx.payment subscription ID
data.customer_idstringpyrx.payment customer ID (maps to tenants.payment_customer_id)
data.plan_idstringPlan identifier (e.g., synapse_growth)
data.amountintegerAmount in cents
data.currencystringThree-letter currency code
data.statusstringSubscription status

Event Details

subscription.activated

Fired when a workspace owner completes checkout and payment succeeds.

json
{
"event_type": "subscription.activated",
"data": {
"plan_id": "synapse_growth",
"amount": 9900,
"status": "active"
}
}

Synapse action:

  • tenants.plan updated to the plan ID (with pyrxcrm_ prefix stripped)
  • tenants.monthly_email_limit synced from the plans table
  • tenants.contacts_limit synced from the plans table
  • tenants.status set to active

subscription.renewed

Fired on successful recurring payment.

json
{
"event_type": "subscription.renewed",
"data": {
"plan_id": "synapse_growth",
"status": "active",
"current_period_start": "2026-05-07T00:00:00Z",
"current_period_end": "2026-06-07T00:00:00Z"
}
}

Synapse action:

  • tenants.monthly_emails_sent reset to 0
  • tenants.monthly_events_used reset to 0

payment.failed / subscription.past_due

Fired when a payment attempt fails or the subscription enters a past-due state.

json
{
"event_type": "payment.failed",
"data": {
"plan_id": "synapse_growth",
"status": "past_due"
}
}

Synapse action:

  • Logged as a warning
  • Workspace remains active -- no immediate impact on access
  • pyrx.payment handles retry/dunning automatically

subscription.cancelled

Fired when a subscription is cancelled (after grace period expires or voluntary cancellation).

json
{
"event_type": "subscription.cancelled",
"data": {
"plan_id": "synapse_growth",
"status": "cancelled"
}
}

Synapse action:

  • tenants.plan downgraded to free
  • Limits synced from the free plan in the plans table
  • tenants.payment_subscription_id cleared
  • Existing data is preserved but new operations are limited

subscription.paused

Fired when a subscription is administratively paused.

json
{
"event_type": "subscription.paused",
"data": {
"plan_id": "synapse_growth",
"status": "paused"
}
}

Synapse action:

  • Workspace set to read-only mode
  • No new emails can be sent
  • Dashboard remains accessible for data viewing
Note

Payment events are processed asynchronously. There may be a delay of a few seconds between payment completion and plan update. The dashboard polls for plan changes after checkout to ensure the user sees the updated plan promptly.


Idempotency

Synapse handles duplicate webhook deliveries gracefully. The same event processed twice will not cause double updates (e.g., resetting monthly_emails_sent twice).


Retry Behavior

The webhook handler always returns 200 OK, even if internal processing fails. This prevents pyrx.payment from retrying indefinitely. Internal failures are logged and alerted via Sentry.

json
{
"received": true,
"event_type": "subscription.activated"
}