1 ---
2 title: "Create a USDC Payment Request — ProcureNet Wallet"
3 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. 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
11 ```http
12 POST /mods/procurement_wallet/usdc/request
13 ```
14
15 ## Authentication
16
17 All requests to the wallet mod endpoints require your mod API key in the `x-perplexity-mod-key` header.
18
19 ```text
20 x-perplexity-mod-key: <your-api-key>
21 ```
22
23 ## Request Body
24
25 <ParamField body="tenant_id" type="string" required>
26 Your tenant identifier. This must match a tenant registered in ProcureNet. Requests for unregistered tenants return `422`.
27 </ParamField>
28
29 <ParamField body="amount_usdc" type="number" required>
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 Amount |
33 |---|---|
34 | ≥ 9.0 | 500 USDC |
35 | ≥ 7.0 | 250 USDC |
36 | ≥ 5.0 | 100 USDC |
37 | < 5.0 | 0 USDC (no payment initiated) |
38 </ParamField>
39
40 <ParamField body="network" type="string" required>
41 The blockchain network on which to route the payment. Accepted values: `base`, `arbitrum`, `polygon`, `ethereum`.
42 </ParamField>
43
44 <ParamField body="token" type="string" required>
45 Token type. Always pass `"USDC"`.
46 </ParamField>
47
48 <ParamField body="memo" type="string" required>
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. Keys and values must be JSON-serializable.
54
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 | `submitted_at` | string | ISO 8601 timestamp of submission |
61 </Expandable>
62 </ParamField>
63
64 ## Code Example
65
66 <CodeGroup>
67 ```typescript TypeScript
68 import { ProcureNetWalletClient } from '@procurenet/wallet-sdk';
69
70 const wallet = new ProcureNetWalletClient(
71 'https://api.procurenet.io',
72 process.env.PROCURENET_MOD_KEY!,
73 { autoWatch: true }
74 );
75
76 const payment = await wallet.createUSDCPayment({
77 tenant_id: 'tenant_abc',
78 amount_usdc: 250,
79 network: 'base',
80 token: 'USDC',
81 memo: 'Procurement evaluation — assignment assign_789',
82 metadata: {
83 evaluator_id: 'eval_456',
84 assignment_id: 'assign_789'
85 }
86 });
87
88 console.log(payment.payment_id); // 'pay_xyz789'
89 console.log(payment.deposit_address); // '0xabc123...'
90 console.log(payment.expires_at); // '2025-09-01T12:00:00Z'
91 ```
92
93 ```bash cURL
94 curl -X POST https://api.procurenet.io/mods/procurement_wallet/usdc/request \
95 -H "Content-Type: application/json" \
96 -H "x-perplexity-mod-key: $PROCURENET_MOD_KEY" \
97 -d '{
98 "tenant_id": "tenant_abc",
99 "amount_usdc": 250,
100 "network": "base",
101 "token": "USDC",
102 "memo": "Procurement evaluation — assignment assign_789",
103 "metadata": {
104 "evaluator_id": "eval_456",
105 "assignment_id": "assign_789"
106 }
107 }'
108 ```
109 </CodeGroup>
110
111 ## Response
112
113 <ResponseField name="payment_id" type="string" required>
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>
118 The on-chain wallet address that will receive the USDC transfer.
119 </ResponseField>
120
121 <ResponseField name="qr_code" type="string">
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">
126 ISO 8601 timestamp after which this payment request is no longer valid. If the on-chain transfer is not confirmed before this time, the request expires and you must create a new one.
127 </ResponseField>
128
129 ### Example Response
130
131 ```json
132 {
133 "payment_id": "pay_xyz789",
134 "deposit_address": "0xabc123def456abc123def456abc123def456abc1",
135 "qr_code": "data:image/png;base64,iVBORw0KGgo...",
136 "expires_at": "2025-09-01T12:00:00Z"
137 }
138 ```
139
140 ## Error Codes
141
142 | Status | Meaning |
143 |---|---|
144 | `400` | Invalid `network` value or `amount_usdc` is zero or negative |
145 | `401` | Missing or invalid `x-perplexity-mod-key` header |
146 | `422` | `tenant_id` does not match a registered ProcureNet tenant |
147
148 <Tip>
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>