> ## Documentation Index
> Fetch the complete documentation index at: https://neverminedag-sync-api-errors-9d14109.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Purchase Plans

> Purchase Nevermined payment plans to access AI agents. Pay in crypto (USDC, EURC, or any ERC-20) or via fiat checkout with Stripe or Braintree.

With the Payments Library it's easy for users and AI agents to buy Payment Plans. The user only needs to hold sufficient balance in the plan currency (set on plan creation). With Nevermined, Plan creators can set payments currency to any valid ERC-20 or native token.

Payment Plans can also be purchased in fiat (via Stripe or Braintree). The fiat checkout flow requires a credit card and is fully integrated into the Nevermined Web App. The active payment provider is selected per plan via the seller's `fiatPaymentProvider` metadata at registration time. Nevermined likes to recommend stablecoin payments — that way the payment and fetching of credits associated with the Payment Plan can be done in a single step.

## Which payment type does this plan need?

Every plan is paid for in **one** of two ways, and the two need different setup — so check the type *before* you pay rather than discovering it when a payment fails:

| Plan type  | x402 scheme           | What you need as a buyer                                                                                          |
| ---------- | --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Crypto** | `nvm:erc4337`         | A smart account funded with the plan's token (USDC, EURC, …)                                                      |
| **Fiat**   | `nvm:card-delegation` | An [enrolled card](/docs/products/payments/card-enrollment) with the plan's provider (Stripe, Braintree, or Visa) |

A plan is strictly one type or the other — there are no dual crypto-and-fiat plans. The type comes from the plan's pricing config: `registry.price.isCrypto` (and, for fiat, `metadata.plan.fiatPaymentProvider` names the provider). Rather than read that metadata yourself, let the SDK resolve it — `resolveScheme()` / `resolve_scheme()` fetches the plan (cached for 5 minutes) and returns the scheme:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { Payments, resolveScheme } from '@nevermined-io/payments'

    const scheme = await resolveScheme(payments, planId)
    // 'nvm:erc4337' (crypto) or 'nvm:card-delegation' (fiat)
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from payments_py.x402.resolve_scheme import resolve_scheme

    scheme = resolve_scheme(payments, plan_id)
    # 'nvm:erc4337' (crypto) or 'nvm:card-delegation' (fiat)
    ```
  </Tab>
</Tabs>

<Note>
  Server-side middleware (Express, FastAPI) and the A2A clients resolve the scheme for you. The direct `getX402AccessToken` / `get_x402_access_token` call does **not** — it defaults to `nvm:erc4337`. For a fiat plan you must pass `scheme: 'nvm:card-delegation'` and have a card enrolled with the matching provider. See [Core Concepts](/docs/getting-started/core-concepts#fiat-vs-crypto-what-each-plan-needs) for the full prerequisites and [Payment method mismatch](/docs/development-guide/integration-faq#how-do-i-fix-a-payment-method-mismatch) if a payment is rejected.
</Note>

## Buying a Plan

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // Here we are ordering the plan created in the previous steps
    const orderResult = await payments.plans.orderPlan(planId)
    // OUTPUT: orderResult:
    // {
    //   txHash: '0x5b95ebaec594b6d87e688faddf85eec3d708e6a06e61864699e5a366af1343f6',
    //   success: true
    // }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # Here we are ordering the Plan created in the previous steps
    order_result = payments.plans.order_plan(plan_id)
    # OUTPUT: orderResult:
    # { success: True, agreementId: '0xaabbcc' }
    ```
  </Tab>
</Tabs>

## Buying Plans with Fiat (Stripe or Braintree)

When the Payment Plan requires a payment in fiat, the payment is finalised in the Nevermined App. The app handles the checkout flow for the seller's chosen provider (Stripe Checkout or Braintree Drop-in) and returns the user to the application that initiated the purchase flow.

The SDK exposes a programmatic order method (`orderFiatPlan`) for **Stripe-priced** plans, which redirects the buyer to a Stripe Checkout session. **Braintree-priced** plans are checked out exclusively through the Nevermined App's Drop-in flow — there is no SDK-level order method for Braintree today; link buyers to the plan's purchase page on `nevermined.app` instead.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // Get fiat payment configuration
    const fiatConfig = await payments.plans.getFiatPriceConfig(planId)

    // Order plan with fiat payment
    const { sessionId, url } = await payments.plans.orderFiatPlan(planId)

    // Redirect user to Stripe checkout
    window.location.href = url

    // After successful payment, user will be redirected back with the plan active
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # Get fiat payment configuration
    fiat_config = payments.plans.get_fiat_price_config(plan_id)

    # Order plan with fiat payment
    fiat_result = payments.plans.order_fiat_plan(plan_id)

    # Redirect user to Stripe checkout
    print(f'Stripe checkout URL: {fiat_result["url"]}')
    # User completes payment on Stripe and returns to your application
    ```
  </Tab>
</Tabs>

## Checking the Credit Balance of a Payment Plan

After a user purchases a plan, they can check their balance for that plan. The balance represents the number of credits the user has available to use within the plan.

<Note>
  Time-based plans provide a balance of 1 credit for subscribers. When the plan expires, this balance will be zero.
</Note>

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const balanceResult = await payments.plans.getPlanBalance(planId)
    // OUTPUT: balanceResult:
    // {
    //   planId: '84262690312400469275420649384078993542777341811308941725027729655403981619104',
    //   planType: 'credits',
    //   holderAddress: '0x8924803472bb453b7c27a3C982A08f7515D7aA72',
    //   creditsContract: '0x17FaFabF74312EdaBEB1DB9f0CaAccd44aAFDE39',
    //   balance: '100',
    //   isSubscriber: true
    // }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    balance_result = payments.plans.get_plan_balance(plan_id)
    # OUTPUT: balanceResult:
    # {
    #   "planType": "credits",
    #   "isSubscriptor": True,
    #   "isOwner": False,
    #   "balance": 10000000
    # }  
    ```
  </Tab>
</Tabs>

## Understanding Plan Types and Balances

<CardGroup cols={2}>
  <Card title="Credits-Based Plans" icon="coins">
    Users receive a specific number of credits upon purchase. Each API call consumes credits based on your pricing configuration.
  </Card>

  <Card title="Time-Based Plans" icon="clock">
    Users receive 1 credit that grants unlimited access for the specified duration. Balance becomes 0 when expired.
  </Card>
</CardGroup>

## Payment Flow Examples

### Complete Purchase Flow

<Steps>
  <Step title="Discover Plans">
    Users browse available payment plans and select one that fits their needs
  </Step>

  <Step title="Initiate Purchase">
    Call `payments.plans.orderPlan()` or `payments.plans.orderFiatPlan()` depending on payment method
  </Step>

  <Step title="Complete Payment">
    For crypto: transaction is processed on-chain and happens in one transaction.
    For fiat: user completes Stripe checkout, and the credits will be distributed automatically after the payment.
  </Step>

  <Step title="Verify Purchase">
    Check balance to confirm the plan was successfully purchased and get the balance. Call `payments.plans.getPlanBalance()`.
  </Step>

  <Step title="Access Services">
    Use the plan to access AI agents and services. Call `payments.x402.getX402AccessToken()`.
  </Step>
</Steps>

### Error Handling

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    try {
      const orderResult = await payments.plans.orderPlan(planId)
      
      if (orderResult.success) {
        console.log('Plan purchased successfully!')
        console.log('Transaction hash:', orderResult.txHash)
        
        // Check balance to confirm
        const balance = await payments.plans.getPlanBalance(planId)
        console.log('Available credits:', balance.balance)
      }
    } catch (error) {
      console.error('Purchase failed:', error.message)
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    try:
        order_result = payments.plans.order_plan(plan_id)
        
        if order_result.get('success'):
            print('Plan purchased successfully!')
            print(f'Agreement ID: {order_result.get("agreementId")}')
            
            # Check balance to confirm
            balance = payments.plans.get_plan_balance(plan_id)
            print(f'Available credits: {balance.get("balance")}')
            
    except Exception as error:
        print(f'Purchase failed: {error}')
        
    ```
  </Tab>
</Tabs>

## Best Practices for Plan Purchasing

<AccordionGroup>
  <Accordion title="User Experience">
    * Always show clear pricing and what users get for their purchase
    * Create different plans for crypto and fiat payments if you want to support both
    * Show plan benefits and limitations clearly
  </Accordion>

  <Accordion title="Error Handling">
    * Handle network failures gracefully with retry mechanisms
    * Provide clear error messages for common issues
    * Allow users to check their balance before making additional purchases
    * Implement transaction status checking for pending purchases
  </Accordion>

  <Accordion title="Security">
    * Never store private keys or sensitive wallet information
    * Validate plan purchases on the backend before granting access
    * Implement rate limiting to prevent abuse
    * Log purchase events for audit trails
  </Accordion>
</AccordionGroup>

## Next Steps

After users purchase plans, they can:

<CardGroup cols={2}>
  <Card title="Query AI Agents" icon="search" href="/docs/development-guide/query-agents">
    Learn how to access AI services with purchased plans
  </Card>

  <Card title="Handle Requests" icon="chart-line" href="/docs/development-guide/process-requests">
    Learn how to process requests and manage responses
  </Card>
</CardGroup>
