 Quick Start

AmwalPayment iOS SDK

Compatibility

SwiftUI UIKit CocoaPods
Swift Package Manager

Integrate Amwal’s prebuilt payment Sheet into the checkout of your iOS app with the PaymentSheet DSL friendly APIs.

Screenshots

Image 1 Image 2 Image 3

Table of Contents

Intoduction

AmwalPayment SDK offers the flexibility to use pass keys for enhanced security during the payment process. Pass keys provide an additional layer of protection by replacing traditional OTPs (One-Time Passwords) and ensuring a secure payment experience. Here's how you can generate and integrate pass keys into the Payment Sheet

Install SDK

Swift Package Manager (SPM)

Add the following line to your Package.swift file's dependencies:

dependencies: [
   .package(url: "https://github.com/amwal/payment-sdk-ios.git", from: "1.0.10")
]

CocoaPods

pod 'AmwalPayment', '~> 1.0.10'

⚠️ Important : Add AmwalPay in your associated domains

  • In Xcode > Choose your target
  • Head to Signing & Capabilities
  • Press + Capability
  • Search and choose Associated Domains
  • In the newly added Associated Domains section add
    webcredentials:pay.sa.amwal.tech

⚠️ Important : Add your Bundle Identifier and iOS App Id Prefix to Merchant dashboard

  • Head to your Merchant dashboard settings
  • Choose IOS SETTINGS tab
  • Select your Store
  • Add your iOS App Id Prefix aka Your team Id
  • Add your iOS Bundle Id
  • Click Save and you should see "iOS Settings Updated" message ✅

2. Initialize the PaymentSheet

you can use in SwiftUI with .sheet and UIKit with modalPresentationStyle.

1-
import AmwalPayment

2- initialize View

        AmwalPaymentView(
            currency: .SAR,
            amount: 110,
            vat: 20,
            merchantId: "merchantId",
            completion: { transactionId in
                isPresented = false
            }
        )

3. Showing Payment Sheet

  • you can use our button direct to show payment sheet or use a sheet view

SwiftUI Sheet

import SwiftUI
import AmwalPay

struct ContentView: View {
    @SwiftUI.State var isPresented: Bool = false
    var body: some View {
        VStack {
            Button {
                isPresented = true
            } label: {
                Label("Pay With Amwal", systemImage: "dollarsign.circle")
                    .padding(10)
                    .foregroundColor(.white)
                    .background(Color.blue)
                    .clipShape(Capsule(style: .continuous))
            }
        }
        .frame(maxWidth: .infinity)
        .padding()
        .sheet(isPresented: $isPresented) {
            
            AmwalPaymentView(
                currency: .SAR,
                amount: 110,
                vat: 20,
                merchantId: "merchantId",
                completion: { transactionId in
                isPresented = false
            })
        }
    }
}

SwiftUI AmwalPayButton

import AmwalPay
import SwiftUI
enum PayResult: String {
    case success
    case failure
}

struct ContentView: View {
    @State var isPresented: Bool = false
    @State var amount: String = "110"
    @State var vat: String = "20"
    @State var merchantId: String = "sandbox-amwal-3db24246-8d09-4f78-a3eb-0d4b8b03bd4b"
    @State var transactionID: String = ""
    @State var result: PayResult?
    var body: some View {
        VStack {
            Text("Enter your values to test")
                .font(.largeTitle)
            HStack(alignment: .center) {
                VStack(alignment: .leading, spacing: 20) {
                    Text("Amount:")
                    Text("Vat:")
                }
                VStack(spacing: 5) {
                    TextField("Amount", text: $amount)
                        .keyboardType(.numberPad)
                        .textFieldStyle(.roundedBorder)
                    TextField("Vat", text: $vat)
                        .keyboardType(.numberPad)
                        .textFieldStyle(.roundedBorder)
                }
            }
            .padding([.top, .horizontal])
            VStack(alignment: .leading) {
                Text("MerchantID")
                TextField("MerchantID", text: $merchantId)
                    .keyboardType(.default)
                    .textFieldStyle(.roundedBorder)
            }
            .padding([.bottom, .horizontal])
            Text("TransactionID: \(transactionID)")
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding()
            HStack {
                Image(systemName: "circle.fill")
                    .foregroundColor(
                        result == .success
                            ? .green
                            : result == nil
                            ? .gray
                            : .red
                    )
                Text(result?.rawValue ?? "none")
            }
            .padding()
            .frame(maxWidth: .infinity, alignment: .leading)
            Spacer()
            AmwalPayButton(
                currency: .SAR,
                amount: Double(amount) ?? 110,
                vat: Double(vat) ?? 20,
                merchantId: merchantId
            ) { status in
                switch status {
                case let .success(transactionId):
                    self.transactionID = transactionId
                    result = .success
                case let .fail(error):
                    result = .failure
                    print(error)
                }
            }
        }
        .padding(.bottom)
    }
}

UIKit Sheet

import UIKit
import SwiftUI
import AmwalPay

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    func dismissPayment() {
        self.dismiss(animated: true)
    }
    
    func presentPaymentView() {
        let paymentView = AmwalPaymentView(
            currency: .SAR,
            amount: 110,
            vat: 20,
            merchantId: "merchantId",
            completion: { [weak self] transactionId in
                self?.dismissPayment()

            })
        let viewController = UIHostingController(rootView: paymentView)
        self.present(viewController, animated: true)
    }
}

UIKIT AmwalPayButton

import AmwalPay
import SwiftUI
import UIKit

class ViewController: UIViewController {
    lazy var payButton: UIView = {
        let button =  AmwalPayButton(
            currency: .SAR,
            amount:  110,
            vat:  20,
            merchantId: "sandbox-amwal-3db24246-8d09-4f78-a3eb-0d4b8b03bd4b"
        ) { status in
            switch status {
            case let .success(transactionId):
                debugPrint(transactionId)
            case let .fail(error):
                debugPrint(error)
            }
        }
        let ButtonView = UIHostingController(rootView: button)
        return ButtonView.view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor(resource: .custom)
        setupConstrains()
    }

    private func setupConstrains() {
        let stackView = UIStackView(arrangedSubviews: [payButton])
        stackView.axis = .horizontal
        stackView.alignment = .center
        stackView.spacing = 10
        stackView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(stackView)

        // Set constraints
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
            stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10),
            payButton.heightAnchor.constraint(equalToConstant: 60),
        ])

    }
}

4. Listen for results

we are return status success with transaction id and fail with error

Tips

🚧 Securely store your keys

The merchantId should be securely stored and not hard-coded as shown in this example. For more information on securely storing keys in iOS, see this article.


What’s Next

try our demo