Skip to main content

WalletConnect Pay Integration Guide for Kotlin/Android

This guide enables Android wallet developers to integrate WalletConnect Pay into applications that already have WalletKit configured.By following this guide, your wallet will be able to process crypto payment links, allowing users to pay merchants directly from your app.

Before You Begin

Study First, Then Implement

This document is a reference guide, not boilerplate code to copy-paste. Before implementing:
  1. Study your existing codebase - Understand how URI handling, signing, and navigation work in your app
  2. Follow established patterns - Match your app’s architecture, naming conventions, and code style
  3. Adapt, don’t copy - The code examples show what to do, not necessarily how your specific app should do it

Prerequisites

  • WalletKit SDK integrated and initialized (com.reown:walletkit)
  • Ethereum signing capability (EIP-712 typed data, personal_sign)
  • Kotlin Coroutines for async operations
  • Understanding of your app’s navigation and state management

Dependencies

Architecture Overview

How WalletConnect Pay Works

WalletConnect Pay enables crypto payments through payment links. The flow works as follows:

WalletKit Integration

WalletKit automatically initializes WalletConnectPay during WalletKit.initialize(). The Pay functionality is exposed through the WalletKit.Pay object:

Using the Official Detection Function

WalletKit provides isPaymentLink() to identify payment URIs. Always use this function rather than custom URL parsing to ensure compatibility as the protocol evolves.

Add Detection to All Entry Points

Payment link detection must be added wherever your app processes URIs:
  1. QR Code Scanner
  1. Text Input / Paste
  1. Deep Link Handler
Important: The isPaymentLink() check must precede any generic HTTPS handlers to prevent payment links from accidentally opening in a browser.

Step 2: Implement the Payment Flow

Data Models

WalletKit exposes payment models under Wallet.Model:

Payment Flow Implementation

2.1 Get Payment Options

2.2 Handle Data Collection via WebView (if required)

Some payments require user information (KYC/AML compliance). Data collection requirements are specified per payment option via collectData. Show all options first, then handle data collection after the user selects an option:
When selectedOption.collectData?.url is present, display the URL in a WebView before proceeding with signing. The hosted form handles rendering, validation, and Terms & Conditions acceptance. The WebView communicates completion via JavaScript bridge messages (IC_COMPLETE / IC_ERROR). The form URL accepts optional query parameters (append them with buildFormUrl before loading):
  • prefill — base64url-encoded JSON of known user fields. Keys must match the required fields from collectData.schema (e.g. fullName, dob, pobAddress).
  • themelight 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.

WebView Implementation

2.3 Get Required Payment Actions

After user selects a payment option, get the signing actions:

2.4 Sign the Actions

Sign each WalletRpcAction with the wallet’s private key:
Critical: Pass raw JSON strings directly to signing APIs. Do not parse and reconstruct the JSON data, as this can cause transformation issues leading to signature verification failures.

2.5 Confirm Payment

Submit the signatures to confirm the payment (data collection, if any, was already submitted by the WebView):

Step 3: State Management

Implement a state machine to manage the payment flow:

ViewModel Implementation

Step 4: UI Components

Required Screens

  1. Loading Screen - Show while fetching payment options
  2. Options Screen - List of payment options (tokens/chains). Show an “Info required” badge on options that have collectData != null
  3. Data Collection Screen - WebView for KYC/compliance data (shown after selecting an option that requires IC)
  4. Processing Screen - Show while signing and confirming
  5. Success Screen - Payment completed successfully
  6. Error Screen - Handle failures gracefully

Jetpack Compose Example

Utility Functions

Format Payment Amount

Format Expiry Time

Validate Date Input

Error Handling

Common Errors

WalletKit exposes typed errors for payment operations:

Error Handling Strategy

Troubleshooting

Payment Options Empty

Symptom: getPaymentOptions returns an empty options list. Causes:
  • Wallet address not supported by merchant
  • Chain not supported for this payment
  • Payment link already used or expired
Solution:
  • Verify CAIP-10 account format: eip155:{chainId}:{address}
  • Include all chains your wallet supports
  • Check if payment link is still valid

Signature Verification Failed

Symptom: confirmPayment fails with signature verification error. Causes:
  • Incorrect EIP-712 signing implementation
  • JSON transformation altering the typed data
  • Wrong address used for signing
Solution:
  • Use StructuredDataEncoder for EIP-712 hashing
  • Pass raw JSON strings to signing without parsing/reconstruction
  • Verify the signing address matches the requested address in params

Wrong Chain

Symptom: Transaction fails or signing produces unexpected results. Causes:
  • Not using the chainId from WalletRpcAction
  • Signing with wrong network context
Solution:
  • Always use action.chainId to determine which network to sign for
  • Ensure your wallet’s signing context matches the action’s chain

Payment Status Polling

For PROCESSING status, implement polling:

Complete Flow Example

Reference Implementation

For a complete working example, see the sample wallet implementation:
  • sample/wallet/src/main/kotlin/com/reown/sample/wallet/ui/routes/dialog_routes/payment/PaymentViewModel.kt
  • sample/wallet/src/main/kotlin/com/reown/sample/wallet/ui/routes/dialog_routes/payment/PaymentRoute.kt

Additional Resources