> ## Documentation Index
> Fetch the complete documentation index at: https://paypal-sb-staging.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Test card generator

export const CreditCardGenerator = () => {
  const CardTypes = {
    visa: {
      prefixList: ['403203'],
      digitCount: 16,
      cvvCount: 3,
      name: 'Visa'
    },
    mastercard: {
      prefixList: ['511092'],
      digitCount: 16,
      cvvCount: 3,
      name: 'Mastercard'
    },
    amex: {
      prefixList: ['34', '37'],
      digitCount: 15,
      cvvCount: 4,
      name: 'American Express'
    },
    discover: {
      prefixList: ['6011'],
      digitCount: 16,
      cvvCount: 3,
      name: 'Discover'
    },
    maestro: {
      prefixList: ['5018', '5020', '5038', '5893'],
      digitCount: 16,
      cvvCount: 3,
      name: 'Maestro'
    },
    jcb: {
      prefixList: ['353', '354', '355', '356', '357'],
      digitCount: 16,
      cvvCount: 3,
      name: 'JCB'
    },
    elo_br: {
      prefixList: ['506727', '636368'],
      digitCount: 16,
      cvvCount: 3,
      name: 'ELO (Brazil)'
    }
  };
  const currencyBinMap = {
    'USD_TYPE_CARD_VISA': '403203',
    'USD_TYPE_CARD_MASTERCARD': '511092',
    'GBP_TYPE_CARD_VISA': '469846',
    'GBP_TYPE_CARD_MASTERCARD': '542854',
    'GBP_TYPE_CARD_SWITCH': '675906',
    'EUR_TYPE_CARD_VISA': '402002',
    'EUR_TYPE_CARD_MASTERCARD': '523210',
    'AUD_TYPE_CARD_VISA': '423953',
    'AUD_TYPE_CARD_MASTERCARD': '512576',
    'CAD_TYPE_CARD_VISA': '421402',
    'CAD_TYPE_CARD_MASTERCARD': '531780',
    'JPY_TYPE_CARD_VISA': '452591',
    'JPY_TYPE_CARD_MASTERCARD': '528386',
    'MXN_TYPE_CARD_VISA': '416502',
    'MXN_TYPE_CARD_MASTERCARD': '547080',
    'MXN_TYPE_CARD_AMEX': '370786',
    'BRL_TYPE_CARD_VISA': '410863',
    'BRL_TYPE_CARD_MASTERCARD': '516230',
    'TRY_TYPE_CARD_VISA': '407461',
    'SGD_TYPE_CARD_VISA': '409636',
    'SGD_TYPE_CARD_MASTERCARD': '542113',
    'PLN_TYPE_CARD_VISA': '406333',
    'PLN_TYPE_CARD_MASTERCARD': '522471',
    'MYR_TYPE_CARD_VISA': '429312',
    'MYR_TYPE_CARD_MASTERCARD': '540007',
    'RUB_TYPE_CARD_VISA': '462758643',
    'RUB_TYPE_CARD_MASTERCARD': '527594',
    'RUB_TYPE_CARD_MAESTRO': '676280',
    'INR_TYPE_CARD_VISA': '486337',
    'INR_TYPE_CARD_MASTERCARD': '524178',
    'ILS_TYPE_CARD_VISA': '458043',
    'ILS_TYPE_CARD_MASTERCARD': '532610',
    'ILS_TYPE_CARD_AMEX': '375987',
    'KRW_TYPE_CARD_VISA': '411904',
    'KRW_TYPE_CARD_MASTERCARD': '515594',
    'KRW_TYPE_CARD_AMEX': '379183',
    'IDR_TYPE_CARD_VISA': '410505',
    'IDR_TYPE_CARD_MASTERCARD': '524125',
    'THB_TYPE_CARD_VISA': '453215',
    'THB_TYPE_CARD_MASTERCARD': '540492',
    'PHP_TYPE_CARD_VISA': '402822',
    'PHP_TYPE_CARD_MASTERCARD': '545143',
    'NOK_TYPE_CARD_VISA': '402960',
    'NOK_TYPE_CARD_MASTERCARD': '540123',
    'DKK_TYPE_CARD_VISA': '417577',
    'DKK_TYPE_CARD_MASTERCARD': '544756',
    'SEK_TYPE_CARD_VISA': '466554',
    'SEK_TYPE_CARD_MASTERCARD': '548945',
    'CHF_TYPE_CARD_VISA': '405911',
    'CHF_TYPE_CARD_MASTERCARD': '540108'
  };
  const countryCurrency = {
    'US': 'USD',
    'GB': 'GBP',
    'IT': 'EUR',
    'ES': 'EUR',
    'AU': 'AUD',
    'CA': 'CAD',
    'DE': 'EUR',
    'FR': 'EUR',
    'HK': 'HKD',
    'JP': 'JPY',
    'MX': 'MXN',
    'NL': 'EUR',
    'BR': 'BRL',
    'C2': 'USD',
    'NZ': 'NZD',
    'TR': 'TRY',
    'SG': 'SGD',
    'RU': 'RUB',
    'CH': 'CHF',
    'AT': 'EUR',
    'IN': 'USD',
    'PL': 'PLN',
    'MY': 'MYR',
    'IL': 'ILS',
    'BE': 'EUR',
    'LU': 'EUR',
    'FI': 'EUR',
    'CZ': 'CZK',
    'SK': 'EUR',
    'HU': 'HUF',
    'GR': 'EUR',
    'SE': 'SEK',
    'NO': 'NOK',
    'DK': 'DKK',
    'MA': 'USD',
    'DZ': 'USD',
    'TN': 'USD',
    'EG': 'USD',
    'JO': 'USD',
    'KW': 'USD',
    'BH': 'USD',
    'QA': 'USD',
    'SA': 'USD',
    'AE': 'USD',
    'OM': 'USD',
    'YE': 'USD',
    'AZ': 'USD',
    'TM': 'USD',
    'KG': 'USD',
    'TJ': 'USD',
    'KZ': 'USD',
    'KR': 'USD',
    'ZA': 'USD',
    'KE': 'USD',
    'IE': 'EUR',
    'PT': 'EUR',
    'CY': 'EUR',
    'MU': 'USD',
    'SN': 'USD',
    'SI': 'EUR',
    'LV': 'EUR',
    'EE': 'EUR',
    'AR': 'USD',
    'BO': 'USD',
    'CL': 'USD',
    'CO': 'USD',
    'CR': 'USD',
    'DO': 'USD',
    'GT': 'USD',
    'SV': 'USD',
    'HN': 'USD',
    'JM': 'USD',
    'PA': 'USD',
    'PE': 'USD',
    'UY': 'USD',
    'VE': 'USD',
    'ID': 'USD',
    'TH': 'THB',
    'RO': 'EUR',
    'AL': 'USD',
    'BA': 'USD',
    'BG': 'EUR'
  };
  const countries = [{
    code: 'US',
    name: 'United States of America'
  }, {
    code: 'AL',
    name: 'Albania'
  }, {
    code: 'DZ',
    name: 'Algeria'
  }, {
    code: 'AR',
    name: 'Argentina'
  }, {
    code: 'AU',
    name: 'Australia'
  }, {
    code: 'AT',
    name: 'Austria'
  }, {
    code: 'AZ',
    name: 'Azerbaijan'
  }, {
    code: 'BH',
    name: 'Bahrain'
  }, {
    code: 'BE',
    name: 'Belgium'
  }, {
    code: 'BO',
    name: 'Bolivia'
  }, {
    code: 'BA',
    name: 'Bosnia and Herzegovina'
  }, {
    code: 'BR',
    name: 'Brazil'
  }, {
    code: 'BG',
    name: 'Bulgaria'
  }, {
    code: 'CA',
    name: 'Canada'
  }, {
    code: 'CL',
    name: 'Chile'
  }, {
    code: 'C2',
    name: 'China'
  }, {
    code: 'CO',
    name: 'Colombia'
  }, {
    code: 'CR',
    name: 'Costa Rica'
  }, {
    code: 'CY',
    name: 'Cyprus'
  }, {
    code: 'CZ',
    name: 'Czech Republic'
  }, {
    code: 'DK',
    name: 'Denmark'
  }, {
    code: 'DO',
    name: 'Dominican Republic'
  }, {
    code: 'EG',
    name: 'Egypt'
  }, {
    code: 'SV',
    name: 'El Salvador'
  }, {
    code: 'EE',
    name: 'Estonia'
  }, {
    code: 'FI',
    name: 'Finland'
  }, {
    code: 'FR',
    name: 'France'
  }, {
    code: 'DE',
    name: 'Germany'
  }, {
    code: 'GR',
    name: 'Greece'
  }, {
    code: 'GT',
    name: 'Guatemala'
  }, {
    code: 'HN',
    name: 'Honduras'
  }, {
    code: 'HK',
    name: 'Hong Kong SAR China'
  }, {
    code: 'HU',
    name: 'Hungary'
  }, {
    code: 'IS',
    name: 'Iceland'
  }, {
    code: 'IN',
    name: 'India'
  }, {
    code: 'ID',
    name: 'Indonesia'
  }, {
    code: 'IE',
    name: 'Ireland'
  }, {
    code: 'IL',
    name: 'Israel'
  }, {
    code: 'IT',
    name: 'Italy'
  }, {
    code: 'JM',
    name: 'Jamaica'
  }, {
    code: 'JP',
    name: 'Japan'
  }, {
    code: 'JO',
    name: 'Jordan'
  }, {
    code: 'KZ',
    name: 'Kazakhstan'
  }, {
    code: 'KE',
    name: 'Kenya'
  }, {
    code: 'KW',
    name: 'Kuwait'
  }, {
    code: 'KG',
    name: 'Kyrgyzstan'
  }, {
    code: 'LV',
    name: 'Latvia'
  }, {
    code: 'LU',
    name: 'Luxembourg'
  }, {
    code: 'MY',
    name: 'Malaysia'
  }, {
    code: 'MU',
    name: 'Mauritius'
  }, {
    code: 'MX',
    name: 'Mexico'
  }, {
    code: 'MA',
    name: 'Morocco'
  }, {
    code: 'NL',
    name: 'Netherlands'
  }, {
    code: 'NZ',
    name: 'New Zealand'
  }, {
    code: 'NO',
    name: 'Norway'
  }, {
    code: 'OM',
    name: 'Oman'
  }, {
    code: 'PA',
    name: 'Panama'
  }, {
    code: 'PE',
    name: 'Peru'
  }, {
    code: 'PL',
    name: 'Poland'
  }, {
    code: 'PT',
    name: 'Portugal'
  }, {
    code: 'QA',
    name: 'Qatar'
  }, {
    code: 'RO',
    name: 'Romania'
  }, {
    code: 'SA',
    name: 'Saudi Arabia'
  }, {
    code: 'SN',
    name: 'Senegal'
  }, {
    code: 'SG',
    name: 'Singapore'
  }, {
    code: 'SK',
    name: 'Slovakia'
  }, {
    code: 'SI',
    name: 'Slovenia'
  }, {
    code: 'ZA',
    name: 'South Africa'
  }, {
    code: 'KR',
    name: 'South Korea'
  }, {
    code: 'ES',
    name: 'Spain'
  }, {
    code: 'SE',
    name: 'Sweden'
  }, {
    code: 'CH',
    name: 'Switzerland'
  }, {
    code: 'TJ',
    name: 'Tajikistan'
  }, {
    code: 'TN',
    name: 'Tunisia'
  }, {
    code: 'TR',
    name: 'Turkey'
  }, {
    code: 'TM',
    name: 'Turkmenistan'
  }, {
    code: 'AE',
    name: 'United Arab Emirates'
  }, {
    code: 'GB',
    name: 'United Kingdom'
  }, {
    code: 'UY',
    name: 'Uruguay'
  }, {
    code: 'VE',
    name: 'Venezuela'
  }, {
    code: 'YE',
    name: 'Yemen'
  }];
  const need3DsCountries = ['IN'];
  const getRandomInt = (max, min = 0) => {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  };
  const getLastDigit = (cardNumber, digitCount) => {
    const reversed = cardNumber.split('').reverse().map(Number);
    let sum = 0;
    let pos = 0;
    while (pos < digitCount - 1) {
      let odd = reversed[pos] * 2;
      if (odd > 9) odd -= 9;
      sum += odd;
      if (pos !== digitCount - 2) sum += reversed[pos + 1];
      pos += 2;
    }
    return ((Math.floor(sum / 10) + 1) * 10 - sum) % 10;
  };
  const generateCardData = (type, countryCode) => {
    const cardConfig = CardTypes[type];
    if (!cardConfig) return null;
    const currency = countryCurrency[countryCode] || 'USD';
    const binKey = currency + '_TYPE_CARD_' + type.toUpperCase();
    let prefix = currencyBinMap[binKey] || cardConfig.prefixList[getRandomInt(cardConfig.prefixList.length - 1)];
    let cardNumber = prefix;
    while (cardNumber.length < cardConfig.digitCount - 1) {
      cardNumber += getRandomInt(9);
    }
    cardNumber += getLastDigit(cardNumber, cardConfig.digitCount);
    const is3ds = need3DsCountries.includes(countryCode);
    const currYear = new Date().getFullYear();
    let expiryMonth, expiryYear;
    if (is3ds) {
      expiryMonth = '01';
      expiryYear = currYear + 1;
    } else {
      expiryMonth = String(getRandomInt(12, 1)).padStart(2, '0');
      expiryYear = currYear + getRandomInt(5, 1);
    }
    const cvvMax = cardConfig.cvvCount === 4 ? 9999 : 999;
    const cvv = String(getRandomInt(cvvMax)).padStart(cardConfig.cvvCount, '0');
    return {
      cardNumber,
      expiryDate: expiryMonth + '/' + expiryYear,
      cvv,
      cardType: cardConfig.name
    };
  };
  const [cardType, setCardType] = useState('visa');
  const [country, setCountry] = useState('US');
  const [card, setCard] = useState(null);
  const [copiedField, setCopiedField] = useState(null);
  useEffect(() => {
    setCard(generateCardData(cardType, country));
  }, []);
  const handleGenerate = () => {
    setCard(generateCardData(cardType, country));
  };
  const copyToClipboard = (text, field) => {
    navigator.clipboard.writeText(text);
    setCopiedField(field);
    setTimeout(() => setCopiedField(null), 2000);
  };
  return <div style={{
    padding: '20px',
    backgroundColor: '#f9fafb',
    borderRadius: '12px',
    border: '1px solid #e5e7eb'
  }}>
      <div style={{
    marginBottom: '16px'
  }}>
        <label style={{
    display: 'block',
    fontSize: '14px',
    fontWeight: '500',
    marginBottom: '6px',
    color: '#374151'
  }}>
          Card type
        </label>
        <select value={cardType} onChange={e => setCardType(e.target.value)} style={{
    width: '100%',
    padding: '10px 12px',
    fontSize: '14px',
    border: '1px solid #d1d5db',
    borderRadius: '8px',
    backgroundColor: 'white',
    cursor: 'pointer',
    marginBottom: '12px'
  }}>
          <option value="visa">Visa</option>
          <option value="mastercard">Mastercard</option>
          <option value="amex">American Express</option>
          <option value="discover">Discover</option>
          <option value="maestro">Maestro</option>
          <option value="jcb">JCB</option>
          <option value="elo_br">ELO (Brazil)</option>
        </select>
      </div>

      <div style={{
    marginBottom: '16px'
  }}>
        <label style={{
    display: 'block',
    fontSize: '14px',
    fontWeight: '500',
    marginBottom: '6px',
    color: '#374151'
  }}>
          Country
        </label>
        <select value={country} onChange={e => setCountry(e.target.value)} style={{
    width: '100%',
    padding: '10px 12px',
    fontSize: '14px',
    border: '1px solid #d1d5db',
    borderRadius: '8px',
    backgroundColor: 'white',
    cursor: 'pointer',
    marginBottom: '12px'
  }}>
          {countries.map(c => <option key={c.code} value={c.code}>{c.name}</option>)}
        </select>
      </div>

      <button onClick={handleGenerate} style={{
    width: '100%',
    padding: '12px 16px',
    fontSize: '14px',
    fontWeight: '600',
    color: 'white',
    backgroundColor: '#0070ba',
    border: 'none',
    borderRadius: '8px',
    cursor: 'pointer'
  }}>
        Generate Credit Card
      </button>

      {card && <div style={{
    marginTop: '20px',
    padding: '16px',
    backgroundColor: 'white',
    border: '1px solid #e5e7eb',
    borderRadius: '8px'
  }}>
          <h4 style={{
    fontSize: '14px',
    fontWeight: '600',
    marginBottom: '12px',
    color: '#1f2937'
  }}>
            Generated credit card details
          </h4>

          <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: '8px 0',
    borderBottom: '1px solid #f3f4f6'
  }}>
            <span style={{
    fontSize: '13px',
    color: '#6b7280'
  }}>Card number</span>
            <div style={{
    display: 'flex',
    alignItems: 'center',
    gap: '8px'
  }}>
              <code style={{
    fontSize: '14px',
    fontWeight: '500'
  }}>{card.cardNumber}</code>
              <button onClick={() => copyToClipboard(card.cardNumber, 'cardNumber')} style={{
    padding: '4px 10px',
    fontSize: '12px',
    backgroundColor: copiedField === 'cardNumber' ? '#d1fae5' : '#f3f4f6',
    color: copiedField === 'cardNumber' ? '#059669' : '#374151',
    border: 'none',
    borderRadius: '4px',
    cursor: 'pointer'
  }}>
                {copiedField === 'cardNumber' ? 'Copied!' : 'Copy'}
              </button>
            </div>
          </div>

          <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: '8px 0',
    borderBottom: '1px solid #f3f4f6'
  }}>
            <span style={{
    fontSize: '13px',
    color: '#6b7280'
  }}>Expiry date</span>
            <div style={{
    display: 'flex',
    alignItems: 'center',
    gap: '8px'
  }}>
              <code style={{
    fontSize: '14px',
    fontWeight: '500'
  }}>{card.expiryDate}</code>
              <button onClick={() => copyToClipboard(card.expiryDate, 'expiry')} style={{
    padding: '4px 10px',
    fontSize: '12px',
    backgroundColor: copiedField === 'expiry' ? '#d1fae5' : '#f3f4f6',
    color: copiedField === 'expiry' ? '#059669' : '#374151',
    border: 'none',
    borderRadius: '4px',
    cursor: 'pointer'
  }}>
                {copiedField === 'expiry' ? 'Copied!' : 'Copy'}
              </button>
            </div>
          </div>

          <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: '8px 0'
  }}>
            <span style={{
    fontSize: '13px',
    color: '#6b7280'
  }}>CVC code</span>
            <div style={{
    display: 'flex',
    alignItems: 'center',
    gap: '8px'
  }}>
              <code style={{
    fontSize: '14px',
    fontWeight: '500'
  }}>{card.cvv}</code>
              <button onClick={() => copyToClipboard(card.cvv, 'cvv')} style={{
    padding: '4px 10px',
    fontSize: '12px',
    backgroundColor: copiedField === 'cvv' ? '#d1fae5' : '#f3f4f6',
    color: copiedField === 'cvv' ? '#059669' : '#374151',
    border: 'none',
    borderRadius: '4px',
    cursor: 'pointer'
  }}>
                {copiedField === 'cvv' ? 'Copied!' : 'Copy'}
              </button>
            </div>
          </div>
        </div>}
    </div>;
};

<CreditCardGenerator />
