<!-- tempo-docs-context -->
> Source: [/docs/guide/payments/send-a-payment/examples](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/examples.md)
> Section: [Accounts](https://tempo.xyz/developers/docs/accounts.md). Create accounts, connect wallets, read balances, send and receive payments, and reconcile deposits.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Payment examples

Use these examples to send AlphaUSD on Moderato testnet. Start with [Send payments](https://tempo.xyz/developers/docs/guide/payments/send-a-payment) for the integration flow, or [Browser payments](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/browser) for a complete React walkthrough.

Fund a test account with the [faucet](https://tempo.xyz/developers/docs/quickstart/faucet) and replace the example recipients with accounts you control. Set `RPC_URL` or `TEMPO_RPC_URL` to `https://rpc.moderato.tempo.xyz` for command-line examples. Use the [SDK guides](https://tempo.xyz/developers/docs/sdk) to install and configure your language's tooling. Cast examples use `TEMPO_PRIVATE_KEY` from the [CLI setup](https://tempo.xyz/developers/docs/accounts/examples#cli-client); all token amounts are in base units.

## Send a payment

Send a payment using the standard `transfer` function. The Solidity examples are owner-operated treasury contracts: pass the token address to the constructor and fund the contract before calling it.

### Viem

:::code-group
```ts twoslash [example.ts]
// @noErrors
import { parseUnits } from 'viem'
import { client } from './viem.config'

const { receipt } = await client.token.transferSync({
  amount: parseUnits('100', 6), // 100 tokens (6 decimals) // [!code hl]
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb', // [!code hl]
  token: '0x20c0000000000000000000000000000000000001', // AlphaUSD // [!code hl]
})
```

```ts twoslash [viem.config.ts]
import { tempoModerato } from 'viem/chains'
import { Account, createClient } from 'viem/tempo'

const privateKey = process.env.TEMPO_PRIVATE_KEY
if (!privateKey || !/^0x[0-9a-fA-F]{64}$/.test(privateKey)) {
  throw new Error('Set TEMPO_PRIVATE_KEY to your funded test account private key')
}

export const client = createClient({
  account: Account.fromSecp256k1(privateKey as `0x${string}`),
  chain: tempoModerato,
  feeToken: '0x20c0000000000000000000000000000000000001',
})
```
:::

### Wagmi

```tsx twoslash
// @noErrors
import { Hooks } from 'wagmi/tempo'
import { parseUnits } from 'viem'

function SendPayment() {
  const { mutate, isPending } = Hooks.token.useTransferSync() // [!code hl]

  return (
    <button
      onClick={() =>
        mutate({ // [!code hl]
          amount: parseUnits('100', 6), // [!code hl]
          to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb', // [!code hl]
          token: '0x20c0000000000000000000000000000000000001', // [!code hl]
        }) // [!code hl]
      }
      disabled={isPending}
    >
      Send Payment
    </button>
  )
}
```

### Rust

:::code-group
```rust [example.rs]
use alloy::{
    primitives::{address, U256},
    providers::ProviderBuilder,
};
use tempo_alloy::{TempoNetwork, contracts::precompiles::ITIP20};

mod provider;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let provider = provider::get_provider().await?;

    let token = ITIP20::new( // [!code hl]
        address!("0x20c0000000000000000000000000000000000001"), // AlphaUSD // [!code hl]
        &provider, // [!code hl]
    ); // [!code hl]

    let receipt = token // [!code hl]
        .transfer( // [!code hl]
            address!("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb"), // [!code hl]
            U256::from(100_000_000), // 100 tokens (6 decimals) // [!code hl]
        ) // [!code hl]
        .send() // [!code hl]
        .await? // [!code hl]
        .get_receipt() // [!code hl]
        .await?; // [!code hl]

    println!("Transfer successful: {:?}", receipt.transaction_hash);

    Ok(())
}
```

```rust [provider.rs]
use alloy::providers::ProviderBuilder;
use alloy::signers::local::PrivateKeySigner;
use tempo_alloy::TempoNetwork;

pub async fn get_provider() -> Result<
    impl alloy::providers::Provider<TempoNetwork>,
    Box<dyn std::error::Error>,
> {
    let signer: PrivateKeySigner = std::env::var("PRIVATE_KEY")
        .expect("PRIVATE_KEY not set")
        .parse()?;

    let provider = ProviderBuilder::new_with_network::<TempoNetwork>()
        .wallet(signer)
        .connect(&std::env::var("RPC_URL").expect("RPC_URL not set"))
        .await?;

    Ok(provider)
}
```
:::

### Python

:::code-group
```python [example.py]
from eth_abi import encode
from pytempo import Call, TempoTransaction
from provider import w3, account

TRANSFER_SELECTOR = bytes.fromhex("a9059cbb")
ALPHA_USD = "0x20c0000000000000000000000000000000000001"

data = TRANSFER_SELECTOR + encode( # [!code hl]
    ["address", "uint256"], # [!code hl]
    ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb", 100_000_000], # [!code hl]
) # [!code hl]

tx = TempoTransaction.create(
    chain_id=w3.eth.chain_id,
    gas_limit=100_000,
    max_fee_per_gas=w3.eth.gas_price * 2,
    max_priority_fee_per_gas=w3.eth.gas_price,
    nonce=w3.eth.get_transaction_count(account.address),
    calls=(
        Call.create(to=ALPHA_USD, data="0x" + data.hex()), # [!code hl]
    ),
)

signed_tx = tx.sign(account.key.hex())
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
```

```python [provider.py]
from web3 import Web3
from eth_account import Account

w3 = Web3(Web3.HTTPProvider("https://rpc.moderato.tempo.xyz"))
account = Account.from_key("0x...")
```
:::

### Go

:::code-group
```go [main.go]
package main

import (
	"context"
	"log"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/tempoxyz/tempo-go/pkg/signer"
	"github.com/tempoxyz/tempo-go/pkg/transaction"
)

func buildTransferData(to common.Address, amount *big.Int) []byte {
	data := make([]byte, 68) // 4 (selector) + 32 (address) + 32 (uint256)
	data[0], data[1], data[2], data[3] = 0xa9, 0x05, 0x9c, 0xbb
	copy(data[16:36], to.Bytes())
	amount.FillBytes(data[36:68])
	return data
}

func main() {
	sgn, _ := signer.NewSigner("0x...")
	c := newClient()
	ctx := context.Background()

	nonce, _ := c.GetTransactionCount(ctx, sgn.Address().Hex())

	recipient := common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb")
	alphaUSD := common.HexToAddress("0x20c0000000000000000000000000000000000001")

    tx := transaction.NewBuilder(big.NewInt(42431)).
		SetNonce(nonce).
		SetGas(100_000).
		SetMaxFeePerGas(big.NewInt(25_000_000_000)).
		SetMaxPriorityFeePerGas(big.NewInt(1_000_000_000)).
		AddCall( // [!code hl]
			alphaUSD, // [!code hl]
			big.NewInt(0), // [!code hl]
			buildTransferData(recipient, big.NewInt(100_000_000)), // [!code hl]
		). // [!code hl]
		Build()

	_ = transaction.SignTransaction(tx, sgn)
	serialized, _ := transaction.Serialize(tx, nil)
	txHash, _ := c.SendRawTransaction(ctx, serialized)

	log.Printf("Transaction hash: %s", txHash)
}
```

```go [provider.go]
package main

import (
	"os"

	"github.com/tempoxyz/tempo-go/pkg/client"
)

func newClient() *client.Client {
	return client.New(os.Getenv("TEMPO_RPC_URL"))
}
```
:::

### Cast

```bash
cast erc20 transfer \
  0x20c0000000000000000000000000000000000001 \
  0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb \
  100000000 \
  --tempo.fee-token 0x20c0000000000000000000000000000000000001 \
  --rpc-url "$TEMPO_RPC_URL" \
  --private-key "$TEMPO_PRIVATE_KEY" # [!code hl]
```

### Solidity

```solidity
import {ITIP20} from "tempo-std/interfaces/ITIP20.sol";

contract PaymentSender {
    ITIP20 public immutable token;
    address public immutable owner;

    constructor(ITIP20 token_) {
        token = token_;
        owner = msg.sender;
    }

    function sendPayment(address recipient, uint256 amount) external {
        require(msg.sender == owner, "Only owner");
        token.transfer(recipient, amount); // [!code hl]
    }
}
```

## Add a payment reference

Include a memo for payment reconciliation and tracking. Use a short invoice or order ID. Follow [Payment references](https://tempo.xyz/developers/docs/guide/payments/transfer-memos#encode-a-payment-reference) for the shared UTF-8 encoding and length checks.

### Viem

:::code-group
```ts twoslash [example.ts]
// @noErrors
import { parseUnits, toHex } from 'viem'
import { client } from './viem.config'

const invoiceId = toHex('INV-12345', { size: 32 }) // [!code hl]

const { receipt } = await client.token.transferSync({
  amount: parseUnits('100', 6),
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
  token: '0x20c0000000000000000000000000000000000001',
  memo: invoiceId, // [!code hl]
})
```

```ts twoslash [viem.config.ts]
import { tempoModerato } from 'viem/chains'
import { Account, createClient } from 'viem/tempo'

const privateKey = process.env.TEMPO_PRIVATE_KEY
if (!privateKey || !/^0x[0-9a-fA-F]{64}$/.test(privateKey)) {
  throw new Error('Set TEMPO_PRIVATE_KEY to your funded test account private key')
}

export const client = createClient({
  account: Account.fromSecp256k1(privateKey as `0x${string}`),
  chain: tempoModerato,
  feeToken: '0x20c0000000000000000000000000000000000001',
})
```
:::

### Wagmi

```tsx twoslash
// @noErrors
import { Hooks } from 'wagmi/tempo'
import { parseUnits, toHex } from 'viem'

function SendPaymentWithMemo() {
  const { mutate, isPending } = Hooks.token.useTransferSync()

  return (
    <button
      onClick={() =>
        mutate({
          amount: parseUnits('100', 6),
          to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
          token: '0x20c0000000000000000000000000000000000001',
          memo: toHex('INV-12345', { size: 32 }), // [!code hl]
        })
      }
      disabled={isPending}
    >
      Send Payment
    </button>
  )
}
```

### Rust

:::code-group
```rust [example.rs]
use alloy::{
    primitives::{address, B256, U256},
    providers::ProviderBuilder,
};
use tempo_alloy::{TempoNetwork, contracts::precompiles::ITIP20};

mod provider;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let provider = provider::get_provider().await?;

    let token = ITIP20::new(
        address!("0x20c0000000000000000000000000000000000001"),
        &provider,
    );

    let receipt = token
        .transferWithMemo( // [!code hl]
            address!("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb"),
            U256::from(100_000_000),
            B256::right_padding_from("INV-12345".as_bytes()), // [!code hl]
        )
        .send()
        .await?
        .get_receipt()
        .await?;

    println!("Transfer successful: {:?}", receipt.transaction_hash);

    Ok(())
}
```

```rust [provider.rs]
use alloy::providers::ProviderBuilder;
use alloy::signers::local::PrivateKeySigner;
use tempo_alloy::TempoNetwork;

pub async fn get_provider() -> Result<
    impl alloy::providers::Provider<TempoNetwork>,
    Box<dyn std::error::Error>,
> {
    let signer: PrivateKeySigner = std::env::var("PRIVATE_KEY")
        .expect("PRIVATE_KEY not set")
        .parse()?;

    let provider = ProviderBuilder::new_with_network::<TempoNetwork>()
        .wallet(signer)
        .connect(&std::env::var("RPC_URL").expect("RPC_URL not set"))
        .await?;

    Ok(provider)
}
```
:::

### Python

:::code-group
```python [example.py]
from eth_abi import encode
from pytempo import Call, TempoTransaction
from provider import w3, account

TRANSFER_WITH_MEMO_SELECTOR = bytes.fromhex("76a8ee59")
ALPHA_USD = "0x20c0000000000000000000000000000000000001"

memo = b"INV-12345" + b"\x00" * 23  # right-pad to 32 bytes # [!code hl]

data = TRANSFER_WITH_MEMO_SELECTOR + encode( # [!code hl]
    ["address", "uint256", "bytes32"], # [!code hl]
    ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb", 100_000_000, memo], # [!code hl]
) # [!code hl]

tx = TempoTransaction.create(
    chain_id=w3.eth.chain_id,
    gas_limit=100_000,
    max_fee_per_gas=w3.eth.gas_price * 2,
    max_priority_fee_per_gas=w3.eth.gas_price,
    nonce=w3.eth.get_transaction_count(account.address),
    calls=(
        Call.create(to=ALPHA_USD, data="0x" + data.hex()),
    ),
)

signed_tx = tx.sign(account.key.hex())
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
```

```python [provider.py]
from web3 import Web3
from eth_account import Account

w3 = Web3(Web3.HTTPProvider("https://rpc.moderato.tempo.xyz"))
account = Account.from_key("0x...")
```
:::

### Go

:::code-group
```go [main.go]
package main

import (
	"context"
	"log"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/tempoxyz/tempo-go/pkg/signer"
	"github.com/tempoxyz/tempo-go/pkg/transaction"
)

func buildTransferWithMemoData(to common.Address, amount *big.Int, memo [32]byte) []byte {
	data := make([]byte, 100) // 4 + 32 + 32 + 32
	data[0], data[1], data[2], data[3] = 0x76, 0xa8, 0xee, 0x59
	copy(data[16:36], to.Bytes())
	amount.FillBytes(data[36:68])
	copy(data[68:100], memo[:])
	return data
}

func main() {
	sgn, _ := signer.NewSigner("0x...")
	c := newClient()
	ctx := context.Background()

	nonce, _ := c.GetTransactionCount(ctx, sgn.Address().Hex())

	recipient := common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb")
	alphaUSD := common.HexToAddress("0x20c0000000000000000000000000000000000001")

	var memo [32]byte // [!code hl]
	copy(memo[:], []byte("INV-12345")) // [!code hl]

    tx := transaction.NewBuilder(big.NewInt(42431)).
		SetNonce(nonce).
		SetGas(100_000).
		SetMaxFeePerGas(big.NewInt(25_000_000_000)).
		SetMaxPriorityFeePerGas(big.NewInt(1_000_000_000)).
		AddCall( // [!code hl]
			alphaUSD, // [!code hl]
			big.NewInt(0), // [!code hl]
			buildTransferWithMemoData(recipient, big.NewInt(100_000_000), memo), // [!code hl]
		). // [!code hl]
		Build()

	_ = transaction.SignTransaction(tx, sgn)
	serialized, _ := transaction.Serialize(tx, nil)
	txHash, _ := c.SendRawTransaction(ctx, serialized)

	log.Printf("Transaction hash: %s", txHash)
}
```

```go [provider.go]
package main

import (
	"os"

	"github.com/tempoxyz/tempo-go/pkg/client"
)

func newClient() *client.Client {
	return client.New(os.Getenv("TEMPO_RPC_URL"))
}
```
:::

### Cast

```bash
cast send \
  0x20c0000000000000000000000000000000000001 \
  "transferWithMemo(address,uint256,bytes32)" \
  0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb \
  100000000 \
  "$(cast format-bytes32-string "INV-12345")" \
  --tempo.fee-token 0x20c0000000000000000000000000000000000001 \
  --rpc-url "$TEMPO_RPC_URL" \
  --private-key "$TEMPO_PRIVATE_KEY" # [!code hl]
```

### Solidity

```solidity
import {ITIP20} from "tempo-std/interfaces/ITIP20.sol";

contract PaymentSender {
    ITIP20 public immutable token;
    address public immutable owner;

    constructor(ITIP20 token_) {
        token = token_;
        owner = msg.sender;
    }

    function sendPaymentWithMemo(
        address recipient,
        uint256 amount,
        bytes32 invoiceId
    ) external {
        require(msg.sender == owner, "Only owner");
        token.transferWithMemo(recipient, amount, invoiceId); // [!code hl]
    }
}
```

## Batch payments

Send several payments as calls in one transaction. If a call reverts, the whole batch reverts. For separate transaction receipts, [send payments in parallel](https://tempo.xyz/developers/docs/guide/payments/send-parallel-transactions).

### Viem

:::code-group
```ts twoslash [example.ts]
// @noErrors
import { parseUnits } from 'viem'
import { Actions } from 'viem/tempo'
import { client } from './viem.config'

const token = '0x20c0000000000000000000000000000000000001' as const
const payments = [
  { to: '0x742d35cc6634c0532925a3b844bc9e7595f0bebb', amount: parseUnits('100', 6) },
  { to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', amount: parseUnits('50', 6) },
] as const

const calls = payments.map(({ to, amount }) =>
  Actions.token.transfer.call({ token, to, amount }), // [!code hl]
)

await client.sendTransaction({ calls }) // [!code hl]
```

```ts twoslash [viem.config.ts]
import { tempoModerato } from 'viem/chains'
import { Account, createClient } from 'viem/tempo'

const privateKey = process.env.TEMPO_PRIVATE_KEY
if (!privateKey || !/^0x[0-9a-fA-F]{64}$/.test(privateKey)) {
  throw new Error('Set TEMPO_PRIVATE_KEY to your funded test account private key')
}

export const client = createClient({
  account: Account.fromSecp256k1(privateKey as `0x${string}`),
  chain: tempoModerato,
  feeToken: '0x20c0000000000000000000000000000000000001',
})
```
:::

### Wagmi

```tsx twoslash
// @noErrors
import { useSendTransactionSync } from 'wagmi'
import { parseUnits } from 'viem'
import { Actions } from 'viem/tempo'

function BatchPayment() {
  const { mutate: sendTransactionSync, isPending } = useSendTransactionSync()

  const token = '0x20c0000000000000000000000000000000000001'

  return (
    <button
      onClick={() =>
        sendTransactionSync({
          calls: [ // [!code hl]
            Actions.token.transfer.call({ // [!code hl]
              token, // [!code hl]
              to: '0x742d35cc6634c0532925a3b844bc9e7595f0bebb', // [!code hl]
              amount: parseUnits('100', 6), // [!code hl]
            }), // [!code hl]
            Actions.token.transfer.call({ // [!code hl]
              token, // [!code hl]
              to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code hl]
              amount: parseUnits('50', 6), // [!code hl]
            }), // [!code hl]
          ], // [!code hl]
        })
      }
      disabled={isPending}
    >
      Send Batch Payment
    </button>
  )
}
```

### Rust

:::code-group
```rust [example.rs]
use alloy::{
    primitives::{address, Address, U256},
    providers::{Provider, ProviderBuilder},
    sol_types::SolCall,
};
use tempo_alloy::{
    TempoNetwork, contracts::precompiles::ITIP20, primitives::transaction::Call,
    rpc::TempoTransactionRequest,
};

mod provider;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let provider = provider::get_provider().await?;

    let recipient1 = address!("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb");
    let recipient2 = address!("0x70997970C51812dc3A010C7d01b50e0d17dc79C8");
    let token_address: Address = address!("0x20c0000000000000000000000000000000000001");

    let calls = vec![ // [!code hl]
        Call { // [!code hl]
            to: token_address.into(), // [!code hl]
            input: ITIP20::transferCall { // [!code hl]
                to: recipient1, // [!code hl]
                amount: U256::from(100_000_000), // [!code hl]
            } // [!code hl]
            .abi_encode() // [!code hl]
            .into(), // [!code hl]
            value: U256::ZERO, // [!code hl]
        }, // [!code hl]
        Call { // [!code hl]
            to: token_address.into(), // [!code hl]
            input: ITIP20::transferCall { // [!code hl]
                to: recipient2, // [!code hl]
                amount: U256::from(50_000_000), // [!code hl]
            } // [!code hl]
            .abi_encode() // [!code hl]
            .into(), // [!code hl]
            value: U256::ZERO, // [!code hl]
        }, // [!code hl]
    ]; // [!code hl]

    let pending = provider
        .send_transaction(TempoTransactionRequest {
            calls,
            ..Default::default()
        })
        .await?;
    let tx_hash = pending.tx_hash();

    println!("Batch transaction sent: {tx_hash:?}");

    Ok(())
}
```

```rust [provider.rs]
use alloy::providers::ProviderBuilder;
use alloy::signers::local::PrivateKeySigner;
use tempo_alloy::TempoNetwork;

pub async fn get_provider() -> Result<
    impl alloy::providers::Provider<TempoNetwork>,
    Box<dyn std::error::Error>,
> {
    let signer: PrivateKeySigner = std::env::var("PRIVATE_KEY")
        .expect("PRIVATE_KEY not set")
        .parse()?;

    let provider = ProviderBuilder::new_with_network::<TempoNetwork>()
        .wallet(signer)
        .connect(&std::env::var("RPC_URL").expect("RPC_URL not set"))
        .await?;

    Ok(provider)
}
```
:::

### Python

:::code-group
```python [example.py]
from eth_abi import encode
from pytempo import Call, TempoTransaction
from provider import w3, account

TRANSFER_SELECTOR = bytes.fromhex("a9059cbb")
ALPHA_USD = "0x20c0000000000000000000000000000000000001"

def build_transfer(to: str, amount: int) -> str:
    data = TRANSFER_SELECTOR + encode(
        ["address", "uint256"], [to, amount]
    )
    return "0x" + data.hex()

tx = TempoTransaction.create(
    chain_id=w3.eth.chain_id,
    gas_limit=200_000,
    max_fee_per_gas=w3.eth.gas_price * 2,
    max_priority_fee_per_gas=w3.eth.gas_price,
    nonce=w3.eth.get_transaction_count(account.address),
    calls=( # [!code hl]
        Call.create( # [!code hl]
            to=ALPHA_USD, # [!code hl]
            data=build_transfer("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb", 100_000_000), # [!code hl]
        ), # [!code hl]
        Call.create( # [!code hl]
            to=ALPHA_USD, # [!code hl]
            data=build_transfer("0x70997970C51812dc3A010C7d01b50e0d17dc79C8", 50_000_000), # [!code hl]
        ), # [!code hl]
    ), # [!code hl]
)

signed_tx = tx.sign(account.key.hex())
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
```

```python [provider.py]
from web3 import Web3
from eth_account import Account

w3 = Web3(Web3.HTTPProvider("https://rpc.moderato.tempo.xyz"))
account = Account.from_key("0x...")
```
:::

### Go

:::code-group
```go [main.go]
package main

import (
	"context"
	"log"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/tempoxyz/tempo-go/pkg/signer"
	"github.com/tempoxyz/tempo-go/pkg/transaction"
)

func buildTransferData(to common.Address, amount *big.Int) []byte {
	data := make([]byte, 68)
	data[0], data[1], data[2], data[3] = 0xa9, 0x05, 0x9c, 0xbb
	copy(data[16:36], to.Bytes())
	amount.FillBytes(data[36:68])
	return data
}

func main() {
	sgn, _ := signer.NewSigner("0x...")
	c := newClient()
	ctx := context.Background()

	nonce, _ := c.GetTransactionCount(ctx, sgn.Address().Hex())

	recipient1 := common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb")
	recipient2 := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8")
	alphaUSD := common.HexToAddress("0x20c0000000000000000000000000000000000001")

    tx := transaction.NewBuilder(big.NewInt(42431)).
		SetNonce(nonce).
		SetGas(200_000).
		SetMaxFeePerGas(big.NewInt(25_000_000_000)).
		SetMaxPriorityFeePerGas(big.NewInt(1_000_000_000)).
		AddCall(alphaUSD, big.NewInt(0), buildTransferData(recipient1, big.NewInt(100_000_000))). // [!code hl]
		AddCall(alphaUSD, big.NewInt(0), buildTransferData(recipient2, big.NewInt(50_000_000))). // [!code hl]
		Build()

	_ = transaction.SignTransaction(tx, sgn)
	serialized, _ := transaction.Serialize(tx, nil)
	txHash, _ := c.SendRawTransaction(ctx, serialized)

	log.Printf("Batch transaction sent: %s", txHash)
}
```

```go [provider.go]
package main

import (
	"os"

	"github.com/tempoxyz/tempo-go/pkg/client"
)

func newClient() *client.Client {
	return client.New(os.Getenv("TEMPO_RPC_URL"))
}
```
:::

### Cast

```bash
cast batch-send \
  --tempo.fee-token 0x20c0000000000000000000000000000000000001 \
  --rpc-url "$TEMPO_RPC_URL" \
  --private-key "$TEMPO_PRIVATE_KEY" \
  --call "0x20c0000000000000000000000000000000000001::transfer(address,uint256):0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb,100000000" \
  --call "0x20c0000000000000000000000000000000000001::transfer(address,uint256):0x70997970C51812dc3A010C7d01b50e0d17dc79C8,50000000" # [!code hl]
```

### Solidity

```solidity
import {ITIP20} from "tempo-std/interfaces/ITIP20.sol";

contract BatchPaymentSender {
    ITIP20 public immutable token;
    address public immutable owner;

    constructor(ITIP20 token_) {
        token = token_;
        owner = msg.sender;
    }

    struct Payment {
        address recipient;
        uint256 amount;
    }

    function batchPay(Payment[] calldata payments) external {
        require(msg.sender == owner, "Only owner");
        for (uint256 i = 0; i < payments.length; i++) {
            token.transfer(payments[i].recipient, payments[i].amount); // [!code hl]
        }
    }
}
```

Pass every encoded call together so Tempo executes all transfers in one all-or-nothing transaction.

Check the receipt and transfer events before recording delivery. See [Confirm delivery](https://tempo.xyz/developers/docs/guide/payments/send-a-payment#confirm-delivery).
