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

# Wallet-to-Card Linking

> Connect internal wallets to cards for seamless cryptocurrency payments

## Overview

Card linking allows users to connect their custodial internal wallets to their payment cards. Once linked, card transactions automatically deduct funds from the connected wallets, enabling seamless cryptocurrency spending for everyday purchases.

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Card
    participant Platform
    participant Wallet1
    participant Wallet2

    User->>Card: Make purchase
    Card->>Platform: Request funds
    Platform->>Wallet1: Check priority 1 wallet
    alt Sufficient balance
        Wallet1->>Platform: Deduct funds
        Platform->>Card: Approve transaction
    else Insufficient balance
        Platform->>Wallet2: Check priority 2 wallet
        Wallet2->>Platform: Deduct funds
        Platform->>Card: Approve transaction
    end
    Card->>User: Transaction complete
```

When a card transaction occurs:

1. Platform checks the highest priority linked wallet
2. If balance is sufficient, funds are deducted
3. If insufficient, platform moves to next priority wallet
4. Process continues until transaction succeeds or all wallets exhausted

## Linking Wallets

Link an internal wallet to a user's card:

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST "https://api.example.com/v1/wallet/internal/card_linked" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "addressId": "7c1839ee-918e-4787-b74f-deeb48ead58b"
    }'
  ```

  ```json Response theme={null}
  {
    "success": true
  }
  ```
</CodeGroup>

### Getting the addressId

The `addressId` is returned when you retrieve internal wallets:

```bash theme={null}
curl -X GET "https://api.example.com/v1/wallet/internal" \
  -H "x-client-key: YOUR_PUBLIC_KEY" \
  -H "Authorization: Bearer USER_ACCESS_TOKEN"
```

```json theme={null}
[
  {
    "id": "098aeb90-e7f7-4f81-bc2e-4963330122c5",
    "balance": "150.50",
    "currency": "usdc",
    "address": "0x0a4b21fa733e9aeaddbf070302a85c559de13c4d",
    "addressId": "7c1839ee-918e-4787-b74f-deeb48ead58b",  // Use this value
    "type": "INTERNAL"
  }
]
```

<Note>
  Each user can link up to 5 wallets to their card. Attempting to link more than 5 wallets returns a validation error.
</Note>

## Viewing Linked Wallets

Get all wallets currently linked to the user's card:

<CodeGroup>
  ```bash Request theme={null}
  curl -X GET "https://api.example.com/v1/wallet/internal/card_linked" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN"
  ```

  ```json Response theme={null}
  [
    {
      "id": "1693a6da-5945-4461-ba1c-0b9891f78848",
      "address": "0x0a4b21fa733e9aeaddbf070302a85c559de13c4d",
      "currency": "usdc",
      "network": "linea",
      "priority": 1
    },
    {
      "id": "2804b7eb-6a56-5572-cb2d-1c9a02f89959",
      "address": "0x1b5c32gb844f9fbefcef181303b96c670ef24d5e",
      "currency": "usdt",
      "network": "ethereum",
      "priority": 2
    }
  ]
  ```
</CodeGroup>

### Response Fields

| Field      | Description                                    |
| ---------- | ---------------------------------------------- |
| `id`       | Linked wallet identifier                       |
| `address`  | Blockchain address of the wallet               |
| `currency` | Currency held in the wallet                    |
| `network`  | Blockchain network                             |
| `priority` | Payment priority (lower numbers charged first) |

## Unlinking Wallets

Remove a wallet from card linking:

<CodeGroup>
  ```bash Request theme={null}
  curl -X DELETE "https://api.example.com/v1/wallet/internal/card_linked" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "addressId": "7c1839ee-918e-4787-b74f-deeb48ead58b"
    }'
  ```

  ```json Response theme={null}
  {
    "success": true
  }
  ```
</CodeGroup>

<Warning>
  Unlinking a wallet does not affect the wallet itself or its balance. The wallet remains accessible for deposits and withdrawals.
</Warning>

## Priority Management

Priority determines which wallet is charged first for card transactions. Lower priority numbers have higher precedence (priority 1 is charged before priority 2).

### Viewing Current Priority

<CodeGroup>
  ```bash Request theme={null}
  curl -X GET "https://api.example.com/v1/wallet/internal/card_linked" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN"
  ```

  ```json Response theme={null}
  [
    {
      "id": "wallet-1",
      "address": "0x0a4b21fa733e9aeaddbf070302a85c559de13c4d",
      "currency": "usdc",
      "network": "linea",
      "priority": 1
    },
    {
      "id": "wallet-2",
      "address": "0x1b5c32gb844f9fbefcef181303b96c670ef24d5e",
      "currency": "usdt",
      "network": "ethereum",
      "priority": 2
    },
    {
      "id": "wallet-3",
      "address": "DfKNsYfrCEHb7ScJkuMTtPTeDiyjmBBm9NMHnbR7uFHz",
      "currency": "usdc",
      "network": "solana",
      "priority": 3
    }
  ]
  ```
</CodeGroup>

### Updating Priority

Change the priority order of linked wallets:

<CodeGroup>
  ```bash Request theme={null}
  curl -X PUT "https://api.example.com/v1/wallet/internal/card_linked/priority" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "wallets": [
        {
          "addressId": "7c1839ee-918e-4787-b74f-deeb48ead58b",
          "priority": 1
        },
        {
          "addressId": "8d9e0f1g-2h3i-4j5k-6l7m-8n9o0p1q2r3s",
          "priority": 2
        },
        {
          "addressId": "9e0f1g2h-3i4j-5k6l-7m8n-9o0p1q2r3s4t",
          "priority": 3
        }
      ]
    }'
  ```

  ```json Response theme={null}
  {
    "success": true
  }
  ```
</CodeGroup>

<Note>
  You must provide ALL linked wallets when updating priority. The API replaces the entire priority configuration with the provided list.
</Note>

### Priority Rules

1. **Ascending Order**: Priority 1 is checked first, then 2, then 3, etc.
2. **Sequential Processing**: Platform checks each wallet in order until transaction succeeds
3. **Balance-Based**: If a wallet has insufficient balance, platform moves to next priority
4. **No Gaps**: Priority numbers should be sequential (1, 2, 3) without gaps

## Common Use Cases

<AccordionGroup>
  <Accordion title="Multi-Currency Spending">
    Link wallets with different currencies (USDC, USDT, SOL) and set priority based on which currency you prefer to spend first.

    **Example:**

    * Priority 1: USDC on Linea (lowest fees)
    * Priority 2: USDT on Ethereum (backup)
    * Priority 3: SOL on Solana (last resort)
  </Accordion>

  <Accordion title="Fee Optimization">
    Prioritize wallets on networks with lower transaction fees. For example, set Linea wallets to priority 1 (lower fees) and Ethereum wallets to priority 2 (higher fees).

    **Example:**

    * Priority 1: USDC on Linea (\$0.01 avg fee)
    * Priority 2: USDC on Ethereum (\$2-5 avg fee)
  </Accordion>

  <Accordion title="Balance Management">
    Set priority based on wallet balances. Use wallets with smaller balances first to consolidate funds, or use larger balance wallets first to keep smaller amounts as reserves.

    **Example (Spend Small First):**

    * Priority 1: Wallet with \$50 balance
    * Priority 2: Wallet with \$500 balance
  </Accordion>

  <Accordion title="Rewards Optimization">
    If certain wallets offer cashback or rewards, prioritize those wallets to maximize benefits.

    **Example:**

    * Priority 1: Wallet with 2% cashback
    * Priority 2: Wallet with 1% cashback
    * Priority 3: Standard wallet
  </Accordion>
</AccordionGroup>

## Implementation Examples

### Complete Linking Flow

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function linkWalletToCard(userToken, currency) {
    // 1. Get available internal wallets
    const walletsResponse = await fetch(
      'https://api.example.com/v1/wallet/internal',
      {
        headers: {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': `Bearer ${userToken}`
        }
      }
    );

    const wallets = await walletsResponse.json();

    // 2. Find wallet with specified currency
    const wallet = wallets.find(w => w.currency === currency);

    if (!wallet) {
      throw new Error(`No ${currency} wallet found`);
    }

    // 3. Link wallet to card
    const linkResponse = await fetch(
      'https://api.example.com/v1/wallet/internal/card_linked',
      {
        method: 'POST',
        headers: {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': `Bearer ${userToken}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          addressId: wallet.addressId
        })
      }
    );

    return await linkResponse.json();
  }

  // Usage
  await linkWalletToCard(userToken, 'usdc');
  ```

  ```python Python theme={null}
  import requests

  def link_wallet_to_card(user_token: str, currency: str) -> dict:
      base_url = 'https://api.example.com'
      headers = {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': f'Bearer {user_token}'
      }

      # 1. Get available internal wallets
      wallets_response = requests.get(
          f'{base_url}/v1/wallet/internal',
          headers=headers
      )
      wallets = wallets_response.json()

      # 2. Find wallet with specified currency
      wallet = next((w for w in wallets if w['currency'] == currency), None)

      if not wallet:
          raise ValueError(f'No {currency} wallet found')

      # 3. Link wallet to card
      link_response = requests.post(
          f'{base_url}/v1/wallet/internal/card_linked',
          headers={**headers, 'Content-Type': 'application/json'},
          json={'addressId': wallet['addressId']}
      )

      return link_response.json()

  # Usage
  result = link_wallet_to_card(user_token, 'usdc')
  ```
</CodeGroup>

### Priority Management UI

<CodeGroup>
  ```jsx React Component theme={null}
  import { useState, useEffect } from 'react';

  function WalletPriorityManager({ userToken }) {
    const [linkedWallets, setLinkedWallets] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
      fetchLinkedWallets();
    }, []);

    const fetchLinkedWallets = async () => {
      const response = await fetch(
        'https://api.example.com/v1/wallet/internal/card_linked',
        {
          headers: {
            'x-client-key': 'YOUR_PUBLIC_KEY',
            'Authorization': `Bearer ${userToken}`
          }
        }
      );
      const wallets = await response.json();
      setLinkedWallets(wallets.sort((a, b) => a.priority - b.priority));
    };

    const updatePriority = async (walletId, newPriority) => {
      setLoading(true);

      const updatedWallets = linkedWallets.map(w =>
        w.id === walletId ? { ...w, priority: newPriority } : w
      );

      // Reorder and reassign priorities
      const sorted = updatedWallets
        .sort((a, b) => a.priority - b.priority)
        .map((w, index) => ({ ...w, priority: index + 1 }));

      const payload = {
        wallets: sorted.map(w => ({
          addressId: w.address,
          priority: w.priority
        }))
      };

      await fetch(
        'https://api.example.com/v1/wallet/internal/card_linked/priority',
        {
          method: 'PUT',
          headers: {
            'x-client-key': 'YOUR_PUBLIC_KEY',
            'Authorization': `Bearer ${userToken}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(payload)
        }
      );

      await fetchLinkedWallets();
      setLoading(false);
    };

    return (
      <div className="priority-manager">
        <h3>Linked Wallets (Payment Priority)</h3>
        <p>Lower numbers are charged first</p>

        {linkedWallets.map(wallet => (
          <div key={wallet.id} className="wallet-row">
            <span className="priority">#{wallet.priority}</span>
            <div className="wallet-info">
              <strong>{wallet.currency.toUpperCase()}</strong>
              <span>{wallet.network}</span>
              <code>{wallet.address.slice(0, 10)}...</code>
            </div>
            <div className="priority-controls">
              <button
                onClick={() => updatePriority(wallet.id, wallet.priority - 1)}
                disabled={wallet.priority === 1 || loading}
              >
                ↑
              </button>
              <button
                onClick={() => updatePriority(wallet.id, wallet.priority + 1)}
                disabled={wallet.priority === linkedWallets.length || loading}
              >
                ↓
              </button>
            </div>
          </div>
        ))}
      </div>
    );
  }
  ```
</CodeGroup>

## Transaction Flow Example

Here's what happens when a user makes a \$100 purchase with multiple linked wallets:

**Linked Wallets:**

* Priority 1: USDC on Linea (balance: \$50)
* Priority 2: USDT on Ethereum (balance: \$75)
* Priority 3: USDC on Solana (balance: \$200)

**Transaction Flow:**

<Steps>
  <Step title="Check Priority 1">
    Platform checks USDC Linea wallet. Balance: $50. Insufficient for $100 purchase.
  </Step>

  <Step title="Check Priority 2">
    Platform checks USDT Ethereum wallet. Balance: $75. Insufficient for $100 purchase.
  </Step>

  <Step title="Check Priority 3">
    Platform checks USDC Solana wallet. Balance: $200. Sufficient! Deduct $100.
  </Step>

  <Step title="Complete Transaction">
    Card transaction approved. User's Solana wallet balance now \$100.
  </Step>
</Steps>

<Note>
  The platform checks wallets sequentially until finding one with sufficient balance. Only one wallet is charged per transaction.
</Note>

## Error Handling

### Maximum Linked Wallets Exceeded

```json theme={null}
{
  "error": "Maximum linked wallets",
  "code": "WALLET_MAX_LINKED",
  "message": "User has reached the maximum number of linked wallets (5)"
}
```

**Solution:** Unlink an existing wallet before linking a new one.

### Wallet Already Linked

```json theme={null}
{
  "error": "Wallet already linked",
  "code": "WALLET_ALREADY_LINKED",
  "message": "This wallet is already linked to the card"
}
```

**Solution:** No action needed. Wallet is already available for card payments.

### Invalid Address ID

```json theme={null}
{
  "error": "Invalid address ID",
  "code": "WALLET_INVALID_ADDRESS_ID",
  "message": "The specified addressId does not exist or does not belong to this user"
}
```

**Solution:** Verify the `addressId` from GET /v1/wallet/internal response and ensure it belongs to the authenticated user.

### Insufficient Balance (During Transaction)

```json theme={null}
{
  "error": "Insufficient balance",
  "code": "WALLET_INSUFFICIENT_BALANCE",
  "message": "All linked wallets have insufficient balance for this transaction"
}
```

**Solution:** Prompt user to fund one of their linked wallets or add a new wallet with sufficient balance.

## Best Practices

<Card title="Set Logical Priority" icon="list-ol">
  Prioritize wallets based on fees, balances, or user preferences. Lower-fee networks should typically have higher priority.
</Card>

<Card title="Display Balance Status" icon="wallet">
  Show wallet balances in your UI so users understand which wallet will be charged and whether they have sufficient funds.
</Card>

<Card title="Allow Easy Reordering" icon="arrows-up-down">
  Provide drag-and-drop or button controls to let users easily adjust wallet priority.
</Card>

<Card title="Show Network Fees" icon="dollar-sign">
  Display typical network fees for each wallet to help users make informed priority decisions.
</Card>

<Card title="Notify on Insufficient Balance" icon="bell">
  Alert users when their primary wallet has low balance and suggest funding it or adjusting priority.
</Card>

<Card title="Limit Linked Wallets" icon="warning">
  Consider encouraging users to link only 2-3 wallets to keep the experience simple and manageable.
</Card>

## Next Steps

<CardGroup cols={2}>
  <Card title="Internal Wallets" icon="wallet" href="/guides/wallet/custodial/internal-wallets">
    Learn how to create internal wallets for linking
  </Card>

  <Card title="Whitelist Management" icon="list-check" href="/guides/wallet/custodial/whitelist">
    Manage withdrawal addresses
  </Card>

  <Card title="Card Operations" icon="credit-card" href="/guides/card">
    Explore card management features
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    View complete API documentation
  </Card>
</CardGroup>
