Skip to main content
All new Payoes payments use the Soroban escrow contract. Checkout returns setup instructions if the contract or operator account is not configured correctly. Use the deploy script in scripts/soroban-deploy-contract.sh. It builds the contract, deploys it, initializes it, and prints the values you need for .env.local.

Prerequisites

  • Stellar CLI (stellar)
  • Rust toolchain (cargo)
  • A funded Stellar account on the target network

Quick start (Testnet)

From the repository root:

1. Create Stellar CLI identities

You need two logical roles: For local development, one identity is enough. Use the same name for both flags.
If you want a separate funder account:

2. Fund the accounts

Fund whichever account pays fees on Testnet:
If operator and funder are different, fund both. The operator also needs a small XLM balance to pay the initialize transaction fee.

3. Deploy and initialize

Single account (simplest):
Separate operator and funder:
Or via npm:
The script will:
  1. Run cargo test -p payoes
  2. Build the contract WASM
  3. Deploy to the selected network (default: testnet)
  4. Call initialize(admin, authorization_signer, fee_recipient) with the operator public key
  5. Print:

4. Configure .env.local

Add the deploy output to .env.local at the repository root: Copy the script output into your env file:
Restart the dev server:

5. Verify the contract

You should see register_payment, deposit, release_deposit_to_operator, record_settlement, and refund_held_deposit.

Script reference

Supported networks are any name from:
Common values: testnet, mainnet, futurenet, local.
Deploy fees are paid by --source-account. initialize is signed by --operator-account because the contract requires admin authorization.
QR deposits are received by muxed addresses on the Payoes operator account. The app automatically adds operator trustlines for each merchant accepted asset when payments are created, quotes are refreshed, or payment methods are enabled.

Common checkout errors

Redeploying after contract changes

When the Rust contract changes:
  1. Re-run the deploy script (it creates a new contract ID)
  2. Update SOROBAN_TESTNET_CONTRACT_ID in .env.local
  3. Restart npm run dev
Existing pending payments registered on the old contract cannot be completed on the new one.

Mainnet

Use the same script with --network mainnet and set the *_MAINNET_* env vars instead:
Mainnet accounts must be funded outside Friendbot. Treat operator secrets as production credentials.

Reference Testnet deployment

An example Testnet contract ID is documented in Soroban payment router status. Use your own deployment for local development unless you control that contract’s authorization signer.