Apple Pay
The library includes the SecureApplePayButton component, which simplifies Apple Pay integration into your app. The component automatically:
- verifies Apple Pay availability on the device and in the session,
- displays the standard Apple Pay button (
PKPaymentButton), - handles the payment flow and obtains the payment token,
- submits the token to the payment gateway for processing.
Prerequisites for using Apple Pay are Checkout API activation and proper setup in the Apple Developer account and Apple Pay payment-processing certificate, described below.
1. Apple Developer Account
Before deploying Apple Pay you need to create a Merchant ID in the Apple Developer portal.
- Sign in to the Apple Developer portal.
- Open Certificates, Identifiers & Profiles → Identifiers.
- In the left menu, choose the Merchant IDs type.
- Click + and register a new Merchant ID with the format
merchant.<your-domain>.<name>(e.g.merchant.cz.example.production). - We recommend creating two Merchant IDs — one for testing and one for production.
These Merchant IDs are then passed to ComgateSecureSession as the applePayMerchantIdentifier parameter.
2. Apple Pay Payment Processing Certificate
For each Merchant ID you must generate a Payment Processing Certificate that enables encryption of payment data.
- On the Merchant ID detail page in the Apple Developer portal, click Apple Pay Payment Processing Certificate → Create Certificate.
- Apple will request a Certificate Signing Request (CSR).
- Comgate support will provide this CSR — contact them to receive the correct CSR file.
- Upload the CSR to the Apple Developer portal, download the generated certificate, and hand it back to Comgate.
- Once the certificate is deployed on the Comgate side, Apple Pay is ready for use with that Merchant ID.
Activating the certificate on Comgate's side is not instant — it takes some time. For the initial Apple Pay setup, deliver the certificate to Comgate well in advance of the planned production launch.
The Apple Pay certificate must be renewed every year. Tracking the expiration is the merchant's responsibility — ideally contact Comgate support 2 months before expiration and start the renewal proactively.
3. Implementation
The following section describes the library components needed to integrate Apple Pay into your app.
The library handles payment-gateway configuration, building the payment request, extracting the token, and submitting it to the API automatically. You only need to use the SecureApplePayButton component and pass the required parameters.
Requirements
| Requirement | Description |
|---|---|
| Apple Pay capability | In Xcode, on the Signing & Capabilities tab, add the Apple Pay capability. |
| Merchant ID in entitlements | The Apple Pay Merchant ID must be listed in com.apple.developer.in-app-payments in your entitlements file. |
applePayMerchantIdentifier | Apple Pay Merchant ID — required for Apple Pay. Passed to ComgateSecureSession. |
applePayDisplayName | Merchant display name shown in the Apple Pay sheet (optional, recommended). |
threeDSConfig | A ThreeDSConfig instance passed to ComgateSecureSession (required for Apple Pay too). |
| Checkout API activation | Apple Pay configuration is loaded internally by the library during session initialization. |
How to obtain applePayMerchantIdentifier
You'll find your applePayMerchantIdentifier in the Apple Developer portal on your Merchant ID detail page:
- Sign in to the Apple Developer portal.
- Select your Merchant ID.
- Copy the Identifier value (e.g.
merchant.cz.example.production). - Use this value as
applePayMerchantIdentifierinComgateSecureSession.
SecureApplePayButton
import SwiftUI
import ComgateSDK
SecureApplePayButton(
session: session,
paymentParams: {
try! PaymentParams(
email: "customer@example.com",
price: 100,
curr: "CZK",
country: "CZ",
label: "Payment label",
refId: "ref-123",
fullName: "John Doe"
)
},
onResult: { result in
// Handle payment result
}
)
.frame(height: 56)
Button appearance
SecureApplePayButton lets you customize the look and type of the Apple Pay button via the ApplePayButtonStyle struct:
| Property | Type | Description |
|---|---|---|
type | PKPaymentButtonType | Button label type (e.g. .plain, .buy, .checkout, .continue, .donate, .subscribe). Default: .plain. |
appearance | PKPaymentButtonStyle | Visual variant (.black, .white, .whiteOutline, .automatic). Default: .black. |
cornerRadius | CGFloat | Button corner radius in points. Default: 12. |
SecureApplePayButton(
session: session,
paymentParams: { /* ... */ },
onResult: { _ in },
style: ApplePayButtonStyle(
type: .checkout,
appearance: .black,
cornerRadius: 16
)
)
.frame(height: 56)
Automatic session binding
SecureApplePayButton is automatically bound to ComgateSecureSession. The button is shown only when:
applePayMerchantIdentifierwas provided when the session was created,- the session reports
isApplePayConfigured == true(after successful initialization).
When Apple Pay is not configured, the component returns an empty EmptyView() — so you can safely place the button on the screen without manually checking availability.
PaymentParams
Apple Pay payment parameters use the same PaymentParams struct as card payments. Full parameter description is available in Card data — PaymentParams.
Configuration in ComgateSecureSession
For Apple Pay, pass applePayMerchantIdentifier and optionally applePayDisplayName to the ComgateSecureSession initializer:
let session = ComgateSecureSession(
checkoutId: "your-checkout-id",
applePayMerchantIdentifier: "merchant.cz.example.production",
applePayDisplayName: "Store name",
threeDSConfig: ThreeDSConfig()
)
Complete example
import SwiftUI
import ComgateSDK
@main
struct ApplePayApp: App {
@StateObject private var session = ComgateSecureSession(
checkoutId: "your-checkout-id",
applePayMerchantIdentifier: "merchant.cz.example.production",
applePayDisplayName: "Store name",
threeDSConfig: ThreeDSConfig()
)
var body: some Scene {
WindowGroup {
ApplePayScreen(session: session)
.task {
if case .notInitialized = session.state {
try? await session.initialize()
}
}
}
}
}
struct ApplePayScreen: View {
@ObservedObject var session: ComgateSecureSession
@State private var resultText = ""
var body: some View {
VStack(spacing: 16) {
SecureApplePayButton(
session: session,
paymentParams: {
try! PaymentParams(
email: "customer@example.com",
price: 100,
curr: "CZK",
country: "CZ",
label: "Order #123",
refId: "order-123",
fullName: "John Doe"
)
},
onResult: { result in
switch result {
case .paid: resultText = "Payment successful"
case .authorized: resultText = "Payment authorized"
case .pending: resultText = "Payment pending…"
case .cancelled(let reason, _): resultText = "Cancelled: \(reason ?? "-")"
case .failed(let err): resultText = "Error: \(err.message)"
}
}
)
.frame(height: 56)
if !resultText.isEmpty {
Text(resultText)
}
}
.padding()
}
}
Combining with card payments
The Apple Pay button can easily be combined with the card form on the same screen. Both components share the same ComgateSecureSession:
struct CombinedPaymentScreen: View {
@ObservedObject var session: ComgateSecureSession
@StateObject private var panState: SecurePanFieldState
@StateObject private var expiryState: SecureExpiryFieldState
@StateObject private var cvvState: SecureCvvFieldState
@StateObject private var statusState = PaymentStatusState()
@StateObject private var holder: CollectorHolder
init(session: ComgateSecureSession) {
self._session = ObservedObject(wrappedValue: session)
let pan = SecurePanFieldState()
let expiry = SecureExpiryFieldState()
let cvv = SecureCvvFieldState()
_panState = StateObject(wrappedValue: pan)
_expiryState = StateObject(wrappedValue: expiry)
_cvvState = StateObject(wrappedValue: cvv)
_holder = StateObject(wrappedValue: CollectorHolder(pan: pan, expiry: expiry, cvv: cvv))
}
private var collector: SecureCardDataCollector { holder.collector }
private func params() -> PaymentParams {
try! PaymentParams(
email: "customer@example.com",
price: 100,
curr: "CZK",
country: "CZ",
label: "Order",
refId: "order-123",
fullName: "John Doe"
)
}
var body: some View {
VStack(spacing: 12) {
SecurePanField(state: panState)
SecureExpiryField(state: expiryState)
SecureCvvField(state: cvvState)
SecurePayButton(
session: session,
collector: collector,
paymentParams: params,
onResult: { statusState.show(result: $0) }
)
Divider()
SecureApplePayButton(
session: session,
paymentParams: params,
onResult: { statusState.show(result: $0) }
)
.frame(height: 56)
SecurePaymentStatusView(state: statusState)
}
.padding()
}
}
When using Apple Pay through the Mobile SDK, always create and pass threeDSConfig to ComgateSecureSession.
4. Test environment
Sandbox tester
For testing Apple Pay in the sandbox environment, use a Sandbox Tester Account created in App Store Connect (Users and Access → Sandbox Testers).
- Create a Sandbox Tester Account with a test Apple ID.
- On a physical device, sign out of your production Apple ID in the App Store and sign in as the sandbox tester in Settings → Wallet & Apple Pay.
- Add test cards from Apple's test-card list.
Test Merchant ID
The test Merchant ID must be registered in your Apple Developer account and must have a Payment Processing Certificate paired with Comgate.
Physical device vs. simulator
Apple Pay has limited functionality in the simulator:
| Environment | Apple Pay support |
|---|---|
| iOS simulator | The Apple Pay sheet appears, but only the test cards stored in Wallet are available (limited set). Not sufficient for full testing. |
| Physical device (sandbox) | Full support with a Sandbox Tester Account and test cards. Recommended for testing. |
| Physical device (production) | After certificate approval, real transactions work. |
For full Apple Pay testing, always use a physical device signed in with a Sandbox Tester Account. The simulator cannot generate a valid production-format payment token.