diff --git a/payments/psps/headless-sdk/implementation.mdx b/payments/psps/headless-sdk/implementation.mdx
index f2d4996..9b3fd71 100644
--- a/payments/psps/headless-sdk/implementation.mdx
+++ b/payments/psps/headless-sdk/implementation.mdx
@@ -306,8 +306,10 @@ switch (snapshot.state) {
return
case 'InformationCapture':
- // Render snapshot.collectData.fields, then:
- return
+ // Render a form from snapshot.collectData.schema — a JSON Schema whose top-level
+ // "required" array and conditional "anyOf" groups define every mandatory field.
+ // Do not render from the deprecated collectData.fields array: it omits required fields.
+ return
case 'OptionSelected':
case 'RequiresApproval':
diff --git a/payments/wallets/api-first.mdx b/payments/wallets/api-first.mdx
index 896895f..6eae37f 100644
--- a/payments/wallets/api-first.mdx
+++ b/payments/wallets/api-first.mdx
@@ -215,7 +215,11 @@ Data collection is per-option — each payment option may independently have a `
If the selected option's `collectData` has a `url` field, display it in a WebView before confirming. The URL is already scoped to that option's account. The WebView handles form rendering, validation, and T&C acceptance. When the WebView signals completion (`IC_COMPLETE` via JS bridge), proceed to confirm — no need to include `collectedData` in the request.
-If you choose not to use the WebView and instead build your own form, use the `collectData.schema` JSON schema to determine the required fields, collect the values, and pass them as `collectedData` in the confirm request.
+If you choose not to use the WebView and instead build your own form, `collectData.schema` is the single source of truth for which fields to render. Parse the JSON Schema: render an input for each entry in `properties`, treat every field in the top-level `required` array as mandatory, and honor conditional `anyOf` groups (for example, the schema may require **either** place-of-birth or place-of-residence fields). Collect the values and pass them as `collectedData` in the confirm request.
+
+
+Do not build forms from the deprecated `collectData.fields` array. It is retained for backward compatibility only and does not include all required fields (for example, country of residence or birth) — forms built from it will collect incomplete compliance data.
+
### Expiration handling
diff --git a/payments/wallets/overview.mdx b/payments/wallets/overview.mdx
index 58e4b49..6e19df5 100644
--- a/payments/wallets/overview.mdx
+++ b/payments/wallets/overview.mdx
@@ -194,7 +194,7 @@ Wallets can earn interchange-like revenue on eligible WalletConnect Pay payments
- [WalletConnect Terms and Conditions](https://walletconnect.com/terms)
- [WalletConnect Privacy Policy](https://walletconnect.com/privacy)
- The required user information can be sent to WalletConnect using schema in the `collect_data` object.
+ When building custom UI, the JSON Schema in `collectData.schema` is the single source of truth for which fields to render: treat every field in its top-level `required` array as mandatory and honor conditional `anyOf` groups (for example, the schema may require either place-of-birth or place-of-residence fields). Do **not** build forms from the deprecated `fields` array — it does not include all required fields. Submit the collected values as `collectedData` when confirming the payment.
We strongly recommend using the WebView-based flow over building custom native UI. Data collection requirements are driven by regulation and can evolve. The hosted WebView form is maintained and updated centrally so that wallets can automatically pick up changes.
diff --git a/payments/wallets/standalone/flutter.mdx b/payments/wallets/standalone/flutter.mdx
index eea4e47..a105d79 100644
--- a/payments/wallets/standalone/flutter.mdx
+++ b/payments/wallets/standalone/flutter.mdx
@@ -665,11 +665,15 @@ class WalletRpcAction {
```dart
class CollectDataAction {
- final String url; // WebView URL for data collection
- final String? schema; // JSON schema describing required fields
+ final String url; // WebView URL for data collection (recommended)
+ final String? schema; // JSON Schema — source of truth for native-UI forms (parse required + anyOf)
}
```
+
+`CollectDataAction` also exposes a deprecated `fields` property. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
## Error Handling
The SDK throws specific exception types for different error scenarios. All errors extend the abstract `PayError` class, which itself extends `PlatformException`:
diff --git a/payments/wallets/standalone/kotlin.mdx b/payments/wallets/standalone/kotlin.mdx
index 2bac1d5..b161534 100644
--- a/payments/wallets/standalone/kotlin.mdx
+++ b/payments/wallets/standalone/kotlin.mdx
@@ -656,11 +656,15 @@ sealed class RequiredAction {
```kotlin
data class CollectDataAction(
- val url: String, // WebView URL for data collection
- val schema: String? // JSON schema describing required fields
+ val url: String, // WebView URL for data collection (recommended)
+ val schema: String? // JSON Schema — source of truth for native-UI forms (parse required + anyOf)
)
```
+
+`CollectDataAction` also exposes a deprecated `fields` property. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
**Pay.ConfirmPaymentResponse**
```kotlin
diff --git a/payments/wallets/standalone/react-native.mdx b/payments/wallets/standalone/react-native.mdx
index 06f1eaf..d896748 100644
--- a/payments/wallets/standalone/react-native.mdx
+++ b/payments/wallets/standalone/react-native.mdx
@@ -297,7 +297,7 @@ const result = await client.confirmPayment({
paymentId: options.paymentId,
optionId: options.options[0].id,
signatures,
- collectedData, // Include if collectData was present
+ collectedData, // Native UI only — omit when using the WebView flow; build from collectData.schema
});
if (result.status === "succeeded") {
@@ -734,13 +734,17 @@ interface BuyerInfo {
```typescript
interface CollectDataAction {
- /** URL for data collection (displayed in WebView) */
+ /** URL for data collection (displayed in WebView) — recommended */
url: string;
- /** JSON schema describing required fields */
+ /** JSON Schema — source of truth for native-UI forms (parse required + anyOf) */
schema?: string;
}
```
+
+`collectData` in the API response also contains a deprecated `fields` array. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
## Error Handling
The SDK throws typed errors for different failure scenarios:
diff --git a/payments/wallets/standalone/swift.mdx b/payments/wallets/standalone/swift.mdx
index 2d1f275..c214628 100644
--- a/payments/wallets/standalone/swift.mdx
+++ b/payments/wallets/standalone/swift.mdx
@@ -709,11 +709,15 @@ struct WalletRpcAction {
```swift
struct CollectDataAction {
- let url: String // WebView URL for data collection
- let schema: String? // JSON schema describing required fields
+ let url: String // WebView URL for data collection (recommended)
+ let schema: String? // JSON Schema — source of truth for native-UI forms (parse required + anyOf)
}
```
+
+`CollectDataAction` also exposes a deprecated `fields` property. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
**ConfirmPaymentResultResponse**
```swift
diff --git a/payments/wallets/standalone/web.mdx b/payments/wallets/standalone/web.mdx
index 75e94fc..801366e 100644
--- a/payments/wallets/standalone/web.mdx
+++ b/payments/wallets/standalone/web.mdx
@@ -294,7 +294,7 @@ const result = await client.confirmPayment({
paymentId: options.paymentId,
optionId: options.options[0].id,
signatures,
- collectedData, // Include if collectData was present
+ collectedData, // Custom form UI only — omit when using the iframe flow; build from collectData.schema
});
if (result.status === "succeeded") {
@@ -691,13 +691,17 @@ interface BuyerInfo {
```typescript
interface CollectDataAction {
- /** URL for data collection (displayed in iframe) */
+ /** URL for data collection (displayed in iframe) — recommended */
url: string;
- /** JSON schema describing required fields */
+ /** JSON Schema — source of truth for custom form UI (parse required + anyOf) */
schema?: string;
}
```
+
+`collectData` in the API response also contains a deprecated `fields` array. Do not use it to build custom form UI — it does not include all required fields. Use `url` for the iframe flow (recommended) or parse `schema` for custom forms.
+
+
## Error Handling
The SDK throws typed errors for different failure scenarios:
diff --git a/payments/wallets/walletkit/ai-prompts/flutter.mdx b/payments/wallets/walletkit/ai-prompts/flutter.mdx
index a263c5a..ebddc49 100644
--- a/payments/wallets/walletkit/ai-prompts/flutter.mdx
+++ b/payments/wallets/walletkit/ai-prompts/flutter.mdx
@@ -207,7 +207,7 @@ class PaymentResultInfo {
class CollectDataAction {
final String url; // WebView URL for data collection
- final String? schema; // JSON schema describing required fields
+ final String? schema; // JSON Schema — source of truth for native-UI forms (parse required + anyOf); never use the deprecated `fields` property
}
class PaymentInfo {
diff --git a/payments/wallets/walletkit/ai-prompts/kotlin.mdx b/payments/wallets/walletkit/ai-prompts/kotlin.mdx
index c4aa44b..98ae982 100644
--- a/payments/wallets/walletkit/ai-prompts/kotlin.mdx
+++ b/payments/wallets/walletkit/ai-prompts/kotlin.mdx
@@ -165,7 +165,7 @@ data class PaymentOption(
// Data collection action (for KYC/compliance via WebView)
data class CollectDataAction(
val url: String, // WebView URL for data collection
- val schema: String? // JSON schema describing required fields
+ val schema: String? // JSON Schema — source of truth for native-UI forms (parse required + anyOf); never use the deprecated `fields` property
)
// Transaction result details (present when payment already completed)
diff --git a/payments/wallets/walletkit/ai-prompts/react-native.mdx b/payments/wallets/walletkit/ai-prompts/react-native.mdx
index 3ad1616..9ba6509 100644
--- a/payments/wallets/walletkit/ai-prompts/react-native.mdx
+++ b/payments/wallets/walletkit/ai-prompts/react-native.mdx
@@ -550,7 +550,7 @@ interface PayAmount {
interface CollectDataAction {
url: string; // WebView URL for data collection
- schema?: string; // JSON schema describing required fields
+ schema?: string; // JSON Schema — source of truth for native-UI forms (parse required + anyOf); never use the deprecated `fields` array
}
interface Action {
diff --git a/payments/wallets/walletkit/ai-prompts/swift.mdx b/payments/wallets/walletkit/ai-prompts/swift.mdx
index 955e65d..b054e50 100644
--- a/payments/wallets/walletkit/ai-prompts/swift.mdx
+++ b/payments/wallets/walletkit/ai-prompts/swift.mdx
@@ -639,7 +639,7 @@ struct WalletRpcAction {
struct CollectDataAction {
let url: String // WebView URL for data collection
- let schema: String? // JSON schema describing required fields
+ let schema: String? // JSON Schema — source of truth for native-UI forms (parse required + anyOf); never use the deprecated `fields` property
}
struct ConfirmPaymentResultResponse {
diff --git a/payments/wallets/walletkit/flutter.mdx b/payments/wallets/walletkit/flutter.mdx
index ea60d0b..ea873ab 100644
--- a/payments/wallets/walletkit/flutter.mdx
+++ b/payments/wallets/walletkit/flutter.mdx
@@ -607,11 +607,15 @@ enum PaymentStatus {
```dart
class CollectDataAction {
- final String url; // WebView URL for data collection
- final String? schema; // JSON schema describing required fields
+ final String url; // WebView URL for data collection (recommended)
+ final String? schema; // JSON Schema — source of truth for native-UI forms (parse required + anyOf)
}
```
+
+`CollectDataAction` also exposes a deprecated `fields` property. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
## Error Handling
The SDK throws specific exception types for different error scenarios. All errors extend the abstract `PayError` class, which itself extends `PlatformException`:
diff --git a/payments/wallets/walletkit/kotlin.mdx b/payments/wallets/walletkit/kotlin.mdx
index 55627e0..fbe05b1 100644
--- a/payments/wallets/walletkit/kotlin.mdx
+++ b/payments/wallets/walletkit/kotlin.mdx
@@ -666,11 +666,15 @@ data class WalletRpcAction(
```kotlin
data class CollectDataAction(
- val url: String, // WebView URL for data collection
- val schema: String? // JSON schema describing required fields
+ val url: String, // WebView URL for data collection (recommended)
+ val schema: String? // JSON Schema — source of truth for native-UI forms (parse required + anyOf)
)
```
+
+`CollectDataAction` also exposes a deprecated `fields` property. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
**Wallet.Model.ConfirmPaymentResponse**
```kotlin
diff --git a/payments/wallets/walletkit/react-native.mdx b/payments/wallets/walletkit/react-native.mdx
index c37356b..19da534 100644
--- a/payments/wallets/walletkit/react-native.mdx
+++ b/payments/wallets/walletkit/react-native.mdx
@@ -279,7 +279,7 @@ const result = await walletkit.pay.confirmPayment({
paymentId: options.paymentId,
optionId: options.options[0].id,
signatures,
- collectedData, // Optional, if collectData was present
+ collectedData, // Native UI only — omit when using the WebView flow; build from collectData.schema
});
// result.status - "succeeded" | "processing" | "failed" | "expired"
@@ -635,13 +635,17 @@ interface AmountDisplay {
```typescript
interface CollectDataAction {
- /** WebView URL for data collection */
+ /** WebView URL for data collection — recommended */
url: string;
- /** JSON schema describing required fields */
+ /** JSON Schema — source of truth for native-UI forms (parse required + anyOf) */
schema?: string;
}
```
+
+`collectData` in the API response also contains a deprecated `fields` array. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
## Error Handling
Handle errors gracefully in your payment flow:
diff --git a/payments/wallets/walletkit/swift.mdx b/payments/wallets/walletkit/swift.mdx
index d892ebb..1943290 100644
--- a/payments/wallets/walletkit/swift.mdx
+++ b/payments/wallets/walletkit/swift.mdx
@@ -659,11 +659,15 @@ struct WalletRpcAction {
```swift
struct CollectDataAction {
- let url: String // WebView URL for data collection
- let schema: String? // JSON schema describing required fields
+ let url: String // WebView URL for data collection (recommended)
+ let schema: String? // JSON Schema — source of truth for native-UI forms (parse required + anyOf)
}
```
+
+`CollectDataAction` also exposes a deprecated `fields` property. Do not use it to build native UI — it does not include all required fields. Use `url` for the WebView flow (recommended) or parse `schema` for native forms.
+
+
**ConfirmPaymentResultResponse**
```swift
diff --git a/payments/wallets/walletkit/web.mdx b/payments/wallets/walletkit/web.mdx
index 608151a..fa6fff7 100644
--- a/payments/wallets/walletkit/web.mdx
+++ b/payments/wallets/walletkit/web.mdx
@@ -285,7 +285,7 @@ const result = await walletkit.pay.confirmPayment({
paymentId: options.paymentId,
optionId: options.options[0].id,
signatures,
- collectedData, // Optional, if collectData was present
+ collectedData, // Custom form UI only — omit when using the iframe flow; build from collectData.schema
});
// result.status - "succeeded" | "processing" | "failed" | "expired"
@@ -627,13 +627,17 @@ interface AmountDisplay {
```typescript
interface CollectDataAction {
- /** URL for data collection (displayed in iframe) */
+ /** URL for data collection (displayed in iframe) — recommended */
url: string;
- /** JSON schema describing required fields */
+ /** JSON Schema — source of truth for custom form UI (parse required + anyOf) */
schema?: string;
}
```
+
+`collectData` in the API response also contains a deprecated `fields` array. Do not use it to build custom form UI — it does not include all required fields. Use `url` for the iframe flow (recommended) or parse `schema` for custom forms.
+
+
## Error Handling
Handle errors gracefully in your payment flow:
diff --git a/snippets/webview-data-collection-overview.mdx b/snippets/webview-data-collection-overview.mdx
index c4bdc45..3501bd7 100644
--- a/snippets/webview-data-collection-overview.mdx
+++ b/snippets/webview-data-collection-overview.mdx
@@ -54,3 +54,19 @@ The top-level `collectData` on the payment options response is still available f
Do **not** pass `collectedData` to `confirmPayment()` when using the embedded form. The form handles data submission directly.
+
+
+ WalletConnect Pay strongly recommends the embedded form: data collection requirements are driven by regulation and can change, and the hosted form is updated centrally. Wallets that build native UI instead must use `collectData.schema` as the single source of truth for which fields to render:
+
+
+ Do **not** build native forms from the deprecated `fields` array on `collectData`. It is retained for backward compatibility only and does not include all required fields (for example, country of residence or birth). Forms built from `fields` will collect incomplete compliance data.
+
+
+ 1. Parse `schema` — a [JSON Schema](https://json-schema.org/) (draft 2020-12) string
+ 2. Render an input for each entry in `properties` (each has a `title`, `description`, `type`, and format constraints)
+ 3. Treat every field in the top-level `required` array as mandatory
+ 4. Honor conditional requirements in `anyOf` — for example, the schema may require **either** place-of-birth (`pobCountry` + `pobAddress`) **or** place-of-residence (`porCountry` + `porAddress`)
+ 5. Validate values against the schema constraints (`pattern`, `format`, `minLength`, `maxLength`)
+ 6. Ensure the user accepts the [WalletConnect Terms and Conditions](https://walletconnect.com/terms) and [Privacy Policy](https://walletconnect.com/privacy) (`tosConfirmed`)
+ 7. Pass the collected values as `collectedData` to `confirmPayment()` — required when using native UI
+