import { base } from '@base-org/account';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base as baseChain } from 'viem/chains';

// Initialize wallet client with your subscription owner account
const account = privateKeyToAccount('0x...'); // Your app's private key
const walletClient = createWalletClient({
  account,
  chain: baseChain,
  transport: http()
});

// Prepare to charge a specific amount
const chargeCalls = await base.subscription.prepareCharge({
  id: '0x71319cd488f8e4f24687711ec5c95d9e0c1bacbf5c1064942937eba4c7cf2984',
  amount: '9.99',
  testnet: false
});

// Execute each charge call
const transactionHashes = [];

for (const call of chargeCalls) {
  const hash = await walletClient.sendTransaction({
    to: call.to,
    data: call.data,
    value: call.value || 0n
  });
  
  transactionHashes.push(hash);
  
  // Wait for transaction confirmation before next call
  await walletClient.waitForTransactionReceipt({ hash });
}

console.log(`Charge transactions: ${transactionHashes.join(', ')}`);
[
  {
    to: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    data: "0x095ea7b3...",
    value: "0x0"
  },
  {
    to: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    data: "0xa9059cbb...",
    value: "0x0"
  }
]
Defined in the Base Account SDK
The subscription.prepareCharge function prepares the necessary transaction calls to charge a subscription. It returns the array of call data objects to execute the charge through wallet_sendCalls or eth_sendTransaction. This gives you programmatic control over when and how to execute subscription charges.

Parameters

id
string
required
The subscription ID (permission hash) returned from subscribe().Pattern: ^0x[0-9a-fA-F]{64}$
amount
string | 'max-remaining-charge'
required
Amount to charge (e.g., “10.50”) or ‘max-remaining-charge’ for the full remaining amount in the current period.
testnet
boolean
Must match the testnet setting used in the original subscribe call. Default: false

Returns

result
PrepareChargeResult
Array of transaction calls to execute the charge.
The returned array contains:
  • An approval call (if the permission is not yet active)
  • A spend call to charge the subscription
import { base } from '@base-org/account';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base as baseChain } from 'viem/chains';

// Initialize wallet client with your subscription owner account
const account = privateKeyToAccount('0x...'); // Your app's private key
const walletClient = createWalletClient({
  account,
  chain: baseChain,
  transport: http()
});

// Prepare to charge a specific amount
const chargeCalls = await base.subscription.prepareCharge({
  id: '0x71319cd488f8e4f24687711ec5c95d9e0c1bacbf5c1064942937eba4c7cf2984',
  amount: '9.99',
  testnet: false
});

// Execute each charge call
const transactionHashes = [];

for (const call of chargeCalls) {
  const hash = await walletClient.sendTransaction({
    to: call.to,
    data: call.data,
    value: call.value || 0n
  });
  
  transactionHashes.push(hash);
  
  // Wait for transaction confirmation before next call
  await walletClient.waitForTransactionReceipt({ hash });
}

console.log(`Charge transactions: ${transactionHashes.join(', ')}`);
[
  {
    to: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    data: "0x095ea7b3...",
    value: "0x0"
  },
  {
    to: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    data: "0xa9059cbb...",
    value: "0x0"
  }
]

Error Handling

try {
  const chargeCalls = await base.subscription.prepareCharge({
    id: subscriptionId,
    amount: chargeAmount,
    testnet: false
  });
  // Execute charge
} catch (error) {
  console.error(`Failed to prepare charge: ${error.message}`);
}