Stripe Payment Gateway Integration in Mobile App

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Stripe Payment Gateway Integration in Mobile App
Complex
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Stripe Payment Gateway Integration in Mobile Application

Stripe is the technically most mature payment gateway from a mobile SDK perspective. Stripe iOS and Android SDKs cover not only basic card input, but also Apple Pay, Google Pay, 3DS2, Link, and payment method storage via SetupIntent. Selecting the correct flow depends on the task: one-time payment, subscription, or card storage without immediate charge — these are different APIs.

PaymentIntent vs SetupIntent: Which to Use

PaymentIntent — for immediate charge. Created on server, passed to client via client_secret, client confirms.

SetupIntent — for card storage without charge (for example, during registration to charge later via API). Similar flow, but without amount.

The main mistake is creating PaymentIntent on the client. secret_key must never reach the application. Only publishable_key — client-side.

iOS: PaymentSheet and Custom Flow

Stripe offers two approaches: ready-made PaymentSheet (native UI from Stripe) and element-by-element STPPaymentHandler.

PaymentSheet (Recommended for Start)

import StripePaymentSheet

var paymentSheet: PaymentSheet?

func preparePaymentSheet(clientSecret: String, customerId: String, ephemeralKeySecret: String) {
    var config = PaymentSheet.Configuration()
    config.merchantDisplayName = "Your Company"
    config.customer = .init(id: customerId, ephemeralKeySecret: ephemeralKeySecret)
    config.applePay = .init(
        merchantId: "merchant.com.yourcompany.app",
        merchantCountryCode: "US"
    )
    config.defaultBillingDetails.address.country = "RU"
    config.allowsDelayedPaymentMethods = true

    paymentSheet = PaymentSheet(
        paymentIntentClientSecret: clientSecret,
        configuration: config
    )
}

@IBAction func checkoutTapped(_ sender: UIButton) {
    paymentSheet?.present(from: self) { [weak self] result in
        switch result {
        case .completed:
            self?.handleSuccess()
        case .failed(let error):
            print("Payment failed: \(error.localizedDescription)")
        case .canceled:
            break
        }
    }
}

Custom Flow with CardField

If full UI control is needed:

let cardField = STPPaymentCardTextField()

// Confirm payment
STPPaymentHandler.shared().confirmPayment(
    paymentParams,
    with: self
) { [weak self] status, paymentIntent, error in
    switch status {
    case .succeeded:
        self?.handleSuccess()
    case .failed:
        print("Error: \(error?.localizedDescription ?? "")")
    case .canceled:
        break
    @unknown default:
        break
    }
}

Android: PaymentSheet and CardInputWidget

import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

private lateinit var paymentSheet: PaymentSheet

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    paymentSheet = PaymentSheet(this) { result ->
        when (result) {
            is PaymentSheetResult.Completed -> handleSuccess()
            is PaymentSheetResult.Failed -> {
                Log.e("Stripe", result.error.message ?: "Unknown error")
            }
            is PaymentSheetResult.Canceled -> {}
        }
    }
}

fun launchPaymentSheet(clientSecret: String, customerId: String, ephemeralKey: String) {
    val config = PaymentSheet.Configuration(
        merchantDisplayName = "Your Company",
        customer = PaymentSheet.CustomerConfiguration(customerId, ephemeralKey),
        googlePay = PaymentSheet.GooglePayConfiguration(
            environment = PaymentSheet.GooglePayConfiguration.Environment.Production,
            countryCode = "RU",
            currencyCode = "RUB"
        ),
        allowsDelayedPaymentMethods = true
    )

    paymentSheet.presentWithPaymentIntent(clientSecret, config)
}

3DS2: What Happens Under the Hood

Stripe SDK handles 3DS2 automatically within confirmPayment / PaymentSheet.present. When the bank requires verification, SDK opens native 3DS2 challenge (biometry or OTP) directly in the application — without browser redirect. This is important: 3DS1 redirect via WebView often loses the callback, and the transaction hangs.

If your provider returns requires_action in PaymentIntent status — this is normal, Stripe SDK will handle the challenge.

Typical Issues

No such PaymentIntent — client uses client_secret from different environment (test key with live secret or vice versa). Publishable key and client_secret must be from the same environment.

PaymentSheet not opening on Android, no error. Stripe PaymentSheet requires FragmentActivity, not plain Activity. Running from regular Activity — you get silent refusal.

Ephemeral key expired. Stripe Ephemeral Keys live 1 hour. If user sits on payment screen for long — key expires, PaymentSheet crashes trying to load saved payment methods. Must refresh key before opening sheet.

Server Side (Minimal Backend)

# FastAPI / Django / Laravel — logic is identical
stripe.api_key = settings.STRIPE_SECRET_KEY

@app.post("/create-payment-intent")
async def create_payment_intent(amount: int, currency: str = "rub"):
    intent = stripe.PaymentIntent.create(
        amount=amount,  # in kopecks
        currency=currency,
        automatic_payment_methods={"enabled": True},
    )
    return {"clientSecret": intent.client_secret}

Work Scope

  • PaymentSheet or custom card flow implementation on iOS and Android
  • Server endpoint for PaymentIntent / SetupIntent creation
  • Apple Pay and Google Pay integration via Stripe
  • Webhook configuration for final payment status confirmation
  • Testing with Stripe test cards (4242 4242 4242 4242 and 3DS scenarios)

Timeline

3–5 days for full integration with Apple Pay, Google Pay, and 3DS2. Basic card flow only — 1–2 days. Cost calculated individually.