From 6fd1fb6928e8bcf0fca50e53a98f625539e84c1f Mon Sep 17 00:00:00 2001 From: Enes Date: Wed, 2 Sep 2026 16:23:00 +0300 Subject: [PATCH 1/3] =?UTF-8?q?docs(headless-sdk):=20information=20capture?= =?UTF-8?q?=20=E2=80=94=20hosted=20URL=20(primary)=20+=20native=20schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an Information capture section: the hosted collectData.url form as the recommended path (zero UI, via notifyInfoCaptureSubmitted), the native collectData.schema form as the custom-UI alternative, and a deprecation note on collectData.fields. Update the InformationCapture render case to match. --- payments/psps/headless-sdk/implementation.mdx | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/payments/psps/headless-sdk/implementation.mdx b/payments/psps/headless-sdk/implementation.mdx index d660784..eee4119 100644 --- a/payments/psps/headless-sdk/implementation.mdx +++ b/payments/psps/headless-sdk/implementation.mdx @@ -230,7 +230,8 @@ export function Checkout({ paymentId }: { paymentId: string }) { disconnectWallet, selectOption, confirmSelection, - submitInfoCapture + submitInfoCapture, + notifyInfoCaptureSubmitted } = usePaymentSession({ paymentId, seams, wallet }) return
{/* render per snapshot.state — see Step 5 */}
@@ -306,8 +307,12 @@ switch (snapshot.state) { return case 'InformationCapture': - // Render snapshot.collectData.fields, then: - return + // Identity capture — see "Information capture" below. Prefer the hosted form: + return snapshot.collectData?.url ? ( + + ) : ( + + ) case 'OptionSelected': case 'RequiresApproval': @@ -337,6 +342,38 @@ switch (snapshot.state) { That's a full gateway. Connect → options → (optional KYC) → confirm → sign → settle, all driven by the runtime; you only render and call actions. Once a wallet is connected, `disconnectWallet(namespace?)` drops one namespace or all of them. +## Information capture + +Some payments require identity details (name, date of birth, country, terms acceptance) before they can settle — usually for regulatory reasons, often only on a buyer's first payment. When the selected option needs it, the runtime enters the `InformationCapture` state and describes what to collect on `snapshot.collectData`. There are **two ways** to satisfy it. + +### Hosted form (recommended) + +`snapshot.collectData.url` is a WalletConnect-hosted page that renders the exact, always-current identity form and submits it for you. Open it (a new tab, webview, or iframe); when the buyer finishes, call `notifyInfoCaptureSubmitted()` to advance the flow: + +```tsx +const { collectData } = snapshot + +if (collectData?.url) { + // Open the hosted form, e.g. window.open(collectData.url, '_blank') + // …then, once the buyer completes it: + notifyInfoCaptureSubmitted() +} +``` + +You build **no form UI** and never touch identity data yourself — the hosted form submits it to WalletConnect Pay directly, and the payment confirms against the record it already holds. This is the recommended path. + +### Native form (custom UI) + +If you'd rather render the identity form inside your own UI, build it from `snapshot.collectData.schema` — a JSON Schema (`properties`, `required`, `anyOf` for proof-of-birth / proof-of-residence, and a `tosConfirmed` checkbox) — and submit the collected values with `submitInfoCapture(data)`. The runtime sends them with the payment confirmation. + +```tsx + +``` + + + `collectData.fields` (name + date of birth only) is **deprecated** — it under-collects. Drive your form from `collectData.url` (hosted) or `collectData.schema` (native). + + ## Environment variables ```bash .env.local From d946b0eb948ba238ca26ee343fd8df2a95748185 Mon Sep 17 00:00:00 2001 From: Enes Date: Wed, 2 Sep 2026 17:00:54 +0300 Subject: [PATCH 2/3] docs(headless-sdk): IC hosted path is SDK-owned (openInfoCapture) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reframe the hosted information-capture path around openInfoCapture(): one call, the SDK opens the WC-hosted form and detects completion itself — the integrator wires no completion handling. Drops the host-triggered signal framing. Native schema path + fields-deprecation note unchanged. --- payments/psps/headless-sdk/implementation.mdx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/payments/psps/headless-sdk/implementation.mdx b/payments/psps/headless-sdk/implementation.mdx index eee4119..6413437 100644 --- a/payments/psps/headless-sdk/implementation.mdx +++ b/payments/psps/headless-sdk/implementation.mdx @@ -231,7 +231,7 @@ export function Checkout({ paymentId }: { paymentId: string }) { selectOption, confirmSelection, submitInfoCapture, - notifyInfoCaptureSubmitted + openInfoCapture } = usePaymentSession({ paymentId, seams, wallet }) return
{/* render per snapshot.state — see Step 5 */}
@@ -309,7 +309,8 @@ switch (snapshot.state) { case 'InformationCapture': // Identity capture — see "Information capture" below. Prefer the hosted form: return snapshot.collectData?.url ? ( - + // The SDK opens the hosted form, detects completion, and advances — you wire nothing. + ) : ( ) @@ -348,19 +349,13 @@ Some payments require identity details (name, date of birth, country, terms acce ### Hosted form (recommended) -`snapshot.collectData.url` is a WalletConnect-hosted page that renders the exact, always-current identity form and submits it for you. Open it (a new tab, webview, or iframe); when the buyer finishes, call `notifyInfoCaptureSubmitted()` to advance the flow: +When `snapshot.collectData.url` is set, the option wants the WalletConnect-hosted identity form. Call `openInfoCapture()` — from a user gesture (a click) so the popup opens: ```tsx -const { collectData } = snapshot - -if (collectData?.url) { - // Open the hosted form, e.g. window.open(collectData.url, '_blank') - // …then, once the buyer completes it: - notifyInfoCaptureSubmitted() -} + ``` -You build **no form UI** and never touch identity data yourself — the hosted form submits it to WalletConnect Pay directly, and the payment confirms against the record it already holds. This is the recommended path. +That's the whole integration. The SDK opens the hosted form, **detects when the buyer finishes it, and advances the flow itself** — you build no form UI, handle no completion events, and never touch identity data (the hosted form submits it to WalletConnect Pay directly, and the payment confirms against the record it already holds). This is the recommended path. ### Native form (custom UI) From 0b0b45472bcc72e0d77a5f84990a154548ac7bcb Mon Sep 17 00:00:00 2001 From: Enes Date: Wed, 2 Sep 2026 17:30:40 +0300 Subject: [PATCH 3/3] docs(headless-sdk): scope IC to native collectData.schema (drop hosted URL for now) Render the identity form from collectData.schema + submitInfoCapture; deprecate fields. The hosted collectData.url path is parked (cross-origin completion detection blocked by the /collect COOP), so it's not offered to headless users yet. --- payments/psps/headless-sdk/implementation.mdx | 30 ++++--------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/payments/psps/headless-sdk/implementation.mdx b/payments/psps/headless-sdk/implementation.mdx index 6413437..51eacdd 100644 --- a/payments/psps/headless-sdk/implementation.mdx +++ b/payments/psps/headless-sdk/implementation.mdx @@ -230,8 +230,7 @@ export function Checkout({ paymentId }: { paymentId: string }) { disconnectWallet, selectOption, confirmSelection, - submitInfoCapture, - openInfoCapture + submitInfoCapture } = usePaymentSession({ paymentId, seams, wallet }) return
{/* render per snapshot.state — see Step 5 */}
@@ -307,13 +306,8 @@ switch (snapshot.state) { return case 'InformationCapture': - // Identity capture — see "Information capture" below. Prefer the hosted form: - return snapshot.collectData?.url ? ( - // The SDK opens the hosted form, detects completion, and advances — you wire nothing. - - ) : ( - - ) + // Identity capture — render from collectData.schema (see "Information capture" below). + return case 'OptionSelected': case 'RequiresApproval': @@ -345,28 +339,16 @@ That's a full gateway. Connect → options → (optional KYC) → confirm → si ## Information capture -Some payments require identity details (name, date of birth, country, terms acceptance) before they can settle — usually for regulatory reasons, often only on a buyer's first payment. When the selected option needs it, the runtime enters the `InformationCapture` state and describes what to collect on `snapshot.collectData`. There are **two ways** to satisfy it. - -### Hosted form (recommended) - -When `snapshot.collectData.url` is set, the option wants the WalletConnect-hosted identity form. Call `openInfoCapture()` — from a user gesture (a click) so the popup opens: - -```tsx - -``` - -That's the whole integration. The SDK opens the hosted form, **detects when the buyer finishes it, and advances the flow itself** — you build no form UI, handle no completion events, and never touch identity data (the hosted form submits it to WalletConnect Pay directly, and the payment confirms against the record it already holds). This is the recommended path. - -### Native form (custom UI) +Some payments require identity details (name, date of birth, country, terms acceptance) before they can settle — usually for regulatory reasons, often only on a buyer's first payment. When the selected option needs it, the runtime enters the `InformationCapture` state and describes what to collect on `snapshot.collectData`. -If you'd rather render the identity form inside your own UI, build it from `snapshot.collectData.schema` — a JSON Schema (`properties`, `required`, `anyOf` for proof-of-birth / proof-of-residence, and a `tosConfirmed` checkbox) — and submit the collected values with `submitInfoCapture(data)`. The runtime sends them with the payment confirmation. +Render the form from **`snapshot.collectData.schema`** — a JSON Schema (`properties`, `required`, `anyOf` for proof-of-birth / proof-of-residence, and a `tosConfirmed` checkbox) — and submit the collected values with `submitInfoCapture(data)`. The runtime sends them with the payment confirmation; the flow advances on its own. ```tsx ``` - `collectData.fields` (name + date of birth only) is **deprecated** — it under-collects. Drive your form from `collectData.url` (hosted) or `collectData.schema` (native). + `collectData.fields` (name + date of birth only) is **deprecated** — it under-collects. Drive your form from `collectData.schema`. ## Environment variables