> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer Wallets

> Build credit-based billing systems like OpenAI or Claude with customer wallets. Track balances, manage credits, and create sophisticated financial workflows.

<CardGroup cols={3}>
  <Card title="Get Customer Wallets" icon="code" href="/api-reference/customers/get-customer-wallets">
    Check customer wallet balances across currencies.
  </Card>

  <Card title="Create Ledger Entry" icon="plus" href="/api-reference/customers/post-customer-wallets-ledger-entries">
    Add or remove credits from customer wallets.
  </Card>

  <Card title="List Ledger Entries" icon="list" href="/api-reference/customers/get-customer-wallets-ledger-entries">
    View complete transaction history with pagination.
  </Card>
</CardGroup>

## What are Customer Wallets?

Think of customer wallets as digital piggy banks for your users. Every customer gets one automatically when you create their account. You can use these wallets to:

* **Track credit balances** in USD and INR
* **Build API credit systems** like OpenAI or Claude
* **Create prepaid billing** where customers buy credits upfront
* **Handle refunds** as wallet credits instead of cash
* **Manage complex billing** with detailed transaction history

<Info>
  Every customer automatically gets a wallet when you create their account. Wallets support USD and INR currencies with separate balances for each.
</Info>

<Frame>
  <img src="https://mintcdn.com/dodopayments/9oQrV7vsGpxeyDkL/images/customer/customer-wallet.png?fit=max&auto=format&n=9oQrV7vsGpxeyDkL&q=85&s=a4a7ff3c89f4074f37e19b8d99d49ef5" alt="Customer Wallets" width="2860" height="1492" data-path="images/customer/customer-wallet.png" />
</Frame>

## How It Works

Customer wallets are simple: they hold money (credits) that customers can spend on your services. When a customer makes a purchase, their wallet balance is checked first, and any available credits are used before charging their payment method.

<Frame>
  <img src="https://mintcdn.com/dodopayments/9oQrV7vsGpxeyDkL/images/customer/customer-wallet.png?fit=max&auto=format&n=9oQrV7vsGpxeyDkL&q=85&s=a4a7ff3c89f4074f37e19b8d99d49ef5" alt="Ví Khách Hàng" style={{ maxHeight: '500px', width: 'auto' }} width="2860" height="1492" data-path="images/customer/customer-wallet.png" />
</Frame>

When you create a new customer, Dodo Payments automatically creates a wallet with zero balance. It's ready to use immediately through our API.

### Multi-Currency Support

Each wallet can hold balances in different currencies:

<ResponseField name="USD Balance" type="integer">
  Balance in US Dollars (stored in cents)
</ResponseField>

<ResponseField name="INR Balance" type="integer">
  Balance in Indian Rupees (stored in paise)
</ResponseField>

<Info>
  Currently, only <strong>USD</strong> and <strong>INR</strong> balances are available. More currencies coming soon.
</Info>

## Working with Wallets

### Check Customer Balances

See how much credit a customer has across all currencies. Perfect for checking if they have enough funds before processing a purchase.

<Card title="Get Customer Wallet Balances" icon="wallet" href="/api-reference/customers/get-customer-wallets">
  Check a customer’s wallet credit balances in all supported currencies.
</Card>

### Add or Remove Credits

Give customers credits (like welcome bonuses) or deduct credits (like usage charges). You can add reasons for each transaction to keep track of what happened.

<Card title="Create Customer Wallet Ledger Entry" icon="plus" href="/api-reference/customers/post-customer-wallets-ledger-entries">
  Add or remove credits from a customer’s wallet.
</Card>

### View Transaction History

See every credit and debit transaction for a customer. Great for debugging billing issues or showing customers their spending history.

<Card title="List Customer Wallet Ledger Entries" icon="list" href="/api-reference/customers/get-customer-wallets-ledger-entries">
  View every credit and debit transaction for a customer.
</Card>

## Real-World Examples

### API Credit System (Like OpenAI)

Build a system where customers buy credits and spend them on API calls:

```javascript theme={null}
// Give new customers welcome credits
async function giveWelcomeCredits(customerId) {
  await client.customers.wallets.ledgerEntries.create(customerId, {
    amount: 10000, // $100 in cents
    currency: 'USD',
    entry_type: 'credit',
    reason: 'Welcome bonus - 100 API credits',
    idempotency_key: `welcome_${customerId}_${Date.now()}`
  });
}

// Charge customers for API usage
async function chargeForApiUsage(customerId, usageCost) {
  try {
    await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: usageCost, // Cost in cents
      currency: 'USD',
      entry_type: 'debit',
      reason: `API usage - ${usageCost} credits consumed`,
      idempotency_key: `usage_${customerId}_${Date.now()}`
    });
  } catch (error) {
    if (error.status === 400) {
      console.log('Customer needs to buy more credits');
    }
  }
}
```

### Prepaid Billing System

Let customers buy credits upfront and spend them over time:

<Steps>
  <Step title="Welcome New Customers">
    Give new customers some free credits to get started.

    ```javascript theme={null}
    await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: 5000, // $50 welcome bonus
      currency: 'USD',
      entry_type: 'credit',
      reason: 'Welcome bonus for new customer',
      idempotency_key: `welcome_${customerId}`
    });
    ```
  </Step>

  <Step title="Handle Credit Purchases">
    When customers buy credits, add them to their wallet.

    ```javascript theme={null}
    await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: purchaseAmount, // Amount paid in cents
      currency: 'USD',
      entry_type: 'credit',
      reason: `Credit purchase - ${purchaseAmount} credits`,
      idempotency_key: `purchase_${paymentId}`
    });
    ```
  </Step>

  <Step title="Charge for Usage">
    Deduct credits when customers use your service.

    ```javascript theme={null}
    await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: usageCost,
      currency: 'USD', 
      entry_type: 'debit',
      reason: `Service usage - ${usageCost} credits`,
      idempotency_key: `usage_${usageId}`
    });
    ```
  </Step>

  <Step title="Monitor Balances">
    Check if customers are running low on credits.

    ```javascript theme={null}
    const wallets = await client.customers.wallets.list(customerId);
    const usdWallet = wallets.items.find(w => w.currency === 'USD');
    const balance = usdWallet.balance;

    if (balance < 1000) { // Less than $10
      // Send low balance notification
      await sendLowBalanceNotification(customerId, balance);
    }
    ```
  </Step>
</Steps>

### Multi-Currency Support

Handle customers in different countries:

<AccordionGroup>
  <Accordion title="US Customers">
    Give USD credits to US-based customers.

    ```javascript theme={null}
    await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: 20000, // $200 in cents
      currency: 'USD',
      entry_type: 'credit',
      reason: 'USD credit purchase',
      idempotency_key: `usd_purchase_${paymentId}`
    });
    ```
  </Accordion>

  <Accordion title="Indian Customers">
    Give INR credits to Indian customers.

    ```javascript theme={null}
    await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: 1500000, // Rs 15,000 in paise
      currency: 'INR',
      entry_type: 'credit',
      reason: 'INR credit purchase',
      idempotency_key: `inr_purchase_${paymentId}`
    });
    ```
  </Accordion>
</AccordionGroup>

## Best Practices

### Prevent Duplicate Transactions

Use idempotency keys to make sure you don't accidentally charge customers twice for the same thing:

```javascript theme={null}
async function addCreditsSafely(customerId, amount, reason) {
  const idempotencyKey = `${reason}_${customerId}_${Date.now()}`;
  
  try {
    const result = await client.customers.wallets.ledgerEntries.create(customerId, {
      amount: amount,
      currency: 'USD',
      entry_type: 'credit',
      reason: reason,
      idempotency_key: idempotencyKey
    });
    
    return { success: true, wallet: result };
  } catch (error) {
    if (error.status === 400 && error.message.includes('Insufficient balance')) {
      return { success: false, error: 'INSUFFICIENT_BALANCE' };
    }
    
    if (error.status === 409) {
      // Transaction already processed
      return { success: true, wallet: null, duplicate: true };
    }
    
    throw error;
  }
}
```

### Check Balances Before Charging

Always verify customers have enough credits before processing expensive operations:

```javascript theme={null}
async function checkBalanceBeforeOperation(customerId, requiredAmount) {
  const wallets = await client.customers.wallets.list(customerId);
  const usdWallet = wallets.items.find(w => w.currency === 'USD');
  
  if (!usdWallet || usdWallet.balance < requiredAmount) {
    throw new Error('Not enough credits for this operation');
  }
  
  return usdWallet.balance;
}
```

## What's Coming Next

<Warning>
  These features are planned for future releases:
</Warning>

* **Credit Expiration**: Set credits to expire after a certain time
* **Better Analytics**: Detailed spending reports and usage insights
* **More Webhooks**: Real-time notifications for balance changes and low credits

<Tip>
  Start simple with basic credit/debit operations, then add more complex features as your business grows.
</Tip>

### Kiểm tra số dư trước khi tính phí

Xác minh khách hàng có đủ tiền trước khi cố gắng xử lý các giao dịch lớn từ ví.

```javascript theme={null}
async function checkBalanceBeforeOperation(customerId, requiredAmount) {
  const wallets = await client.customers.wallets.list(customerId);
  const usdWallet = wallets.items.find(w => w.currency === 'USD');
  
  if (!usdWallet || usdWallet.balance < requiredAmount) {
    throw new Error('Insufficient funds for this operation');
  }
  
  return usdWallet.balance;
}
```

## Những điều sắp tới

<Warning>
  Những tính năng này được lên kế hoạch cho các bản phát hành tương lai:
</Warning>

* **Balance Expiration**: Đặt tiền hết hạn sau một khoảng thời gian
* **Better Analytics**: Báo cáo chi tiêu chi tiết và xu hướng số dư
* **More Webhooks**: Thông báo thời gian thực cho các thay đổi số dư và cảnh báo số dư thấp

<Tip>
  Bắt đầu với các thao tác nạp và trừ cơ bản, sau đó tích hợp các quy trình thanh toán tự động phức tạp hơn khi doanh nghiệp của bạn phát triển.
</Tip>
