Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,20 @@ experiences.

## Platform Requirements

- **React Native** - Minimum version `0.76` (v4+) / `0.70` (v3 and earlier)
- **React Native** - Minimum version `0.76` (`3.9.0+`) / `0.70` (`<=3.8.x`)
- **iOS** - Minimum version iOS 13
- **Android** - Minimum Java 11 & Android SDK version `23`

## Version Compatibility

Starting with **v4.0.0**, `@shopify/checkout-sheet-kit` requires the React Native
Starting with **v3.9.0**, `@shopify/checkout-sheet-kit` requires the React Native
**New Architecture** (TurboModules + Fabric). Apps on the old architecture must
stay on the `v3.x` line until they migrate.
stay on `v3.8.x` until they migrate.

| Package version | React Native | Architecture |
| --------------- | -------------- | ------------------ |
| `4.x` | `>= 0.76` | New Architecture |
| `3.x` | `>= 0.70` | Old Architecture |
| `3.9.x` | `>= 0.76` | New Architecture |
| `<=3.8.x` | `>= 0.70` | Old Architecture |

See the [React Native upgrade guide](https://reactnative.dev/docs/the-new-architecture/use-the-new-architecture)
for help enabling the New Architecture in your app.
Expand Down
2 changes: 1 addition & 1 deletion modules/@shopify/checkout-sheet-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@shopify/checkout-sheet-kit",
"license": "MIT",
"version": "4.0.0",
"version": "3.9.0",
"main": "lib/commonjs/index.js",
"types": "src/index.ts",
"source": "src/index.ts",
Expand Down
44 changes: 24 additions & 20 deletions modules/@shopify/checkout-sheet-kit/src/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ type Maybe<T> = T | undefined;
interface Context {
acceleratedCheckoutsAvailable: boolean;
addEventListener: AddEventListener;
getConfig: () => Configuration | undefined;
setConfig: (config: Configuration) => void;
getConfig: () => Promise<Configuration | undefined>;
setConfig: (config: Configuration) => Promise<void>;
removeEventListeners: RemoveEventListeners;
preload: (checkoutUrl: string) => void;
present: (checkoutUrl: string) => void;
Expand Down Expand Up @@ -71,24 +71,28 @@ export function ShopifyCheckoutSheetProvider({
}

useEffect(() => {
if (!instance.current || !configuration) {
return;
}

const customer = configuration.acceleratedCheckouts?.customer;
if (customer?.accessToken && (customer?.email || customer?.phoneNumber)) {
// eslint-disable-next-line no-console
console.warn(
'[ShopifyCheckoutSheetKit] Providing accessToken with contactFields (email / phoneNumber) is deprecated and will become an error in v4.' +
'When the user is authenticated with Customer Accounts, provide accessToken' +
'When the user is otherwise authenticated, provide email/phoneNumber.',
async function configureCheckoutKit() {
if (!instance.current || !configuration) {
return;
}

const customer = configuration.acceleratedCheckouts?.customer;
if (customer?.accessToken && (customer?.email || customer?.phoneNumber)) {
// eslint-disable-next-line no-console
console.warn(
'[ShopifyCheckoutSheetKit] Providing accessToken with contactFields (email / phoneNumber) is deprecated and will become an error in v4.' +
'When the user is authenticated with Customer Accounts, provide accessToken' +
'When the user is otherwise authenticated, provide email/phoneNumber.',
);
}

await instance.current.setConfig(configuration);
setAcceleratedCheckoutsAvailable(
instance.current.acceleratedCheckoutsReady,
);
}

instance.current.setConfig(configuration);
setAcceleratedCheckoutsAvailable(
instance.current.acceleratedCheckoutsReady,
);
configureCheckoutKit();
}, [configuration]);

const addEventListener: AddEventListener = useCallback(
Expand Down Expand Up @@ -122,11 +126,11 @@ export function ShopifyCheckoutSheetProvider({
instance.current?.dismiss();
}, []);

const setConfig = useCallback((config: Configuration) => {
instance.current?.setConfig(config);
const setConfig = useCallback(async (config: Configuration) => {
await instance.current?.setConfig(config);
}, []);

const getConfig = useCallback(() => {
const getConfig = useCallback(async () => {
return instance.current?.getConfig();
}, []);

Expand Down
6 changes: 3 additions & 3 deletions modules/@shopify/checkout-sheet-kit/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export interface ShopifyCheckoutSheetKit {
/**
* Return the current config for the checkout. See README.md for more details.
*/
getConfig(): Configuration;
getConfig(): Promise<Configuration>;
/**
* Listen for checkout events
*/
Expand All @@ -344,10 +344,10 @@ export interface ShopifyCheckoutSheetKit {
*/
configureAcceleratedCheckouts(
config: AcceleratedCheckoutConfiguration,
): boolean;
): Promise<boolean>;

/**
* Check if accelerated checkout is available for the given cart or product
*/
isAcceleratedCheckoutAvailable(): boolean;
isAcceleratedCheckoutAvailable(): Promise<boolean>;
}
21 changes: 11 additions & 10 deletions modules/@shopify/checkout-sheet-kit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,21 +151,22 @@ class ShopifyCheckoutSheet implements ShopifyCheckoutSheetKit {

/**
* Retrieves the current checkout configuration
* @returns The current Configuration
* @returns Promise containing the current Configuration
*/
public getConfig(): Configuration {
public async getConfig(): Promise<Configuration> {
return this.coerceConfigurationResult(RNShopifyCheckoutSheetKit.getConfig());
}

/**
* Updates the checkout configuration
* @param configuration New configuration settings to apply
*/
public setConfig(configuration: Configuration): void {
public async setConfig(configuration: Configuration): Promise<void> {
if (configuration.acceleratedCheckouts) {
this._acceleratedCheckoutsReady = this.configureAcceleratedCheckouts(
configuration.acceleratedCheckouts,
);
this._acceleratedCheckoutsReady =
await this.configureAcceleratedCheckouts(
configuration.acceleratedCheckouts,
);
}
RNShopifyCheckoutSheetKit.setConfig(configuration);
}
Expand Down Expand Up @@ -233,9 +234,9 @@ class ShopifyCheckoutSheet implements ShopifyCheckoutSheetKit {
* Configure AcceleratedCheckouts for Shop Pay and Apple Pay buttons
* @param config Configuration for AcceleratedCheckouts
*/
public configureAcceleratedCheckouts(
public async configureAcceleratedCheckouts(
config: AcceleratedCheckoutConfiguration,
): boolean {
): Promise<boolean> {
if (!this.acceleratedCheckoutsSupported) {
return false;
}
Expand Down Expand Up @@ -265,9 +266,9 @@ class ShopifyCheckoutSheet implements ShopifyCheckoutSheetKit {

/**
* Check if accelerated checkout is available for the given cart or product
* @returns boolean indicating availability
* @returns Promise<boolean> indicating availability
*/
public isAcceleratedCheckoutAvailable(): boolean {
public async isAcceleratedCheckoutAvailable(): Promise<boolean> {
if (!this.acceleratedCheckoutsSupported) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ describe('useShopifyCheckoutSheet', () => {
</Wrapper>,
);

const config = hookValue.getConfig();
const config = await hookValue.getConfig();
expect(config).toEqual({
preloading: true,
colorScheme: 'automatic',
Expand Down
50 changes: 25 additions & 25 deletions modules/@shopify/checkout-sheet-kit/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ describe('ShopifyCheckoutSheetKit', () => {
});

describe('getConfig', () => {
it('returns the parsed config from the Native Module', () => {
it('returns the parsed config from the Native Module', async () => {
const instance = new ShopifyCheckoutSheet();
expect(instance.getConfig()).toStrictEqual({
await expect(instance.getConfig()).resolves.toStrictEqual({
preloading: true,
colorScheme: ColorScheme.automatic,
logLevel: LogLevel.error,
Expand Down Expand Up @@ -732,7 +732,7 @@ describe('ShopifyCheckoutSheetKit', () => {
NativeModule.configureAcceleratedCheckouts.mockReturnValue(true);

const result =
instance.configureAcceleratedCheckouts(acceleratedConfig);
await instance.configureAcceleratedCheckouts(acceleratedConfig);

expect(result).toBe(true);
expect(
Expand All @@ -757,7 +757,7 @@ describe('ShopifyCheckoutSheetKit', () => {
};
NativeModule.configureAcceleratedCheckouts.mockReturnValue(true);

instance.configureAcceleratedCheckouts(minimalConfig);
await instance.configureAcceleratedCheckouts(minimalConfig);

expect(
NativeModule.configureAcceleratedCheckouts,
Expand All @@ -778,7 +778,7 @@ describe('ShopifyCheckoutSheetKit', () => {
const instance = new ShopifyCheckoutSheet();

const result =
instance.configureAcceleratedCheckouts(acceleratedConfig);
await instance.configureAcceleratedCheckouts(acceleratedConfig);

expect(result).toBe(false);
expect(
Expand All @@ -794,9 +794,9 @@ describe('ShopifyCheckoutSheetKit', () => {
};
const expectedError = new Error('`storefrontDomain` is required');

expect(
await expect(
instance.configureAcceleratedCheckouts(invalidConfig),
).toBe(false);
).resolves.toBe(false);
expect(console.error).toHaveBeenCalledWith(
'[ShopifyCheckoutSheetKit] Failed to configure accelerated checkouts with',
expectedError,
Expand All @@ -812,9 +812,9 @@ describe('ShopifyCheckoutSheetKit', () => {

const expectedError = new Error('`storefrontAccessToken` is required');

expect(
await expect(
instance.configureAcceleratedCheckouts(invalidConfig),
).toBe(false);
).resolves.toBe(false);
expect(console.error).toHaveBeenCalledWith(
'[ShopifyCheckoutSheetKit] Failed to configure accelerated checkouts with',
expectedError,
Expand All @@ -837,9 +837,9 @@ describe('ShopifyCheckoutSheetKit', () => {
'`wallets.applePay.merchantIdentifier` is required',
);

expect(
await expect(
instance.configureAcceleratedCheckouts(invalidConfig),
).toBe(false);
).resolves.toBe(false);
expect(console.error).toHaveBeenCalledWith(
'[ShopifyCheckoutSheetKit] Failed to configure accelerated checkouts with',
expectedError,
Expand All @@ -862,29 +862,29 @@ describe('ShopifyCheckoutSheetKit', () => {
`'wallets.applePay.contactFields' contains unexpected values. Expected "email, phone", received "invalid"`,
);

expect(
await expect(
instance.configureAcceleratedCheckouts(invalidConfig as any),
).toBe(false);
).resolves.toBe(false);
expect(console.error).toHaveBeenCalledWith(
'[ShopifyCheckoutSheetKit] Failed to configure accelerated checkouts with',
expectedError,
);
});

it('does not throw when Apple Pay wallet is not configured', () => {
it('does not throw when Apple Pay wallet is not configured', async () => {
const instance = new ShopifyCheckoutSheet();
const configWithoutApplePay = {
storefrontDomain: 'test-shop.myshopify.com',
storefrontAccessToken: 'shpat_test_token',
};
NativeModule.configureAcceleratedCheckouts.mockReturnValue(true);

expect(
await expect(
instance.configureAcceleratedCheckouts(configWithoutApplePay),
).toBe(true);
).resolves.toBe(true);
});

it('throws when a non-string value is given for supportedShippingCountries', () => {
it('throws when a non-string value is given for supportedShippingCountries', async () => {
const instance = new ShopifyCheckoutSheet();
const invalidConfig = {
...acceleratedConfig,
Expand All @@ -901,9 +901,9 @@ describe('ShopifyCheckoutSheetKit', () => {
`'wallets.applePay.supportedShippingCountries' contains unexpected values. Expects ISO 3166-1 alpha-2 country codes (e.g., "US", "CA", "GB").`,
);

expect(
await expect(
instance.configureAcceleratedCheckouts(invalidConfig as any),
).toBe(false);
).resolves.toBe(false);
expect(console.error).toHaveBeenCalledWith(
'[ShopifyCheckoutSheetKit] Failed to configure accelerated checkouts with',
expectedError,
Expand All @@ -913,7 +913,7 @@ describe('ShopifyCheckoutSheetKit', () => {
it('calls configureAcceleratedCheckouts with an empty array for supportShippingCountries when omitted', async () => {
const instance = new ShopifyCheckoutSheet();

instance.configureAcceleratedCheckouts({
await instance.configureAcceleratedCheckouts({
...acceleratedConfig,
wallets: {
applePay: {
Expand All @@ -940,7 +940,7 @@ describe('ShopifyCheckoutSheetKit', () => {
it('calls configureAcceleratedCheckouts with supportShippingCountries when given', async () => {
const instance = new ShopifyCheckoutSheet();

instance.configureAcceleratedCheckouts({
await instance.configureAcceleratedCheckouts({
...acceleratedConfig,
wallets: {
applePay: {
Expand All @@ -967,25 +967,25 @@ describe('ShopifyCheckoutSheetKit', () => {
});

describe('isAcceleratedCheckoutAvailable', () => {
it('calls native isAcceleratedCheckoutAvailable on iOS', () => {
it('calls native isAcceleratedCheckoutAvailable on iOS', async () => {
const instance = new ShopifyCheckoutSheet();
NativeModule.isAcceleratedCheckoutAvailable.mockReturnValue(true);

const result = instance.isAcceleratedCheckoutAvailable();

expect(result).toBe(true);
await expect(result).resolves.toBe(true);
expect(
NativeModule.isAcceleratedCheckoutAvailable,
).toHaveBeenCalledTimes(1);
});

it('returns false on Android', () => {
it('returns false on Android', async () => {
Platform.OS = 'android';
const instance = new ShopifyCheckoutSheet();

const result = instance.isAcceleratedCheckoutAvailable();

expect(result).toBe(false);
await expect(result).resolves.toBe(false);
expect(
NativeModule.isAcceleratedCheckoutAvailable,
).not.toHaveBeenCalled();
Expand Down
4 changes: 2 additions & 2 deletions sample/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2578,7 +2578,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNShopifyCheckoutSheetKit (4.0.0):
- RNShopifyCheckoutSheetKit (3.9.0):
- boost
- DoubleConversion
- fast_float
Expand Down Expand Up @@ -2996,7 +2996,7 @@ SPEC CHECKSUMS:
RNGestureHandler: eeb622199ef1fb3a076243131095df1c797072f0
RNReanimated: 237d420b7bb4378ef1dacc7d7a5c674fddb4b5d2
RNScreens: 3fc29af06302e1f1c18a7829fe57cbc2c0259912
RNShopifyCheckoutSheetKit: 2a8c97d7780466538843d4cb1368c7ed76a33689
RNShopifyCheckoutSheetKit: 5425cb8c6928b1aabe4504a8b37731d7e487cfd3
RNVectorIcons: be4d047a76ad307ffe54732208fb0498fcb8477f
ShopifyCheckoutSheetKit: 5253ca4da4c4f31069286509693930d02b4150d8
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Expand Down
4 changes: 2 additions & 2 deletions sample/src/context/Cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ export const CartProvider: React.FC<PropsWithChildren> = ({children}) => {
}, [cartId, fetchCart, setTotalQuantity]);

const preloadCheckout = useCallback(
(checkoutURL: string) => {
async (checkoutURL: string) => {
if (checkoutURL) {
const config = shopify.getConfig();
const config = await shopify.getConfig();
if (config?.preloading) {
shopify.preload(checkoutURL);
}
Expand Down
Loading
Loading