- Fund your account with a simulated deposit
- Deposit testnet coins, with a USDC deposit on Ethereum Sepolia
- Withdraw the USDC back to your test wallet
- Sample scripts that run the deposit and withdrawal flows end to end
- Bitcoin on-chain and Lightning flows
- Set up local development and check your credentials.
- Confirm with your Payward contact that crypto deposits and withdrawals are enabled for your sandbox account.
- Check Sandbox test networks for the supported networks and tokens.
https://api.sandbox.services.payward.com, signed as described in
Authentication. The
Deposits and withdrawals guide covers each request in
full. To send these requests without writing code, use the Postman collection, which signs
each request for you. Set its baseUrl variable to the sandbox base URL.
Fund your account with a simulated deposit
To get a test balance without sending testnet coins, call Simulate funding deposit. It credits a synthetic, successful deposit to the account. It’s available only in the sandbox.- Use a deposit method
idasmethod_id, from List deposit methods (GET /v1/accounts/{account_id}/funds/deposits/methods), such as the Ethereum USDC method. See Select and activate the method. - The response is
{"data":{"simulated":true}}. It doesn’t include a transaction ID. - The deposit appears in List portfolio transactions (
GET /v1/accounts/{account_id}/portfolio/transactions) asin_progress, thensuccessful, usually within a minute. Itsreference.kindisfunding. - After that, the balance is available to trade and transfer. Use it to test quotes and swaps or transfers.
Deposit testnet coins
To run these steps as one program, use the deposit script.Select and activate the method
- Call List deposit methods
(
GET /v1/accounts/{account_id}/funds/deposits/methods?asset_symbol=USDC). - Select the method whose
networkisEthereum Sepolia Testnet, and keep itsidandminimum. Match onnetwork, not on themethodname: several networks use the nameStandard. In the sandbox, the Ethereum method uses Sepolia, even though itsnetwork_infoshows the mainnet explorer and contract. See Select the sandbox method. The maximumpage_sizeis 25. - If the method’s
activation_statusisneeded, activate it with Activate deposit method (POST /v1/accounts/{account_id}/funds/deposits/methods/{method_id}/activation). A204response means the request was accepted; list the methods again until itsactivation_statusiscompleted. - Check the account’s deposit limits with List deposit limits (
GET /v1/accounts/{account_id}/funds/deposits/limits/{asset_symbol}).
Get a deposit address
List deposit addresses (GET /v1/accounts/{account_id}/funds/deposits/addresses) for the method, and reuse one if it exists.
Otherwise, claim one with Claim deposit address
(POST /v1/accounts/{account_id}/funds/deposits/addresses), and send the method’s id as method_id in the body.
Send the deposit
- Set your wallet to Ethereum Sepolia, and add Circle’s test USDC token,
0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238. - Get test USDC from Circle’s faucet, plus Sepolia ETH for the transaction fee. See Get test funds.
- Send at least the method’s
minimum(2 USDC for Ethereum USDC in the sandbox), and stay within the deposit limits. - Keep the transaction hash. You use it to find your deposit in the next step.
Confirm the credit
Poll List portfolio transactions (GET /v1/accounts/{account_id}/portfolio/transactions?types=deposit) until the deposit’s
status reaches successful or failed.
- Match your deposit by
details.crypto_transaction_id, the on-chain transaction hash in the transaction’sdetailsobject. Results are newest first, so don’t assume the first deposit is yours. - Don’t filter by status while you wait. That hides deposits that are still
in_progress. - Follow
next_page_tokenuntil it’s absent, even when a page is empty. - In the sandbox, a USDC deposit on Ethereum Sepolia usually reaches
successfulwithin a few minutes of being mined. - A confirmed transaction in the block explorer doesn’t mean your account has been credited. Wait for the portfolio transaction.
Withdraw
Withdraw a small amount back to your test wallet. Follow these steps in order. To run them as one program, use the withdrawal script.- List withdrawal methods. Call List withdrawal methods (
GET /v1/accounts/{account_id}/funds/withdrawals/methods) for USDC. Withdrawal method IDs are separate from deposit method IDs. Pick the one whosenetworkisEthereum Sepolia Testnet. - Check limits. Call List withdrawal limits (
GET /v1/accounts/{account_id}/funds/withdrawals/limits/{asset_symbol}). - Register the destination. Reuse or create a funding address for your test wallet with
Create funding address (
POST /v1/accounts/{account_id}/funds/addresses). Scope the address to one withdrawal method withscope.method_id, or to every method on its network withscope.network_id, using the method’snetwork_id. Either way, register your wallet again for each network you withdraw on. - Quote the fee. Call Calculate funding fees (
POST /v1/accounts/{account_id}/funds/fees) to get the fee and a short-livedfee_token. Do this right before you create the withdrawal, so the token doesn’t expire. - Create the withdrawal. Call Create withdrawal (
POST /v1/accounts/{account_id}/funds/withdrawals) with anIdempotency-Keyheader and thefee_token. - Verify the address, if asked. A
409 withdrawal_verification_requiredresponse means you need to verify that the user owns the destination. Complete aself_attestationverification for the user, then submit a new withdrawal. When you withdraw from your ownmainaccount, the user ID is your Console Client ID. See Address-ownership verification. - Confirm completion. Poll portfolio transactions with
types=withdrawal, without a status filter. Match the transaction whosereference.kindisfundingand whosereference.idis thewithdrawal_idfrom the response, and wait until the withdrawal reachessuccessfulorfailed. Itsdetails.crypto_transaction_idholds the on-chain transaction hash. Then check that the funds arrived in your wallet. In the sandbox, a small USDC withdrawal on Ethereum Sepolia usually completes within a few minutes.
Sample scripts
These scripts run the deposit and withdrawal flows above as one program each. They read the variables from Set up local development, plusPWS_ACCOUNT_ID. Each was run end to end against the sandbox.
Helpers
Save the helpers next to the scripts. They sign each request as described in Authentication.Deposit script
Run it once to get the deposit address. Send at least the method’s minimum, then run it again withTX_HASH set to the
transaction hash.
Withdrawal script
SetWALLET_ADDRESS to your test wallet, and optionally AMOUNT (the default is 1 USDC).
Bitcoin
Bitcoin uses two different testnets in the sandbox. Use a separate wallet for each.On-chain Bitcoin on Signet
Follow the same deposit and withdrawal steps as above, withasset_symbol=BTC, and pick the methods whose
network is Bitcoin. Set your wallet to the default Signet: coins sent from testnet3, testnet4, or a custom signet are never
credited, even though the addresses look the same.
Bitcoin differs from the Ethereum Sepolia flow in a few ways:
- A deposit appears as
in_progresswithin seconds of being broadcast, and becomessuccessfulafter 3 confirmations. Signet blocks are irregular, so allow up to an hour. The sample scripts stop polling after 15 minutes, so raise their timeout for Bitcoin. - Bitcoin transaction hashes have no
0xprefix. Comparedetails.crypto_transaction_idwith the hash exactly as your wallet reports it. The deposit’sdetails.voutis the output index within that transaction. - Withdrawals have a network fee, 0.000015 BTC in the sandbox. The withdrawal method’s
feeshows it, and Calculate funding fees returns the exact amount. In the sandbox, a 0.0005 BTC withdrawal reachedsuccessfulin about 20 minutes.
Lightning on testnet3
For Lightning deposits, use Create Lightning invoice (POST /v1/accounts/{account_id}/funds/deposits/lightning-invoices) instead of claiming
an address. Send asset_symbol BTC and the exact
amount the invoice should request, for example 0.0005. Each invoice is single-use, for an exact amount, and must be paid in full before it expires. Creating an
invoice isn’t idempotent, so don’t retry a timed-out request automatically. Create a new invoice instead, and let the
unpaid one expire.
Pay the invoice from a Lightning wallet on testnet3. Test Bitcoin withdrawals on Signet.
If a test fails
Send your Payward contact the account ID, asset, network, method IDs, request IDs or references, the transaction hash, and the last status the API returned. Don’t include API keys, secrets, or signed request headers.Next steps
- Before you go live, follow the Production checklist.
- To react to deposits and withdrawals as they happen instead of polling, subscribe to the deposit webhook events and withdrawal webhook events.
- For every request field, error, and edge case, see the Deposits and withdrawals guide.