9.4 KiB
title, tags, created
| title | tags | created | ||||||
|---|---|---|---|---|---|---|---|---|
| Escrow Marketplace E2E Procedure |
|
2026-06-06 |
Escrow Marketplace E2E Procedure
This procedure validates the marketplace flow with one buyer and at least two sellers. Use it for live dev validation after payment, marketplace, delivery, or scanner changes.
Preconditions
- Dev API is reachable:
GET https://dev.amn.gg/api/version. - Backend, frontend, and scanner containers are healthy.
- Admin credentials are available through a secure local channel, not docs.
- BSC Testnet wallet has enough tBNB for gas and enough canonical tUSDT.
- Backend/scanner chain 97 registry points to
0x109F54Dab34426D5477986b0460aE5dFBA65f022. - Local wallet private key or mnemonic is stored only in ignored
.env. - Notification checks are enabled in the runner. See Notification Assertion Procedure.
Actors
| Actor | Count | Role |
|---|---|---|
| Buyer | 1 | Creates request, accepts offer, funds payment, confirms delivery. |
| Sellers | 2 minimum, 3 preferred | Submit competing offers and delivery evidence. |
| Admin | 1 | Creates test users and can inspect/repair state. |
High-Level Procedure
- Generate a run id.
- Admin creates one buyer and at least two sellers.
- Assert initial notification baselines for buyer and sellers.
- Buyer creates purchase request with a min/max USDT budget.
- Assert purchase-request notifications for expected sellers.
- Sellers submit bids inside the budget range.
- After each seller bid, assert offer notifications for the buyer.
- Randomize or vary:
- bid amount,
- delivery timing,
- seller note,
- delivery method.
- Buyer selects a bid.
- Assert offer-accepted notification for selected seller and offer-rejected/updated notifications for non-selected sellers when implemented.
- Backend creates scanner payment intent.
- Assert payment-pending or payment-started notification where implemented; if missing, record as notification coverage gap.
- Buyer pays with BSC Testnet tUSDT.
- Scanner confirms the payment.
- Assert payment-confirmed notifications for buyer and selected seller.
- Seller marks delivery.
- Assert delivery notification for buyer.
- Buyer confirms delivery.
- Assert delivery-confirmed notification for selected seller and buyer status notification if implemented.
- Record current block: flow pauses before automated release policy.
Expected State Transitions
| Step | Purchase request expectation | Payment expectation |
|---|---|---|
| Request created | request visible to sellers | no payment |
| Offers submitted | received_offers or equivalent offer-ready state |
no payment |
| Offer accepted | selected offer stored | payment intent can be created |
| Payment sent | payment/check pending or processing | scanner sees chain/token/destination/amount |
| Scanner confirms | request can proceed to delivery path | status paid/confirmed/completed depending endpoint |
| Seller delivers | delivery |
escrow remains held |
| Buyer confirms | delivered, deliveryConfirmed=true |
release policy not automatic yet |
Notification Assertions After Every Step
Notification verification is mandatory after every state-changing step. A step is not complete until the test runner has either:
- observed the expected notification for every recipient; or
- recorded a known coverage gap with route/action, expected recipient, and linked issue/backlog item.
Use Notification Assertion Procedure for the exact API/socket checks.
| Step | Expected recipients | Required notification assertion |
|---|---|---|
| Baseline after user creation | buyer, every seller | Capture unread count and latest notification id for each actor before business mutations. |
| Buyer creates request | eligible sellers | Sellers receive a request/new-opportunity notification, or the gap is recorded. |
| Seller submits bid | buyer | Buyer receives a new-offer notification with relatedId or action URL pointing to the request/offer. |
| Buyer selects bid | selected seller; non-selected sellers if rejection notices are implemented | Selected seller receives acceptance notification. Non-selected sellers receive rejection/update notification where supported. |
| Payment intent created | buyer | Buyer receives payment-started/pending notification where supported. Missing pending_payment coverage is a known notification gap and must be recorded. |
| Scanner confirms payment | buyer, selected seller | Buyer and seller receive payment-confirmed/funded notification. |
| Seller marks delivery | buyer | Buyer receives delivery/proof submitted notification. |
| Buyer confirms delivery | selected seller; buyer if status-change notices are implemented | Seller receives delivery-confirmed notification. |
| Dispute raised, when added | buyer, seller, admin/mediator | All parties receive dispute-created/hold notification. |
| Release/refund, when added | buyer, seller, admin | Funds movement notification is persisted and pushed. |
Minimum notification evidence per assertion:
| Evidence | Source |
|---|---|
| unread count before and after | GET /api/notifications/unread-count |
| latest notification payload | GET /api/notifications?limit=5 |
| recipient id/email | authenticated actor profile or test user record |
| notification category/type/title/actionUrl | notification payload |
| socket event, if runner supports it | new-notification on user-<userId> |
| elapsed time from action to notification visibility | runner timestamp |
Buyer Request Template
Use unique values so live data can be filtered later:
{
"title": "Scanner BSC Testnet E2E <runId> R<round>",
"description": "Automated scanner payment test round <round>",
"productType": "physical_product",
"productLink": "https://example.test/e2e/<runId>/<round>",
"quantity": 1,
"budget": {
"min": 0.18,
"max": 0.48,
"currency": "USDT"
},
"urgency": "medium"
}
Seller Bid Rules
For each round:
- create at least two bids;
- prefer three bids so ranking/selection is clearer;
- keep all bids within buyer min/max budget;
- vary delivery timing, for example 1 day, 4 days, 7 days;
- pick a deterministic winner rule for automation, such as lowest price.
Example bid set:
| Seller | Amount | Delivery |
|---|---|---|
| seller1 | 0.31 USDT |
7 days |
| seller2 | 0.28 USDT |
5 days |
| seller3 | 0.26 USDT |
4 days |
Delivery Proof
Seller delivery should include structured proof where the API supports it:
{
"proof": {
"type": "e2e",
"runId": "<runId>",
"round": 1,
"note": "Seller delivery proof for automated dev test"
}
}
Buyer confirmation may use similar metadata:
{
"proof": {
"type": "e2e-confirmation",
"runId": "<runId>",
"round": 1
}
}
Assertions
Minimum assertions per round:
| Assertion | Required |
|---|---|
| Buyer login succeeds | yes |
| Seller logins succeed | yes |
| Request id is created | yes |
| At least two offer ids are created | yes |
| Selected offer id matches accepted seller | yes |
| Payment id is created | yes |
Payment chain id is 97 |
yes |
| Payment token is canonical tUSDT | yes |
| On-chain tx hash exists | yes |
| Scanner check returns paid/confirmed | yes |
| Seller delivery returns HTTP 200 | yes |
| Buyer confirm delivery returns HTTP 200 | yes |
Final request status is delivered |
yes |
| Notification assertion executed after each state-changing step | yes |
| Notification gaps are recorded with expected recipient and route/action | yes |
Reference Execution - 2026-06-06
Run id:
20260606043238
Generated users:
| Actor | |
|---|---|
| Buyer | amn-e2e-20260606043238-buyer@example.test |
| Seller 1 | amn-e2e-20260606043238-seller1@example.test |
| Seller 2 | amn-e2e-20260606043238-seller2@example.test |
| Seller 3 | amn-e2e-20260606043238-seller3@example.test |
Round 1:
| Field | Value |
|---|---|
| purchaseRequestId | 732e9de8-9631-484e-a5ac-bb657ca55020 |
| paymentId | f7f02ba4-9154-4408-984b-d3481d1ec5fa |
| selectedOfferId | 263b30f0-7ee6-4e63-9d0a-af2d7624fdde |
| selected seller | seller3 |
| amount | 0.26 USDT |
| token | 0x109F54Dab34426D5477986b0460aE5dFBA65f022 |
| txHash | 0x7a5c2785161df3367374574d8e1af00c548131c8a44c3fa06b592966920e3edc |
| scanner result | paid |
| final request status | delivered |
Round 2:
| Field | Value |
|---|---|
| purchaseRequestId | da34d9bc-2b2d-4dc3-98f0-aa1a07a55ebb |
| paymentId | 2e8582eb-3ac3-4793-b10f-ea721b6466d4 |
| selectedOfferId | 36e3a912-2121-4f07-87e6-4c73b1adf224 |
| selected seller | seller2 |
| amount | 0.32 USDT |
| token | 0x109F54Dab34426D5477986b0460aE5dFBA65f022 |
| txHash | 0x861a1197d7d345609f5a46b1a3723a29877ba9929bd1e7b21f7060381a1b14d0 |
| scanner result | paid |
| final request status | delivered |
Important finding from this run:
- Payment confirmation succeeded after correcting the chain 97 token registry to the actual tUSDT contract.
- Buyer delivery confirmation initially failed with HTTP 403 because user ids were compared across stores directly. Backend
2.8.117fixed the id comparison; both confirmations then returned HTTP 200.
Current Product Boundary
The procedure currently stops at delivered.
Release policy is not complete:
- physical-product grace period is not implemented;
- gift-card/digital immediate release is not implemented;
- dispute-to-release/refund automation is not complete.
Use Testing Expansion Backlog before extending this scenario into fund release.