This library includes the high level components providing complete payment forms to use the Paylike ecosystem.
If you are looking for our core elements required to implement payment flow towards the API, check here.
- Paylike's Swift SDK
This library was created to provide the simplest way of integrating Paylike into your iOS application.
It provides views and viewModels to create a payment form and an easy way to handle the payment result.
For the UI related design and implementation the chosen technology is SwiftUI. The minimal target is iOS 13.0. It is supported by 96.1% of iOS devices (Last Updated 2023.06.29)
For the library you can find the API reference here.
To get more familiar with our server API you can find here the official documentation.
To use the ecosystem you must add the package as a dependency to your xcodeproject, or package.
- Open your xcodeporj file
- Go to the Package Dependencies tab
- Click the + icon to add a new package
- In the Search bar at the top right enter the package url:
https://github.com/paylike/swift-sdk
Package.swift
// swift-tools-version: 5.6
import PackageDescription
let package = Package(
// ...
dependencies: [
.package(url: "https://github.com/paylike/swift-sdk", .upToNextMajor(from: "0.1.0")),
// ...
],
// ...
)
Don't forget to create your OWN API key (merchant ID) for the Paylike ecosystem. See: Integration Docs & Getting an API key
import SwiftUI
import Foundation
import PaylikeClient
import PaylikeEngine
import PaylikeSDK
func onSuccess() -> Void {
print("Success!")
}
@main
struct ExampleApp: App {
var paylikeViewModel: SimplePaymentFormViewModel
init() {
var engine = PaylikeEngine(merchantID: "YOUR_KEY", engineMode: .TEST, loggingMode: .DEBUG) // PaylikeEngine handles the payment flow under the hood. Don't forget to add your own key!
var amount = PaymentAmount(currency: .EUR, value: 30, exponent: 0)
paylikeViewModel = SimplePaymentFormViewModel(engine: engine, amount: amount, onSuccess: onSuccess)
// For testing define test data, to simulate a valid card:
paylikeViewModel.addPaymentTestData(PaymentTest())
}
var body: some Scene {
WindowGroup {
// Simple Payment Form only asks for card details, and handles the payment flow.
// Shows errors, loading, WebView for TDS, and a success state
SimplePaymentForm(viewModel: paylikeViewModel)
.environmentObject(PaylikeTheme) // PaylikeTheme is required for theming of the components. You can define your own theme if you like
}
}
}
This form provides the simplest implementation of a payment flow.
Features:
- Card number input field (indicating the recognized card issuer; supported cards are Maestro, MasterCard and Visa),
- Expiry date input field,
- Card verification code input field,
- Pay button,
- WebView to help TDS and
- can receive custom theme definition.
Every field has a realtime sanitation and check if its acceptable. Pushing the pay button has a check if every field meets the requirements, if not the button is disabled. If every field exaushted the expected conditions then the payment flow starts, a loading overlay is shown on top of the input fields, and the button becomes disabled. The webView appears when necessary, accepts user input to solve TDS, then disappears. The form shows a success overlay or an error in case the flow is finished. The navigation to and from the form is up to the developer. A Theme environmentObject has to be defined in order for the views to show properly. You can use the prepared PaylikeTheme for paylike branding, or you can define your own.
SimplePaylikeExampleView.swift
import SwiftUI
import Foundation
import PaylikeClient
import PaylikeEngine
import PaylikeSDK
class SimpleExampleViewModel: ObservableObject {
@Published var showSuccessOverlay = false
func onSuccess() -> Void {
showSuccessOverlay = true
}
}
struct SimplePaylikeExample: View {
@ObservedObject var exampleViewModel: SimpleExampleViewModel
var paylikeViewModel: SimplePaymentFormViewModel
init() {
// Create the exampleViewModel inside the init method, so the closures can be used by paylikeViewModel
let exampleViewModel = SimpleExampleViewModel()
// Initialization of VM, and including Engine
var engine = PaylikeEngine(merchantID: "YOUR_KEY", engineMode: .TEST, loggingMode: .DEBUG) // Use your OWN merchant key, highly recommended to store it in obfuscated environmental variable and not hardcode it to codebase. Can be obtained from Paylike. Test mode: ApiMode.TEST
// optionally define webView, or use the default Paylike webView, defined in swift-engine.
paylikeViewModel = SimplePaymentFormViewModel(engine: engine, onSuccess: onSuccess)
// Add payment amount, and additionally any other defined data to VM. See: https://github.com/paylike/swift-engine and Paylike API documentation
var amount = PaymentAmount(currency: .EUR, value: 30, exponent: 0)
paylikeViewModel.addDescriptionPaymentData(
// paymentTestData: PaymentTest(), // Only in test mode
paymentAmount: amount,
// paymentPlanDataList: paymentPlanDto,
// paymentUnplannedData: paymentUnplannedDto,
)
// optionally
// paylikeViewModel.addAdditionalPaymentData(
// textData: textData,
// customData: customData,
// )
self.exampleViewModel = exampleViewModel
}
var body: some View {
ZStack {
// Create the simple payment form
SimplePaymentForm(viewModel: paylikeViewModel)
.environmentObject(PaylikeTheme) // PaylikeTheme is required for theming of the components. You can define your own theme if you like
// The whole form will be covered with this overlay once the payment succesfully finished. This is for showcasing purposes only
ExampleSuccessOverlay(showOverlay: exampleViewModel.showSuccessOverlay)
}
.onDisappear {
paylikeViewModel.resetViewModelAndEngine() // Reset the VM and engine state after leaving the view, so a new payment can be made
exampleViewModel.showSuccessOverlay = false
}
}
}
Paylike Swift SDK is built by defining high level components that use the same theme across the board.Components use a @EnvironmentObject Theme
to set their own colors and sizes. The SDK exports a default Theme called PaylikeTheme
, which is using the Paylike color scheme. However if you want to add your own branding to the form, you can create your own Theme and pass it on to to the components.
MyTheme.swift
import SwiftUI
import PaylikeSDK
var CustomTheme: Theme {
let theme = Theme()
theme.primaryColor = .blue
theme.errorColor = .orange
theme.disabledColor = Color(red: 1, green: 0.2, blue: 0.2)
return theme
}
// Usage in another file:
SimplePaymentForm(viewModel: paylikeViewModel)
.environmentObject(CustomTheme)
Use the beforePayment
closure to set additional custom data on the Payment, when the Pay Button is pressed. Two kinds of additional data can be added to the payment, both are optional:
- textData: String data
- customData: any Encodable data.
ExtendedPaylikeExample.swift
import AnyCodable
import SwiftUI
import PaylikeEngine
import PaylikeSDK
import PaylikeClient
/// Encodable custom data
struct CustomData: Encodable {
var email = "not-real@test.com"
var testArray = [0, 1, 2]
}
class ExtendedExampleViewModel: ObservableObject {
// This data can be edited in the example, and is added to the payment as additional data in the beforePayment callback
@Published var textData = "this is a test"
@Published var customData = CustomData()
func beforePayment (engine: PaylikeEngine, _: String, _: String, _: CardExpiry, _: String?, _: AnyEncodable?) -> Void {
// Add the additional data to the engine before the payment is started
engine.addAdditionalPaymentData(textData: textData, customData: AnyEncodable(customData))
}
}
struct ExtendedPaylikeExample: View {
@ObservedObject var exampleViewModel: ExtendedExampleViewModel
var paylikeViewModel: SimplePaymentFormViewModel
init(engine: PaylikeEngine) {
// Create the exampleViewModel inside the init method, so the closures can be used by paylikeViewModel
let exampleViewModel = ExtendedExampleViewModel()
paylikeViewModel = SimplePaymentFormViewModel(engine: engine, onSuccess: exampleViewModel.onSuccess, beforePayment: exampleViewModel.beforePayment)
paylikeViewModel.addPaymentAmount(PaymentAmount(currency: .EUR, value: 30, exponent: 0))
paylikeViewModel.addPaymentTestData(PaymentTest()) // Only during testing
self.exampleViewModel = exampleViewModel
}
var body: some View {
VStack(alignment: .leading) {
Text("ADDITIONAL TEXT DATA")
.bold()
TextField<Text>("placeholder", text: $exampleViewModel.textData) // Editing the text field is allowed until the Pay Button is pressed
SimplePaymentForm(viewModel: paylikeViewModel)
.environmentObject(PaylikeTheme)
}
.onDisappear {
paylikeViewModel.resetViewModelAndEngine()
}
}
}
public typealias OnSuccessHandler = () -> Void
Called when the PaylikeEngine status changes to SUCCESS. Can be set in the PaylikeViewModel initializer. Use this closure for redirection after a successful payment.
public typealias OnErrorHandler = (_ error: PaylikeError) -> Void
Called when the PaylikeEngine status changes to ERROR. Can be set in the PaylikeViewModel initializer. The Error Object emitted by the Engine will also be passed as a parameter
public typealias BeforePayment = (_ engine: PaylikeEngine, // Engine under the hood. see https://github.com/paylike/swift-engine
_ cardNumber: String, // Card Number entered by the user
_ cvc: String, // Card Verification code entered by the user
_ cardExpiry: CardExpiry, // Card Expiry Date entered by the user
_ textData: String?, // TextData already added to the payment repository
_ customData: AnyEncodable? // CustomData already added to the payment repository
) -> Void
Called when the Pay Button has been pressed, and all the Payment Data has been set according to the viewModel, but before payment is started. You can use this callback to modify data on the engine, or to do third party logic. Can be set in the PaylikeViewModel initializer.
Localisation is not supported by the iOS version yet. Help us out!
For error definitions see: here
There is an example application showcasing the usual use-cases in an Example application under this folder of this repository.