Learn how to configure the PayPal payout receiver component for iOS.
The PayPalPayoutReceiverComponent displays the recipient's PayPal email address with optional masking for privacy. This component shows users which PayPal account will receive their payout. Use this component alongside the PayoutAmountComponent and PayoutSubmissionComponent for returning users who have already linked their PayPal accounts.
This component is for users with stored PayPal credentials provided by your backend.
Before using the payout receiver component, ensure you have:
- Initialised the SDK with stored PayPal credentials:
let paypalConfig = PayPalConfig(
payout: PayPalPayoutConfig(
paypalWallet: PayPalWallet(
email: "user@example.com", // This email will be displayed
payerId: "PAYERID123ABC", // Credentials from backend
proceedPayoutWithSdk: true
)
)
)
let checkoutConfig = CheckoutConfig(
environment: .test,
session: sessionData,
transactionData: transactionData,
merchantShopperId: "user-123",
ownerId: "merchant-456",
paypalConfig: paypalConfig
)
let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)- Retrieved the user's PayPal credentials from your backend:
// Fetch stored PayPal credentials from your backend
let credentials = try await fetchPayPalCredentials(userId: currentUser.id)
// Use credentials.paypalAccountId and credentials.paypalEmail in SDK initialisationAt minimum, the payout receiver component requires no mandatory configuration:
let config = PayPalPayoutReceiverComponentConfig()
let component = try pxpCheckout.create(.paypalPayoutReceiver, componentConfig: config)Enable email masking for privacy (e.g., j***@****.com):
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
accessibilityLabel: "PayPal account email",
applyMask: true,
showMaskToggle: true
)
let component = try pxpCheckout.create(.paypalPayoutReceiver, componentConfig: config)| Property | Description |
|---|---|
labelString? | The label text displayed above the email field. |
accessibilityLabelString? | The accessibility label for screen readers. |
applyMaskBool | Whether to mask the email address. Defaults to true. |
showMaskToggleBool | Whether to show a toggle button to reveal/hide the email. Defaults to true. |
For more complex implementations, configure styling, validation messages, and receiver type:
let config = PayPalPayoutReceiverComponentConfig(
label: "Receiving PayPal Account",
placeholder: "PayPal email",
guideText: "Funds will be sent to this account",
accessibilityLabel: "PayPal account receiving the payout",
applyMask: true,
showMaskToggle: true,
receiverType: .email,
// Custom container styling
styles: FieldStyle(
backgroundColor: Color(.systemGray6),
borderColor: Color(.systemGray4),
borderWidth: 1,
cornerRadius: 8,
padding: EdgeInsets(top: 12, leading: 16, bottom: 12, trailing: 16)
),
// Custom input text styling
inputStyles: FieldInputStateStyles(
base: FieldStyle(
color: Color(.label),
fontSize: 16,
fontWeight: .regular
)
),
// Custom label styling
labelStyles: FieldLabelStateStyles(
base: FieldStyle(
color: Color(.secondaryLabel),
fontSize: 14,
fontWeight: .medium
)
),
// Custom validation messages
validations: PayPalPayoutReceiverValidationResource(
PPE01: "PayPal email is required",
PPE02: "Please enter a valid email address"
)
)| Property | Description |
|---|---|
labelString? | The label text displayed above the email field. |
placeholderString? | The placeholder text shown when the field is empty. |
guideTextString? | The helper text displayed below the email field. |
accessibilityLabelString? | The accessibility label for screen readers. |
applyMaskBool | Whether to mask the email address. Defaults to true. |
showMaskToggleBool | Whether to show a toggle to reveal/hide email. Defaults to true. |
receiverTypePayoutRecipientType | The recipient type. Defaults to .email. |
stylesFieldStyle? | Custom styling for the container. |
inputStylesFieldInputStateStyles? | Custom styling for the email text. |
labelStylesFieldLabelStateStyles? | Custom styling for the label text. |
validationsPayPalPayoutReceiverValidationResource? | Custom validation error messages. |
The receiver component supports email masking for user privacy. When masking is enabled, emails are displayed in a protected format.
For john.doe@example.com:
- If
applyMask: false, thenjohn.doe@example.comis displayed. - If
applyMask: true, thenj***@****.comis displayed.
Email masking displays:
- The first character of the local part (before
@) - Three asterisks replacing the remaining local part characters
- The
@symbol - Four asterisks the replacing domain name
.com(or the actual TLD)
When showMaskToggle is enabled, users can tap to reveal or hide their email:
let config = PayPalPayoutReceiverComponentConfig(
applyMask: true, // Start with masked email
showMaskToggle: true // Allow user to reveal/hide
)For maximum privacy, hide the toggle so users can't reveal the full email:
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
applyMask: true,
showMaskToggle: false
)For contexts where privacy is less of a concern:
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
applyMask: false,
showMaskToggle: false
)The payout receiver component renders with default styling suitable for most applications:
// Default container style
FieldStyle(
color: Color(red: 0.035, green: 0.035, blue: 0.047),
font: .system(size: 16, weight: .regular),
backgroundColor: Color(red: 0.929, green: 0.933, blue: 0.937),
borderColor: Color(red: 0.725, green: 0.741, blue: 0.753),
borderWidth: 1,
cornerRadius: 4,
padding: EdgeInsets(top: 12, leading: 16, bottom: 12, trailing: 16)
)
// Default label style
FieldStyle(
color: Color.primary,
font: .system(size: 14, weight: .bold)
)Customise the appearance to match your app's design:
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
applyMask: true,
showMaskToggle: true,
// Container styling
styles: FieldStyle(
backgroundColor: Color(red: 0.0, green: 0.44, blue: 0.73).opacity(0.1), // Light PayPal blue
borderColor: Color(red: 0.0, green: 0.44, blue: 0.73),
borderWidth: 1,
cornerRadius: 8,
padding: EdgeInsets(top: 14, leading: 16, bottom: 14, trailing: 16)
),
// Email text styling
inputStyles: FieldInputStateStyles(
base: FieldStyle(
color: Color(red: 0.0, green: 0.44, blue: 0.73), // PayPal blue
fontSize: 16,
fontWeight: .medium
)
),
// Label styling
labelStyles: FieldLabelStateStyles(
base: FieldStyle(
color: Color(.secondaryLabel),
fontSize: 12,
fontWeight: .semibold
)
)
)Apply PayPal's brand colours:
struct PayPalBrand {
static let blue = Color(red: 0.0, green: 0.44, blue: 0.73)
static let darkBlue = Color(red: 0.0, green: 0.18, blue: 0.38)
static let lightBlue = Color(red: 0.0, green: 0.44, blue: 0.73).opacity(0.1)
}
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
applyMask: true,
showMaskToggle: true,
styles: FieldStyle(
backgroundColor: PayPalBrand.lightBlue,
borderColor: PayPalBrand.blue,
borderWidth: 2,
cornerRadius: 8,
padding: EdgeInsets(top: 16, leading: 20, bottom: 16, trailing: 20)
),
inputStyles: FieldInputStateStyles(
base: FieldStyle(
color: PayPalBrand.darkBlue,
fontSize: 16,
fontWeight: .semibold
)
),
labelStyles: FieldLabelStateStyles(
base: FieldStyle(
color: PayPalBrand.blue,
fontSize: 13,
fontWeight: .bold
)
)
)Each FieldStyle object supports the following SwiftUI-based properties:
| Property | Type | Description | Example |
|---|---|---|---|
color | Color? | The text/foreground colour. | .label |
font | Font? | The SwiftUI font for the text. | .body |
fontWeight | Font.Weight? | The font weight. | .semibold, .bold |
fontSize | CGFloat? | The font size in points. | 16 |
labelFont | Font? | The SwiftUI font for labels. | .caption |
labelColor | Color? | The colour for labels. | .secondary |
valueFont | Font? | The SwiftUI font for values. | .body |
valueColor | Color? | The colour for values. | .primary |
backgroundColor | Color? | The background colour. | Color(.systemGray6) |
borderColor | Color? | The border colour. | .gray |
borderWidth | CGFloat? | The border width in points. | 1 |
cornerRadius | CGFloat? | The corner radius in points. | 8 |
padding | EdgeInsets? | The padding around the content. | EdgeInsets(top: 12, leading: 16, bottom: 12, trailing: 16) |
margin | EdgeInsets? | The margin around the component. | EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0) |
textAlignment | TextAlignment? | The text alignment. | .leading |
opacity | Double? | The opacity (0.0 - 1.0). | 1.0 |
shadow | ShadowStyle? | Shadow styling. | ShadowStyle(color: .black.opacity(0.2), radius: 4, x: 0, y: 2) |
icon | IconStyle? | Icon styling with size and tint colour. | IconStyle(size: CGSize(width: 24, height: 24), tintColor: .white) |
Provide custom error messages for validation scenarios:
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
validations: PayPalPayoutReceiverValidationResource(
PPE01: "Please provide a PayPal email address",
PPE02: "The email address format is invalid"
)
)| Validation | Description |
|---|---|
PPE01 | Message shown when the receiver email is missing. |
PPE02 | Message shown when the email format is invalid. |
Currently, only .email is supported:
receiverType: .email // Only supported valueRenders the receiver display as a SwiftUI view:
func buildContent() -> AnyViewReturns the component as a SwiftUI AnyView. The returned view is a read-only display showing the PayPal email from SDK configuration.
struct PayoutView: View {
@State private var receiverComponent: BaseComponent?
var body: some View {
VStack {
if let component = receiverComponent {
component.buildContent()
.frame(maxWidth: .infinity)
}
}
.onAppear {
createReceiverComponent()
}
}
private func createReceiverComponent() {
Task {
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
applyMask: true,
showMaskToggle: true
)
let component = try pxpCheckout.create(.paypalPayoutReceiver, componentConfig: config)
await MainActor.run {
self.receiverComponent = component
}
}
}
}The PayPalPayoutReceiverComponent is primarily a display component. The email address displayed is determined by the paypalConfig.payout.paypalWallet.email configured during the SDK initialisation.
The PayPalPayoutReceiverComponent is a read-only display component:
- The email address is sourced from
PayPalWallet.emailin the SDK configuration. - Users can't edit the email through this component.
- To change the displayed email, you must reinitialise SDK with a different
PayPalWalletconfiguration. - The component has no
getValue()method (display-only, no input collection).
// To change the displayed email, update SDK configuration
let updatedPaypalWallet = PayPalWallet(
email: "newemail@example.com", // New email to display
payerId: "PAYERID123ABC",
proceedPayoutWithSdk: true
)
// Reinitialise SDK with new configuration
let checkoutConfig = CheckoutConfig(
// ... other config
paypalConfig: PayPalConfig(
payout: PayPalPayoutConfig(
paypalWallet: updatedPaypalWallet
)
)
)A simple implementation showing the PayPal email:
import SwiftUI
import PXPCheckoutSDK
struct BasicReceiverView: View {
@State private var receiverComponent: BaseComponent?
var body: some View {
VStack(spacing: 16) {
Text("Payout Destination")
.font(.title)
if let component = receiverComponent {
component.buildContent()
.frame(maxWidth: .infinity)
}
}
.padding()
.onAppear {
createComponent()
}
}
private func createComponent() {
Task {
let config = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
accessibilityLabel: "PayPal account for receiving payout",
applyMask: true,
showMaskToggle: true
)
let component = try pxpCheckout.create(.paypalPayoutReceiver, componentConfig: config)
await MainActor.run {
self.receiverComponent = component
}
}
}
}Implementation with masked email and no reveal option:
let config = PayPalPayoutReceiverComponentConfig(
label: "Linked PayPal Account",
guideText: "Your email is hidden for security",
accessibilityLabel: "Linked PayPal account",
applyMask: true,
showMaskToggle: false, // Cannot reveal email
styles: FieldStyle(
backgroundColor: Color(.systemGray6),
borderColor: Color(.systemGray4),
borderWidth: 1,
cornerRadius: 8,
padding: EdgeInsets(top: 14, leading: 16, bottom: 14, trailing: 16)
),
inputStyles: FieldInputStateStyles(
base: FieldStyle(
color: Color(.label),
fontSize: 16,
fontWeight: .medium,
// Add a lock icon style if supported
)
)
)Use the receiver component alongside the amount and submission components:
struct DirectPayoutView: View {
@State private var amountComponent: BaseComponent?
@State private var receiverComponent: BaseComponent?
@State private var submissionComponent: BaseComponent?
var body: some View {
VStack(spacing: 20) {
Text("Withdraw to PayPal")
.font(.title)
// Amount display
if let amount = amountComponent {
amount.buildContent()
.frame(maxWidth: .infinity)
}
// Receiver display
if let receiver = receiverComponent {
receiver.buildContent()
.frame(maxWidth: .infinity)
}
Divider()
.padding(.vertical, 8)
// Submit button
if let submit = submissionComponent {
submit.buildContent()
.frame(maxWidth: .infinity)
}
}
.padding()
.onAppear {
createComponents()
}
}
private func createComponents() {
Task {
// Create amount component
let amountConfig = PayoutAmountComponentConfig(
label: "Payout Amount"
)
let amount = try pxpCheckout.create(.payoutAmount, componentConfig: amountConfig)
// Create receiver component with PayPal branding
let receiverConfig = PayPalPayoutReceiverComponentConfig(
label: "PayPal Account",
applyMask: true,
showMaskToggle: true,
styles: FieldStyle(
backgroundColor: Color(red: 0.0, green: 0.44, blue: 0.73).opacity(0.05),
borderColor: Color(red: 0.0, green: 0.44, blue: 0.73).opacity(0.3),
borderWidth: 1,
cornerRadius: 8
)
)
let receiver = try pxpCheckout.create(.paypalPayoutReceiver, componentConfig: receiverConfig)
// Create submission component
let submissionConfig = PayoutSubmissionComponentConfig(
submitText: "Withdraw Now",
onPostPayout: { result in
print("Payout completed: \(result.merchantTransactionId)")
}
)
let submission = try pxpCheckout.create(.payoutSubmission, componentConfig: submissionConfig)
await MainActor.run {
self.amountComponent = amount
self.receiverComponent = receiver
self.submissionComponent = submission
}
}
}
}The receiver component can generate validation errors. Handle these errors through the PayoutSubmissionComponent's onError callback:
| Error code | Exception | Description |
|---|---|---|
SDK0803 | PaypalPayoutReceiverRequiredException | The receiver is required. |
SDK0804 | PayoutReceiverTypeInvalidException | Invalid receiver type. |
SDK0805 | PaypalPayoutReceiverTypeEmailOnlyException | The receiver type must be Email. |
SDK0808 | PaypalPayoutEmailInvalidException | Invalid email format. |
While the receiver component displays the PayPal email, validation errors are triggered by the PayoutSubmissionComponent when attempting to execute a payout. Handle these errors through the submission component's onError callback:
let submissionConfig = PayoutSubmissionComponentConfig(
onError: { error in
// Handle receiver-related validation errors here
switch error.errorCode {
case "SDK0803", "SDK0804", "SDK0805", "SDK0808":
// Receiver validation errors
print("Receiver error: \(error.errorMessage)")
default:
break
}
}
)For a complete list of error codes, see Data validation.