Skip to main content

Overview

The registerIntent() method creates a purchase instruction that the user authenticates with their Passkey. This intent acts as a permission for an AI agent to make a specific purchase on the user’s behalf.
Requires Passkey: This method always triggers biometric authentication to ensure the user explicitly authorizes the purchase.

Method Signature

prava.registerIntent(intent: PurchaseIntent): Promise<RegisteredIntent>

Parameters

intent
PurchaseIntent
required
Purchase instruction details

Return Value

result
RegisteredIntent

Example

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

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

// User says: "Buy me wireless earbuds under $100"
async function handlePurchaseRequest(userMessage: string) {
  // 1. Get user's cards
  const cards = await prava.listCards(sessionToken);
  const defaultCard = cards.find(c => c.is_default);

  if (!defaultCard) {
    return { error: 'No payment method available' };
  }

  // 2. Register intent (triggers Passkey)
  try {
    const intent = await prava.registerIntent({
      cardId: defaultCard.id,
      merchantName: 'Amazon',
      merchantUrl: 'https://amazon.com',
      merchantCategory: 'Electronics',
      merchantCategoryCode: '5732',
      declineThreshold: {
        amount: 100,
        currency: 'USD'
      },
      effectiveUntilTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), // 24 hours
      products: [
        {
          name: 'Wireless Earbuds',
          url: 'https://amazon.com/product/xyz',
          quantity: 1,
          amount: 79.99
        }
      ],
      consumerPrompt: 'Wireless earbuds under $100 from Amazon'
    });

    return {
      success: true,
      intentId: intent.intentId,
      message: 'Purchase authorized! Proceeding to checkout...'
    };
  } catch (error) {
    if (error.code === 'PASSKEY_CANCELLED') {
      return { error: 'User cancelled authorization' };
    }
    throw error;
  }
}

Passkey Authentication Flow

The Passkey prompt shows the consumerPrompt text, so make it clear and specific (e.g., “Wireless earbuds under $100” not just “Purchase”).

Under the Hood

When you call registerIntent():
1

Transaction Creation

Prava creates a transaction record with all purchase details (amount, merchant, products).
2

Challenge Generation

The backend generates a cryptographic challenge for WebAuthn.
3

Passkey Prompt

The user sees a biometric prompt with the consumerPrompt text and must authenticate.
4

Signature Verification

The signed assertion is verified to ensure it came from the registered device.
5

Card Network Registration

Prava securely submits the authenticated instruction to the card network for registration.
6

Mandate Creation

The card network returns identifiers that can be used to retrieve payment credentials later.

Intent Object Structure

The full intent object structure:
interface PurchaseIntent {
  // Required
  cardId: string;
  merchantName: string;
  declineThreshold: {
    amount: number;
    currency: string;
  };
  effectiveUntilTime: string; // ISO 8601
  consumerPrompt: string;

  // Optional but recommended
  merchantUrl?: string;
  merchantCategory?: string;
  merchantCategoryCode?: string; // MCC

  // Optional
  products?: {
    name: string;
    url?: string;
    quantity?: number;
    amount?: number;
  }[];
  mandateId?: string; // Auto-generated if omitted
}

Merchant Category Codes (MCC)

Common MCCs for scoping intents:
MCCCategoryExample
5732Electronics StoresBest Buy, Newegg
5651Family Clothing StoresGap, H&M
5411Grocery StoresWhole Foods, Trader Joe’s
5812Eating Places, RestaurantsChipotle, Starbucks
5661Shoe StoresNike, Foot Locker
5942Book StoresBarnes & Noble, Amazon Books
MCCs are enforced at the network level. If the merchant’s actual MCC doesn’t match, the payment will be declined.

Error Handling

error
PravaError

Common Errors

CodeCauseResolution
PASSKEY_CANCELLEDUser cancelled authenticationAllow retry or cancel flow
PASSKEY_FAILEDBiometric verification failedAsk user to retry
CARD_NOT_FOUNDCard ID is invalidRefresh card list
AMOUNT_EXCEEDS_LIMITAmount exceeds card/account limitReduce amount or use different card
MERCHANT_BLOCKEDMerchant is on blocklistChoose different merchant
INVALID_MCCMCC doesn’t match merchantVerify MCC code

Best Practices

1. Clear Consumer Prompts

// ✅ Good: Specific and clear
consumerPrompt: "Wireless Sony WH-1000XM5 headphones for $348"

// ❌ Bad: Too vague
consumerPrompt: "Purchase"

2. Reasonable Expiration Times

// ✅ Good: Near-term purchase
effectiveUntilTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString() // 24 hours

// ⚠️ Caution: Long expiration (use for subscriptions only)
effectiveUntilTime: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString() // 30 days

3. Accurate Product Details

// ✅ Good: Complete product information
products: [
  {
    name: 'Sony WH-1000XM5 Wireless Headphones',
    url: 'https://amazon.com/dp/B09XS7JWHH',
    quantity: 1,
    amount: 348.00
  }
]

// ❌ Bad: Missing details
products: [{ name: 'Headphones' }]

Security Considerations

Decline threshold is enforced by card network: Even if an agent tries to exceed the authorized amount, the network will decline the transaction.
MCC scoping prevents misuse: If you authorize electronics purchases, the credential cannot be used at restaurants or other categories.
Short expiration = less risk: Use the minimum necessary expiration time. For immediate purchases, 1 hour is sufficient.

Next Steps