How It Works

How PCI Proxy Works

You send us card data. We tokenise it, store it in a PCI DSS vault and return a token. Your systems never receive the card number.

Data Flow

The flow in 5 steps

From the moment the customer enters their card to the token you save in your back office: here is what happens step by step.

Phase 1

Card data in

Website checkout, API call or call centre form

Phase 2

PCI Proxy intercepts

We receive card data from the HTTP payload before it reaches your servers

Phase 3

Tokenisation

We encrypt the card number and generate a unique token

Phase 4

Secure vault

The card number stays encrypted in our PCI DSS Level 1 vault, EU only

Phase 5

Token to you

You receive the token and use it for payments, subscriptions or refunds

Tokenisation

What happens when we tokenise

We replace the card number with a token. You never see the plain card in your systems. Here are the three internal steps.

01

Step

We detect card data

We analyse incoming requests and identify card numbers in JSON, forms or multipart payloads. No code changes on your side: connect your flow and you are done.

02

Step

We create the token

Every token starts with tok_pci_eu_ and includes the last four digits, scheme and expiry. So your UI can show "Visa ending in 1234" without ever holding the card number.

03

Step

Same token, same card

If the same card arrives again, we return the same token. Useful for subscriptions and saved cards. The mapping stays only in the vault and is not exposed via API.

pci-proxy · live example ACTIVE

→ POST /v1/tokenize

{

"card_number": "4111 1111 1111 1234",

"expiry": "12/26"

}

AES-256 · EU vault

← 200 OK · 47ms

{

"token": "tok_pci_eu_a1b2c3d4e5f61234",

"last_four": "1234",

"brand": "visa",

"card_in_your_systems": false

}

Card number never on your servers · EU vault · Logged
Card retrieval

When the card number is needed

To authorise a payment the PSP needs the real card number. You send the token: we retrieve the card from the vault and forward it securely. You never see it.

1

When it happens

When you need to charge a saved card, send the token to our forward endpoint. We resolve the card number in the vault and pass it to the PSP over an encrypted connection. It does not appear in your logs.

2

Who can do it

Only holders of an API key with forward or detokenize permission. You can restrict by IP, environment and request volume.

3

Fully audited

Every retrieval is logged: who requested it, when, and which PSP. Logs are kept for at least 12 months and are available from the dashboard or API.

Protection layers

Level 1 Signed API key

Every request is authenticated

Level 2 IP whitelist

Only from your authorised servers

Level 3 Encrypted connection to PSP

TLS with verified certificates

Level 4 Audit logs

Retained for at least 12 months

API

Two endpoints, clear flow

Authenticate with your API key. One endpoint creates the token, the other uses it to pay. JSON in, JSON out.

POST /v1/tokenize Scope: tokenize

Request body

{
  "card_number": "4111111111111111",
  "expiry":      "12/26",
  "cvv":         "123"
}

Response 200 OK

{
  "token":      "tok_pci_eu_a1b2c3d4e5f6",
  "last_four": "1111",
  "brand":     "visa",
  "expires_at": "2026-12-31"
}
POST /v1/forward Scope: forward

Request body

{
  "token":      "tok_pci_eu_a1b2c3d4e5f6",
  "target_url": "https://psp.eu/charge",
  "amount":     9900,
  "currency":   "EUR"
}

Response (from PSP, proxied)

{
  "status":         "authorized",
  "transaction_id": "txn_9f8e7d6c",
  "amount":         9900,
  "currency":       "EUR"
}
Signed requests
Average latency under 50 ms
REST + Webhooks
Real-Time Events

Webhooks and notifications

When something happens (token created, payment sent, error), we send a real-time event to your endpoint. Every message is signed so you can verify it server-side.

If delivery fails, we retry up to 5 times with increasing intervals. You can also replay manually from the dashboard within 72 hours.

Supported Event Types

token.created New token generated
token.used Token sent to PSP
token.expired Token reached its TTL
token.deleted Token removed on request
forward.success PSP returned 2xx
forward.failure PSP returned error

Webhook Payload Example

POST your-server.com/webhooks/pci LIVE
{
  "event":     "token.created",
  "timestamp": "2026-04-03T10:15:30Z",
  "data": {
    "token":       "tok_pci_eu_a1b2c3d4e5f6",
    "last_four":   "1111",
    "brand":       "visa",
    "merchant_id": "mrc_xyz789"
  },
  "signature": "sha256=4a8b9c..."  // HMAC-SHA256
}

Signature verification

Every webhook includes the X-PCI-Signature header. Compute HMAC-SHA256 of the body with your secret and compare it to the signature. If they do not match, reject the request.

Anti-replay Verifiable signature 5 automatic retries
Integration

SDKs and ways to integrate

SDKs for Node, Python and PHP, or hosted fields in iFrames. Choose what fits your stack.

JS

JavaScript SDK

npm
import PCIProxy from '@pci-proxy-eu/js';

const pci = new PCIProxy({
  merchantId: 'mrc_xyz789'
});

const { token } = await pci.tokenize({
  cardNumber: '4111...'
});
Node.js 18+ · Browser · TypeScript included
PY

Python SDK

PyPI
from pci_proxy_eu import Client

client = Client(
  merchant_id="mrc_xyz789",
  api_key="sk_live_..."
)

result = client.tokenize(
  card_number="4111..."
)
Python 3.9+ · AsyncClient available
PHP

PHP SDK

Composer
use PCIProxyEU\Client;

$client = new Client(
  merchantId: 'mrc_xyz789',
  apiKey: 'sk_live_...'
);

$result = $client->tokenize([
  'card_number' => '4111...'
]);
PHP 8.1+ · Java and .NET available
Hosted fields

Secure iFrames for checkout

To stay in SAQ A: card fields are rendered in our iFrames. Card data never passes through your DOM.

hosted-fields.html
<div id="card-number"></div>
<div id="card-expiry"></div>
<div id="card-cvv"></div>

<script>
  PCIProxy.hostedFields({
    merchantId: 'mrc_xyz789',
    fields: {
      cardNumber: '#card-number',
      expiry:     '#card-expiry',
      cvv:        '#card-cvv'
    },
    onTokenize: (result) => {
      // token only, never the card number
      console.log(result.token);
    }
  });
</script>
checkout.your-shop.com

Payment Details

4111 1111 1111 •••• iFrame
12/27 iFrame
••• iFrame

Card data never on your server

SAQ A

Less PCI burden

CSS

Customisable styling

Mobile

Responsive

Ready to integrate?

Learn what a PCI Proxy is, explore tokenisation in depth or see how developers use the platform.