Raw
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <title>ProcureNet — Funding Method Picker</title>
7 <link rel="stylesheet" href="styles.css" />
8 </head>
9 <body>
10 <div class="page">
11 <header class="header">
12 <div class="brand">
13 <span class="brand-mark" aria-hidden="true"></span>
14 <div>
15 <p class="eyebrow">ProcureNet v7</p>
16 <h1>Checkout funding method</h1>
17 </div>
18 </div>
19 <p class="header-meta">Session <code id="sessionIdDisplay">sess_demo_001</code></p>
20 </header>
21
22 <main class="card">
23 <section class="section">
24 <h2>API connection</h2>
25 <p class="muted">Values persist in <code>localStorage</code>. Leave JWT empty only when using Preview only — live submit requires a Bearer token.</p>
26 <div class="field-grid">
27 <label class="field field-span">
28 <span>API base URL</span>
29 <input id="apiBase" name="apiBase" type="url" autocomplete="off" placeholder="https://api.procurenet.io" />
30 </label>
31 <label class="field field-span">
32 <span>Bearer JWT <em>(never hardcoded)</em></span>
33 <input id="bearerJwt" name="bearerJwt" type="password" autocomplete="off" placeholder="Paste access token" />
34 </label>
35 <label class="field field-span">
36 <span>Session ID</span>
37 <input id="sessionId" name="sessionId" autocomplete="off" placeholder="sess_demo_001" />
38 </label>
39 <label class="field field-span">
40 <span>Fee recipient <em>(override platform default)</em></span>
41 <input id="feeRecipient" name="feeRecipient" autocomplete="off" spellcheck="false" maxlength="42" placeholder="0xD0Fb43F2e9b4Dcd4C9FB70DA89385f77086cb778" />
42 </label>
43 <label class="field">
44 <span>Amount <em>(optional, for fee estimate)</em></span>
45 <input id="amount" name="amount" inputmode="decimal" autocomplete="off" placeholder="250.00" />
46 </label>
47 <label class="field">
48 <span>Fee asset</span>
49 <select id="feeAsset" name="feeAsset">
50 <option value="usdc" selected>usdc</option>
51 <option value="eth">eth</option>
52 </select>
53 </label>
54 </div>
55 <div class="fee-line" id="feeLine" role="status" aria-live="polite">
56 <span class="fee-label">Platform fee</span>
57 <span class="fee-value" id="feeLineText">1% → 0xD0Fb…b778</span>
58 <span class="fee-estimate" id="feeEstimate" hidden></span>
59 </div>
60 <label class="toggle">
61 <input type="checkbox" id="previewOnly" name="previewOnly" />
62 <span>Preview only — build JSON, do not call the API</span>
63 </label>
64 </section>
65
66 <section class="section">
67 <h2>Payment method</h2>
68 <p class="muted">Choose how this procurement session will be funded. The payload below mirrors <code>POST /api/v7/sessions/{id}/funding-method</code>.</p>
69
70 <div class="method-grid" role="radiogroup" aria-label="Payment method">
71 <label class="method-option">
72 <input type="radio" name="method" value="usdc" checked />
73 <span class="method-face">
74 <span class="method-title">USDC</span>
75 <span class="method-sub">On-chain stablecoin</span>
76 </span>
77 </label>
78 <label class="method-option">
79 <input type="radio" name="method" value="card" />
80 <span class="method-face">
81 <span class="method-title">Card</span>
82 <span class="method-sub">Credit or debit</span>
83 </span>
84 </label>
85 <label class="method-option">
86 <input type="radio" name="method" value="bank_transfer" />
87 <span class="method-face">
88 <span class="method-title">ACH</span>
89 <span class="method-sub">US bank transfer</span>
90 </span>
91 </label>
92 <label class="method-option">
93 <input type="radio" name="method" value="eth_wallet" />
94 <span class="method-face">
95 <span class="method-title">ETH wallet</span>
96 <span class="method-sub">Native ether</span>
97 </span>
98 </label>
99 </div>
100 </section>
101
102 <section class="section panel" id="panel-usdc" data-panel="usdc">
103 <h3>Network</h3>
104 <label class="field">
105 <span>Blockchain network</span>
106 <select id="network" name="network">
107 <option value="base" selected>Base (recommended)</option>
108 <option value="arbitrum">Arbitrum</option>
109 <option value="polygon">Polygon</option>
110 <option value="ethereum">Ethereum</option>
111 </select>
112 </label>
113 </section>
114
115 <section class="section panel" id="panel-card" data-panel="card" hidden>
116 <h3>Card</h3>
117 <p class="muted">Card collection is handled by your PCI-compliant vault in production. This demo only binds <code>method: "card"</code>.</p>
118 </section>
119
120 <section class="section panel" id="panel-ach" data-panel="bank_transfer" hidden>
121 <h3>ACH bank account</h3>
122 <div class="field-grid">
123 <label class="field">
124 <span>Routing number <em>(ABA, 9 digits)</em></span>
125 <input id="routing_number" name="routing_number" inputmode="numeric" autocomplete="off" maxlength="9" placeholder="021000021" />
126 </label>
127 <label class="field">
128 <span>Account number</span>
129 <input id="account_number" name="account_number" inputmode="numeric" autocomplete="off" maxlength="17" placeholder="123456789012" />
130 </label>
131 <label class="field">
132 <span>Account type</span>
133 <select id="account_type" name="account_type">
134 <option value="checking" selected>Checking</option>
135 <option value="savings">Savings</option>
136 </select>
137 </label>
138 <label class="field field-span">
139 <span>Account holder name</span>
140 <input id="account_holder_name" name="account_holder_name" autocomplete="name" maxlength="100" placeholder="Acme Procurement LLC" />
141 </label>
142 </div>
143 <p class="hint">Send routing and account numbers as strings so leading zeros are preserved. Full account numbers are never returned by the API.</p>
144 </section>
145
146
147 <section class="section panel" id="panel-eth" data-panel="eth_wallet" hidden>
148 <h3>ETH wallet</h3>
149 <div class="field-grid">
150 <label class="field field-span">
151 <span>Wallet address <em>(0x + 40 hex)</em></span>
152 <input id="wallet_address" name="wallet_address" autocomplete="off" spellcheck="false" maxlength="42" placeholder="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0" />
153 </label>
154 <label class="field field-span">
155 <span>ENS name <em>(optional)</em></span>
156 <input id="ens_name" name="ens_name" autocomplete="off" maxlength="255" placeholder="treasury.acme.eth" />
157 </label>
158 <label class="field field-span">
159 <span>Network</span>
160 <select id="eth_network" name="eth_network">
161 <option value="ethereum" selected>Ethereum (default)</option>
162 <option value="base">Base</option>
163 <option value="arbitrum">Arbitrum</option>
164 <option value="polygon">Polygon</option>
165 </select>
166 </label>
167 </div>
168 <p class="hint">Only the public address is sent. Never paste a private key or seed phrase into this form.</p>
169 </section>
170
171 <p class="form-error" id="formError" hidden role="alert"></p>
172
173 <div class="actions">
174 <button type="button" class="btn btn-primary" id="submitBtn">Submit funding method</button>
175 <button type="button" class="btn btn-ghost" id="resetBtn">Reset form</button>
176 </div>
177 </main>
178
179 <aside class="card payload-card">
180 <div class="payload-header">
181 <h2>Request</h2>
182 <span class="badge" id="payloadBadge">Idle</span>
183 </div>
184 <p class="muted endpoint">
185 <span class="verb">POST</span>
186 <code id="endpointPath">/api/v7/sessions/sess_demo_001/funding-method</code>
187 </p>
188 <pre id="payloadOut" class="payload" aria-live="polite">{ /* choose a method and submit */ }</pre>
189 <p class="hint" id="requestHint">Live POST uses Authorization: Bearer and Content-Type: application/json. Enable Preview only to skip the network call.</p>
190 </aside>
191
192 <aside class="card payload-card" id="responseCard">
193 <div class="payload-header">
194 <h2>Response</h2>
195 <span class="badge" id="responseBadge">—</span>
196 </div>
197 <p class="muted" id="responseMeta">No response yet.</p>
198 <pre id="responseOut" class="payload" aria-live="polite">{ /* submit to see status and body */ }</pre>
199 </aside>
200
201 <footer class="footer">
202 <p>Institutional checkout demo · Omnipay / ProcureNet docs</p>
203 </footer>
204 </div>
205 <script src="app.js"></script>
206 </body>
207 </html>