Prerequisites:
nekuda Account: Sign up for a nekuda account and obtain your API Keys from the nekuda Dashboard.

This guide walks you through setting up both frontend payment collection and backend payment handling using the nekuda SDKs. The primary API endpoint is https://api.nekuda.ai.

Overview

nekuda provides two complementary SDKs:

  1. Frontend SDK (@nekuda/react-nekuda-js) - Securely collect payment details in your UI. This is typically a JavaScript library.
  2. Backend SDK (nekuda) - Handle payments and reveal card details on your server. This guide focuses on the Python nekuda package.
1

Frontend: Collect Payment Details

Use the @nekuda/react-nekuda-js to securely capture credit card information from the user and obtain a payment token or reference.

2

Backend: Handle Payments

Use the Python nekuda SDK on your server to:

  1. Create a mandate (user’s intent to purchase) using a user_id.
  2. Request a card reveal token using the mandate_id obtained from mandate creation.
  3. Reveal card details using the token to complete the payment process in a guest checkout page.

Crucial Workflow Notes for Backend SDK (nekuda):

  • A unique user_id (string) identifying your end-user must be provided when creating a UserContext (client.user(user_id)).
  • A MandateData object describing the purchase must be created and sent to the API via user.create_mandate(mandate_data) to obtain a mandate_id.
  • This mandate_id is then required to request a reveal_token via user.request_card_reveal_token(mandate_id).

Frontend Setup: Collect Payment Details

First, install the wallet SDK for your frontend (details usually found in its specific documentation):

npm install @nekuda/react-nekuda-js

Set up payment collection in your React application (example):

import React, { useState } from 'react';
import {
  NekudaWalletProvider,
  useNekudaWallet,
  NekudaPaymentForm
} from '@nekuda/react-nekuda-js'; // Assuming this is the correct import

function PaymentCollectionComponent() {
const [processing, setProcessing] = useState(false);
const [paymentSubmission, setPaymentSubmission] = useState(null);
const { elements } = useNekudaWallet(); // Hook from the wallet SDK
const userIdForNekuda = "user_frontend_example_123"; // Match this with backend user_id

const handleSubmit = async (event) => {
event.preventDefault();
if (!elements || processing) return;

    setProcessing(true);
    try {
      // The .submit() method on elements would typically handle talking to nekuda
      // to tokenize card details and might involve the userId.
      const result = await elements.submit(); // This is a conceptual example
      setPaymentSubmission(result); // result might contain a token or confirmation

      // Send the result (e.g., token, user_id) to your backend for processing with the Python nekuda SDK
      await fetch('/api/process-payment-with-nekuda', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          nekudaPaymentData: result, // Contains token/reference from frontend SDK
          userId: userIdForNekuda,
          amount: 49.99,
          currency: 'USD',
          productDescription: 'Frontend Purchase Example'
        })
      });
      alert('Payment data sent to backend!');
    } catch (err) {
      console.error('Frontend Payment SDK error:', err);
      alert('Payment collection failed.');
    }
    setProcessing(false);

};

return (

<NekudaPaymentForm>
  {" "}
  {/* This component would render the card input fields */}
  <button
    type="button"
    onClick={handleSubmit}
    disabled={!elements || processing}
  >
    {processing
      ? "Collecting Card Details..."
      : "Submit Card for Backend Processing"}
  </button>
</NekudaPaymentForm>
); }

Replace pk_live_your_public_key_here with your actual Public Key from the nekuda Dashboard. Never expose your Secret Key (sk_live_...) in frontend code. The user_id used in the frontend SDK provider should match the user_id used in your backend nekuda SDK calls for the same user.

Backend Setup: Process Payments with Python nekuda SDK

Install the Python nekuda package on your server:

uv pip install nekuda

Set up your backend (e.g., FastAPI) to handle payments using data from your frontend and the nekuda SDK.

from fastapi import FastAPI, HTTPException
from nekuda import NekudaClient, MandateData, NekudaError # Python SDK
import os
from pydantic import BaseModel

app = FastAPI()

# Initialize the nekuda Python client (recommended: from environment)

# Ensure NEKUDA_SECRET_KEY and optionally NEKUDA_BASE_URL are set.

# NEKUDA_BASE_URL defaults to https://api.nekuda.ai

nekuda_client = NekudaClient.from_env()

class PaymentProcessingRequest(BaseModel):
nekudaPaymentData: dict # Data from frontend SDK (e.g., a token)
userId: str
amount: float
currency: str
productDescription: str

@app.post("/api/process-payment-with-nekuda")
async def process_payment_with_nekuda(request_data: PaymentProcessingRequest):
user_id = request_data.userId
user_context = nekuda_client.user(user_id)

    try:
        # Step 1: Create a Mandate (user's intent to purchase)
        # This uses the user_id provided from the frontend, which should match the one
        # used during the frontend SDK initialization for this user.
        print(f"Creating mandate for user: {user_id}")
        mandate_details = MandateData(
            product=request_data.productDescription,
            price=request_data.amount,
            currency=request_data.currency,
            merchant="Your Awesome Store"
        )
        mandate_response = user_context.create_mandate(mandate_details)
        print(f"Mandate {mandate_response.mandate_id} created for user {user_id}.")

        # Step 2: Request a card reveal token using the mandate_id.
        # The nekudaPaymentData from frontend might be used here if it contains a reference
        # that nekuda backend needs, or it might have already been used by the frontend SDK
        # to store the card against the user_id.
        # For this example, we assume card details were collected by frontend SDK and associated
        # with the user_id, and now we are proceeding with that context.
        print(f"Requesting reveal token for mandate: {mandate_response.mandate_id}")
        reveal_token_response = user_context.request_card_reveal_token(
            mandate_id=mandate_response.mandate_id
        )
        print(f"Reveal token obtained: {reveal_token_response.reveal_token[:10]}...")

        # Step 3: Reveal actual card details using the token.
        print("Revealing card details...")
        card_details = user_context.reveal_card_details(
            reveal_token=reveal_token_response.reveal_token
        )
        print(f"Card details revealed: **** **** **** {card_details.card_number[-4:]}")

        # Step 4: Process payment with the actual card details.
        # This is where you'd integrate with your payment processor (Stripe, Braintree, etc.)
        # using card_details.card_number, card_details.card_expiry_date, etc.
        print(f"Simulating payment processing for {card_details.cardholder_name}...")
        # payment_processor.charge(card_details, request_data.amount, request_data.currency)

        return {
            "success": True,
            "transaction_id": f"nekuda_txn_{mandate_response.mandate_id}",
            "message": "Payment processed successfully via nekuda flow."
        }

    except NekudaError as e:
        print(f"nekuda SDK Error for user {user_id}: {e}")
        # Provide specific error messages based on e.code or e.status_code
        raise HTTPException(status_code=400, detail=f"Payment processing failed: {str(e)}")
    except Exception as e:
        print(f"Generic Error for user {user_id}: {e}")
        raise HTTPException(status_code=500, detail="An unexpected error occurred.")

Environment Variables (Backend)

Set these environment variables on your server where the Python nekuda SDK runs:

.env
NEKUDA_SECRET_KEY=sk_live_your_secret_key_here # Your Secret Key from app.nekuda.ai
# NEKUDA_BASE_URL=https://api.nekuda.ai  # Optional, defaults to production API

Always keep your Secret Key (sk_live_...) secure on your backend. Never expose it in client-side code or public repositories. The API endpoint https://api.nekuda.ai is the standard for production.

Complete Backend Flow Example (Python nekuda SDK)

Here’s a standalone Python example focusing on the nekuda SDK’s role after user and payment intent (mandate) information is known.

complete_nekuda_sdk_flow.py
from nekuda import NekudaClient, MandateData, NekudaError
import os

# Ensure NEKUDA_SECRET_KEY is set in your environment
# client = NekudaClient.from_env() # Recommended
# For explicit local testing if env var not set:
client = NekudaClient(api_key=os.getenv("NEKUDA_SECRET_KEY", "sk_test_fallback_key"))

user_id_for_flow = "user_python_example_789"
user = client.user(user_id_for_flow)

try:
    # Step 1: Create a mandate for the purchase.
    # A user_id must be associated with this mandate via the user context.
    mandate_payload = MandateData(
        product="Super Gadget Pro",
        price=149.99,
        currency="EUR",
        merchant="Test Merchant Inc.",
        product_description="The best super gadget for professionals."
    )

    print(f"Creating mandate for user '{user_id_for_flow}'...")
    mandate_response = user.create_mandate(mandate_payload)
    print(f"✅ Mandate created: {mandate_response.mandate_id} (Request ID: {mandate_response.request_id})")

    # Step 2: Request a card reveal token using the mandate_id.
    # This mandate_id comes from the successful mandate creation above.
    print(f"Requesting card reveal token for mandate ID: {mandate_response.mandate_id}...")
    reveal_response = user.request_card_reveal_token(
        mandate_id=mandate_response.mandate_id
    )
    print(f"🔑 Reveal token: {reveal_response.reveal_token[:20]}... (Expires: {reveal_response.expires_at or 'N/A'})")

    # Step 3: Reveal actual card details using the token.
    # The token is single-use and typically short-lived.
    print("Revealing card details...")
    card_details = user.reveal_card_details(
        reveal_token=reveal_response.reveal_token
    )

    # Step 4: Use card details (e.g., with a payment processor).
    # For security, avoid logging full card details in production.
    print(f"💳 Card for {card_details.cardholder_name} revealed: **** **** **** {card_details.card_number[-4:]}, Expires: {card_details.card_expiry_date}")
    print("✅ nekuda SDK backend flow completed successfully!")

except CardNotFoundError as e:
    print(f"❌ Card Not Found for user '{e.user_id}': {e.message}. Ensure card was collected for this user ID.")
except InvalidRequestError as e:
    print(f"❌ Invalid Request to nekuda API: {e.message} (Code: {e.code}, HTTP Status: {e.status_code})")
except AuthenticationError as e:
    print(f"❌ nekuda Authentication Failed: {e.message}. Verify your NEKUDA_SECRET_KEY.")
except NekudaValidationError as e:
    print(f"❌ nekuda Data Validation Error: {e}.")
except NekudaApiError as e: # Catch other nekuda API errors
    print(f"❌ nekuda API Error: {e.message} (Code: {e.code}, HTTP Status: {e.status_code})")
except NekudaError as e: # Catch any other nekuda SDK specific error
    print(f"❌ A nekuda SDK error occurred: {e}")
except Exception as e:
    print(f"💥 An unexpected system error occurred: {e}")

Testing Your Integration

Use test API keys and card details from the nekuda Dashboard during development.

Next Steps

In production, ensure you are using your live API keys (pk_live_... and sk_live_...) obtained from app.nekuda.ai. Implement robust error handling, logging, and monitoring for all backend processes.