@primer-io/react-native 2.6.1 → 2.7.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.
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/primerioreactnative/PrimerRN.kt +1 -0
- package/android/src/main/java/com/primerioreactnative/PrimerRNEventListener.kt +24 -1
- package/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckoutListener.kt +24 -1
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerCheckoutAdditionalInfoRN.kt +13 -0
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerCheckoutDataRN.kt +4 -1
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerEvents.kt +1 -0
- package/android/src/main/java/com/primerioreactnative/extensions/PrimerCheckoutAdditionalInfo.kt +12 -0
- package/android/src/main/java/com/primerioreactnative/extensions/PrimerCheckoutData.kt +1 -1
- package/android/src/main/java/com/primerioreactnative/utils/PrimerHeadlessUniversalCheckoutImplementedRNCallbacks.kt +2 -0
- package/android/src/main/java/com/primerioreactnative/utils/PrimerImplementedRNCallbacks.kt +2 -0
- package/ios/DataModels/ImplementedRNCallbacks.swift +6 -3
- package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.swift +23 -1
- package/ios/RNTPrimer.swift +72 -49
- package/lib/commonjs/Primer.js +14 -3
- package/lib/commonjs/Primer.js.map +1 -1
- package/lib/commonjs/RNPrimer.js +1 -1
- package/lib/commonjs/RNPrimer.js.map +1 -1
- package/lib/commonjs/headless_checkout/PrimerHeadlessUniversalCheckout.js +17 -6
- package/lib/commonjs/headless_checkout/PrimerHeadlessUniversalCheckout.js.map +1 -1
- package/lib/commonjs/headless_checkout/RNPrimerHeadlessUniversalCheckout.js +1 -1
- package/lib/commonjs/headless_checkout/RNPrimerHeadlessUniversalCheckout.js.map +1 -1
- package/lib/commonjs/index.js +14 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/PrimerCheckoutAdditionalInfo.js +2 -0
- package/lib/commonjs/models/PrimerCheckoutAdditionalInfo.js.map +1 -0
- package/lib/commonjs/models/PrimerCheckoutData.js +3 -0
- package/lib/commonjs/models/PrimerCheckoutData.js.map +1 -1
- package/lib/module/Primer.js +14 -3
- package/lib/module/Primer.js.map +1 -1
- package/lib/module/RNPrimer.js +1 -1
- package/lib/module/RNPrimer.js.map +1 -1
- package/lib/module/headless_checkout/PrimerHeadlessUniversalCheckout.js +17 -6
- package/lib/module/headless_checkout/PrimerHeadlessUniversalCheckout.js.map +1 -1
- package/lib/module/headless_checkout/RNPrimerHeadlessUniversalCheckout.js +1 -1
- package/lib/module/headless_checkout/RNPrimerHeadlessUniversalCheckout.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/PrimerCheckoutAdditionalInfo.js +2 -0
- package/lib/module/models/PrimerCheckoutAdditionalInfo.js.map +1 -0
- package/lib/module/models/PrimerCheckoutData.js +2 -0
- package/lib/module/models/PrimerCheckoutData.js.map +1 -1
- package/lib/typescript/src/RNPrimer.d.ts +1 -1
- package/lib/typescript/src/headless_checkout/RNPrimerHeadlessUniversalCheckout.d.ts +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/models/PrimerCheckoutAdditionalInfo.d.ts +10 -0
- package/lib/typescript/src/models/PrimerCheckoutData.d.ts +3 -1
- package/lib/typescript/src/models/PrimerSettings.d.ts +2 -0
- package/package.json +1 -1
- package/primer-io-react-native.podspec +1 -1
- package/src/Primer.ts +16 -0
- package/src/RNPrimer.ts +2 -0
- package/src/headless_checkout/PrimerHeadlessUniversalCheckout.ts +16 -0
- package/src/headless_checkout/RNPrimerHeadlessUniversalCheckout.ts +2 -0
- package/src/index.tsx +5 -1
- package/src/models/PrimerCheckoutAdditionalInfo.ts +11 -0
- package/src/models/PrimerCheckoutData.ts +5 -2
- package/src/models/PrimerSettings.ts +8 -6
package/android/build.gradle
CHANGED
|
@@ -137,5 +137,5 @@ dependencies {
|
|
|
137
137
|
api 'com.facebook.react:react-native:+'
|
|
138
138
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
139
139
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
|
|
140
|
-
implementation 'io.primer:android:2.
|
|
140
|
+
implementation 'io.primer:android:2.7.0'
|
|
141
141
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.primerioreactnative
|
|
2
2
|
|
|
3
3
|
import com.primerioreactnative.datamodels.*
|
|
4
|
+
import com.primerioreactnative.extensions.*
|
|
4
5
|
import com.primerioreactnative.extensions.toPrimerCheckoutDataRN
|
|
5
6
|
import com.primerioreactnative.extensions.toPrimerClientSessionRN
|
|
6
7
|
import com.primerioreactnative.extensions.toPrimerPaymentMethodDataRN
|
|
@@ -13,6 +14,8 @@ import io.primer.android.completion.PrimerResumeDecisionHandler
|
|
|
13
14
|
import io.primer.android.domain.PrimerCheckoutData
|
|
14
15
|
import io.primer.android.domain.action.models.PrimerClientSession
|
|
15
16
|
import io.primer.android.domain.error.models.PrimerError
|
|
17
|
+
import io.primer.android.domain.payments.additionalInfo.MultibancoCheckoutAdditionalInfo
|
|
18
|
+
import io.primer.android.domain.payments.additionalInfo.PrimerCheckoutAdditionalInfo
|
|
16
19
|
import io.primer.android.domain.tokenization.models.PrimerPaymentMethodData
|
|
17
20
|
import io.primer.android.domain.tokenization.models.PrimerPaymentMethodTokenData
|
|
18
21
|
import kotlinx.serialization.encodeToString
|
|
@@ -38,7 +41,11 @@ class PrimerRNEventListener : PrimerCheckoutListener {
|
|
|
38
41
|
if (implementedRNCallbacks?.isOnCheckoutCompleteImplemented == true) {
|
|
39
42
|
sendEvent?.invoke(
|
|
40
43
|
PrimerEvents.ON_CHECKOUT_COMPLETE.eventName,
|
|
41
|
-
JSONObject(Json.encodeToString(checkoutData.toPrimerCheckoutDataRN()))
|
|
44
|
+
JSONObject(Json.encodeToString(checkoutData.toPrimerCheckoutDataRN())).apply {
|
|
45
|
+
val additionalInfoJson = optJSONObject(Keys.ADDITIONAL_INFO)
|
|
46
|
+
additionalInfoJson?.remove("type")
|
|
47
|
+
putOpt(Keys.ADDITIONAL_INFO, additionalInfoJson)
|
|
48
|
+
}
|
|
42
49
|
)
|
|
43
50
|
} else {
|
|
44
51
|
sendError?.invoke(
|
|
@@ -139,6 +146,22 @@ class PrimerRNEventListener : PrimerCheckoutListener {
|
|
|
139
146
|
}
|
|
140
147
|
}
|
|
141
148
|
|
|
149
|
+
override fun onResumePending(additionalInfo: PrimerCheckoutAdditionalInfo?) {
|
|
150
|
+
if (implementedRNCallbacks?.isOnResumePendingImplemented == true) {
|
|
151
|
+
if (additionalInfo is MultibancoCheckoutAdditionalInfo) {
|
|
152
|
+
sendEvent?.invoke(
|
|
153
|
+
PrimerEvents.ON_RESUME_PENDING.eventName,
|
|
154
|
+
JSONObject(Json.encodeToString(additionalInfo.toCheckoutAdditionalInfoRN()))
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
sendError?.invoke(
|
|
159
|
+
ErrorTypeRN.NativeBridgeFailed
|
|
160
|
+
errorTo "Callback [onResumePending] should be implemented."
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
142
165
|
override fun onDismissed() {
|
|
143
166
|
if (implementedRNCallbacks?.isOnDismissImplemented == true) {
|
|
144
167
|
sendEvent?.invoke(
|
package/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckoutListener.kt
CHANGED
|
@@ -4,6 +4,7 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.bridge.Callback
|
|
5
5
|
import com.facebook.react.bridge.Promise
|
|
6
6
|
import com.primerioreactnative.datamodels.*
|
|
7
|
+
import com.primerioreactnative.extensions.*
|
|
7
8
|
import com.primerioreactnative.extensions.toPrimerCheckoutDataRN
|
|
8
9
|
import com.primerioreactnative.extensions.toPrimerClientSessionRN
|
|
9
10
|
import com.primerioreactnative.extensions.toPrimerPaymentMethodDataRN
|
|
@@ -18,6 +19,8 @@ import io.primer.android.components.domain.core.models.PrimerHeadlessUniversalCh
|
|
|
18
19
|
import io.primer.android.domain.PrimerCheckoutData
|
|
19
20
|
import io.primer.android.domain.action.models.PrimerClientSession
|
|
20
21
|
import io.primer.android.domain.error.models.PrimerError
|
|
22
|
+
import io.primer.android.domain.payments.additionalInfo.MultibancoCheckoutAdditionalInfo
|
|
23
|
+
import io.primer.android.domain.payments.additionalInfo.PrimerCheckoutAdditionalInfo
|
|
21
24
|
import io.primer.android.domain.tokenization.models.PrimerPaymentMethodData
|
|
22
25
|
import io.primer.android.domain.tokenization.models.PrimerPaymentMethodTokenData
|
|
23
26
|
import kotlinx.serialization.encodeToString
|
|
@@ -79,7 +82,11 @@ class PrimerRNHeadlessUniversalCheckoutListener : PrimerHeadlessUniversalCheckou
|
|
|
79
82
|
if (implementedRNCallbacks?.isOnCheckoutCompleteImplemented == true) {
|
|
80
83
|
sendEvent?.invoke(
|
|
81
84
|
PrimerHeadlessUniversalCheckoutEvent.ON_CHECKOUT_COMPLETE.eventName,
|
|
82
|
-
JSONObject(Json.encodeToString(checkoutData.toPrimerCheckoutDataRN()))
|
|
85
|
+
JSONObject(Json.encodeToString(checkoutData.toPrimerCheckoutDataRN())).apply {
|
|
86
|
+
val additionalInfoJson = optJSONObject(Keys.ADDITIONAL_INFO)
|
|
87
|
+
additionalInfoJson?.remove("type")
|
|
88
|
+
putOpt(Keys.ADDITIONAL_INFO, additionalInfoJson)
|
|
89
|
+
}
|
|
83
90
|
)
|
|
84
91
|
} else {
|
|
85
92
|
sendError?.invoke(
|
|
@@ -180,6 +187,22 @@ class PrimerRNHeadlessUniversalCheckoutListener : PrimerHeadlessUniversalCheckou
|
|
|
180
187
|
}
|
|
181
188
|
}
|
|
182
189
|
|
|
190
|
+
override fun onResumePending(additionalInfo: PrimerCheckoutAdditionalInfo?) {
|
|
191
|
+
if (implementedRNCallbacks?.isOnResumePendingImplemented == true) {
|
|
192
|
+
if (additionalInfo is MultibancoCheckoutAdditionalInfo) {
|
|
193
|
+
sendEvent?.invoke(
|
|
194
|
+
PrimerEvents.ON_RESUME_PENDING.eventName,
|
|
195
|
+
JSONObject(Json.encodeToString(additionalInfo.toCheckoutAdditionalInfoRN()))
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
sendError?.invoke(
|
|
200
|
+
ErrorTypeRN.NativeBridgeFailed
|
|
201
|
+
errorTo "Callback [onResumePending] should be implemented."
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
183
206
|
override fun onFailed(
|
|
184
207
|
error: PrimerError,
|
|
185
208
|
checkoutData: PrimerCheckoutData?,
|
package/android/src/main/java/com/primerioreactnative/datamodels/PrimerCheckoutAdditionalInfoRN.kt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.primerioreactnative.datamodels
|
|
2
|
+
|
|
3
|
+
import kotlinx.serialization.Serializable
|
|
4
|
+
|
|
5
|
+
@Serializable
|
|
6
|
+
sealed class PrimerCheckoutAdditionalInfoRN
|
|
7
|
+
|
|
8
|
+
@Serializable
|
|
9
|
+
data class MultibancoCheckoutAdditionalInfoRN(
|
|
10
|
+
val expiresAt: String,
|
|
11
|
+
val reference: String,
|
|
12
|
+
val entity: String,
|
|
13
|
+
) : PrimerCheckoutAdditionalInfoRN()
|
|
@@ -3,7 +3,10 @@ package com.primerioreactnative.datamodels
|
|
|
3
3
|
import kotlinx.serialization.Serializable
|
|
4
4
|
|
|
5
5
|
@Serializable
|
|
6
|
-
data class PrimerCheckoutDataRN(
|
|
6
|
+
data class PrimerCheckoutDataRN(
|
|
7
|
+
val payment: PrimerPaymentRN,
|
|
8
|
+
val additionalInfo: PrimerCheckoutAdditionalInfoRN? = null
|
|
9
|
+
)
|
|
7
10
|
|
|
8
11
|
@Serializable
|
|
9
12
|
data class PrimerPaymentRN(
|
package/android/src/main/java/com/primerioreactnative/extensions/PrimerCheckoutAdditionalInfo.kt
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.primerioreactnative.extensions
|
|
2
|
+
|
|
3
|
+
import com.primerioreactnative.datamodels.MultibancoCheckoutAdditionalInfoRN
|
|
4
|
+
import io.primer.android.domain.payments.additionalInfo.MultibancoCheckoutAdditionalInfo
|
|
5
|
+
import io.primer.android.domain.payments.additionalInfo.PrimerCheckoutAdditionalInfo
|
|
6
|
+
|
|
7
|
+
internal fun PrimerCheckoutAdditionalInfo.toCheckoutAdditionalInfoRN() = when (this) {
|
|
8
|
+
is MultibancoCheckoutAdditionalInfo ->
|
|
9
|
+
MultibancoCheckoutAdditionalInfoRN(expiresAt, reference, entity)
|
|
10
|
+
else -> null
|
|
11
|
+
}
|
|
12
|
+
|
|
@@ -4,4 +4,4 @@ import com.primerioreactnative.datamodels.PrimerCheckoutDataRN
|
|
|
4
4
|
import io.primer.android.domain.PrimerCheckoutData
|
|
5
5
|
|
|
6
6
|
internal fun PrimerCheckoutData.toPrimerCheckoutDataRN() =
|
|
7
|
-
PrimerCheckoutDataRN(payment.toPrimerPaymentRN())
|
|
7
|
+
PrimerCheckoutDataRN(payment.toPrimerPaymentRN(), additionalInfo?.toCheckoutAdditionalInfoRN())
|
|
@@ -19,6 +19,8 @@ data class PrimerHeadlessUniversalCheckoutImplementedRNCallbacks(
|
|
|
19
19
|
val isOnTokenizeSuccessImplemented: Boolean? = null,
|
|
20
20
|
@SerialName("onResumeSuccess")
|
|
21
21
|
val isOnResumeSuccessImplemented: Boolean? = null,
|
|
22
|
+
@SerialName("onResumePending")
|
|
23
|
+
val isOnResumePendingImplemented: Boolean? = null,
|
|
22
24
|
@SerialName("onHUCTokenizeStart")
|
|
23
25
|
val isOnHUCTokenizeStartsImplemented: Boolean? = null,
|
|
24
26
|
@SerialName("onHUCPrepareStart")
|
|
@@ -21,4 +21,6 @@ data class PrimerImplementedRNCallbacks(
|
|
|
21
21
|
val isOnTokenizeSuccessImplemented: Boolean? = null,
|
|
22
22
|
@SerialName("onResumeSuccess")
|
|
23
23
|
val isOnResumeSuccessImplemented: Boolean? = null,
|
|
24
|
+
@SerialName("onResumePending")
|
|
25
|
+
val isOnResumePendingImplemented: Boolean? = null,
|
|
24
26
|
)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import Foundation
|
|
9
9
|
|
|
10
10
|
internal struct ImplementedRNCallbacks: Decodable {
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
internal var isOnCheckoutCompleteImplemented: Bool = false
|
|
13
13
|
internal var isOnBeforeClientSessionUpdateImplemented: Bool = false
|
|
14
14
|
internal var isOnClientSessionUpdateImplemented: Bool = false
|
|
@@ -17,11 +17,12 @@ internal struct ImplementedRNCallbacks: Decodable {
|
|
|
17
17
|
internal var isOnDismissImplemented: Bool = false
|
|
18
18
|
internal var isOnTokenizeSuccessImplemented: Bool = false
|
|
19
19
|
internal var isOnResumeSuccessImplemented: Bool = false
|
|
20
|
+
internal var isOnResumePendingImplemented: Bool = false
|
|
20
21
|
internal var isOnHUCTokenizeStartImplemented: Bool = false
|
|
21
22
|
internal var isOnHUCPrepareStartImplemented: Bool = false
|
|
22
23
|
internal var isOnHUCAvailablePaymentMethodsLoadedImplemented: Bool = false
|
|
23
24
|
internal var isOnHUCPaymentMethodShowImplemented: Bool = false
|
|
24
|
-
|
|
25
|
+
|
|
25
26
|
enum CodingKeys: String, CodingKey {
|
|
26
27
|
case isOnCheckoutCompleteImplemented = "onCheckoutComplete"
|
|
27
28
|
case isOnBeforeClientSessionUpdateImplemented = "onBeforeClientSessionUpdate"
|
|
@@ -31,12 +32,13 @@ internal struct ImplementedRNCallbacks: Decodable {
|
|
|
31
32
|
case isOnDismissImplemented = "onDismiss"
|
|
32
33
|
case isOnTokenizeSuccessImplemented = "onTokenizeSuccess"
|
|
33
34
|
case isOnResumeSuccessImplemented = "onResumeSuccess"
|
|
35
|
+
case isOnResumePendingImplemented = "onResumePending"
|
|
34
36
|
case isOnHUCTokenizeStartImplemented = "onHUCTokenizeStart"
|
|
35
37
|
case isOnHUCPrepareStartImplemented = "onHUCPrepareStart"
|
|
36
38
|
case isOnHUCAvailablePaymentMethodsLoadedImplemented = "onHUCAvailablePaymentMethodsLoaded"
|
|
37
39
|
case isOnHUCPaymentMethodShowImplemented = "onHUCPaymentMethodShow"
|
|
38
40
|
}
|
|
39
|
-
|
|
41
|
+
|
|
40
42
|
init(from decoder: Decoder) throws {
|
|
41
43
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
42
44
|
|
|
@@ -48,6 +50,7 @@ internal struct ImplementedRNCallbacks: Decodable {
|
|
|
48
50
|
self.isOnDismissImplemented = (try? container.decode(Bool?.self, forKey: .isOnDismissImplemented)) ?? false
|
|
49
51
|
self.isOnTokenizeSuccessImplemented = (try? container.decode(Bool?.self, forKey: .isOnTokenizeSuccessImplemented)) ?? false
|
|
50
52
|
self.isOnResumeSuccessImplemented = (try? container.decode(Bool?.self, forKey: .isOnResumeSuccessImplemented)) ?? false
|
|
53
|
+
self.isOnResumePendingImplemented = (try? container.decode(Bool?.self, forKey: .isOnResumePendingImplemented)) ?? false
|
|
51
54
|
self.isOnHUCTokenizeStartImplemented = (try? container.decode(Bool?.self, forKey: .isOnHUCTokenizeStartImplemented)) ?? false
|
|
52
55
|
self.isOnHUCPrepareStartImplemented = (try? container.decode(Bool?.self, forKey: .isOnHUCPrepareStartImplemented)) ?? false
|
|
53
56
|
self.isOnHUCAvailablePaymentMethodsLoadedImplemented = (try? container.decode(Bool?.self, forKey: .isOnHUCAvailablePaymentMethodsLoadedImplemented)) ?? false
|
|
@@ -17,6 +17,7 @@ enum PrimerHeadlessUniversalCheckoutEvents: Int, CaseIterable {
|
|
|
17
17
|
case onHUCPaymentMethodShow
|
|
18
18
|
case onTokenizeSuccess
|
|
19
19
|
case onResumeSuccess
|
|
20
|
+
case onResumePending
|
|
20
21
|
case onBeforePaymentCreate
|
|
21
22
|
case onBeforeClientSessionUpdate
|
|
22
23
|
case onClientSessionUpdate
|
|
@@ -35,6 +36,8 @@ enum PrimerHeadlessUniversalCheckoutEvents: Int, CaseIterable {
|
|
|
35
36
|
return "onTokenizeSuccess"
|
|
36
37
|
case .onResumeSuccess:
|
|
37
38
|
return "onResumeSuccess"
|
|
39
|
+
case .onResumePending:
|
|
40
|
+
return "onResumePending"
|
|
38
41
|
case .onBeforePaymentCreate:
|
|
39
42
|
return "onBeforePaymentCreate"
|
|
40
43
|
case .onBeforeClientSessionUpdate:
|
|
@@ -398,6 +401,25 @@ extension RNTPrimerHeadlessUniversalCheckout: PrimerHeadlessUniversalCheckoutDel
|
|
|
398
401
|
}
|
|
399
402
|
}
|
|
400
403
|
}
|
|
404
|
+
|
|
405
|
+
func primerHeadlessUniversalCheckoutDidEnterResumePendingWithPaymentAdditionalInfo(_ additionalInfo: PrimerCheckoutAdditionalInfo?) {
|
|
406
|
+
DispatchQueue.main.async {
|
|
407
|
+
if self.implementedRNCallbacks?.isOnResumePendingImplemented == true {
|
|
408
|
+
do {
|
|
409
|
+
let checkoutAdditionalInfo = try JSONEncoder().encode(additionalInfo)
|
|
410
|
+
let checkoutAdditionalInfoJson = try JSONSerialization.jsonObject(with: checkoutAdditionalInfo, options: .allowFragments)
|
|
411
|
+
self.sendEvent(withName: PrimerHeadlessUniversalCheckoutEvents.onResumePending.stringValue, body: checkoutAdditionalInfoJson)
|
|
412
|
+
} catch {
|
|
413
|
+
let checkoutData = PrimerCheckoutData(payment: nil, additionalInfo: additionalInfo)
|
|
414
|
+
self.handleRNBridgeError(error, checkoutData: checkoutData, stopOnDebug: true)
|
|
415
|
+
}
|
|
416
|
+
} else {
|
|
417
|
+
let err = NSError(domain: "native-bridge", code: 1, userInfo: [NSLocalizedDescriptionKey: "Callback [onResumePending] should be implemented."])
|
|
418
|
+
let checkoutData = PrimerCheckoutData(payment: nil, additionalInfo: additionalInfo)
|
|
419
|
+
self.handleRNBridgeError(err, checkoutData: checkoutData, stopOnDebug: false)
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
401
423
|
|
|
402
424
|
func primerHeadlessUniversalCheckoutClientSessionWillUpdate() {
|
|
403
425
|
if self.implementedRNCallbacks?.isOnBeforeClientSessionUpdateImplemented == true {
|
|
@@ -405,7 +427,7 @@ extension RNTPrimerHeadlessUniversalCheckout: PrimerHeadlessUniversalCheckoutDel
|
|
|
405
427
|
self.sendEvent(withName: PrimerHeadlessUniversalCheckoutEvents.onBeforeClientSessionUpdate.stringValue, body: nil)
|
|
406
428
|
}
|
|
407
429
|
} else {
|
|
408
|
-
//
|
|
430
|
+
// React Native app hasn't implemented this callback, ignore.
|
|
409
431
|
}
|
|
410
432
|
}
|
|
411
433
|
|
package/ios/RNTPrimer.swift
CHANGED
|
@@ -11,7 +11,7 @@ import UIKit
|
|
|
11
11
|
|
|
12
12
|
@objc
|
|
13
13
|
enum PrimerEvents: Int, CaseIterable {
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
case onCheckoutComplete = 0
|
|
16
16
|
case onBeforeClientSessionUpdate
|
|
17
17
|
case onClientSessionUpdate
|
|
@@ -19,9 +19,10 @@ enum PrimerEvents: Int, CaseIterable {
|
|
|
19
19
|
case onDismiss
|
|
20
20
|
case onTokenizeSuccess
|
|
21
21
|
case onResumeSuccess
|
|
22
|
+
case onResumePending
|
|
22
23
|
case onError
|
|
23
24
|
case detectImplementedRNCallbacks
|
|
24
|
-
|
|
25
|
+
|
|
25
26
|
var stringValue: String {
|
|
26
27
|
switch self {
|
|
27
28
|
case .onCheckoutComplete:
|
|
@@ -38,6 +39,8 @@ enum PrimerEvents: Int, CaseIterable {
|
|
|
38
39
|
return "onTokenizeSuccess"
|
|
39
40
|
case .onResumeSuccess:
|
|
40
41
|
return "onResumeSuccess"
|
|
42
|
+
case .onResumePending:
|
|
43
|
+
return "onResumePending"
|
|
41
44
|
case .onError:
|
|
42
45
|
return "onError"
|
|
43
46
|
case .detectImplementedRNCallbacks:
|
|
@@ -54,28 +57,28 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
54
57
|
private var primerDidResumeWithDecisionHandler: ((_ resumeToken: String?, _ errorMessage: String?) -> Void)?
|
|
55
58
|
private var primerDidFailWithErrorDecisionHandler: ((_ errorMessage: String) -> Void)?
|
|
56
59
|
private var implementedRNCallbacks: ImplementedRNCallbacks?
|
|
57
|
-
|
|
60
|
+
|
|
58
61
|
// MARK: - INITIALIZATION & REACT NATIVE SUPPORT
|
|
59
|
-
|
|
62
|
+
|
|
60
63
|
override class func requiresMainQueueSetup() -> Bool {
|
|
61
64
|
return true
|
|
62
65
|
}
|
|
63
|
-
|
|
66
|
+
|
|
64
67
|
deinit {
|
|
65
68
|
print("🧨 deinit: \(self) \(Unmanaged.passUnretained(self).toOpaque())")
|
|
66
69
|
}
|
|
67
|
-
|
|
70
|
+
|
|
68
71
|
override init() {
|
|
69
72
|
super.init()
|
|
70
73
|
PrimerSDK.Primer.shared.delegate = self
|
|
71
74
|
}
|
|
72
|
-
|
|
75
|
+
|
|
73
76
|
override func supportedEvents() -> [String]! {
|
|
74
77
|
return PrimerEvents.allCases.compactMap({ $0.stringValue })
|
|
75
78
|
}
|
|
76
|
-
|
|
79
|
+
|
|
77
80
|
// MARK: - SDK API
|
|
78
|
-
|
|
81
|
+
|
|
79
82
|
@objc
|
|
80
83
|
public func configure(_ settingsStr: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
81
84
|
DispatchQueue.main.async {
|
|
@@ -87,7 +90,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
|
-
|
|
93
|
+
|
|
91
94
|
@objc
|
|
92
95
|
public func showUniversalCheckoutWithClientToken(_ clientToken: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
93
96
|
DispatchQueue.main.async {
|
|
@@ -102,7 +105,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
|
-
|
|
108
|
+
|
|
106
109
|
@objc
|
|
107
110
|
public func showVaultManagerWithClientToken(_ clientToken: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
108
111
|
DispatchQueue.main.async {
|
|
@@ -117,7 +120,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
|
-
|
|
123
|
+
|
|
121
124
|
@objc
|
|
122
125
|
public func showPaymentMethod(_ paymentMethodTypeStr: String, intent: String, clientToken: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
123
126
|
DispatchQueue.main.async {
|
|
@@ -126,7 +129,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
126
129
|
let err = NSError(domain: "native-bridge", code: 0, userInfo: [NSLocalizedDescriptionKey: "Intent \(intent) is not valid."])
|
|
127
130
|
throw err
|
|
128
131
|
}
|
|
129
|
-
|
|
132
|
+
|
|
130
133
|
PrimerSDK.Primer.shared.showPaymentMethod(paymentMethodTypeStr, withIntent: primerIntent, andClientToken: clientToken) { err in
|
|
131
134
|
DispatchQueue.main.async {
|
|
132
135
|
if let err = err {
|
|
@@ -141,21 +144,21 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
|
-
|
|
147
|
+
|
|
145
148
|
@objc
|
|
146
149
|
public func dismiss() {
|
|
147
150
|
Primer.shared.dismiss()
|
|
148
151
|
}
|
|
149
|
-
|
|
152
|
+
|
|
150
153
|
@objc
|
|
151
154
|
public func dispose() {
|
|
152
155
|
Primer.shared.dismiss()
|
|
153
156
|
}
|
|
154
|
-
|
|
157
|
+
|
|
155
158
|
// MARK: - DECISION HANDLERS
|
|
156
|
-
|
|
159
|
+
|
|
157
160
|
// MARK: Tokenization
|
|
158
|
-
|
|
161
|
+
|
|
159
162
|
@objc
|
|
160
163
|
public func handleTokenizationNewClientToken(_ newClientToken: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
161
164
|
DispatchQueue.main.async {
|
|
@@ -164,7 +167,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
164
167
|
resolver(nil)
|
|
165
168
|
}
|
|
166
169
|
}
|
|
167
|
-
|
|
170
|
+
|
|
168
171
|
@objc
|
|
169
172
|
public func handleTokenizationSuccess(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
170
173
|
DispatchQueue.main.async {
|
|
@@ -173,7 +176,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
173
176
|
resolver(nil)
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
|
-
|
|
179
|
+
|
|
177
180
|
@objc
|
|
178
181
|
public func handleTokenizationFailure(_ errorMessage: String?, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
179
182
|
DispatchQueue.main.async {
|
|
@@ -182,9 +185,9 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
182
185
|
resolver(nil)
|
|
183
186
|
}
|
|
184
187
|
}
|
|
185
|
-
|
|
188
|
+
|
|
186
189
|
// MARK: Resume Payment
|
|
187
|
-
|
|
190
|
+
|
|
188
191
|
@objc
|
|
189
192
|
public func handleResumeWithNewClientToken(_ newClientToken: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
190
193
|
DispatchQueue.main.async {
|
|
@@ -193,7 +196,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
193
196
|
resolver(nil)
|
|
194
197
|
}
|
|
195
198
|
}
|
|
196
|
-
|
|
199
|
+
|
|
197
200
|
@objc
|
|
198
201
|
public func handleResumeSuccess(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
199
202
|
DispatchQueue.main.async {
|
|
@@ -202,7 +205,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
202
205
|
resolver(nil)
|
|
203
206
|
}
|
|
204
207
|
}
|
|
205
|
-
|
|
208
|
+
|
|
206
209
|
@objc
|
|
207
210
|
public func handleResumeFailure(_ errorMessage: String?, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
208
211
|
DispatchQueue.main.async {
|
|
@@ -211,9 +214,9 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
211
214
|
resolver(nil)
|
|
212
215
|
}
|
|
213
216
|
}
|
|
214
|
-
|
|
217
|
+
|
|
215
218
|
// MARK: Payment Creation
|
|
216
|
-
|
|
219
|
+
|
|
217
220
|
@objc
|
|
218
221
|
public func handlePaymentCreationAbort(_ errorMessage: String?, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
219
222
|
DispatchQueue.main.async {
|
|
@@ -222,7 +225,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
222
225
|
resolver(nil)
|
|
223
226
|
}
|
|
224
227
|
}
|
|
225
|
-
|
|
228
|
+
|
|
226
229
|
@objc
|
|
227
230
|
public func handlePaymentCreationContinue(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
228
231
|
DispatchQueue.main.async {
|
|
@@ -231,9 +234,9 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
231
234
|
resolver(nil)
|
|
232
235
|
}
|
|
233
236
|
}
|
|
234
|
-
|
|
237
|
+
|
|
235
238
|
// MARK: Error Handler
|
|
236
|
-
|
|
239
|
+
|
|
237
240
|
@objc
|
|
238
241
|
public func showErrorMessage(_ errorMessage: String?, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
239
242
|
DispatchQueue.main.async {
|
|
@@ -242,17 +245,17 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
242
245
|
resolver(nil)
|
|
243
246
|
}
|
|
244
247
|
}
|
|
245
|
-
|
|
248
|
+
|
|
246
249
|
// MARK: Helpers
|
|
247
|
-
|
|
250
|
+
|
|
248
251
|
private func configure(settingsStr: String? = nil) throws {
|
|
249
252
|
try PrimerSDK.Primer.shared.configure(settings: PrimerSettings.initialize(with: settingsStr), delegate: self)
|
|
250
253
|
}
|
|
251
|
-
|
|
254
|
+
|
|
252
255
|
private func detectImplemetedCallbacks() {
|
|
253
256
|
sendEvent(withName: PrimerEvents.detectImplementedRNCallbacks.stringValue, body: nil)
|
|
254
257
|
}
|
|
255
|
-
|
|
258
|
+
|
|
256
259
|
@objc
|
|
257
260
|
public func setImplementedRNCallbacks(_ implementedRNCallbacksStr: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
258
261
|
DispatchQueue.main.async {
|
|
@@ -265,19 +268,19 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
265
268
|
resolver(nil)
|
|
266
269
|
} catch {
|
|
267
270
|
self.primerDidFailWithError(error, data: nil) { decisionHandler in
|
|
268
|
-
|
|
271
|
+
|
|
269
272
|
}
|
|
270
273
|
rejecter(error.rnError["errorId"]!, error.rnError["description"], error)
|
|
271
274
|
}
|
|
272
275
|
}
|
|
273
276
|
}
|
|
274
|
-
|
|
277
|
+
|
|
275
278
|
private func handleRNBridgeError(_ error: Error, checkoutData: PrimerCheckoutData?, stopOnDebug: Bool) {
|
|
276
279
|
DispatchQueue.main.async {
|
|
277
280
|
if stopOnDebug {
|
|
278
281
|
assertionFailure(error.localizedDescription)
|
|
279
282
|
}
|
|
280
|
-
|
|
283
|
+
|
|
281
284
|
var body: [String: Any] = ["error": error.rnError]
|
|
282
285
|
if let checkoutData = checkoutData,
|
|
283
286
|
let data = try? JSONEncoder().encode(checkoutData),
|
|
@@ -293,7 +296,7 @@ class RNTPrimer: RCTEventEmitter {
|
|
|
293
296
|
// MARK: - PRIMER DELEGATE
|
|
294
297
|
|
|
295
298
|
extension RNTPrimer: PrimerDelegate {
|
|
296
|
-
|
|
299
|
+
|
|
297
300
|
func primerDidCompleteCheckoutWithData(_ data: PrimerCheckoutData) {
|
|
298
301
|
DispatchQueue.main.async {
|
|
299
302
|
if self.implementedRNCallbacks?.isOnCheckoutCompleteImplemented == true {
|
|
@@ -310,7 +313,27 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
310
313
|
}
|
|
311
314
|
}
|
|
312
315
|
}
|
|
313
|
-
|
|
316
|
+
|
|
317
|
+
func primerDidEnterResumePendingWithPaymentAdditionalInfo(_ additionalInfo: PrimerCheckoutAdditionalInfo?) {
|
|
318
|
+
DispatchQueue.main.async {
|
|
319
|
+
if self.implementedRNCallbacks?.isOnResumePendingImplemented == true {
|
|
320
|
+
do {
|
|
321
|
+
let checkoutAdditionalInfo = try JSONEncoder().encode(additionalInfo)
|
|
322
|
+
let checkoutAdditionalInfoJson = try JSONSerialization.jsonObject(with: checkoutAdditionalInfo, options: .allowFragments)
|
|
323
|
+
self.sendEvent(withName: PrimerHeadlessUniversalCheckoutEvents.onResumePending.stringValue, body: checkoutAdditionalInfoJson)
|
|
324
|
+
} catch {
|
|
325
|
+
let checkoutData = PrimerCheckoutData(payment: nil, additionalInfo: additionalInfo)
|
|
326
|
+
self.handleRNBridgeError(error, checkoutData: checkoutData, stopOnDebug: true)
|
|
327
|
+
}
|
|
328
|
+
} else {
|
|
329
|
+
let err = NSError(domain: "native-bridge", code: 1, userInfo: [NSLocalizedDescriptionKey: "Callback [onResumePending] should be implemented."])
|
|
330
|
+
let checkoutData = PrimerCheckoutData(payment: nil, additionalInfo: additionalInfo)
|
|
331
|
+
self.handleRNBridgeError(err, checkoutData: checkoutData, stopOnDebug: false)
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
|
|
314
337
|
func primerWillCreatePaymentWithData(_ data: PrimerCheckoutPaymentMethodData, decisionHandler: @escaping (PrimerPaymentCreationDecision) -> Void) {
|
|
315
338
|
if self.implementedRNCallbacks?.isOnBeforePaymentCreateImplemented == true {
|
|
316
339
|
self.primerWillCreatePaymentWithDataDecisionHandler = { errorMessage in
|
|
@@ -322,7 +345,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
322
345
|
}
|
|
323
346
|
}
|
|
324
347
|
}
|
|
325
|
-
|
|
348
|
+
|
|
326
349
|
DispatchQueue.main.async {
|
|
327
350
|
do {
|
|
328
351
|
let checkoutPaymentmethodData = try JSONEncoder().encode(data)
|
|
@@ -339,7 +362,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
339
362
|
}
|
|
340
363
|
}
|
|
341
364
|
}
|
|
342
|
-
|
|
365
|
+
|
|
343
366
|
func primerClientSessionWillUpdate() {
|
|
344
367
|
if self.implementedRNCallbacks?.isOnBeforeClientSessionUpdateImplemented == true {
|
|
345
368
|
DispatchQueue.main.async {
|
|
@@ -349,7 +372,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
349
372
|
// RN Dev hasn't implemented this callback, ignore.
|
|
350
373
|
}
|
|
351
374
|
}
|
|
352
|
-
|
|
375
|
+
|
|
353
376
|
func primerClientSessionDidUpdate(_ clientSession: PrimerClientSession) {
|
|
354
377
|
if self.implementedRNCallbacks?.isOnClientSessionUpdateImplemented == true {
|
|
355
378
|
do {
|
|
@@ -365,7 +388,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
365
388
|
// RN Dev hasn't implemented this callback, ignore.
|
|
366
389
|
}
|
|
367
390
|
}
|
|
368
|
-
|
|
391
|
+
|
|
369
392
|
func primerDidTokenizePaymentMethod(_ paymentMethodTokenData: PrimerPaymentMethodTokenData, decisionHandler: @escaping (PrimerResumeDecision) -> Void) {
|
|
370
393
|
if self.implementedRNCallbacks?.isOnTokenizeSuccessImplemented == true {
|
|
371
394
|
self.primerDidTokenizePaymentMethodDecisionHandler = { (newClientToken, errorMessage) in
|
|
@@ -379,7 +402,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
379
402
|
}
|
|
380
403
|
}
|
|
381
404
|
}
|
|
382
|
-
|
|
405
|
+
|
|
383
406
|
do {
|
|
384
407
|
let data = try JSONEncoder().encode(paymentMethodTokenData)
|
|
385
408
|
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
|
|
@@ -395,7 +418,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
395
418
|
// auto flow.
|
|
396
419
|
}
|
|
397
420
|
}
|
|
398
|
-
|
|
421
|
+
|
|
399
422
|
func primerDidResumeWith(_ resumeToken: String, decisionHandler: @escaping (PrimerResumeDecision) -> Void) {
|
|
400
423
|
if self.implementedRNCallbacks?.isOnResumeSuccessImplemented == true {
|
|
401
424
|
self.primerDidResumeWithDecisionHandler = { (resumeToken, errorMessage) in
|
|
@@ -409,7 +432,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
409
432
|
}
|
|
410
433
|
}
|
|
411
434
|
}
|
|
412
|
-
|
|
435
|
+
|
|
413
436
|
DispatchQueue.main.async {
|
|
414
437
|
self.sendEvent(withName: PrimerEvents.onResumeSuccess.stringValue, body: ["resumeToken": resumeToken])
|
|
415
438
|
}
|
|
@@ -418,7 +441,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
418
441
|
// Throw an error if it's the manual flow.
|
|
419
442
|
}
|
|
420
443
|
}
|
|
421
|
-
|
|
444
|
+
|
|
422
445
|
func primerDidDismiss() {
|
|
423
446
|
if self.implementedRNCallbacks?.isOnDismissImplemented == true {
|
|
424
447
|
DispatchQueue.main.async {
|
|
@@ -429,7 +452,7 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
429
452
|
// Ignore!
|
|
430
453
|
}
|
|
431
454
|
}
|
|
432
|
-
|
|
455
|
+
|
|
433
456
|
func primerDidFailWithError(_ error: Error, data: PrimerCheckoutData?, decisionHandler: @escaping ((PrimerErrorDecision) -> Void)) {
|
|
434
457
|
if self.implementedRNCallbacks?.isOnErrorImplemented == true {
|
|
435
458
|
// Set up the callback that will be called by **handleErrorMessage** when the RN
|
|
@@ -440,10 +463,10 @@ extension RNTPrimer: PrimerDelegate {
|
|
|
440
463
|
decisionHandler(.fail(withErrorMessage: errorMessage.isEmpty ? nil : errorMessage))
|
|
441
464
|
}
|
|
442
465
|
}
|
|
443
|
-
|
|
466
|
+
|
|
444
467
|
// Send the error message to the RN bridge.
|
|
445
468
|
self.handleRNBridgeError(error, checkoutData: nil, stopOnDebug: false)
|
|
446
|
-
|
|
469
|
+
|
|
447
470
|
} else {
|
|
448
471
|
// RN dev hasn't opted in on listening SDK dismiss.
|
|
449
472
|
// Ignore!
|