Skip to main content

Overview

The collectPAN() method securely collects credit card details from users through an isolated iframe. The card data is tokenized via PCI Data Vault and provisioned with card network, ensuring PCI compliance without card data ever touching your servers.

Method Signature

prava.collectPAN(options: CollectPANOptions): Promise<CollectPANResult>

Parameters

options
CollectPANOptions
required
Configuration options for card collection

Return Value

result
CollectPANResult

Example

import { useState } from 'react';
import { PravaSDK } from '@prava/sdk-core';

function CardEnrollment() {
  const [loading, setLoading] = useState(false);
  const [sessionToken, setSessionToken] = useState<string | null>(null);

  const prava = new PravaSDK({
    publishableKey: 'pk_sandbox_your_key',
    environment: 'sandbox'
  });

  // Get session token from your backend
  useEffect(() => {
    fetch('/api/create-session', { method: 'POST' })
      .then(r => r.json())
      .then(data => setSessionToken(data.session_token));
  }, []);

  const handleCollect = async () => {
    if (!sessionToken) return;

    setLoading(true);
    
    try {
      const result = await prava.collectPAN({
        sessionToken,
        container: '#card-form',
        onReady: () => {
          console.log('Form ready');
        },
        onChange: (state) => {
          console.log('Validation:', state);
        },
        onSuccess: (data) => {
          console.log('Card enrolled:', data.card_last4);
          // Navigate to success page or next step
        },
        onError: (error) => {
          console.error('Error:', error);
          setLoading(false);
        }
      });
    } catch (error) {
      console.error('Collection failed:', error);
      setLoading(false);
    }
  };

  return (
    <div>
      <div id="card-form"></div>
      <button onClick={handleCollect} disabled={loading || !sessionToken}>
        {loading ? 'Processing...' : 'Add Card'}
      </button>
    </div>
  );
}

Flow Diagram

Under the Hood

When you call collectPAN(), here’s what happens:
1

Iframe Injection

The SDK injects a secure, isolated iframe into your specified container. The iframe is served from Prava’s domain to ensure zero PCI scope.
2

Session Validation

The iframe validates the session token with Prava’s backend to ensure the request is legitimate and not expired.
3

User Input

The user enters their card details (number, expiry, CVV, name) in the iframe form with real-time validation.
4

PCI Data Vault Vaulting

When the user submits, the iframe sends the card data directly to PCI Data Vault for tokenization. Your servers never see the raw PAN.
5

Card Network Provisioning

Prava’s backend retrieves the encrypted payment instrument from PCI Data Vault and provisions a token with card network, binding it to the user’s device via FIDO.
6

Result

The enrollment result (with last4, brand, vProvisionedTokenID) is returned to your app.

Validation States

The onChange callback receives a CardValidationState object:
interface CardValidationState {
  valid: boolean;
  errors: {
    cardNumber?: string;
    expiry?: string;
    cvv?: string;
    name?: string;
  };
}

Error Handling

error
PravaError

Common Errors

CodeCauseResolution
SESSION_EXPIREDSession token expired (15 min)Create new session
SESSION_INVALIDInvalid or tampered session tokenVerify backend logic
INVALID_CARDCard failed Luhn check or formatUser re-enters card
CARD_DECLINEDIssuer declined enrollmentUser tries different card
NETWORK_ERRORConnection issueRetry after delay

Security Notes

Never attempt to bypass the iframe or collect card data directly. This breaks PCI compliance and exposes your infrastructure to liability.
The iframe uses Content Security Policy (CSP), Subresource Integrity (SRI), and strict origin validation to prevent XSS and data exfiltration.

Next Steps