react-native-klarna-inapp-sdk 2.4.10 → 2.5.1

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 (167) hide show
  1. package/android/build.gradle +3 -1
  2. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/KlarnaMobileSDKPackage.java +5 -1
  3. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/checkout/KlarnaCheckoutViewManager.java +4 -10
  4. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/WebViewResizeObserver.java +28 -0
  5. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/event/ComponentEventSender.java +5 -1
  6. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/ui/ResizeObserverWrapperView.java +2 -2
  7. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/ui/WrapperView.java +2 -2
  8. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/ui/YogaLayoutHelper.java +39 -0
  9. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/expresscheckout/KlarnaExpressCheckoutViewCallback.kt +30 -0
  10. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/expresscheckout/KlarnaExpressCheckoutViewEventSender.kt +80 -0
  11. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/expresscheckout/KlarnaExpressCheckoutViewManager.java +544 -0
  12. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/osm/KlarnaOSMViewEventHandler.java +30 -0
  13. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/osm/KlarnaOSMViewEventSender.java +64 -0
  14. package/android/src/main/java/com/klarna/mobile/sdk/reactnative/osm/KlarnaOSMViewManager.java +356 -0
  15. package/android/src/newarch/java/com/klarna/mobile/sdk/reactnative/spec/RNKlarnaExpressCheckoutViewSpec.java +31 -0
  16. package/android/src/newarch/java/com/klarna/mobile/sdk/reactnative/spec/RNKlarnaOSMViewSpec.java +31 -0
  17. package/android/src/oldarch/java/com/klarna/mobile/sdk/reactnative/spec/RNKlarnaExpressCheckoutViewSpec.java +36 -0
  18. package/android/src/oldarch/java/com/klarna/mobile/sdk/reactnative/spec/RNKlarnaOSMViewSpec.java +32 -0
  19. package/android/src/test/java/com/klarna/mobile/sdk/reactnative/KlarnaMobileSDKPackageTest.java +5 -1
  20. package/android/src/test/java/com/klarna/mobile/sdk/reactnative/common/ui/YogaLayoutHelperTest.java +79 -0
  21. package/android/src/test/java/com/klarna/mobile/sdk/reactnative/expresscheckout/KlarnaExpressCheckoutViewManagerTest.java +259 -0
  22. package/android/src/test/java/com/klarna/mobile/sdk/reactnative/osm/KlarnaOSMViewEventHandlerTest.java +136 -0
  23. package/android/src/test/java/com/klarna/mobile/sdk/reactnative/osm/KlarnaOSMViewEventSenderTest.java +184 -0
  24. package/android/src/test/java/com/klarna/mobile/sdk/reactnative/osm/KlarnaOSMViewManagerTest.java +385 -0
  25. package/ios/RNKlarnaMobileSDK.xcodeproj/project.pbxproj +110 -52
  26. package/ios/Sources/KlarnaExpressCheckoutViewManager.h +5 -0
  27. package/ios/Sources/KlarnaExpressCheckoutViewManager.mm +39 -0
  28. package/ios/Sources/KlarnaOSMViewManager.h +5 -0
  29. package/ios/Sources/KlarnaOSMViewManager.mm +59 -0
  30. package/ios/Sources/view/KlarnaExpressCheckoutButtonDelegateProxy.swift +145 -0
  31. package/ios/Sources/view/KlarnaExpressCheckoutViewWrapper.h +41 -0
  32. package/ios/Sources/view/KlarnaOSMViewWrapper.h +48 -0
  33. package/ios/Sources/view/newarch/KlarnaExpressCheckoutViewWrapper.mm +228 -0
  34. package/ios/Sources/view/newarch/KlarnaOSMViewWrapper.mm +294 -0
  35. package/ios/Sources/view/newarch/KlarnaStandaloneWebViewWrapper.mm +20 -13
  36. package/ios/Sources/view/oldarch/KlarnaExpressCheckoutViewWrapper.mm +222 -0
  37. package/ios/Sources/view/oldarch/KlarnaOSMViewWrapper.mm +273 -0
  38. package/ios/Sources/view/oldarch/KlarnaStandaloneWebViewWrapper.mm +11 -13
  39. package/ios/Tests/KlarnaExpressCheckoutViewWrapperTests.m +391 -0
  40. package/ios/Tests/KlarnaOSMViewWrapperTests.m +450 -0
  41. package/ios/Tests/KlarnaStandaloneWebViewWrapperTests.m +105 -0
  42. package/lib/commonjs/KlarnaCheckoutView.js +2 -4
  43. package/lib/commonjs/KlarnaCheckoutView.js.map +1 -1
  44. package/lib/commonjs/KlarnaExpressCheckoutView.js +73 -0
  45. package/lib/commonjs/KlarnaExpressCheckoutView.js.map +1 -0
  46. package/lib/commonjs/KlarnaOSMView.js +92 -0
  47. package/lib/commonjs/KlarnaOSMView.js.map +1 -0
  48. package/lib/commonjs/KlarnaPaymentView.js +32 -55
  49. package/lib/commonjs/KlarnaPaymentView.js.map +1 -1
  50. package/lib/commonjs/KlarnaSignInSDK.js +1 -1
  51. package/lib/commonjs/KlarnaSignInSDK.js.map +1 -1
  52. package/lib/commonjs/KlarnaStandaloneWebView.js +2 -4
  53. package/lib/commonjs/KlarnaStandaloneWebView.js.map +1 -1
  54. package/lib/commonjs/index.js +128 -0
  55. package/lib/commonjs/index.js.map +1 -1
  56. package/lib/commonjs/specs/KlarnaCheckoutViewNativeComponent.js +3 -5
  57. package/lib/commonjs/specs/KlarnaCheckoutViewNativeComponent.js.map +1 -1
  58. package/lib/commonjs/specs/KlarnaExpressCheckoutViewNativeComponent.js +10 -0
  59. package/lib/commonjs/specs/KlarnaExpressCheckoutViewNativeComponent.js.map +1 -0
  60. package/lib/commonjs/specs/KlarnaOSMViewNativeComponent.js +14 -0
  61. package/lib/commonjs/specs/KlarnaOSMViewNativeComponent.js.map +1 -0
  62. package/lib/commonjs/specs/KlarnaPaymentViewNativeComponent.js +3 -5
  63. package/lib/commonjs/specs/KlarnaPaymentViewNativeComponent.js.map +1 -1
  64. package/lib/commonjs/specs/KlarnaStandaloneWebViewNativeComponent.js +3 -5
  65. package/lib/commonjs/specs/KlarnaStandaloneWebViewNativeComponent.js.map +1 -1
  66. package/lib/commonjs/specs/NativeKlarnaSignIn.js +1 -2
  67. package/lib/commonjs/specs/NativeKlarnaSignIn.js.map +1 -1
  68. package/lib/commonjs/types/button/KlarnaButtonShape.js +13 -0
  69. package/lib/commonjs/types/button/KlarnaButtonShape.js.map +1 -0
  70. package/lib/commonjs/types/button/KlarnaButtonStyle.js +12 -0
  71. package/lib/commonjs/types/button/KlarnaButtonStyle.js.map +1 -0
  72. package/lib/commonjs/types/button/KlarnaButtonTheme.js +13 -0
  73. package/lib/commonjs/types/button/KlarnaButtonTheme.js.map +1 -0
  74. package/lib/commonjs/types/common/KlarnaEnvironment.js +1 -2
  75. package/lib/commonjs/types/common/KlarnaEnvironment.js.map +1 -1
  76. package/lib/commonjs/types/common/KlarnaExpressCheckoutSessionOptions.js +8 -0
  77. package/lib/commonjs/types/common/KlarnaExpressCheckoutSessionOptions.js.map +1 -0
  78. package/lib/commonjs/types/common/KlarnaMobileSDKError.js.map +1 -1
  79. package/lib/commonjs/types/common/KlarnaOSMPlacementKey.js +2 -0
  80. package/lib/commonjs/types/common/KlarnaOSMPlacementKey.js.map +1 -0
  81. package/lib/commonjs/types/common/KlarnaProductEvent.js.map +1 -1
  82. package/lib/commonjs/types/common/KlarnaRegion.js +1 -2
  83. package/lib/commonjs/types/common/KlarnaRegion.js.map +1 -1
  84. package/lib/commonjs/types/common/KlarnaTheme.js +13 -0
  85. package/lib/commonjs/types/common/KlarnaTheme.js.map +1 -0
  86. package/lib/module/KlarnaCheckoutView.js.map +1 -1
  87. package/lib/module/KlarnaExpressCheckoutView.js +64 -0
  88. package/lib/module/KlarnaExpressCheckoutView.js.map +1 -0
  89. package/lib/module/KlarnaOSMView.js +84 -0
  90. package/lib/module/KlarnaOSMView.js.map +1 -0
  91. package/lib/module/KlarnaPaymentView.js +30 -51
  92. package/lib/module/KlarnaPaymentView.js.map +1 -1
  93. package/lib/module/KlarnaSignInSDK.js.map +1 -1
  94. package/lib/module/KlarnaStandaloneWebView.js.map +1 -1
  95. package/lib/module/index.js +11 -0
  96. package/lib/module/index.js.map +1 -1
  97. package/lib/module/specs/KlarnaCheckoutViewNativeComponent.js.map +1 -1
  98. package/lib/module/specs/KlarnaExpressCheckoutViewNativeComponent.js +3 -0
  99. package/lib/module/specs/KlarnaExpressCheckoutViewNativeComponent.js.map +1 -0
  100. package/lib/module/specs/KlarnaOSMViewNativeComponent.js +7 -0
  101. package/lib/module/specs/KlarnaOSMViewNativeComponent.js.map +1 -0
  102. package/lib/module/specs/KlarnaPaymentViewNativeComponent.js.map +1 -1
  103. package/lib/module/specs/KlarnaStandaloneWebViewNativeComponent.js.map +1 -1
  104. package/lib/module/specs/NativeKlarnaSignIn.js.map +1 -1
  105. package/lib/module/types/button/KlarnaButtonShape.js +7 -0
  106. package/lib/module/types/button/KlarnaButtonShape.js.map +1 -0
  107. package/lib/module/types/button/KlarnaButtonStyle.js +6 -0
  108. package/lib/module/types/button/KlarnaButtonStyle.js.map +1 -0
  109. package/lib/module/types/button/KlarnaButtonTheme.js +7 -0
  110. package/lib/module/types/button/KlarnaButtonTheme.js.map +1 -0
  111. package/lib/module/types/common/KlarnaEnvironment.js.map +1 -1
  112. package/lib/module/types/common/KlarnaExpressCheckoutSessionOptions.js +2 -0
  113. package/lib/module/types/common/KlarnaExpressCheckoutSessionOptions.js.map +1 -0
  114. package/lib/module/types/common/KlarnaMobileSDKError.js.map +1 -1
  115. package/lib/module/types/common/KlarnaOSMPlacementKey.js +2 -0
  116. package/lib/module/types/common/KlarnaOSMPlacementKey.js.map +1 -0
  117. package/lib/module/types/common/KlarnaProductEvent.js.map +1 -1
  118. package/lib/module/types/common/KlarnaRegion.js.map +1 -1
  119. package/lib/module/types/common/KlarnaTheme.js +7 -0
  120. package/lib/module/types/common/KlarnaTheme.js.map +1 -0
  121. package/lib/typescript/KlarnaCheckoutView.d.ts.map +1 -1
  122. package/lib/typescript/KlarnaExpressCheckoutView.d.ts +47 -0
  123. package/lib/typescript/KlarnaExpressCheckoutView.d.ts.map +1 -0
  124. package/lib/typescript/KlarnaOSMView.d.ts +36 -0
  125. package/lib/typescript/KlarnaOSMView.d.ts.map +1 -0
  126. package/lib/typescript/KlarnaPaymentView.d.ts.map +1 -1
  127. package/lib/typescript/KlarnaStandaloneWebView.d.ts.map +1 -1
  128. package/lib/typescript/index.d.ts +11 -0
  129. package/lib/typescript/index.d.ts.map +1 -1
  130. package/lib/typescript/specs/KlarnaCheckoutViewNativeComponent.d.ts.map +1 -1
  131. package/lib/typescript/specs/KlarnaExpressCheckoutViewNativeComponent.d.ts +45 -0
  132. package/lib/typescript/specs/KlarnaExpressCheckoutViewNativeComponent.d.ts.map +1 -0
  133. package/lib/typescript/specs/KlarnaOSMViewNativeComponent.d.ts +35 -0
  134. package/lib/typescript/specs/KlarnaOSMViewNativeComponent.d.ts.map +1 -0
  135. package/lib/typescript/specs/KlarnaPaymentViewNativeComponent.d.ts.map +1 -1
  136. package/lib/typescript/specs/KlarnaStandaloneWebViewNativeComponent.d.ts.map +1 -1
  137. package/lib/typescript/specs/NativeKlarnaSignIn.d.ts +1 -1
  138. package/lib/typescript/specs/NativeKlarnaSignIn.d.ts.map +1 -1
  139. package/lib/typescript/types/button/KlarnaButtonShape.d.ts +6 -0
  140. package/lib/typescript/types/button/KlarnaButtonShape.d.ts.map +1 -0
  141. package/lib/typescript/types/button/KlarnaButtonStyle.d.ts +5 -0
  142. package/lib/typescript/types/button/KlarnaButtonStyle.d.ts.map +1 -0
  143. package/lib/typescript/types/button/KlarnaButtonTheme.d.ts +6 -0
  144. package/lib/typescript/types/button/KlarnaButtonTheme.d.ts.map +1 -0
  145. package/lib/typescript/types/common/KlarnaExpressCheckoutSessionOptions.d.ts +10 -0
  146. package/lib/typescript/types/common/KlarnaExpressCheckoutSessionOptions.d.ts.map +1 -0
  147. package/lib/typescript/types/common/KlarnaOSMPlacementKey.d.ts +2 -0
  148. package/lib/typescript/types/common/KlarnaOSMPlacementKey.d.ts.map +1 -0
  149. package/lib/typescript/types/common/KlarnaTheme.d.ts +6 -0
  150. package/lib/typescript/types/common/KlarnaTheme.d.ts.map +1 -0
  151. package/package.json +17 -16
  152. package/react-native-klarna-inapp-sdk.podspec +2 -1
  153. package/src/KlarnaExpressCheckoutView.tsx +169 -0
  154. package/src/KlarnaOSMView.tsx +157 -0
  155. package/src/KlarnaStandaloneWebView.tsx +1 -2
  156. package/src/index.tsx +11 -0
  157. package/src/specs/KlarnaExpressCheckoutViewNativeComponent.ts +66 -0
  158. package/src/specs/KlarnaOSMViewNativeComponent.ts +50 -0
  159. package/src/specs/NativeKlarnaSignIn.ts +1 -1
  160. package/src/types/button/KlarnaButtonShape.ts +5 -0
  161. package/src/types/button/KlarnaButtonStyle.ts +4 -0
  162. package/src/types/button/KlarnaButtonTheme.ts +5 -0
  163. package/src/types/common/KlarnaExpressCheckoutSessionOptions.ts +13 -0
  164. package/src/types/common/KlarnaOSMPlacementKey.ts +3 -0
  165. package/src/types/common/KlarnaTheme.ts +5 -0
  166. package/LICENSE +0 -201
  167. package/README.md +0 -93
@@ -0,0 +1,145 @@
1
+ import Foundation
2
+ import KlarnaCore
3
+ import KlarnaPayments
4
+
5
+ /// A Swift class that implements the pure-Swift `KlarnaExpressCheckoutButtonDelegate` protocol
6
+ /// and forwards events to closures that can be set from Obj-C++ wrapper code.
7
+ @objc public class KlarnaExpressCheckoutButtonDelegateProxy: NSObject, KlarnaExpressCheckoutButtonDelegate {
8
+
9
+ @objc public var onAuthorizedHandler: ((_ response: NSDictionary) -> Void)?
10
+ @objc public var onErrorHandler: ((_ name: String, _ message: String, _ isFatal: Bool) -> Void)?
11
+
12
+ public func onAuthorized(
13
+ view: KlarnaExpressCheckoutButton,
14
+ response: KlarnaExpressCheckoutButtonAuthorizationResponse
15
+ ) {
16
+ let responseDict: NSDictionary = [
17
+ "showForm": response.showForm,
18
+ "approved": response.approved,
19
+ "finalizedRequired": response.finalizedRequired,
20
+ "clientToken": response.clientToken ?? "",
21
+ "authorizationToken": response.authorizationToken ?? "",
22
+ "sessionId": response.sessionId,
23
+ "collectedShippingAddress": response.collectedShippingAddress ?? "",
24
+ "merchantReference1": response.merchantReference1 ?? "",
25
+ "merchantReference2": response.merchantReference2 ?? "",
26
+ ]
27
+ onAuthorizedHandler?(responseDict)
28
+ }
29
+
30
+ public func onError(
31
+ view: KlarnaExpressCheckoutButton,
32
+ error: KlarnaError
33
+ ) {
34
+ onErrorHandler?(error.name, error.message, error.isFatal)
35
+ }
36
+ }
37
+
38
+ // MARK: - Helper to create KEC options from Obj-C++
39
+
40
+ @objc public class KlarnaExpressCheckoutHelper: NSObject {
41
+
42
+ @objc public static func createButton(
43
+ sessionType: String?,
44
+ clientId: String?,
45
+ clientToken: String?,
46
+ locale: String?,
47
+ returnUrl: String,
48
+ delegate: KlarnaExpressCheckoutButtonDelegateProxy,
49
+ theme: String?,
50
+ shape: String?,
51
+ buttonStyle: String?,
52
+ autoFinalize: Bool,
53
+ collectShippingAddress: Bool,
54
+ sessionData: String?,
55
+ environment: String?,
56
+ region: String?
57
+ ) -> KlarnaExpressCheckoutButton? {
58
+ // Build session options based on the explicit sessionType.
59
+ let sessionOptions: KlarnaExpressCheckoutSessionOptions
60
+ if sessionType == "clientToken" {
61
+ sessionOptions = KlarnaExpressCheckoutSessionOptions.ServerSideSession(
62
+ clientToken: clientToken ?? "",
63
+ autoFinalize: autoFinalize,
64
+ collectShippingAddress: collectShippingAddress,
65
+ sessionData: sessionData
66
+ )
67
+ } else {
68
+ sessionOptions = KlarnaExpressCheckoutSessionOptions.ClientSideSession(
69
+ clientId: clientId ?? "",
70
+ sessionData: sessionData ?? "",
71
+ autoFinalize: autoFinalize,
72
+ collectShippingAddress: collectShippingAddress
73
+ )
74
+ }
75
+
76
+ // Build style configuration
77
+ var buttonTheme: KlarnaButtonTheme?
78
+ if let theme = theme {
79
+ switch theme {
80
+ case "light": buttonTheme = .light
81
+ case "dark": buttonTheme = .dark
82
+ case "auto": buttonTheme = .auto
83
+ default: break
84
+ }
85
+ }
86
+
87
+ var buttonShape: KlarnaButtonShape?
88
+ if let shape = shape {
89
+ switch shape {
90
+ case "roundedRect": buttonShape = .roundedRect
91
+ case "pill": buttonShape = .pill
92
+ case "rectangle": buttonShape = .rectangle
93
+ default: break
94
+ }
95
+ }
96
+
97
+ var klarnaButtonStyle: KlarnaButtonStyle?
98
+ if let buttonStyle = buttonStyle {
99
+ switch buttonStyle {
100
+ case "filled": klarnaButtonStyle = .filled
101
+ case "outlined": klarnaButtonStyle = .outlined
102
+ default: break
103
+ }
104
+ }
105
+
106
+ let styleConfig = KlarnaExpressCheckoutButtonStyleConfiguration(
107
+ theme: buttonTheme,
108
+ shape: buttonShape,
109
+ style: klarnaButtonStyle
110
+ )
111
+
112
+ // Build environment
113
+ var klarnaEnvironment: KlarnaEnvironment?
114
+ if let environment = environment {
115
+ switch environment {
116
+ case "playground": klarnaEnvironment = .playground
117
+ case "production": klarnaEnvironment = .production
118
+ default: break
119
+ }
120
+ }
121
+
122
+ // Build region
123
+ var klarnaRegion: KlarnaRegion?
124
+ if let region = region {
125
+ switch region {
126
+ case "eu": klarnaRegion = .eu
127
+ case "na": klarnaRegion = .na
128
+ case "oc": klarnaRegion = .oc
129
+ default: break
130
+ }
131
+ }
132
+
133
+ let options = KlarnaExpressCheckoutButtonOptions(
134
+ sessionOptions: sessionOptions,
135
+ returnUrl: returnUrl,
136
+ delegate: delegate,
137
+ locale: locale,
138
+ styleConfiguration: styleConfig,
139
+ environment: klarnaEnvironment,
140
+ region: klarnaRegion
141
+ )
142
+
143
+ return KlarnaExpressCheckoutButton(options: options)
144
+ }
145
+ }
@@ -0,0 +1,41 @@
1
+ #import <React/RCTUIManager.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ #if RCT_NEW_ARCH_ENABLED
5
+ #import <React/RCTViewComponentView.h>
6
+ #else
7
+ #import <AVFoundation/AVFoundation.h>
8
+ #import <React/RCTView.h>
9
+ #endif
10
+
11
+ NS_ASSUME_NONNULL_BEGIN
12
+
13
+ #if RCT_NEW_ARCH_ENABLED
14
+ @interface KlarnaExpressCheckoutViewWrapper : RCTViewComponentView
15
+ #else
16
+ @interface KlarnaExpressCheckoutViewWrapper : UIView
17
+
18
+ @property (nonatomic, copy) RCTDirectEventBlock onAuthorized;
19
+ @property (nonatomic, copy) RCTDirectEventBlock onError;
20
+ @property (nonatomic, copy) RCTDirectEventBlock onResized;
21
+
22
+ @property (nonatomic, strong) NSString* sessionType;
23
+ @property (nonatomic, strong) NSString* clientId;
24
+ @property (nonatomic, strong) NSString* clientToken;
25
+ @property (nonatomic, strong) NSString* locale;
26
+ @property (nonatomic, strong) NSString* environment;
27
+ @property (nonatomic, strong) NSString* region;
28
+ @property (nonatomic, strong) NSString* returnUrl;
29
+ @property (nonatomic, strong) NSString* theme;
30
+ @property (nonatomic, strong) NSString* shape;
31
+ @property (nonatomic, strong) NSString* buttonStyle;
32
+ @property (nonatomic, assign) BOOL autoFinalize;
33
+ @property (nonatomic, assign) BOOL collectShippingAddress;
34
+ @property (nonatomic, strong) NSString* sessionData;
35
+ #endif
36
+
37
+ @property (nonatomic, weak) RCTUIManager* uiManager;
38
+
39
+ @end
40
+
41
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,48 @@
1
+ #import <React/RCTUIManager.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ #if RCT_NEW_ARCH_ENABLED
5
+ #import <React/RCTViewComponentView.h>
6
+ #endif
7
+
8
+ #if RCT_NEW_ARCH_ENABLED
9
+
10
+ @interface KlarnaOSMViewWrapper : RCTViewComponentView
11
+
12
+ #else
13
+
14
+ @interface KlarnaOSMViewWrapper : UIView
15
+
16
+ @property (nonatomic, copy) RCTDirectEventBlock onError;
17
+ @property (nonatomic, copy) RCTDirectEventBlock onResized;
18
+ @property (nonatomic, copy) RCTDirectEventBlock onOSMViewReady;
19
+
20
+ @property (nonatomic, strong) NSString* clientId;
21
+ @property (nonatomic, strong) NSString* placementKey;
22
+ @property (nonatomic, strong) NSString* locale;
23
+ @property (nonatomic, strong) NSString* purchaseAmount;
24
+ @property (nonatomic, strong) NSString* environment;
25
+ @property (nonatomic, strong) NSString* region;
26
+ @property (nonatomic, strong) NSString* theme;
27
+ @property (nonatomic, strong) NSString* osmBackgroundColor;
28
+ @property (nonatomic, strong) NSString* textColor;
29
+ @property (nullable, nonatomic, strong) NSString* returnUrl;
30
+
31
+ - (void)setClientId:(NSString * _Nonnull)clientId;
32
+ - (void)setPlacementKey:(NSString * _Nonnull)placementKey;
33
+ - (void)setLocale:(NSString * _Nonnull)locale;
34
+ - (void)setPurchaseAmount:(NSString * _Nonnull)purchaseAmount;
35
+ - (void)setEnvironment:(NSString * _Nonnull)environment;
36
+ - (void)setRegion:(NSString * _Nonnull)region;
37
+ - (void)setTheme:(NSString * _Nonnull)theme;
38
+ - (void)setOsmBackgroundColor:(NSString * _Nonnull)osmBackgroundColor;
39
+ - (void)setTextColor:(NSString * _Nonnull)textColor;
40
+ - (void)setReturnUrl:(NSString * _Nullable)returnUrl;
41
+
42
+ #endif
43
+
44
+ @property (nonatomic, weak) RCTUIManager* uiManager;
45
+
46
+ - (void)render;
47
+
48
+ @end
@@ -0,0 +1,228 @@
1
+ #if RCT_NEW_ARCH_ENABLED
2
+
3
+ #import <AVFoundation/AVFoundation.h>
4
+ #import <React/RCTLog.h>
5
+ #import <react/renderer/components/RNKlarnaMobileSDK/ComponentDescriptors.h>
6
+ #import <react/renderer/components/RNKlarnaMobileSDK/EventEmitters.h>
7
+ #import <react/renderer/components/RNKlarnaMobileSDK/Props.h>
8
+ #import <react/renderer/components/RNKlarnaMobileSDK/RCTComponentViewHelpers.h>
9
+ #import "../KlarnaExpressCheckoutViewWrapper.h"
10
+ #import "RCTFabricComponentsPlugins.h"
11
+ #import <KlarnaMobileSDK/KlarnaMobileSDK.h>
12
+ #import <KlarnaMobileSDK/KlarnaMobileSDK-Swift.h>
13
+
14
+ #if __has_include("react_native_klarna_inapp_sdk-Swift.h")
15
+ #import "react_native_klarna_inapp_sdk-Swift.h"
16
+ #elif __has_include("RNKlarnaMobileSDK-Swift.h")
17
+ #import "RNKlarnaMobileSDK-Swift.h"
18
+ #else
19
+ #import <RNKlarnaMobileSDK/RNKlarnaMobileSDK-Swift.h>
20
+ #endif
21
+
22
+ using namespace facebook::react;
23
+
24
+ @interface KlarnaExpressCheckoutViewWrapper () <RCTRNKlarnaExpressCheckoutViewViewProtocol>
25
+
26
+ @property (nonatomic, strong) KlarnaExpressCheckoutButton* expressCheckoutButton;
27
+ @property (nonatomic, strong) KlarnaExpressCheckoutButtonDelegateProxy* delegateProxy;
28
+ @property (nonatomic, assign) BOOL isButtonCreated;
29
+
30
+ // Store props for button creation
31
+ @property (nonatomic, strong) NSString* storedSessionType;
32
+ @property (nonatomic, strong) NSString* storedClientId;
33
+ @property (nonatomic, strong) NSString* storedClientToken;
34
+ @property (nonatomic, strong) NSString* storedLocale;
35
+ @property (nonatomic, strong) NSString* storedEnvironment;
36
+ @property (nonatomic, strong) NSString* storedRegion;
37
+ @property (nonatomic, strong) NSString* storedReturnUrl;
38
+ @property (nonatomic, strong) NSString* storedTheme;
39
+ @property (nonatomic, strong) NSString* storedShape;
40
+ @property (nonatomic, strong) NSString* storedButtonStyle;
41
+ @property (nonatomic, assign) BOOL storedAutoFinalize;
42
+ @property (nonatomic, assign) BOOL storedCollectShippingAddress;
43
+ @property (nonatomic, strong) NSString* storedSessionData;
44
+
45
+ @end
46
+
47
+ @implementation KlarnaExpressCheckoutViewWrapper
48
+
49
+ #pragma mark - Initialization
50
+
51
+ - (instancetype)initWithFrame:(CGRect)frame
52
+ {
53
+ self = [super initWithFrame:frame];
54
+ if (self) {
55
+ self.backgroundColor = [UIColor clearColor];
56
+ self.isButtonCreated = NO;
57
+ self.storedAutoFinalize = YES;
58
+ self.storedCollectShippingAddress = NO;
59
+ static const auto defaultProps = std::make_shared<const RNKlarnaExpressCheckoutViewProps>();
60
+ _props = defaultProps;
61
+ [self setupDelegateProxy];
62
+ }
63
+
64
+ return self;
65
+ }
66
+
67
+ + (ComponentDescriptorProvider)componentDescriptorProvider
68
+ {
69
+ return concreteComponentDescriptorProvider<RNKlarnaExpressCheckoutViewComponentDescriptor>();
70
+ }
71
+
72
+ Class<RCTComponentViewProtocol> RNKlarnaExpressCheckoutViewCls(void)
73
+ {
74
+ return KlarnaExpressCheckoutViewWrapper.class;
75
+ }
76
+
77
+ - (void)setupDelegateProxy {
78
+ self.delegateProxy = [[KlarnaExpressCheckoutButtonDelegateProxy alloc] init];
79
+
80
+ __weak __typeof(self) weakSelf = self;
81
+
82
+ self.delegateProxy.onAuthorizedHandler = ^(NSDictionary * _Nonnull response) {
83
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
84
+ if (!strongSelf || !strongSelf->_eventEmitter) {
85
+ return;
86
+ }
87
+
88
+ auto emitter = std::dynamic_pointer_cast<const RNKlarnaExpressCheckoutViewEventEmitter>(strongSelf->_eventEmitter);
89
+ if (emitter) {
90
+ emitter->onAuthorized(RNKlarnaExpressCheckoutViewEventEmitter::OnAuthorized{
91
+ .authorizationResponse = {
92
+ .showForm = [[response objectForKey:@"showForm"] boolValue],
93
+ .approved = [[response objectForKey:@"approved"] boolValue],
94
+ .finalizedRequired = [[response objectForKey:@"finalizedRequired"] boolValue],
95
+ .clientToken = std::string([([response objectForKey:@"clientToken"] ?: @"") UTF8String]),
96
+ .authorizationToken = std::string([([response objectForKey:@"authorizationToken"] ?: @"") UTF8String]),
97
+ .sessionId = std::string([([response objectForKey:@"sessionId"] ?: @"") UTF8String]),
98
+ .collectedShippingAddress = std::string([([response objectForKey:@"collectedShippingAddress"] ?: @"") UTF8String]),
99
+ .merchantReference1 = std::string([([response objectForKey:@"merchantReference1"] ?: @"") UTF8String]),
100
+ .merchantReference2 = std::string([([response objectForKey:@"merchantReference2"] ?: @"") UTF8String]),
101
+ }
102
+ });
103
+ }
104
+ };
105
+
106
+ self.delegateProxy.onErrorHandler = ^(NSString * _Nonnull name, NSString * _Nonnull message, BOOL isFatal) {
107
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
108
+ if (!strongSelf || !strongSelf->_eventEmitter) {
109
+ return;
110
+ }
111
+
112
+ auto emitter = std::dynamic_pointer_cast<const RNKlarnaExpressCheckoutViewEventEmitter>(strongSelf->_eventEmitter);
113
+ if (emitter) {
114
+ emitter->onError(RNKlarnaExpressCheckoutViewEventEmitter::OnError{
115
+ .error = {
116
+ .name = std::string([name UTF8String]),
117
+ .message = std::string([message UTF8String]),
118
+ .isFatal = isFatal,
119
+ }
120
+ });
121
+ }
122
+ };
123
+ }
124
+
125
+ #pragma mark - Props Update
126
+
127
+ - (void)updateProps:(const facebook::react::Props::Shared &)props oldProps:(const facebook::react::Props::Shared &)oldProps {
128
+ const auto &newViewProps = *std::static_pointer_cast<RNKlarnaExpressCheckoutViewProps const>(props);
129
+
130
+ self.storedSessionType = [[NSString alloc] initWithUTF8String:newViewProps.sessionType.c_str()];
131
+ self.storedClientId = [[NSString alloc] initWithUTF8String:newViewProps.clientId.c_str()];
132
+ self.storedClientToken = [[NSString alloc] initWithUTF8String:newViewProps.clientToken.c_str()];
133
+ self.storedLocale = [[NSString alloc] initWithUTF8String:newViewProps.locale.c_str()];
134
+ self.storedEnvironment = [[NSString alloc] initWithUTF8String:newViewProps.environment.c_str()];
135
+ self.storedRegion = [[NSString alloc] initWithUTF8String:newViewProps.region.c_str()];
136
+ self.storedReturnUrl = [[NSString alloc] initWithUTF8String:newViewProps.returnUrl.c_str()];
137
+ self.storedTheme = [[NSString alloc] initWithUTF8String:newViewProps.theme.c_str()];
138
+ self.storedShape = [[NSString alloc] initWithUTF8String:newViewProps.shape.c_str()];
139
+ self.storedButtonStyle = [[NSString alloc] initWithUTF8String:newViewProps.buttonStyle.c_str()];
140
+ self.storedAutoFinalize = newViewProps.autoFinalize;
141
+ self.storedCollectShippingAddress = newViewProps.collectShippingAddress;
142
+ self.storedSessionData = [[NSString alloc] initWithUTF8String:newViewProps.sessionData.c_str()];
143
+
144
+ if (self.isButtonCreated) {
145
+ [self resetButton];
146
+ }
147
+ [self createButtonIfNeeded];
148
+
149
+ [super updateProps:props oldProps:oldProps];
150
+ }
151
+
152
+ #pragma mark - Button Creation
153
+
154
+ - (void)resetButton {
155
+ if (self.expressCheckoutButton) {
156
+ [self.expressCheckoutButton removeFromSuperview];
157
+ self.expressCheckoutButton = nil;
158
+ }
159
+ self.isButtonCreated = NO;
160
+ }
161
+
162
+ - (void)createButtonIfNeeded {
163
+ if (self.isButtonCreated) {
164
+ return;
165
+ }
166
+
167
+ KlarnaExpressCheckoutButton *button = [KlarnaExpressCheckoutHelper
168
+ createButtonWithSessionType:self.storedSessionType ?: @""
169
+ clientId:self.storedClientId ?: @""
170
+ clientToken:self.storedClientToken ?: @""
171
+ locale:self.storedLocale
172
+ returnUrl:self.storedReturnUrl ?: @""
173
+ delegate:self.delegateProxy
174
+ theme:self.storedTheme
175
+ shape:self.storedShape
176
+ buttonStyle:self.storedButtonStyle
177
+ autoFinalize:self.storedAutoFinalize
178
+ collectShippingAddress:self.storedCollectShippingAddress
179
+ sessionData:self.storedSessionData
180
+ environment:self.storedEnvironment
181
+ region:self.storedRegion];
182
+
183
+ if (button) {
184
+ self.expressCheckoutButton = button;
185
+ self.expressCheckoutButton.translatesAutoresizingMaskIntoConstraints = NO;
186
+ [self addSubview:self.expressCheckoutButton];
187
+
188
+ [NSLayoutConstraint activateConstraints:@[
189
+ [self.expressCheckoutButton.topAnchor constraintEqualToAnchor:self.topAnchor],
190
+ [self.expressCheckoutButton.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
191
+ [self.expressCheckoutButton.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
192
+ [self.expressCheckoutButton.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
193
+ ]];
194
+
195
+ self.isButtonCreated = YES;
196
+
197
+ // Send resize event after layout
198
+ __weak __typeof(self) weakSelf = self;
199
+ dispatch_async(dispatch_get_main_queue(), ^{
200
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
201
+ if (!strongSelf || !strongSelf->_eventEmitter || !strongSelf.expressCheckoutButton) {
202
+ return;
203
+ }
204
+ CGFloat height = strongSelf.expressCheckoutButton.intrinsicContentSize.height;
205
+ if (height > 0) {
206
+ auto emitter = std::dynamic_pointer_cast<const RNKlarnaExpressCheckoutViewEventEmitter>(strongSelf->_eventEmitter);
207
+ if (emitter) {
208
+ emitter->onResized(RNKlarnaExpressCheckoutViewEventEmitter::OnResized{
209
+ .height = std::string([[[NSNumber numberWithFloat:height] stringValue] UTF8String]),
210
+ });
211
+ }
212
+ }
213
+ });
214
+ }
215
+ }
216
+
217
+ #pragma mark - UIView Lifecycle
218
+
219
+ - (void)didMoveToWindow {
220
+ [super didMoveToWindow];
221
+ if (!self.window) {
222
+ [self resetButton];
223
+ }
224
+ }
225
+
226
+ @end
227
+
228
+ #endif