/yookassa-payments-swift

This library allows implementing payment acceptance into mobile apps on iOS and works as an extension to the YooMoney API

Primary LanguageSwiftMIT LicenseMIT

YooMoney for Business Payments SDK (YooKassaPayments)

Platform GitHub tag Documentation License

This library allows implementing payment acceptance into mobile apps on iOS and works as an extension to the YooMoney API.
The mobile SDK contains ready-made payment interfaces (the payment form and everything related to it).
Using the SDK, you can receive tokens for processing payments via bank cards, Apple Pay, Sberbank Online, or YooMoney wallets.


Changelog

Link to the Changelog

Migration guide

Link to the Migration guide

Adding dependencies

CocoaPods

  1. Install CocoaPods version 1.10.0 or higher.
gem install cocoapods

Official documentation for installing CocoaPods.
Available CocoaPods versions.

  1. Create Podfile

CocoaPods provides the pod init command for creating Podfile with default settings.

  1. Add dependencies to Podfile.
    Example of Podfile from the demo app.
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/yoomoney-tech/cocoa-pod-specs.git'

platform :ios, '10.0'
use_frameworks!

target 'Your Target Name' do
  pod 'YooKassaPayments',
    :git => 'https://github.com/yoomoney/yookassa-payments-swift.git',
    :tag => 'tag'
end

Your Target Name: name of the target in Xcode for your app.
tag: SDK version. You can find information about the latest version in the releases section on github.

If you use static linkage, you need to activate the cocoapods-user-defined-build-types plugin:

source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/yoomoney-tech/cocoa-pod-specs.git'

plugin 'cocoapods-user-defined-build-types'
enable_user_defined_build_types!

platform :ios, '10.0'

target 'Your Target Name' do
  pod 'YooKassaPayments',
    :build_type => :dynamic_framework,
    :git => 'https://github.com/yoomoney/yookassa-payments-swift.git',
    :tag => 'tag'
end
  1. Run the pod install command

Carthage

At the moment, Carthage is not supported.

Quick integration

  1. Create TokenizationModuleInputData (you'll need a key for client apps from the YooMoney Merchant Profile). Payment parameters (currency and amount) and payment form parameters which users will see during the payment (payment methods, store name, and order description) are specified in this model.

To work with YooKassaPayments entities, import dependencies to the original file

import YooKassaPayments

Example for creating TokenizationModuleInputData:

let clientApplicationKey = "<Key for client apps>"
let amount = Amount(value: 999.99, currency: .rub)
let tokenizationModuleInputData =
          TokenizationModuleInputData(clientApplicationKey: clientApplicationKey,
                                      shopName: "Space objects",
                                      purchaseDescription: """
                                                            An extra bright comet, rotation period: 112 years
                                                            """,
                                      amount: amount,
                                      savePaymentMethod: .on)
  1. Create TokenizationFlow with the .tokenization case and enter TokenizationModuleInputData.

Example of creating TokenizationFlow:

let inputData: TokenizationFlow = .tokenization(tokenizationModuleInputData)
  1. Create ViewController from TokenizationAssembly and put it on the screen.
let viewController = TokenizationAssembly.makeModule(inputData: inputData,
                                                       moduleOutput: self)
present(viewController, animated: true, completion: nil)

You need to specify the object which implements the TokenizationModuleOutput in moduleOutput.

  1. Implement the TokenizationModuleOutput protocol.
extension ViewController: TokenizationModuleOutput {
    func tokenizationModule(
        _ module: TokenizationModuleInput,
        didTokenize token: Tokens,
        paymentMethodType: PaymentMethodType
    ) {
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            self.dismiss(animated: true)
        }
        // Send the token to your system
    }

    func didFinish(
        on module: TokenizationModuleInput,
        with error: YooKassaPaymentsError?
    ) {
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            self.dismiss(animated: true)
        }
    }

    func didSuccessfullyConfirmation(
        paymentMethodType: PaymentMethodType
    ) {
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            // Create a success screen after confirmation is completed (3DS or SberPay)
            self.dismiss(animated: true)
            // Display the success screen
        }
    }
}

Close the SDK module and send the token to your system. After that, create a payment via the YooMoney API, enter the token you received in the SDK in the payment_token parameter. When a payment is created, the confirmation method depends on the payment method selected by the user. It's sent with the token in paymentMethodType.

Available payment methods

The following payment methods are currently supported in SDK for iOS:

.yooMoney: YooMoney (payments via the wallet or linked cards)
.bankCard: bank cards (cards can be scanned)
.sberbank: SberPay (with confirmation via the Sberbank Online mobile app if it's installed; otherwise, payments will be confirmed via text messages)
.applePay: Apple Pay

Setting up payment methods

You can configure payment methods.
To do that, you need to enter a model of the TokenizationSettings type in the tokenizationSettings parameter when creating TokenizationModuleInputData.

Additional configuration is required for some payment methods (see below).
By default, all available payment methods are used.

// Create empty OptionSet PaymentMethodTypes
var paymentMethodTypes: PaymentMethodTypes = []

if <Condition for bank cards> {
    // Adding the `.bankCard` element to paymentMethodTypes
    paymentMethodTypes.insert(.bankCard)
}

if <Condition for Sberbank Online> {
    // Adding the `.sberbank` element to paymentMethodTypes
    paymentMethodTypes.insert(.sberbank)
}

if <Condition for YooMoney> {
    // Adding the `.yooMoney` element to paymentMethodTypes
    paymentMethodTypes.insert(.yooMoney)
}

if <Condition for Apple Pay> {
    // Adding the `.applePay` element to paymentMethodTypes
    paymentMethodTypes.insert(.applePay)
}

let tokenizationSettings = TokenizationSettings(paymentMethodTypes: paymentMethodTypes)

Now use tokenizationSettings when initializing TokenizationModuleInputData.

YooMoney

To add YooMoney as a payment method, you need to:

  1. Receive client id of the YooMoney authorization center.
  2. Enter client id in the moneyAuthClientId parameter when creating TokenizationModuleInputData

How to get client id of the YooMoney authorization center

  1. Sign in at yookassa.ru
  2. Go to the page for signing up in the authorization center: yookassa.ru/oauth/v2/client
  3. Click Sign up
  4. Fill in the following fields:
    4.1. "Name": a required field, it's displayed in the list of apps and when rights are provided.
    4.2. "Description": an optional field, it's displayed to the user in the list of apps.
    4.3. "Link to app's website": an optional field, it's displayed to the user in the list of apps.
    4.4. "Confirmation code": select Specify in Callback URL, you can enter any value, for example, a link to a website.
  5. Select accesses:
    5.1. YooMoney wallet -> View
    5.2. YooMoney account -> View
  6. Click Sign up

Entering client id in the moneyAuthClientId parameter

Enter client id in the moneyAuthClientId parameter when creating TokenizationModuleInputData

let moduleData = TokenizationModuleInputData(
    ...
    moneyAuthClientId: "client_id")

To process a payment:

  1. Enter .yooMoney as the value in paymentMethodTypes. when creating TokenizationModuleInputData
  2. Receive a token.
  3. Create a payment with the token via the YooMoney API.

Support of authorization via the mobile app

  1. You need to specify applicationScheme, the scheme for returning to the app after a successful sign-in to YooMoney via the mobile app, in TokenizationModuleInputData.

Example of applicationScheme:

let moduleData = TokenizationModuleInputData(
    ...
    applicationScheme: "examplescheme://"
  1. Import the YooKassaPayments dependency in AppDelegate:

    import YooKassaPayments
  2. Add processing links via YKSdk in AppDelegate:

func application(
    _ application: UIApplication,
    open url: URL,
    sourceApplication: String?,
    annotation: Any
) -> Bool {
    return YKSdk.shared.handleOpen(
        url: url,
        sourceApplication: sourceApplication
    )
}

@available(iOS 9.0, *)
func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
    return YKSdk.shared.handleOpen(
        url: url,
        sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
    )
}
  1. Add the following rows to Info.plist:
<key>LSApplicationQueriesSchemes</key>
<array>
	<string>yoomoneyauth</string>
</array>
<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleTypeRole</key>
		<string>Editor</string>
		<key>CFBundleURLName</key>
		<string>${BUNDLE_ID}</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>examplescheme</string>
		</array>
	</dict>
</array>

where examplescheme is the scheme for opening your app that you specified in applicationScheme when creating TokenizationModuleInputData. This scheme will be used to open you app after a successful sign-in to YooMoney via the mobile app.

Bank cards

  1. Enter .bankcard as the value in paymentMethodTypes when creating TokenizationModuleInputData.
  2. Receive a token.
  3. Create a payment with the token via the YooMoney API.

SberPay

Using the SDK, you can process payments via Sberbank's "Mobile banking". Payments are confirmed via the Sberbank Online app if it's installed or otherwise via text messages.

You need to specify applicationScheme, the scheme for returning to the app after a successful payment via SberPay in the Sberbank Online app, in TokenizationModuleInputData.

Example of applicationScheme:

let moduleData = TokenizationModuleInputData(
    ...
    applicationScheme: "examplescheme://"

To process a payment:

  1. Enter .sberbank as the value in paymentMethodTypes when creating TokenizationModuleInputData.
  2. Receive a token.
  3. Create a payment with the token via the YooMoney API.

Payment confirmation via the Sberbank Online app:

  1. Import the YooKassaPayments dependency in AppDelegate:

    import YooKassaPayments
  2. Add processing link via YKSdk in AppDelegate:

func application(
    _ application: UIApplication,
    open url: URL,
    sourceApplication: String?,
    annotation: Any
) -> Bool {
    return YKSdk.shared.handleOpen(
        url: url,
        sourceApplication: sourceApplication
    )
}

@available(iOS 9.0, *)
func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
    return YKSdk.shared.handleOpen(
        url: url,
        sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
    )
}
  1. Add the following rows to Info.plist:
<key>LSApplicationQueriesSchemes</key>
<array>
	<string>sberpay</string>
</array>
<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleTypeRole</key>
		<string>Editor</string>
		<key>CFBundleURLName</key>
		<string>${BUNDLE_ID}</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>examplescheme</string>
		</array>
	</dict>
</array>

where examplescheme is the scheme for opening your app that you specified in applicationScheme when creating TokenizationModuleInputData. This scheme will be used to open you app after a successful payment via SberPay.

  1. Implement the didSuccessfullyConfirmation(paymentMethodType:) method of the TokenizationModuleOutput protocol which will be called after a successful payment confirmation (see Setting up payment confirmation).

Apple Pay

  1. To implement Apple Pay, you need to provide a certificate, using which Apple will encrypt bank card details, to YooMoney.

In order to do it:

  • Contact your manager and ask them to create a request for a certificate (.csr) for you.
  • Create a certificate in Apple Developer Tools (use .csr).
  • Download the certificate you created and send it to your manager.

Full manual (see Section 2. Exchanging certificates with Apple)

  1. Enable Apple Pay in Xcode.

To process a payment:

  1. You need to enter the apple pay identifier in the applePayMerchantIdentifier parameter when initializing the TokenizationModuleInputData object.
let moduleData = TokenizationModuleInputData(
    ...
    applePayMerchantIdentifier: "com.example.identifier"
  1. Receive a token.
  2. Create a payment with the token via the YooMoney API.

Description of public parameters

TokenizationFlow

Enum which determines the logic of how the SDK operates.

Case Type Description
tokenization TokenizationFlow Receives the TokenizationModuleInputData model as input. Logic for tokenizing multiple payment method options: Bank card, YooMoney, Sberbank Online, or Apple Pay
bankCardRepeat TokenizationFlow Receives the BankCardRepeatModuleInputDatamodel as input. Logic for tokenizing saved payment methods using the payment method ID

YooKassaPaymentsError

Enum with possible errors which can be processed in the func didFinish(on module:, with error:) method

Case Type Description
paymentMethodNotFound Error No saved payment methods were found using paymentMethodId.

TokenizationModuleInputData

Required parameters:

Parameter Type Description
clientApplicationKey String Key for client apps from the YooMoney Merchant Profile
shopName String Store name in the payment form
purchaseDescription String Order description in the payment form
amount Amount Object containing the order amount and currency
savePaymentMethod SavePaymentMethod Object containing the logic for determining if it's going to be a recurring payment

Optional parameters:

Parameter Type Description
gatewayId String By default: nil. Used if you have multiple payment gateways with different IDs.
tokenizationSettings TokenizationSettings The standard initializer with all the payment methods is used by default. This parameter is used for setting up tokenization (payment methods and the YooMoney logo).
testModeSettings TestModeSettings By default: nil. Test mode settings.
cardScanning CardScanning By default: nil. Feature of scanning bank cards.
applePayMerchantIdentifier String By default: nil. Apple Pay merchant ID (required for payments via Apple Pay).
returnUrl String By default: nil. URL of the page (only https supported) where you need to return after completing 3-D Secure. Only required for custom implementation of 3-D Secure. If you use startConfirmationProcess(confirmationUrl:paymentMethodType:), don't specify this parameter.
isLoggingEnabled Bool By default: false. Enables logging of network requests.
userPhoneNumber String By default: nil. User's phone number.
customizationSettings CustomizationSettings The blueRibbon color is used by default. Color of the main elements, button, switches, and input fields.
moneyAuthClientId String By default: nil. ID for the center of authorizationin the YooMoney system
applicationScheme String By default: nil. Scheme for returning to the app after a successful payment via Sberpay in the Sberbank Online app or after a successful sign-in to YooMoney via the mobile app.
customerId String By default: nil. Unique customer id for your system, ex: email or phone number. 200 symbols max. Used by library to save user payment method and display saved methods. It is your responsibility to make sure that a particular customerId identifies the user, which is willing to make a purchase. For example use two-factor authentication. Using wrong id will let the user to use payment methods that don't belong to this user.

BankCardRepeatModuleInputData

Required parameters:

Parameter Type Description
clientApplicationKey String Key for client apps from the YooMoney Merchant Profile
shopName String Store name in the payment form
purchaseDescription String Order description in the payment form
paymentMethodId String ID of the saved payment method
amount Amount Object containing the order amount and currency
savePaymentMethod SavePaymentMethod Object containing the logic for determining if it's going to be a recurring payment

Optional parameters:

Parameter Type Description
testModeSettings TestModeSettings By default: nil. Test mode settings.
returnUrl String By default: nil. URL of the page (only https supported) where you need to return after completing 3-D Secure. Only required for custom implementation of 3-D Secure. If you use startConfirmationProcess(confirmationUrl:paymentMethodType:), don't specify this parameter.
isLoggingEnabled Bool By default: false. Enables logging of network requests.
customizationSettings CustomizationSettings The blueRibbon color is used by default. Color of the main elements, button, switches, and input fields.
gatewayId String By default: nil. Used if you have multiple payment gateways with different IDs.

TokenizationSettings

You can configure the list of payment methods and how the YooMoney logo is displayed in the app.

Parameter Type Description
paymentMethodTypes PaymentMethodTypes By default: .all. Payment methods available to the user in the app.
showYooKassaLogo Bool By default: true. It determines if the YooMoney logo is displayed. By default, the logo is displayed.

TestModeSettings

Parameter Type Description
paymentAuthorizationPassed Bool It determines if the payment authorization has been completed for payments via YooMoney.
cardsCount Int Number of cards linked to the YooMoney wallet.
charge Amount Payment amount and currency.
enablePaymentError Bool It determines if the payment is completed with an error.

Amount

Parameter Type Description
value Decimal Payment amount
currency Currency Payment currency

Currency

Parameter Type Description
rub String ₽ - Russian ruble
usd String $ - U.S. dollar
eur String € - Euro
custom String The value you entered will be displayed

CustomizationSettings

Parameter Type Description
mainScheme UIColor The blueRibbon color is used by default. Color of the main elements, button, switches, and input fields.

SavePaymentMethod

Parameter Type Description
on SavePaymentMethod Save the payment method for processing recurring payments. Only payment methods which support saving will be available to the user. A notification that the payment method will be saved will be displayed on the contract screen.
off SavePaymentMethod It doesn't allow the user to choose if the payment method should be saved or not.
userSelects SavePaymentMethod User chooses if the payment method should be saved or not. If the payment method can be saved, a switch will appear on the contract screen.

Scanning bank cards

If you want users to be able to scan bank cards when making payments, you need to:

  1. Create an entity and implement the CardScanning protocol.
class CardScannerProvider: CardScanning {
    weak var cardScanningDelegate: CardScanningDelegate?

    var cardScanningViewController: UIViewController? {

        // Create and return scanner view controller

        viewController.delegate = self
        return viewController
    }
}
  1. Set up receiving data from your tool for scanning bank cards.
    Example for CardIO:
extension CardScannerProvider: CardIOPaymentViewControllerDelegate {
    public func userDidProvide(_ cardInfo: CardIOCreditCardInfo!,
                               in paymentViewController: CardIOPaymentViewController!) {
        let scannedCardInfo = ScannedCardInfo(number: cardInfo.cardNumber,
                                              expiryMonth: "\(cardInfo.expiryMonth)",
                                              expiryYear: "\(cardInfo.expiryYear)")
        cardScanningDelegate?.cardScannerDidFinish(scannedCardInfo)
    }

    public func userDidCancel(_ paymentViewController: CardIOPaymentViewController!) {
        cardScanningDelegate?.cardScannerDidFinish(nil)
    }
}
  1. Enter an instance of the CardScannerProvider object in TokenizationModuleInputData in the cardScanning: parameter.
let inputData = TokenizationModuleInputData(
    ...
    cardScanning: CardScannerProvider())

Setting up payment confirmation

If you'd like to use our implementation of payment confirmation, don't close the SDK module after receiving the token.
Send the token to your server and close the module after a successful payment.
If your server stated that the payment needs to be confirmed (i.e. the payment with the pending was received), call the startConfirmationProcess(confirmationUrl:paymentMethodType:) method.

After the payment confirmation is completed successfully, the didSuccessfullyConfirmation(paymentMethodType:) method of the TokenizationModuleOutput protocol will be called.

Code examples:

  1. Save the tokenization module.
self.tokenizationViewController = TokenizationAssembly.makeModule(inputData: inputData,
                                                                 moduleOutput: self)
present(self.tokenizationViewController, animated: true, completion: nil)
  1. Don't close the tokenization module after receiving the token.
func tokenizationModule(_ module: TokenizationModuleInput,
                        didTokenize token: Tokens,
                        paymentMethodType: PaymentMethodType) {
    // Send the token to your server.
}
  1. Call payment confirmation if necessary.
self.tokenizationViewController.startConfirmationProcess(
    confirmationUrl: confirmationUrl,
    paymentMethodType: paymentMethodType
)
  1. After the payment is confirmed successfully, the method will be called.
func didSuccessfullyConfirmation(paymentMethodType: PaymentMethodType) {
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }

        // Now close tokenization module
        self.dismiss(animated: true)
    }
}

Logging

You can enable logging of all network requests.
To do that, you need to enter isLoggingEnabled: true when creating TokenizationModuleInputData

let moduleData = TokenizationModuleInputData(
    ...
    isLoggingEnabled: true)

Test mode

You can launch the mobile SDK in test mode.
In test mode, no network requests are made and response from the server is emulated.

If you'd like to run the SDK in test mode, you need to:

  1. Configure an object with the TestModeSettings type.
let testModeSettings = TestModeSettings(paymentAuthorizationPassed: false,
                                        cardsCount: 2,
                                        charge: Amount(value: 999, currency: .rub),
                                        enablePaymentError: false)
  1. Enter it in TokenizationModuleInputData in the testModeSettings: parameter
let moduleData = TokenizationModuleInputData(
    ...
    testModeSettings: testModeSettings)

Launching Example

To launch the Example app, you need to:

  1. Make a git clone of the repository.
git clone https://github.com/yoomoney/yookassa-payments-swift.git
  1. Go to the project folder and run the following commands in console:
gem install bundler
bundle
pod install
  1. Open YooKassaPayments.xcworkspace.
  2. Select and launch the YooKassaPaymentsDemoApp scheme.

Interface customization

The blueRibbon color is used by default. Color of the main elements, button, switches, and input fields.

  1. Configure an CustomizationSettings object and enter it in the customizationSettings parameter of the TokenizationModuleInputData object.
let moduleData = TokenizationModuleInputData(
    ...
    customizationSettings: CustomizationSettings(mainScheme: /* UIColor */ ))

Payments via bank cards linked to the store with an additional CVC/CVV request

  1. Create BankCardRepeatModuleInputData.
let bankCardRepeatModuleInputData = BankCardRepeatModuleInputData(
            clientApplicationKey: oauthToken,
            shopName: translate(Localized.name),
            purchaseDescription: translate(Localized.description),
            paymentMethodId: "24e4eca6-000f-5000-9000-10a7bb3cfdb2",
            amount: amount,
            testModeSettings: testSettings,
            isLoggingEnabled: true,
            customizationSettings: CustomizationSettings(mainScheme: .blueRibbon)
        )
  1. Create TokenizationFlow with the .bankCardRepeat case and enter BankCardRepeatModuleInputData.
let inputData: TokenizationFlow = .bankCardRepeat(bankCardRepeatModuleInputData)
  1. Create ViewController from TokenizationAssembly and put it on the screen.
let viewController = TokenizationAssembly.makeModule(
    inputData: inputData,
    moduleOutput: self
)
present(viewController, animated: true, completion: nil)

License

YooMoney for Business Payments SDK (YooKassaPayments) is available under the MIT license. See the LICENSE file for additional information.