--- title: Scanner BSC Testnet Payment Procedure tags: [testing, scanner, payment, bsc-testnet, usdt] created: 2026-06-06 --- # Scanner BSC Testnet Payment Procedure This procedure validates that dev payments use the correct BSC Testnet tUSDT contract and that scanner confirms the payment. Related docs: - [[04 - Flows/Payment Flow - Scanner]] - [[01 - Architecture/Scanner Architecture]] - [[03 - API Reference/Scanner API]] ## Preconditions - Dev stack is healthy. - Scanner is deployed from the latest Forgejo `scanner` commit. - Backend and scanner token registries agree on chain 97 USDT. - Frontend `2.8.118+` is deployed if wallet UI is part of the test. - Test wallet has: - tBNB for gas, - tUSDT at `0x109F54Dab34426D5477986b0460aE5dFBA65f022`. ## Chain Registry Smoke Run from backend: ```bash cd ~/CascadeProjects/escrow/backend BASE_URL=https://dev.amn.gg bash scripts/smoke/bsc-testnet-payment-registry.sh ``` Expected: - chain 97 exists; - USDT address is `0x109f54dab34426d5477986b0460ae5dfba65f022`; - decimals are `18`; - RPC URL is a BSC Testnet RPC; - frontend/backend metadata does not point to the old token. ## Live Scanner Balance Check From a backend or host context that can reach scanner, check the funded wallet by symbol. Expected fields: | Field | Expected | |---|---| | `chainId` | `97` | | `tokenSymbol` | `USDT` | | `tokenAddress` | `0x109f54dab34426d5477986b0460ae5dfba65f022` | | `decimals` | `18` | | `balance` | positive base-unit balance | If BscScan shows token balance but scanner returns zero, the usual cause is a token contract mismatch. ## Direct-Balance Payment Flow ```mermaid sequenceDiagram autonumber actor B as Buyer wallet participant FE as Frontend/API test participant BE as Backend participant SC as Scanner participant BSC as BSC Testnet FE->>BE: Create payment intent BE->>SC: Store baseline balance for destination/token SC->>BSC: balanceOf(destination) SC-->>BE: baseline recorded FE-->>B: Show destination, amount, token B->>BSC: transfer tUSDT to destination FE->>BE: "I paid" / direct-balance check BE->>SC: POST /balances/check SC->>BSC: balanceOf(destination) SC-->>BE: delta >= expected amount BE-->>FE: payment paid/confirmed ``` ## Required Assertions | Assertion | Why | |---|---| | Intent uses chain `97` | Ensures testnet path, not BSC mainnet. | | Intent uses token `0x109F54...` | Ensures canonical test USDT. | | Amount base units equals decimal amount * `10^18` | Prevents 6-vs-18 decimal errors. | | Destination address matches scanner check | Prevents false positives from wrong wallet. | | Tx hash exists on BSC Testnet | Confirms buyer transfer actually happened. | | Scanner reports `paid` or `confirmed` | Confirms scanner sees the transfer. | | Backend marks payment paid/confirmed | Confirms scanner result reaches business state. | ## Negative Scenarios These are designed and should be automated before release confidence is claimed. ### Wrong token 1. Create a chain 97 tUSDT intent. 2. Pay the same amount using a different token contract. 3. Run scanner balance check. Expected: - intended tUSDT destination delta is unchanged; - payment remains pending; - logs explain token mismatch or no matching delta. ### Underpayment 1. Create an intent for `0.30 USDT`. 2. Transfer `0.29 USDT`. 3. Run scanner balance check. Expected: - scanner returns unpaid or insufficient delta; - backend does not mark payment paid. ### Wrong destination 1. Create a valid intent. 2. Transfer exact token/amount to a different address. 3. Run scanner balance check for the intended destination. Expected: - intended payment remains pending. ### Duplicate payment 1. Complete a payment successfully. 2. Transfer the same amount to the same destination again. 3. Trigger check/webhook path again. Expected: - no duplicate ledger credit; - payment remains single-paid; - second transfer is either ignored or tracked as overpayment/manual recovery. ### Missing gas 1. Use a wallet with tUSDT but no tBNB. 2. Attempt payment through checkout UI. Expected: - wallet cannot broadcast transaction; - UI shows wallet/network/gas error; - scanner does not mark paid. ## UI Assertions For frontend `2.8.118+`: | UI item | Expected | |---|---| | Network row | `BSC Testnet (97)` | | Token contract row | `USDT 0x109F...f022` with copy/link support | | Address link | `https://testnet.bscscan.com/address/...` | | Tx link | `https://testnet.bscscan.com/tx/...` | | Wallet switch | chain id `97` is supported by Wagmi config | ## Troubleshooting | Symptom | Likely cause | Check | |---|---|---| | Wallet funded but scanner sees zero | Wrong token contract in scanner/backend registry | `tokens.json`, `supported-chains.json`, scanner balance result | | Intent id looks like `undefined-c56-USDC` | Backend adapter fell back to global merchant/default context | `scannerContext` in backend AMN scanner intent path | | Payment waits for too many confirmations | Runtime/admin threshold for chain 97 too high | `confirmation_threshold:97` | | UI links to mainnet BscScan | Frontend explorer map missing chain 97 | frontend checkout version | | Wallet cannot switch to testnet | Wagmi config missing `bscTestnet` | frontend `src/web3/config.ts` |