@mindtdilly / Omnipay / commits / 241f58c

docs: review pass — fix internal leaks, SEO titles, auth accuracy, code examples

mintlify[bot] committed Sep 10, 2026 at 11:50 UTC 241f58c541c59e58d96662fbca2db73b7f40d720
21 files changed +213 -216
api/sessions-escrow-accept.mdx
+1 -1
@@ -1,5 +1,5 @@
1 ---
2 -title: "POST /api/v7/sessions/{id}/escrow-accept"
2 +title: "Escrow Accept — Confirm High-Value Procurement Session"
3 sidebarTitle: "POST /escrow-accept"
4 description: "Accept escrow for a high-value procurement session. Writes an immutable audit trail entry before confirmation. This action cannot be undone."
5 ---
api/sessions-funding-method.mdx
+2 -2
@@ -1,10 +1,10 @@
1 ---
2 -title: "POST /api/v7/sessions/{id}/funding-method"
2 +title: "Funding Method — Bind Payment to Procurement Session"
3 sidebarTitle: "POST /funding-method"
4 description: "Bind a payment method to an active procurement session. Accepts USDC on-chain, card, or bank transfer. Replaces the deprecated POST /api/payments/route."
5 ---
6
7 -Once a procurement session is ready for payment, this endpoint binds a funding method to it. You specify the method type — USDC, card, or bank transfer — and for USDC payments, the target blockchain network. ProcureNet validates the combination against the session's state and the buyer's entitlements stored in the local vector store, then advances the session toward payment processing. This endpoint replaces the deprecated `POST /api/payments/route` — if your integration still uses that path, follow the migration guidance at the bottom of this page.
7 +Once a procurement session is ready for payment, this endpoint binds a funding method to it. You specify the method type — USDC, card, or bank transfer — and for USDC payments, the target blockchain network. ProcureNet validates the combination against the session's state and the buyer's entitlements, then advances the session toward payment processing. This endpoint replaces the deprecated `POST /api/payments/route` — if your integration still uses that path, follow the migration guidance at the bottom of this page.
8
9 ## Authentication
10
api/sessions-prefill.mdx
+2 -2
@@ -4,7 +4,7 @@ sidebarTitle: "GET /prefill"
4 description: "Retrieve cached buyer profile and payment preferences for a resolved session. Only available when the session's Wallet Confidence Score is 100 or above."
5 ---
6
7 -When ProcureNet resolves a session with a Wallet Confidence Score of 100 or higher, it caches the buyer's known profile data in the local-first vector store and makes it available through the prefill endpoint. Fetching this data lets your checkout UI pre-populate name, address, and payment preference fields, reducing friction for returning buyers. If the session was classified as `partial` or `anonymous`, this endpoint returns `403` — you must present the buyer with a manual entry form instead.
7 +When ProcureNet resolves a session with a Wallet Confidence Score of 100 or higher, it caches the buyer's known profile data and makes it available through the prefill endpoint. Fetching this data lets your checkout UI pre-populate name, address, and payment preference fields, reducing friction for returning buyers. If the session was classified as `partial` or `anonymous`, this endpoint returns `403` — you must present the buyer with a manual entry form instead.
8
9 ## Authentication
10
@@ -132,4 +132,4 @@ Before calling this endpoint, inspect the `mode` field from your `POST /api/v7/o
132 | `401 Unauthorized` | Missing, expired, or invalid Bearer JWT. |
133 | `403 Forbidden` | The session's WCS is below 100 (`partial` or `anonymous` mode). Prefill is not available for this session. |
134 | `404 Not Found` | No session exists for the provided `id`. |
135 -| `500 Internal Server Error` | Vector store lookup failure. Retry the request. |
135 +| `500 Internal Server Error` | Profile data lookup failure. Retry the request. |
api/sessions-transition.mdx
+4 -4
@@ -1,10 +1,10 @@
1 ---
2 title: "POST /api/v7/sessions/{id}/transition — Advance State"
3 sidebarTitle: "POST /transition"
4 -description: "Advance a session through the procurement state machine. Illegal moves return deterministic error codes. Every call emits an observability pipeline event."
4 +description: "Advance a session through the procurement state machine. Illegal moves return deterministic error codes. Every transition emits a timestamped audit event."
5 ---
6
7 -ProcureNet manages each procurement session as a strict state machine. Calling this endpoint moves the session forward to a target state you specify. The engine validates that the transition is permitted from the session's current state — if it isn't, you receive a deterministic `400` error with a machine-readable rejection code so your integration can handle it without guesswork. Every successful transition also emits an event to the observability pipeline, giving you a complete, timestamped audit trail of how a session progressed.
7 +ProcureNet manages each procurement session as a strict state machine. Calling this endpoint moves the session forward to a target state you specify. The engine validates that the transition is permitted from the session's current state — if it isn't, you receive a deterministic `400` error with a machine-readable rejection code so your integration can handle it without guesswork. Every successful transition also emits a timestamped audit event, giving you a complete, structured record of how a session progressed.
8
9 ## Authentication
10
@@ -79,7 +79,7 @@ const result = await res.json();
79 </ResponseField>
80
81 <ResponseField name="transitioned_at" type="string" required>
82 - ISO 8601 timestamp of when the transition was recorded. This is the same timestamp written to the observability pipeline event.
82 + ISO 8601 timestamp of when the transition was recorded. This is the same timestamp written to the transition audit event.
83 </ResponseField>
84
85 ## Response Example
@@ -117,7 +117,7 @@ if (!res.ok) {
117 ```
118
119 <Info>
120 - Every successful transition — and every rejected attempt — is emitted as a structured event to the ProcureNet observability pipeline. You can use these events to reconstruct the full lifecycle of any session for debugging or compliance purposes.
120 + Every successful transition — and every rejected attempt — is emitted as a structured audit event. You can use these events to reconstruct the full lifecycle of any session for debugging or compliance purposes.
121 </Info>
122
123 ## Error Codes
api/usdc-manual-confirm.mdx
+20 -25
@@ -4,7 +4,7 @@ sidebarTitle: "POST /manual-confirm"
4 description: "Force-confirm a pending USDC payment request using elevated admin credentials. Use when autoWatch is disabled or automated confirmation has stalled."
5 ---
6
7 -The manual confirmation endpoint lets an administrator force a USDC payment into confirmed status without waiting for the automated on-chain watch cycle. This is an elevated operation intended for operational recovery — use it when `autoWatch` is disabled on your `ProcureNetWalletClient`, when a payment has stalled due to network delays, or when you need to confirm a payment outside the normal polling window. The `VCIProcureNetBridge` exposes this via the `manualConfirmPayment()` method, which accepts a local queue record ID and resolves the associated `payment_id` automatically.
7 +The manual confirmation endpoint lets an administrator force a USDC payment into confirmed status without waiting for the automated on-chain watch cycle. This is an elevated operation intended for operational recovery — use it when `autoWatch` is disabled on your `ProcureNetWalletClient`, when a payment has stalled due to network delays, or when you need to confirm a payment outside the normal polling window. Both `x-perplexity-mod-key` and `x-admin-key` headers are required; this endpoint is not accessible with a mod key alone.
8
9 ## Endpoint
10
@@ -28,18 +28,26 @@ x-admin-key: <your-admin-key>
28 ## Request Body
29
30 <ParamField body="payment_id" type="string" required>
31 - The `payment_id` of the payment you want to manually confirm. You can retrieve this from the original create-request response, or from the queue record's metadata under the key `procurenet_payment_id` when using `VCIProcureNetBridge`.
31 + The `payment_id` of the payment you want to manually confirm. You can retrieve this from the original create-request response.
32 </ParamField>
33
34 ## Code Example
35
36 <CodeGroup>
37 -```typescript TypeScript
38 -import { VCIProcureNetBridge, ProcureNetWalletClient } from './integrations/VCIProcureNetBridge';
37 +```typescript TypeScript (Bridge)
38 +import { VCIProcureNetBridge, ProcureNetWalletClient } from '@procurenet/wallet-sdk';
39
40 -// Using VCIProcureNetBridge (resolves payment_id from queue record automatically)
40 +// Instantiate the wallet client and bridge
41 +const wallet = new ProcureNetWalletClient(
42 + 'https://api.procurenet.io',
43 + process.env.PROCURENET_MOD_KEY!
44 +);
45 +
46 +const bridge = new VCIProcureNetBridge(queue, wallet);
47 +
48 +// manualConfirmPayment accepts a local record ID and admin key
49 const result = await bridge.manualConfirmPayment(
42 - localId, // local queue record ID (number)
50 + localId, // local record ID (number)
51 process.env.ADMIN_KEY!
52 );
53
@@ -50,8 +58,8 @@ if (result.confirmed) {
58 }
59 ```
60
53 -```typescript Direct Client Call
54 -import { ProcureNetWalletClient } from './integrations/VCIProcureNetBridge';
61 +```typescript TypeScript (Direct Client)
62 +import { ProcureNetWalletClient } from '@procurenet/wallet-sdk';
63
64 const wallet = new ProcureNetWalletClient(
65 'https://api.procurenet.io',
@@ -81,13 +89,13 @@ curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/manual-confi
89
90 <CardGroup cols={2}>
91 <Card title="autoWatch Disabled" icon="eye-slash">
84 - If you initialized `ProcureNetWalletClient` with `autoWatch: false`, the bridge will not poll for on-chain confirmations. Use this endpoint to confirm payments after you have verified the transfer through an external source.
92 + If you initialized `ProcureNetWalletClient` with `autoWatch: false`, the client will not poll for on-chain confirmations. Use this endpoint to confirm payments after you have verified the transfer through an external source.
93 </Card>
94 <Card title="Stalled Confirmation" icon="clock">
87 - If a payment remains unconfirmed longer than expected — for example, due to network congestion on Ethereum mainnet — you can use this endpoint to unblock the settlement queue.
95 + If a payment remains unconfirmed longer than expected — for example, due to network congestion on Ethereum mainnet — you can use this endpoint to unblock the settlement flow.
96 </Card>
97 <Card title="Operational Recovery" icon="wrench">
90 - During incidents where the watch service is temporarily unavailable, you can replay confirmations for all affected payments using this endpoint from a secure admin context.
98 + During incidents where the watch service is temporarily unavailable, you can replay confirmations for affected payments using this endpoint from a secure admin context.
99 </Card>
100 <Card title="Testing & Staging" icon="flask">
101 In non-production environments where you are not routing real on-chain transfers, use manual confirmation to exercise the rest of your payment settlement workflow without waiting for blockchain activity.
@@ -113,19 +121,6 @@ curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/manual-confi
121 }
122 ```
123
116 -## Bridge Behavior After Confirmation
117 -
118 -When you call `bridge.manualConfirmPayment()`, the bridge automatically writes back to the queue record on success:
119 -
120 -```typescript
121 -await this.queue.updateRecordMetadata(localId, {
122 - status: 'payment_confirmed',
123 - tx_hash: result.transaction_hash,
124 -});
125 -```
126 -
127 -This keeps your offline queue in sync with the confirmed payment state so downstream processes see the record as fully settled.
128 -
124 ## Error Codes
125
126 | Status | Meaning |
@@ -134,5 +129,5 @@ This keeps your offline queue in sync with the confirmed payment state so downst
129 | `404` | No payment found for the given `payment_id` |
130
131 <Info>
137 - If you need to confirm payments in bulk — for example, to recover a batch of stalled evaluations — iterate over affected local queue records and call `bridge.manualConfirmPayment()` for each one. The bridge resolves `payment_id` for you from the queue metadata, so you only need the local record ID.
132 + If you need to confirm multiple stalled payments in bulk, iterate over the affected payment IDs and call `wallet.manualConfirm(paymentId, adminKey)` for each one. Ensure your admin workflow logs each confirmation with a timestamp for your audit trail.
133 </Info>
api/usdc-request.mdx
+14 -16
@@ -4,7 +4,7 @@ sidebarTitle: "POST /usdc/request"
4 description: "Initiate an on-chain USDC payment request for a tenant. Returns a deposit address, optional QR code, and a payment_id to track confirmation."
5 ---
6
7 -The USDC payment request endpoint creates an on-chain payment instruction for a specific tenant and amount. When a field evaluator's offline evaluation syncs successfully, `VCIProcureNetBridge` calls this endpoint automatically to initiate settlement. You can also call it directly to request payment outside of the automated sync flow. Each response includes a `payment_id` you can pass to the watch or manual-confirm endpoints to track the transaction's on-chain status.
7 +The USDC payment request endpoint creates an on-chain payment instruction for a specific tenant and amount. Call this endpoint whenever you need to initiate a USDC settlement — for example, after a procurement evaluation completes or when issuing a direct payment. The response includes a `payment_id` that you pass to the watch or manual-confirm endpoints to track the transaction's on-chain status. Each payment request targets a single blockchain network and expires if the corresponding on-chain transfer is not confirmed within the allotted window.
8
9 ## Endpoint
10
@@ -27,14 +27,14 @@ x-perplexity-mod-key: <your-api-key>
27 </ParamField>
28
29 <ParamField body="amount_usdc" type="number" required>
30 - Payment amount in USDC. Must be a positive number. The `VCIProcureNetBridge` derives this automatically from the evaluator's average score using the following tiers:
30 + Payment amount in USDC. Must be a positive number. ProcureNet's VCI payment tiers determine the appropriate amount based on average evaluation score:
31
32 - | Average Score | Payment |
32 + | Average Score | Payment Amount |
33 |---|---|
34 | ≥ 9.0 | 500 USDC |
35 | ≥ 7.0 | 250 USDC |
36 | ≥ 5.0 | 100 USDC |
37 - | < 5.0 | 0 USDC (no payment created) |
37 + | < 5.0 | 0 USDC (no payment initiated) |
38 </ParamField>
39
40 <ParamField body="network" type="string" required>
@@ -46,20 +46,18 @@ x-perplexity-mod-key: <your-api-key>
46 </ParamField>
47
48 <ParamField body="memo" type="string" required>
49 - A human-readable description attached to the payment. For VCI evaluations, the bridge generates this automatically in the format `VCI Eval: <assignmentId> | Score: <avg>`.
49 + A human-readable description attached to the payment. Use this to identify the purpose of the payment, such as a reference number or a brief note about the transaction.
50 </ParamField>
51
52 <ParamField body="metadata" type="object">
53 - Arbitrary key-value pairs attached to the payment record. Use this field to link the payment back to your internal records — for example, an evaluator ID, assignment ID, or GPS snapshot. Keys and values must be JSON-serializable.
53 + Arbitrary key-value pairs attached to the payment record. Use this field to link the payment back to your internal records. Keys and values must be JSON-serializable.
54
55 - <Expandable title="Common metadata keys">
55 + <Expandable title="Example metadata keys">
56 | Key | Type | Description |
57 |---|---|---|
58 | `evaluator_id` | string | Your internal evaluator identifier |
59 | `assignment_id` | string | The assignment this payment covers |
60 - | `vci_local_id` | number | Local offline queue record ID |
61 - | `gps` | object | GPS snapshot at time of evaluation |
62 - | `submitted_at` | string | ISO 8601 timestamp of offline submission |
60 + | `submitted_at` | string | ISO 8601 timestamp of submission |
61 </Expandable>
62 </ParamField>
63
@@ -67,7 +65,7 @@ x-perplexity-mod-key: <your-api-key>
65
66 <CodeGroup>
67 ```typescript TypeScript
70 -import { ProcureNetWalletClient } from './integrations/VCIProcureNetBridge';
68 +import { ProcureNetWalletClient } from '@procurenet/wallet-sdk';
69
70 const wallet = new ProcureNetWalletClient(
71 'https://api.procurenet.io',
@@ -80,7 +78,7 @@ const payment = await wallet.createUSDCPayment({
78 amount_usdc: 250,
79 network: 'base',
80 token: 'USDC',
83 - memo: 'VCI Eval: assign_789 | Score: 7.50',
81 + memo: 'Procurement evaluation — assignment assign_789',
82 metadata: {
83 evaluator_id: 'eval_456',
84 assignment_id: 'assign_789'
@@ -101,7 +99,7 @@ curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/request \
99 "amount_usdc": 250,
100 "network": "base",
101 "token": "USDC",
104 - "memo": "VCI Eval: assign_789 | Score: 7.50",
102 + "memo": "Procurement evaluation — assignment assign_789",
103 "metadata": {
104 "evaluator_id": "eval_456",
105 "assignment_id": "assign_789"
@@ -113,7 +111,7 @@ curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/request \
111 ## Response
112
113 <ResponseField name="payment_id" type="string" required>
116 - Unique identifier for this payment request. Pass this value to [`GET /usdc/watch/{paymentId}`](/api/usdc-watch) to poll confirmation, or to [`POST /usdc/manual-confirm`](/api/usdc-manual-confirm) to force-confirm.
114 + Unique identifier for this payment request. Pass this value to [`GET /usdc/watch/{paymentId}`](/api/usdc-watch) to poll for confirmation, or to [`POST /usdc/manual-confirm`](/api/usdc-manual-confirm) to force-confirm.
115 </ResponseField>
116
117 <ResponseField name="deposit_address" type="string" required>
@@ -121,7 +119,7 @@ curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/request \
119 </ResponseField>
120
121 <ResponseField name="qr_code" type="string">
124 - A data URI containing a QR code image for the deposit address. Render this in your UI so evaluators can scan and pay directly from a mobile wallet.
122 + A data URI containing a QR code image for the deposit address. Render this in your UI so payers can scan and transfer directly from a mobile wallet.
123 </ResponseField>
124
125 <ResponseField name="expires_at" type="string">
@@ -148,5 +146,5 @@ curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/request \
146 | `422` | `tenant_id` does not match a registered ProcureNet tenant |
147
148 <Tip>
151 - Store `payment_id` and `deposit_address` in your queue metadata immediately after a successful response. The `VCIProcureNetBridge` does this automatically via `queue.updateRecordMetadata()`.
149 + Store `payment_id` and `deposit_address` from the response immediately after a successful request. Pass `payment_id` to the watch endpoint to begin polling for on-chain confirmation.
150 </Tip>
api/usdc-watch.mdx
+5 -5
@@ -4,7 +4,7 @@ sidebarTitle: "GET /usdc/watch"
4 description: "Poll an active USDC payment request for on-chain confirmation. Returns confirmed status and a transaction hash once the transfer is detected."
5 ---
6
7 -After creating a USDC payment request, use the watch endpoint to check whether the corresponding on-chain transfer has been confirmed. You call this endpoint periodically, passing the `payment_id` returned by the create endpoint, until `confirmed` is `true`. When you initialize `ProcureNetWalletClient` with `autoWatch: true`, the `VCIProcureNetBridge` handles this polling loop automatically after every successful evaluation sync — you only need to call this endpoint directly when managing the polling lifecycle yourself.
7 +After creating a USDC payment request, use the watch endpoint to check whether the corresponding on-chain transfer has been confirmed. Call this endpoint periodically with the `payment_id` returned by the create endpoint until `confirmed` is `true`. When you initialize `ProcureNetWalletClient` with `autoWatch: true`, the client handles this polling loop automatically — you only need to call this endpoint directly when you want to manage the polling lifecycle yourself.
8
9 ## Endpoint
10
@@ -23,7 +23,7 @@ x-perplexity-mod-key: <your-api-key>
23 ## Path Parameters
24
25 <ParamField path="paymentId" type="string" required>
26 - The `payment_id` returned when you created the payment request via [`POST /usdc/request`](/api/usdc-request). This value is also stored in your queue record's metadata under the key `procurenet_payment_id` when using `VCIProcureNetBridge`.
26 + The `payment_id` returned when you created the payment request via [`POST /usdc/request`](/api/usdc-request).
27 </ParamField>
28
29 ## Polling Behavior
@@ -31,14 +31,14 @@ x-perplexity-mod-key: <your-api-key>
31 Call this endpoint on a fixed interval until the response includes `"confirmed": true`. A reasonable starting interval is every 10–15 seconds for `base` and `arbitrum` networks, and every 30–60 seconds for `ethereum` mainnet.
32
33 <Note>
34 - If `autoWatch: true` is set on your `ProcureNetWalletClient` instance, `VCIProcureNetBridge` automatically calls `watchPayment()` for you after initiating settlement. You do not need to poll manually in that case.
34 + If `autoWatch: true` is set on your `ProcureNetWalletClient` instance, the client automatically calls `watchPayment()` after initiating a payment request. You do not need to poll manually in that case.
35 </Note>
36
37 ## Code Example
38
39 <CodeGroup>
40 ```typescript TypeScript
41 -import { ProcureNetWalletClient } from './integrations/VCIProcureNetBridge';
41 +import { ProcureNetWalletClient } from '@procurenet/wallet-sdk';
42
43 const wallet = new ProcureNetWalletClient(
44 'https://api.procurenet.io',
@@ -117,5 +117,5 @@ curl -X GET \
117 | `404` | No payment found for the given `paymentId` |
118
119 <Tip>
120 - Once you receive `"confirmed": true`, update your internal records immediately. The `VCIProcureNetBridge` writes `status: "payment_confirmed"` and `tx_hash` back to the queue record automatically when using the bridge's built-in watch flow.
120 + Once you receive `"confirmed": true`, record the `transaction_hash` in your own systems immediately for auditing and reconciliation purposes.
121 </Tip>
authentication.mdx
+1 -1
@@ -1,7 +1,7 @@
1 ---
2 title: "How to Authenticate Every Request to ProcureNet APIs"
3 sidebarTitle: "Authentication"
4 -description: "ProcureNet uses four credential types — mod keys, JWT bearer tokens, webhook HMAC signatures, and admin keys — each scoped to a specific part of the API."
4 +description: "ProcureNet uses four credential types — mod keys, JWT tokens, webhook HMAC signatures, and admin keys — each scoped to a specific part of the API."
5 ---
6
7 ProcureNet authenticates requests through four distinct mechanisms, each scoped to a different surface of the API. Wallet and payment endpoints use a mod key passed as a custom header. Session endpoints require a JWT bearer token. Inbound webhooks from Procurement Express carry an HMAC signature you must verify before processing. Admin override endpoints require a separate admin key. Understanding which credential applies where prevents auth failures and keeps your integration secure.
concepts/orchestration-modes.mdx
+1 -1
@@ -1,5 +1,5 @@
1 ---
2 -title: "Orchestration Modes: Resolved, Partial, Anonymous"
2 +title: "ProcureNet Orchestration Modes: Resolved, Partial, Anonymous"
3 sidebarTitle: "Modes"
4 description: "Explore how ProcureNet's three orchestration modes shape the checkout experience, transport protocol, and available prefill data for each session."
5 ---
concepts/payment-settlement.mdx
+5 -4
@@ -1,5 +1,5 @@
1 ---
2 -title: "USDC Payment Settlement on EVM Networks"
2 +title: "ProcureNet USDC Payment Settlement on EVM Networks"
3 sidebarTitle: "Payment Settlement"
4 description: "Learn how ProcureNet settles payments in USDC across Base, Arbitrum, Polygon, and Ethereum, including field evaluator payout tiers."
5 ---
@@ -77,7 +77,7 @@ Follow these steps to create and confirm a USDC payment.
77 For field evaluation workflows, ProcureNet calculates the USDC payout automatically based on the evaluator's average quality score. You do not need to specify an amount manually — pass the evaluation results when creating the payment request and the bridge applies the correct tier.
78
79 <Note>
80 - Payments for field evaluations include GPS metadata from the evaluator's device when location data is available at sync time. This metadata is stored alongside the transaction record for audit purposes.
80 + Payments for field evaluations are calculated automatically from the submitted evaluation results. You do not need to specify an amount manually — pass the evaluation data when creating the payment request and ProcureNet applies the correct payout tier.
81 </Note>
82
83 | Average Evaluation Score | USDC Payout |
@@ -88,7 +88,7 @@ For field evaluation workflows, ProcureNet calculates the USDC payout automatica
88 | < 5.0 | 0 USDC |
89
90 <Accordion title="How the tier is calculated">
91 - The VCI bridge averages all evaluation scores submitted in a sync batch. If an evaluator submits five evaluations with scores of 8.5, 9.2, 7.8, 8.0, and 9.5, their average is 8.6 — which falls into the ≥ 7.0 tier and triggers a 250 USDC payout. The bridge computes this automatically; no manual tier selection is exposed via the API.
91 + ProcureNet averages all evaluation scores submitted for an assignment. If an evaluator submits five evaluations with scores of 8.5, 9.2, 7.8, 8.0, and 9.5, their average is 8.6 — which falls into the ≥ 7.0 tier and triggers a 250 USDC payout. The platform computes this automatically; no manual tier selection is exposed via the API.
92 </Accordion>
93
94 ## Admin Manual Confirmation
@@ -97,9 +97,10 @@ In exceptional cases — such as on-chain delays or network congestion — an ad
97
98 ```bash
99 curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/manual-confirm \
100 + -H "x-perplexity-mod-key: <api_key>" \
101 -H "x-admin-key: <admin_key>" \
102 -H "Content-Type: application/json" \
102 - -d '{ "payment_id": "pay_xyz", "transaction_hash": "0xabc..." }'
103 + -d '{ "payment_id": "pay_xyz" }'
104 ```
105
106 <Warning>
concepts/session-lifecycle.mdx
+1 -2
@@ -1,5 +1,5 @@
1 ---
2 -title: "ProcureNet Session Lifecycle and State Machine"
2 +title: "ProcureNet Session Lifecycle and State Transitions"
3 sidebarTitle: "Session Lifecycle"
4 description: "Understand how ProcureNet sessions progress through states from creation to completion, and how to drive each transition correctly."
5 ---
@@ -45,7 +45,6 @@ Follow these steps to move a session from creation to completion.
45
46 ```bash
47 curl -X POST https://api.procurenet.io/api/v7/orchestrate \
48 - -H "Authorization: Bearer <JWT>" \
48 -H "Content-Type: application/json" \
49 -d '{
50 "hints": {
concepts/wallet-confidence-score.mdx
+1 -1
@@ -1,5 +1,5 @@
1 ---
2 -title: "What Is the Wallet Confidence Score?"
2 +title: "ProcureNet Wallet Confidence Score (WCS) Explained"
3 sidebarTitle: "WCS"
4 description: "Learn how ProcureNet scores buyer identity signals to determine session mode, transport, and checkout experience at orchestration time."
5 ---
configuration/ai-agents.mdx
+12 -13
@@ -1,14 +1,14 @@
1 ---
2 -title: "OpenClaw AI Agent Swarm Configuration Guide"
2 +title: "OpenClaw AI Agents: Security, Reliability, Diagnostics"
3 sidebarTitle: "AI Agents"
4 -description: "Learn how ProcureNet's OpenClaw worker fleet handles security, reliability, and observability automatically — and what that means for your integration."
4 +description: "Learn how ProcureNet's OpenClaw workers handle webhook security, session reliability, and payment diagnostics automatically for your integration."
5 ---
6
7 -ProcureNet's OpenClaw agent swarm runs a fleet of specialized AI workers that handle security, data reliability, observability, and procurement automation. These agents operate continuously in the background on your behalf — you do not invoke them directly or manage their lifecycle. Instead, you configure their behavior through settings in your integration and interpret the signals they surface, such as trace IDs and webhook retry outcomes.
7 +ProcureNet's OpenClaw agent swarm runs a fleet of specialized AI workers that handle security, data reliability, and observability on your behalf. These agents operate continuously in the background — you do not invoke them directly or manage their lifecycle. Instead, you configure their behavior through settings in your integration and interpret the signals they surface, such as trace IDs and webhook retry outcomes.
8
9 ## Key Worker Classes
10
11 -OpenClaw currently runs 10+ worker classes. The three below have the most direct impact on your day-to-day integration.
11 +OpenClaw runs several worker classes. The three below have the most direct impact on your day-to-day integration.
12
13 <CardGroup cols={3}>
14 <Card title="claw-v1 — Security" icon="shield-halved">
@@ -63,8 +63,8 @@ OpenClaw currently runs 10+ worker classes. The three below have the most direct
63 <Accordion title="Can I configure which agents run?">
64 No. The OpenClaw agent swarm is fully managed by ProcureNet and runs
65 automatically for every account. There is no option to enable or disable
66 - individual workers. All 10+ worker classes are active on your sessions from
67 - the moment you create them.
66 + individual workers. All active worker classes are running on your sessions
67 + from the moment you create them.
68 </Accordion>
69
70 <Accordion title="How do I know if an agent is failing?">
@@ -76,12 +76,11 @@ OpenClaw currently runs 10+ worker classes. The three below have the most direct
76 exactly which worker encountered an error and when.
77 </Accordion>
78
79 -<Accordion title="Are agent skills updated automatically?">
80 - Yes. ProcureNet deploys agent skill updates as part of regular platform
81 - releases. New capabilities are added to the 48-skill manifest without
82 - changing any public API contract, so your integration does not need to be
83 - modified when updates ship. You will see improvements in accuracy and
84 - coverage automatically.
79 +<Accordion title="Are agent capabilities updated automatically?">
80 + Yes. ProcureNet deploys agent updates as part of regular platform releases.
81 + New capabilities are added without changing any public API contract, so your
82 + integration does not need to be modified when updates ship. You will see
83 + improvements in accuracy and coverage automatically.
84 </Accordion>
85
86 <Accordion title="What happens if an agent is temporarily unavailable?">
@@ -95,5 +94,5 @@ OpenClaw currently runs 10+ worker classes. The three below have the most direct
94 ---
95
96 <Note>
98 - OpenClaw currently runs 10+ worker classes with a 48-skill manifest planned. New skills are deployed transparently — your integration code does not need to change to benefit from expanded agent capabilities as they roll out.
97 + Agent updates are deployed transparently as part of regular ProcureNet platform releases. Your integration code does not need to change to benefit from expanded agent capabilities as they roll out.
98 </Note>
configuration/environment.mdx
+3 -3
@@ -1,7 +1,7 @@
1 ---
2 -title: "Configure ProcureNet for Your Environment"
2 +title: "ProcureNet API Keys, Networks, and VCI Bridge Setup"
3 sidebarTitle: "Environment"
4 -description: "Set up your API credentials, choose an EVM payment network, and tune the VCI bridge — everything you need to connect your app to ProcureNet."
4 +description: "Configure API credentials, payment networks, and VCI bridge options to connect your application to ProcureNet's orchestration API."
5 ---
6
7 ProcureNet exposes a set of configuration options you control through your account settings and API keys. This page covers the **customer-configurable** settings only — what you pass in API calls and set in your application. You will not need to touch any infrastructure; every option described here is a value you supply at initialization time or as an HTTP header.
@@ -66,7 +66,7 @@ The `VCIProcureNetBridge` connects your offline VCI evaluation queue to ProcureN
66 When `true`, the bridge automatically polls for on-chain confirmation after
67 creating a payment request — no extra calls needed from your side. Set to
68 `false` if you want to control the confirmation check yourself by calling
69 - `manualConfirmPayment()` explicitly.
69 + `processWalletSettlement()` and `manualConfirmPayment()` explicitly.
70 </ParamField>
71
72 <ParamField body="tenantIdResolver" type="() => string" default="() => 'default-tenant'">
configuration/vector-store.mdx
+33 -65
@@ -1,10 +1,10 @@
1 ---
2 -title: "ProcureNet Local-First Vector Store Configuration"
2 +title: "ProcureNet Vector Store: Indexes and Buyer Data Flow"
3 sidebarTitle: "Vector Store"
4 -description: "Understand how ProcureNet's four vector indexes — wcs_profiles, contract_rules, translations, and entitlements — drive AI lookups in your checkout flows."
4 +description: "Understand how ProcureNet's four vector indexes power buyer resolution, contract validation, localization, and entitlements in your checkout flows."
5 ---
6
7 -ProcureNet uses a local-first vector store to power AI-driven lookups for buyer profiles, contract rules, translations, and entitlements. The store runs on-device alongside the OpenClaw agent swarm, meaning reads are low-latency and survive network interruptions. You do not write vectors yourself — the platform populates and queries the store automatically based on the data you supply to the orchestration API.
7 +ProcureNet uses a local-first vector store to power AI-driven lookups for buyer profiles, contract rules, translations, and entitlements. The store operates alongside the OpenClaw agent swarm, meaning reads are low-latency and survive network interruptions. You do not write vectors yourself — the platform populates and queries the store automatically based on the data you supply to the orchestration API.
8
9 ## The Four Indexes
10
@@ -14,17 +14,17 @@ The vector store contains four named indexes. Each serves a distinct role in the
14 <Card title="wcs_profiles" icon="user">
15 **Type: `scoring`**
16
17 - Stores embedding representations of buyer identity signals. Powers the Wallet Confidence Score engine to resolve sessions as `resolved`, `partial`, or `anonymous`.
17 + Stores buyer identity signals used by the Wallet Confidence Score engine to resolve sessions as `resolved`, `partial`, or `anonymous`. The richer the identity data you pass to `/api/v7/orchestrate`, the more accurately this index can identify returning buyers.
18 </Card>
19 <Card title="contract_rules" icon="file-contract">
20 **Type: `validation`**
21
22 - Holds procurement contract terms and validation logic. Checked during state transitions to ensure orders comply with applicable rules before advancing.
22 + Holds procurement contract terms and validation logic. Checked during state transitions to ensure orders comply with applicable rules before advancing to the next stage.
23 </Card>
24 <Card title="translations" icon="language">
25 **Type: `i18n`**
26
27 - Contains localized string embeddings for checkout UI flows. Enables ProcureNet to serve the correct language and locale to buyers without round-trips to a remote translation service.
27 + Contains localized strings for checkout UI flows. Enables ProcureNet to serve the correct language and locale to buyers without round-trips to a remote translation service.
28 </Card>
29 <Card title="entitlements" icon="badge-check">
30 **Type: `authorization`**
@@ -35,47 +35,15 @@ The vector store contains four named indexes. Each serves a distinct role in the
35
36 ---
37
38 -## Vector Item Structure
39 -
40 -Every item stored in any index shares the same shape, defined in ProcureNet's internal schema.
41 -
42 -<ResponseField name="id" type="string" required>
43 - A unique identifier for this vector item within its index.
44 -</ResponseField>
45 -
46 -<ResponseField name="vector" type="number[]" required>
47 - The embedding float array produced by the index's configured embedding model.
48 - Array length matches the `dimensions` value declared for that index.
49 -</ResponseField>
50 -
51 -<ResponseField name="payload" type="object" required>
52 - Arbitrary metadata attached to the vector item. Shape varies by index type —
53 - for example, `wcs_profiles` payloads contain buyer signal fields, while
54 - `contract_rules` payloads contain rule predicates.
55 -</ResponseField>
56 -
57 -<ResponseField name="updatedAt" type="string (ISO 8601)" required>
58 - Timestamp of the last write to this item. Used by the OpenClaw reliability
59 - worker to detect stale entries and trigger re-embedding.
60 -</ResponseField>
61 -
62 -<ResponseField name="ttlSeconds" type="integer">
63 - Optional expiry in seconds from `updatedAt`. When set, the item is
64 - automatically evicted from the index once the TTL elapses. Commonly applied
65 - to `wcs_profiles` items for short-lived anonymous sessions.
66 -</ResponseField>
67 -
68 ----
69 -
38 ## How Each Index Affects Your Integration
39
40 The indexes work together as a pipeline. Understanding their roles helps you pass the right data at the right time.
41
42 <Steps>
43 <Step title="Buyer signals flow into wcs_profiles">
76 - When you call `POST /api/v7/orchestrate`, ProcureNet embeds the identity
44 + When you call `POST /api/v7/orchestrate`, ProcureNet uses the identity
45 signals you supply in the `hints` object — `customerId`, `email`, `phone`,
78 - and `deviceId` — and queries the `wcs_profiles` index to calculate the
46 + and `deviceId` — to query the `wcs_profiles` index and calculate the
47 Wallet Confidence Score. A richer profile means a higher score and a
48 `resolved` session mode.
49 </Step>
@@ -100,31 +68,31 @@ The indexes work together as a pipeline. Understanding their roles helps you pas
68
69 ---
70
103 -## Schema Reference (Condensed)
104 -
105 -The full index schema follows JSON Schema draft 2020-12. The abbreviated structure below shows the shape of each index object.
106 -
107 -```json JSON
108 -{
109 - "indexes": {
110 - "<index_name>": {
111 - "name": "string",
112 - "type": "i18n | validation | scoring | authorization",
113 - "embeddingModel": "string",
114 - "dimensions": 1536,
115 - "items": [
116 - {
117 - "id": "string",
118 - "vector": [0.021, -0.113, "..."],
119 - "payload": {},
120 - "updatedAt": "2025-01-15T10:30:00Z",
121 - "ttlSeconds": 3600
122 - }
123 - ]
124 - }
125 - }
126 -}
127 -```
71 +## Vector Item Fields
72 +
73 +Every item stored in any index shares the same shape. These fields are managed by ProcureNet — you reference them only when reading diagnostic output or support responses.
74 +
75 +<ResponseField name="id" type="string" required>
76 + A unique identifier for this vector item within its index.
77 +</ResponseField>
78 +
79 +<ResponseField name="payload" type="object" required>
80 + Metadata attached to the vector item. Shape varies by index type —
81 + for example, `wcs_profiles` payloads contain buyer signal fields, while
82 + `contract_rules` payloads contain rule predicates.
83 +</ResponseField>
84 +
85 +<ResponseField name="updatedAt" type="string (ISO 8601)" required>
86 + Timestamp of the last write to this item.
87 +</ResponseField>
88 +
89 +<ResponseField name="ttlSeconds" type="integer">
90 + Optional expiry in seconds from `updatedAt`. When set, the item is
91 + automatically evicted from the index once the TTL elapses. Commonly applied
92 + to `wcs_profiles` items for short-lived anonymous sessions.
93 +</ResponseField>
94 +
95 +---
96
97 <Note>
98 The vector store is managed internally by OpenClaw agents — you do not write vectors directly. Buyer data you pass to `POST /api/v7/orchestrate` is used to populate and query profiles automatically.
guides/escrow-flows.mdx
+3 -3
@@ -1,5 +1,5 @@
1 ---
2 -title: "Use Escrow Flows for High-Value Transactions"
2 +title: "Use Escrow Flows for High-Value Procurement Sessions"
3 sidebarTitle: "Escrow Flows"
4 description: "Trigger and accept ProcureNet escrow on high-value sessions to satisfy compliance requirements and generate an immutable procurement audit trail."
5 ---
@@ -60,7 +60,7 @@ After the audit trail is written, ProcureNet transitions the session to the `fun
60 ## Authorization Requirements
61
62 <Note>
63 - Only the authorized buyer or a delegated party holding a valid JWT with escrow acceptance permissions can call `POST /api/v7/sessions/{id}/escrow-accept`. Calls with an unauthorized or expired JWT return `403 Forbidden`.
63 + Only the authorized buyer or a delegated party holding a valid Bearer JWT with escrow acceptance permissions can call `POST /api/v7/sessions/{id}/escrow-accept`. Calls with an unauthorized or expired JWT return `403 Forbidden`.
64 </Note>
65
66 Ensure your JWT is issued with the correct claims before calling this endpoint. If you are delegating escrow acceptance to a procurement agent or system account, verify that the delegated JWT has the `escrow:accept` scope.
@@ -84,5 +84,5 @@ Ensure your JWT is issued with the correct claims before calling this endpoint.
84 </Accordion>
85
86 <Accordion title="Can I automate escrow acceptance?">
87 - Yes. You can call `POST /api/v7/sessions/{id}/escrow-accept` from a server-side service as long as the request includes a valid JWT with the appropriate permissions. Ensure your automated system includes adequate review logic before accepting — the acceptance is irreversible.
87 + Yes. You can call `POST /api/v7/sessions/{id}/escrow-accept` from a server-side service as long as the request includes a valid Bearer JWT with the appropriate permissions. Ensure your automated system includes adequate review logic before accepting — the acceptance is irreversible.
88 </Accordion>
guides/field-evaluation-payments.mdx
+5 -5
@@ -1,5 +1,5 @@
1 ---
2 -title: "Automate Field Evaluator Payments with VCI Bridge"
2 +title: "Automate Field Evaluator Payments with the VCI Bridge"
3 sidebarTitle: "Field Payments"
4 description: "Automatically pay field evaluators in USDC when their offline assessments sync — no manual intervention required for eligible score tiers."
5 ---
@@ -31,7 +31,7 @@ The bridge intercepts `vci-sync-status`, reads the evaluator's average score acr
31
32 ### Payment Request Is Created and Attached
33
34 -The bridge calls `POST /mods/procurement_wallet/usdc/request` to create a USDC payment request on the configured network. The response includes a `deposit_address` and an optional `qr_code`. Both are attached to the evaluation record for traceability.
34 +The bridge calls `POST /mods/procurement_wallet/usdc/request` to create a USDC payment request on the Base network by default. The response includes a `deposit_address` and an optional `qr_code`. Both are attached to the evaluation record for traceability.
35
36 GPS metadata captured by the field device — latitude, longitude, accuracy, and timestamp — is automatically included in the payment request metadata, creating a location-stamped audit record.
37
@@ -67,11 +67,11 @@ const bridge = new VCIProcureNetBridge(queue, wallet, () => 'tenant_abc');
67
68 ## Supported Networks
69
70 -ProcureNet's USDC bridge supports the following networks. Specify the target network when configuring your wallet client:
70 +ProcureNet's USDC bridge supports the following networks. Payments default to **Base** unless you configure an alternative network:
71
72 <CardGroup cols={2}>
73 <Card title="Base" icon="circle-b">
74 - Low-fee L2 — recommended for high-volume field payment operations.
74 + Low-fee L2 — the default network. Recommended for high-volume field payment operations.
75 </Card>
76 <Card title="Arbitrum" icon="circle-a">
77 High-throughput L2 with strong DeFi ecosystem support.
@@ -98,7 +98,7 @@ window.addEventListener('vci-wallet-sync', (event) => {
98
99 ## Manual Confirmation
100
101 -If you instantiate the bridge with `autoWatch: false`, you are responsible for triggering on-chain confirmation. Call `manualConfirmPayment` with the local evaluation record ID and your admin key.
101 +If you instantiate the bridge with `autoWatch: false`, you are responsible for triggering on-chain confirmation. Call `bridge.manualConfirmPayment` with the local evaluation record ID and your admin key.
102
103 ```typescript
104 const result = await bridge.manualConfirmPayment(localId, adminKey);
guides/integrate-checkout.mdx
+8 -9
@@ -1,5 +1,5 @@
1 ---
2 -title: "Integrate ProcureNet Checkout into Your App"
2 +title: "Integrate ProcureNet Checkout into Your Application"
3 sidebarTitle: "Integrate Checkout"
4 description: "Embed ProcureNet's AI-orchestrated checkout flow into your app — from collecting buyer signals to advancing through session states."
5 ---
@@ -36,19 +36,18 @@ The WCS engine uses these scores to classify the session into one of three modes
36 | < 40 | `anonymous` | WebSocket |
37
38 <Tip>
39 - Pass `deviceId` alongside `email` or `phone` to reach a WCS of 100 even without a `customerId`. A score of 100 unlocks the `resolved` mode and SSE transport — which enables full prefill.
39 + Pass `deviceId` alongside `email` or `phone` to reach a WCS of 100 even without a `customerId`. A score of 100 unlocks the `resolved` mode and SSE transport — which enables full prefill. You can also combine all four signals for a maximum score of 200.
40 </Tip>
41
42 ### Start the Orchestration Session
43
44 -Call `POST /api/v7/orchestrate` with your buyer hints and transaction details. The response includes the `session_id`, WCS score, resolved mode, and the transport your client should connect to.
44 +Call `POST /api/v7/orchestrate` with your buyer hints and transaction details. This endpoint does not require authentication — include whatever buyer signals you have available. The response includes the `session_id`, WCS score, resolved mode, and the transport your client should connect to.
45
46 ```typescript
47 const res = await fetch('https://api.procurenet.io/api/v7/orchestrate', {
48 method: 'POST',
49 headers: {
50 - 'Content-Type': 'application/json',
51 - 'Authorization': `Bearer ${token}`
50 + 'Content-Type': 'application/json'
51 },
52 body: JSON.stringify({
53 amount: 250.00,
@@ -103,7 +102,7 @@ Use the `transport` value from the previous response to open the appropriate rea
102
103 ### Handle Prefill for Resolved Sessions
104
106 -If `mode` is `"resolved"` (WCS ≥ 100), call `GET /api/v7/sessions/{id}/prefill` to retrieve stored buyer data and pre-populate your checkout form. This endpoint is only available for resolved sessions.
105 +If `mode` is `"resolved"` (WCS ≥ 100), call `GET /api/v7/sessions/{id}/prefill` to retrieve stored buyer data and pre-populate your checkout form. This endpoint requires a Bearer JWT and is only available for resolved sessions.
106
107 ```typescript
108 const prefillRes = await fetch(
@@ -125,7 +124,7 @@ const prefillData = await prefillRes.json();
124
125 ### Set the Funding Method
126
128 -Once the buyer has selected a payment method, register it against the session by calling `POST /api/v7/sessions/{id}/funding-method`.
127 +Once the buyer has selected a payment method, register it against the session by calling `POST /api/v7/sessions/{id}/funding-method`. This endpoint requires a Bearer JWT.
128
129 ```typescript
130 const fundingRes = await fetch(
@@ -146,7 +145,7 @@ const fundingRes = await fetch(
145
146 ### Advance Through Session States
147
149 -Call `POST /api/v7/sessions/{id}/transition` to move the session forward through ProcureNet's state machine. Transitions are event-driven — pass the target event name to advance.
148 +Call `POST /api/v7/sessions/{id}/transition` to move the session forward through ProcureNet's state machine. Transitions are event-driven — pass the target event name to advance. This endpoint requires a Bearer JWT.
149
150 ```typescript
151 const transitionRes = await fetch(
@@ -172,7 +171,7 @@ Listen on your stream connection for real-time state change events alongside exp
171 ## Migrating from the Legacy Payments Route
172
173 <Warning>
175 - `POST /api/payments/route` is deprecated and will be removed in a future release. Migrate to `POST /api/v7/orchestrate` as soon as possible.
174 + `POST /api/payments/route` is deprecated and will be removed in a future release. Migrate to `POST /api/v7/orchestrate` as soon as possible to gain WCS scoring, session streaming, and prefill support.
175 </Warning>
176
177 The legacy `POST /api/payments/route` endpoint does not support WCS scoring, session streaming, or prefill. To migrate:
guides/webhooks.mdx
+88 -45
@@ -1,5 +1,5 @@
1 ---
2 -title: "Receive Procurement Approval Webhooks Securely"
2 +title: "Receive and Verify Procurement Approval Webhooks Securely"
3 sidebarTitle: "Webhooks"
4 description: "Verify HMAC-signed Procurement Express callbacks and use approval decisions to resume or terminate your orchestration sessions in real time."
5 ---
@@ -42,31 +42,68 @@ export WEBHOOK_SECRET=your_webhook_secret_here
42
43 In ProcureNet settings, add your server's public URL as a Procurement Express callback target. ProcureNet will `POST` to this URL for every approval decision event.
44
45 +### Configure Raw Body Parsing
46 +
47 +HMAC verification requires the **raw, unparsed request body bytes**. You must configure your framework to capture the raw body before any JSON parsing middleware runs. In Express, use `express.raw()` — not `express.json()` — for your webhook route.
48 +
49 +<Warning>
50 + Do not use `express.json()` (or any body-parsing middleware that parses JSON) on your webhook route. Parsing and re-serializing the body can alter field ordering or whitespace, causing your computed HMAC to differ from ProcureNet's. Use `express.raw({ type: 'application/json' })` to capture the raw bytes before any parsing occurs.
51 +</Warning>
52 +
53 +```typescript
54 +import express from 'express';
55 +
56 +const app = express();
57 +
58 +// Use raw body parsing ONLY for the webhook route
59 +app.post(
60 + '/webhooks/procurement',
61 + express.raw({ type: 'application/json' }),
62 + (req, res) => {
63 + // req.body is now a Buffer containing the raw bytes
64 + }
65 +);
66 +```
67 +
68 ### Implement HMAC Verification
69
70 For every inbound request, compute the expected HMAC signature from the raw request body using your webhook secret and compare it to the `x-procure-signature` header. Reject any request where they do not match.
71
72 ```typescript
50 -import { createHmac } from 'crypto';
51 -
52 -function verifySignature(payload: string, signature: string, secret: string): boolean {
53 - const expected = createHmac('sha256', secret).update(payload).digest('hex');
54 - return `sha256=${expected}` === signature;
73 +import { createHmac, timingSafeEqual } from 'crypto';
74 +
75 +function verifySignature(rawBody: Buffer, signature: string, secret: string): boolean {
76 + const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
77 + const expectedBuf = Buffer.from(expected, 'utf8');
78 + const signatureBuf = Buffer.from(signature, 'utf8');
79 + if (expectedBuf.length !== signatureBuf.length) return false;
80 + return timingSafeEqual(expectedBuf, signatureBuf);
81 }
82
57 -// In your webhook handler:
58 -app.post('/webhooks/procurement', (req, res) => {
59 - const signature = req.headers['x-procure-signature'] as string;
60 - const rawBody = JSON.stringify(req.body);
83 +app.post(
84 + '/webhooks/procurement',
85 + express.raw({ type: 'application/json' }),
86 + (req, res) => {
87 + const signature = req.headers['x-procure-signature'] as string;
88
62 - if (!verifySignature(rawBody, signature, process.env.WEBHOOK_SECRET!)) {
63 - return res.status(401).send('Invalid signature');
64 - }
89 + if (!verifySignature(req.body as Buffer, signature, process.env.WEBHOOK_SECRET!)) {
90 + return res.status(401).send('Invalid signature');
91 + }
92 +
93 + const payload = JSON.parse((req.body as Buffer).toString('utf8'));
94 + const { session_id, decision, actor, reason } = payload;
95
66 - const { session_id, decision, actor } = req.body;
67 - // Resume or cancel the orchestration flow based on the decision
68 - res.status(204).send();
69 -});
96 + if (decision === 'approved') {
97 + // Resume the orchestration session
98 + resumeSession(session_id);
99 + } else if (decision === 'rejected') {
100 + // Terminate session and surface the reason to the buyer
101 + cancelSession(session_id, reason);
102 + }
103 +
104 + res.status(204).send();
105 + }
106 +);
107 ```
108
109 <Warning>
@@ -85,43 +122,49 @@ Respond with `204 No Content` after successfully processing the webhook. Procure
122 An `"approved"` decision resumes a suspended orchestration flow — call `POST /api/v7/sessions/{id}/transition` with the appropriate event to continue. A `"rejected"` decision terminates the session; clean up any pending UI state and notify the buyer.
123 </Note>
124
88 -Use the `decision` field to branch your handler logic:
125 +Use the `decision` field to branch your handler logic. The complete handler combining verification and decision routing looks like this:
126
127 ```typescript
91 -app.post('/webhooks/procurement', (req, res) => {
92 - const signature = req.headers['x-procure-signature'] as string;
93 - const rawBody = JSON.stringify(req.body);
94 -
95 - if (!verifySignature(rawBody, signature, process.env.WEBHOOK_SECRET!)) {
96 - return res.status(401).send('Invalid signature');
128 +app.post(
129 + '/webhooks/procurement',
130 + express.raw({ type: 'application/json' }),
131 + (req, res) => {
132 + const signature = req.headers['x-procure-signature'] as string;
133 +
134 + if (!verifySignature(req.body as Buffer, signature, process.env.WEBHOOK_SECRET!)) {
135 + return res.status(401).send('Invalid signature');
136 + }
137 +
138 + const { session_id, decision, actor, reason } = JSON.parse(
139 + (req.body as Buffer).toString('utf8')
140 + );
141 +
142 + if (decision === 'approved') {
143 + resumeSession(session_id);
144 + } else if (decision === 'rejected') {
145 + cancelSession(session_id, reason);
146 + }
147 +
148 + res.status(204).send();
149 }
98 -
99 - const { session_id, decision, actor, reason } = req.body;
100 -
101 - if (decision === 'approved') {
102 - // Resume the orchestration session
103 - resumeSession(session_id);
104 - } else if (decision === 'rejected') {
105 - // Terminate session and surface the reason to the buyer
106 - cancelSession(session_id, reason);
107 - }
108 -
109 - res.status(204).send();
110 -});
150 +);
151 ```
152
153 ## Signature Verification Reference
154
115 -The `x-procure-signature` header uses the format `sha256=<hex_digest>`. ProcureNet computes the HMAC-SHA256 of the raw JSON request body using your webhook secret. Your verification must use the **raw body bytes** — do not parse and re-serialize the JSON before computing the digest, as field ordering or whitespace differences will cause a mismatch.
155 +The `x-procure-signature` header uses the format `sha256=<hex_digest>`. ProcureNet computes the HMAC-SHA256 of the raw JSON request body using your webhook secret. Your verification must use the **raw body bytes** — do not parse and re-serialize the JSON before computing the digest, as field ordering or whitespace differences will cause a mismatch. Use a timing-safe comparison to prevent timing-based attacks.
156
157 <CodeGroup>
158
159 ```typescript TypeScript
120 -import { createHmac } from 'crypto';
121 -
122 -function verifySignature(payload: string, signature: string, secret: string): boolean {
123 - const expected = createHmac('sha256', secret).update(payload).digest('hex');
124 - return `sha256=${expected}` === signature;
160 +import { createHmac, timingSafeEqual } from 'crypto';
161 +
162 +function verifySignature(rawBody: Buffer, signature: string, secret: string): boolean {
163 + const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
164 + const expectedBuf = Buffer.from(expected, 'utf8');
165 + const signatureBuf = Buffer.from(signature, 'utf8');
166 + if (expectedBuf.length !== signatureBuf.length) return false;
167 + return timingSafeEqual(expectedBuf, signatureBuf);
168 }
169 ```
170
@@ -129,9 +172,9 @@ function verifySignature(payload: string, signature: string, secret: string): bo
172 import hmac
173 import hashlib
174
132 -def verify_signature(payload: str, signature: str, secret: str) -> bool:
175 +def verify_signature(raw_body: bytes, signature: str, secret: str) -> bool:
176 expected = 'sha256=' + hmac.new(
134 - secret.encode(), payload.encode(), hashlib.sha256
177 + secret.encode(), raw_body, hashlib.sha256
178 ).hexdigest()
179 return hmac.compare_digest(expected, signature)
180 ```
introduction.mdx
+2 -6
@@ -4,7 +4,7 @@ sidebarTitle: "Introduction"
4 description: "ProcureNet orchestrates checkout sessions with real-time buyer scoring, AI agent automation, and on-chain USDC payments for field evaluators."
5 ---
6
7 -ProcureNet is an AI-powered procurement and checkout orchestration platform that brings together real-time buyer identity scoring, stateful session management, on-chain payment settlement, and a swarm of intelligent procurement agents — all through a unified API. Whether you're embedding a checkout flow into your storefront, automating supplier procurement, or paying field evaluators for completed work, ProcureNet gives you a single surface to coordinate the entire journey.
7 +ProcureNet is an AI-powered procurement and checkout orchestration platform that brings together real-time buyer identity scoring, stateful session management, on-chain payment settlement, and intelligent procurement automation — all through a unified API. Whether you're embedding a checkout flow into your storefront, automating supplier procurement, or paying field evaluators for completed work, ProcureNet gives you a single surface to coordinate the entire journey.
8
9 <CardGroup cols={2}>
10 <Card title="Quickstart" icon="bolt" href="/quickstart">
@@ -31,7 +31,7 @@ ProcureNet handles four distinct areas of procurement orchestration:
31
32 **USDC Payment Bridge** — Field evaluators who complete offline evaluations receive on-chain USDC payments when their work syncs. The bridge calculates payout tier from average evaluation scores and settles directly to a deposit address on your chosen network (Base, Arbitrum, Polygon, or Ethereum).
33
34 -**OpenClaw AI Agent Swarm** — A swarm of 10+ AI workers runs procurement intelligence tasks in the background: sourcing suppliers, validating contract rules, resolving entitlements, and enriching session context from the local-first vector store.
34 +**Procurement Intelligence** — Automated workers run in the background to handle sourcing, contract validation, and entitlement resolution, enriching session context without requiring additional integration work on your end.
35
36 ## Session Modes
37
@@ -52,7 +52,3 @@ The WCS score your session receives determines which mode — and which real-tim
52 <Note>
53 Your session mode is determined at the moment you call `POST /api/v7/orchestrate`. If your buyer's identity context changes mid-session (for example, they log in), start a new orchestration call with updated hints to re-score and potentially upgrade to a higher mode.
54 </Note>
55 -
56 -## The Local-First Vector Store
57 -
58 -ProcureNet's OpenClaw swarm operates against a local-first vector store that holds four index types: **WCS profiles** for scoring history, **contract rules** for procurement validation, **translations** for i18n content, and **entitlements** for authorization. This store runs on-device, keeping latency low and allowing the swarm to operate even during intermittent connectivity — crucial for field evaluation workflows.
quickstart.mdx
+2 -3
@@ -1,5 +1,5 @@
1 ---
2 -title: "Get Started with ProcureNet Orchestration API Fast"
2 +title: "ProcureNet Quickstart: Run Your First Orchestration Call"
3 sidebarTitle: "Quickstart"
4 description: "Start a WCS-scored procurement session, connect to the real-time stream, and advance your first state machine transition in under 10 minutes."
5 ---
@@ -43,7 +43,6 @@ This guide walks you through the fastest path to a working ProcureNet integratio
43 method: "POST",
44 headers: {
45 "Content-Type": "application/json",
46 - Authorization: `Bearer ${process.env.PROCURENET_JWT}`,
46 },
47 body: JSON.stringify({
48 amount: 1250.00,
@@ -142,7 +141,7 @@ This guide walks you through the fastest path to a working ProcureNet integratio
141 </Tabs>
142
143 <Info>
145 - Keep your stream connection open for the lifetime of the session. ProcureNet emits state transition events, escrow status updates, and swarm intelligence results over this channel in real time.
144 + Keep your stream connection open for the lifetime of the session. ProcureNet emits state transition events, escrow status updates, and procurement intelligence results over this channel in real time.
145 </Info>
146 </Step>
147