OPApplePayLauncher

@available(iOSApplicationExtension, unavailable)
@available(macCatalystApplicationExtension, unavailable)
@objc
public class OPApplePayLauncher : NSObject, PKPaymentAuthorizationControllerDelegate, OPApplePayLauncherProtocol

A helper class that implements and simplifies ApplePay.

Use of this class looks like this:

  1. Create an instance of this class
  2. Create instances of OPApplePayConfiguration and OPApplePayLauncherDelegate and update the configuration and delegate properties of this class
  3. Create a button for ApplePay and connect it to a click handler
  4. Enable/Disable or Hide/Show the ApplePay button by calling OPApplePayLauncher.canMakePayments()
  5. In the click handler, call OPApplePayLauncher.present() to present the Apple Pay sheet and begin the payment process
  6. Implement OPApplePayLauncherDelegate.paymentMethodCreated(...) to submit the basket to Olo’s Ordering API
  7. Optionally implement OPApplePayLauncherDelegate.applePayDismissed(...) to handle success and error states when the ApplePay sheet is dimissed

Warning

OPApplePayLauncher needs to be created as a class member variable rather than a variable with function scope or else it can become nil while the ApplePay sheet is presented and callback methods won’t get called

Example Implementation

class ViewController: UIViewController, OPApplePayLauncherDelegate {
    // This needs to be a class member variable or it can go out of
    // scope during the ApplePay flow and become nil, preventing callbacks
    // from executing
    var _applePayLauncher: OPApplePayLauncherProtocol

    required init() {
        _applePayLauncher = OPApplePayLauncher()
        super.init()

        _applePayLauncher.delegate = self
        _applePayLauncher.configuration = OPApplePayConfiguration(
            merchantId: "merchant.com.your.applepay.id",
            companyLabel: "Your Company Name"
        )
    }

    // Called when user taps on ApplePay button to begin ApplePay flow
    func submitApplePay() {
        // To allow mocking this check, it could instead be called like this:
        // type(of: _applePayLauncher).canMakePayments()
        guard OPApplePayLauncher.canMakePayments() else {
            return
        }

        do {
            let amount: NSDecimalNumber = 1.23
            try _applePayLauncher?.present(for: amount) {
                // Optional logic for when the ApplePay flow is displayed
            }
        }
        catch {
            // Handle error conditions. See docs for `OPApplePayLauncher.present()` for more information
        }
    }

    func paymentMethodCreated(from launcher: OPApplePayLauncherProtocol, with paymentMethod: OPPaymentMethod) -> NSError? {
        // Use the payment method to submit the basket to Olo's Ordering API (the basket id can be retrieved with `launcher.basketId`
        // If the API returns an error, return that error. If the API call is successful, return nil
    }

    func applePayDismissed(from launcher: OPApplePayLauncherProtocol, with status: OPPaymentStatus, error: Error?) {
        // This is called after the payment sheet has been dismissed
        // Use the status and error parameters to determine if payment was successful
    }
}