Crypto Withdrawal Confirmation — Test Cases
Feature version: v1.0
Reference doc: Withdrawal — Crypto Amount Confirmation
Result notation: ✅ Pass | ❌ Fail | ⏭ Skip | 🐛 Fail + bug report
Changelog
| Date | Version | Change | Author |
|---|---|---|---|
| 2026-05-10 | v1.0 | Initial creation — feature not yet deployed | — |
TC-CRYPTO-001 — API /api/payment/crypto-estimate 🆕 NEW
Precondition: Player has a valid auth token. BTCPay and 0xProcessing are operational.
| # | Description | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| 1 | BTC estimate (BTCPay path) | GET /api/payment/crypto-estimate?withdrawalType=bitcoin_transfer&netUsd=98 | Returns { coin:'BTC', provider:'btcpay', estimatedCryptoAmount, rateUsd, source:'btcpay_rates_api', fetchedAt } | |
| 2 | LTC estimate (BTCPay path) | withdrawalType=litecoin_transfer&netUsd=98 | coin: 'LTC'; estimate reflects current LTC/USD rate | |
| 3 | DOGE estimate (BTCPay path) | withdrawalType=dogecoin_transfer&netUsd=98 | coin: 'DOGE'; estimate reflects current DOGE/USD rate | |
| 4 | USDT estimate (0xProcessing path) | withdrawalType=zerox_usdt&netUsd=98 | { coin:'USDT', provider:'zeroxprocessing', estimatedCryptoAmount ≈ 98, rateUsd ≈ 1 } | |
| 5 | ETH estimate (0xProcessing path) | withdrawalType=zerox_eth&netUsd=98 | coin: 'ETH'; estimate reflects current ETH/USD rate | |
| 6 | Missing withdrawalType param | Call API without withdrawalType | HTTP 400 | |
| 7 | Missing netUsd param | Call API without netUsd | HTTP 400 | |
| 8 | netUsd = 0 | Pass netUsd=0 | Estimate skipped or returns 0 | |
| 9 | Unsupported 0x coin | withdrawalType=zerox_fakecoin | HTTP 422 with reason: 'coin_not_supported' | |
| 10 | No auth token | Call API without a token | HTTP 401 | |
| 11 | fetchedAt is valid ISO-8601 | Check response field | fetchedAt format: YYYY-MM-DDTHH:mm:ss.sssZ |
TC-CRYPTO-002 — Confirm modal display (Frontend) 🆕 NEW
Precondition: Player has entered an amount and wallet address. Estimate API returns successfully.
| # | Description | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| 1 | BTC: estimate shown with ≈ prefix | Withdraw BTC → Open confirm modal | Shows ≈ 0.00101234 BTC | |
| 2 | BTC: rate line format | Check the rate line in the BTC modal | Rate: 1 BTC = $XX,XXX.XX (live estimate) | |
| 3 | USDT: stablecoin note displayed | Withdraw USDT → Open modal | Shows 1 USDT ≈ $1.00 — stablecoin | |
| 4 | Wallet address is masked | Long wallet address in modal | Displays as <first 6 chars>...<last 4 chars> | |
| 5 | BTCPay disclaimer is correct | Check modal for BTC withdrawal | Contains "Final amount determined by BTCPay at payout time" | |
| 6 | 0xProcessing disclaimer is correct | Check modal for USDT withdrawal | Contains "Final amount confirmed by 0xProcessing at payout time" | |
| 7 | Bank transfer shows no crypto section | Select bank_transfer → Open modal | No "Estimated crypto payout" section visible | |
| 8 | BTC: 8 decimal places | Check BTC amount format | 0.00101234 (8 decimal places) | |
| 9 | DOGE: 2 decimal places | Check DOGE amount format | XX.XX DOGE | |
| 10 | USDT: 2 decimal places | Check USDT amount format | 98.00 USDT |
TC-CRYPTO-003 — Edge cases 🆕 NEW
| # | Description | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| 1 | Estimate API timeout → modal still opens | Simulate API timeout (> 10 s) | Modal opens without the crypto section; player can still submit | |
| 2 | Estimate API 500 error → modal still opens | Simulate API HTTP 500 | Modal opens without the crypto section; submission is not blocked | |
| 3 | Modal open > 2 minutes → "Rate may be stale" badge | Leave the confirm modal open for more than 2 minutes | Badge appears: "Rate may be stale — close and reopen to refresh" | |
| 4 | Rate does not auto-refresh inside modal | Wait > 2 minutes in modal | Rate is not automatically updated (prevents race conditions) | |
| 5 | BTCPay testnet → (testnet) label | Use a testnet environment | (testnet) label displayed next to the coin symbol | |
| 6 | USDT rate deviates > 2% from $1.00 | 0xProcessing returns an anomalous rate | Result is still displayed; warning is logged but user is not blocked |
TC-CRYPTO-004 — Estimate snapshot stored in transaction metadata 🆕 NEW
Important: The snapshot is audit data only — it must never be used in any financial calculation on the backend.
| # | Description | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| 1 | Snapshot saved to metadata | Submit a crypto withdrawal with cryptoEstimateSnapshot in the body | transaction.metadata.cryptoEstimateSnapshot contains all required fields | |
| 2 | Snapshot contains all required fields | Check DB | { coin, rateUsd, estimatedCryptoAmount, source, fetchedAt } all present | |
| 3 | Snapshot does not affect payout amount | Submit a snapshot with a wrong rate → Admin approves | Payout amount is still computed from real-time netPayoutUsd | |
| 4 | Bank transfer → snapshot is null | Submit a bank_transfer withdrawal | metadata.cryptoEstimateSnapshot = null or field absent | |
| 5 | Pre-feature transaction has no snapshot | Check a transaction created before this feature was deployed | metadata.cryptoEstimateSnapshot is null or absent |