<!-- tempo-docs-context -->
> Source: [/docs/guide/payments/send-a-payment](https://tempo.xyz/developers/docs/guide/payments/send-a-payment.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.

<span id="how-to-send-a-stablecoin-payment-on-tempo" />

# Send payments

Send stablecoin payments and payouts between Tempo accounts and verify delivery. Use a payment reference when you need to match a transfer to an invoice or order.

The examples use AlphaUSD on Moderato testnet. [Create and fund a test account](https://tempo.xyz/developers/get-started/quickstart), then choose a recipient you control.

For complete files and more languages, see [single transfers](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/examples#send-a-payment), [payment references](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/examples#add-a-payment-reference), or [batches](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/examples#batch-payments).

<span id="send-from-your-backend" />

<span id="basic-tip-20-transfer" />

## Send a payment

Use the [CLI, Viem, and Wagmi setup](https://tempo.xyz/developers/docs/accounts/examples#choose-your-tools) with a funded test account. It defines the signer, `client`, `recipient`, and `alphaUsd`; the Python setup supplies `w3` and `transaction_options()`. All amounts use base units: `10_000_000` is ten AlphaUSD. Wagmi hooks belong inside a React component; call the named handlers from buttons and show their pending and error states.

:::code-group
```ts [Viem]
const { receipt } = await client.token.transferSync({
  token: alphaUsd, to: recipient, amount: 10_000_000n,
})
console.log(receipt.transactionHash)
```

```bash [CLI]
cast erc20 transfer "$ALPHA_USD" "$TEMPO_RECIPIENT" 10000000 \
  --tempo.fee-token "$ALPHA_USD" \
  --rpc-url "$TEMPO_RPC_URL" --private-key "$TEMPO_PRIVATE_KEY"
```

```tsx [Wagmi]
import { Hooks } from 'wagmi/tempo'
const { mutate: transfer, data, isPending, error } = Hooks.token.useTransferSync()
const sendPayment = () => transfer({
  token: alphaUsd, to: recipient, amount: 10_000_000n,
})
```

```python [Python]
tx = TempoTransaction.create(
    **transaction_options(),
    calls=(TIP20(alpha_usd).transfer(to=recipient, amount=10_000_000),),
)
signed_tx = tx.sign(private_key)
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
```

```bash [cURL (RPC)]
curl --fail-with-body https://rpc.moderato.tempo.xyz \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_sendRawTransaction","params":["'"$SIGNED_TRANSACTION"'"]}'
```
:::

Viem and Wagmi sign and wait for the receipt. Python signs and submits; wait for its receipt below. cURL **only submits an already-signed transaction**: set `SIGNED_TRANSACTION` to the encoded hex bytes from your signer, as shown in [Python setup](https://tempo.xyz/developers/docs/accounts/examples#python-client). The hosted API does not sign a payment for you.

<span id="send-payment-demo" />

<span id="send-payment-implementation-steps" />

<span id="add-a-payment-action-in-the-browser" />

<span id="set-up-wagmi-for-tempo-payments" />

<span id="add-testnet-stablecoin-funds" />

<span id="add-tip-20-transfer-logic" />

<span id="display-the-payment-receipt" />

<span id="next-steps-after-sending-a-payment" />

For customer-approved payments, follow the [browser walkthrough](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/browser). To try a live payment first, use the [quickstart demo](https://tempo.xyz/developers/get-started/quickstart#try-a-payment).

<span id="transfer-with-memo" />

### Add a payment reference

Use a memo to carry an invoice or order identifier. Encode it as a 32-byte value and save the same identifier in your payment record.

:::code-group
```ts [Viem]
const { receipt } = await client.token.transferSync({
  token: alphaUsd, to: recipient, amount: 10_000_000n,
  memo: toHex('invoice-001', { size: 32 }),
})
```

```bash [CLI]
cast send "$ALPHA_USD" 'transferWithMemo(address,uint256,bytes32)' \
  "$TEMPO_RECIPIENT" 10000000 "$(cast format-bytes32-string invoice-001)" \
  --tempo.fee-token "$ALPHA_USD" \
  --rpc-url "$TEMPO_RPC_URL" --private-key "$TEMPO_PRIVATE_KEY"
```

```tsx [Wagmi]
import { Hooks } from 'wagmi/tempo'
import { toHex } from 'viem'
const { mutate: transfer, data, isPending, error } = Hooks.token.useTransferSync()
const sendPayment = () => transfer({
  token: alphaUsd, to: recipient, amount: 10_000_000n,
  memo: toHex('invoice-001', { size: 32 }),
})
```

```python [Python]
memo = b"invoice-001".ljust(32, b"\0")
call = TIP20(alpha_usd).transfer_with_memo(
    to=recipient, amount=10_000_000, memo=memo,
)
tx = TempoTransaction.create(**transaction_options(), calls=(call,))
signed_tx = tx.sign(private_key)
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
```
:::

See [Payment references](https://tempo.xyz/developers/docs/guide/payments/transfer-memos) for encoding rules and reconciliation.

<span id="batch-payment-transactions" />

## Batch payments

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

:::code-group
```ts [Viem]
const calls = [10_000_000n, 20_000_000n].map((amount) =>
  Actions.token.transfer.call({ token: alphaUsd, to: recipient, amount }),
)
const hash = await client.sendTransaction({ calls })
const receipt = await client.waitForTransactionReceipt({ hash })
```

```bash [CLI]
cast batch-send \
  --call "$ALPHA_USD::transfer(address,uint256):$TEMPO_RECIPIENT,10000000" \
  --call "$ALPHA_USD::transfer(address,uint256):$TEMPO_RECIPIENT,20000000" \
  --tempo.fee-token "$ALPHA_USD" \
  --rpc-url "$TEMPO_RPC_URL" --private-key "$TEMPO_PRIVATE_KEY"
```

```tsx [Wagmi]
import { useSendTransactionSync } from 'wagmi'
import { Actions } from 'viem/tempo'
const { mutate: send, data: receipt, isPending, error } = useSendTransactionSync()
const sendBatch = () => send({ calls: [10_000_000n, 20_000_000n].map((amount) =>
  Actions.token.transfer.call({ token: alphaUsd, to: recipient, amount }),
) })
```

```python [Python]
calls = tuple(TIP20(alpha_usd).transfer(to=recipient, amount=amount)
              for amount in (10_000_000, 20_000_000))
tx = TempoTransaction.create(**transaction_options(), calls=calls)
signed_tx = tx.sign(private_key)
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
```
:::

Use your own list of recipients and amounts. Confirm every expected transfer in the receipt before marking the batch delivered.

## Pay fees

The Viem and CLI examples select AlphaUSD for transaction fees. Wallet-connected Wagmi requests use the wallet's fee settings. Keep enough of the fee token in addition to the payment amount.

* [Choose a fee token](https://tempo.xyz/developers/docs/guide/payments/pay-fees-in-any-stablecoin) when the sender pays.
* [Sponsor fees](https://tempo.xyz/developers/docs/guide/payments/sponsor-user-fees) when your application pays for its customers.
* [Estimate costs](https://tempo.xyz/developers/docs/network/fees#estimate-costs) before funding a payment run.

Choosing a fee token does not convert the payment itself. Use [Routes](https://tempo.xyz/developers/docs/routes) for supported cross-network transfers and [Exchange](https://tempo.xyz/developers/docs/guide/stablecoin-dex) for onchain swaps.

<span id="index-payment-events" />

<span id="stablecoin-payment-best-practices" />

<span id="payment-loading-states" />

<span id="payment-error-handling" />

## Confirm delivery

Use the transaction hash as `PAYMENT_TX_HASH` (CLI), `paymentHash` (Wagmi), or `tx_hash` (Python). Viem's synchronous helper already returned `receipt`; the Wagmi transfer exposes `data?.receipt`. Use the API tool below to inspect a transaction by its hash and network.

:::code-group
```ts [Viem]
if (receipt.status !== 'success') throw new Error('Transaction failed')
console.log(receipt.transactionHash)
```

```bash [CLI]
cast receipt "$PAYMENT_TX_HASH" --rpc-url "$TEMPO_RPC_URL"
```

```tsx [Wagmi]
import { useWaitForTransactionReceipt } from 'wagmi'
const { data: receipt, isPending, error } = useWaitForTransactionReceipt({
  hash: paymentHash,
})
const succeeded = receipt?.status === 'success'
```

```python [Python]
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
if receipt["status"] != 1:
    raise RuntimeError("Transaction failed")
print(receipt["transactionHash"].hex())
```
:::

`GET /v1/transactions/{transactionHash}/receipt`

Get a transaction receipt

[API reference](https://tempo.xyz/developers/docs/api/transactions#getreceipt) — request parameters, authentication, and response schema. The examples below use editable sample values.

**cURL**

```bash
curl 'https://api.tempo.xyz/v1/transactions/0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665/receipt?chainId=42431'
```

**TypeScript**

```ts
fetch('https://api.tempo.xyz/v1/transactions/0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665/receipt?chainId=42431')
```

Check the transaction status, then match the token contract, recipient, and amount in the receipt's `Transfer` events. A successful transaction alone is not proof that the intended recipient received funds; a [receive policy](https://tempo.xyz/developers/docs/guide/payments/configure-receive-policies#monitor-blocked-receipts) can redirect funds to `ReceivePolicyGuard` instead of the recipient.

If submission times out, check the submitted transaction hash before rebuilding or sending another payment.

Use the [verification example](https://tempo.xyz/developers/docs/guide/payments/accept-a-payment/examples#verify-an-invoice) to connect confirmed transfers to application records. Save the network, transaction hash, and transfer log index so a replay cannot credit the same payment twice.

For a browser integration, show [pending and failed payment states](https://tempo.xyz/developers/docs/guide/payments/send-a-payment/browser#payment-states).

<span id="stablecoin-payment-recipes" />

<span id="stablecoin-payment-learning-resources" />

See [Transactions](https://tempo.xyz/developers/docs/protocol/transactions) for execution details.
