Overview
Partners who are not PCI DSS compliant can display sensitive card data to end-users using a Contro-hosted HTML widget embedded in an iframe. Sensitive data never reaches your servers - reducing PCI scope to SAQ-A .
If your organization is PCI DSS compliant and you prefer full UI control, use the direct API method instead.
Prerequisites
A Contro partner account with API keys
Configure your allowed origins in the partner dashboard https://partner.contro.me/settings - this controls which domains can embed the iframe
Step 1: Generate a reveal URL
Call the reveal-html endpoint to get a short-lived, single-use signed URL:
curl -X POST https://api.contro.me/v1/partner/cards/{card_id}/reveal-html \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"stylesheetUrl": "https://cdn.example.com/card-widget.css",
"copyPan": true
}'
Response:
{
"accessUrl" : "https://api.contro.me/v1/web/partner-card-details?token=eyJ..."
}
The URL expires after 60 seconds and can only be used once . Generate a fresh URL each time the user opens the card reveal UI.
Step 2: Embed the iframe
< iframe
src = "ACCESS_URL_FROM_STEP_1"
width = "400"
height = "300"
frameborder = "0"
allow = "clipboard-write"
></ iframe >
The clipboard-write permission allows users to copy card fields to their clipboard.
Step 3: Custom styling (optional)
Pass a stylesheetUrl in the request body to apply custom CSS. The stylesheet must be served over HTTPS.
The widget exposes these DOM IDs for styling:
ID Element #card-dataMain container #pan-divCard number field container #expiry-divExpiry date field container #cvv-divCVV field container #pan-valueCard number value #expiry-valueExpiry date value #cvv-valueCVV value
Sandbox testing
Use sk_test_ API keys to generate sandbox URLs. The widget displays test data with a visible SANDBOX badge:
Field Value Card Number 4000 0000 0000 0000CVV 123Expiry 12/2030Name TEST CARDHOLDER
Security
CSP headers : The widget sets strict Content-Security-Policy headers including frame-ancestors restricted to your configured allowed origins
Allowed origins : Configure via dashboard Settings. In production, unconfigured origins result in frame-ancestors 'none' (iframe blocked)
Single-use tokens : Each URL can only be loaded once - replay attacks are rejected
60-second expiry : Tokens expire quickly to minimize the attack window