YooKassa Payment Gateway Integration in Mobile Application
YooKassa (formerly Yandex.Kassa) is one of the most popular payment gateways for the Russian market. Mobile SDK supports card payment, SberPay, SBP, Apple Pay, Google Pay, and YooMoney wallet. Integration is built around payment data tokenization on the client with subsequent charge via server API.
Architecture: Tokenization Instead of Credentials
YooKassa does not transmit card data directly to your server. Client SDK creates a payment token — an encrypted object that works once and only for your store. The server uses this token to create a payment via YooKassa API.
iOS: YooKassaPayments SDK
// Podfile
pod 'YooKassaPayments'
// or SPM
.package(url: "https://github.com/yoomoney/yookassa-payments-swift", from: "7.x.x")
Launch payment screen:
import YooKassaPayments
let inputData = TokenizationModuleInputData(
clientApplicationKey: "live_your_client_key", // from YooKassa cabinet
title: "Your Company",
subtitle: "Order #1234",
amount: Amount(value: 1500, currency: .rub),
paymentTypes: [.bankCard, .sberbank, .sbp, .applePay, .yooMoney],
savePaymentMethod: .on, // or .off, .userSelects
isLoggingEnabled: false
)
let viewController = TokenizationAssembly.makeModule(
inputData: inputData,
moduleOutput: self
)
present(viewController, animated: true)
Handle result:
extension PaymentViewController: TokenizationModuleOutput {
func tokenizationModule(
_ module: TokenizationModuleInput,
didTokenize token: Tokens,
paymentMethodType: PaymentMethodType
) {
dismiss(animated: true)
// token.paymentToken — send to server
sendTokenToBackend(token.paymentToken, paymentMethodType: paymentMethodType.rawValue)
}
func didFinish(on module: TokenizationModuleInput, with error: YooKassaPaymentsError?) {
dismiss(animated: true)
if let error = error {
print("YooKassa error: \(error)")
}
}
}
Android: YooKassa Payments SDK
// build.gradle
implementation("ru.yoomoney.sdk.kassa.payments:yookassa-android-sdk:7.x.x")
private val tokenizeLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val token = Checkout.createTokenizationResult(result.data!!)
sendTokenToBackend(
token.paymentToken,
token.paymentMethodType.name
)
}
}
fun startPayment() {
val paymentParameters = PaymentParameters(
amount = Amount(BigDecimal.valueOf(1500), Currency.getInstance("RUB")),
title = "Your Company",
subtitle = "Order #1234",
clientApplicationKey = "live_your_client_key",
shopId = "your_shop_id",
savePaymentMethod = SavePaymentMethod.ON,
paymentMethodTypes = setOf(
PaymentMethodType.BANK_CARD,
PaymentMethodType.SBERBANK,
PaymentMethodType.SBP,
PaymentMethodType.GOOGLE_PAY,
PaymentMethodType.YOO_MONEY
)
)
val intent = Checkout.createTokenizeIntent(this, paymentParameters)
tokenizeLauncher.launch(intent)
}
Server Payment Confirmation
Token from client is passed to server, which creates a payment:
POST https://api.yookassa.ru/v3/payments
Authorization: Basic base64(shopId:secretKey)
Content-Type: application/json
Idempotence-Key: unique-uuid
{
"amount": { "value": "1500.00", "currency": "RUB" },
"capture": true,
"payment_method_data": {
"type": "bank_card"
},
"confirmation": {
"type": "mobile_application",
"return_url": "yourapp://payment/result"
},
"payment_token": "token_from_client",
"description": "Order #1234"
}
If response contains status: pending and confirmation.type: redirect — 3DS requires confirmation. SDK handles this automatically, but with direct API integration need to open confirmation_url in SFSafariViewController / Custom Tabs.
Typical Pitfalls
clientApplicationKey vs secretKey. SDK takes only clientApplicationKey (starts with live_ or test_). secretKey only on server. Mix them up — API returns 401, but message not always obvious.
SavePaymentMethod and offer. With SavePaymentMethod.ON YooKassa requires user to accept recurring payment offer. SDK shows checkbox automatically, but skip it in custom UI — transaction will be rejected.
Work Scope
- YooKassa SDK integration (iOS / Android / Flutter)
- Payment types configuration per project needs
- Server endpoint for payment creation and confirmation
- Webhook setup for final status
- Testing in YooKassa test store
Timeline
2–3 days. Cost calculated individually.







