# iOS SDK integration

A guide to integrating the Peach Orchestration mobile SDK into a native iOS app using Swift and the `Hyperswitch` framework. Minimum: iOS 15.1+.

## What this page covers
- Ten sections: Prerequisites, Installation, Configuration, Basic integration, Payment methods, Saved cards, Error handling, Customisation, Testing, Troubleshooting
- Xcode/Swift prerequisites and getting Dashboard credentials (publishable key `pk_snd_xxx`/`pk_prd_xxx`)
- Installing via CocoaPods from the private Peach spec repo
- Creating and presenting the `PaymentSheet` with a `client_secret` from your backend
- Payment methods: cards, Apple Pay, direct wallet buttons (`ApplePayButton` / `ExpressCheckoutButton`), Google Pay (Catalyst), bank redirects, PayJustNow (BNPL)
- Saved cards via customer configuration + ephemeral keys, and Setup Intents
- Theming with `PaymentSheet.Appearance`, dark mode, error handling and retry logic
- Test cards, XCTest unit/UI tests, and troubleshooting (Apple Pay, 3DS, deep links)

## Key steps / API

Current version: all three pods at **0.7.0**; release assets come from the GitHub tag `v0.7.0`. Minimum deployment target iOS 15.1.

The pods live on a **private spec repo, not CocoaPods trunk**, so a consumer's Podfile needs both sources:

```ruby
source 'https://github.com/peach-payments/hyperswitch-sdk-ios.git'
source 'https://cdn.cocoapods.org/'

pod 'peachpayments-hyperswitch-ios', '~> 0.7'
```

Then `pod repo update && pod install`.

| Pod | Swift module |
|---|---|
| `peachpayments-hyperswitch-ios` | `Hyperswitch` |
| `peachpayments-hyperswitch-ios-lite` | `HyperswitchLite` |
| `peachpayments-hyperswitch-ios-authentication` | `HyperswitchAuthentication` |

Subspecs on the main pod: `core` and `common` are the defaults, plus `sentry`, `scancard`, `netcetera3ds`, `airborne`, `paypal` — request one as `pod 'peachpayments-hyperswitch-ios/scancard'`. The Flutter plugin depends on `peachpayments-hyperswitch-ios/sentry`.

**`import Hyperswitch` stays as-is.** Migrating from the upstream `hyperswitch-sdk-ios` pod only changes the *pod* name — the Swift `module_name` is still `Hyperswitch`, so imports must not be rewritten.

```swift
import Hyperswitch

// 1. Create the session with your publishable key
let paymentSession = PaymentSession(
    publishableKey: "pk_test_your_publishable_key",
    customBackendUrl: "https://app.sandbox-next.peachpayments.com/api"
)

// 2. Initialise with a client secret fetched from your server
paymentSession.initPaymentSession(paymentIntentClientSecret: clientSecret)

// 3. Present the payment sheet
let configuration = PaymentSheet.Configuration()
paymentSession.presentPaymentSheet(viewController: self, configuration: configuration) { result in
    switch result {
    case .completed(let data): // success
    case .canceled(let data):  // user dismissed
    case .failed(let error):   // error
    }
}
```

Other real API surface referenced in the source:
- `PaymentSheet.Configuration` fields: `merchantDisplayName`, `applePay` (`PaymentSheet.ApplePayConfiguration`), `googlePay` (`PaymentSheet.GooglePayConfiguration`), `returnURL`, `paymentMethodOrder`, `customer` (`PaymentSheet.CustomerConfiguration(id:ephemeralKeySecret:)`), `savePaymentMethodOptIn`
- `PaymentSession.handleURLCallback(url)` — handle 3DS/redirect return in `AppDelegate`
- Setup Intent: construct `PaymentSheet(setupIntentClientSecret:configuration:)` to save a card without charging
- Theming: `PaymentSheet.Appearance` with `.colors`, `.cornerRadius`, `.borderWidth`, `.shadow`, `.font`, `.primaryButton`
- SwiftUI: `PaymentSheet.PaymentButton(paymentSession:configuration:onCompletion:)`

### Direct wallet buttons

New public API for embedding a branded Apple Pay button in your own checkout, with no payment sheet:

```swift
let button = ApplePayButton(
    paymentSession: paymentSession,
    configuration: configuration
) { result in /* .completed / .canceled / .failed */ }

view.addSubview(button)   // pin leading/trailing/top — no height constraint
```

`ExpressCheckoutButton` has identical initialisers and renders every enabled wallet. Both need the two-stage bootstrap: `Hyperswitch(configuration:)` → `initPaymentSession(configuration:)`. `confirm()` starts the payment programmatically, though Apple's guidelines expect the branded button to be the tap target.

The button may render nothing: availability is decided by the SDK (wallet enabled for the merchant, connector returns a session token, wallet usable on the device), and it collapses to zero height — a normal empty state, not an error. Keep a card fallback. Testing Apple Pay needs a real device with a provisioned card, or a simulator signed into a sandbox tester account. Wallet result callbacks only reach the host from pod 0.7.0 onward.

Sandbox API base is `https://app.sandbox-next.peachpayments.com/api`; production is `https://app.next.peachpayments.com/api`. Mobile SDK V2 Apple Pay requires your own merchant ID and payment processing certificate (Apple Developer Program membership; Peach Payments provides CSRs — [contact support](https://support.peachpayments.com/support/tickets/new?ticket_form=log_a_support_ticket)). Register the merchant ID ([portal](https://developer.apple.com/account/resources/identifiers/list/merchant); format `merchant.com.yourcompany`), add the Apple Pay capability in Xcode, then send the merchant ID and certificates to Peach Payments to configure your account. See Apple's [setup documentation](https://developer.apple.com/documentation/apple_pay_on_the_web/setting_up_your_server) and [configuration guide](https://developer.apple.com/apple-pay/implementation/).

## Related
- [iOS SDK customisation](/sdk-customization-ios.md): live simulator that restyles the iOS payment sheet
- [Android SDK](/sdk-mobile-android.md): native Android equivalent
- [Web SDK](/sdk-web.md): browser integration
- [API Playground](/playground.md): create a payment intent and get a `client_secret`
- [Testing](/docs/testing.md): test cards and sandbox guidance

---

Interactive version: https://playground.peachpayments.com/sdk-mobile/ios
