@primer-io/react-native 0.15.4 → 0.16.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 -4
- package/android/src/main/java/com/primerioreactnative/PrimerCardNumberEditTextManager.kt +83 -0
- package/android/src/main/java/com/primerioreactnative/PrimerHeadlessUniversalCheckout.kt +198 -0
- package/android/src/main/java/com/primerioreactnative/PrimerRN.kt +13 -8
- package/android/src/main/java/com/primerioreactnative/PrimerRNEventListener.kt +2 -1
- package/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt +14 -3
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerErrorRN.kt +2 -0
- package/android/src/main/java/com/primerioreactnative/huc/assets/AssetsManager.kt +56 -0
- package/android/src/main/java/com/primerioreactnative/huc/events/PrimerHeadlessUniversalCheckoutEvent.kt +11 -0
- package/android/src/main/java/com/primerioreactnative/huc/extensions/Map.kt +10 -0
- package/android/src/main/java/com/primerioreactnative/utils/ErrorHelper.kt +1 -1
- package/android/src/main/java/com/primerioreactnative/utils/Keys.kt +7 -0
- package/ios/{ReactNative-Bridging-Header.h → Core/ReactNative-Bridging-Header.h} +1 -0
- package/ios/DataModels/PrimerSettingsRN.swift +2 -6
- package/ios/Headless Universal Checkout/RNTPrimerCardNumberInputElementManager.m +23 -0
- package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.m +30 -0
- package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.swift +241 -0
- package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.m +14 -0
- package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.swift +113 -0
- package/ios/{Pods/Manifest.lock → Podfile.lock} +1 -1
- package/ios/RNTPrimer.swift +14 -0
- package/lib/commonjs/Primer.js +84 -124
- package/lib/commonjs/Primer.js.map +1 -1
- package/lib/commonjs/PrimerInput.js +80 -0
- package/lib/commonjs/PrimerInput.js.map +1 -0
- package/lib/commonjs/RNPrimer.js +1 -0
- package/lib/commonjs/RNPrimer.js.map +1 -1
- package/lib/commonjs/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js +14 -0
- package/lib/commonjs/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js.map +1 -0
- package/lib/commonjs/headless_checkout/NativePrimerHeadlessUniversalCheckout.js +110 -0
- package/lib/commonjs/headless_checkout/NativePrimerHeadlessUniversalCheckout.js.map +1 -0
- package/lib/commonjs/headless_checkout/PrimerHeadlessUniversalCheckout.js +117 -0
- package/lib/commonjs/headless_checkout/PrimerHeadlessUniversalCheckout.js.map +1 -0
- package/lib/commonjs/headless_checkout/types.js +2 -0
- package/lib/commonjs/headless_checkout/types.js.map +1 -0
- package/lib/commonjs/index.js +28 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/primer-callbacks.js +4 -0
- package/lib/commonjs/models/primer-config.js +4 -0
- package/lib/commonjs/models/primer-settings.js +4 -0
- package/lib/commonjs/models/primer.js +4 -0
- package/lib/commonjs/utils/index.js +1 -1
- package/lib/module/Primer.js +79 -118
- package/lib/module/Primer.js.map +1 -1
- package/lib/module/PrimerInput.js +46 -0
- package/lib/module/PrimerInput.js.map +1 -0
- package/lib/module/RNPrimer.js +1 -0
- package/lib/module/RNPrimer.js.map +1 -1
- package/lib/module/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js +5 -0
- package/lib/module/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js.map +1 -0
- package/lib/module/headless_checkout/NativePrimerHeadlessUniversalCheckout.js +98 -0
- package/lib/module/headless_checkout/NativePrimerHeadlessUniversalCheckout.js.map +1 -0
- package/lib/module/headless_checkout/PrimerHeadlessUniversalCheckout.js +100 -0
- package/lib/module/headless_checkout/PrimerHeadlessUniversalCheckout.js.map +1 -0
- package/lib/module/headless_checkout/types.js +2 -0
- package/lib/module/headless_checkout/types.js.map +1 -0
- package/lib/module/index.js +4 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/primer-callbacks.js +1 -1
- package/lib/module/models/primer-config.js +1 -1
- package/lib/module/models/primer-settings.js +1 -1
- package/lib/module/models/primer.js +1 -1
- package/lib/typescript/PrimerInput.d.ts +15 -0
- package/lib/typescript/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.d.ts +1 -0
- package/lib/typescript/headless_checkout/NativePrimerHeadlessUniversalCheckout.d.ts +13 -0
- package/lib/typescript/headless_checkout/PrimerHeadlessUniversalCheckout.d.ts +13 -0
- package/lib/typescript/headless_checkout/types.d.ts +16 -0
- package/lib/typescript/index.d.ts +3 -1
- package/lib/typescript/models/primer-config.d.ts +4 -0
- package/lib/typescript/models/primer-settings.d.ts +4 -2
- package/package.json +1 -1
- package/primer-io-react-native.podspec +1 -1
- package/src/Primer.ts +86 -124
- package/src/PrimerInput.tsx +73 -0
- package/src/RNPrimer.ts +1 -0
- package/src/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.tsx +2 -0
- package/src/headless_checkout/NativePrimerHeadlessUniversalCheckout.ts +132 -0
- package/src/headless_checkout/PrimerHeadlessUniversalCheckout.ts +140 -0
- package/src/headless_checkout/types.ts +18 -0
- package/src/index.tsx +3 -2
- package/src/models/primer-config.ts +5 -0
- package/src/models/primer-settings.ts +5 -2
- package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -344
- package/ios/Pods/Pods.xcodeproj/xcuserdata/aladintaleb.xcuserdatad/xcschemes/Pods-ReactNative.xcscheme +0 -60
- package/ios/Pods/Pods.xcodeproj/xcuserdata/aladintaleb.xcuserdatad/xcschemes/xcschememanagement.plist +0 -16
- package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative-acknowledgements.markdown +0 -3
- package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative-acknowledgements.plist +0 -29
- package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative.debug.xcconfig +0 -8
- package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative.release.xcconfig +0 -8
- package/ios/ReactNative.xcworkspace/xcuserdata/aladintaleb.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
package/android/build.gradle
CHANGED
|
@@ -37,9 +37,6 @@ android {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
buildTypes {
|
|
40
|
-
debug {
|
|
41
|
-
consumerProguardFiles 'consumer-rules.pro'
|
|
42
|
-
}
|
|
43
40
|
release {
|
|
44
41
|
consumerProguardFiles 'consumer-rules.pro'
|
|
45
42
|
minifyEnabled false
|
|
@@ -132,5 +129,5 @@ dependencies {
|
|
|
132
129
|
api 'com.facebook.react:react-native:+'
|
|
133
130
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
134
131
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1"
|
|
135
|
-
implementation 'io.primer:android:1.
|
|
132
|
+
implementation 'io.primer:android:1.15.0'
|
|
136
133
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
package com.primerioreactnative
|
|
2
|
+
|
|
3
|
+
import android.content.res.ColorStateList
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.graphics.drawable.ColorDrawable
|
|
6
|
+
import android.graphics.drawable.GradientDrawable
|
|
7
|
+
import android.view.ViewGroup
|
|
8
|
+
import android.widget.EditText
|
|
9
|
+
import android.widget.LinearLayout
|
|
10
|
+
import android.widget.TextView
|
|
11
|
+
import com.facebook.drawee.backends.pipeline.Fresco
|
|
12
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
13
|
+
import com.facebook.react.uimanager.SimpleViewManager
|
|
14
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
15
|
+
import com.facebook.react.uimanager.ViewProps
|
|
16
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
17
|
+
import com.facebook.react.views.image.ReactImageView
|
|
18
|
+
import io.primer.android.components.manager.PrimerCardManager
|
|
19
|
+
import io.primer.android.components.manager.PrimerUniversalCheckoutCardManagerInterface
|
|
20
|
+
import io.primer.android.components.ui.widgets.*
|
|
21
|
+
|
|
22
|
+
val listOfTextInputs = mutableListOf<PrimerEditText>()
|
|
23
|
+
|
|
24
|
+
class PrimerCardNumberEditTextManager : SimpleViewManager<PrimerCardNumberEditText>() {
|
|
25
|
+
|
|
26
|
+
override fun getName(): String {
|
|
27
|
+
return REACT_CLASS
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun createViewInstance(reactContext: ThemedReactContext): PrimerCardNumberEditText {
|
|
31
|
+
val editText = PrimerCardNumberEditText(reactContext)
|
|
32
|
+
return editText
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
companion object {
|
|
36
|
+
const val REACT_CLASS = "PrimerCardNumberEditText"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class PrimerCardholderNameEditTextManager : SimpleViewManager<PrimerCardholderNameEditText>() {
|
|
41
|
+
|
|
42
|
+
override fun getName(): String {
|
|
43
|
+
return REACT_CLASS
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun createViewInstance(reactContext: ThemedReactContext): PrimerCardholderNameEditText {
|
|
47
|
+
return PrimerCardholderNameEditText(reactContext)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
companion object {
|
|
51
|
+
const val REACT_CLASS = "PrimerCardholderNameEditText"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
class PrimerExpiryEditTextManager : SimpleViewManager<PrimerExpiryEditText>() {
|
|
56
|
+
|
|
57
|
+
override fun getName(): String {
|
|
58
|
+
return REACT_CLASS
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override fun createViewInstance(reactContext: ThemedReactContext): PrimerExpiryEditText {
|
|
62
|
+
return PrimerExpiryEditText(reactContext)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
companion object {
|
|
66
|
+
const val REACT_CLASS = "PrimerExpiryEditText"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class PrimerCvvEditTextManager : SimpleViewManager<PrimerCvvEditText>() {
|
|
71
|
+
|
|
72
|
+
override fun getName(): String {
|
|
73
|
+
return REACT_CLASS
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun createViewInstance(reactContext: ThemedReactContext): PrimerCvvEditText {
|
|
77
|
+
return PrimerCvvEditText(reactContext)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
companion object {
|
|
81
|
+
const val REACT_CLASS = "PrimerCvvEditText"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
package com.primerioreactnative
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.Nullable
|
|
4
|
+
import androidx.core.content.ContextCompat
|
|
5
|
+
import com.facebook.react.bridge.*
|
|
6
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
7
|
+
import com.primerioreactnative.datamodels.*
|
|
8
|
+
import com.primerioreactnative.huc.assets.AssetsManager
|
|
9
|
+
import com.primerioreactnative.huc.assets.AssetsManager.drawableToBitmap
|
|
10
|
+
import com.primerioreactnative.huc.assets.AssetsManager.getFile
|
|
11
|
+
import com.primerioreactnative.huc.events.PrimerHeadlessUniversalCheckoutEvent
|
|
12
|
+
import com.primerioreactnative.huc.extensions.toArgumentsMap
|
|
13
|
+
import com.primerioreactnative.utils.Keys
|
|
14
|
+
import com.primerioreactnative.utils.errorTo
|
|
15
|
+
import io.primer.android.completion.ResumeHandler
|
|
16
|
+
import io.primer.android.components.PrimerHeadlessUniversalCheckout
|
|
17
|
+
import io.primer.android.components.PrimerHeadlessUniversalCheckoutListener
|
|
18
|
+
import io.primer.android.components.domain.core.models.PrimerHeadlessUniversalCheckoutPaymentMethod
|
|
19
|
+
import io.primer.android.components.ui.assets.ImageType
|
|
20
|
+
import io.primer.android.model.dto.*
|
|
21
|
+
import kotlinx.serialization.decodeFromString
|
|
22
|
+
import kotlinx.serialization.encodeToString
|
|
23
|
+
import kotlinx.serialization.json.Json
|
|
24
|
+
import org.json.JSONObject
|
|
25
|
+
|
|
26
|
+
class PrimerHeadlessUniversalCheckout(
|
|
27
|
+
private val reactContext: ReactApplicationContext,
|
|
28
|
+
private val json: Json,
|
|
29
|
+
) : ReactContextBaseJavaModule(reactContext), PrimerHeadlessUniversalCheckoutListener {
|
|
30
|
+
|
|
31
|
+
override fun getName(): String {
|
|
32
|
+
return "PrimerHeadlessUniversalCheckout"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private var resumeHandler: ResumeHandler? = null
|
|
36
|
+
private var successCallback: Callback? = null
|
|
37
|
+
|
|
38
|
+
@ReactMethod
|
|
39
|
+
fun startWithClientToken(
|
|
40
|
+
clientToken: String,
|
|
41
|
+
settingsStr: String?,
|
|
42
|
+
errorCallback: Callback,
|
|
43
|
+
successCallback: Callback
|
|
44
|
+
) {
|
|
45
|
+
try {
|
|
46
|
+
val settings = if (settingsStr.isNullOrBlank()) PrimerSettingsRN() else
|
|
47
|
+
json.decodeFromString(settingsStr.orEmpty())
|
|
48
|
+
this.successCallback = successCallback
|
|
49
|
+
PrimerHeadlessUniversalCheckout.current.start(
|
|
50
|
+
reactContext,
|
|
51
|
+
clientToken,
|
|
52
|
+
PrimerConfig(settings = settings.format()),
|
|
53
|
+
this
|
|
54
|
+
)
|
|
55
|
+
} catch (e: Exception) {
|
|
56
|
+
errorCallback.invoke(
|
|
57
|
+
json.encodeToString(
|
|
58
|
+
ErrorTypeRN.InitFailed errorTo
|
|
59
|
+
"failed to initialise PrimerHeadlessUniversalCheckout SDK, error: $e",
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@ReactMethod
|
|
66
|
+
fun resumeWithClientToken(resumeToken: String) {
|
|
67
|
+
this.resumeHandler?.handleNewClientToken(resumeToken)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@ReactMethod
|
|
71
|
+
fun showPaymentMethod(paymentMethodType: String) {
|
|
72
|
+
val primerPaymentMethodType = PrimerPaymentMethodType.safeValueOf(paymentMethodType)
|
|
73
|
+
PrimerHeadlessUniversalCheckout.current.showPaymentMethod(
|
|
74
|
+
reactContext,
|
|
75
|
+
primerPaymentMethodType
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@ReactMethod
|
|
80
|
+
fun disposeHeadlessCheckout() {
|
|
81
|
+
PrimerHeadlessUniversalCheckout.current.cleanup()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@ReactMethod
|
|
85
|
+
fun getAssetForPaymentMethodType(
|
|
86
|
+
paymentMethodType: String,
|
|
87
|
+
assetType: String,
|
|
88
|
+
errorCallback: Callback,
|
|
89
|
+
successCallback: Callback
|
|
90
|
+
) {
|
|
91
|
+
|
|
92
|
+
val primerPaymentMethodType = PrimerPaymentMethodType.safeValueOf(paymentMethodType)
|
|
93
|
+
val type = ImageType.values().find { it.name.equals(assetType, ignoreCase = true) }
|
|
94
|
+
when {
|
|
95
|
+
primerPaymentMethodType == PaymentMethodType.UNKNOWN -> {
|
|
96
|
+
errorCallback.invoke(
|
|
97
|
+
json.encodeToString(
|
|
98
|
+
ErrorTypeRN.AssetMissing errorTo
|
|
99
|
+
"Asset for $paymentMethodType does not exist, make sure you don't have any typos."
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
type == null -> {
|
|
104
|
+
errorCallback.invoke(
|
|
105
|
+
json.encodeToString(
|
|
106
|
+
ErrorTypeRN.AssetMismatch errorTo
|
|
107
|
+
"You have provided assetType=$assetType, but variable assetType can be 'LOGO' or 'ICON'."
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
else -> {
|
|
112
|
+
PrimerHeadlessUniversalCheckout.getAsset(primerPaymentMethodType, type)?.let { resourceId ->
|
|
113
|
+
val file = getFile(reactContext, paymentMethodType)
|
|
114
|
+
AssetsManager.saveBitmapToFile(
|
|
115
|
+
file,
|
|
116
|
+
drawableToBitmap(ContextCompat.getDrawable(reactContext, resourceId)!!),
|
|
117
|
+
)
|
|
118
|
+
successCallback.invoke("file://${file.absolutePath}")
|
|
119
|
+
} ?: run {
|
|
120
|
+
errorCallback.invoke(
|
|
121
|
+
json.encodeToString(
|
|
122
|
+
ErrorTypeRN.AssetMissing errorTo
|
|
123
|
+
"Failed to find $paymentMethodType for $assetType"
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
override fun onClientSessionSetupSuccessfully(paymentMethods: List<PrimerHeadlessUniversalCheckoutPaymentMethod>) {
|
|
132
|
+
sendEvent(PrimerHeadlessUniversalCheckoutEvent.CLIENT_SESSION_SETUP_SUCCESS)
|
|
133
|
+
successCallback?.invoke(
|
|
134
|
+
Arguments.fromList(paymentMethods.map { it.paymentMethodType.name })
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
override fun onTokenizationPreparation() {
|
|
139
|
+
sendEvent(PrimerHeadlessUniversalCheckoutEvent.TOKENIZATION_PREPARATION_STARTED)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
override fun onTokenizationStarted() {
|
|
143
|
+
sendEvent(PrimerHeadlessUniversalCheckoutEvent.TOKENIZATION_STARTED)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override fun onPaymentMethodShowed() {
|
|
147
|
+
sendEvent(PrimerHeadlessUniversalCheckoutEvent.PAYMENT_METH0D_SHOWED)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
override fun onTokenizationSuccess(
|
|
151
|
+
paymentMethodToken: PaymentMethodToken,
|
|
152
|
+
resumeHandler: ResumeHandler
|
|
153
|
+
) {
|
|
154
|
+
this.resumeHandler = resumeHandler
|
|
155
|
+
|
|
156
|
+
sendEvent(
|
|
157
|
+
PrimerHeadlessUniversalCheckoutEvent.TOKENIZATION_SUCCESS,
|
|
158
|
+
mapOf(
|
|
159
|
+
Keys.PAYMENT_METHOD_TOKEN to json.encodeToString(
|
|
160
|
+
PrimerPaymentInstrumentTokenRN.fromPaymentMethodToken(
|
|
161
|
+
paymentMethodToken
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
).toArgumentsMap()
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
override fun onResumeSuccess(resumeToken: String, resumeHandler: ResumeHandler) {
|
|
169
|
+
this.resumeHandler = resumeHandler
|
|
170
|
+
|
|
171
|
+
sendEvent(
|
|
172
|
+
PrimerHeadlessUniversalCheckoutEvent.RESUME,
|
|
173
|
+
mapOf(Keys.RESUME_TOKEN to resumeToken).toArgumentsMap()
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
override fun onError(error: APIError) {
|
|
178
|
+
sendEvent(
|
|
179
|
+
PrimerHeadlessUniversalCheckoutEvent.ERROR,
|
|
180
|
+
mapOf(
|
|
181
|
+
Keys.ERROR to json.encodeToString(
|
|
182
|
+
ErrorTypeRN.CheckoutFlowFailed errorTo
|
|
183
|
+
error.description
|
|
184
|
+
)
|
|
185
|
+
).toArgumentsMap()
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
private fun sendEvent(
|
|
191
|
+
event: PrimerHeadlessUniversalCheckoutEvent,
|
|
192
|
+
@Nullable params: WritableMap? = null
|
|
193
|
+
) {
|
|
194
|
+
reactContext
|
|
195
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
196
|
+
.emit(event.eventName, params)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -4,19 +4,21 @@ import android.util.Log
|
|
|
4
4
|
import com.facebook.react.bridge.*
|
|
5
5
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
6
6
|
import com.primerioreactnative.datamodels.*
|
|
7
|
+
import com.primerioreactnative.utils.Keys
|
|
7
8
|
import com.primerioreactnative.utils.PrimerImplementedRNCallbacks
|
|
8
9
|
import com.primerioreactnative.utils.errorTo
|
|
9
10
|
import io.primer.android.PaymentMethodIntent
|
|
10
11
|
import io.primer.android.Primer
|
|
11
12
|
import io.primer.android.model.dto.PrimerConfig
|
|
12
13
|
import io.primer.android.model.dto.PrimerPaymentMethod
|
|
14
|
+
import io.primer.android.model.dto.PrimerPaymentMethodType
|
|
13
15
|
import kotlinx.serialization.decodeFromString
|
|
14
16
|
import kotlinx.serialization.encodeToString
|
|
15
17
|
import kotlinx.serialization.json.Json
|
|
16
18
|
import org.json.JSONObject
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
class PrimerRN(reactContext: ReactApplicationContext) :
|
|
21
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
20
22
|
|
|
21
23
|
private var settings: PrimerSettingsRN = PrimerSettingsRN()
|
|
22
24
|
private var theme: PrimerThemeRN = PrimerThemeRN()
|
|
@@ -121,7 +123,7 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
|
|
|
121
123
|
promise: Promise
|
|
122
124
|
) {
|
|
123
125
|
try {
|
|
124
|
-
this.intent = PaymentMethodIntent.valueOf(intentStr)
|
|
126
|
+
this.intent = PaymentMethodIntent.valueOf(intentStr.uppercase())
|
|
125
127
|
} catch (e: Exception) {
|
|
126
128
|
val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse intent."
|
|
127
129
|
checkoutFailed(exception)
|
|
@@ -129,7 +131,7 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
|
|
|
129
131
|
return
|
|
130
132
|
}
|
|
131
133
|
try {
|
|
132
|
-
val paymentMethod =
|
|
134
|
+
val paymentMethod = getPrimerPaymentMethod(paymentMethodTypeStr)
|
|
133
135
|
this.paymentMethod = paymentMethod
|
|
134
136
|
} catch (e: Exception) {
|
|
135
137
|
val exception = ErrorTypeRN.CheckoutFlowFailed errorTo "failed to parse payment method type."
|
|
@@ -266,9 +268,12 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
|
|
|
266
268
|
}
|
|
267
269
|
}
|
|
268
270
|
}
|
|
269
|
-
}
|
|
270
271
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
private fun getPrimerPaymentMethod(paymentMethodTypeStr: String): PrimerPaymentMethod {
|
|
273
|
+
if (PrimerPaymentMethodType.PAYMENT_CARD.name == paymentMethodTypeStr) {
|
|
274
|
+
return PrimerPaymentMethod.CARD
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return PrimerPaymentMethod.valueOf(paymentMethodTypeStr)
|
|
278
|
+
}
|
|
274
279
|
}
|
|
@@ -2,6 +2,7 @@ package com.primerioreactnative
|
|
|
2
2
|
|
|
3
3
|
import android.util.Log
|
|
4
4
|
import com.primerioreactnative.datamodels.*
|
|
5
|
+
import com.primerioreactnative.utils.Keys
|
|
5
6
|
import com.primerioreactnative.utils.PrimerImplementedRNCallbacks
|
|
6
7
|
import com.primerioreactnative.utils.asError
|
|
7
8
|
import com.primerioreactnative.utils.errorTo
|
|
@@ -125,7 +126,7 @@ class PrimerRNEventListener : CheckoutEventListener {
|
|
|
125
126
|
sendError?.invoke(exception)
|
|
126
127
|
} else {
|
|
127
128
|
sendError?.invoke(ErrorTypeRN.InitFailed
|
|
128
|
-
errorTo "Callback [
|
|
129
|
+
errorTo "Callback [onError] should had been implemented.")
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
else -> Unit
|
|
@@ -4,15 +4,26 @@ import com.facebook.react.ReactPackage
|
|
|
4
4
|
import com.facebook.react.bridge.NativeModule
|
|
5
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
6
|
import com.facebook.react.uimanager.ViewManager
|
|
7
|
-
|
|
7
|
+
import kotlinx.serialization.json.Json
|
|
8
8
|
|
|
9
9
|
class ReactNativePackage : ReactPackage {
|
|
10
|
+
|
|
11
|
+
private val json = Json { ignoreUnknownKeys = true }
|
|
12
|
+
|
|
10
13
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
|
-
return listOf(
|
|
14
|
+
return listOf(
|
|
15
|
+
PrimerRN(reactContext),
|
|
16
|
+
PrimerHeadlessUniversalCheckout(reactContext, json)
|
|
17
|
+
)
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
-
return
|
|
21
|
+
return mutableListOf(
|
|
22
|
+
PrimerCardNumberEditTextManager(),
|
|
23
|
+
PrimerCardholderNameEditTextManager(),
|
|
24
|
+
PrimerExpiryEditTextManager(),
|
|
25
|
+
PrimerCvvEditTextManager(),
|
|
26
|
+
)
|
|
16
27
|
}
|
|
17
28
|
}
|
|
18
29
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
package com.primerioreactnative.huc.assets
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.drawable.BitmapDrawable
|
|
6
|
+
import android.graphics.drawable.Drawable
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import java.io.File
|
|
9
|
+
import java.io.FileOutputStream
|
|
10
|
+
import java.util.*
|
|
11
|
+
|
|
12
|
+
internal object AssetsManager {
|
|
13
|
+
|
|
14
|
+
private const val ASSETS_DIRECTORY = "primer-sdk"
|
|
15
|
+
private const val COMPRESS_QUALITY = 100
|
|
16
|
+
|
|
17
|
+
fun drawableToBitmap(drawable: Drawable): Bitmap {
|
|
18
|
+
if (drawable is BitmapDrawable) {
|
|
19
|
+
return drawable.bitmap
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
val bitmap = Bitmap.createBitmap(
|
|
23
|
+
drawable.intrinsicWidth,
|
|
24
|
+
drawable.intrinsicHeight,
|
|
25
|
+
Bitmap.Config.ARGB_8888
|
|
26
|
+
)
|
|
27
|
+
val canvas = Canvas(bitmap)
|
|
28
|
+
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
|
29
|
+
drawable.draw(canvas)
|
|
30
|
+
return bitmap
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fun saveBitmapToFile(
|
|
34
|
+
file: File,
|
|
35
|
+
bitmap: Bitmap,
|
|
36
|
+
format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG,
|
|
37
|
+
) {
|
|
38
|
+
|
|
39
|
+
FileOutputStream(file).use {
|
|
40
|
+
bitmap.compress(format, COMPRESS_QUALITY, it)
|
|
41
|
+
it.close()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fun getFile(context: ReactApplicationContext, path: String): File {
|
|
46
|
+
val directory = File(context.filesDir, path)
|
|
47
|
+
if (!directory.exists()) directory.mkdirs()
|
|
48
|
+
val file = File(
|
|
49
|
+
context.filesDir,
|
|
50
|
+
ASSETS_DIRECTORY + File.pathSeparator + path.toLowerCase(Locale.ROOT)
|
|
51
|
+
)
|
|
52
|
+
if (!file.exists()) file.createNewFile()
|
|
53
|
+
return file
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package com.primerioreactnative.huc.events
|
|
2
|
+
|
|
3
|
+
internal enum class PrimerHeadlessUniversalCheckoutEvent(val eventName: String) {
|
|
4
|
+
CLIENT_SESSION_SETUP_SUCCESS("clientSessionDidSetUpSuccessfully"),
|
|
5
|
+
TOKENIZATION_PREPARATION_STARTED("preparationStarted"),
|
|
6
|
+
PAYMENT_METH0D_SHOWED("paymentMethodPresented"),
|
|
7
|
+
TOKENIZATION_STARTED("tokenizationStarted"),
|
|
8
|
+
TOKENIZATION_SUCCESS("tokenizationSucceeded"),
|
|
9
|
+
RESUME("resume"),
|
|
10
|
+
ERROR("error");
|
|
11
|
+
}
|
|
@@ -22,7 +22,7 @@ extension PrimerSettingsRN {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
let debugOptions = PrimerDebugOptions(is3DSSanityCheckEnabled: !(options?.is3DSDevelopmentModeEnabled ?? false))
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
return PrimerSettings(
|
|
27
27
|
merchantIdentifier: options?.ios?.merchantIdentifier,
|
|
28
28
|
customerId: customer?.id,
|
|
@@ -103,13 +103,9 @@ fileprivate struct BusinessRN: Decodable {
|
|
|
103
103
|
|
|
104
104
|
fileprivate extension BusinessRN {
|
|
105
105
|
var primerFormat: BusinessDetails? {
|
|
106
|
-
guard let address = address else {
|
|
107
|
-
return nil
|
|
108
|
-
}
|
|
109
|
-
|
|
110
106
|
return BusinessDetails(
|
|
111
107
|
name: name,
|
|
112
|
-
address: address
|
|
108
|
+
address: address?.primerFormat
|
|
113
109
|
)
|
|
114
110
|
}
|
|
115
111
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNTPrimerCardNumberInputElementManager.m
|
|
3
|
+
// primer-io-react-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Evangelos on 3/3/22.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <React/RCTViewManager.h>
|
|
9
|
+
@import PrimerSDK;
|
|
10
|
+
|
|
11
|
+
@interface RNTPrimerCardNumberInputElementManager : RCTViewManager
|
|
12
|
+
@end
|
|
13
|
+
|
|
14
|
+
@implementation RNTPrimerCardNumberInputElementManager
|
|
15
|
+
|
|
16
|
+
RCT_EXPORT_MODULE(PrimerCardNumberEditText)
|
|
17
|
+
|
|
18
|
+
- (UIView *)view
|
|
19
|
+
{
|
|
20
|
+
return [[PrimerCardNumberInputElement alloc] init];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNTPrimerHeadlessUniversalCheckout.m
|
|
3
|
+
// primer-io-react-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Evangelos on 8/3/22.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <React/RCTBridgeModule.h>
|
|
9
|
+
#import <React/RCTEventEmitter.h>
|
|
10
|
+
|
|
11
|
+
@interface RCT_EXTERN_MODULE(PrimerHeadlessUniversalCheckout, RCTEventEmitter)
|
|
12
|
+
|
|
13
|
+
RCT_EXTERN_METHOD(startWithClientToken:(NSString *)clientToken settingsStr:(NSString *)settingsStr errorCallback:(RCTResponseSenderBlock)errorCallback successCallback: (RCTResponseSenderBlock)successCallback)
|
|
14
|
+
|
|
15
|
+
RCT_EXTERN_METHOD(resumeWithClientToken:(NSString *)resumeToken)
|
|
16
|
+
|
|
17
|
+
RCT_EXTERN_METHOD(showPaymentMethod:(NSString *)paymentMethodTypeStr)
|
|
18
|
+
|
|
19
|
+
RCT_EXTERN_METHOD(getAssetForPaymentMethodType:(NSString *)paymentMethodTypeStr
|
|
20
|
+
assetType:(NSString *)assetTypeStr
|
|
21
|
+
errorCallback:(RCTResponseSenderBlock)errorCallback
|
|
22
|
+
successCallback: (RCTResponseSenderBlock)successCallback)
|
|
23
|
+
|
|
24
|
+
RCT_EXTERN_METHOD(getAssetForCardNetwork:(NSString *)cardNetworkStr
|
|
25
|
+
assetType:(NSString *)assetTypeStr
|
|
26
|
+
errorCallback:(RCTResponseSenderBlock)errorCallback
|
|
27
|
+
successCallback: (RCTResponseSenderBlock)successCallback)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@end
|