Payment Initiation
Good to know: payment initiation is responsible for bank and card payment support.
Firstly, you will need to integrate kevin. API and fetch payment ID. Instructions on how to do it can be found here:
Customise payment flow by tweaking our configuration:
// initialize configuration with paymentId fetched from the API
let configuration = KevinPaymentSessionConfiguration.Builder(paymentId: paymentId)
.setPaymentType(.bank)
.setPreselectedCountry(.lithuania)
.setCountryFilter([.lithuania, .latvia, .estonia])
.setDisableCountrySelection(false)
.setPreselectedBank("SOME_BANK_ID")
.setSkipBankSelection(false)
.setSkipAuthentication(false)
.build()
Implement
KevinPaymentSessionDelegate
protocol. Make sure you show returned UIViewController
somewhere:protocol KevinPaymentSessionDelegate: AnyObject {
func onKevinPaymentInitiationStarted(controller: UINavigationController)
func onKevinPaymentCanceled(error: Error?)
func onKevinPaymentSucceeded(paymentId: String)
}
Call
KevinPaymentSession
and listen to delegate:KevinPaymentSession.shared.delegate = self
try KevinPaymentSession.shared.initiatePayment(
configuration: configuration
)
Library is built on UIKit, however it can be easily used within SwiftUI.
Firstly, create representable for kevin.
UIViewController
:import SwiftUI
struct KevinViewControllerRepresentable: UIViewControllerRepresentable {
let controller: UIViewController
func makeUIViewController(context: Context) -> some UIViewController {
return controller
}
func updateUIViewController(
_ uiViewController: UIViewControllerType,
context: Context
) { }
}
Define your view from which you will be showing representable:
import Kevin
import SwiftUI
struct SampleView: View {
@ObservedObject var viewModel: SampleViewModel
var body: some View {
VStack(spacing: 20) {
Spacer()
Button {
viewModel.invokeBankPaymentInitiationSession()
} label: {
Text("Make Bank Payment")
}.buttonStyle(MainButtonStyle())
Button {
viewModel.invokeCardPaymentInitiationSession()
} label: {
Text("Make Card Payment")
}.buttonStyle(MainButtonStyle())
.sheet(isPresented: $viewModel.viewState.openKevin, content: {
if let controller = viewModel.kevinController {
KevinViewControllerRepresentable(controller: controller)
.presentation(canDismissSheet: false)
}
})
Spacer()
}
.padding(20)
}
}
Define your ViewModel which will subscribe to
KevinPaymentSessionDelegate
and invoke the SDK:import UIKit
import Kevin
class SampleViewModel: ObservableObject, KevinPaymentSessionDelegate {
@Published var viewState = SampleViewState()
var kevinController: UIViewController? = nil
private let apiClient = ApiClient()
func invokeBankPaymentInitiationSession() {
apiClient.initializeBankPayment().done { state in
do {
KevinPaymentSession.shared.delegate = self
try KevinPaymentSession.shared.initiatePayment(
configuration: KevinPaymentSessionConfiguration.Builder(
paymentId: state.id
)
.setPreselectedCountry(.lithuania)
.setSkipBankSelection(false)
.build()
)
} catch {
// do something
}
}.catch { error in
// do something
}
}
func invokeCardPaymentInitiationSession() {
apiClient.initializeCardPayment().done { state in
do {
KevinPaymentSession.shared.delegate = self
try KevinPaymentSession.shared.initiatePayment(
configuration: KevinPaymentSessionConfiguration.Builder(
paymentId: state.id
)
.setPaymentType(.card)
.build()
)
} catch {
// do something
}
}.catch { error in
// do something
}
}
//MARK: KevinPaymentSessionDelegate
func onKevinPaymentInitiationStarted(controller: UINavigationController) {
self.kevinController = controller
self.viewState = MainViewState(openKevin: true)
}
func onKevinPaymentCanceled(error: Error?) {
// notify user if error has been returned
}
func onKevinPaymentSucceeded(paymentId: String) {
// notify user
}
}
KevinPaymentSessionConfiguration has multiple settings to tackle:
setPaymentType
- sets payment to be BANK or CARD. The payment needs to be initialised with the corresponding type. See reference here.setPreselectedCountry
- preselects country in our prebuilt UIsetDisableCountrySelection
- uses only preselected country and does not allow to change itsetCountryFilter
- allow only certain countries to be supportedsetPreselectedBank
- preselects bank in our prebuilt UIsetSkipBankSelection
- skips bank and country selection and redirects user to the bank SCA immediately- setSkipAuthentication - allows users to skip the SCA bank step and proceed directly to the payment confirmation. Bank payment needs to be initialised with an account access token. See reference here.
Example:
KevinPaymentSession.shared.initiatePayment(
configuration: KevinPaymentSessionConfiguration.Builder(
paymentId: state.id
)
.setPreselectedCountry(.lithuania)
.setCountryFilter([.lithuania, .latvia, .estonia])
.setPreselectedBank("SOME_BANK_ID")
.build()
)
Last modified 1mo ago