CardFormDefaults exposes a set of per-field building blocks alongside its full section renderers. Each building block is a static function with the signature (PrimerCardFormSession) -> CardFieldContent. Drop any of them into a custom PrimerCardForm section slot to recompose the form one field at a time, while keeping the SDK’s built-in formatting, validation, keyboard configuration, and inline error display.
Every building block is self-hiding: it renders nothing unless its field is part of the active
CardFormConfiguration for the current session. You can drop every block into a layout without worrying about which fields the current session actually requires — only the configured ones appear.How the building blocks work
The full-section renderers —CardFormDefaults.cardDetails(_:) and CardFormDefaults.billingAddress(_:) — produce the complete, config-aware form. The field-level building blocks let you interleave your own content (banners, headings, custom layout) between individual fields instead.
Each field block forwards to the same shared, configuration-aware renderer the section helpers use, so a hand-composed layout behaves identically to the default form. The block checks whether its field appears in the session’s configuration.cardFields or configuration.billingFields; if not, it resolves to an EmptyView.
PrimerCardFormSession parameter and return a concrete View. Read session.state for rendering and call into the session for mutations and submission.
Card detail fields
These map to thecardFields in the active CardFormConfiguration (the default configuration is .cardNumber, .expiryDate, .cvv, .cardholderName).
| Method | Return type | Renders when | Description |
|---|---|---|---|
cardNumber(_:) | CardFieldContent | .cardNumber is in configuration.cardFields | Card number field with network-aware grouping, Luhn validation, and detected-network icon. |
expiryDate(_:) | CardFieldContent | .expiryDate is configured | Expiry field; auto-inserts the / separator (MM/YY) and validates for a valid, future month. |
cvv(_:) | CardFieldContent | .cvv is configured | CVV field; masked input, max length adapts to the detected network (4 for Amex, 3 otherwise). |
cardholderName(_:) | CardFieldContent | .cardholderName is configured | Cardholder name field with word capitalization. |
Co-badged card network selector
cardNetwork(_:) is a standalone selector for co-badged cards. Unlike the other blocks it does not read CardFormConfiguration; it renders only when more than one network is detected (session.state.availableNetworks.count > 1), reusing the SDK’s built-in dropdown. Tapping a network commits the choice through session.selectCardNetwork(_:).
| Method | Return type | Renders when | Description |
|---|---|---|---|
cardNetwork(_:) | CardNetworkFieldContent | availableNetworks.count > 1 | Dropdown selector for co-badged cards (e.g., Cartes Bancaires + Visa). |
Billing address fields
These map to thebillingFields in the active CardFormConfiguration. They appear only when billing address collection is enabled for the session (configuration.requiresBillingAddress and the corresponding field present in billingFields).
| Method | Return type | Renders when | Description |
|---|---|---|---|
firstName(_:) | CardFieldContent | .firstName is in configuration.billingFields | First name field with word capitalization. |
lastName(_:) | CardFieldContent | .lastName is configured | Last name field with word capitalization. |
email(_:) | CardFieldContent | .email is configured | Email field for receipts and notifications. |
phoneNumber(_:) | CardFieldContent | .phoneNumber is configured | Phone number field. |
addressLine1(_:) | CardFieldContent | .addressLine1 is configured | Primary street address line. |
addressLine2(_:) | CardFieldContent | .addressLine2 is configured | Secondary address line (apartment, suite, etc.). |
city(_:) | CardFieldContent | .city is configured | City field. |
state(_:) | CardFieldContent | .state is configured | State or province field; label adapts to the selected country. |
postalCode(_:) | CardFieldContent | .postalCode is configured | Postal/ZIP code field; format and label vary by country. |
countryCode(_:) | CardFieldContent | .countryCode is configured | Country selector field. |
Composing a custom card detail layout
Pass a@ViewBuilder closure to the cardDetails slot on PrimerCardForm. Lay out the field blocks in any order, and add your own content between them. Because each block is self-hiding, the extra fields you reference (such as cardholderName) appear only if the session’s configuration includes them.
Recomposing billing fields too
ThebillingAddress slot works the same way. Group billing blocks into your own layout; only the configured fields render.
Reacting to field state
Each building block manages its own input and inline error display, so you don’t have to wire bindings manually. When you need to react to the form as a whole — for example to drive your own submit button — read the publishedsession.state:
session.state via fieldErrors, hasError(for:), and errorMessage(for:). See Card Form Session for the full state surface.
See also
Card Form Defaults
The full section renderers and submit button these blocks complement.
PrimerCardForm
The composable form view and its
@ViewBuilder section slots.Card Form Session
Observable state, field updates, and submission for the card form.