Developer guide

Reference deployment topology

9 min read

Where each component runs when a Partner operates the platform with real funds. The topology is deployed inside the Partner's own cloud project.

flowchart LR
    EXT[Partner app / backend and channels] -->|1| LB[Load Balancer / WAF]
    subgraph GCP[Partner's own cloud project]
        API[B2B API]
        CP[Control Plane]
        W[Workers]
        O[Observers]
        R[Reconciler]
        WH[Webhook Dispatcher]
        SG[Partner Signer Gateway]
        SQL[(Managed PostgreSQL, high availability)]
        PUB[Event bus]
        TASKS[Scheduled tasks]
        SM[Secret Manager / vault]
        AR[Artifact Registry]
        MON[Logging / Monitoring / Trace]
        LB -->|2| API
        API -->|3| SQL
        API -->|4| PUB
        PUB -->|5| W
        PUB -->|5| O
        PUB -->|5| R
        PUB -->|5| WH
        TASKS -->|6| W
        W -->|7| SG
        SG -->|8| SM
        API -->|9| MON
        W -->|9| MON
        O -->|9| MON
        R -->|9| MON
        WH -->|9| MON
    end
    W -->|10| RPC[RPC / blockchain providers]
    O -->|10| RPC
    WH -->|11| EXT

What each part does

  1. Partner app, backend and channels → Load Balancer. All external traffic enters through one controlled edge.
  2. Load Balancer → B2B API. The public contract, the only component external traffic reaches directly.
  3. API → PostgreSQL. The durable state: operations, ledger, identity, configuration.
  4. API → event bus. The Outbox is published here, and from here every consumer is fed.
  5. Bus → workers, observers, reconciler, webhook dispatcher. Delivery is at-least-once, so consumers deduplicate.
  6. Scheduled tasks → workers. Scheduled retries and sweeps: what has to happen later, not in response to a request.
  7. Workers → Partner Signer Gateway. The only path to a signature.
  8. Gateway → Secret Manager or vault. The gateway is the only component that can read the key material, under the Partner's own access control.
  9. Everything → Logging, Monitoring, Trace. Operational signals centralized.
  10. Workers and observers → RPC and blockchain providers. The only outbound path to the networks.
  11. Webhook dispatcher → Partner. Signed events back to the Partner's backend.

One deployment, one Partner

This topology serves exactly one Partner. The instance, the database, the secrets and the conversational instance are the Partner's own, and no part of them is shared with another Partner's deployment. It is the isolation model itself, not a starting configuration that later gets tightened.

Every record still carries the tenant it belongs to, so the data is portable to a shared deployment if one is ever offered, and so a report can be read per tenant. But a deployment refuses to start if its configured credentials name more than one tenant, and it refuses to register a client under a tenant that is not its own: what keeps one Partner's data away from another's here is that the other Partner is not in this instance.

Infrastructure responsibilities

  • The managed Kubernetes platform runs the API, workers, observers, reconciler, webhook dispatcher and signer as workloads with separate identities, so one compromised workload does not inherit the permissions of the others.
  • Managed PostgreSQL keeps the durable transactional state, with high availability.
  • The event bus distributes events at-least-once.
  • Scheduled tasks handle programmed retries and sweeps.
  • Secret Manager or a key vault stores the initial master secret and the other secrets, under the Partner's access control.
  • Artifact Registry keeps the images the Partner has imported and approved. They are private, and the cluster pulls from this registry and never from ChatterPay's: the image arrived here through an OCI copy that is a release step, so once the copy is done the deployment starts even if the origin registry is gone. ChatterPay can perform that copy -- and then the Partner needs no credential of ours -- or the Partner can, with read access, which is what lets it decide when to promote a version.
  • Logging, Monitoring and Trace centralize operational signals.

A reference topology, not the only one

What is fixed here is the function of each component, not the product that provides it. The diagram names a managed Kubernetes platform, a managed PostgreSQL, an event bus, a secret store and an OCI registry because the deployment needs those five capabilities -- not because it needs any particular vendor's version of them. A Partner running on another cloud maps each function to its own equivalent and deploys the same chart.

That is also why every heading below names the function first and the product second. A page written the other way round reads as a requirement to buy something.

Kubernetes stays in the diagram, and serverless is a legitimate option. The same chart's workloads can run on a managed serverless container platform -- Cloud Run on GCP is the example this project itself uses for the development environment -- and it is meaningfully cheaper for a deployment that is idle most of the time, because nothing pays for an idle node pool.

Two counterparts come with it, and both are real:

  • It ties the deployment to that provider. A Helm chart is portable across managed Kubernetes; a serverless container service is configured in that provider's own resource model, so moving clouds means rewriting the deployment rather than repointing it.
  • It throttles the continuous consumers. The workers, the observers, the reconciler and the webhook dispatcher are not request-driven: they run all the time. A serverless platform that scales to zero and allocates CPU only during a request either starves them or has to be pinned to a minimum instance with CPU always on, which removes most of the saving for those workloads.

A common middle ground is the API on the serverless platform, where traffic is bursty, and the continuous consumers on nodes.

Does it run on my cloud?

Five requirements, and a cloud that meets them runs this deployment.

  • PostgreSQL 16 or newer, reachable over a connection URL.
  • A way to inject secrets into a workload as environment variables.
  • An OCI registry the platform can pull from.
  • An ingress that terminates TLS with a certificate.
  • A DNS name the Partner administers.

Everything else in the topology is an equivalence:

Function in the topologyGCPAWSAzure
Public edge with WAFCloud Load Balancing + Cloud ArmorApplication Load Balancer + AWS WAFApplication Gateway + WAF
Managed container platformGKE, or Cloud RunEKS, or ECS on FargateAKS, or Container Apps
Managed PostgreSQL with high availabilityCloud SQL for PostgreSQLRDS or Aurora PostgreSQLAzure Database for PostgreSQL
Event bus with at-least-once deliveryPub/SubEventBridge, or SNS with SQSService Bus
Scheduled tasksCloud SchedulerEventBridge SchedulerContainer Apps jobs
Secret storage under the Partner's access controlSecret ManagerSecrets ManagerKey Vault
OCI registryArtifact RegistryECRContainer Registry
Logs, metrics and tracesCloud Logging, Monitoring and TraceCloudWatch and X-RayAzure Monitor and Application Insights

What is deployed, what is optional, and what is not deployed at all

Mandatory. The B2B API; the workers, observers, reconciler and webhook dispatcher, which are the same image running as different workloads; the Partner Signer Gateway; PostgreSQL; the secret store; the OCI registry; the public edge; and the observability stack. Remove any of them and the platform does not settle an operation.

Optional, and the choice belongs to the Partner.

  • The conversational bot and its MongoDB. They are needed only if the Partner offers the WhatsApp channel. A Partner integrating through the API and the SDK from its own app deploys neither.
  • The chain providers of the networks it does not operate. Blockfrost is needed for Cardano, an Esplora endpoint for Bitcoin, and an EVM RPC provider for Arbitrum and Base. A deployment that only moves EVM assets needs the third one.

Not deployed at a real Partner.

  • The Reference Partner is a demonstration of the integration. In a real deployment the webhook receiver is the Partner's own backend, which is what the demo stands in for.
  • The documentation portal and its public sandbox belong to ChatterPay's environment. The chart carries the portal as a workload and ships it switched off.
  • The operations console is operated by ChatterPay today, reading each Partner's own database; the Partner consumes it as a user. Deploying one per Partner arrives with the white-label scheme.

Trust boundaries

Two hostnames are public, and everything else is reachable only from inside the project.

  • Public. The B2B API, behind the load balancer and its WAF. And, when the Partner offers the WhatsApp channel, the bot's webhook route -- Meta validates the endpoint when the webhook is registered, so it has to be reachable from outside.
  • Internal. The Partner Signer Gateway, the database, the event bus, and every consumer. None of them has a public hostname, and their ingress refuses traffic that did not originate inside the project's network.
  • Outbound. The workers and observers reach the RPC and blockchain providers; the webhook dispatcher reaches the Partner's backend. Those are the only two paths out.

The Signer Gateway is the boundary the rest of the design exists to protect, and it has two properties worth stating separately. It carries no public hostname: nothing outside the project can address it at all. And it does not share a service identity with the API: the API holds the permission to call it and no permission to read the key material, which lives in the Partner's own secret store under the gateway's identity.

The consequence is the one that matters when something goes wrong. An attacker who reaches the API can ask for signatures within the policy the gateway enforces -- and cannot obtain a key, because the component that can read one does not answer to the component that was reached.

Who provides each element

The split is stated in full on Who is responsible for what. Applied to this diagram:

ElementProvided by
Container images and the release manifestChatterPay publishes them; the Partner imports and promotes them into its own registry
IaC modules and the Helm chartChatterPay
The cloud project, its IAM, its network and its operationPartner
Domain and DNS zonePartner
Third-party accounts: Meta, OpenAI, EVM RPC, Blockfrost, LI.FIPartner
MongoDB and the console's identity providerChatterPay contracts them and hands over the connection string; the Partner keeps it in its own secret store
Secrets: the master key, the API signing key, the webhook secretThe Partner generates and holds them; ChatterPay names them and never reads them
Operational funds: relayer gas, the paymaster deposit, the Cardano and Bitcoin funding walletsPartner

No central dependency

A real Partner's self-hosted deployment does not depend on a central ChatterPay service to sign or process operations.

ChatterPay publishes versioned artefacts; the Partner controls when they are promoted. That is what makes the Partner's operational continuity independent of ours.