🔧 Dev

OffreThe Augmented Engineering Programdès 2 500 € / mois

Tech Lead & équipe · ou MVP livré en 3 mois + recrutement

Découvrir

🧩 CH1 - Building a Modern Payment Gateway with a Rebill Scheduler - Chapter 1 – Foundations

Sébastien Techer10/10/2025

Why you might want to build your own payment gateway — and how to do it safely with an external PCI-compliant vault.

💡 Why Build Your Own Payment Gateway?

For most startups and SaaS platforms, using Stripe or Adyen feels like the obvious choice. It’s fast, simple, and gets you online in minutes. But as your product grows — and your payment flows get more complex — you start hitting invisible walls.

  • You can’t control retry logic.
  • You can’t design custom reconciliation or refund workflows.
  • You can’t easily migrate users from one PSP (Payment Service Provider) to another.
  • And your compliance surface (PCI, PSD2, 3DS) becomes someone else’s black box.

At that point, building your own modular gateway becomes more than a technical luxury — it’s a strategic decision. It means controlling your data, your money flows, and your roadmap.

In short:

Using a PSP is easy. Owning your payment stack is power.


🧱 The Architecture of a Modular Payment Gateway in Go

Think of a gateway as a digital switchboard: it routes payment requests to the right provider, handles their lifecycle, and maintains the source of truth for your platform.

To do this properly, we split the architecture into three core layers:

1. PSP Layer (Adapters)

Each provider (Stripe, Adyen, TrustPayments, etc.) is wrapped in an adapter that implements a standard interface.
CreateIntent(), ContinueIntent(), Capture(), Refund(), Cancel(), VerifyWebhook(), etc.
No SDK chaos — one clean abstraction.

2. Vault Layer (External)

We never store or process card data inside our infrastructure.
Instead, we delegate all card handling to a PCI-DSS Level 1 certified vault provider.
This keeps our backend within SAQ-A compliance and removes the need for us to handle sensitive payment data directly.

A typical flow looks like this:

  1. The frontend sends card data directly to the external vault provider.
  2. The vault returns a token representing the payment method.
  3. The frontend sends that token to your backend.
  4. Your backend passes it to your vault provider to execute (after detokenization) the payment via the selected PSP.

No card numbers ever touch your systems — only tokens.

3. Core Layer (Business Logic)

The orchestrator.
It knows when to authorize, when to capture, when to retry, and how to reconcile asynchronous events.
It’s your payment brain, independent of any PSP or vault.

A simple Go-based design might look like this:

// PSP defines a 3DS-aware, intent-style interface.
type PSP interface {
    // Create an intent (may return requires_action with NextAction)
    CreateIntent(ctx context.Context, req PaymentRequest) (PaymentResponse, error)

    // Continue an intent after client completed NextAction (e.g., returned from ACS)
    ContinueIntent(ctx context.Context, intentID string, payload map[string]string) (PaymentResponse, error)

    // Capture/Refund/Cancel on the underlying provider object
    Capture(ctx context.Context, intentID string, amount *Money) (PaymentResponse, error)
    Refund(ctx context.Context, intentID string, amount *Money) (PaymentResponse, error)
    Cancel(ctx context.Context, intentID string) error

    // Webhooks → normalize to provider-agnostic events
    VerifyWebhook(ctx context.Context, signature string, payload []byte) (WebhookEvent, error)
}

With this interface in place, adding a new PSP becomes a plug-in operation — clean and predictable.

🔐 Security & PCI-DSS: Understand Before You Code

Before writing a single line, understand where your PCI responsibility starts and ends.

There are multiple Self-Assessment Questionnaires (SAQs) under PCI-DSS, but for developers, the two key ones are:

SAQ-A: Your system never touches card data. All payments go through an external vault or PSP-hosted form.

SAQ-D: You handle or store card data directly. Full PCI scope. Audits, scanning, and lots of headaches.

Your goal as a builder?

Stay SAQ-A for as long as possible.

That’s why external vault providers are critical: They tokenize and securely store card data on your behalf, letting you operate without the overhead of PCI audits.

ConceptPurposeKey Principle
Gateway CorePayment orchestration logicPSP-agnostic
PSP AdaptersConnect to multiple providersClean interface
Vault ProviderTokenize and store card data externallyStay SAQ-A
PCI-DSS ScopeDefine responsibility zonesTokenize early

🚀 Coming Next

In Chapter 2, we’ll go deeper into integration patterns:

  • How to design a universal PSP interface in Go.

  • How to connect multiple PSPs without breaking your codebase.

  • How to stay PCI-compliant while scaling.

Your gateway is now an idea. Next, we’ll make it modular — and alive.


Respect de votre vie privée

Nous utilisons des cookies pour améliorer votre expérience, analyser le trafic et personnaliser le contenu. Vous pouvez choisir quels cookies accepter.