Learn how to use the PayPal components in your iOS project.
Every component follows the same basic three-step lifecycle:
- Create the component and optionally add your own configuration.
- Render the component using SwiftUI. This is what makes the component visible and interactive.
- Dispose the component. This is a clean-up step that clears up resources and is handled automatically by SwiftUI.
To use the PayPal components, you first need to:
- Install Components for iOS.
- Complete the PayPal onboarding process in the Unity Portal.
- Configure your Xcode project with the required dependencies.
iOS offers two ways to implement PayPal payments, depending on your requirements:
- Simple PayPal: Use this approach when you need basic PayPal payments without vaulting features. Ideal for guest checkout, simple payments, and digital products.
- PayPal with vaulting: Manually compose the PayPal button and consent components for vaulting support. This approach gives you the flexibility to offer one-click payments with saved PayPal accounts.
The component lifecycle is automatically managed by SwiftUI across both approaches.
To get started, initialise the Checkout SDK in your iOS application.
import PXPCheckoutSDK
// Create session data (usually obtained from your backend)
let sessionData = SessionData(
sessionId: "your-session-id",
hmacKey: "your-hmac-key",
encryptionKey: "your-encryption-key"
)
// Create transaction data
let transactionData = TransactionData(
amount: 25.00,
currency: "USD",
entryType: .ecom,
intent: TransactionIntentData(
card: nil,
paypal: .authorisation
),
merchantTransactionId: "unique-transaction-id-\(UUID().uuidString)",
merchantTransactionDate: { Date() }
)
// Create checkout configuration
let checkoutConfig = CheckoutConfig(
environment: .test, // or .live
session: sessionData,
transactionData: transactionData,
merchantShopperId: "shopper-123",
ownerId: "owner-456"
)
// Initialise PxpCheckout SDK
let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)| Parameter | Description |
|---|---|
environmentEnvironment required | The environment type. Possible values:
|
sessionSessionData required | Details about the checkout session. |
transactionDataTransactionData required | Details about the transaction. |
transactionData.amountDecimal required | The transaction amount (e.g., 25.00 for $25). |
transactionData.currencyString | The currency code as a string (e.g., "USD", "EUR", "GBP"). |
transactionData.entryTypeEntryType required | The entry type. Possible values:
|
transactionData.intentTransactionIntentData required | The transaction intent data. Use TransactionIntentData(card: CardIntentType?, paypal: PayPalIntentType?).PayPal intent values:
|
transactionData.merchantTransactionIdString required | A unique identifier for this transaction. |
transactionData.merchantTransactionDate() -> Date required | A closure that returns the current date. |
merchantShopperIdString required | A unique identifier for this shopper. |
ownerIdString required | The identifier of the owner. |
Create the PayPal button component configuration with basic settings:
let config = PayPalButtonComponentConfig()
config.fundingSource = .paypal
config.payeeEmailAddress = "merchant@example.com"
config.paymentDescription = "Order #12345"
config.shippingPreference = .noShipping
config.userAction = .payNow| Parameter | Description |
|---|---|
fundingSourcePayPalFundingSource | The payment method to support. Possible values:
|
payeeEmailAddressString? | Your merchant email address. |
paymentDescriptionString? | A description of the payment. |
shippingPreferencePayPalShippingPreference? | The shipping details to use. Possible values:
|
userActionPayPalUserAction? | The next step in the payment flow. Possible values:
|
Create and render the component using SwiftUI:
import SwiftUI
import PXPCheckoutSDK
struct PayPalPaymentView: View {
@State private var paypalComponent: BaseComponent?
@State private var isLoading = true
@State private var errorMessage: String?
var body: some View {
VStack(spacing: 16) {
if isLoading {
ProgressView("Initialising PayPal...")
} else if let component = paypalComponent {
component.buildContent()
.frame(height: 50)
} else if let error = errorMessage {
Text("Error: \(error)")
.foregroundColor(.red)
}
}
.padding()
.onAppear {
createPayPalComponent()
}
}
private func createPayPalComponent() {
Task {
do {
let pxpCheckout = try createPxpCheckout()
let config = PayPalButtonComponentConfig()
config.fundingSource = .paypal
let component = try pxpCheckout.create(
.paypalButton,
componentConfig: config
)
await MainActor.run {
paypalComponent = component
isLoading = false
}
} catch {
await MainActor.run {
errorMessage = error.localizedDescription
isLoading = false
}
}
}
}
}Implement event handling callbacks to manage payment outcomes:
let config = PayPalButtonComponentConfig()
config.fundingSource = .paypal
// Payment success handler
config.onApprove = { approvalData in
print("Payment successful - Order ID: \(approvalData.orderID)")
print("Payer ID: \(approvalData.payerID)")
// Navigate to success screen or update UI
navigateToSuccessScreen(approvalData.orderID)
}
// Error handler
config.onError = { error in
print("Payment error: \(error.errorMessage)")
// Show error message to user
showErrorDialog("Payment failed. Please try again.")
}
// Cancellation handler
config.onCancel = { error in
print("Payment cancelled by user")
// Show cancellation message
showMessage("Payment was cancelled.")
}Here's a complete working example with the PayPal button component:
import SwiftUI
import PXPCheckoutSDK
struct SimplePayPalView: View {
@State private var pxpCheckout: PxpCheckout?
@State private var paypalComponent: BaseComponent?
@State private var isLoading = true
@State private var paymentStatus: String?
@State private var showSuccessAlert = false
@State private var showErrorAlert = false
var body: some View {
NavigationView {
VStack(spacing: 16) {
Text("Complete your payment")
.font(.title)
Text("Amount: $25.00")
.font(.title3)
if isLoading {
ProgressView("Initialising PayPal...")
} else if let component = paypalComponent {
component.buildContent()
.frame(height: 50)
.padding(.horizontal)
}
if let status = paymentStatus {
Text(status)
.foregroundColor(.secondary)
.padding()
}
Spacer()
}
.padding()
.onAppear {
createPayPalComponent()
}
.alert("Payment Successful", isPresented: $showSuccessAlert) {
Button("OK") {
// Dismiss and navigate
}
} message: {
Text(paymentStatus ?? "")
}
.alert("Payment Error", isPresented: $showErrorAlert) {
Button("OK", role: .cancel) { }
} message: {
Text(paymentStatus ?? "")
}
}
}
private func createPayPalComponent() {
Task {
do {
// Initialise PxpCheckout SDK
let sessionData = SessionData(
sessionId: "your-session-id",
hmacKey: "your-hmac-key",
encryptionKey: "your-encryption-key"
)
let transactionData = TransactionData(
amount: 25.00,
currency: "USD",
entryType: .ecom,
intent: TransactionIntentData(
card: nil,
paypal: .authorisation
),
merchantTransactionId: "tx-\(UUID().uuidString)",
merchantTransactionDate: { Date() }
)
let checkoutConfig = CheckoutConfig(
environment: .test,
session: sessionData,
transactionData: transactionData,
merchantShopperId: "shopper-123",
ownerId: "owner-456"
)
let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)
self.pxpCheckout = pxpCheckout
// Create PayPal component
let config = PayPalButtonComponentConfig()
config.fundingSource = .paypal
config.payeeEmailAddress = "merchant@example.com"
config.paymentDescription = "Order #12345"
// Button styling
config.style = PayPalButtonStyleConfig(
color: .gold,
label: nil,
size: .collapsed,
edges: .softEdges
)
// Event handlers
config.onApprove = { [self] approvalData in
await MainActor.run {
paymentStatus = "Payment successful! Order ID: \(approvalData.orderID)"
showSuccessAlert = true
}
}
config.onError = { [self] error in
await MainActor.run {
paymentStatus = "Payment failed: \(error.errorMessage)"
showErrorAlert = true
}
}
config.onCancel = { [self] _ in
await MainActor.run {
paymentStatus = "Payment was cancelled"
}
}
let component = try pxpCheckout.create(
.paypalButton,
componentConfig: config
)
await MainActor.run {
paypalComponent = component
isLoading = false
}
} catch {
await MainActor.run {
paymentStatus = "Initialisation error: \(error.localizedDescription)"
isLoading = false
}
}
}
}
}You can configure the appearance and behaviour of the PayPal component to fit your brand. We've documented all configurable parameters in the Configuration section.
let config = PayPalButtonComponentConfig()
config.fundingSource = .paypal
config.payeeEmailAddress = "merchant@example.com"
config.paymentDescription = "Premium Subscription"
config.shippingPreference = .noShipping
config.userAction = .payNow
config.locale = "en_US"
// Custom styling
config.style = PayPalButtonStyleConfig(
color: .blue,
label: .buyNow,
size: .expanded,
edges: .rounded,
contentInsets: .uniform(12)
)The PayPal component emits events based on user interaction or validation. As seen in the steps above, you can implement callback functions to handle these events. For more information about all the available events, see the Events page.
config.onPreAuthorisation = {
// Provide additional transaction data before authorisation
return PayPalTransactionInitData(
addressVerification: true,
riskScreeningData: getRiskScreeningData()
)
}
config.onOrderCreated = { submitResult in
if let merchantResult = submitResult as? MerchantSubmitResult {
print("Order created: \(merchantResult.systemTransactionId)")
// Track order creation for analytics
trackOrderCreation(merchantResult)
}
}Error handling is crucial for payment components because they deal with sensitive financial data and complex validation rules. For more details about error handling, see the Troubleshooting page.
do {
let paypalComponent = try pxpCheckout.create(
.paypalButton,
componentConfig: config
)
// Render component
paypalComponent.buildContent()
.frame(height: 50)
} catch {
print("Failed to initialise PayPal component: \(error.localizedDescription)")
// Show fallback UI or error message to user
Text("Payment system temporarily unavailable. Please try again later.")
.foregroundColor(.red)
}To get real-time updates about PayPal transactions, you can subscribe to the PayPal webhooks in the Unity Portal. Learn more about webhooks.