7 KiB
7 KiB
BTCPay Server Zano Plugin — Testing Guide
What is this?
A BTCPay Server plugin that lets merchants accept Zano (ZANO) payments. When a customer pays an invoice, the plugin:
- Generates a unique integrated address (embeds a payment ID so each invoice gets its own address)
- Shows a checkout page with QR code, address, and "Pay in wallet" button
- Polls the Zano wallet every 15 seconds via
get_bulk_paymentsRPC to detect incoming payments - Tracks confirmations and settles the invoice based on the merchant's threshold setting
Built by forking the Monero BTCPay plugin and adapting it for Zano's RPC API.
QA Instance
- URL: https://btcpay.zano.me
- Server: obscura (157.180.1.140)
- Daemon: Zano testnet remote node (37.27.100.59:10505)
- Wallet: freshly generated testnet wallet inside Docker
Manual Testing (QA Engineer)
Prerequisites
- A Zano testnet wallet with some balance (get testnet ZANO from https://faucet.testnet.zano.org)
- A browser
Test 1: Setup & Enable Zano
- Go to https://btcpay.zano.me
- Register a new admin account (first user becomes admin)
- Create a store (any name)
- In the left sidebar under Wallets, click Zano
- Verify: The settings page shows:
- Node available: True
- Wallet RPC available: True
- Synced: True (with current block height)
- Check Enabled
- Set "Consider the invoice settled when the payment transaction..." to Zero Confirmation
- Click Save
Expected: Green success message, Zano stays enabled on page reload.
Test 2: Create Invoice with Zano
- Go to Invoices in the sidebar
- Click Create Invoice
- Set Amount:
1, Currency:ZANO(USD won't work without a rate source configured) - Click Create
- Click the invoice link to open the checkout page
Expected:
- Shows amount:
1.010000000000 ZANO(1 ZANO + 0.01 network fee) - Shows an integrated address starting with
iZ - QR code is displayed
- "Pay in wallet" button is present (opens
zano:URI) - "View Details" shows the full address and amount breakdown
Test 3: Pay an Invoice
- Create an invoice as above
- Copy the integrated address from the checkout page
- From your testnet wallet, send the exact amount shown to that address:
For 1.01 ZANO: amount = 1010000000000 atomic unitstransfer <integrated_address> <amount_in_atomic_units> 10 - Wait up to 30 seconds on the checkout page
Expected:
- Checkout page updates to show "Processing" or "Paid"
- With Zero Confirmation setting, invoice should settle almost immediately
- Invoice details page shows payment with tx hash, confirmations count
Test 4: Confirmation Tracking
- Set confirmation threshold to At Least One in Zano settings
- Create and pay a new invoice
- Watch the invoice status
Expected:
- Invoice shows "Processing" immediately after payment detected
- After 1 block confirmation (~1 minute on testnet), status changes to "Settled"
- Confirmation count updates on each poll (every 15 seconds)
Test 5: Multiple Invoices
- Create 3 invoices with different amounts
- Pay one of them
- Check that only the paid invoice changes status
Expected: Each invoice has a unique integrated address. Payment to one doesn't affect the others.
Test 6: Underpayment
- Create an invoice for 2 ZANO
- Send only 1 ZANO to the integrated address
Expected: Invoice remains in "New" or shows partial payment, doesn't settle.
Test 7: Settings Persistence
- Enable Zano, set Custom confirmation threshold to 5
- Save, navigate away, come back to Zano settings
Expected: Settings are preserved (Enabled, Custom, value 5).
Automated E2E Testing (Playwright CLI)
Prerequisites
- Node.js with
npx tsxavailable - Playwright installed (
npm install playwrightin~/.claude/scripts/) - BTCPay Server running locally or accessible URL
- Zano wallet RPC accessible
Running the test
# Against local instance
npx tsx ~/.claude/scripts/btcpay-zano-e2e.ts
# Against QA instance (edit BASE_URL in the script first)
BASE_URL=https://btcpay.zano.me npx tsx ~/.claude/scripts/btcpay-zano-e2e.ts
What the script tests
| Step | Action | Verification |
|---|---|---|
| 1 | Register admin account | Redirects to dashboard |
| 2 | Create store "Test Store" | Store appears in nav |
| 3 | Navigate to Zano settings | Shows Node/Wallet status |
| 4 | Enable Zano + Zero Confirmation | Settings saved successfully |
| 5 | Create 1 ZANO invoice | Invoice created, ID assigned |
| 6 | Open checkout page | Integrated address (iZ...) displayed, QR code rendered |
| 7 | Attempt payment via wallet RPC | Transfer call made (may fail if wallet has no funds) |
| 8 | Check invoice status | Status page accessible |
Screenshots
Saved to /tmp/btcpay-zano-e2e/:
01-landing.png— Initial page06-zano-settings.png— Zano settings with node status07-zano-settings-configured.png— Enabled + threshold set12-checkout-page.png— Checkout with QR code and address14-invoice-details.png— Invoice admin view
Adapting the script
Key variables at the top of btcpay-zano-e2e.ts:
const BASE_URL = 'http://127.0.0.1:23002'; // BTCPay Server URL
const WALLET_RPC = 'http://127.0.0.1:11212/json_rpc'; // Zano wallet RPC
const EMAIL = 'admin@test.com';
const PASSWORD = 'Test1234!Test1234!';
What to look for (common issues)
| Symptom | Likely cause |
|---|---|
| Zano not in sidebar | Plugin not loaded — check BTCPay logs for "Plugins.Zano" |
| "Node available: False" | Daemon RPC unreachable — check BTCPAY_ZANO_DAEMON_URI |
| "Wallet RPC available: False" | simplewallet not running or wrong port |
| "Synced: False" | Daemon still syncing — wait or use a synced remote node |
| Invoice shows no Zano option | Zano not enabled for this store |
| Payment not detected | Check wallet is connected to same daemon, check get_bulk_payments response |
| Wrong amount displayed | Divisibility issue (should be 12 decimal places) |
| Address doesn't start with iZ | Integrated address generation failed — check make_integrated_address RPC |
Architecture
Customer → BTCPay checkout page → shows integrated address + QR
↓
Payment sent to address
↓
BTCPay plugin (every 15s) → get_bulk_payments(payment_ids) → wallet RPC
↓
Payment matched by payment_id
↓
Invoice status: Processing → Settled
RPC calls used
| Method | Target | Purpose |
|---|---|---|
getinfo |
Daemon | Sync status, block height |
get_wallet_info |
Wallet | Wallet height, address |
make_integrated_address |
Wallet | Generate unique address per invoice |
get_bulk_payments |
Wallet | Detect payments by payment_id |
getbalance |
Wallet | Balance check |