Architecture
The CatalystPay Payment Session API is built around a clear hierarchy of commerce entities. Understanding how these entities relate to each other will help you design your integration and interpret the data you receive through webhooks and the reconciliation API.
Data hierarchy
Entity descriptions
Campaign
A Campaign is the top-level organizational unit for a payment funnel. It ties together an offer, a payment mode (SEPA Direct Debit, Credit Card, or Open Banking), session settings like maximum payment attempts, and duplicate lead handling rules.
Campaigns also link to Hosted Pages for branded payment page configuration and to Webhook Profiles for event notification routing.
Offer
An Offer combines a product with pricing and billing configuration. It defines:
- Price and currency -- How much the customer pays (e.g., EUR 29.99)
- Billing type --
ONE_OFF,RECURRING, orTRIAL_RECURRING - Billing frequency -- For recurring offers:
WEEKLY,BIWEEKLY,MONTHLY,QUARTERLY,SEMIANNUALLY, orYEARLY - Trial settings -- Trial interval unit (
day,week,month), trial period duration, and trial price - Payment gateway -- Which gateway (MID) processes payments for this offer
Payment Session
A Payment Session tracks the lifecycle of a single checkout attempt. When you call POST /api/v1/payment-sessions/, CatalystPay creates a session and returns a token. That token follows the session through payment submission, optional mandate verification, and completion or failure.
Session statuses:
| Status | Meaning |
|---|---|
PENDING |
Session created, awaiting payment |
PAYMENT_IN_PROGRESS |
Payment submission in flight |
AWAITING_VERIFICATION |
Customer must complete mandate signing |
COMPLETED |
Payment approved |
FAILED |
All retry attempts exhausted |
EXPIRED |
Session cancelled before payment |
Terminal states (COMPLETED, FAILED, EXPIRED) cannot transition to any other state.
Lead
A Lead is the customer identity, uniquely identified by IBAN. Leads are created automatically when a payment session is created (or matched to an existing lead by email within the campaign scope). A lead carries:
- Name, email, phone
- IBAN and BIC
- Address (street, city, postal code, country as ISO 3166-1 alpha-2)
- Lifecycle status:
LEAD->ACTIVE_CUSTOMER->CHURNEDorCHARGEDBACK
Order
An Order is the purchase record created when a payment session completes successfully. It captures the amount, currency, and links to the lead, campaign, offer, and payment gateway. Orders have their own status lifecycle:
| Status | Meaning |
|---|---|
PENDING_PAYMENT_SUBMISSION |
Order created, payment not yet submitted |
PENDING |
Payment submitted, awaiting confirmation |
COMPLETED |
Payment approved |
FAILED |
Payment declined |
PARTIALLY_REFUNDED |
Partial refund issued |
REFUNDED |
Full refund issued |
CHARGEDBACK |
Customer disputed the payment |
CANCELLED |
Order cancelled |
Subscription
A Subscription is created when the purchased offer has a RECURRING or TRIAL_RECURRING billing type. It tracks the billing schedule, next billing date, and revenue counters. Subscription statuses:
| Status | Meaning |
|---|---|
PENDING_ACTIVATION |
Awaiting first successful charge |
ACTIVE |
Billing on schedule |
PENDING |
Pending first payment |
PAST_DUE |
Missed a billing cycle |
PAUSED |
Temporarily suspended |
CANCELLED |
Subscription cancelled |
EXPIRED |
Subscription term ended |
CHARGEDBACK |
Customer disputed a charge |
FAILED |
Subscription creation failed |
Transaction
A Transaction is the financial event record. Every payment attempt, rebill, and refund creates a transaction. Transactions carry standardized statuses and types that are consistent across all payment gateways:
Statuses: approved, declined, pending_async, pending_hold, pending, error, refunded, cancelled, charged_back, voided, chargeback_reversed, represented, representment_reversed, second_chargeback, pending_review, partially_reversed, other_status (unmapped adapter status), pending_payment_submission (transaction created, not yet submitted to processor)
Types: sdd_sale (Direct Debit sale), sdd_refund (Direct Debit refund), other_type (unmapped adapter transaction type)
Chargeback
A Chargeback is a dispute record linked to the original transaction. It carries the report date (when the chargeback was reported), the transaction date (when the original payment occurred), the reason code, and the dispute amount.
Campaign mode vs direct mode
CatalystPay provides two ways to create payment sessions, depending on who owns the product catalog.
Campaign mode
When you pass a campaign_id in the session creation request, CatalystPay resolves the entire payment context automatically:
The campaign acts as a bundle that ties together everything needed for a payment: which product is being sold, at what price, through which gateway, with what billing schedule, how the hosted page should look, and where to send webhooks.
Choose Campaign mode when:
- You use the CatalystPay admin UI to manage products and pricing
- You want hosted payment pages with branded content
- You have multiple campaigns with different offers, gateways, or branding
- Operational teams need to change pricing without code deployments
Direct mode
When campaign_id is omitted, CatalystPay enters direct mode. You must supply four fields that would otherwise come from the campaign chain:
gateway_id-- Which payment gateway to useamount-- The payment amountcurrency-- The currency code (ISO 4217)billing_type--ONE_OFF,RECURRING, orTRIAL_RECURRING
Choose Direct mode when:
- Your system already manages products, prices, and billing schedules
- You treat CatalystPay as a payment processing API, not a commerce platform
- You need maximum control over every parameter in each request
- You are building a server-to-server integration
Pricing overrides
Even in Campaign mode, you can override pricing on a per-session basis by passing optional fields like amount, currency, billing_type, and billing_frequency. These override the campaign's offer values for that session only, without changing the underlying configuration.
This is useful for promotional discounts, currency conversion, A/B testing, or trial customization.
In Direct mode, the Order's campaign and offer fields are null. Webhook routing falls back to an explicit webhook_profile_id rather than the campaign's webhook profile. If you need webhooks in Direct mode, pass a webhook_profile_id when creating the session.
The status cascade
When a transaction's status changes, related entities are automatically recalculated:
The cascade follows a priority hierarchy:
- CHARGEDBACK (highest) -- Any chargeback makes the lead CHARGEDBACK
- ACTIVE_CUSTOMER -- Any active subscription or completed standalone order
- CHURNED -- Only terminal subscriptions remain
- LEAD (default) -- No payment history
This means a single chargeback cascades through the entire entity chain: transaction, order, subscription, and lead.
Next steps
- Getting Started -- Make your first API call
- HPP Integration -- Full hosted payment page walkthrough
- Reconciliation -- Pull transaction data for settlement matching