Qualpay Embedded Fields — Customization Lab

Live-tests every Embedded Fields config option and CSS override against the sandbox. Sandbox only — do not point this at production credentials.
⚠️ This page sends your Security Key as a Basic-Auth header directly from the browser (fine for sandbox testing, not how production should work — that call belongs on your server). Never point this page at production credentials.

1 Transaction Type

Six types tokenize a card through Embedded Fields first (steps 3–4 below load the frame). Three act on an existing transaction's pg_id instead — no card, no Embedded Fields frame needed at all. Batch Close needs neither. Endpoints confirmed from Qualpay's API reference.
Authorizes + captures in one step
Endpoint: POST /pg/sale

2 Credentials

SANDBOX
Pre-filled with the sandbox MID/key on file (matches qualpay-sale-test.html). API host: https://api-test.qualpay.com. Fields stay editable if you need to override.

3 Customize

Builds the config below — get a transient key in step 4 to load the frame with it.
Three distinct builds, confirmed live 2026-09-23: 1.0 AngularJS (deprecated framework, still what Sandbox/QA run) — 1.0 rebuilt on Angular (same features, new framework, Snapshot only) — 2.0 (new features on top of the rebuild, Snapshot only). The rebuild matters to test on its own, separately from 2.0's new features: if the rebuild changes behavior from AngularJS 1.0, that regression will ship to Sandbox/Production later even for merchants who never touch 2.0.
Set automatically from the environment toggle above plus the SDK version — each environment's iframe lives on a different app-{env}.qualpay.com host, and picking the wrong one gets a confusing "Invalid security key" (wrong env) or code 7: "The service called does not exist" (wrong SDK build). Still manually overridable here since this is what this control is for testing.
Per the Angular upgrade synthesis, the rebuilt engine now only accepts plain names (letters/numbers/spaces/hyphens) here — anything else is silently ignored and falls back to the default typeface (system font at 16px, previously Open Sans 14px).
Qualpay's docs describe this as CSS for "very general formatting" — reads like plain tag selectors (input, label), not Qualpay-specific class hooks. Presets below marked "guess" are a starting point — watch the live frame to confirm what actually applies. Per the Angular upgrade synthesis, the rebuilt engine now sanitizes/strips @import, non-HTTPS url(), and javascript: from this string before applying it — ordinary color/font/spacing rules are untouched. --qp-* variable names confirmed 2026-09-22 — read directly out of the live Snapshot demo's own stylesheet (not Qualpay's STYLING.md, which I still don't have — so it's unconfirmed these are the exact same variables the merchant-facing style config exposes, just the same naming system, found in the wild). See the "confirmed --qp-* vars" preset below.
Verbatim from Qualpay's own sample code, and independently corroborated by the Angular upgrade synthesis, which lists these among the settings unchanged in 1.0 and 2.0.
The synthesis doc also names paymentRequestConfig as an unchanged 1.0/2.0 setting (alongside a reCAPTCHA config) — it doesn't give that setting's inner shape, so it's not wired to a toggle here. Test it via "Advanced: raw config overrides" below once you have its shape.
"À la carte embedded fields" (rendering card number/expiry/CVV as separate individual fields instead of one combined form) is a real, named Qualpay feature — confirmed in Qualpay's release notes (a bugfix entry and a reCAPTCHA-support entry, both referencing it as an existing feature by 2019, still active per the July 13, 2021 note). But I could not find its config syntax (container IDs / loadFrame flag) in the current developer docs, an archived 2023 snapshot of the guide, or the release notes themselves — it isn't documented anywhere public I could reach. Rather than guess a plausible-sounding config key, use "Advanced: raw config overrides" below to test it once you have the real syntax (Paul, who maintains the Developer Center, is the most likely person to have it or know who does).
Merged shallowly on top of the built config right before loadFrame() is called. Invalid JSON is ignored (logged as an error).
These are guaranteed to work since they're plain CSS on this page, not inside Qualpay's iframe — useful for testing how the frame sits in your actual page layout/branding.
8px
16px
This button already calls unloadFrame() before loadFrame() every time — confirmed required on 1.0 by the Angular upgrade synthesis (skipping it can double-register submit handlers and submit twice). 2.0 is said to handle this automatically, but this page does it either way.
Any customer's actual checkout page can have its own CSS sitting around Embedded Fields — global resets, dark themes, unusual fonts, aggressive * selectors. Because the fields render in a cross-origin iframe (app.qualpay.com), this page CSS cannot reach inside the fields themselves — but it applies to everything around them: the #qp-embedded-container div, its layout, sizing, fonts. Paste a customer's real page CSS (or one of the presets) below to see what actually breaks — this is separate from and additional to Qualpay's own style config above.
This never touches Qualpay's config or reloads the frame — it only edits this page's own <style>, exactly like a merchant's site CSS would. If it visually wrecks the whole page, that's expected — click "Remove Page CSS" or reload.
This button reproduces a real bug found testing on Sandbox — it sets up the exact conditions, gets a fresh transient key, and reloads the frame. Re-run it after a fix ships to check whether it's actually resolved. Full write-up: "Embedded Fields 2.0 Styling Test Checklist.md".
Bug 2 — documented dark-mode fix doesn't fix the white box
Simulates a merchant's dark-themed page, then applies Qualpay's own documented fix (:root { color-scheme: dark; }) in the style config. Broken today = the box around the fields stays solid opaque white against the dark page. Fixed would look like: the box blends into the dark background (or at least isn't a stark white rectangle).

4 Get Transient Key

GET /platform/embedded — issues a single-use key (expires in 30 min per Qualpay's docs) used to load the frame with whatever you set up in step 3. You can reload the frame with new customizations as many times as you want on the same key — you only need a new one after it expires or after a successful tokenization.
Config being sent to loadFrame()
(click "Apply & Reload Frame" to load)
Transaction types you can run with the card_id / token
Embedded Fields only tokenizes the card (returns card_id) — the transaction type is chosen in your server-side Payment Gateway call, not in the loadFrame() config. All confirmed from Qualpay's API reference.
TypeEndpointWhat it does
SalePOST /pg/saleAuthorizes + captures in one step
AuthorizationPOST /pg/authSends to issuer for approval only
TokenizePOST /pg/tokenizeStores card/ACH info as a reusable token
VerifyPOST /pg/verifySends to issuer for verification only
CapturePOST /pg/capture/{pgIdOrig}Captures a prior authorization
VoidPOST /pg/void/{pgIdOrig}Cancels an authorized transaction
CreditPOST /pg/creditNon-referenced credit to a cardholder
RefundPOST /pg/refund/{pgIdOrig}Full/partial refund of a captured transaction
ForcePOST /pg/forceForces a declined transaction in (voice/ARU auth)
Batch ClosePOST /pg/batchCloseImmediately closes the open batch
Sandbox test cards / CVV / amounts
CardNumber
Visa (debit)4111 1111 1111 1111
Visa (consumer credit)4212 2222 2222 2222
Mastercard (consumer credit)5544 6666 6666 6664
Discover6011 0011 2211 1117
Amex3714 496353 92376
Any future expiration date and any 3-digit CVV work. Full list in Qualpay's test conventions doc.

5 Run Transaction

Payment Gateway endpoints have no CORS headers (confirmed — same as qualpay-sale-test.html), so this browser call is expected to be blocked. On failure, a ready-to-run curl command appears below instead.

Request / Response Log

Ready.