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
Purchase instruction details ID of the enrolled card to use (from listCards())
Name of the merchant (e.g., “Amazon”, “Nike Store”)
Merchant website URL for validation
Human-readable category (e.g., “Electronics”, “Clothing”)
MCC code (e.g., “5732” for electronics stores)
Maximum authorized amount Maximum amount in currency units
ISO 4217 currency code (e.g., “USD”)
ISO 8601 timestamp of when intent expires
List of items to purchase Human-readable description shown during Passkey authentication
(e.g., “Wireless earbuds under $100”)
Optional custom ID (auto-generated if not provided)
Return Value
Unique identifier for this intent
Mandate identifier (can be reused for recurring purchases)
Intent status (registered, pending, expired)
ISO 8601 timestamp of registration
ISO 8601 timestamp of expiration
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():
Transaction Creation
Prava creates a transaction record with all purchase details (amount, merchant, products).
Challenge Generation
The backend generates a cryptographic challenge for WebAuthn.
Passkey Prompt
The user sees a biometric prompt with the consumerPrompt text and must authenticate.
Signature Verification
The signed assertion is verified to ensure it came from the registered device.
Card Network Registration
Prava securely submits the authenticated instruction to the card network for registration.
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:
MCC Category Example 5732Electronics Stores Best Buy, Newegg 5651Family Clothing Stores Gap, H&M 5411Grocery Stores Whole Foods, Trader Joe’s 5812Eating Places, Restaurants Chipotle, Starbucks 5661Shoe Stores Nike, Foot Locker 5942Book Stores Barnes & 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
Common Errors
Code Cause Resolution PASSKEY_CANCELLEDUser cancelled authentication Allow retry or cancel flow PASSKEY_FAILEDBiometric verification failed Ask user to retry CARD_NOT_FOUNDCard ID is invalid Refresh card list AMOUNT_EXCEEDS_LIMITAmount exceeds card/account limit Reduce amount or use different card MERCHANT_BLOCKEDMerchant is on blocklist Choose different merchant INVALID_MCCMCC doesn’t match merchant Verify 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