WalletConnect Pay Integration Guide for Flutter (via WalletKit)
This guide enables Flutter wallet developers to integrate WalletConnect Pay for processing crypto payment links throughreown_walletkit. The integration allows wallet applications to accept and process payment requests from merchants using the WalletConnect Pay protocol.
Important Approach
Study and adapt, don’t blindly copy. Before implementing, examine how your existing wallet app handles:- Deep links and QR code scanning
- Modal/bottom sheet presentation
- State management patterns
- Signing implementations for different methods
Prerequisites
Before starting, ensure your wallet app has:- WalletKit SDK integrated (
reown_walletkit: ^1.4.0package or newer) - EVM signing capability supporting:
eth_signTypedData_v4(EIP-712 typed data signing)personal_sign(message signing)
- Async/await patterns for handling asynchronous operations
- UI modal/bottom sheet system for presenting payment flows
- Understanding of CAIP-10 account format:
{namespace}:{chainId}:{address}(e.g.,eip155:1:0x1234...)
Core Concepts
Payment Flow Overview
- Payment Link Detection: Identify incoming payment links from QR codes, deep links, or text input
- Get Payment Options: Retrieve available payment methods with merchant information
- WebView Data Collection (optional): Display WebView form for KYC/compliance data if required by the payment
- Sign Actions: Execute wallet signing operations (typically
eth_signTypedData_v4) - Confirm Payment: Submit signatures to complete the transaction
- Handle Result: Display success/failure and handle polling if needed
Key Data Models
| Model | Purpose |
|---|---|
GetPaymentOptionsRequest | Request to fetch available payment options |
PaymentOptionsResponse | Contains payment ID, options, merchant info, and data collection requirements |
PaymentOption | Individual payment option with amount, account, and actions |
Action / WalletRpcAction | Signing request with chain ID, method, and parameters |
CollectDataAction | Optional data collection with WebView URL |
ConfirmPaymentRequest | Request to confirm payment with signatures |
ConfirmPaymentResponse | Payment status and polling information |
PaymentStatus | Enum: requires_action, processing, succeeded, failed, expired |
Step-by-Step Integration
Step 1: Dependency Setup
Thewalletconnect_pay package is already a dependency of reown_walletkit and is re-exported. No additional dependencies are needed.
reown_walletkit:
Step 2: WalletKit Initialization
Pay is automatically initialized when you callwalletKit.init(). No separate Pay configuration is required.
Step 3: Payment Link Detection
UsewalletKit.isPaymentLink() to detect payment links. This check must occur at ALL URI entry points in your app.
- QR code scanner results
- Deep link handlers (cold start and warm start)
- Paste/text input handlers
- Universal link handlers
isPaymentLink() check happens BEFORE any generic HTTPS URL handling to prevent opening payment links in a browser.
Step 4: Get Payment Options
Retrieve available payment options using the wallet’s accounts in CAIP-10 format.Step 5: Handle Data Collection via WebView
Ifresponse.collectData is not null and has a url, display the URL in a WebView for data collection. The hosted form handles rendering, validation, and T&C acceptance.
Important: When using the WebView approach, do not passAddcollectedDatatoconfirmPayment(). The WebView submits data directly to the backend.
webview_flutter and url_launcher to your dependencies:
Step 6: Get Required Payment Actions
If the selected payment option has emptyactions, fetch them explicitly.
Step 7: Sign Payment Actions
CRITICAL: Theparams field contains a JSON string. Handle it appropriately for your signing library.
EIP-712 Typed Data Signing (eth_signTypedData_v4)
Personal Sign
Step 8: Confirm Payment
Submit signatures to complete the payment.Step 9: Handle Payment Result
Complete Payment Flow Example
UI Implementation Guidelines
Recommended Screens/Modals
- Loading State: Show while fetching payment options
- Payment Details: Display merchant info, amount, and payment options
- Data Collection (conditional): Collect required fields
- Processing State: Show while confirming payment
- Result Screen: Success or failure with details
Example Modal Structure
Utility Functions
Format Payment Amount
Format Expiration Time
Date Formatting for Data Collection
Error Handling
Error Types
| Error Class | When Thrown |
|---|---|
GetPaymentOptionsError | Failed to fetch payment options |
GetRequiredActionsError | Failed to fetch signing actions |
ConfirmPaymentError | Failed to confirm payment |
PayInitializeError | Failed to initialize Pay SDK |
Common Error Codes
GetPaymentOptions:PaymentExpired- Payment link has expiredPaymentNotFound- Invalid payment linkInvalidAccount- Provided account format is invalidComplianceFailed- Compliance check failed
InvalidSignature- Signature verification failedPaymentExpired- Payment expired during processRouteExpired- Selected payment route expiredUnsupportedMethod- Signing method not supported
Error Handling Pattern
Common Pitfalls
1. Account Format
Wrong:0x1234...
Correct: eip155:1:0x1234... (CAIP-10 format)
2. Signature Order
CRITICAL: Signatures must be in the same order as actions.3. JSON Params Handling
ThewalletRpc.params is a JSON string. Parse appropriately:
4. Hex Value Normalization
Some hex values may have odd length. Normalize before signing:5. Deep Link Handling Order
Check for payment links BEFORE generic URL handling:6. Empty Actions
Payment options may have emptyactions array initially. Always check and fetch if needed:
Testing
Test Payment Links
Contact WalletConnect for test payment links or use the WalletConnect Pay sandbox environment.Debug Logging
Enable logging during development:Summary
Quick Reference - API Methods
Integration Checklist
- WalletKit initialized with
await walletKit.init() - Payment link detection added to all URI entry points
-
isPaymentLink()check occurs BEFORE generic URL handling - Accounts formatted in CAIP-10 format
-
eth_signTypedData_v4signing implemented - Hex value normalization for typed data signing
- Signature order matches action order
- WebView data collection for compliance (using webview_flutter)
- Error handling for all error types
- Loading states during API calls
- Success/failure result screens
- Polling handled for non-final responses
Reference Implementation
See the complete working implementation in the WalletKit example app:packages/reown_walletkit/example/lib/dependencies/walletkit_service.dartpackages/reown_walletkit/example/lib/walletconnect_pay/(UI modals)packages/reown_walletkit/example/lib/dependencies/chain_services/evm_service.dart(signing)