docs: AML scope note, human-blocked items, Task #11 pre-flight inventory

- Add AML scope note to Handoff - RN Multichain Probe (sanctions-only vs full KYT)
- Add human-blocked section with 3 precise next steps for owner
- Create Task 11 Pre-flight Inventory: library choice, dev/prod flow, admin UI gaps, backend gaps, risks, acceptance criteria
This commit is contained in:
Siavash Sameni
2026-05-28 20:42:42 +04:00
parent ddc0434819
commit 81625d35d2
18 changed files with 398 additions and 113 deletions

View File

@@ -1,19 +1,21 @@
---
title: Payment API
tags: [api, payment, reference, shkeeper]
tags: [api, payment, reference, request-network, escrow]
---
# Payment API
The payment surface is split across four routers, all mounted under `/api/payment/*`:
The payment surface is split across provider-neutral payment routers, Request Network checkout/webhook routes, derived-destination custody routes, and admin safety routes:
| Path prefix | File | Purpose |
| --- | --- | --- |
| `/api/payment/*` | [`paymentControllerRoutes.ts`](../../backend/src/services/payment/paymentControllerRoutes.ts) | New controller pattern (CRUD + configuration) |
| `/api/payment/*` | [`paymentRoutes.ts`](../../backend/src/services/payment/paymentRoutes.ts) | Additional legacy endpoints (tx fetch, exports) |
| `/api/payment/decentralized/*` | [`decentralizedPaymentRoutes.ts`](../../backend/src/services/payment/decentralizedPaymentRoutes.ts) | DePay / Web3 confirmations |
| `/api/payment/shkeeper/*` | [`shkeeper/shkeeperRoutes.ts`](../../backend/src/services/payment/shkeeper/shkeeperRoutes.ts) | SHKeeper pay-in, webhook, release/refund |
| `/api/payment/shkeeper/payout*` | [`shkeeper/shkeeperPayoutRoutes.ts`](../../backend/src/services/payment/shkeeper/shkeeperPayoutRoutes.ts) | SHKeeper payouts to sellers |
| `/api/payment/request-network/*` | [`requestNetwork/requestNetworkRoutes.ts`](../../backend/src/services/payment/requestNetwork/requestNetworkRoutes.ts) | Request Network intent creation, in-house checkout payloads, webhook processing |
| `/api/payment/derived-destinations/*` | [`wallets/derivedDestinationRoutes.ts`](../../backend/src/services/payment/wallets/derivedDestinationRoutes.ts) | Derived destination inspection, balance checks, and sweeping |
| `/api/payment/decentralized/*` | [`decentralizedPaymentRoutes.ts`](../../backend/src/services/payment/decentralizedPaymentRoutes.ts) | Legacy wallet-direct confirmations |
| `/api/admin/rn/networks/*` | [`requestNetwork/networkRegistryRoutes.ts`](../../backend/src/services/payment/requestNetwork/networkRegistryRoutes.ts) | Request Network chain/token registry |
| `/api/admin/payments/awaiting-confirmation/*` | `awaitingConfirmationRoutes.ts` | Admin queue for payments waiting on confirmation/safety checks |
Core model: [[Payment]]. Coordination logic to avoid race conditions when multiple sources update the same payment is in `paymentCoordinator.ts`.
@@ -21,7 +23,7 @@ Core model: [[Payment]]. Coordination logic to avoid race conditions when multip
### POST /api/payment/configuration
**Description:** Returns the payment provider configuration the SHKeeper widget needs (accepted blockchains, escrow receiver address, redirect URLs, webhook URL).
**Description:** Returns the active payment provider configuration, including Request Network settings, supported chain/token data, receiver/derived-destination context, and redirect/webhook URLs where applicable.
**Auth required:** No
**Request body:** `{ amount?, currency?, purchaseRequestId? }` (used to scope returned config)
**Response 200:**
@@ -29,7 +31,7 @@ Core model: [[Payment]]. Coordination logic to avoid race conditions when multip
{
"accept": [{ "blockchain": "bsc", "token": "0x55d3...", "receiver": "0xa30..." }],
"redirect": { "success": "...", "cancel": "..." },
"webhook": "https://.../api/payment/shkeeper/webhook"
"webhook": "https://.../api/payment/request-network/webhook"
}
```
@@ -37,18 +39,18 @@ Core model: [[Payment]]. Coordination logic to avoid race conditions when multip
**Description:** Lightweight health probe.
**Auth required:** No
**Response 200:** `{ success, message, endpoints: { shkeeper, decentralized, health } }`
**Response 200:** `{ success, message, endpoints }`. Older builds may still list legacy endpoint names in this health payload; rely on `app.ts` mounts for the authoritative live surface.
### GET /api/payment/shkeeper/config
**Description:** Same payload as `/configuration` but tailored for the SHKeeper-hosted widget; includes explicit CORS `*` headers.
**Description:** Historical compatibility endpoint for the old SHKeeper-hosted widget. It is not part of the current Request Network checkout path.
**Auth required:** No
## Payment records (CRUD)
### POST /api/payment
**Description:** Create a payment record (manual entry — usually the SHKeeper intent path is preferred).
**Description:** Create a payment record manually. Normal buyer checkout should use `POST /api/payment/request-network/intents`.
**Auth required:** Bearer JWT
**Request body:**
```ts
@@ -139,10 +141,44 @@ Core model: [[Payment]]. Coordination logic to avoid race conditions when multip
### POST /api/payment/verify
**Description:** Frontend verification endpoint used by the Web3 flow. Confirms a payment and updates the related [[PurchaseRequest]].
**Description:** Legacy frontend verification endpoint used by the wallet-direct Web3 flow. Confirms a payment and updates the related [[PurchaseRequest]].
**Auth required:** Bearer JWT
## SHKeeper - Pay-in
## Request Network - Pay-in
### POST /api/payment/request-network/intents
**Description:** Creates a Request Network pay-in intent and stores a [[Payment]] with `provider: "request.network"`. The service can attach a per-payment derived destination before creating the provider request.
**Auth required:** Bearer JWT (buyer)
**Request body:**
```ts
{
purchaseRequestId: string;
sellerOfferId: string;
sellerId: string;
amount: number;
token?: string; // default "USDT" or REQUEST_NETWORK_PAYMENT_CURRENCY
network?: string; // default REQUEST_NETWORK_NETWORK or "bsc"
metadata?: Record<string, unknown>;
}
```
**Response 200:** `{ success: true, data: { paymentId, paymentUrl, providerPaymentId, raw, ... } }`
### GET /api/payment/request-network/:paymentId/checkout
**Description:** Rehydrates the in-house checkout payload for an existing Request Network payment so the frontend can build the on-chain approval/payment transaction without relying on the hosted RN page.
**Auth required:** Bearer JWT (buyer who owns the payment)
### POST /api/payment/request-network/webhook
**Description:** Request Network posts settlement updates here. The route verifies `x-request-network-signature` over the raw body, deduplicates delivery IDs, evaluates the Transaction Safety Provider, and coordinates the payment/ledger update.
**Auth required:** No (signature-protected)
**Response:** `200` when processed or duplicate; `202` when accepted but safety checks are pending; `401` for invalid signature.
## Legacy SHKeeper - Pay-in
> [!warning] Historical route family
> The current `app.ts` mounts Request Network routes, not `services/payment/shkeeper/*`. Keep this section only for legacy record migration and old operational context.
### POST /api/payment/shkeeper/intents
@@ -230,7 +266,7 @@ Core model: [[Payment]]. Coordination logic to avoid race conditions when multip
**Description:** Counters for webhook deliveries (success / failure / duplicates).
**Auth required:** Bearer JWT (admin)
## SHKeeper - Release / Refund (escrow)
## Legacy SHKeeper - Release / Refund (escrow)
These build an admin-signed transaction off-chain and require a follow-up confirm with the broadcast tx hash. Source: `shkeeperService.buildAdminSignedTxPayload` and `confirmAdminTx`.
@@ -258,9 +294,9 @@ These build an admin-signed transaction off-chain and require a follow-up confir
**Auth required:** Bearer JWT (admin)
**Request body:** `{ txHash: string }`
## SHKeeper - Payouts
## Legacy SHKeeper - Payouts
Payouts are SHKeeper-side outbound transfers (admin pays the seller from a hot wallet).
Historical payouts were SHKeeper-side outbound transfers. Current routine releases should use ledger-gated release/refund orchestration instead.
### POST /api/payment/shkeeper/payout
@@ -296,7 +332,7 @@ Payouts are SHKeeper-side outbound transfers (admin pays the seller from a hot w
**Auth required:** No (signature checked)
**Response 200/400:** `{ success, message, data }`
## DePay / Web3 (decentralized)
## Legacy Web3 Wallet-Direct
### POST /api/payment/decentralized/save
@@ -351,7 +387,7 @@ Payouts are SHKeeper-side outbound transfers (admin pays the seller from a hot w
### POST /api/payment/decentralized/admin-payout
**Description:** Pay a seller directly from an admin hot wallet (no SHKeeper).
**Description:** Pay a seller directly from an admin hot wallet. This bypasses the newer ledger-gated release/refund orchestration and should not be used for routine releases.
**Auth required:** Bearer JWT (admin)
**Request body:**
```ts
@@ -459,7 +495,7 @@ Same result shape as above, but for a single destination.
- `completed` - confirmed, escrow funded
- `failed` - intentionally failed (expired, declined, refused)
- `cancelled` - cancelled by user/admin
- `released` - escrow released to seller (`shkeeper` flow)
- `released` - escrow released to seller through the release/refund orchestration and custody signer
- `refunded` - escrow returned to buyer
Escrow state (`escrowState`): `unfunded``funded``released` | `refunded`.
@@ -558,7 +594,7 @@ Escrow state (`escrowState`): `unfunded` → `funded` → `released` | `refunded
## Related
- [[Payment Flow]]
- [[Escrow Flow]]
- [[SHKeeper Webhook Flow]]
- [[Request Network Integration Constraints]]
- [[Payout Flow]]
- [[Socket Events]]