---
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` |

