Skip to content
Draft
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
8 changes: 8 additions & 0 deletions platforms/react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,18 @@ instance of the `ShopifyCheckout` class.
| `title` | | `Checkout` | Sets the title of the checkout sheet at runtime on both iOS and Android. For per-locale localization, use the platform resource files. See [Localization](#localization). |
| `colorScheme` | | `automatic` | Sets the color scheme for the checkout. |
| `preloading` | | `true` | Enable/disable [preloading](#preloading). |
| `telemetry` | | `true` | Sends anonymous diagnostic metrics to Shopify on iOS and Android. Set to `false` to opt out. |
| `colors` | | `{}` | An object with `ios` and `android` properties to override the colors for iOS and Android platforms individually. See [`colors`](#colors) for more information. |
| `logLevel` | | `error` | Sets the log level for the native SDK. Use `LogLevel.debug` for verbose logging during development, or `LogLevel.error` for production. |
| `allowedMessageOrigins` | | `[]` | Extra origins trusted to send incoming checkout messages. See [Incoming message origin validation](#incoming-message-origin-validation). |

Checkout Kit reports bounded counts for checkout errors, protocol decoding
failures, and navigation retries, plus navigation duration histograms. These
diagnostics never include checkout URLs, message payloads, buyer data, or
checkout, order, customer, or shop identifiers. Disabling telemetry stops new
collection and discards measurements that have not already been handed to the
operating system for delivery.

Here's an example of how a fully customized configuration object might look:

```tsx
Expand Down
1 change: 1 addition & 0 deletions platforms/react-native/__mocks__/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const exampleConfig = {
colorScheme: 'automatic',
logLevel: 'error',
preloading: true,
telemetry: true,
};
const shopifyCheckoutKitEventEmitter = createMockEmitter();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Pod::Spec.new do |s|
s.dependency "ShopifyCheckoutKit"
s.dependency "ShopifyCheckoutKit/AcceleratedCheckouts"
else
s.dependency "ShopifyCheckoutKit", "~> #{ios_native_sdk_version}"
s.dependency "ShopifyCheckoutKit/AcceleratedCheckouts", "~> #{ios_native_sdk_version}"
s.dependency "ShopifyCheckoutKit", "= #{ios_native_sdk_version}"
s.dependency "ShopifyCheckoutKit/AcceleratedCheckouts", "= #{ios_native_sdk_version}"
end

install_modules_dependencies(s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public WritableMap getConfig() {
resultConfig.putString("colorScheme", colorSchemeStringFor(checkoutConfig.getAppearance()));
resultConfig.putString("logLevel", logLevelStringFor(checkoutConfig.getLogLevel()));
resultConfig.putBoolean("preloading", checkoutConfig.getPreloading().getEnabled());
resultConfig.putBoolean("telemetry", checkoutConfig.getTelemetry().getEnabled());
resultConfig.putArray("allowedMessageOrigins",
Arguments.fromList(new ArrayList<>(checkoutConfig.getAllowedMessageOrigins())));

Expand All @@ -223,6 +224,10 @@ public void setConfig(ReadableMap config) {
configuration.setAllowedMessageOrigins(toStringSet(config.getArray("allowedMessageOrigins")));
}

if (config.hasKey("telemetry")) {
configuration.setTelemetry(new Telemetry(config.getBoolean("telemetry")));
}

if (config.hasKey("logLevel")) {
LogLevel logLevel = logLevelFor(config.getString("logLevel"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ class RCTShopifyCheckoutKit: NSObject {
ShopifyCheckoutKit.configuration.allowedMessageOrigins = allowedMessageOrigins
}

if let telemetry = configuration["telemetry"] as? Bool {
ShopifyCheckoutKit.configuration.telemetry.enabled = telemetry
}

if let colorScheme = configuration["colorScheme"] as? String,
let appearance = appearanceFor(colorScheme)
{
Expand Down Expand Up @@ -216,6 +220,7 @@ class RCTShopifyCheckoutKit: NSObject {
"title": ShopifyCheckoutKit.configuration.title,
"colorScheme": colorSchemeStringFor(ShopifyCheckoutKit.configuration.appearance),
"preloading": ShopifyCheckoutKit.configuration.preloading.enabled,
"telemetry": ShopifyCheckoutKit.configuration.telemetry.enabled,
"tintColor": ShopifyCheckoutKit.configuration.tintColor,
"backgroundColor": ShopifyCheckoutKit.configuration.backgroundColor,
"closeButtonColor": ShopifyCheckoutKit.configuration.closeButtonTintColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ interface CommonConfiguration {
* @default [] (all origins trusted)
*/
allowedMessageOrigins?: string[];
/**
* Sends anonymous diagnostic metrics to Shopify. Set to `false` to opt out.
*
* @default true
*/
telemetry?: boolean;
}

export type Configuration = CommonConfiguration & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ type ConfigurationSpec = {
logLevel?: string;
preloading?: boolean;
allowedMessageOrigins?: string[];
telemetry?: boolean;
colors?: ColorsSpec;
};

type ConfigurationResultSpec = {
colorScheme: string;
logLevel: string;
preloading: boolean;
telemetry: boolean;
title?: string;
tintColor?: string;
backgroundColor?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ describe('useShopifyCheckout', () => {
colorScheme: 'automatic',
logLevel: 'error',
preloading: true,
telemetry: true,
});

expect(NativeModules.ShopifyCheckoutKit.getConfig).toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ describe('Type contracts', () => {
acceptsCustomer({email: 'test@example.com', phoneNumber: '+1234567890'}),
).toEqual({email: 'test@example.com', phoneNumber: '+1234567890'});

expect(
acceptsConfiguration({
telemetry: false,
}).telemetry,
).toBe(false);

expect(
acceptsConfiguration({
acceleratedCheckouts: {
Expand Down Expand Up @@ -139,6 +145,22 @@ describe('Exports', () => {
]);
});
});

describe('CheckoutErrorCode enum', () => {
it('exports current native checkout error codes', () => {
expect(CheckoutErrorCode.customerAccountRequired).toBe(
'customer_account_required',
);
expect(CheckoutErrorCode.networkError).toBe('network_error');
expect(CheckoutErrorCode.webViewNotSupported).toBe(
'web_view_not_supported',
);
expect(CheckoutErrorCode.webContentProcessTerminated).toBe(
'web_content_process_terminated',
);
expect(CheckoutErrorCode.sdkError).toBe('sdk_error');
});
});
});

type Dispatch = (envelopeJson: string) => void;
Expand Down Expand Up @@ -777,6 +799,7 @@ describe('ShopifyCheckoutKit', () => {
colorScheme: ColorScheme.automatic,
logLevel: LogLevel.error,
preloading: true,
telemetry: true,
});
expect(NativeModule.getConfig).toHaveBeenCalledTimes(1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
import com.shopify.checkoutkit.CheckoutErrorCode;
import com.shopify.checkoutkit.CheckoutException;
import com.shopify.checkoutkit.CheckoutPreload;
import com.shopify.checkoutkit.ShopifyCheckoutKit;
import com.shopify.checkoutkit.LogLevel;
import com.shopify.checkoutkit.PreloadState;
import com.shopify.checkoutkit.PreloadStateListener;
import com.shopify.checkoutkit.Preloading;
import com.shopify.checkoutkit.ShopifyCheckoutKit;
import com.shopify.checkoutkit.Telemetry;
import com.shopify.reactnative.checkoutkit.ShopifyCheckoutKitModule;
import com.shopify.reactnative.checkoutkit.CustomCheckoutListener;
import com.shopify.reactnative.checkoutkit.DispatchCallback;
Expand Down Expand Up @@ -60,6 +61,7 @@ public class ShopifyCheckoutKitModuleTest {
private CheckoutAppearance initialAppearance;
private LogLevel initialLogLevel;
private Preloading initialPreloading;
private Telemetry initialTelemetry;

// Mock for Arguments.createMap() to avoid native library loading
private MockedStatic<Arguments> mockedArguments;
Expand Down Expand Up @@ -104,6 +106,7 @@ public void setup() {
initialAppearance = ShopifyCheckoutKitModule.checkoutConfig.getAppearance();
initialLogLevel = ShopifyCheckoutKitModule.checkoutConfig.getLogLevel();
initialPreloading = ShopifyCheckoutKitModule.checkoutConfig.getPreloading();
initialTelemetry = ShopifyCheckoutKitModule.checkoutConfig.getTelemetry();
}

@After
Expand All @@ -121,6 +124,7 @@ public void tearDown() throws Exception {
configuration.setAppearance(initialAppearance);
configuration.setLogLevel(initialLogLevel);
configuration.setPreloading(initialPreloading);
configuration.setTelemetry(initialTelemetry);
ShopifyCheckoutKitModule.checkoutConfig = configuration;
});
}
Expand Down Expand Up @@ -689,6 +693,28 @@ public void testGetConfigIncludesPreloading() {
assertThat(result.getBoolean("preloading")).isFalse();
}

@Test
public void testCanDisableTelemetry() {
JavaOnlyMap config = new JavaOnlyMap();
config.putBoolean("telemetry", false);

shopifyCheckoutKitModule.setConfig(config);

assertThat(ShopifyCheckoutKitModule.checkoutConfig.getTelemetry().getEnabled())
.isFalse();
}

@Test
public void testGetConfigIncludesTelemetry() {
JavaOnlyMap config = new JavaOnlyMap();
config.putBoolean("telemetry", false);
shopifyCheckoutKitModule.setConfig(config);

WritableMap result = shopifyCheckoutKitModule.getConfig();

assertThat(result.getBoolean("telemetry")).isFalse();
}

@Test
public void testGetConfigReturnsDebugForDebugLogLevel() {
JavaOnlyMap config = new JavaOnlyMap();
Expand Down
6 changes: 3 additions & 3 deletions platforms/react-native/sample/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2605,8 +2605,8 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ShopifyCheckoutKit (~> 4.0.0-alpha.5)
- ShopifyCheckoutKit/AcceleratedCheckouts (~> 4.0.0-alpha.5)
- ShopifyCheckoutKit (= 4.0.0-alpha.5)
- ShopifyCheckoutKit/AcceleratedCheckouts (= 4.0.0-alpha.5)
- SocketRocket
- Yoga
- RNVectorIcons (10.3.0):
Expand Down Expand Up @@ -2996,7 +2996,7 @@ SPEC CHECKSUMS:
RNGestureHandler: eeb622199ef1fb3a076243131095df1c797072f0
RNReanimated: 237d420b7bb4378ef1dacc7d7a5c674fddb4b5d2
RNScreens: 3fc29af06302e1f1c18a7829fe57cbc2c0259912
RNShopifyCheckoutKit: f7855358ff15db951f458320526ebd9ce2f91405
RNShopifyCheckoutKit: 01457278b0a89be66df651b9b10d938b8204d5bc
RNVectorIcons: be4d047a76ad307ffe54732208fb0498fcb8477f
ShopifyCheckoutKit: 7874c8866e6c889d86194398c97e00388111d972
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Expand Down
2 changes: 1 addition & 1 deletion platforms/react-native/scripts/lint_swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ SWIFT_PATHS=(
)
MODE="${1:-check}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
SWIFT_TOOLS_DIR="$REPO_ROOT/platforms/swift"

if ! "$REPO_ROOT/scripts/check_xcodebuild_package_resolution"; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2149,8 +2149,8 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ShopifyCheckoutKit (~> 4.0.0-alpha.5)
- ShopifyCheckoutKit/AcceleratedCheckouts (~> 4.0.0-alpha.5)
- ShopifyCheckoutKit (= 4.0.0-alpha.5)
- ShopifyCheckoutKit/AcceleratedCheckouts (= 4.0.0-alpha.5)
- SocketRocket
- Yoga
- ShopifyCheckoutKit (4.0.0-alpha.5):
Expand Down Expand Up @@ -2464,7 +2464,7 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: 8df342c127fd0c1e30e8b9f71ff814c22414a7c0
ReactCodegen: 3ba2a79bc32ff858814c17ade10931b33b09dcf4
ReactCommon: 592ef441605638b95e533653259254b4bd35ff4f
RNShopifyCheckoutKit: f7855358ff15db951f458320526ebd9ce2f91405
RNShopifyCheckoutKit: 01457278b0a89be66df651b9b10d938b8204d5bc
ShopifyCheckoutKit: 7874c8866e6c889d86194398c97e00388111d972
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: a742cc68e8366fcfc681808162492bc0aa7a9498
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ShopifyCheckoutKitTests: XCTestCase {
ShopifyCheckoutKit.configuration.logLevel = LogLevel.warn
ShopifyCheckoutKit.configuration.preloading.enabled = true
ShopifyCheckoutKit.configuration.allowedMessageOrigins = []
ShopifyCheckoutKit.configuration.telemetry.enabled = true
}

private func getShopifyCheckoutKit() -> RCTShopifyCheckoutKit {
Expand Down Expand Up @@ -334,6 +335,20 @@ class ShopifyCheckoutKitTests: XCTestCase {
XCTAssertEqual(result["reason"] as? String, "webContentUnavailable")
}

func testConfigureCanDisableTelemetry() {
shopifyCheckoutKit.setConfig(["telemetry": false])

XCTAssertFalse(ShopifyCheckoutKit.configuration.telemetry.enabled)
}

func testGetConfigIncludesTelemetry() {
shopifyCheckoutKit.setConfig(["telemetry": false])

let result = shopifyCheckoutKit.getConfig() as? [String: Any]

XCTAssertEqual(result?["telemetry"] as? Bool, false)
}

func testPreloadWithInvalidURLDoesNotRetainCheckoutSheet() {
let preloadAttemptCompleted = expectation(description: "preload attempt completed")

Expand Down
Loading