@primer-io/react-native 2.21.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/android/build.gradle +4 -4
  2. package/android/gradle/wrapper/gradle-wrapper.properties +1 -2
  3. package/android/src/main/java/com/primerioreactnative/PrimerRN.kt +2 -2
  4. package/android/src/main/java/com/primerioreactnative/PrimerRNEventListener.kt +10 -8
  5. package/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckout.kt +2 -2
  6. package/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckoutListener.kt +36 -13
  7. package/android/src/main/java/com/primerioreactnative/PrimerRNViewModelStoreOwner.kt +9 -0
  8. package/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt +9 -1
  9. package/android/src/main/java/com/primerioreactnative/components/events/PrimerHeadlessUniversalCheckoutComponentEvent.kt +10 -0
  10. package/android/src/main/java/com/primerioreactnative/components/manager/asset/PrimerRNHeadlessUniversalCheckoutAssetManager.kt +8 -13
  11. package/android/src/main/java/com/primerioreactnative/components/manager/banks/PrimerRNHeadlessUniversalCheckoutBanksComponent.kt +284 -0
  12. package/android/src/main/java/com/primerioreactnative/components/manager/klarna/PrimerKlarnaPaymentViewManager.kt +103 -0
  13. package/android/src/main/java/com/primerioreactnative/components/manager/klarna/PrimerRNHeadlessUniversalCheckoutKlarnaComponent.kt +334 -0
  14. package/android/src/main/java/com/primerioreactnative/components/manager/nativeUi/PrimerRNHeadlessUniversalCheckoutNativeUiManager.kt +10 -8
  15. package/android/src/main/java/com/primerioreactnative/components/manager/raw/PrimerRNHeadlessUniversalCheckoutRawManager.kt +2 -2
  16. package/android/src/main/java/com/primerioreactnative/components/manager/vault/PrimerRNHeadlessUniversalCheckoutVaultManager.kt +5 -9
  17. package/android/src/main/java/com/primerioreactnative/datamodels/NamedComponentStepRN.kt +7 -0
  18. package/android/src/main/java/com/primerioreactnative/datamodels/NamedComponentValidatableDataRN.kt +7 -0
  19. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerErrorRN.kt +8 -0
  20. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerIssuingBankRN.kt +11 -0
  21. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerPaymentMethodDataRN.kt +1 -1
  22. package/android/src/main/java/com/primerioreactnative/datamodels/banks/BanksCollectableDataRN.kt +17 -0
  23. package/android/src/main/java/com/primerioreactnative/datamodels/banks/BanksStepRN.kt +20 -0
  24. package/android/src/main/java/com/primerioreactnative/datamodels/extensions/banks/BanksCollectableData.kt +8 -0
  25. package/android/src/main/java/com/primerioreactnative/datamodels/extensions/banks/BanksStep.kt +11 -0
  26. package/android/src/main/java/com/primerioreactnative/datamodels/klarna/KlarnaPaymentCategoryRN.kt +11 -0
  27. package/android/src/main/java/com/primerioreactnative/datamodels/klarna/KlarnaPaymentCollectableDataRN.kt +21 -0
  28. package/android/src/main/java/com/primerioreactnative/datamodels/klarna/KlarnaPaymentStepRN.kt +31 -0
  29. package/android/src/main/java/com/primerioreactnative/extensions/PrimerError.kt +13 -0
  30. package/android/src/main/java/com/primerioreactnative/extensions/PrimerIssuingBank.kt +7 -0
  31. package/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodData.kt +1 -1
  32. package/android/src/main/java/com/primerioreactnative/extensions/klarna/KlarnaPaymentCategory.kt +12 -0
  33. package/android/src/main/java/com/primerioreactnative/extensions/klarna/KlarnaPaymentCategoryRN.kt +12 -0
  34. package/android/src/main/java/com/primerioreactnative/extensions/klarna/KlarnaPaymentCollectableData.kt +14 -0
  35. package/android/src/main/java/com/primerioreactnative/extensions/klarna/KlarnaPaymentStep.kt +21 -0
  36. package/android/src/main/java/com/primerioreactnative/utils/ErrorHelper.kt +3 -2
  37. package/android/src/main/java/com/primerioreactnative/utils/JsonConverter.kt +8 -1
  38. package/ios/ReactNative-Bridging-Header.h +1 -0
  39. package/ios/Sources/DataModels/Banks Component/RNTBanksCollectableData.swift +42 -0
  40. package/ios/Sources/DataModels/Banks Component/RNTBanksStep.swift +36 -0
  41. package/ios/Sources/DataModels/Klarna Component/PrimerHeadlessUniversalCheckoutComponentEvent.swift +36 -0
  42. package/ios/Sources/DataModels/Klarna Component/RNTKlarnaCollectableData.swift +36 -0
  43. package/ios/Sources/DataModels/Klarna Component/RNTKlarnaPaymentCategory.swift +33 -0
  44. package/ios/Sources/DataModels/Klarna Component/RNTKlarnaStep.swift +61 -0
  45. package/ios/Sources/DataModels/Klarna Component/RNTPrimerError.swift +67 -0
  46. package/ios/Sources/Headless Universal Checkout/Managers/Klarna/KlarnaPaymentView Manager/RNTPrimerKlarnaPaymentViewManager.h +14 -0
  47. package/ios/Sources/Headless Universal Checkout/Managers/Klarna/KlarnaPaymentView Manager/RNTPrimerKlarnaPaymentViewManager.m +25 -0
  48. package/ios/Sources/Headless Universal Checkout/Managers/Klarna/PrimerRNHeadlessUniversalCheckoutKlarnaComponent.m +27 -0
  49. package/ios/Sources/Headless Universal Checkout/Managers/Klarna/PrimerRNHeadlessUniversalCheckoutKlarnaComponent.swift +272 -0
  50. package/ios/Sources/Headless Universal Checkout/Managers/RNTRedirectManager.m +25 -0
  51. package/ios/Sources/Headless Universal Checkout/Managers/RNTRedirectManager.swift +183 -0
  52. package/ios/Sources/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.swift +3 -1
  53. package/ios/Sources/Helpers/PrimerCheckoutPaymentMethodData+RN.swift +21 -0
  54. package/ios/Sources/RNTPrimer.swift +4 -2
  55. package/ios/Sources/version.swift +1 -1
  56. package/lib/commonjs/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.js +9 -0
  57. package/lib/commonjs/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.js.map +1 -0
  58. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.js +103 -0
  59. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.js.map +1 -0
  60. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js +99 -0
  61. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js.map +1 -0
  62. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js +4 -4
  63. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js.map +1 -1
  64. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.js +8 -0
  65. package/lib/commonjs/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.js.map +1 -0
  66. package/lib/commonjs/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js +3 -2
  67. package/lib/commonjs/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js.map +1 -1
  68. package/lib/commonjs/Primer.js +2 -1
  69. package/lib/commonjs/Primer.js.map +1 -1
  70. package/lib/commonjs/index.js +186 -0
  71. package/lib/commonjs/index.js.map +1 -1
  72. package/lib/commonjs/models/IssuingBank.js +2 -0
  73. package/lib/commonjs/models/IssuingBank.js.map +1 -0
  74. package/lib/commonjs/models/NamedComponentStep.js +2 -0
  75. package/lib/commonjs/models/NamedComponentStep.js.map +1 -0
  76. package/lib/commonjs/models/NamedComponentValidatableData.js +2 -0
  77. package/lib/commonjs/models/NamedComponentValidatableData.js.map +1 -0
  78. package/lib/commonjs/models/PrimerComponentDataValidation.js +6 -0
  79. package/lib/commonjs/models/PrimerComponentDataValidation.js.map +1 -0
  80. package/lib/commonjs/models/PrimerError.js +2 -1
  81. package/lib/commonjs/models/PrimerError.js.map +1 -1
  82. package/lib/commonjs/models/banks/BanksCollectableData.js +6 -0
  83. package/lib/commonjs/models/banks/BanksCollectableData.js.map +1 -0
  84. package/lib/commonjs/models/banks/BanksSteps.js +6 -0
  85. package/lib/commonjs/models/banks/BanksSteps.js.map +1 -0
  86. package/lib/commonjs/models/klarna/KlarnaPaymentCategory.js +2 -0
  87. package/lib/commonjs/models/klarna/KlarnaPaymentCategory.js.map +1 -0
  88. package/lib/commonjs/models/klarna/KlarnaPaymentCollectableData.js +6 -0
  89. package/lib/commonjs/models/klarna/KlarnaPaymentCollectableData.js.map +1 -0
  90. package/lib/commonjs/models/klarna/KlarnaPaymentSteps.js +6 -0
  91. package/lib/commonjs/models/klarna/KlarnaPaymentSteps.js.map +1 -0
  92. package/lib/module/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.js +3 -0
  93. package/lib/module/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.js.map +1 -0
  94. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.js +96 -0
  95. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.js.map +1 -0
  96. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js +92 -0
  97. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.js.map +1 -0
  98. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js +4 -4
  99. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js.map +1 -1
  100. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.js +2 -0
  101. package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.js.map +1 -0
  102. package/lib/module/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js +3 -2
  103. package/lib/module/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js.map +1 -1
  104. package/lib/module/Primer.js +2 -1
  105. package/lib/module/Primer.js.map +1 -1
  106. package/lib/module/index.js +24 -0
  107. package/lib/module/index.js.map +1 -1
  108. package/lib/module/models/IssuingBank.js +2 -0
  109. package/lib/module/models/IssuingBank.js.map +1 -0
  110. package/lib/module/models/NamedComponentStep.js +2 -0
  111. package/lib/module/models/NamedComponentStep.js.map +1 -0
  112. package/lib/module/models/NamedComponentValidatableData.js +2 -0
  113. package/lib/module/models/NamedComponentValidatableData.js.map +1 -0
  114. package/lib/module/models/PrimerComponentDataValidation.js +2 -0
  115. package/lib/module/models/PrimerComponentDataValidation.js.map +1 -0
  116. package/lib/module/models/PrimerError.js +2 -1
  117. package/lib/module/models/PrimerError.js.map +1 -1
  118. package/lib/module/models/banks/BanksCollectableData.js +2 -0
  119. package/lib/module/models/banks/BanksCollectableData.js.map +1 -0
  120. package/lib/module/models/banks/BanksSteps.js +2 -0
  121. package/lib/module/models/banks/BanksSteps.js.map +1 -0
  122. package/lib/module/models/klarna/KlarnaPaymentCategory.js +2 -0
  123. package/lib/module/models/klarna/KlarnaPaymentCategory.js.map +1 -0
  124. package/lib/module/models/klarna/KlarnaPaymentCollectableData.js +2 -0
  125. package/lib/module/models/klarna/KlarnaPaymentCollectableData.js.map +1 -0
  126. package/lib/module/models/klarna/KlarnaPaymentSteps.js +2 -0
  127. package/lib/module/models/klarna/KlarnaPaymentSteps.js.map +1 -0
  128. package/lib/typescript/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.d.ts +2 -0
  129. package/lib/typescript/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.d.ts.map +1 -0
  130. package/lib/typescript/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.d.ts +54 -0
  131. package/lib/typescript/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.d.ts.map +1 -0
  132. package/lib/typescript/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.d.ts +50 -0
  133. package/lib/typescript/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.d.ts.map +1 -0
  134. package/lib/typescript/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.d.ts +3 -0
  135. package/lib/typescript/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.d.ts.map +1 -0
  136. package/lib/typescript/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.d.ts.map +1 -1
  137. package/lib/typescript/Primer.d.ts.map +1 -1
  138. package/lib/typescript/index.d.ts +26 -2
  139. package/lib/typescript/index.d.ts.map +1 -1
  140. package/lib/typescript/models/IssuingBank.d.ts +9 -0
  141. package/lib/typescript/models/IssuingBank.d.ts.map +1 -0
  142. package/lib/typescript/models/NamedComponentStep.d.ts +12 -0
  143. package/lib/typescript/models/NamedComponentStep.d.ts.map +1 -0
  144. package/lib/typescript/models/NamedComponentValidatableData.d.ts +12 -0
  145. package/lib/typescript/models/NamedComponentValidatableData.d.ts.map +1 -0
  146. package/lib/typescript/models/PrimerCheckoutPaymentMethodData.d.ts +1 -0
  147. package/lib/typescript/models/PrimerCheckoutPaymentMethodData.d.ts.map +1 -1
  148. package/lib/typescript/models/PrimerComponentDataValidation.d.ts +54 -0
  149. package/lib/typescript/models/PrimerComponentDataValidation.d.ts.map +1 -0
  150. package/lib/typescript/models/PrimerError.d.ts +2 -6
  151. package/lib/typescript/models/PrimerError.d.ts.map +1 -1
  152. package/lib/typescript/models/PrimerValidationError.d.ts +3 -3
  153. package/lib/typescript/models/PrimerValidationError.d.ts.map +1 -1
  154. package/lib/typescript/models/banks/BanksCollectableData.d.ts +23 -0
  155. package/lib/typescript/models/banks/BanksCollectableData.d.ts.map +1 -0
  156. package/lib/typescript/models/banks/BanksSteps.d.ts +20 -0
  157. package/lib/typescript/models/banks/BanksSteps.d.ts.map +1 -0
  158. package/lib/typescript/models/klarna/KlarnaPaymentCategory.d.ts +24 -0
  159. package/lib/typescript/models/klarna/KlarnaPaymentCategory.d.ts.map +1 -0
  160. package/lib/typescript/models/klarna/KlarnaPaymentCollectableData.d.ts +24 -0
  161. package/lib/typescript/models/klarna/KlarnaPaymentCollectableData.d.ts.map +1 -0
  162. package/lib/typescript/models/klarna/KlarnaPaymentSteps.d.ts +36 -0
  163. package/lib/typescript/models/klarna/KlarnaPaymentSteps.d.ts.map +1 -0
  164. package/package.json +1 -1
  165. package/src/HeadlessUniversalCheckout/Components/PrimerKlarnaPaymentView.tsx +5 -0
  166. package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.ts +161 -0
  167. package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/KlarnaManager.ts +147 -0
  168. package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.ts +4 -4
  169. package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/Utils/EventType.ts +10 -0
  170. package/src/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.ts +3 -2
  171. package/src/Primer.ts +2 -1
  172. package/src/index.tsx +62 -62
  173. package/src/models/IssuingBank.ts +8 -0
  174. package/src/models/NamedComponentStep.ts +11 -0
  175. package/src/models/NamedComponentValidatableData.ts +11 -0
  176. package/src/models/PrimerCheckoutPaymentMethodData.ts +6 -1
  177. package/src/models/PrimerComponentDataValidation.ts +60 -0
  178. package/src/models/PrimerError.ts +8 -14
  179. package/src/models/PrimerValidationError.ts +3 -3
  180. package/src/models/banks/BanksCollectableData.ts +25 -0
  181. package/src/models/banks/BanksSteps.ts +22 -0
  182. package/src/models/klarna/KlarnaPaymentCategory.ts +23 -0
  183. package/src/models/klarna/KlarnaPaymentCollectableData.ts +26 -0
  184. package/src/models/klarna/KlarnaPaymentSteps.ts +36 -0
  185. /package/ios/Sources/Headless Universal Checkout/Managers/{RNTAssetsManager.m → Assets Manager/RNTAssetsManager.m} +0 -0
  186. /package/ios/Sources/Headless Universal Checkout/Managers/{RNTAssetsManager.swift → Assets Manager/RNTAssetsManager.swift} +0 -0
@@ -0,0 +1,103 @@
1
+ package com.primerioreactnative.components.manager.klarna
2
+
3
+ import android.os.Handler
4
+ import android.os.Looper
5
+ import android.view.View
6
+ import android.view.ViewGroup
7
+ import android.widget.FrameLayout
8
+ import android.widget.TextView
9
+ import com.facebook.react.bridge.ReactApplicationContext
10
+ import com.facebook.react.uimanager.ThemedReactContext
11
+ import com.facebook.react.uimanager.ViewGroupManager
12
+ import io.primer.android.components.presentation.paymentMethods.nativeUi.klarna.PrimerKlarnaPaymentView
13
+ import java.lang.ref.WeakReference
14
+ import java.util.Timer
15
+ import java.util.TimerTask
16
+
17
+ class PrimerKlarnaPaymentViewManager(private val reactContext: ReactApplicationContext) :
18
+ ViewGroupManager<ViewGroup>() {
19
+ override fun getName() = REACT_CLASS
20
+
21
+ override fun createViewInstance(reactContext: ThemedReactContext) =
22
+ FrameLayout(reactContext).apply {
23
+ addView(
24
+ getPrimerKlarnaPaymentViewOrNull(this)
25
+ ?: PrimerKlarnaPaymentView(context).apply {
26
+ addView(TextView(context).apply { text = "Error loading Klarna payment view" })
27
+ }
28
+ )
29
+ alpha = 0f
30
+ }
31
+
32
+ private fun getPrimerKlarnaPaymentViewOrNull(parent: ViewGroup): View? {
33
+ val view = primerKlarnaPaymentView.get() ?: return null
34
+ val handler = Handler(Looper.getMainLooper())
35
+ val listener =
36
+ object : View.OnLayoutChangeListener {
37
+ private var timer: Timer? = null
38
+
39
+ override fun onLayoutChange(
40
+ v: View?,
41
+ left: Int,
42
+ top: Int,
43
+ right: Int,
44
+ bottom: Int,
45
+ oldLeft: Int,
46
+ oldTop: Int,
47
+ oldRight: Int,
48
+ oldBottom: Int
49
+ ) {
50
+ val listener = this
51
+ timer?.cancel()
52
+ timer =
53
+ Timer().apply {
54
+ schedule(
55
+ object : TimerTask() {
56
+ override fun run() {
57
+ timer?.cancel()
58
+ timer = null
59
+ handler.post(
60
+ Runnable {
61
+ view.removeOnLayoutChangeListener(listener)
62
+ // Re-layout parent once KlarnaPaymentView loads
63
+ layout(view)
64
+ parent.alpha = 1f
65
+ }
66
+ )
67
+ }
68
+ },
69
+ 300L
70
+ )
71
+ }
72
+ }
73
+ }
74
+ view.addOnLayoutChangeListener(listener)
75
+
76
+ return view
77
+ }
78
+
79
+ private fun layout(view: View) {
80
+ val oldX = view.getX().toInt()
81
+ val oldY = view.getY().toInt()
82
+ val parent = (view.parent as? View)
83
+ val fallbackWidth = parent?.width ?: Int.MAX_VALUE
84
+ val fallbackHeight = parent?.height ?: Int.MAX_VALUE
85
+ view.measure(
86
+ View.MeasureSpec.makeMeasureSpec(fallbackWidth, View.MeasureSpec.EXACTLY),
87
+ View.MeasureSpec.makeMeasureSpec(fallbackHeight, View.MeasureSpec.EXACTLY)
88
+ )
89
+ view.layout(oldX, oldY, oldX + fallbackWidth, oldY + fallbackHeight)
90
+ }
91
+
92
+ companion object {
93
+ private var primerKlarnaPaymentView: WeakReference<PrimerKlarnaPaymentView?> =
94
+ WeakReference(null)
95
+ private set
96
+
97
+ fun updatePrimerKlarnaPaymentView(view: PrimerKlarnaPaymentView) {
98
+ primerKlarnaPaymentView = WeakReference(view)
99
+ }
100
+
101
+ const val REACT_CLASS = "PrimerKlarnaPaymentView"
102
+ }
103
+ }
@@ -0,0 +1,334 @@
1
+ package com.primerioreactnative.components.manager.klarna
2
+
3
+ import androidx.lifecycle.LifecycleOwner
4
+ import androidx.lifecycle.ViewModelStoreOwner
5
+ import androidx.lifecycle.lifecycleScope
6
+ import com.facebook.react.bridge.Promise
7
+ import com.facebook.react.bridge.ReactApplicationContext
8
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
9
+ import com.facebook.react.bridge.ReactMethod
10
+ import com.facebook.react.bridge.ReadableMap
11
+ import com.facebook.react.modules.core.DeviceEventManagerModule
12
+ import com.primerioreactnative.PrimerRNViewModelStoreOwner
13
+ import com.primerioreactnative.components.events.PrimerHeadlessUniversalCheckoutComponentEvent
14
+ import com.primerioreactnative.datamodels.ErrorTypeRN
15
+ import com.primerioreactnative.datamodels.PrimerErrorRN
16
+ import com.primerioreactnative.datamodels.PrimerValidationErrorRN
17
+ import com.primerioreactnative.datamodels.klarna.KlarnaPaymentCategoryRN
18
+ import com.primerioreactnative.extensions.klarna.toFinalizePaymentRN
19
+ import com.primerioreactnative.extensions.klarna.toKlarnaPaymentCategory
20
+ import com.primerioreactnative.extensions.klarna.toPaymentOptionsRN
21
+ import com.primerioreactnative.extensions.klarna.toPaymentSessionAuthorizedRN
22
+ import com.primerioreactnative.extensions.klarna.toPaymentSessionCreatedRN
23
+ import com.primerioreactnative.extensions.klarna.toPaymentSessionFinalizedRN
24
+ import com.primerioreactnative.extensions.klarna.toPaymentViewLoadedRN
25
+ import com.primerioreactnative.extensions.toPrimerErrorRN
26
+ import com.primerioreactnative.utils.errorTo
27
+ import com.primerioreactnative.utils.toWritableArray
28
+ import com.primerioreactnative.utils.toWritableMap
29
+ import io.primer.android.PrimerSessionIntent
30
+ import io.primer.android.components.manager.core.composable.PrimerValidationStatus
31
+ import io.primer.android.components.manager.klarna.PrimerHeadlessUniversalCheckoutKlarnaManager
32
+ import io.primer.android.components.presentation.paymentMethods.nativeUi.klarna.composable.KlarnaComponent
33
+ import io.primer.android.components.presentation.paymentMethods.nativeUi.klarna.models.KlarnaPaymentCollectableData
34
+ import io.primer.android.components.presentation.paymentMethods.nativeUi.klarna.models.KlarnaPaymentStep
35
+ import kotlinx.coroutines.CoroutineScope
36
+ import kotlinx.coroutines.Dispatchers
37
+ import kotlinx.coroutines.Job
38
+ import kotlinx.coroutines.SupervisorJob
39
+ import kotlinx.coroutines.coroutineScope
40
+ import kotlinx.coroutines.flow.collectLatest
41
+ import kotlinx.coroutines.launch
42
+ import kotlinx.serialization.encodeToString
43
+ import kotlinx.serialization.json.Json
44
+ import org.json.JSONArray
45
+ import org.json.JSONObject
46
+
47
+ class PrimerRNHeadlessUniversalCheckoutKlarnaComponent(
48
+ private val reactContext: ReactApplicationContext
49
+ ) : ReactContextBaseJavaModule(reactContext) {
50
+
51
+ override fun getName(): String = "RNTPrimerHeadlessUniversalCheckoutKlarnaComponent"
52
+
53
+ private var job: Job? = null
54
+ private var viewModelStoreOwner: ViewModelStoreOwner? = null
55
+ private var klarnaComponent: KlarnaComponent? = null
56
+
57
+ @ReactMethod
58
+ fun configure(intent: String, promise: Promise) {
59
+ val primerSessionIntent = PrimerSessionIntent.values().firstOrNull { intent.equals(it.name, true) }
60
+ if (primerSessionIntent == null) {
61
+ val exception = PrimerErrorRN(
62
+ errorId = ErrorTypeRN.NativeBridgeFailed.errorId,
63
+ description = "Invalid value for 'intent'.",
64
+ diagnosticsId = null,
65
+ recoverySuggestion = "'intent' can be 'CHECKOUT' or 'VAULT'."
66
+ )
67
+ promise.reject(exception.errorId, exception.description)
68
+ return
69
+ }
70
+
71
+ val currentViewModelStoreOwner =
72
+ reactContext.currentActivity as? ViewModelStoreOwner
73
+ ?: run { PrimerRNViewModelStoreOwner() }
74
+
75
+ viewModelStoreOwner = currentViewModelStoreOwner
76
+ klarnaComponent = PrimerHeadlessUniversalCheckoutKlarnaManager(currentViewModelStoreOwner)
77
+ .provideKlarnaComponent(primerSessionIntent)
78
+
79
+ val lifecycleScope =
80
+ (reactContext.currentActivity as? LifecycleOwner)?.lifecycleScope
81
+ ?: CoroutineScope(SupervisorJob() + Dispatchers.Main)
82
+
83
+ job =
84
+ lifecycleScope.launch {
85
+ if (klarnaComponent == null) {
86
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo UNINITIALIZED_ERROR
87
+ promise.reject(exception.errorId, exception.description)
88
+ } else {
89
+ coroutineScope {
90
+ launch { configureStepListener() }
91
+
92
+ launch { configureValidationListener() }
93
+
94
+ launch { configureErrorListener() }
95
+ promise.resolve(null)
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ @ReactMethod
102
+ fun start(promise: Promise) {
103
+ if (klarnaComponent == null) {
104
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo UNINITIALIZED_ERROR
105
+ promise.reject(exception.errorId, exception.description)
106
+ } else {
107
+ klarnaComponent?.start()
108
+ promise.resolve(null)
109
+ }
110
+ }
111
+
112
+ @ReactMethod
113
+ fun submit(promise: Promise) {
114
+ if (klarnaComponent == null) {
115
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo UNINITIALIZED_ERROR
116
+ promise.reject(exception.errorId, exception.description)
117
+ } else {
118
+ klarnaComponent?.submit()
119
+ promise.resolve(null)
120
+ }
121
+ }
122
+
123
+ private suspend fun configureErrorListener() {
124
+ klarnaComponent?.componentError?.collectLatest { error ->
125
+ sendEvent(
126
+ PrimerHeadlessUniversalCheckoutComponentEvent.ON_ERROR.eventName,
127
+ JSONObject().apply {
128
+ put(
129
+ "errors",
130
+ JSONArray().apply {
131
+ put(JSONObject(json.encodeToString(error.toPrimerErrorRN())))
132
+ }
133
+ )
134
+ }
135
+ )
136
+ }
137
+ }
138
+
139
+ private suspend fun configureStepListener() {
140
+ klarnaComponent?.componentStep?.collectLatest { klarnaStep ->
141
+ when (klarnaStep) {
142
+ is KlarnaPaymentStep.PaymentSessionCreated -> {
143
+ sendEvent(
144
+ name = PrimerHeadlessUniversalCheckoutComponentEvent.ON_STEP.eventName,
145
+ data = JSONObject(
146
+ json.encodeToString(klarnaStep.toPaymentSessionCreatedRN())
147
+ )
148
+ )
149
+ }
150
+
151
+ is KlarnaPaymentStep.PaymentViewLoaded -> {
152
+ PrimerKlarnaPaymentViewManager.updatePrimerKlarnaPaymentView(klarnaStep.paymentView)
153
+
154
+ sendEvent(
155
+ name = PrimerHeadlessUniversalCheckoutComponentEvent.ON_STEP.eventName,
156
+ data = JSONObject(json.encodeToString(klarnaStep.toPaymentViewLoadedRN()))
157
+ )
158
+ }
159
+ is KlarnaPaymentStep.PaymentSessionAuthorized -> {
160
+ sendEvent(
161
+ name = PrimerHeadlessUniversalCheckoutComponentEvent.ON_STEP.eventName,
162
+ data = JSONObject(json.encodeToString(klarnaStep.toPaymentSessionAuthorizedRN()))
163
+ )
164
+ }
165
+ is KlarnaPaymentStep.PaymentSessionFinalized -> {
166
+ sendEvent(
167
+ name = PrimerHeadlessUniversalCheckoutComponentEvent.ON_STEP.eventName,
168
+ data = JSONObject(json.encodeToString(klarnaStep.toPaymentSessionFinalizedRN())
169
+ )
170
+ )
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ private suspend fun configureValidationListener() {
177
+ klarnaComponent?.componentValidationStatus?.collectLatest { validationStatus ->
178
+ when (validationStatus) {
179
+ is PrimerValidationStatus.Validating -> {
180
+ sendEvent(
181
+ PrimerHeadlessUniversalCheckoutComponentEvent.ON_VALIDATING.eventName,
182
+ JSONObject().apply {
183
+ putData(validationStatus.collectableData as KlarnaPaymentCollectableData)
184
+ }
185
+ )
186
+ }
187
+ is PrimerValidationStatus.Invalid -> {
188
+ sendEvent(
189
+ PrimerHeadlessUniversalCheckoutComponentEvent.ON_IN_VALID.eventName,
190
+ JSONObject().apply {
191
+ putData(validationStatus.collectableData as KlarnaPaymentCollectableData)
192
+ put(
193
+ "errors",
194
+ JSONArray(
195
+ validationStatus.validationErrors.map {
196
+ JSONObject(
197
+ json.encodeToString(
198
+ PrimerValidationErrorRN(
199
+ it.errorId,
200
+ it.description,
201
+ it.diagnosticsId,
202
+ )
203
+ )
204
+ )
205
+ }
206
+ )
207
+ )
208
+ }
209
+ )
210
+ }
211
+ is PrimerValidationStatus.Valid -> {
212
+ sendEvent(
213
+ PrimerHeadlessUniversalCheckoutComponentEvent.ON_VALID.eventName,
214
+ JSONObject().apply {
215
+ putData(validationStatus.collectableData as KlarnaPaymentCollectableData)
216
+ }
217
+ )
218
+ }
219
+ is PrimerValidationStatus.Error -> {
220
+ sendEvent(
221
+ PrimerHeadlessUniversalCheckoutComponentEvent.ON_VALIDATION_ERROR.eventName,
222
+ JSONObject().apply {
223
+ putData(validationStatus.collectableData as KlarnaPaymentCollectableData)
224
+ put(
225
+ "errors",
226
+ JSONArray().apply {
227
+ put(JSONObject(json.encodeToString(validationStatus.error.toPrimerErrorRN())))
228
+ }
229
+ )
230
+ }
231
+ )
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ private fun JSONObject.putData(collectableData: KlarnaPaymentCollectableData) {
238
+ put(
239
+ "data",
240
+ JSONObject(
241
+ json.encodeToString(
242
+ when (collectableData) {
243
+ is KlarnaPaymentCollectableData.PaymentOptions ->
244
+ collectableData.toPaymentOptionsRN()
245
+ is KlarnaPaymentCollectableData.FinalizePayment ->
246
+ collectableData.toFinalizePaymentRN()
247
+ }
248
+ )
249
+ )
250
+ )
251
+ }
252
+
253
+ @ReactMethod fun addListener(eventName: String?) = Unit
254
+
255
+ @ReactMethod fun removeListeners(count: Int?) = Unit
256
+
257
+ @ReactMethod
258
+ fun onSetPaymentOptions(readableMap: ReadableMap, promise: Promise) {
259
+ val returnIntentUrl = readableMap.getString("returnIntentUrl")
260
+ val paymentCategory = readableMap.getMap("paymentCategory") as ReadableMap
261
+ val json = Json { ignoreUnknownKeys = true }
262
+ val KlarnaPaymentCategoryRN =
263
+ json.decodeFromString<KlarnaPaymentCategoryRN>(
264
+ Json.encodeToString(paymentCategory.toHashMap() as Map<String, String>)
265
+ )
266
+
267
+ val activity = getCurrentActivity()
268
+
269
+ if (activity == null) {
270
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo MISSING_ACTIVITY_ERROR
271
+ promise.reject(exception.errorId, exception.description)
272
+ } else if (klarnaComponent == null) {
273
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo UNINITIALIZED_ERROR
274
+ promise.reject(exception.errorId, exception.description)
275
+ } else {
276
+ klarnaComponent?.updateCollectedData(
277
+ KlarnaPaymentCollectableData.PaymentOptions(
278
+ context = activity,
279
+ returnIntentUrl = requireNotNull(returnIntentUrl),
280
+ paymentCategory = KlarnaPaymentCategoryRN.toKlarnaPaymentCategory()
281
+ )
282
+ )
283
+ promise.resolve(null)
284
+ }
285
+ }
286
+
287
+ @ReactMethod
288
+ fun onFinalizePayment(promise: Promise) {
289
+ if (klarnaComponent == null) {
290
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo UNINITIALIZED_ERROR
291
+ promise.reject(exception.errorId, exception.description)
292
+ } else {
293
+ klarnaComponent?.updateCollectedData(KlarnaPaymentCollectableData.FinalizePayment)
294
+ promise.resolve(null)
295
+ }
296
+ }
297
+
298
+ private fun sendEvent(name: String, data: JSONObject?) {
299
+ reactApplicationContext
300
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
301
+ .emit(name, data.toWritableMap())
302
+ }
303
+
304
+ private fun sendEvent(name: String, data: JSONArray?) {
305
+ reactApplicationContext
306
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
307
+ .emit(name, data.toWritableArray())
308
+ }
309
+
310
+ @ReactMethod
311
+ fun cleanUp(promise: Promise) {
312
+ job?.cancel()
313
+ job = null
314
+ klarnaComponent = null
315
+ viewModelStoreOwner?.viewModelStore?.clear()
316
+ promise.resolve(null)
317
+ }
318
+
319
+ private companion object {
320
+ const val UNINITIALIZED_ERROR =
321
+ """
322
+ The KlarnaComponent has not been initialized.
323
+ Make sure you have initialized the `KlarnaComponent` first.
324
+ """
325
+ const val MISSING_ACTIVITY_ERROR =
326
+ """
327
+ Could not retrieve running activity from context.
328
+ """
329
+
330
+ val TAG = PrimerRNHeadlessUniversalCheckoutKlarnaComponent::class.simpleName
331
+
332
+ val json by lazy { Json { encodeDefaults = true } }
333
+ }
334
+ }
@@ -52,10 +52,11 @@ internal class PrimerRNHeadlessUniversalCheckoutNativeUiManager(
52
52
 
53
53
  if (::nativeUiManager.isInitialized.not()) {
54
54
  val exception = PrimerErrorRN(
55
- ErrorTypeRN.NativeBridgeFailed.errorId,
56
- "The NativeUIManager has not been initialized.",
57
- null,
58
- "Initialize the NativeUIManager by calling the configure function" +
55
+ errorId = ErrorTypeRN.NativeBridgeFailed.errorId,
56
+ errorCode = null,
57
+ description = "The NativeUIManager has not been initialized.",
58
+ diagnosticsId = null,
59
+ recoverySuggestion = "Initialize the NativeUIManager by calling the configure function" +
59
60
  " and providing a payment method type."
60
61
  )
61
62
  promise.reject(exception.errorId, exception.description)
@@ -63,10 +64,11 @@ internal class PrimerRNHeadlessUniversalCheckoutNativeUiManager(
63
64
  .firstOrNull { intentStr.equals(it.name, true) } == null
64
65
  ) {
65
66
  val exception = PrimerErrorRN(
66
- ErrorTypeRN.NativeBridgeFailed.errorId,
67
- "Invalid value for 'intent'.",
68
- null,
69
- "'intent' can be 'CHECKOUT' or 'VAULT'."
67
+ errorId = ErrorTypeRN.NativeBridgeFailed.errorId,
68
+ errorCode = null,
69
+ description = "Invalid value for 'intent'.",
70
+ diagnosticsId = null,
71
+ recoverySuggestion = "'intent' can be 'CHECKOUT' or 'VAULT'."
70
72
  )
71
73
  promise.reject(exception.errorId, exception.description)
72
74
  } else {
@@ -12,8 +12,8 @@ import com.primerioreactnative.components.datamodels.manager.raw.retailOutlets.t
12
12
  import com.primerioreactnative.components.events.PrimerHeadlessUniversalCheckoutEvent
13
13
  import com.primerioreactnative.datamodels.ErrorTypeRN
14
14
  import com.primerioreactnative.datamodels.PrimerErrorRN
15
- import com.primerioreactnative.utils.convertJsonToMap
16
15
  import com.primerioreactnative.utils.errorTo
16
+ import com.primerioreactnative.utils.toWritableMap
17
17
  import io.primer.android.ExperimentalPrimerApi
18
18
  import io.primer.android.components.SdkUninitializedException
19
19
  import io.primer.android.components.domain.exception.UnsupportedPaymentMethodManagerException
@@ -185,7 +185,7 @@ internal class PrimerRNHeadlessUniversalCheckoutRawManager(
185
185
  }
186
186
 
187
187
  private fun prepareData(data: JSONObject?): WritableMap {
188
- return data?.let { convertJsonToMap(data) } ?: Arguments.createMap()
188
+ return data.toWritableMap()
189
189
  }
190
190
 
191
191
  private fun onError(exception: PrimerErrorRN) {
@@ -11,8 +11,8 @@ import com.primerioreactnative.components.datamodels.manager.vault.toPrimerRNVal
11
11
  import com.primerioreactnative.components.datamodels.manager.vault.toPrimerRNVaultedPaymentMethod
12
12
  import com.primerioreactnative.components.datamodels.manager.vault.toPrimerVaultedCardAdditionalData
13
13
  import com.primerioreactnative.datamodels.ErrorTypeRN
14
- import com.primerioreactnative.utils.convertJsonToMap
15
14
  import com.primerioreactnative.utils.errorTo
15
+ import com.primerioreactnative.utils.toWritableMap
16
16
  import io.primer.android.components.manager.vault.PrimerHeadlessUniversalCheckoutVaultManager
17
17
  import io.primer.android.components.manager.vault.PrimerHeadlessUniversalCheckoutVaultManagerInterface
18
18
  import kotlinx.coroutines.CoroutineScope
@@ -51,15 +51,13 @@ class PrimerRNHeadlessUniversalCheckoutVaultManager(
51
51
  vaultScope.launch {
52
52
  nativeVaultManager.fetchVaultedPaymentMethods().onSuccess { vaultedPaymentMethods ->
53
53
  promise.resolve(
54
- convertJsonToMap(
55
- JSONObject(
54
+ JSONObject(
56
55
  Json.encodeToString(
57
56
  PrimerRNVaultedPaymentMethods(vaultedPaymentMethods.map {
58
57
  it.toPrimerRNVaultedPaymentMethod()
59
58
  })
60
59
  )
61
- )
62
- )
60
+ ).toWritableMap()
63
61
  )
64
62
  }.onFailure { throwable ->
65
63
  val exception =
@@ -100,15 +98,13 @@ class PrimerRNHeadlessUniversalCheckoutVaultManager(
100
98
  additionalData.toPrimerVaultedCardAdditionalData()
101
99
  ).onSuccess { errors ->
102
100
  promise.resolve(
103
- convertJsonToMap(
104
- JSONObject(
101
+ JSONObject(
105
102
  Json.encodeToString(
106
103
  PrimerRNValidationErrors(errors.map {
107
104
  it.toPrimerRNValidationError()
108
105
  })
109
106
  )
110
- )
111
- )
107
+ ).toWritableMap()
112
108
  )
113
109
  }.onFailure { throwable ->
114
110
  promise.reject(
@@ -0,0 +1,7 @@
1
+ package com.primerioreactnative.datamodels
2
+
3
+ import kotlinx.serialization.Serializable
4
+
5
+ internal interface NamedComponentStep {
6
+ val stepName: String
7
+ }
@@ -0,0 +1,7 @@
1
+ package com.primerioreactnative.datamodels
2
+
3
+ import kotlinx.serialization.Serializable
4
+
5
+ internal interface NamedComponentValidatableData {
6
+ val validatableDataName: String
7
+ }
@@ -5,6 +5,7 @@ import kotlinx.serialization.Serializable
5
5
  @Serializable
6
6
  data class PrimerErrorRN(
7
7
  val errorId: String? = null,
8
+ val errorCode: String? = null,
8
9
  val description: String? = null,
9
10
  val diagnosticsId: String? = null,
10
11
  val recoverySuggestion: String? = null
@@ -19,3 +20,10 @@ enum class ErrorTypeRN(val errorId: String) {
19
20
  VaultManagerDeleteFailed("vaulted-manager-delete-failed"),
20
21
  InvalidVaultedPaymentMethodId("invalid-vaulted-payment-method-id")
21
22
  }
23
+
24
+ @Serializable
25
+ data class PrimerValidationErrorRN(
26
+ val errorId: String? = null,
27
+ val description: String? = null,
28
+ val diagnosticsId: String? = null,
29
+ )
@@ -0,0 +1,11 @@
1
+ package com.primerioreactnative.datamodels
2
+
3
+ import kotlinx.serialization.Serializable
4
+
5
+ @Serializable
6
+ internal data class PrimerIssuingBankRN(
7
+ val id: String,
8
+ val name: String,
9
+ val disabled: Boolean,
10
+ val iconUrl: String
11
+ )
@@ -3,4 +3,4 @@ package com.primerioreactnative.datamodels
3
3
  import kotlinx.serialization.Serializable
4
4
 
5
5
  @Serializable
6
- data class PrimerPaymentMethodDataRN(val paymentMethodType: String)
6
+ data class PrimerPaymentMethodDataRN(val paymentMethodType: String, val paymentMethod: String)
@@ -0,0 +1,17 @@
1
+ package com.primerioreactnative.datamodels.banks
2
+
3
+ import com.primerioreactnative.datamodels.NamedComponentValidatableData
4
+ import kotlinx.serialization.Serializable
5
+
6
+ @Serializable
7
+ internal sealed interface BanksCollectableDataRN : NamedComponentValidatableData {
8
+ @Serializable
9
+ data class FilterRN(val text: String) : BanksCollectableDataRN {
10
+ override val validatableDataName: String = "bankListFilter"
11
+ }
12
+
13
+ @Serializable
14
+ data class BankIdRN(val id: String) : BanksCollectableDataRN {
15
+ override val validatableDataName: String = "bankId"
16
+ }
17
+ }
@@ -0,0 +1,20 @@
1
+ package com.primerioreactnative.datamodels.banks
2
+
3
+ import kotlinx.serialization.Serializable
4
+ import com.primerioreactnative.datamodels.NamedComponentStep
5
+ import com.primerioreactnative.datamodels.PrimerIssuingBankRN
6
+
7
+ @Serializable
8
+ internal sealed interface BanksStepRN : NamedComponentStep {
9
+ @Serializable
10
+ class LoadingRN : BanksStepRN {
11
+ override val stepName: String = "banksLoading"
12
+ }
13
+
14
+ @Serializable
15
+ data class BanksRetrievedRN(
16
+ val banks: List<PrimerIssuingBankRN>
17
+ ) : BanksStepRN {
18
+ override val stepName: String = "banksRetrieved"
19
+ }
20
+ }
@@ -0,0 +1,8 @@
1
+ package com.primerioreactnative.datamodels.extensions.banks
2
+
3
+ import io.primer.android.components.manager.banks.composable.BanksCollectableData
4
+ import com.primerioreactnative.datamodels.banks.BanksCollectableDataRN
5
+
6
+ internal fun BanksCollectableData.BankId.toBankIdRN() = BanksCollectableDataRN.BankIdRN(id)
7
+
8
+ internal fun BanksCollectableData.Filter.toFilterRN() = BanksCollectableDataRN.FilterRN(text)
@@ -0,0 +1,11 @@
1
+ package com.primerioreactnative.datamodels.extensions.banks
2
+
3
+ import io.primer.android.components.manager.banks.composable.BanksCollectableData
4
+ import io.primer.android.components.manager.banks.composable.BanksStep
5
+ import com.primerioreactnative.datamodels.banks.BanksStepRN
6
+ import com.primerioreactnative.extensions.toPrimerIssuingBankRN
7
+
8
+
9
+ internal fun BanksStep.Loading.toLoadingRN() = BanksStepRN.LoadingRN()
10
+
11
+ internal fun BanksStep.BanksRetrieved.toBanksRetrievedRN() = BanksStepRN.BanksRetrievedRN(banks = banks.map { it.toPrimerIssuingBankRN() })
@@ -0,0 +1,11 @@
1
+ package com.primerioreactnative.datamodels.klarna
2
+
3
+ import kotlinx.serialization.Serializable
4
+
5
+ @Serializable
6
+ internal data class KlarnaPaymentCategoryRN(
7
+ val identifier: String,
8
+ val name: String,
9
+ val descriptiveAssetUrl: String,
10
+ val standardAssetUrl: String
11
+ )