From bd03c46aa4f068698587e2a292047d265cb001df Mon Sep 17 00:00:00 2001 From: Flaviu Dunca Date: Mon, 10 Jun 2024 17:30:34 +0300 Subject: [PATCH 1/8] feat: implement ACH drop-in support --- .../app/src/main/res/values/strings.xml | 2 + .../example/src/screens/CheckoutScreen.tsx | 9 +- .../org.eclipse.buildship.core.prefs | 8 +- packages/sdk/android/build.gradle | 2 +- .../java/com/primerioreactnative/PrimerRN.kt | 4 +- .../PrimerRNHeadlessUniversalCheckout.kt | 2 +- .../datamodels/PrimerSettingsRN.kt | 106 +++++++++--------- .../PrimerPaymentMethodOptionsRN.kt | 18 ++- packages/sdk/src/models/PrimerSettings.ts | 11 ++ 9 files changed, 97 insertions(+), 65 deletions(-) diff --git a/packages/example/android/app/src/main/res/values/strings.xml b/packages/example/android/app/src/main/res/values/strings.xml index d75426c8a..e1d3bbe33 100644 --- a/packages/example/android/app/src/main/res/values/strings.xml +++ b/packages/example/android/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ example + + Would you like to accept this mandate? diff --git a/packages/example/src/screens/CheckoutScreen.tsx b/packages/example/src/screens/CheckoutScreen.tsx index f9e663bc4..6bfa3357a 100644 --- a/packages/example/src/screens/CheckoutScreen.tsx +++ b/packages/example/src/screens/CheckoutScreen.tsx @@ -254,7 +254,14 @@ const CheckoutScreen = (props: any) => { android: { threeDsAppRequestorUrl: "https://primer.io" } - } + }, + stripeOptions: { + publishableKey: "pk_test_51O8zfQKUK6bXIdC2xPvSS6UvriE9kwpvttwB7H9PAzhNAZoGzLgiDOyd4WooozeWHxoRrKo6b2VjZYxNCMX3W7bk00rMDivjau", + mandateData: { + fullMandateResourceKey: "stripe_ach_full_mandate_text", // TODO TWS: iOS to define localized string with this exact key + // merchantName: "Primer Inc.", + } + }, }, uiOptions: { isInitScreenEnabled: true, diff --git a/packages/sdk/android/.settings/org.eclipse.buildship.core.prefs b/packages/sdk/android/.settings/org.eclipse.buildship.core.prefs index c9656b3b3..2b0660e4f 100644 --- a/packages/sdk/android/.settings/org.eclipse.buildship.core.prefs +++ b/packages/sdk/android/.settings/org.eclipse.buildship.core.prefs @@ -1,11 +1,11 @@ -arguments= -auto.sync=false +arguments=--init-script /var/folders/wt/mqwpc4jx2kjgqf88mzm5qvx40000gn/T/d146c9752a26f79b52047fb6dc6ed385d064e120494f96f08ca63a317c41f94c.gradle --init-script /var/folders/wt/mqwpc4jx2kjgqf88mzm5qvx40000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle +auto.sync=true build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.4.2)) +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir=../../example/android eclipse.preferences.version=1 gradle.user.home= -java.home=/Library/Java/JavaVirtualMachines/jdk-11.0.14.jdk/Contents/Home +java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home jvm.arguments= offline.mode=false override.workspace.settings=true diff --git a/packages/sdk/android/build.gradle b/packages/sdk/android/build.gradle index c2ba36328..472930a0a 100644 --- a/packages/sdk/android/build.gradle +++ b/packages/sdk/android/build.gradle @@ -150,7 +150,7 @@ dependencies { api 'com.facebook.react:react-native:+' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1" - implementation 'io.primer:android:2.27.2-snapshot' // TODO TWS: use release version + implementation 'io.primer:android:2.27.4-dropin' // TODO TWS: use release version testImplementation 'io.mockk:mockk:1.13.10' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRN.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRN.kt index 2b92ee460..1d3511f1f 100644 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRN.kt +++ b/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRN.kt @@ -14,7 +14,7 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.json.JSONObject -class PrimerRN(reactContext: ReactApplicationContext, private val json: Json) : +class PrimerRN(private val reactContext: ReactApplicationContext, private val json: Json) : ReactContextBaseJavaModule(reactContext) { private val mListener = PrimerRNEventListener() @@ -36,7 +36,7 @@ class PrimerRN(reactContext: ReactApplicationContext, private val json: Json) : if (settingsStr.isBlank()) PrimerSettingsRN() else json.decodeFromString( settingsStr ) - startSdk(settings.toPrimerSettings()) + startSdk(settings.toPrimerSettings(reactContext)) promise.resolve(null) } catch (e: Exception) { Log.e("PrimerRN", "configure settings error: $e") diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckout.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckout.kt index c8e530fa4..4f7c43a0a 100644 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckout.kt +++ b/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckout.kt @@ -49,7 +49,7 @@ class PrimerRNHeadlessUniversalCheckout( PrimerHeadlessUniversalCheckout.current.start( reactContext, clientToken, - settings.toPrimerSettings(), + settings.toPrimerSettings(reactContext), listener, listener ) diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt index 9d63355f5..3dfd1792b 100644 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt +++ b/packages/sdk/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt @@ -1,5 +1,6 @@ package com.primerioreactnative.datamodels +import android.content.Context import com.primerioreactnative.extensions.toLocale import com.primerioreactnative.extensions.toPrimerDebugOptions import com.primerioreactnative.extensions.toPrimerPaymentMethodOptions @@ -12,29 +13,29 @@ import kotlinx.serialization.Serializable @Serializable data class PrimerSettingsRN( - var paymentHandling: PrimerPaymentHandling = PrimerPaymentHandling.AUTO, - var localeData: LocaleSettingsRN = LocaleSettingsRN(), - var paymentMethodOptions: PrimerPaymentMethodOptionsRN = PrimerPaymentMethodOptionsRN(), - var uiOptions: PrimerUIOptionsRN = PrimerUIOptionsRN(), - var debugOptions: PrimerDebugOptionsRN = PrimerDebugOptionsRN(), + var paymentHandling: PrimerPaymentHandling = PrimerPaymentHandling.AUTO, + var localeData: LocaleSettingsRN = LocaleSettingsRN(), + var paymentMethodOptions: PrimerPaymentMethodOptionsRN = PrimerPaymentMethodOptionsRN(), + var uiOptions: PrimerUIOptionsRN = PrimerUIOptionsRN(), + var debugOptions: PrimerDebugOptionsRN = PrimerDebugOptionsRN(), ) @Serializable data class LocaleSettingsRN( - val languageCode: String? = null, - val localeCode: String? = null + val languageCode: String? = null, + val localeCode: String? = null ) @Serializable data class PrimerPaymentMethodOptionsRN( - @SerialName("android") - val androidSettingsRN: AndroidSettingsRN = AndroidSettingsRN(), - var cardPaymentOptions: PrimerCardPaymentOptionsRN = PrimerCardPaymentOptionsRN(), - var googlePayOptions: PrimerGooglePayOptionsRN = PrimerGooglePayOptionsRN(), - var klarnaOptions: PrimerKlarnaOptionsRN = PrimerKlarnaOptionsRN(), - var apayaOptions: PrimerApayaOptionsRN = PrimerApayaOptionsRN(), - var threeDsOptions: PrimerThreeDsOptionsRN = PrimerThreeDsOptionsRN(), - var stripeOptions: PrimerStripeOptionsRN = PrimerStripeOptionsRN(), + @SerialName("android") + val androidSettingsRN: AndroidSettingsRN = AndroidSettingsRN(), + var cardPaymentOptions: PrimerCardPaymentOptionsRN = PrimerCardPaymentOptionsRN(), + var googlePayOptions: PrimerGooglePayOptionsRN = PrimerGooglePayOptionsRN(), + var klarnaOptions: PrimerKlarnaOptionsRN = PrimerKlarnaOptionsRN(), + var apayaOptions: PrimerApayaOptionsRN = PrimerApayaOptionsRN(), + var threeDsOptions: PrimerThreeDsOptionsRN = PrimerThreeDsOptionsRN(), + var stripeOptions: PrimerStripeOptionsRN = PrimerStripeOptionsRN(), ) @Serializable @@ -42,69 +43,68 @@ data class AndroidSettingsRN(val redirectScheme: String? = null) @Serializable data class PrimerUIOptionsRN( - var isInitScreenEnabled: Boolean = true, - var isSuccessScreenEnabled: Boolean = true, - var isErrorScreenEnabled: Boolean = true, + var isInitScreenEnabled: Boolean = true, + var isSuccessScreenEnabled: Boolean = true, + var isErrorScreenEnabled: Boolean = true, ) @Serializable data class PrimerDebugOptionsRN(val is3DSSanityCheckEnabled: Boolean = true) @Serializable -data class PrimerCardPaymentOptionsRN( - var is3DSOnVaultingEnabled: Boolean = true -) +data class PrimerCardPaymentOptionsRN(var is3DSOnVaultingEnabled: Boolean = true) @Serializable data class PrimerThreeDsOptionsRN( - @SerialName("android") - val threeDsOptionsAndroid: PrimerThreeDsAndroidOptionsRN? = null + @SerialName("android") + val threeDsOptionsAndroid: PrimerThreeDsAndroidOptionsRN? = null ) -@Serializable -data class PrimerThreeDsAndroidOptionsRN( - val threeDsAppRequestorUrl: String? = null -) +@Serializable +data class PrimerThreeDsAndroidOptionsRN(val threeDsAppRequestorUrl: String? = null) @Serializable data class PrimerGooglePayOptionsRN( - var merchantName: String? = null, - var allowedCardNetworks: List = listOf( - "AMEX", - "DISCOVER", - "JCB", - "MASTERCARD", - "VISA" - ), - var buttonStyle: GooglePayButtonStyle = GooglePayButtonStyle.BLACK, - @SerialName("isCaptureBillingAddressEnabled") var captureBillingAddress: Boolean = false, - @SerialName("isExistingPaymentMethodRequired") var existingPaymentMethodRequired: Boolean = false + var merchantName: String? = null, + var allowedCardNetworks: List = + listOf("AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"), + var buttonStyle: GooglePayButtonStyle = GooglePayButtonStyle.BLACK, + @SerialName("isCaptureBillingAddressEnabled") + var captureBillingAddress: Boolean = false, + @SerialName("isExistingPaymentMethodRequired") + var existingPaymentMethodRequired: Boolean = false ) @Serializable data class PrimerKlarnaOptionsRN( - var recurringPaymentDescription: String? = null, - @Deprecated("This property is deprecated and will be removed in future release.") - var webViewTitle: String? = null, + var recurringPaymentDescription: String? = null, + @Deprecated("This property is deprecated and will be removed in future release.") + var webViewTitle: String? = null, ) @Serializable data class PrimerStripeOptionsRN( - var publishableKey: String? = null, -) + val mandateData: MandateDataRN? = null, + val publishableKey: String? = null, +) { + @Serializable + data class MandateDataRN( + @SerialName("fullMandateResourceKey") val fullMandateStringResName: String? = null, + val merchantName: String? = null + ) +} @Serializable @Deprecated("This class is deprecated and will be removed in future release.") data class PrimerApayaOptionsRN( - var webViewTitle: String? = null, + var webViewTitle: String? = null, ) -fun PrimerSettingsRN.toPrimerSettings() = PrimerSettings( - paymentHandling, - localeData.toLocale(), - paymentMethodOptions.toPrimerPaymentMethodOptions(), - uiOptions.toPrimerUIOptions(), - debugOptions.toPrimerDebugOptions() -) - - +fun PrimerSettingsRN.toPrimerSettings(context: Context) = + PrimerSettings( + paymentHandling, + localeData.toLocale(), + paymentMethodOptions.toPrimerPaymentMethodOptions(context), + uiOptions.toPrimerUIOptions(), + debugOptions.toPrimerDebugOptions() + ) diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodOptionsRN.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodOptionsRN.kt index 79214c866..de6c59b6a 100644 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodOptionsRN.kt +++ b/packages/sdk/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodOptionsRN.kt @@ -2,14 +2,17 @@ package com.primerioreactnative.extensions import com.primerioreactnative.datamodels.* import io.primer.android.data.settings.* +import io.primer.android.data.settings.PrimerStripeOptions.MandateData.TemplateMandateData +import io.primer.android.data.settings.PrimerStripeOptions.MandateData.FullMandateData +import android.content.Context -fun PrimerPaymentMethodOptionsRN.toPrimerPaymentMethodOptions() = +fun PrimerPaymentMethodOptionsRN.toPrimerPaymentMethodOptions(context: Context) = PrimerPaymentMethodOptions( androidSettingsRN.redirectScheme, googlePayOptions.toPrimerGooglePayOptions(), klarnaOptions.toPrimerKlarnaOptions(), threeDsOptions.toPrimerThreeDsOptions(), - stripeOptions.toPrimerStripeOptions(), + stripeOptions.toPrimerStripeOptions(context), ) fun PrimerGooglePayOptionsRN.toPrimerGooglePayOptions() = @@ -27,4 +30,13 @@ fun PrimerKlarnaOptionsRN.toPrimerKlarnaOptions() = fun PrimerThreeDsOptionsRN.toPrimerThreeDsOptions() = PrimerThreeDsOptions(threeDsOptionsAndroid?.threeDsAppRequestorUrl) -fun PrimerStripeOptionsRN.toPrimerStripeOptions() = PrimerStripeOptions(publishableKey) +fun PrimerStripeOptionsRN.toPrimerStripeOptions(context: Context) = + PrimerStripeOptions(mandateData = mandateData?.toMandateData(context), publishableKey = publishableKey) + +private fun PrimerStripeOptionsRN.MandateDataRN.toMandateData(context: Context) = when { + merchantName != null -> TemplateMandateData(merchantName) + fullMandateStringResName != null -> FullMandateData( + context.getResources().getIdentifier(fullMandateStringResName, "string", context.getPackageName()) + ) + else -> error("Missing mandate data") +} \ No newline at end of file diff --git a/packages/sdk/src/models/PrimerSettings.ts b/packages/sdk/src/models/PrimerSettings.ts index 9fafad9cf..dedd6b2f5 100644 --- a/packages/sdk/src/models/PrimerSettings.ts +++ b/packages/sdk/src/models/PrimerSettings.ts @@ -150,4 +150,15 @@ interface IPrimerThreeDsOptions { interface IPrimerStripeOptions { publishableKey?: string; + mandateData?: IPrimerStripeTemplateMandateData | IPrimerStripeFullMandateData; +} + +interface IPrimerStripeMandateData {} + +interface IPrimerStripeTemplateMandateData extends IPrimerStripeMandateData { + merchantName: string; +} + +interface IPrimerStripeFullMandateData extends IPrimerStripeMandateData { + fullMandateResourceKey: string; } \ No newline at end of file From 0e4c664a7f876d8ad39081ca41cc5781c426b9b8 Mon Sep 17 00:00:00 2001 From: Semir Date: Tue, 25 Jun 2024 18:15:09 +0200 Subject: [PATCH 2/8] bump: Android SDK -> 2.27.6 --- packages/example/android/app/build.gradle | 2 +- packages/sdk/android/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/example/android/app/build.gradle b/packages/example/android/app/build.gradle index d126c305f..ae0be5963 100644 --- a/packages/example/android/app/build.gradle +++ b/packages/example/android/app/build.gradle @@ -114,7 +114,7 @@ dependencies { implementation project(':primerioreactnative') - implementation "io.primer:3ds-android:1.4.2" + implementation "io.primer:3ds-android:1.4.3" implementation "io.primer:ipay88-my-android:1.0.3" implementation "io.primer:klarna-android:1.0.4" diff --git a/packages/sdk/android/build.gradle b/packages/sdk/android/build.gradle index ecd36bd68..2a2a401c1 100644 --- a/packages/sdk/android/build.gradle +++ b/packages/sdk/android/build.gradle @@ -148,7 +148,7 @@ dependencies { api 'com.facebook.react:react-native:+' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1" - implementation 'io.primer:android:2.27.3' + implementation 'io.primer:android:2.27.6' testImplementation 'io.mockk:mockk:1.13.10' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' From 4475509cbb7f511ee3860edbe6b0b5ef85b54b6e Mon Sep 17 00:00:00 2001 From: Jack Newcombe Date: Wed, 26 Jun 2024 10:28:56 +0100 Subject: [PATCH 3/8] Update ios + RN versions --- packages/example/ios/Podfile.lock | 16 ++++++++-------- packages/sdk/ios/Sources/version.swift | 2 +- packages/sdk/package.json | 2 +- packages/sdk/primer-io-react-native.podspec | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/example/ios/Podfile.lock b/packages/example/ios/Podfile.lock index 9b06daa97..aeb6aa4ac 100644 --- a/packages/example/ios/Podfile.lock +++ b/packages/example/ios/Podfile.lock @@ -11,15 +11,15 @@ PODS: - ReactCommon/turbomodule/core (= 0.72.0) - fmt (6.2.1) - glog (0.3.5) - - primer-io-react-native (2.22.0): - - PrimerSDK (= 2.26.0) + - primer-io-react-native (2.24.1): + - PrimerSDK (= 2.26.7) - React-Core - Primer3DS (2.3.2) - PrimerIPay88MYSDK (0.1.7) - PrimerKlarnaSDK (1.1.0) - - PrimerSDK (2.26.0): - - PrimerSDK/Core (= 2.26.0) - - PrimerSDK/Core (2.26.0) + - PrimerSDK (2.26.7): + - PrimerSDK/Core (= 2.26.7) + - PrimerSDK/Core (2.26.7) - RCT-Folly (2021.07.22.00): - boost - DoubleConversion @@ -566,11 +566,11 @@ SPEC CHECKSUMS: FBReactNativeSpec: 6e7e74b1ed7f0a1a469a82a67521b33285f5fef3 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - primer-io-react-native: d6e2800366bda4069ec31d6d7fcbeee45e9d3704 + primer-io-react-native: e5c9b53cad492b902d836a3c7b6ad50ab4090291 Primer3DS: 81e7969033230c7346a517cd609be956914738bb PrimerIPay88MYSDK: 436ee0be7e2c97e4e81456ccddee20175e9e3c4d PrimerKlarnaSDK: 83e9a1357a7247bf8fa2836fc945cf97644d601d - PrimerSDK: ffa6b212c08cab4157bae5f89566ad9f89f2d613 + PrimerSDK: 3d415b64abebc1a36bd5575169137ea5deed9eba RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: 656ef0536dd60a9740961ade6a64ba0cb0572d2b RCTTypeSafety: 82bd23b63f043d1a6b8e80e72fd15c08e04528a4 @@ -611,6 +611,6 @@ SPEC CHECKSUMS: SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: 1d6727ed193122f6adaf435c3de1a768326ff83b -PODFILE CHECKSUM: 270edb26d82f133812cb878b53aafd50106f3662 +PODFILE CHECKSUM: 52db9ce2025ee0ab78fb1f3cf545403d3fa848fc COCOAPODS: 1.15.2 diff --git a/packages/sdk/ios/Sources/version.swift b/packages/sdk/ios/Sources/version.swift index e80dad009..50d4441f5 100644 --- a/packages/sdk/ios/Sources/version.swift +++ b/packages/sdk/ios/Sources/version.swift @@ -1,2 +1,2 @@ // swiftlint:disable:next identifier_name -public let PrimerReactNativeSDKVersion = "2.24.0" +public let PrimerReactNativeSDKVersion = "2.24.1" diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 2d02eb0a7..f5b4ddd81 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@primer-io/react-native", - "version": "2.24.0", + "version": "2.24.1", "description": "Primer SDK for RN", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/packages/sdk/primer-io-react-native.podspec b/packages/sdk/primer-io-react-native.podspec index e3ff35320..cc78dfecf 100644 --- a/packages/sdk/primer-io-react-native.podspec +++ b/packages/sdk/primer-io-react-native.podspec @@ -16,5 +16,5 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" s.dependency "React-Core" - s.dependency "PrimerSDK", "2.26.4" + s.dependency "PrimerSDK", "2.26.7" end From 54fdfd1d8ad2b80b10e7cedfc97efb7122dbf4d9 Mon Sep 17 00:00:00 2001 From: Jack Newcombe Date: Wed, 26 Jun 2024 10:50:30 +0100 Subject: [PATCH 4/8] iOS test fix for error unit test --- packages/example/ios/Podfile.lock | 2 +- .../HelpersTests/ErrorExtensionTests.swift | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/example/ios/Podfile.lock b/packages/example/ios/Podfile.lock index aeb6aa4ac..8421ed3e8 100644 --- a/packages/example/ios/Podfile.lock +++ b/packages/example/ios/Podfile.lock @@ -566,7 +566,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: 6e7e74b1ed7f0a1a469a82a67521b33285f5fef3 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - primer-io-react-native: e5c9b53cad492b902d836a3c7b6ad50ab4090291 + primer-io-react-native: 24cc7cf1394b46e1731a434592c5b7da9c8d17e8 Primer3DS: 81e7969033230c7346a517cd609be956914738bb PrimerIPay88MYSDK: 436ee0be7e2c97e4e81456ccddee20175e9e3c4d PrimerKlarnaSDK: 83e9a1357a7247bf8fa2836fc945cf97644d601d diff --git a/packages/example/ios/example_0_70_6Tests/HelpersTests/ErrorExtensionTests.swift b/packages/example/ios/example_0_70_6Tests/HelpersTests/ErrorExtensionTests.swift index 4a78a7392..3d87a77e0 100644 --- a/packages/example/ios/example_0_70_6Tests/HelpersTests/ErrorExtensionTests.swift +++ b/packages/example/ios/example_0_70_6Tests/HelpersTests/ErrorExtensionTests.swift @@ -25,12 +25,13 @@ class ErrorExtensionTests: XCTestCase { } func testRNErrorForPrimerError() { - let error = PrimerError.generic(message: "message", userInfo: ["test1": "test2"], diagnosticsId: "diagnosticsId123") + let error = PrimerError.unknown(userInfo: ["test1": "test2"], diagnosticsId: "diagnosticsId123") let expected: [String: String] = [ - "errorId": "primer-generic", + "description": "[unknown] Something went wrong (diagnosticsId: diagnosticsId123)", + "errorId": "unknown", "diagnosticsId": "diagnosticsId123", - "description": "[primer-generic] Generic error | Message: message | Data: {\n \"test1\" : \"test2\"\n}) (diagnosticsId: diagnosticsId123)" + "recoverySuggestion": "Contact Primer and provide them diagnostics id diagnosticsId123" ] XCTAssertEqual(error.rnError, expected) } From 2df76f35cd373340fe19cce9c664fb65f564a3ba Mon Sep 17 00:00:00 2001 From: Jack Newcombe Date: Thu, 11 Jul 2024 13:52:06 +0100 Subject: [PATCH 5/8] Bump iOS 2.26.7 -> 2.27.0, RN 2.24.1 -> 2.25.0 --- packages/example/ios/Podfile.lock | 14 +++++------ .../RNTPrimerCardNumberInputElementManager.m | 23 ------------------- packages/sdk/ios/Sources/version.swift | 2 +- packages/sdk/package.json | 2 +- packages/sdk/primer-io-react-native.podspec | 2 +- 5 files changed, 10 insertions(+), 33 deletions(-) delete mode 100644 packages/sdk/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNTPrimerCardNumberInputElementManager.m diff --git a/packages/example/ios/Podfile.lock b/packages/example/ios/Podfile.lock index 8421ed3e8..3b3f0c8b8 100644 --- a/packages/example/ios/Podfile.lock +++ b/packages/example/ios/Podfile.lock @@ -11,15 +11,15 @@ PODS: - ReactCommon/turbomodule/core (= 0.72.0) - fmt (6.2.1) - glog (0.3.5) - - primer-io-react-native (2.24.1): - - PrimerSDK (= 2.26.7) + - primer-io-react-native (2.25.0): + - PrimerSDK (= 2.27.0) - React-Core - Primer3DS (2.3.2) - PrimerIPay88MYSDK (0.1.7) - PrimerKlarnaSDK (1.1.0) - - PrimerSDK (2.26.7): - - PrimerSDK/Core (= 2.26.7) - - PrimerSDK/Core (2.26.7) + - PrimerSDK (2.27.0): + - PrimerSDK/Core (= 2.27.0) + - PrimerSDK/Core (2.27.0) - RCT-Folly (2021.07.22.00): - boost - DoubleConversion @@ -566,11 +566,11 @@ SPEC CHECKSUMS: FBReactNativeSpec: 6e7e74b1ed7f0a1a469a82a67521b33285f5fef3 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - primer-io-react-native: 24cc7cf1394b46e1731a434592c5b7da9c8d17e8 + primer-io-react-native: 8f5a31d699b11d1fe9538fb6f4c8f08f22dc00dd Primer3DS: 81e7969033230c7346a517cd609be956914738bb PrimerIPay88MYSDK: 436ee0be7e2c97e4e81456ccddee20175e9e3c4d PrimerKlarnaSDK: 83e9a1357a7247bf8fa2836fc945cf97644d601d - PrimerSDK: 3d415b64abebc1a36bd5575169137ea5deed9eba + PrimerSDK: d602d8492ad2b6d04a8ee36274d9756d8ad79a67 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: 656ef0536dd60a9740961ade6a64ba0cb0572d2b RCTTypeSafety: 82bd23b63f043d1a6b8e80e72fd15c08e04528a4 diff --git a/packages/sdk/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNTPrimerCardNumberInputElementManager.m b/packages/sdk/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNTPrimerCardNumberInputElementManager.m deleted file mode 100644 index 7d39f577d..000000000 --- a/packages/sdk/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNTPrimerCardNumberInputElementManager.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// RNTPrimerCardNumberInputElementManager.m -// primer-io-react-native -// -// Created by Evangelos on 3/3/22. -// - -#import -@import PrimerSDK; - -@interface RNTPrimerCardNumberInputElementManager : RCTViewManager -@end - -@implementation RNTPrimerCardNumberInputElementManager - -RCT_EXPORT_MODULE(PrimerCardNumberEditText) - -- (UIView *)view -{ - return [[PrimerCardNumberInputElement alloc] init]; -} - -@end diff --git a/packages/sdk/ios/Sources/version.swift b/packages/sdk/ios/Sources/version.swift index 50d4441f5..f54865fd8 100644 --- a/packages/sdk/ios/Sources/version.swift +++ b/packages/sdk/ios/Sources/version.swift @@ -1,2 +1,2 @@ // swiftlint:disable:next identifier_name -public let PrimerReactNativeSDKVersion = "2.24.1" +public let PrimerReactNativeSDKVersion = "2.25.0" diff --git a/packages/sdk/package.json b/packages/sdk/package.json index f5b4ddd81..937bf4935 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@primer-io/react-native", - "version": "2.24.1", + "version": "2.25.0", "description": "Primer SDK for RN", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/packages/sdk/primer-io-react-native.podspec b/packages/sdk/primer-io-react-native.podspec index cc78dfecf..4c0ab9c22 100644 --- a/packages/sdk/primer-io-react-native.podspec +++ b/packages/sdk/primer-io-react-native.podspec @@ -16,5 +16,5 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" s.dependency "React-Core" - s.dependency "PrimerSDK", "2.26.7" + s.dependency "PrimerSDK", "2.27.0" end From 9dcb370579fa00e4b09b0d0b68f06e785f07f247 Mon Sep 17 00:00:00 2001 From: Jack Newcombe Date: Thu, 11 Jul 2024 14:00:37 +0100 Subject: [PATCH 6/8] Remove defunct card widgets code --- .../PrimerCardNumberInputElement.tsx | 3 - .../PrimerCardNumberEditTextManager.kt | 68 ---------------- .../primerioreactnative/ReactNativePackage.kt | 4 - packages/sdk/src/PrimerInput.tsx | 77 ------------------- 4 files changed, 152 deletions(-) delete mode 100644 packages/example/src/components/PrimerCardNumberInputElement.tsx delete mode 100644 packages/sdk/android/src/main/java/com/primerioreactnative/PrimerCardNumberEditTextManager.kt delete mode 100644 packages/sdk/src/PrimerInput.tsx diff --git a/packages/example/src/components/PrimerCardNumberInputElement.tsx b/packages/example/src/components/PrimerCardNumberInputElement.tsx deleted file mode 100644 index 053721fa7..000000000 --- a/packages/example/src/components/PrimerCardNumberInputElement.tsx +++ /dev/null @@ -1,3 +0,0 @@ -// MyCustomView.js -import {requireNativeComponent} from 'react-native'; -export const PrimerCardNumberEditText = requireNativeComponent('PrimerCardNumberEditText'); diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerCardNumberEditTextManager.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerCardNumberEditTextManager.kt deleted file mode 100644 index 1dfe74ba0..000000000 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/PrimerCardNumberEditTextManager.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.primerioreactnative - -import com.facebook.react.uimanager.SimpleViewManager -import com.facebook.react.uimanager.ThemedReactContext -import io.primer.android.components.ui.widgets.* - -val listOfTextInputs = mutableListOf() - -class PrimerCardNumberEditTextManager : SimpleViewManager() { - - override fun getName(): String { - return REACT_CLASS - } - - override fun createViewInstance(reactContext: ThemedReactContext): PrimerCardNumberEditText { - val editText = PrimerCardNumberEditText(reactContext) - return editText - } - - companion object { - const val REACT_CLASS = "PrimerCardNumberEditText" - } -} - -class PrimerCardholderNameEditTextManager : SimpleViewManager() { - - override fun getName(): String { - return REACT_CLASS - } - - override fun createViewInstance(reactContext: ThemedReactContext): PrimerCardholderNameEditText { - return PrimerCardholderNameEditText(reactContext) - } - - companion object { - const val REACT_CLASS = "PrimerCardholderNameEditText" - } -} - -class PrimerExpiryEditTextManager : SimpleViewManager() { - - override fun getName(): String { - return REACT_CLASS - } - - override fun createViewInstance(reactContext: ThemedReactContext): PrimerExpiryEditText { - return PrimerExpiryEditText(reactContext) - } - - companion object { - const val REACT_CLASS = "PrimerExpiryEditText" - } -} - -class PrimerCvvEditTextManager : SimpleViewManager() { - - override fun getName(): String { - return REACT_CLASS - } - - override fun createViewInstance(reactContext: ThemedReactContext): PrimerCvvEditText { - return PrimerCvvEditText(reactContext) - } - - companion object { - const val REACT_CLASS = "PrimerCvvEditText" - } -} diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt index 69e451afe..ff06feae7 100644 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt +++ b/packages/sdk/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt @@ -34,10 +34,6 @@ class ReactNativePackage : ReactPackage { override fun createViewManagers(reactContext: ReactApplicationContext): List> { return mutableListOf( - PrimerCardNumberEditTextManager(), - PrimerCardholderNameEditTextManager(), - PrimerExpiryEditTextManager(), - PrimerCvvEditTextManager(), PrimerKlarnaPaymentViewManager(reactContext) ) } diff --git a/packages/sdk/src/PrimerInput.tsx b/packages/sdk/src/PrimerInput.tsx deleted file mode 100644 index 4fbf5dd0a..000000000 --- a/packages/sdk/src/PrimerInput.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { PrimerHeadlessUniversalCheckoutCardFormUIManager } from './RNTPrimerHeadlessUniversalCheckoutCardFormUIManager'; -import React, { useEffect, useRef } from 'react'; -import { NativeModules, requireNativeComponent, ViewProps } from 'react-native'; - - -// PrimerCardNumberEditText -export const PrimerCardNumberEditTextRaw = requireNativeComponent<{}>( - 'PrimerCardNumberEditText' -); - -type PrimerCardNumberEditTextProps = ViewProps; - -const { PrimerRN } = NativeModules; - -export const PrimerCardNumberEditText: React.FC = (props) => { - const ref = useRef(React.createRef()); - - useEffect(() => { - const tag = ref.current.current._nativeTag; - PrimerHeadlessUniversalCheckoutCardFormUIManager.addInput(tag); - return () => PrimerRN.removeInput(tag); - }, []); - - const rawComponent = ( - //@ts-ignore - - ); - - return rawComponent; -}; - -// PrimerCardholderNameEditText -export const PrimerCardholderNameEditTextRaw = requireNativeComponent<{}>( - 'PrimerCardholderNameEditText' -); - -type PrimerCardholderNameEditTextProps = ViewProps; - -export const PrimerCardholderNameEditText: React.FC = ( - props -) => { - const ref = useRef(React.createRef()); - - useEffect(() => { - const tag = ref.current.current._nativeTag; - PrimerRN.addInput(tag); - return () => PrimerRN.removeInput(tag); - }, []); - //@ts-ignore - return ; -}; - -// PrimerExpiryEditText -export const PrimerExpiryEditTextRaw = requireNativeComponent<{}>( - 'PrimerExpiryEditText' -); - -type PrimerExpiryEditTextProps = ViewProps; - -export const PrimerExpiryEditText: React.FC = ( - props -) => { - //@ts-ignore - return ; -}; - -// cvv -export const PrimerCvvEditTextRaw = requireNativeComponent<{}>( - 'PrimerCvvEditText' -); - -type PrimerCvvEditTextProps = ViewProps; - -export const PrimerCvvEditText: React.FC = (props) => { - //@ts-ignore - return ; -}; From 5d0fb2e08309cf6cf23db021e33635588910e5ad Mon Sep 17 00:00:00 2001 From: Jack Newcombe Date: Fri, 12 Jul 2024 09:05:01 +0100 Subject: [PATCH 7/8] Disable default styles --- .../example/src/screens/CheckoutScreen.tsx | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/packages/example/src/screens/CheckoutScreen.tsx b/packages/example/src/screens/CheckoutScreen.tsx index 7a463ce0c..15d0d1070 100644 --- a/packages/example/src/screens/CheckoutScreen.tsx +++ b/packages/example/src/screens/CheckoutScreen.tsx @@ -261,34 +261,36 @@ const CheckoutScreen = (props: any) => { isSuccessScreenEnabled: true, isErrorScreenEnabled: true, theme: { - colors: { - mainColor: { - red: 214, - green: 255, - blue: 1, - alpha: 255 - }, - background: { - red: 255, - green: 214, - blue: 1, - alpha: 255 - } - }, - darkModeColors: { - mainColor: { - red: 1, - green: 255, - blue: 1, - alpha: 255 - }, - background: { - red: 255, - green: 1, - blue: 255, - alpha: 255 - } - } + // 👇 Uncomment to try theming drop-in checkout + + // colors: { + // mainColor: { + // red: 214, + // green: 255, + // blue: 1, + // alpha: 255 + // }, + // background: { + // red: 255, + // green: 214, + // blue: 1, + // alpha: 255 + // } + // }, + // darkModeColors: { + // mainColor: { + // red: 1, + // green: 255, + // blue: 1, + // alpha: 255 + // }, + // background: { + // red: 255, + // green: 1, + // blue: 255, + // alpha: 255 + // } + // } } }, debugOptions: { From c262c348c5bc530c410e30ede1198cbb863aef91 Mon Sep 17 00:00:00 2001 From: FlaviuExtPrimer <149587774+FlaviuExtPrimer@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:19:08 +0300 Subject: [PATCH 8/8] chore: update Stripe wrapper, include deviceInfo and scenario in client session --- packages/example/android/app/build.gradle | 2 +- .../src/models/IClientSessionRequestBody.ts | 16 ++++++++++++++++ packages/sdk/android/build.gradle | 2 +- ...erRNHeadlessUniversalCheckoutPaymentMethod.kt | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/example/android/app/build.gradle b/packages/example/android/app/build.gradle index 1e02600cc..cbf9b0b04 100644 --- a/packages/example/android/app/build.gradle +++ b/packages/example/android/app/build.gradle @@ -129,7 +129,7 @@ dependencies { implementation "io.primer:3ds-android:1.4.3" implementation "io.primer:ipay88-my-android:1.0.3" implementation "io.primer:klarna-android:1.0.4" - implementation "io.primer:stripe-android:1.1.0" // TODO TWS: use release version + implementation "io.primer:stripe-android:1.0.0" implementation project(path: ':primerioreactnative') diff --git a/packages/example/src/models/IClientSessionRequestBody.ts b/packages/example/src/models/IClientSessionRequestBody.ts index 6ac9cefa7..f30f893aa 100644 --- a/packages/example/src/models/IClientSessionRequestBody.ts +++ b/packages/example/src/models/IClientSessionRequestBody.ts @@ -7,6 +7,7 @@ export interface IClientSessionRequestBody { customerId?: string; orderId?: string; currencyCode?: string; + metadata?: IClientSessionMetadata; order?: IClientSessionOrder; customer?: IClientSessionCustomer; paymentMethod?: IClientSessionPaymentMethod; @@ -17,6 +18,15 @@ export interface IClientSessionOrder { lineItems?: Array } +export interface IClientSessionMetadata { + scenario?: string; + deviceInfo?: IClientSessionDeviceInfo; +} + +export interface IClientSessionDeviceInfo { + ipAddress?: string; +} + export interface IClientSessionCustomer { emailAddress?: string; mobileNumber?: string; @@ -91,6 +101,12 @@ export let appPaymentParameters: AppPaymentParameters = { customerId: `rn-customer-${makeRandomString(8)}`, orderId: `rn-order-${makeRandomString(8)}`, currencyCode: 'EUR', + metadata: { + scenario: 'STRIPE_ACH_ONEOFF', + deviceInfo : { + ipAddress: '127.0.0.1' + } + }, order: { countryCode: 'DE', lineItems: [ diff --git a/packages/sdk/android/build.gradle b/packages/sdk/android/build.gradle index c2ba36328..22f2e1941 100644 --- a/packages/sdk/android/build.gradle +++ b/packages/sdk/android/build.gradle @@ -150,7 +150,7 @@ dependencies { api 'com.facebook.react:react-native:+' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1" - implementation 'io.primer:android:2.27.2-snapshot' // TODO TWS: use release version + implementation 'io.primer:android:2.27.6-snapshot' testImplementation 'io.mockk:mockk:1.13.10' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' diff --git a/packages/sdk/android/src/main/java/com/primerioreactnative/components/datamodels/core/PrimerRNHeadlessUniversalCheckoutPaymentMethod.kt b/packages/sdk/android/src/main/java/com/primerioreactnative/components/datamodels/core/PrimerRNHeadlessUniversalCheckoutPaymentMethod.kt index 3c7142faa..09ef79769 100644 --- a/packages/sdk/android/src/main/java/com/primerioreactnative/components/datamodels/core/PrimerRNHeadlessUniversalCheckoutPaymentMethod.kt +++ b/packages/sdk/android/src/main/java/com/primerioreactnative/components/datamodels/core/PrimerRNHeadlessUniversalCheckoutPaymentMethod.kt @@ -21,5 +21,5 @@ internal fun PrimerHeadlessUniversalCheckoutPaymentMethod.toPrimerRNHeadlessUniv PrimerRNHeadlessUniversalCheckoutPaymentMethod( paymentMethodType, supportedPrimerSessionIntents, - paymentMethodManagerCategories.minus(PrimerPaymentMethodManagerCategory.CARD_COMPONENTS) + paymentMethodManagerCategories )