Here are the steps:

  1. Set up your environment
  2. Create a Stripe Cardholder
  3. Create a Virtual Card with spending controls
  4. Retrieve Virtual Card Details
  5. Make a Purchase
1

Set up your environment

Before starting, install dependencies and configure authentication keys. The .env file securely stores API keys for Stripe, Browserbase, and optional AI models for Stagehand.

npm install

You will need the following keys:

.env

STRIPE_API_KEY=your_stripe_api_key

BROWSERBASE_PROJECT_ID=your_browserbase_project_id
BROWSERBASE_API_KEY=your_browserbase_api_key

ANTHROPIC_API_KEY=OPTIONAL_your_anthropic_api_key
OPENAI_API_KEY=OPTIONAL_your_openai_api_key

2

Create a StripeCardholder

A cardholder must be created before issuing virtual cards. The cardholder will have a verified billing address and will be eligible to receive virtual cards.

create-cardholder.ts
import Stripe from 'stripe';
import dotenv from 'dotenv';
dotenv.config();

const stripe = new Stripe(process.env.STRIPE_API_KEY!);

async function createCardholder() {
    const cardholder = await stripe.issuing.cardholders.create({
        name: "Browserbase User",
        email: "hello@browserbase.com",
        phone_number: "+15555555555",
        status: 'active',
        type: 'individual',
        billing: {
            address: {
            line1: '123 Main Street',
            city: 'San Francisco',
            state: 'CA',
            country: 'US',
            postal_code: '94111',
            }
        },
    });
    console.log("Cardholder created:", cardholder.id);
    return cardholder;
}

const cardholder = createCardholder();
3

Create a Virtual Card

Once you have a cardholder, you can create a virtual card under their name. This step generates a virtual card with a predefined spending limit. Stripe allows you to customize the card’s spending controls, including setting daily, monthly, or per-transaction limits. Find more information on spending controls in the Stripe docs.

create-card.ts
async function createCard(cardholderId: string) {
    const card = await stripe.issuing.cards.create({
        cardholder: cardholderId,
        currency: 'usd',
        type: 'virtual',
        spending_controls: {
            allowed_categories: ['charitable_and_social_service_organizations_fundraising'],
            // Choose to block certain categories instead of allowing them
            // blocked_categories: ['automated_cash_disburse'],
            spending_limits: [{
                amount: 7500, // $75.00 measured in cents
                interval: 'daily', // all_time, daily, weekly, monthly, yearly, per_authorization
            }],
        },
    });

    console.log('Card created:', card.id);
    return card;
}

const cardholderId = "ic_INPUT_CARDHOLDER_ID_HERE" // replace with your cardholder id from the previous step
const virtual_card = createCard(cardholderId);
4

Retrieve Virtual Card Details

After creating a virtual card, you’ll need to retrieve its details (card number, expiration date, and CVC) to use it for transactions. The returned data can be used to automatically enter the card details when needed.

get-card.ts
export async function getCard(cardId: string) {
    const card = await stripe.issuing.cards.retrieve(
        cardId, {expand: ['number', 'cvc']});

    const cardInfo = {
        cardholder_firstName: card.cardholder.name.split(' ')[0],
        cardholder_lastName: card.cardholder.name.split(' ')[1],
        cardholder_email: card.cardholder.email,
        cardholder_phone: card.cardholder.phone_number,
        cardholder_address: card.cardholder.billing.address,
        card_number: card.number,
        expiration_month: card.exp_month,
        expiration_year: card.exp_year.toString().slice(-2), // 2028 -> 28
        cvc: card.cvc,
        brand: card.brand,
        currency: card.currency,
    };
    console.log('Card info:', cardInfo);
    return cardInfo;
}

const cardId = "ic_INPUT_CARD_ID_HERE"; // replace with your card id from the previous step
getCard(cardId);
5

Make a Purchase

In this step, you will automate filling in the credit card payment form. This example walks you through navigating to the Red Cross donation page, selecting a donation amount, and completing the payment process using the virtual card details retrieved earlier.

import { Page, BrowserContext, Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";
import chalk from "chalk";
import dotenv from "dotenv";
import { getCard } from "./3-get-card.js";

dotenv.config();

const cardId = "ic_INPUT_CARD_ID_HERE"; // replace with your card id from the previous step

export async function main({
    page,
    context,
    stagehand,
    }: {
    page: Page; // Playwright Page with act, extract, and observe methods
    context: BrowserContext; // Playwright BrowserContext
    stagehand: Stagehand; // Stagehand instance
    }) {

    const paymentInfo = await getCard(cardId);

    await page.goto('https://www.redcross.org/donate/donation.html/')
    const donationAmount = await page.observe({
        instruction: "Find the donation amounts",
    });
    await page.act(donationAmount[0])

    const continueButton = await page.observe({
        instruction: "Find the continue button and click it",
    });
    await page.act(continueButton[0])

    const creditCardButton = await page.observe({
        instruction: "Find the credit card button and click it",
    });
    await page.act(creditCardButton[0])

    await page.act({action: "click the continue button"})

    const formValues = await page.observe({
        instruction: `Fill in the form with the following values: ${JSON.stringify(paymentInfo)}`,
    });
    console.log("formValues", formValues);

    for (const value of formValues) {
        await page.act(value);
    }
}

🎉 You made an online purchase with Stripe and Browserbase!