Developing a Checkout Screen for Mobile Apps
The checkout screen is where users most often abandon the purchase. A long form with address fields, delivery options, and card entry on a mobile screen becomes a trial if not specifically designed for touch interaction. Our team develops such screens considering all platform specifics — from proper KeyboardAvoidingView handling to Apple Pay and Google Pay integration. Practice shows that up to 60% of users abandon checkout with a poorly designed form. Technically, it is the most complex screen in an e-commerce app: payment integration, real-time validation, keyboard handling, multiple scroll zones. In 5 years on the market, we have delivered over 50 checkout screens for iOS and Android, reducing abandoned cart rates by an average of 30-40%. Our experience ensures compliance with all App Store and Google Play requirements.
Why Checkout Is the Most Complex Screen?
The combination of payment requirements, UX nuances, and performance makes checkout a bottleneck. For example, on iOS you must correctly handle PKPaymentAuthorizationViewController on the main thread, otherwise the app crashes. On Android, you must check IsReadyToPayRequest before showing Google Pay. All fields must validate without blocking input, and the keyboard must not cover the active field. We solve these problems using proven patterns.
How We Ensure Payment Security?
PCI DSS prohibits transmitting raw card data through your own backend. Only tokenization via the provider's SDK is allowed. Apple App Review rejects apps with self-hosted card forms for this reason. We use ready-made SDKs: stripe-react-native or native Stripe SDK, CloudPayments SDK, YooKassa. For each provider, we configure tokenization and 3D Secure. As a result, card data never reaches your server.
Payment Integrations
This is the most labor-intensive part. Each provider has its own SDK with specific requirements.
Stripe — stripe-react-native or native Stripe iOS/Android SDK. The CardField component handles card input with auto-formatting and validation. PaymentSheet is a ready-made bottom sheet from Stripe, minimal customization but maximum reliability. For custom UI, use useStripe().confirmPayment() with a PaymentIntent client secret from the backend.
Apple Pay / Google Pay. On iOS — PKPaymentAuthorizationViewController, in React Native via @stripe/stripe-react-native with useApplePay(). On Android — PaymentsClient from Google Pay API + IsReadyToPayRequest. Both buttons are shown only if the payment method is available on the device — stripe.isApplePaySupported() / paymentsClient.isReadyToPay(). Savings on development using ready-made SDKs can reach up to 20%.
| Provider | SDK | Specifics |
|---|---|---|
| Stripe | stripe-react-native | PaymentSheet, CardField, 3D Secure |
| CloudPayments | CloudPayments SDK | Cryptogram, recurring payments |
| YooKassa | YooKassa | Yandex.Kassa, Apple Pay on iOS |
How Payment Integrations Affect Architecture?
Each provider requires its own scenario: Stripe needs a PaymentIntent, CloudPayments requires a cryptogram, YooKassa expects a token. We design a payment layer with an abstract protocol so that switching between providers does not affect the UI. For example, in React Native we use the Provider pattern with a common interface processPayment(token: String). This reduces the cost of modifications when changing the payment gateway.
| Platform | Checkout Implementation Features |
|---|---|
| iOS | PKPaymentAuthorizationViewController, Core Data for address caching, SwiftUI or UIKit |
| Android | Google Pay API, Room for data storage, Jetpack Compose |
| Cross-platform | Unified validation logic, native bridges for payments |
Form Management
A checkout form typically contains 10–15 fields. Without proper navigation between fields (returnKeyType="next" + ref.focus() on the next input) it becomes unbearable. In React Native Hook Form — Controller + useRef array for fields + automatic setFocus on error after submit.
The keyboard is the main pain. KeyboardAwareScrollView from react-native-keyboard-aware-scroll-view works better than the standard KeyboardAvoidingView: it automatically scrolls to the active field and correctly handles height changes on orientation change.
On iOS, numeric fields (postal code, CVV) must open UIKeyboardType.numberPad. decimalPad for amounts. emailAddress for email. The wrong keyboardType is a small detail that all users notice but don't mention aloud.
Validation and UX
Real-time validation is only for fields with a deterministic format: phone, email, postal code, card number. For text fields (name, address) — only on blur (onBlur), otherwise an error like "invalid name" appears on the third letter.
Address autocomplete via Google Places Autocomplete API or Dadata API (for Russia) is a must. Manually entering street, house, and apartment in separate fields increases input time by 3-4 times and delivery errors. Autocomplete reduces form fill time from 3-4 minutes to 30 seconds and cuts delivery errors by 25%.
From practice: a delivery app, React Native + Stripe. When paying with Apple Pay on a physical iPhone XR, the app crashed with NSException immediately after authorization. The cause — PKPaymentAuthorizationController was called from a background thread. Moving it to DispatchQueue.main in the native module solved the problem. The React Native bridge does not guarantee the main thread for callbacks.
Why Is Real-Time Validation Critical?
The user expects instant feedback. If the error is shown only after pressing "Pay", they have to fix multiple fields at once, increasing the likelihood of abandonment. We implement validation on input for fields with a clear format, and for others after losing focus. This improves conversion by 10-15%.
Multi-Step Checkout
For a long checkout we use a stepper (steps: address → delivery → payment → confirmation). Each step is a separate component with its own validation. State is stored in a single store, not passed via props between screens. A ProgressBar on top shows the current step.
The "Back" button must preserve already entered data — do not reset the form when returning to a previous step.
What's Included in the Work
- Address form with autocomplete (via Places API)
- Delivery method selection with cost and time estimation
- List of saved user addresses
- Payment provider integration (Stripe, CloudPayments, YooKassa, and others)
- Apple Pay / Google Pay with availability check
- Real-time validation + API error handling
- Order confirmation screen with number and details
- Storage of last used address and card
- Integration documentation and post-release support
Timeline and Cost
3–5 business days — depends on the number of payment providers, complexity of discount logic, and address validation requirements. Integration of one provider with Apple Pay/Google Pay takes 2–3 days. Cost is calculated individually. We will assess your project for free — contact us to discuss details. Get an engineer's consultation and an accurate timeline estimate today.







