Skip to main content

Overview

The removeCard() method permanently deletes an enrolled card. This operation requires Passkey authentication to prevent unauthorized card removal.
This action is irreversible. Once removed, the card must be re-enrolled to be used again.

Method Signature

prava.removeCard(cardId: string, options?: RemoveCardOptions): Promise<void>

Parameters

cardId
string
required
Unique identifier of the card to remove (from listCards())
options
RemoveCardOptions
Optional configuration

Return Value

Returns a Promise<void> that resolves when the card is successfully removed.

Example

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

function CardItem({ card }) {
  const [removing, setRemoving] = useState(false);

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

  async function handleRemove() {
    if (!confirm(`Remove card ending in ${card.last4}?`)) {
      return;
    }

    setRemoving(true);

    try {
      // This will trigger Passkey authentication
      await prava.removeCard(card.id, {
        reason: 'User requested removal'
      });

      alert('Card removed successfully');
      window.location.reload(); // Refresh card list
    } catch (error) {
      if (error.code === 'PASSKEY_CANCELLED') {
        alert('Card removal cancelled');
      } else {
        alert(`Failed to remove card: ${error.message}`);
      }
    } finally {
      setRemoving(false);
    }
  }

  return (
    <div className="card-item">
      <span>{card.brand} •••• {card.last4}</span>
      <button 
        onClick={handleRemove} 
        disabled={removing}
        className="btn-danger"
      >
        {removing ? 'Removing...' : 'Remove'}
      </button>
    </div>
  );
}

Passkey Authentication Flow

When you call removeCard(), the SDK automatically triggers a Passkey authentication challenge:
The Passkey prompt will show the user which card they’re removing and ask for biometric or PIN confirmation.

Use Cases

User-Initiated Removal

Let users manage their own cards:
function CardManagement() {
  const [cards, setCards] = useState([]);

  async function handleRemove(cardId) {
    try {
      await prava.removeCard(cardId);
      setCards(cards.filter(c => c.id !== cardId));
    } catch (error) {
      if (error.code === 'PASSKEY_CANCELLED') {
        // User cancelled, do nothing
        return;
      }
      showError(error.message);
    }
  }

  return (
    <div>
      {cards.map(card => (
        <CardItem
          key={card.id}
          card={card}
          onRemove={() => handleRemove(card.id)}
        />
      ))}
    </div>
  );
}

Security Breach Response

Remove all cards in case of a security incident:
async function removeAllCards() {
  const cards = await prava.listCards(sessionToken);
  
  const confirmed = confirm(
    `Remove all ${cards.length} card(s)? This action cannot be undone.`
  );

  if (!confirmed) return;

  const results = await Promise.allSettled(
    cards.map(card => prava.removeCard(card.id, {
      reason: 'Security precaution'
    }))
  );

  const removed = results.filter(r => r.status === 'fulfilled').length;
  const failed = results.filter(r => r.status === 'rejected').length;

  alert(`Removed ${removed} card(s). ${failed} failed.`);
}

Error Handling

error
PravaError

Common Errors

CodeCauseResolution
PASSKEY_CANCELLEDUser cancelled authenticationAllow user to retry
PASSKEY_FAILEDBiometric verification failedAsk user to retry
PASSKEY_NOT_AVAILABLEDevice doesn’t support PasskeyUse fallback auth method
CARD_NOT_FOUNDCard ID doesn’t existRefresh card list
CARD_IN_USECard has pending transactionsWait for transactions to settle
SESSION_EXPIREDSession token expiredCreate new session

Default Card Handling

If the removed card was the default, the next available card becomes default:
async function removeCardSafely(cardId) {
  const cards = await prava.listCards(sessionToken);
  const cardToRemove = cards.find(c => c.id === cardId);

  if (cardToRemove?.is_default && cards.length > 1) {
    // Warn user that another card will become default
    const confirmed = confirm(
      `This is your default card. ${cards[1].brand} ending in ${cards[1].last4} will become your new default. Continue?`
    );
    
    if (!confirmed) return;
  }

  await prava.removeCard(cardId);
}

Audit Logging

The reason parameter is stored in Prava’s audit logs:
// Good practices for audit trails
await prava.removeCard(cardId, {
  reason: 'User requested removal' // User-initiated
});

await prava.removeCard(cardId, {
  reason: 'Card expired' // Automatic cleanup
});

await prava.removeCard(cardId, {
  reason: 'Fraudulent activity detected' // Security
});

await prava.removeCard(cardId, {
  reason: 'Duplicate card' // Data quality
});

Security Considerations

Passkey required: Unlike listCards(), this method always requires Passkey authentication. There is no way to bypass this security measure.
Rate limiting: Repeated failed Passkey attempts may trigger rate limiting to prevent brute force attacks.
Best practice: Always show a confirmation dialog before calling removeCard() to prevent accidental deletions.

Testing in Sandbox

In sandbox mode, you can use a test Passkey:
// Sandbox automatically uses test Passkey
const prava = new PravaSDK({
  publishableKey: 'pk_sandbox_your_key',
  environment: 'sandbox'
});

// This will use mock authentication in sandbox
await prava.removeCard('card_test_123');

Next Steps