WalletConnect Pay Integration via WalletKit (Swift)
Integration guide for iOS/Swift wallets that already have WalletKit integrated.
Agent Guidance (For AI Assistants)
Adaptation Principles
-
WalletKit Required - This guide assumes WalletKit is already configured. Pay is accessed via
WalletKit.instance.Pay.*.
-
Configuration Order Matters:
-
CAIP-10 Format Required - All accounts must be in
eip155:{chainId}:{address} format.
-
Result Order Critical - The
data array passed to confirmPayment must match the actions array order exactly.
-
Travel Rule Conditional - Only collect user data when
selectedOption.collectData is non-nil. IC is per-option, not global.
Code Adaptation Guidelines
When adapting for a specific wallet:
- Replace Signing Logic - Use the wallet’s native EIP-712 signing implementation.
- Adapt UI Flow - Match the wallet’s existing design patterns and navigation.
- Account Discovery - Use the wallet’s account management to build CAIP-10 accounts.
- Error Handling - Add wallet-specific error handling and user feedback.
Common Patterns
Prerequisites
- iOS 13.0+
- Swift 5.7+
- WalletKit (reown-swift 2.4.0 or later) already integrated (ships YttriumWrapper 0.10.59; required for the
data parameter in confirmPayment)
- WalletConnect Cloud
PROJECT_ID (Get one)
Architecture Overview
State Machine
IMPORTANT: Pay is auto-configured when you configure WalletKit. No separate Pay configuration needed.
Step 2: Handle Deep Links
Info.plist Configuration
SceneDelegate Implementation
Step 3: Detect Payment Links
Use WalletKit.isPaymentLink() to detect payment links from QR codes or deep links.
Detection Patterns:
pay. hosts (e.g., pay.walletconnect.com)
pay= parameter in WalletConnect URIs
pay_ prefix in bare payment IDs
Step 4: Get Payment Options
CAIP-10 Format: eip155:{chainId}:{address}
Step 5: Complete Payment Flow
CRITICAL: Keep data in the same order as the actions array. Each element of data is either a plain string (a signature or transaction hash) or, for chains like Tron, a JSON-encoded object; WalletConnect Pay forwards each element verbatim to the gateway. See Tron support for the Tron payload.
The signatures: overload of confirmPayment is deprecated in favor of data: and will be removed in a future major version. Existing integrations that pass signatures: keep working; the overload forwards its value to data.
WebView Data Collection
When selectedOption.collectData.url is present, display the URL in a WKWebView. The hosted form handles rendering, validation, and T&C acceptance.
The form URL accepts optional query parameters — append them to selectedOption.collectData.url before loading, preserving existing query parameters:
prefill — base64url-encoded JSON of known user fields. Keys must match the required fields from collectData.schema (e.g. fullName, dob, pobAddress).
theme — light or dark, to match your wallet’s color mode.
themeVariables — a base64url string exported from the WalletConnect Pay Dashboard that overrides design tokens (font, font size, some colors, button/input border radius). Append it verbatim.
Important: When using the WebView approach, do not pass collectedData to confirmPayment(). The WebView submits data directly to the backend.
Core API Reference
Methods
Types
Troubleshooting
Configuration Issues
Deep Link Issues
Payment Failures
Signing Issues
File Checklist
Common Pitfalls
-
Forgetting CAIP-10 format - Accounts must be
eip155:{chainId}:{address}, not just addresses.
-
Wrong result order - The
data array must match the actions array order exactly.
-
Skipping WebView data collection - Always check
selectedOption.collectData?.url after the user selects an option and show the WebView before calling getRequiredPaymentActions.
-
Not handling cold start - Deep links on app launch need delayed handling.
-
Not dispatching on RPC method — Always check
action.walletRpc.method and use the appropriate handler. For example, eth_signTypedData_v4 requires EIP-712 signing, while eth_sendTransaction requires sending a transaction on-chain.
-
Missing chains - Provide accounts for all chains you support to maximize payment options.
Testing
-
Enable Logging:
-
Test Both Deep Link Formats:
- WC URI:
yourwallet://?uri=wc:abc...&pay=pay_xyz
- POS:
yourwallet://walletconnectpay?paymentId=pay_xyz
-
Test Cold vs Warm Start:
- Cold: Kill app, open deep link
- Warm: App in background, open deep link
Support