# Accept Apple Pay on iOS

If you have a native iOS App you can use Tyro Apple Pay SDK to easily accept Apple Pay payments.

## Prerequisites

Please familiarise yourself with the guide to [Accept an Online Payment](/app/apis/pay/accept-an-online-payment), as the steps outlined in this document builds upon the existing knowledge.

Warning
Tyro Apple Pay SDK is internally configured to hit different environments based on your building mode

- DEBUG: sandbox
- RELEASE: production


## Integration Steps

### 1. Configure Your iOS App

Make sure your app is running iOS 16+

### 2. Add Tyro Apple Pay SDK

The SDK has been developed as a Swift Package and it is hosted on Github. Open the [Tyro Pay Api iOS](https://github.com/tyro/tyro-pay-api-ios) and follow the step to add it to your project.

### 3. Add The Apple Pay Button

Follow [Apple's guidelines](https://developer.apple.com/design/human-interface-guidelines/apple-pay) to add the Apple Pay button to your App's UI.

### 4. Create a TyroApplePay

* Create an instance of the `TyroApplePay`.
* Provide the configuration which includes the merchant identifier you should have previously setup on the Apple developer center.


Info
Click [here](https://developer.apple.com/documentation/passkit_apple_pay_and_wallet/apple_pay/setting_up_apple_pay) for help setting up your merchant id


```swift
// Swift Sample Code
let tyroApplePay = TyroApplePay(config: TyroApplePay.Configuration(
  merchantIdentifier: "merchant.tyro-pay-api-sample-app", // Your merchant id registered for the app on apple developer center
  allowedCardNetworks: [.visa, .masterCard]
), layout: TyroApplePay.Layout(
  totalLabel: "MerchantName"
))
```

### 5. Verify if Apple Pay is available for user

Before you display the Apple Pay button, use the available static methods `isApplePayAvailable` or `canSetupCard` to determine if Apple Pay is available for the user.


```swift
if TyroApplePay.isApplePayAvailable() {
  ...
}
```

or


```swift
if TyroApplePay.canSetupCard([.visa, .masterCard]) {
  ...
}
```

### 6. Include the PayWithApplePayButton, trigger the payment and handle the results

* Obtain the `paySecret` by creating a PayRequest from your server.
* Invoke `tyroApplePay.startPayment(paySecret: paySecret)` to start Apple Pay.
* Handle the results



```swift
// Swift Sample Code
...
PayWithApplePayButton {
  Task.detached { @MainActor in
    do {
      let result = try await tyroApplePay.startPayment(paySecret: paySecret)

      switch result {
      case .cancelled:
        print("ApplePay cancelled")
      case .success:
        print("payment successful")
      }
    } catch is TyroApplePayError {
      print("payment failed")
    }
  }
}
...
```

## Error Cases

### TyroApplePayError

| Error | Description |
|  --- | --- |
| .applePayNotReady | Thrown in case Apple Pay is not ready for the user. |
| .failedWith(Error) | Thrown to handle errors coming from the Apple Pay API. |
| .invalidPayRequestStatus | Thrown when the Pay Request Status validation fails. Valid pay request statuses are: AwaitingPaymentInput, AwaitingAuthentication, Failed. |
| .unableToFetchPayRequest | Thrown when unable to fetch Pay Request. |
| .payRequestNotFound | Throw when unable to find a pay request for the provided pay secret. |
| .payRequestFailed | Thrown when pay request failed. |
| .payRequestTimeout | Thrown when the returned pay request is still processing. |
| .unknown | Thrown when pay request is in an unknown status. |