This guide will walk you through a straightforward solution to accept payments within your iOS application. The iOS SDK is a small framework built with SwiftUI that allows you to quickly and safely integrate Moyasar payments within your SwiftUI or UIKit apps.
Installing CocoaPods
Before you can add the library to your project, you need to install CocoaPods on your macOS using the following command:
Shell
brew install cocoapods
Or as a Ruby gem
Shell
gem install cocoapods
Add the Dependency
If you haven't already added CocoaPods to your project, initialize it with:
Shell
pod init
Now add the following pod to your Podfile:
Ruby
pod 'MoyasarSdk', git:'https://github.com/moyasar/moyasar-ios-pod.git'
Make sure to add use_frameworks!
Configuring a Payment Request
We need to prepare a PaymentRequest object:
Swift
let paymentRequest =PaymentRequest(
apiKey:"pk_live_1234567",
amount:1000,// Amount in the smallest currency unit For example: 10 SAR = 10 * 100 Halalas
currency:"SAR",
description:"Flat White",
metadata:["order_id":"ios_order_3214124"],
manual:false,// authorize and capture payment automatically or capture it manually
saveCard:false,
allowedNetworks:[.mastercard,.visa,.mada]// set your supported networks)
When the user authorizes the payment using Face ID or Touch ID on their iOS device, the didAuthorizePayment event will be dispatched. In this step, you must pass the token to ApplePayService found within the PKPayment object. Here is an example:
Swift
let payment: PKPayment =// Payment object we got in the didAuthorizePayment event
let service =ApplePayService(apiKey:"pk_live_1234567")// From MoyasarSdk
Task {do{
let paymentResult =try await service.authorizePayment(request: paymentRequest, token: payment.token)// Handle the success caseprint("Got payment")print(paymentResult.status)print(paymentResult.id)handleCompletedPaymentResult(paymentResult)}catch{// Handle the error caseprint(error)handlePaymentError(error)}}
func handleCompletedPaymentResult(_ payment: ApiPayment){// ...}
func handlePaymentError(_ error: MoyasarError){// Handle all MoyasarError enum cases}
Don't forget to import PassKit.
An error will be printed if the API key format is incorrect.
SwiftUI Credit Card Payments
The SDK provides a SwiftUI view called CreditCardView that allows you to easily create a credit card form.
We can add the CreditCardView to our view as follows:
Swift
struct ContentView: View {
func handleCompletedPaymentResult(_ payment: ApiPayment){// ...}
func handlePaymentError(_ error: MoyasarError){// Handle all MoyasarError enum cases}
var body: some View {CreditCardView(
request: paymentRequest,
callback: handlePaymentResult
)}}
UIKit Credit Card Payments
If you are using UIKit you will need to create a wrapper to host the SwiftUI CreditCardView view:
Now, we can handle the Credit Card payment result as follows:
Swift
func handlePaymentResult(result: PaymentResult){
switch (result){
case .completed(let payment):handleCompletedPaymentResult(payment)break
case .failed(let error):handlePaymentError(error)break
case .canceled:// Handle cancel Resultbreak
@unknown default:// Handle any future casesbreak}}
func handleCompletedPaymentResult(_ payment: ApiPayment){// Payment status}
func handlePaymentError(_ error: MoyasarError){// Handle all MoyasarError enum cases}
If the payment failed during the 3DS authentication process, the PaymentResult will be .failed with the MoyasarError enum case beggining with webview.... You should fetch the payment as per this documentation and check it's status as it might be paid.
Make sure to dismiss the webview screen after getting the result.
Handling Completed Payment Result
The payment status could be paid, failed or other statuses, we need to handle this:
Swift
func handleCompletedPaymentResult(_ payment: ApiPayment){
switch payment.status {
case .paid:// Handle paid!break
default:// Handle other statuses like failed}}
'Completed' payment doesn't necessarily mean that the payment is successful. It means that the payment process has been completed successfully.
You need to check the payment status to make sure that the payment is successful.
Use the create method in the PaymentService class like this:
Swift
let paymentService =PaymentService(apiKey:"pk_live_1234567")
let source =ApiCreditCardSource(
name:"John Doe",
number:"4111111111111111",
month:"09",
year:"25",
cvc:"456",
manual:"false",
saveCard:"false")
let paymentRequest =ApiPaymentRequest(
amount:1000,
currency:"SAR",
description:"Flat White",
callbackUrl:"https://sdk.moyasar.com/return",
source: ApiPaymentSource.creditCard(source),
metadata:["sdk":"ios","order_id":"ios_order_3214124"])
Task {do{
let payment =try await paymentService.createPayment(paymentRequest)
DispatchQueue.main.async {
self.startPaymentAuthProcess(payment)}}catch let error as MoyasarError {print("Payment creation error: \(error )")
self.handlePaymentError(error)}catch{print("An unexpected error occurred: \(error)")// handleUnexpectedError(error) // Add your general error handling here}}
func startPaymentAuthProcess(_ payment: ApiPayment){// ...}
func handlePaymentError(_ error: MoyasarError){// Handle all MoyasarError enum cases}
Make sure to add the 'sdk' field with the value of 'ios' in ApiPaymentRequest metadata dictionary field. (Only when creating a custom UI)
Now when the payment is initiated successfully you need to initialize the 3DS web view as follows:
Swift
func startPaymentAuthProcess(_ payment: ApiPayment){
guard payment.isInitiated()else{// Handle case// Payment status could be paid, failed, authorized, etc...return}
guard case let .creditCard(source)= payment.source else{// Handle errorreturn}
guard let transactionUrl = source.transactionUrl, let url =URL(string: transactionUrl)else{// Handle errorreturn}showWebView(url)}
func showWebView(_ url: URL){// Initialize the 3DS web view}
Moyasar provides a sandbox environment for testing credit card payments without charging any real money. This allows you to test your integration and ensure that everything is working correctly before going live with actual payments. Learn more about our testing cards here
Apple Pay
Testing using a simulator will not work! Learn more about Apple Pay testing here.