Skip to content

Commit 25246c5

Browse files
feat: add applePayStyle prop and AcceleratedCheckoutButtons README section
1 parent 64318b1 commit 25246c5

9 files changed

Lines changed: 280 additions & 12 deletions

File tree

README.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,178 @@ shopify.addEventListener('geolocationRequest', async (event: GeolocationRequestE
841841

842842
---
843843

844+
## Accelerated Checkouts
845+
846+
Accelerated checkout buttons surface Apple Pay and Shop Pay options earlier in the buyer journey so more orders complete without leaving your app.
847+
848+
### Prerequisites
849+
850+
- iOS 16 or later
851+
- The `write_cart_wallet_payments` access scope ([request access](https://www.appsheet.com/start/1ff317b6-2da1-4f39-b041-c01cfada6098))
852+
- Apple Pay payment processing certificates ([setup guide](https://shopify.dev/docs/storefronts/mobile/create-apple-payment-processing-certificates))
853+
- A device configured for Apple Pay ([Apple setup instructions](https://developer.apple.com/documentation/passkit/setting-up-apple-pay))
854+
855+
### Configure the integration
856+
857+
Pass an `acceleratedCheckouts` configuration when setting up the provider or `ShopifyCheckoutSheet` instance. This connects the accelerated checkout buttons to your storefront.
858+
859+
```tsx
860+
import {ShopifyCheckoutSheetProvider} from '@shopify/checkout-sheet-kit';
861+
862+
const config = {
863+
acceleratedCheckouts: {
864+
storefrontDomain: 'your-shop.myshopify.com',
865+
storefrontAccessToken: 'your-storefront-access-token',
866+
customer: {
867+
// For authenticated customers
868+
accessToken: 'customer-access-token',
869+
// OR for guest customers
870+
// email: 'customer@example.com',
871+
// phoneNumber: '0123456789',
872+
},
873+
wallets: {
874+
applePay: {
875+
merchantIdentifier: 'merchant.com.yourcompany',
876+
contactFields: ['email', 'phone'],
877+
// Optionally restrict shipping countries (ISO 3166-1 alpha-2)
878+
// supportedShippingCountries: ['US', 'CA'],
879+
},
880+
},
881+
},
882+
};
883+
884+
function App() {
885+
return (
886+
<ShopifyCheckoutSheetProvider configuration={config}>
887+
<YourApp />
888+
</ShopifyCheckoutSheetProvider>
889+
);
890+
}
891+
```
892+
893+
> [!WARNING]
894+
> Do not provide both `accessToken` and `email`/`phoneNumber` together. For authenticated customers, email and phone are fetched automatically from the Shopify account.
895+
896+
### Render accelerated checkout buttons
897+
898+
Use `AcceleratedCheckoutButtons` to attach accelerated checkout calls-to-action to product or cart surfaces once you have a valid cart ID or product variant ID from the Storefront API.
899+
900+
```tsx
901+
import {
902+
AcceleratedCheckoutButtons,
903+
AcceleratedCheckoutWallet,
904+
} from '@shopify/checkout-sheet-kit';
905+
906+
function CartFooter({cartId}: {cartId: string}) {
907+
return (
908+
<AcceleratedCheckoutButtons
909+
cartId={cartId}
910+
wallets={[AcceleratedCheckoutWallet.shopPay, AcceleratedCheckoutWallet.applePay]}
911+
/>
912+
);
913+
}
914+
```
915+
916+
You can also render buttons for a single product variant:
917+
918+
```tsx
919+
<AcceleratedCheckoutButtons
920+
variantId={variantId}
921+
quantity={1}
922+
wallets={[AcceleratedCheckoutWallet.applePay]}
923+
/>
924+
```
925+
926+
#### Customize wallet options
927+
928+
Accelerated checkout buttons display every available wallet by default. Use `wallets` to show a subset or adjust the order.
929+
930+
```tsx
931+
// Display only Shop Pay
932+
<AcceleratedCheckoutButtons
933+
cartId={cartId}
934+
wallets={[AcceleratedCheckoutWallet.shopPay]}
935+
/>
936+
937+
// Display Shop Pay first, then Apple Pay
938+
<AcceleratedCheckoutButtons
939+
cartId={cartId}
940+
wallets={[AcceleratedCheckoutWallet.shopPay, AcceleratedCheckoutWallet.applePay]}
941+
/>
942+
```
943+
944+
#### Modify the Apple Pay button label
945+
946+
Use `applePayLabel` to map to the native `PayWithApplePayButtonLabel` values. The default is `plain`.
947+
948+
```tsx
949+
import {ApplePayLabel} from '@shopify/checkout-sheet-kit';
950+
951+
<AcceleratedCheckoutButtons
952+
cartId={cartId}
953+
applePayLabel={ApplePayLabel.buy}
954+
/>
955+
```
956+
957+
#### Customize the Apple Pay button style
958+
959+
Use `applePayStyle` to set the color style of the Apple Pay button. The default is `automatic`, which adapts to the current appearance (light/dark mode).
960+
961+
```tsx
962+
import {ApplePayStyle} from '@shopify/checkout-sheet-kit';
963+
964+
<AcceleratedCheckoutButtons
965+
cartId={cartId}
966+
applePayStyle={ApplePayStyle.whiteOutline}
967+
/>
968+
```
969+
970+
Available styles: `automatic`, `black`, `white`, `whiteOutline`.
971+
972+
#### Customize button corners
973+
974+
The `cornerRadius` prop lets you match the buttons to other calls-to-action in your app. Buttons default to an 8pt radius.
975+
976+
```tsx
977+
// Pill-shaped buttons
978+
<AcceleratedCheckoutButtons cartId={cartId} cornerRadius={16} />
979+
980+
// Square buttons
981+
<AcceleratedCheckoutButtons cartId={cartId} cornerRadius={0} />
982+
```
983+
984+
### Handle loading, errors, and lifecycle events
985+
986+
Attach lifecycle handlers to respond when buyers finish, cancel, or encounter an error.
987+
988+
```tsx
989+
<AcceleratedCheckoutButtons
990+
cartId={cartId}
991+
onComplete={(event) => {
992+
// Clear cart after successful checkout
993+
clearCart();
994+
}}
995+
onFail={(error) => {
996+
console.error('Accelerated checkout failed:', error);
997+
}}
998+
onCancel={() => {
999+
analytics.track('accelerated_checkout_cancelled');
1000+
}}
1001+
onRenderStateChange={(event) => {
1002+
// event.state: 'loading' | 'rendered' | 'error'
1003+
setRenderState(event.state);
1004+
}}
1005+
onWebPixelEvent={(event) => {
1006+
analytics.track(event);
1007+
}}
1008+
onClickLink={(url) => {
1009+
Linking.openURL(url);
1010+
}}
1011+
/>
1012+
```
1013+
1014+
---
1015+
8441016
## Contributing
8451017

8461018
See the [contributing documentation](CONTRIBUTING.md) for details on how to get started.

modules/@shopify/checkout-sheet-kit/ios/AcceleratedCheckoutButtons+Extensions.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,23 @@ extension PayWithApplePayButtonLabel {
5858
"topUp": .topUp
5959
]
6060
}
61+
62+
// MARK: - Apple Pay Button Style
63+
64+
@available(iOS 16.0, *)
65+
extension PayWithApplePayButtonStyle {
66+
static func from(_ string: String?, fallback: PayWithApplePayButtonStyle = .automatic) -> PayWithApplePayButtonStyle {
67+
guard let string, let value = map[string] else {
68+
return fallback
69+
}
70+
71+
return value
72+
}
73+
74+
private static let map: [String: PayWithApplePayButtonStyle] = [
75+
"automatic": .automatic,
76+
"black": .black,
77+
"white": .white,
78+
"whiteOutline": .whiteOutline
79+
]
80+
}

modules/@shopify/checkout-sheet-kit/ios/AcceleratedCheckoutButtons.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
120120
}
121121
}
122122

123+
@objc var applePayStyle: String? {
124+
didSet {
125+
updateView()
126+
}
127+
}
128+
123129
@objc var onFail: RCTBubblingEventBlock?
124130
@objc var onComplete: RCTBubblingEventBlock?
125131
@objc var onCancel: RCTBubblingEventBlock?
@@ -207,7 +213,7 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
207213
updateView()
208214
}
209215

210-
private func attachModifiers(to buttons: AcceleratedCheckoutButtons, wallets: [Wallet]?, applePayLabel: PayWithApplePayButtonLabel?) -> AcceleratedCheckoutButtons {
216+
private func attachModifiers(to buttons: AcceleratedCheckoutButtons, wallets: [Wallet]?, applePayLabel: PayWithApplePayButtonLabel?, applePayStyle: PayWithApplePayButtonStyle?) -> AcceleratedCheckoutButtons {
211217
var modifiedButtons = buttons
212218

213219
if let wallets {
@@ -218,6 +224,10 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
218224
modifiedButtons = modifiedButtons.applePayLabel(applePayLabel)
219225
}
220226

227+
if let applePayStyle {
228+
modifiedButtons = modifiedButtons.applePayStyle(applePayStyle)
229+
}
230+
221231
if let cornerRadius {
222232
modifiedButtons = modifiedButtons.cornerRadius(CGFloat(cornerRadius.doubleValue))
223233
}
@@ -276,8 +286,8 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
276286
return
277287
}
278288

279-
// Attach modifiers (wallets, applePayLabel, cornerRadius)
280-
buttons = attachModifiers(to: buttons, wallets: shopifyWallets, applePayLabel: PayWithApplePayButtonLabel.from(applePayLabel))
289+
// Attach modifiers (wallets, applePayLabel, applePayStyle, cornerRadius)
290+
buttons = attachModifiers(to: buttons, wallets: shopifyWallets, applePayLabel: PayWithApplePayButtonLabel.from(applePayLabel), applePayStyle: PayWithApplePayButtonStyle.from(applePayStyle))
281291
// Attach event handlers
282292
buttons = attachEventListeners(to: buttons)
283293

modules/@shopify/checkout-sheet-kit/src/components/AcceleratedCheckoutButtons.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ export enum ApplePayLabel {
6161
topUp = 'topUp',
6262
}
6363

64+
export const ApplePayStyle = {
65+
automatic: 'automatic',
66+
black: 'black',
67+
white: 'white',
68+
whiteOutline: 'whiteOutline',
69+
} as const;
70+
71+
export type ApplePayStyle = (typeof ApplePayStyle)[keyof typeof ApplePayStyle];
72+
6473
type CheckoutIdentifier =
6574
| {
6675
cartId: string;
@@ -87,6 +96,12 @@ interface CommonAcceleratedCheckoutButtonsProps {
8796
*/
8897
applePayLabel?: ApplePayLabel;
8998

99+
/**
100+
* Style for the Apple Pay button color
101+
* Defaults to 'automatic' which adapts to the current appearance (light/dark mode)
102+
*/
103+
applePayStyle?: ApplePayStyle;
104+
90105
/**
91106
* Called when checkout fails
92107
*/
@@ -148,6 +163,7 @@ export type AcceleratedCheckoutButtonsProps = (CartProps | VariantProps) &
148163

149164
interface NativeAcceleratedCheckoutButtonsProps {
150165
applePayLabel?: string;
166+
applePayStyle?: string;
151167
style?: ViewStyle;
152168
checkoutIdentifier: CheckoutIdentifier;
153169
cornerRadius?: number;
@@ -193,6 +209,7 @@ export const AcceleratedCheckoutButtons: React.FC<
193209
AcceleratedCheckoutButtonsProps
194210
> = ({
195211
applePayLabel,
212+
applePayStyle,
196213
cornerRadius,
197214
wallets,
198215
onFail,
@@ -307,6 +324,7 @@ export const AcceleratedCheckoutButtons: React.FC<
307324
return (
308325
<RCTAcceleratedCheckoutButtons
309326
applePayLabel={applePayLabel}
327+
applePayStyle={applePayStyle}
310328
style={{...defaultStyles, height: dynamicHeight}}
311329
checkoutIdentifier={checkoutIdentifier}
312330
cornerRadius={cornerRadius}

modules/@shopify/checkout-sheet-kit/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import {
5858
import {CheckoutErrorCode} from './errors.d';
5959
import type {CheckoutCompletedEvent} from './events.d';
6060
import type {CustomEvent, PixelEvent, StandardEvent} from './pixels.d';
61-
import {ApplePayLabel} from './components/AcceleratedCheckoutButtons';
61+
import {ApplePayLabel, ApplePayStyle} from './components/AcceleratedCheckoutButtons';
6262
import type {
6363
AcceleratedCheckoutButtonsProps,
6464
RenderStateChangeEvent,
@@ -515,6 +515,7 @@ export {
515515
AcceleratedCheckoutWallet,
516516
ApplePayContactField,
517517
ApplePayLabel,
518+
ApplePayStyle,
518519
ColorScheme,
519520
LogLevel,
520521
ShopifyCheckoutSheet,

sample/src/context/Config.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import React, {
66
useMemo,
77
useState,
88
} from 'react';
9-
import {ColorScheme} from '@shopify/checkout-sheet-kit';
9+
import {ColorScheme, ApplePayStyle} from '@shopify/checkout-sheet-kit';
1010
import EncryptedStorage from 'react-native-encrypted-storage';
1111
import {useTheme} from './Theme';
1212
import {BuyerIdentityMode} from '../auth/types';
1313

1414
export interface AppConfig {
1515
colorScheme: ColorScheme;
1616
buyerIdentityMode: BuyerIdentityMode;
17+
applePayStyle: ApplePayStyle;
1718
}
1819

1920
interface Context {
@@ -26,6 +27,7 @@ const CONFIG_STORAGE_KEY = 'app_config';
2627
const defaultAppConfig: AppConfig = {
2728
colorScheme: ColorScheme.automatic,
2829
buyerIdentityMode: BuyerIdentityMode.Guest,
30+
applePayStyle: ApplePayStyle.automatic,
2931
};
3032

3133
const ConfigContext = createContext<Context>({

sample/src/screens/CartScreen.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
ApplePayLabel,
4242
AcceleratedCheckoutWallet,
4343
} from '@shopify/checkout-sheet-kit';
44+
import {useConfig} from '../context/Config';
4445
import useShopify from '../hooks/useShopify';
4546
import type {CartLineItem} from '../../@types';
4647
import type {Colors} from '../context/Theme';
@@ -55,6 +56,7 @@ function CartScreen(): React.JSX.Element {
5556
const {cartId, checkoutURL, totalQuantity, removeFromCart, addingToCart} =
5657
useCart();
5758
const {queries} = useShopify();
59+
const {appConfig} = useConfig();
5860
const eventHandlers = useShopifyEventHandlers(
5961
'Cart - AcceleratedCheckoutButtons',
6062
);
@@ -167,6 +169,7 @@ function CartScreen(): React.JSX.Element {
167169
<AcceleratedCheckoutButtons
168170
{...eventHandlers}
169171
applePayLabel={ApplePayLabel.checkout}
172+
applePayStyle={appConfig.applePayStyle}
170173
cartId={cartId}
171174
wallets={[
172175
AcceleratedCheckoutWallet.applePay,

sample/src/screens/ProductDetailsScreen.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
ApplePayLabel,
4646
useShopifyCheckoutSheet,
4747
} from '@shopify/checkout-sheet-kit';
48+
import {useConfig} from '../context/Config';
4849
import {useShopifyEventHandlers} from '../hooks/useCheckoutEventHandlers';
4950

5051
type Props = NativeStackScreenProps<RootStackParamList, 'ProductDetails'>;
@@ -90,6 +91,7 @@ function ProductDetails({
9091
loading?: boolean;
9192
onAddToCart: (variantId: string) => void;
9293
}) {
94+
const {appConfig} = useConfig();
9395
const {colors, cornerRadius} = useTheme();
9496
const styles = createStyles(colors, cornerRadius);
9597
const image = product.images?.edges[0]?.node;
@@ -126,6 +128,7 @@ function ProductDetails({
126128
<AcceleratedCheckoutButtons
127129
{...eventHandlers}
128130
applePayLabel={ApplePayLabel.order}
131+
applePayStyle={appConfig.applePayStyle}
129132
wallets={[AcceleratedCheckoutWallet.applePay]}
130133
variantId={variant.id}
131134
quantity={1}

0 commit comments

Comments
 (0)