Skip to content

Compliance & security

What the platform enforces in code, and what needs a contract.

Two questions get asked together and have very different answers. What the platform does on every request is on this page, verifiable against the API you are already calling. Certifications, licences and data residency are contractual, they change per market and per contract, and they come from enterprise@wajub.com rather than from a documentation page.

What runs on every request

GuaranteeMechanism
A key is never stored or compared in plaintextKeys are kept encrypted; showing one again asks for a security verification code
A revoked or expired key stops working immediately401, checked on every request
A private key cannot be used from a browserAn sk. key detected in a browser request is refused with 403 and the owner is alerted
A leaked key can be bound to your serversPer-key IP allow-list, exact address or CIDR
A key can be narrowed to what it needsRestricted keys, fourteen resource scopes, read and write
A webhook proves it came from WajubHMAC-SHA256 over timestamp and body, 300 second tolerance
Sandbox cannot reach live dataSandbox and live share no data; the key you authenticate with decides the environment
A retry cannot charge twiceIdempotency-Key: the first response is replayed for 24 hours, and a payment, transfer or refund is never created twice for one key

Security best practices walks through each of those from the integrator's side, including rotation without downtime.

Card data and your PCI scope

Card numbers never reach Wajub. The payer types the card into the card provider's own fields or window, and Wajub only receives what the provider hands back: a token, encrypted fields or a session reference.

Card providerWhere the payer types the card
StripeStripe's card fields, inside Hosted Checkout or Wajub Components
AdyenAdyen's encrypted card fields, inside Hosted Checkout or Wajub Components
MollieMollie's card fields, inside Hosted Checkout or Wajub Components
PayPalPayPal's card button and form, inside Hosted Checkout or Wajub Components
Paystack, Flutterwave, FedaPay, Paddle, PayDunya, CinetPay, KkiapayThe provider's payment window, opened on top of Hosted Checkout or Wajub Components

The mobile SDKs use Stripe's fields where Stripe handles the card, on iOS through the CardCollector your app writes with Stripe's SDK. For the other providers they open the provider's own payment page. Your servers never handle card data either, since they only create the payment and hand the payer a checkout.

Of a card that has been charged, two fragments survive on our side.

FragmentWhat it isWhat it is for
First eight digitsFirst eight digitsThe issuing BINRisk scoring, issuer and country signals
Last four digitsLast four digitsShown as **** 4242Letting a returning payer recognise their card

The digits in between are never written down. A saved payment method is a token plus those two fragments, never a number you could charge elsewhere.

Deleting a payer

DELETE /customers/{id} is a real erasure request, not a status change. It keeps a full copy in an archive, then anonymises the record and deletes it. If a step fails, nothing changes and the call answers 500.

StepWhat happens
The customer recordname becomes Deleted User {pseudonym}, every other identifying field is nulled
AddressesDeleted
Saved payment methodsDeleted
Transaction snapshotsPseudonymised, so the accounting still balances
InvoicesKept, still linked to the customer, with the name, email, phone, address and tax number replaced by a pseudonym
SearchThe customer can no longer be found by search, and searching their payments and invoices no longer returns their details
Recorded eventsThe customer's details are removed from the events already recorded, a payment's addresses and an invoice's copy of the customer included, so Konsole, GET /events and a replay show the anonymised record
Delivered webhooksThe body each delivery stored is cleaned the same way, so Konsole shows it cleaned and a retry sends it cleaned. A copy a Sync platform received is cleaned too
AnalyticsThe customer's data is deleted
ArchiveThe full copy is kept for 120 days, then permanently deleted
Audit trailThe anonymisation itself is recorded

Tax IDs are the one exception: they are kept when one of them has been verified, because a verified tax ID is identity evidence, and the obligation to keep it outlives the request.

The operation is idempotent

Repeating the call on a customer already erased answers the same 200 and never archives twice. It does finish what an earlier call left: a customer deleted but never anonymised is anonymised, and the cleaning of events and deliveries runs again in case it failed.

What already left Wajub cannot be called back: a webhook your endpoint received, or a payload a connected platform stored on its side, is yours or theirs to erase. With X-Sync, the call is refused with 403: erasing a customer is the merchant's decision, not a platform's.

Transactions themselves are not deleted. Their customer snapshot is pseudonymised and their link to the customer is removed, which leaves your books intact. The wallet or account number a payment was made with stays on that payment: it is part of the financial record that has to be kept.

Sandbox and live are separate systems

The key you authenticate with decides the environment. Sandbox and live share no data, even for keys of the same team.

The practical consequences show up as 404, not as a permission error. A live payment id looked up with a test key does not exist, and the reverse is equally true. Nothing crosses: not customers, not webhook endpoints, not events.

Verification gates live money

A team that has not passed compliance verification takes no live payment at all, whichever provider would carry it: Wajub's rails or your own Stripe, Paystack or other connection. Every live payment answers 402 with error_code: merchant_not_verified until the verification is approved; the next attempt after the approval goes through. Payouts answer 422 until then. Sandbox keeps working unchanged. Limits and quotas describes the account limits verification unlocks.

Reporting a vulnerability

Send it to security@wajub.com. The API, Konsole, the SDKs and this documentation site are all in scope. There is no public bounty programme, and disclosures are credited in the changelog when the reporter wants to be named.

Questionnaires, certifications and residency

Anything that belongs in a contract is answered by a person, not by this page: certification status and certificates, penetration test reports, data processing agreements, residency commitments, per-market licensing and the regulated partners behind each corridor.

Write to enterprise@wajub.com with the questionnaire you need completed.

What did you think of this content?