PCI Compliant SDK
Browser SDK that collects and reveals card data inside Wirex-served iframes, so cardholder data never reaches your page.
Before You Start
Read the following guides before proceeding:
| Guide | Why |
|---|---|
| Getting Started | Platform overview and setup |
| Api Basics | Required headers and request configuration |
| Authentication | How to mint the user token the SDK authenticates with — see User Token Issuance (Login as User) |
| Environments | BaaS and PCI environment base URLs |
Overview
The PCI Compliant SDK is a set of npm packages for browser applications. Each package mounts one or more
iframes served from a Wirex-operated origin. The user types the card number, expiry and CVV inside those
iframes; the iframe posts the card data straight to Wirex and returns a token to your page. Your DOM, your
JavaScript and your servers never receive the PAN or the CVV.
Every frame authenticates with a user token — the per-user access token from
User Token Issuance (Login as User). The
SDK has no keys of its own, and S2S company tokens are not accepted. See
Which Token the SDK Needs.
Use it when your application collects or displays card data in a browser and you do not want that data in
your PCI scope. Everything the SDK produces — a card_id, an external card token, a completed 3DS
challenge — feeds the same REST flows documented in Card Top-Up,
Push to Card and Card Details.
Not the same package as the TypeScript SDK.
@wirexapp/wpay-baas-sdk
(TypeScript / JavaScript SDK) wraps the REST API and on-chain wallet operations. The
PCI Compliant SDK covers only card-data surfaces. The two are installed and versioned independently and
can be used together.
Version. These pages document
1.0.0, the first stable release of the family. Every package ships
under the@wirexappscope and releases in lockstep.
Packages
| Package | Produces | Guide |
|---|---|---|
@wirexapp/card-topup-web | cardId for an external top-up card | Collect a Top-Up Card |
@wirexapp/card-oct-web | externalCardId for a payout destination card | Collect a Payout Card |
@wirexapp/card-reveal-web | In-frame display of an issued card's PAN, expiry, CVV and PIN | Reveal Card Details |
@wirexapp/card-3ds-web | 3DS challenge outcome | 3DS Challenge Element |
@wirexapp/card-react | React components and hooks over all of the above | React Bindings |
@wirexapp/card-sdk-core | Shared foundation — installed automatically as a dependency | — |
@wirexapp/card-sdk-web | Umbrella package re-exporting every package above | SDK Setup |
All packages release in lockstep under one version number, because they share the frame message protocol.
The current release is 1.0.0. Your lockfile must show that same version for @wirexapp/card-sdk-core and
every @wirexapp/card-* package — a version mismatch makes the loader and the frame refuse to
communicate.
Isolation Model
Your page (no card data) Wirex frame origin Wirex API
──────────────────────── ────────────────── ─────────
npm package ─mounts─► card-field iframes
• creates the iframes • user types PAN / CVV
• receives events + tokens ◄────── • validates, detects brand
• POSTs card data direct ───► tokenize
your flow continues card token
with the token only ◄────────── token + brand / bin / last4 ◄──
The npm packages carry no cardholder data. The iframes are served by Wirex from a dedicated origin, so the
browser's Same-Origin Policy prevents any script on your page — including an XSS or a compromised
dependency — from reading the card fields.
Two properties are enforced by Wirex, not by your integration:
- The frames' API endpoints are injected server-side. A compromised host page cannot redirect card data to
another server. Selecting an environment is the only endpoint control you have. - The frames are served with a
frame-ancestorspolicy listing only the parent origins registered against
yourclientId. An unregistered origin renders an empty, browser-blocked frame.
Top-Up Collection Flow
sequenceDiagram
participant User as Cardholder
participant App as Your Page
participant Frame as Wirex Card Frames
participant BaaS as Wirex BaaS
App->>Frame: 1. mount card field iframes
User->>Frame: 2. type PAN / expiry / CVV / name
Frame-->>App: 3. change event (validity + brand only)
App->>Frame: 4. tokenizeTopUp (billing details)
Frame->>BaaS: 5. POST card data
BaaS-->>Frame: card_id
Frame-->>App: 6. cardId, brand, bin, last4
App->>BaaS: 7. POST /api/v1/cards/topup/estimate
App->>BaaS: 8. POST /api/v1/cards/topup/execute
BaaS-->>App: id, status, three_ds_state
App->>Frame: 9. mount 3DS challenge on three_ds_state.url
| Step | Action | Description |
|---|---|---|
| 1 | field(name).mount(container) | One iframe per card field, arranged by your layout |
| 2 | User input | Values stay inside the Wirex origin |
| 3 | onChange | complete, brand and per-field validity — never values |
| 4 | tokenizeTopUp(params) | Billing address is collected by your own form |
| 5 | Frame to Wirex | The only network call that carries card data |
| 6 | Tokenize result | cardId is the only value you store |
| 7 | POST /api/v1/cards/topup/estimate | Pass cardId as external_card_id |
| 8 | POST /api/v1/cards/topup/execute | Returns three_ds_state when a challenge is required |
| 9 | createThreeDsChallenge | Runs the issuer challenge in an iframe |
Payout Collection Flow
sequenceDiagram
participant User as Sender
participant App as Your Page
participant Frame as Wirex Card Frames
participant BaaS as Wirex BaaS
App->>Frame: 1. mount card-number iframe
User->>Frame: 2. type destination PAN
App->>Frame: 3. tokenizeOctDestination (cardholder name)
Frame->>BaaS: 4. POST card data
BaaS-->>Frame: card token
Frame-->>App: 5. externalCardId, brand, bin, last4
App->>BaaS: 6. POST /api/v2/recipients (type: Card)
App->>BaaS: 7. POST /api/v1/cards/transfer/estimate
App->>BaaS: 8. POST /api/v1/cards/transfer
| Step | Action | Description |
|---|---|---|
| 1 | field('number').mount(container) | The payout profile renders the card-number field only |
| 2 | User input | No CVV and no expiry are collected for a payout destination |
| 3 | tokenizeOctDestination(params) | Cardholder name and labels are collected by your own form |
| 4 | Frame to Wirex | The only network call that carries the PAN |
| 5 | Tokenize result | externalCardId is the card token |
| 6 | POST /api/v2/recipients | Pass externalCardId as card.card_id |
| 7 | POST /api/v1/cards/transfer/estimate | Pass externalCardId as external_card_id |
| 8 | POST /api/v1/cards/transfer | Executes the payout |
Reveal Flow
sequenceDiagram
participant User as Cardholder
participant App as Your Page
participant Frame as Wirex Reveal Frame
participant BaaS as Wirex BaaS
User->>App: 1. Request card details
App->>BaaS: 2. POST /api/v1/confirmation/signature/verify
BaaS-->>App: action_token
App->>Frame: 3. mount reveal element (cardId + actionToken)
Frame->>BaaS: 4. POST /api/v1/cards/{cardId}/details
Frame->>BaaS: 5. POST /api/v1/cards/{cardId}/cvv
BaaS-->>Frame: card_number, expiry_date, cvv
Frame-->>App: 6. onStateChange status ready
| Step | Action | Description |
|---|---|---|
| 1 | User request | Reveal is a short-lived, user-initiated view |
| 2 | POST /api/v1/confirmation/signature/verify | Mints a single-use action_token, valid 5 minutes |
| 3 | reveal.mount(container) | Values are fetched only after the frame verifies its init |
| 4–5 | Frame to Wirex | One call per requested row group; your page never sees the responses |
| 6 | onStateChange | loading, ready or error — never values |
Guides
| Guide | Description |
|---|---|
| SDK Setup | Onboarding inputs, environments, installation, CSP, going live |
| Collect a Top-Up Card | Card entry for top-up and the handover to the top-up API |
| Collect a Payout Card | Destination-card entry for push to card |
| Reveal Card Details | In-frame display of an issued card's PAN, expiry, CVV and PIN |
| 3DS Challenge Element | Running the issuer challenge returned by a card operation |
| Appearance and Localization | Whitelisted styling tokens, brand fonts, translated labels |
| React Bindings | Providers, field components and hooks |
| Events and Error Handling | Change events, failure modes, timeouts, element lifecycle |
Updated 10 days ago

