Skip to main content

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

  1. A Contro partner account with API keys
  2. 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:
IDElement
#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:
FieldValue
Card Number4000 0000 0000 0000
CVV123
Expiry12/2030
NameTEST 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