IOS SDK
Introduction
Payrails iOS SDK provides you with the building blocks to create a seamless checkout experience for your customers. The SDK offers a variety of UI components and payment methods, including card payments, Apple Pay, PayPal, and redirect-based payment methods.
Installation
Minimum Requirements
- iOS 14.0 or later
- Swift 5.0 or later
CocoaPods
Add the following line to your Podfile :
pod "Payrails/Checkout"Then run:
pod install
Swift Package Manager
- In Xcode, go to File > Add Packages...
- Enter the repository URL:
https://github.com/payrails/ios-sdk - Select the
PayrailsCheckoutproduct
The SDK includes dependencies for PayPal's checkout SDK and Payrails' Client-Side Encryption (CSE) library. These are managed automatically by CocoaPods or Swift Package Manager.
Enabling Apple Pay Capability
To use Apple Pay in your app:
- Add the Apple Pay capability in your Xcode project's "Signing & Capabilities" tab for your app target
- Configure a Merchant ID with Apple
SDK Initialization
Before using any of the SDK's features, you need to initialize it by creating a Payrails.Session object.
Using Async/await
import Payrails
// 1) Fetch InitData from your backend
let initData = try await Api()
.call(
endpoint: .initSdk(settings: settings, token: authentication.accessToken),
type: Payrails.InitData.self
)
// 2) Build configuration
let configuration = Payrails.Configuration(
initData: initData,
option: Payrails.Options(env: .dev) // .prod in production
)
// 3) Initialize the SDK
let session = try await Payrails.createSession(with: configuration)
// 4) Store the session if you need a direct reference
self.payrailsSession = sessionNotes:
Payrails.createSession(with:)is the public entry point for SDK initialization.initDatais justversionanddata; pass it as provided by your backend.- Creating UI components should happen on the main thread after initialization.
Using Callback
Payrails.createSession(with: configuration) { result in
switch result {
case .success(let session):
print("Session created: \(String(describing: session.executionId))")
case .failure(let error):
print("Initialization failed: \(error)")
}
}Session lifetime guidance
- Create one session and reuse it during the app lifecycle.
Payrails.createSession(with:)sets an internalcurrentSessionused by the factory methods.
Payment Flow Presenter
Some payment methods require presenting additional UI (3DS, PayPal login, redirects). Implement PaymentPresenter in the view controller that owns the checkout UI.
Implementing PaymentPresenter
Your view controller that initiates payments should conform to the PaymentPresenter protocol
final class CheckoutViewController: UIViewController, PaymentPresenter {
func presentPayment(_ viewController: UIViewController) {
present(viewController, animated: true)
}
// Used by the SDK for card payments
var encryptedCardData: String?
}You must assign an object conforming to PaymentPresenter to the presenter property of UI payment elements (like CardPaymentButton, ApplePayButton, etc.) before initiating a payment.
UI Elements
The SDK provides several UI components for different payment methods. All UI elements are created using static factory methods on the Payrails class after SDK initialization.
Card Payments
Card payments use two components:
Payrails.CardFormto collect and encrypt card dataPayrails.CardPaymentButtonto submit the payment
Create a Card Form
let cardForm = Payrails.createCardForm(
config: nil,
showSaveInstrument: false
)
view.addSubview(cardForm)You can customize styles and translations using CardFormConfig:
let customConfig = CardFormConfig(
showNameField: true,
showSaveInstrument: true,
styles: customStyles, // Optional CardFormStylesConfig
translations: customTranslations // Optional CardTranslations
)
let cardForm = Payrails.createCardForm(config: customConfig, showSaveInstrument: true)Create a Card Payment Button
createCardPaymentButton requires a session and a card form to exist. Call createCardForm(...) first.
let buttonTranslations = CardPaymenButtonTranslations(label: "Pay Now")
let payButton = Payrails.createCardPaymentButton(
buttonStyle: nil,
translations: buttonTranslations
)
payButton.delegate = self
payButton.presenter = selfNotes:
- When using
CardPaymentButton, do not setcardForm.delegatemanually. The button sets itself as the delegate to receive encrypted card data. - Use
PayrailsCardPaymentButtonDelegatefor success/failure callbacks.
Apple Pay
let applePayButton = Payrails.createApplePayButton(
type: .checkout,
style: .black,
showSaveInstrument: false
)
applePayButton.delegate = self
applePayButton.presenter = selfPayPal
let payPalButton = Payrails.createPayPalButton(showSaveInstrument: true)
payPalButton.delegate = self
payPalButton.presenter = selfRedirect Payment Methods
For redirect-based methods (e.g., iDEAL), use a generic redirect button and the payment method code from your backend configuration:
let buttonTranslations = CardPaymenButtonTranslations(label: "Pay with iDEAL")
let buttonStyle = CardButtonStyle(
backgroundColor: .systemBlue,
textColor: .white,
cornerRadius: 8
)
let idealButton = Payrails.createGenericRedirectButton(
buttonStyle: buttonStyle,
translations: buttonTranslations,
paymentMethodCode: "ideal"
)
idealButton.presenter = self
idealButton.delegate = selfStored Instruments
Accessing stored instruments
let cards = session.storedInstruments(for: .card)
let paypals = session.storedInstruments(for: .payPal)Or via the static helper (uses the current session):
let payPalInstruments = Payrails.getStoredInstruments(for: .payPal)Displaying stored instruments
let storedInstrumentsView = Payrails.createStoredInstruments(
showDeleteButton: true,
showUpdateButton: true,
showPayButton: true
)
storedInstrumentsView.delegate = self
storedInstrumentsView.presenter = selfDisplaying a single stored instrument
let instrumentView = Payrails.createStoredInstrumentView(
instrument: instrument,
showDeleteButton: true,
showUpdateButton: true,
showPayButton: true
)
instrumentView.delegate = self
instrumentView.setPresenter(self)Managing stored instruments
Use Payrails.api to delete or update a stored instrument:
// Delete
let result = try await Payrails.api("deleteInstrument", instrumentId)
// Update (set as default)
let body = UpdateInstrumentBody(default: true)
let result = try await Payrails.api("updateInstrument", instrumentId, body)Debugging
// Toggle the SDK on-screen log overlay
Payrails.DebugManager.shared.toggleLogView()
// Present a SwiftUI viewer with the parsed SDK config
let debugView = Payrails.Debug.configViewer(session: session)
let hostingController = UIHostingController(rootView: debugView)
present(hostingController, animated: true)
// Log entries to the SDK log store
Payrails.log("Some message")Customization Notes
The current implementation exposes styling, fonts, colors, and text labels, but has these limitations:
- Field order and placement are fixed (
[1, 1, 3]with name,[1, 3]without name). - Field dimensions are applied internally; custom Auto Layout constraints are limited.
- The save-instrument toggle layout is not configurable.
- Some low-level styling (card-brand icon, asterisk visibility) is not exposed via
CardFormConfig.
Security Policy
Reporting a Vulnerability
If you find any vulnerability in Payrails iOS SDK, do not hesitate to report them.
-
Send the disclosure to [email protected]
-
Describe the vulnerability.
If you have a fix, that is most welcome -- please attach or summarize it in your message!
-
We will evaluate the vulnerability and, if necessary, release a fix or mitigating steps to address it. We will contact you to let you know the outcome, and will credit you in the report.
Please do not disclose the vulnerability publicly until a fix is released!
-
Once we have either a) published a fix, or b) declined to address the vulnerability for whatever reason, you are free to publicly disclose it.
Updated about 7 hours ago