Overview

The nekuda Card Management system enables your users to securely save and manage multiple payment methods. The frontend SDK collects and tokenizes card information, while your backend uses the stored cards with your secret key to handle information through your AI agents or automated workflows.
Key Benefits:
Secure Storage: Cards are tokenized and linked to user IDs you manage
Multiple Cards: Users can save and manage multiple payment methods
PCI Compliant: Card details are tokenized and never touch your servers
Backend Processing: Use stored cards in your agentic workflows with secret key
Important: The frontend SDK only collects and stores payment information. Actual information handling happens on your backend using the nekuda backend SDK with your secret API key. Never expose your secret key in frontend code.

Understanding User IDs

User IDs are the key to linking saved cards with your users. You must generate and manage these IDs in your system:
// Example: Generate user ID when user signs up or logs in
function App() {
  // You generate and manage user IDs - they can be:
  // - Your database user IDs
  // - Session IDs
  // - Any unique identifier for your users
  const userId = getCurrentUserId(); // e.g., "user_abc123", "12345", etc.

  return (
    <NekudaWalletProvider
      publicKey="pk_test_..." // Your publishable key (safe for frontend)
      userId={userId}         // Your user's unique ID
    >
      {/* Your app */}
    </NekudaWalletProvider>
  );
}
Best Practices for User IDs:
  • Use stable, persistent IDs (not session tokens that change)
  • Store the mapping between your user records and nekuda user IDs
  • Use the same user ID across sessions for returning users
  • Consider using your existing user database IDs

Installation

The card management component is included in the main SDK package:
npm install @nekuda/react-nekuda-js

Quick Integration

Step 1: Import Required Components

import {
  NekudaWalletProvider,
  NekudaCardManagement
} from '@nekuda/react-nekuda-js';

Step 2: Implement Card Management

function PaymentSettings() {
  const userId = getCurrentUserId(); // Your user ID management
  
  const handleCardSave = (card) => {
    console.log('Card saved:', card);
    // Handle successful card save
  };

  const handleCardDelete = (cardId) => {
    console.log('Card deleted:', cardId);
    // Handle card deletion
  };

  const handleDefaultCardSet = (cardId) => {
    console.log('Default card set:', cardId);
    // Handle default card selection
  };

  return (
    <NekudaWalletProvider
      publicKey="pk_test_..."
      userId={userId}
    >
      <NekudaCardManagement
        open={true}
        onCardSave={handleCardSave}
        onCardDelete={handleCardDelete}
        onDefaultCardSet={handleDefaultCardSet}
      />
    </NekudaWalletProvider>
  );
}

Component API Reference

<NekudaCardManagement>

The main card management component that provides a complete UI for managing payment methods.
open
boolean
Controls the visibility of the card management modal. When used without onOpenChange, the component renders inline.
onOpenChange
function
Callback function to control modal open/close state. Signature: (open: boolean) => void
onAddCardClick
function
Called when the “Add Card” button is clicked. Useful for updating prefill data or tracking user interactions.
onCardsUpdated
function
Called whenever the cards list changes (add, update, delete, or set default). Receives the updated array of saved cards.
onCardSave
function
Called when a new card is successfully saved. Receives the saved card object.
onCardUpdate
function
Called when an existing card is updated. Receives the updated card object.
onCardDelete
function
Called when a card is deleted. Receives the deleted card ID.
onDefaultCardSet
function
Called when a default card is set. Receives the card ID.
defaultCardDetails
object
Pre-fill data for the add card form. When provided, these values will populate the form fields when adding a new card. The data is consumed after being used once. Supports fields like email, billing_address, city, state, zip_code, and phone_number.
onDefaultCardDetailsConsumed
function
Called when the default card details have been consumed and applied to the form. Useful for clearing or updating the prefill data.
className
string
Optional CSS class name for custom styling.
style
object
Optional inline styles for the component.
styles
object
Base typography and font styling for the component. Includes fontFamily and fontSize.
elementsConfig
object
Styling configuration for individual form elements (cardNumber, cardExpiry, cardCvv, etc.). Each element accepts base and focus style states.
walletStyles
object
Theming styles for wallet components including modal, cardItem, and button (with primary, secondary, ghost variants).

Saved Card Object Structure

When cards are saved or retrieved, they follow this structure:
interface SavedCard {
  id: string;           // Unique card identifier
  last4: string;        // Last 4 digits of card number
  expiry: string;       // Card expiry date (MM/YY)
  brand: string;        // Card brand (visa, mastercard, etc.)
  holderName: string;   // Cardholder name
  isDefault: boolean;   // Whether this is the default card
}

Frontend Collection vs Backend Processing

The nekuda system separates payment collection (frontend) from information handling (backend):
1

Frontend: Collect & Store Cards

Use the React SDK to securely collect and tokenize payment information. Cards are stored and linked to user IDs.
2

Backend: Retrieve Payment Methods

Your backend uses the secret API key to retrieve stored cards and handle payments through your AI agents or automated workflows.

Usage Patterns

// Let users manage their saved payment methods
function PaymentSettings() {
  const userId = getCurrentUserId(); // Your user ID

  return (
    <NekudaWalletProvider
      publicKey="pk_test_..."
      userId={userId}
    >
      <NekudaCardManagement
        onCardSave={(card) => {
          console.log('Card saved for user:', userId);
          // Card is now available for backend to retrieve
        }}
      />
    </NekudaWalletProvider>
  );
}

Security Considerations

Important Security Notes:
• Card numbers are tokenized immediately upon entry
• Only the last 4 digits are stored for display purposes
• CVV is never stored and must be re-entered for each transaction
• All card data transmission occurs over secure, encrypted channels

PCI Compliance

The card management system maintains PCI compliance by:
  1. Tokenization: Sensitive card data is converted to secure tokens
  2. Iframe Isolation: Card inputs are rendered in secure iframes
  3. No Raw Card Storage: Your servers never receive or store actual card numbers
  4. Secure Communication: All data transmission uses TLS encryption

Styling

The NekudaCardManagement component supports comprehensive styling through the nekuda three-prop styling system:
  • styles - Base typography configuration
  • elementsConfig - Form element styling (for add/edit card forms)
  • walletStyles - Component theming for modal, card items, and buttons
For complete styling examples including dark themes and design system integration, see the Customization Guide.

Quick Example

<NekudaCardManagement
  styles={{ fontFamily: '"Inter", sans-serif', fontSize: '14px' }}
  walletStyles={{
    modal: { backgroundColor: '#fff', color: '#111827' },
    cardItem: { backgroundColor: '#fff', border: '1px solid #e5e7eb' },
    button: {
      primary: { backgroundColor: '#3b82f6', color: '#fff' }
    }
  }}
/>

Error Handling

The card management component handles errors gracefully with user-friendly messages:
function PaymentSettingsWithErrorHandling() {
  const [error, setError] = useState(null);

  return (
    <NekudaWalletProvider
      publicKey="YOUR_KEY"
      userId="user_123"
      onError={(errorInfo) => {
        if (errorInfo.apiError) {
          // Handle API errors (network, auth, etc.)
          setError(errorInfo.apiError.userMessage);
        }
      }}
    >
      {error && <Alert type="error">{error}</Alert>}

      <NekudaCardManagement
        onCardSave={(card) => {
          setError(null); // Clear any previous errors
          // Handle successful save
        }}
      />
    </NekudaWalletProvider>
  );
}

Best Practices

1

Provide Clear Feedback

Always show loading states and success/error messages for card operations.
2

Confirm Destructive Actions

The component includes built-in confirmation dialogs for card deletion.
3

Handle Edge Cases

Consider scenarios like expired cards, declined cards, and network failures.
4

Secure Your Implementation

Always use HTTPS in production and validate user permissions server-side.

Next Steps