From 07031b1fab2816f920b4eb272fd99173551d5ffa Mon Sep 17 00:00:00 2001 From: borisprimer <137198782+borisprimer@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:19:43 +0200 Subject: [PATCH] feature: Update DX for Apple Pay (#236) * Update DX for Apple Pay * Add configurable fields for ApplePay Express Checkout to enable testing --------- Co-authored-by: Boris Nikolic --- packages/example/ios/Podfile | 2 +- packages/example/ios/Podfile.lock | 17 ++- .../example_0_70_6.xcodeproj/project.pbxproj | 132 +++++++++--------- .../example/src/screens/CheckoutScreen.tsx | 11 +- .../example/src/screens/SettingsScreen.tsx | 103 ++++++++++++++ .../PrimerSettings+Extensions.swift | 37 ++++- packages/sdk/src/models/PrimerSettings.ts | 21 ++- 7 files changed, 234 insertions(+), 89 deletions(-) diff --git a/packages/example/ios/Podfile b/packages/example/ios/Podfile index e2b991f13..c403f541e 100644 --- a/packages/example/ios/Podfile +++ b/packages/example/ios/Podfile @@ -48,7 +48,7 @@ target 'example_0_70_6' do pod 'PrimerSDK' pod 'Primer3DS' pod 'PrimerIPay88MYSDK' - pod 'PrimerKlarnaSDK', '1.1.0' + pod 'PrimerKlarnaSDK', '1.1.1' pod 'PrimerStripeSDK', '1.0.0' target 'example_0_70_6Tests' do diff --git a/packages/example/ios/Podfile.lock b/packages/example/ios/Podfile.lock index 4b8c3cb7a..963b67c3a 100644 --- a/packages/example/ios/Podfile.lock +++ b/packages/example/ios/Podfile.lock @@ -16,7 +16,7 @@ PODS: - React-Core - Primer3DS (2.3.2) - PrimerIPay88MYSDK (0.1.7) - - PrimerKlarnaSDK (1.1.0) + - PrimerKlarnaSDK (1.1.1) - PrimerSDK (2.31.0): - PrimerSDK/Core (= 2.31.0) - PrimerSDK/Core (2.31.0) @@ -291,7 +291,7 @@ PODS: - React-jsinspector (0.72.0) - React-logger (0.72.0): - glog - - react-native-safe-area-context (4.10.1): + - react-native-safe-area-context (4.8.1): - React-Core - react-native-segmented-control (2.4.3): - React-Core @@ -400,10 +400,9 @@ PODS: - React-jsi (= 0.72.0) - React-logger (= 0.72.0) - React-perflogger (= 0.72.0) - - RNScreens (3.31.1): + - RNScreens (3.29.0): - RCT-Folly (= 2021.07.22.00) - React-Core - - React-RCTImage - SocketRocket (0.6.0) - Yoga (1.14.0) @@ -416,7 +415,7 @@ DEPENDENCIES: - primer-io-react-native (from `../../sdk`) - Primer3DS - PrimerIPay88MYSDK - - PrimerKlarnaSDK (= 1.1.0) + - PrimerKlarnaSDK (= 1.1.1) - PrimerSDK - PrimerStripeSDK (= 1.0.0) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -563,7 +562,7 @@ SPEC CHECKSUMS: primer-io-react-native: 4b4eb3b62c7787537191a6f74598db8a78c29587 Primer3DS: 81e7969033230c7346a517cd609be956914738bb PrimerIPay88MYSDK: 436ee0be7e2c97e4e81456ccddee20175e9e3c4d - PrimerKlarnaSDK: 83e9a1357a7247bf8fa2836fc945cf97644d601d + PrimerKlarnaSDK: 564105170cc7b467bf95c31851813ea41c468f8b PrimerSDK: 78d1a48ba9b4677f78da9750448af6c72007f4fe PrimerStripeSDK: c37d4e7c1b5256d67d4890c4cc4b38ddc9427489 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 @@ -581,7 +580,7 @@ SPEC CHECKSUMS: React-jsiexecutor: de4e98ab0f2661affeb54931806a79a93a34d1ea React-jsinspector: 8d754fc957255a29d93e52fc67a895045cdc8703 React-logger: 454ffb01980778a43b0153ee98721d0275b56616 - react-native-safe-area-context: dcab599c527c2d7de2d76507a523d20a0b83823d + react-native-safe-area-context: cd1169d797a2ef722a00bfc5af10748d5b6c94f9 react-native-segmented-control: d88b35fcd06c0c8e1f1f7ed1eb066c2b02570fdd React-NativeModulesApple: 1d81d927ef1a67a3545a01e14c2e98500bf9b199 React-perflogger: 684a11499a0589cc42135d6d5cc04d0e4e0e261a @@ -600,10 +599,10 @@ SPEC CHECKSUMS: React-runtimescheduler: 4a36521cc1ec1bc3997ae2462b6779dadaae376b React-utils: c12d2e75c8bbc727939ddc4319ed95493395ed5a ReactCommon: b9547f82aed45eccc1aa59034dc6c72809e37000 - RNScreens: 93ae3be2f119d955620f9bbb39ad372adb53b7a9 + RNScreens: 3c5b9f4a9dcde752466854b6109b79c0e205dad3 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: 1d6727ed193122f6adaf435c3de1a768326ff83b -PODFILE CHECKSUM: e1d93bf98428be80f71d4652c0496e390624cf68 +PODFILE CHECKSUM: 4505e915c8982e98dcb8297a1c627233ce3a067f COCOAPODS: 1.15.2 diff --git a/packages/example/ios/example_0_70_6.xcodeproj/project.pbxproj b/packages/example/ios/example_0_70_6.xcodeproj/project.pbxproj index 28b9555b4..6c5c0bcb1 100644 --- a/packages/example/ios/example_0_70_6.xcodeproj/project.pbxproj +++ b/packages/example/ios/example_0_70_6.xcodeproj/project.pbxproj @@ -8,10 +8,10 @@ /* Begin PBXBuildFile section */ 04979F682AB1E55A00469C99 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 04979F672AB1E55A00469C99 /* main.jsbundle */; }; - 1214FDC22DE9422B04CBD0AF /* libPods-example_0_70_6-example_0_70_6Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C8ED1C5D0D2C71B628914E /* libPods-example_0_70_6-example_0_70_6Tests.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 5B6FD62EA8AF38BB98287424 /* libPods-example_0_70_6.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5461A80700BFFD7D2638CFBC /* libPods-example_0_70_6.a */; }; 6CA351F7D8EEBFA61B7FE8CC /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; A127AC7D2BFF7A3500D45E2B /* RNTRedirectManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A127AC7C2BFF7A3500D45E2B /* RNTRedirectManagerTests.swift */; }; @@ -31,7 +31,7 @@ A17A44C02BFF650A00433548 /* RNTBanksCollectableDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17A44BF2BFF650A00433548 /* RNTBanksCollectableDataTests.swift */; }; A17A44C82BFF731B00433548 /* RNTPrimerHeadlessUniversalCheckoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17A44C72BFF731B00433548 /* RNTPrimerHeadlessUniversalCheckoutTests.swift */; }; C010C35792AF87095495BFED /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; - E2253F14964058B3C5DE0E0E /* libPods-example_0_70_6.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A030C4DDD12752D9E24EFC8F /* libPods-example_0_70_6.a */; }; + E284668B61D39631DD0DF8E4 /* libPods-example_0_70_6-example_0_70_6Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E634CC5265A75354348809 /* libPods-example_0_70_6-example_0_70_6Tests.a */; }; F004EDB82BF60A4E006F3CAA /* UIColorExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F004EDB72BF60A4E006F3CAA /* UIColorExtensionTests.swift */; }; F0C3A3482BF60837002E6AC4 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 04979F672AB1E55A00469C99 /* main.jsbundle */; }; /* End PBXBuildFile section */ @@ -47,7 +47,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 00C8ED1C5D0D2C71B628914E /* libPods-example_0_70_6-example_0_70_6Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example_0_70_6-example_0_70_6Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356EE1AD99517003FC87E /* example_0_70_6Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = example_0_70_6Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 04979F672AB1E55A00469C99 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; @@ -57,10 +56,13 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example_0_70_6/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example_0_70_6/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example_0_70_6/main.m; sourceTree = ""; }; + 2618D20E7DC27E7C47AF2531 /* Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig"; path = "Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig"; sourceTree = ""; }; + 3542D0B2E131D922AF48E77E /* Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig"; path = "Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig"; sourceTree = ""; }; + 35808B8DBC5F9AEB80654DB3 /* Pods-example_0_70_6.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6.release.xcconfig"; path = "Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6.release.xcconfig"; sourceTree = ""; }; + 5461A80700BFFD7D2638CFBC /* libPods-example_0_70_6.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example_0_70_6.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = example_0_70_6/LaunchScreen.storyboard; sourceTree = ""; }; + 82DCDFD2FB9AB5118FE4FF8C /* Pods-example_0_70_6.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6.debug.xcconfig"; path = "Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6.debug.xcconfig"; sourceTree = ""; }; 848652F22954A52C0071549C /* example_0_70_6.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = example_0_70_6.entitlements; path = example_0_70_6/example_0_70_6.entitlements; sourceTree = ""; }; - 93B4C4BC8D0B04C5DBF443C1 /* Pods-example_0_70_6.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6.release.xcconfig"; path = "Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6.release.xcconfig"; sourceTree = ""; }; - A030C4DDD12752D9E24EFC8F /* libPods-example_0_70_6.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example_0_70_6.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A127AC7C2BFF7A3500D45E2B /* RNTRedirectManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNTRedirectManagerTests.swift; sourceTree = ""; }; A17A44A02BF7A57F00433548 /* UIImageExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensionTests.swift; sourceTree = ""; }; A17A44A12BF7A57F00433548 /* CodableExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodableExtensionsTests.swift; sourceTree = ""; }; @@ -77,9 +79,7 @@ A17A44BB2BFB8C7B00433548 /* RNTNativeErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNTNativeErrorTests.swift; sourceTree = ""; }; A17A44BF2BFF650A00433548 /* RNTBanksCollectableDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNTBanksCollectableDataTests.swift; sourceTree = ""; }; A17A44C72BFF731B00433548 /* RNTPrimerHeadlessUniversalCheckoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNTPrimerHeadlessUniversalCheckoutTests.swift; sourceTree = ""; }; - A712341D104E82B355559620 /* Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig"; path = "Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig"; sourceTree = ""; }; - B5750A5702A1C227CA8B7B25 /* Pods-example_0_70_6.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6.debug.xcconfig"; path = "Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6.debug.xcconfig"; sourceTree = ""; }; - C8BF4EA544BD509C32CD4752 /* Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig"; path = "Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig"; sourceTree = ""; }; + A9E634CC5265A75354348809 /* libPods-example_0_70_6-example_0_70_6Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example_0_70_6-example_0_70_6Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; F004EDB42BF6091A006F3CAA /* example_0_70_6Tests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "example_0_70_6Tests-Bridging-Header.h"; sourceTree = ""; }; F004EDB72BF60A4E006F3CAA /* UIColorExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensionTests.swift; sourceTree = ""; }; @@ -91,7 +91,7 @@ buildActionMask = 2147483647; files = ( 6CA351F7D8EEBFA61B7FE8CC /* BuildFile in Frameworks */, - 1214FDC22DE9422B04CBD0AF /* libPods-example_0_70_6-example_0_70_6Tests.a in Frameworks */, + E284668B61D39631DD0DF8E4 /* libPods-example_0_70_6-example_0_70_6Tests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -100,7 +100,7 @@ buildActionMask = 2147483647; files = ( C010C35792AF87095495BFED /* BuildFile in Frameworks */, - E2253F14964058B3C5DE0E0E /* libPods-example_0_70_6.a in Frameworks */, + 5B6FD62EA8AF38BB98287424 /* libPods-example_0_70_6.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -148,8 +148,8 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - A030C4DDD12752D9E24EFC8F /* libPods-example_0_70_6.a */, - 00C8ED1C5D0D2C71B628914E /* libPods-example_0_70_6-example_0_70_6Tests.a */, + 5461A80700BFFD7D2638CFBC /* libPods-example_0_70_6.a */, + A9E634CC5265A75354348809 /* libPods-example_0_70_6-example_0_70_6Tests.a */, ); name = Frameworks; sourceTree = ""; @@ -224,10 +224,10 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - B5750A5702A1C227CA8B7B25 /* Pods-example_0_70_6.debug.xcconfig */, - 93B4C4BC8D0B04C5DBF443C1 /* Pods-example_0_70_6.release.xcconfig */, - A712341D104E82B355559620 /* Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig */, - C8BF4EA544BD509C32CD4752 /* Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig */, + 82DCDFD2FB9AB5118FE4FF8C /* Pods-example_0_70_6.debug.xcconfig */, + 35808B8DBC5F9AEB80654DB3 /* Pods-example_0_70_6.release.xcconfig */, + 2618D20E7DC27E7C47AF2531 /* Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig */, + 3542D0B2E131D922AF48E77E /* Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -239,12 +239,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "example_0_70_6Tests" */; buildPhases = ( - D9F1C64A6F206C8108DD5326 /* [CP] Check Pods Manifest.lock */, + CEC87FC88254C6D182423612 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 7389BE0D6811C804E2362671 /* [CP] Embed Pods Frameworks */, - 1549D5D53EECB6BB0C1036F7 /* [CP] Copy Pods Resources */, + 1AA03BF8C4C1D0A176327C04 /* [CP] Embed Pods Frameworks */, + 57ADE4DACA1774C1D1253F8F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -260,15 +260,15 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example_0_70_6" */; buildPhases = ( - 215129FA43F49F875405446B /* [CP] Check Pods Manifest.lock */, + CEA153A1D113F533AAD28CC8 /* [CP] Check Pods Manifest.lock */, 04DB853E2B766F4700910EAE /* Update Version */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - A256A8D7CB0FE34FBFB4196B /* [CP] Embed Pods Frameworks */, - 6FFEDB94F3DD170594C304C8 /* [CP] Copy Pods Resources */, + 59614C0A2C55009832B99853 /* [CP] Embed Pods Frameworks */, + CEF58893CD15DE8B081D7F12 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -375,116 +375,116 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nSCRIPT_LOCATION=\"../../../scripts/update-ios-version.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $SCRIPT_LOCATION\"\n"; }; - 1549D5D53EECB6BB0C1036F7 /* [CP] Copy Pods Resources */ = { + 1AA03BF8C4C1D0A176327C04 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 215129FA43F49F875405446B /* [CP] Check Pods Manifest.lock */ = { + 57ADE4DACA1774C1D1253F8F /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-example_0_70_6-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 6FFEDB94F3DD170594C304C8 /* [CP] Copy Pods Resources */ = { + 59614C0A2C55009832B99853 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 7389BE0D6811C804E2362671 /* [CP] Embed Pods Frameworks */ = { + CEA153A1D113F533AAD28CC8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-example_0_70_6-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6-example_0_70_6Tests/Pods-example_0_70_6-example_0_70_6Tests-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - A256A8D7CB0FE34FBFB4196B /* [CP] Embed Pods Frameworks */ = { + CEC87FC88254C6D182423612 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-example_0_70_6-example_0_70_6Tests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - D9F1C64A6F206C8108DD5326 /* [CP] Check Pods Manifest.lock */ = { + CEF58893CD15DE8B081D7F12 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-example_0_70_6-example_0_70_6Tests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example_0_70_6/Pods-example_0_70_6-resources.sh\"\n"; showEnvVarsInLog = 0; }; FD10A7F022414F080027D42C /* Start Packager */ = { @@ -555,7 +555,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A712341D104E82B355559620 /* Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig */; + baseConfigurationReference = 2618D20E7DC27E7C47AF2531 /* Pods-example_0_70_6-example_0_70_6Tests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ENABLE_MODULES = YES; @@ -594,7 +594,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C8BF4EA544BD509C32CD4752 /* Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig */; + baseConfigurationReference = 3542D0B2E131D922AF48E77E /* Pods-example_0_70_6-example_0_70_6Tests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ENABLE_MODULES = YES; @@ -629,7 +629,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B5750A5702A1C227CA8B7B25 /* Pods-example_0_70_6.debug.xcconfig */; + baseConfigurationReference = 82DCDFD2FB9AB5118FE4FF8C /* Pods-example_0_70_6.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -663,7 +663,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 93B4C4BC8D0B04C5DBF443C1 /* Pods-example_0_70_6.release.xcconfig */; + baseConfigurationReference = 35808B8DBC5F9AEB80654DB3 /* Pods-example_0_70_6.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/packages/example/src/screens/CheckoutScreen.tsx b/packages/example/src/screens/CheckoutScreen.tsx index 4a3fe6d1c..6d94e4b2c 100644 --- a/packages/example/src/screens/CheckoutScreen.tsx +++ b/packages/example/src/screens/CheckoutScreen.tsx @@ -241,7 +241,8 @@ const CheckoutScreen = (props: any) => { merchantName: appPaymentParameters.merchantName || "Merchant name", isCaptureBillingAddressEnabled: true, showApplePayForUnsupportedDevice: true, - checkProvidedNetworks: false + checkProvidedNetworks: false, + shippingOptions: appPaymentParameters.shippingOptions }, googlePayOptions: { isCaptureBillingAddressEnabled: true, @@ -321,14 +322,6 @@ const CheckoutScreen = (props: any) => { } }; - if (appPaymentParameters.merchantName) { - //@ts-ignore - settings.paymentMethodOptions.applePayOptions = { - merchantIdentifier: 'merchant.checkout.team', - merchantName: appPaymentParameters.merchantName - }; - } - const onVaultManagerButtonTapped = async () => { try { setIsLoading(true); diff --git a/packages/example/src/screens/SettingsScreen.tsx b/packages/example/src/screens/SettingsScreen.tsx index b837cdc8a..0509e9546 100644 --- a/packages/example/src/screens/SettingsScreen.tsx +++ b/packages/example/src/screens/SettingsScreen.tsx @@ -13,6 +13,7 @@ import { styles } from '../styles'; import SegmentedControl from '@react-native-segmented-control/segmented-control'; import { Environment, makeEnvironmentFromIntVal, makePaymentHandlingFromIntVal, PaymentHandling } from '../network/Environment'; import { appPaymentParameters, IClientSessionAddress, IClientSessionCustomer, IClientSessionLineItem, IClientSessionOrder, IClientSessionPaymentMethod, IClientSessionPaymentMethodOptions, IClientSessionRequestBody } from '../models/IClientSessionRequestBody'; +import { useState } from 'react'; import { Switch } from 'react-native'; import TextField from '../components/TextField'; import type { NewLineItemScreenProps } from './NewLineItemSreen'; @@ -22,6 +23,11 @@ export interface AppPaymentParameters { paymentHandling: PaymentHandling; clientSessionRequestBody: IClientSessionRequestBody; merchantName?: string; + shippingOptions?: { + isCaptureShippingAddressEnabled: boolean; + requireShippingMethod: boolean; + additionalShippingContactFields: string[]; + }; } export let customApiKey: string | undefined; @@ -66,6 +72,11 @@ const SettingsScreen = ({ navigation }) => { const [visaSurcharge, setVisaSurcharge] = React.useState(appPaymentParameters.clientSessionRequestBody.paymentMethod?.options?.PAYMENT_CARD?.networks.VISA?.surcharge.amount); const [masterCardSurcharge, setMasterCardSurcharge] = React.useState(appPaymentParameters.clientSessionRequestBody.paymentMethod?.options?.PAYMENT_CARD?.networks.MASTERCARD?.surcharge.amount); + const [isShippingOptionsApplied, setIsShippingOptionsApplied] = useState(false); + const [isCaptureShippingAddressEnabled, setIsCaptureShippingAddressEnabled] = useState(false); + const [requireShippingMethod, setRequireShippingMethod] = useState(false); + const [additionalShippingContactFields, setAdditionalShippingContactFields] = useState([]); + const backgroundStyle = { backgroundColor: isDarkMode ? Colors.black : Colors.white }; @@ -617,6 +628,7 @@ const SettingsScreen = ({ navigation }) => { {renderMerchantSection()} {renderCustomerSection()} {renderSurchargeSection()} + {renderShippingOptionsSection()} ); } @@ -674,6 +686,91 @@ const SettingsScreen = ({ navigation }) => { ); } + const renderShippingOptionsSection = () => { + return ( + + + + Shipping Options + + + { + setIsShippingOptionsApplied(val); + }} + /> + + + { + !isShippingOptionsApplied ? null : + + + Capture Shipping Address Enabled + { + setIsCaptureShippingAddressEnabled(val); + }} + /> + + + Require Shipping Method + { + setRequireShippingMethod(val); + }} + /> + + Additional Shipping Contact Fields + + + Name + { + if (val) { + setAdditionalShippingContactFields([...additionalShippingContactFields, 'name']); + } else { + setAdditionalShippingContactFields(additionalShippingContactFields.filter(field => field !== 'name')); + } + }} + /> + + + Email Address + { + if (val) { + setAdditionalShippingContactFields([...additionalShippingContactFields, 'emailAddress']); + } else { + setAdditionalShippingContactFields(additionalShippingContactFields.filter(field => field !== 'emailAddress')); + } + }} + /> + + + Phone Number + { + if (val) { + setAdditionalShippingContactFields([...additionalShippingContactFields, 'phoneNumber']); + } else { + setAdditionalShippingContactFields(additionalShippingContactFields.filter(field => field !== 'phoneNumber')); + } + }} + /> + + + + } + + ); + }; + const updateAppPaymentParameters = () => { appPaymentParameters.merchantName = merchantName; appPaymentParameters.environment = environment; @@ -779,6 +876,12 @@ const SettingsScreen = ({ navigation }) => { currentClientSessionRequestBody.paymentMethod = Object.keys(currentPaymentMethod).length === 0 ? undefined : currentPaymentMethod; appPaymentParameters.clientSessionRequestBody = currentClientSessionRequestBody; + appPaymentParameters.shippingOptions = isShippingOptionsApplied ? { + isCaptureShippingAddressEnabled: isCaptureShippingAddressEnabled, + requireShippingMethod: requireShippingMethod, + additionalShippingContactFields: additionalShippingContactFields, + } : undefined; + } return ( diff --git a/packages/sdk/ios/Sources/DataModels/PrimerSettings+Extensions.swift b/packages/sdk/ios/Sources/DataModels/PrimerSettings+Extensions.swift index f0c134aa2..a03533ed7 100644 --- a/packages/sdk/ios/Sources/DataModels/PrimerSettings+Extensions.swift +++ b/packages/sdk/ios/Sources/DataModels/PrimerSettings+Extensions.swift @@ -34,20 +34,51 @@ extension PrimerSettings { var applePayOptions: PrimerApplePayOptions? if let rnApplePayOptions = ((settingsJson["paymentMethodOptions"] as? [String: Any])?["applePayOptions"] as? [String: Any]), - let rnApplePayMerchantIdentifier = rnApplePayOptions["merchantIdentifier"] as? String, - let rnApplePayMerchantName = rnApplePayOptions["merchantName"] as? String + let rnApplePayMerchantIdentifier = rnApplePayOptions["merchantIdentifier"] as? String { + let rnApplePayMerchantName = rnApplePayOptions["merchantName"] as? String let rnApplePayIsCaptureBillingAddressEnabled = (rnApplePayOptions["isCaptureBillingAddressEnabled"] as? Bool) ?? false let rnApplePayShowApplePayForUnsupportedDevice = (rnApplePayOptions["showApplePayForUnsupportedDevice"] as? Bool) ?? true let rnApplePayCheckProvidedNetworks = (rnApplePayOptions["checkProvidedNetworks"] as? Bool) ?? true + var shippingOptions: PrimerApplePayOptions.ShippingOptions? = nil + if let rnShippingOptions = rnApplePayOptions["shippingOptions"] as? [String: Any] { + let isCaptureShippingAddressEnabled = rnShippingOptions["isCaptureShippingAddressEnabled"] as? Bool ?? false + let requireShippingMethod = rnShippingOptions["requireShippingMethod"] as? Bool ?? false + + var additionalShippingContactFields: [PrimerApplePayOptions.ShippingOptions.AdditionalShippingContactField]? = nil + if let additionalFieldsStrings = rnShippingOptions["additionalShippingContactFields"] as? [String] { + additionalShippingContactFields = additionalFieldsStrings.compactMap { fieldStr in + switch fieldStr { + case "name": + return .name + case "emailAddress": + return .emailAddress + case "phoneNumber": + return .phoneNumber + default: + return nil // Ignore unknown values or handle accordingly + } + } + } + + shippingOptions = PrimerApplePayOptions.ShippingOptions( + isCaptureShippingAddressEnabled: isCaptureShippingAddressEnabled, + additionalShippingContactFields: additionalShippingContactFields, + requireShippingMethod: requireShippingMethod + ) + } + applePayOptions = PrimerApplePayOptions( merchantIdentifier: rnApplePayMerchantIdentifier, merchantName: rnApplePayMerchantName, isCaptureBillingAddressEnabled: rnApplePayIsCaptureBillingAddressEnabled, showApplePayForUnsupportedDevice: rnApplePayShowApplePayForUnsupportedDevice, - checkProvidedNetworks: rnApplePayCheckProvidedNetworks) + checkProvidedNetworks: rnApplePayCheckProvidedNetworks, + shippingOptions: shippingOptions + ) } + var klarnaOptions: PrimerKlarnaOptions? if let rnKlarnaRecurringPaymentDescription = ((settingsJson["paymentMethodOptions"] as? [String: Any])?["klarnaOptions"] as? [String: Any])?["recurringPaymentDescription"] as? String { diff --git a/packages/sdk/src/models/PrimerSettings.ts b/packages/sdk/src/models/PrimerSettings.ts index ca2614d1a..27d09b7ea 100644 --- a/packages/sdk/src/models/PrimerSettings.ts +++ b/packages/sdk/src/models/PrimerSettings.ts @@ -94,11 +94,30 @@ interface IPrimerApayaOptions { interface IPrimerApplePayOptions { merchantIdentifier: string; - merchantName: string; + /** + * @deprecated Use Client Session API to provide merchant name value: https://primer.io/docs/payment-methods/apple-pay/direct-integration#prepare-the-client-session + */ + merchantName?: string; isCaptureBillingAddressEnabled?: boolean; + /** + * If you don't want to present the Apple Pay option when the device doesn't support it, set this to `false`. + * Default value is `true`. + */ showApplePayForUnsupportedDevice?: boolean; + /** + * Due to reports about the Apple Pay flow not presenting because `canMakePayments(usingNetworks:)` was returning false + * when there were no cards in the Wallet, we introduced this flag to continue supporting the old behavior. + * Default value is `true`. + */ checkProvidedNetworks?: boolean; + shippingOptions?: IShippingOptions; +} +interface IShippingOptions { + isCaptureShippingAddressEnabled: boolean; + additionalShippingContactFields?: AdditionalShippingContactField[]; + requireShippingMethod: boolean; } +type AdditionalShippingContactField = 'name' | 'emailAddress' | 'phoneNumber'; interface IPrimerCardPaymentOptions { is3DSOnVaultingEnabled: boolean;