judokit-react-native 3.4.9 → 4.0.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/JudoPay.tsx +41 -26
- package/RNJudopay.podspec +1 -1
- package/android/build.gradle +113 -124
- package/android/src/main/java/com/reactlibrary/Extensions.kt +187 -5
- package/android/src/main/java/com/reactlibrary/Helpers.kt +177 -16
- package/android/src/main/java/com/reactlibrary/JudoReactNativeModule.kt +54 -1
- package/ios/.xcode.env +11 -0
- package/ios/Classes/RNJudo.m +22 -6
- package/ios/Classes/Wrappers/RNWrappers.m +448 -79
- package/ios/Podfile +28 -56
- package/ios/Podfile.lock +418 -208
- package/ios/RNJudo.xcodeproj/project.pbxproj +21 -16
- package/ios/RNJudo.xcodeproj/xcshareddata/xcschemes/RNJudo.xcscheme +1 -1
- package/package.json +31 -25
- package/types/JudoTypes.tsx +80 -23
|
@@ -5,6 +5,11 @@ import android.os.Bundle
|
|
|
5
5
|
import com.facebook.react.bridge.Arguments
|
|
6
6
|
import com.facebook.react.bridge.ReadableMap
|
|
7
7
|
import com.facebook.react.bridge.WritableMap
|
|
8
|
+
import com.judopay.judo3ds2.customization.ButtonCustomization
|
|
9
|
+
import com.judopay.judo3ds2.customization.LabelCustomization
|
|
10
|
+
import com.judopay.judo3ds2.customization.TextBoxCustomization
|
|
11
|
+
import com.judopay.judo3ds2.customization.ToolbarCustomization
|
|
12
|
+
import com.judopay.judo3ds2.customization.UiCustomization
|
|
8
13
|
import com.judopay.judokit.android.Judo
|
|
9
14
|
import com.judopay.judokit.android.api.model.Authorization
|
|
10
15
|
import com.judopay.judokit.android.api.model.BasicAuthorization
|
|
@@ -16,6 +21,41 @@ import com.judopay.judokit.android.model.googlepay.GooglePayBillingAddressParame
|
|
|
16
21
|
import com.judopay.judokit.android.model.googlepay.GooglePayEnvironment
|
|
17
22
|
import com.judopay.judokit.android.model.googlepay.GooglePayShippingAddressParameters
|
|
18
23
|
|
|
24
|
+
// For consistency with:
|
|
25
|
+
// https://github.com/Judopay/JudoKit-iOS/blob/master/Source/Models/Response/JPResponse.m#L36
|
|
26
|
+
private const val TRANSACTION_TYPE_PAYMENT = "payment"
|
|
27
|
+
private const val TRANSACTION_TYPE_PRE_AUTH = "preauth"
|
|
28
|
+
private const val TRANSACTION_TYPE_REGISTER = "register"
|
|
29
|
+
private const val TRANSACTION_TYPE_REGISTER_CARD = "registercard"
|
|
30
|
+
private const val TRANSACTION_TYPE_SAVE_CARD = "save"
|
|
31
|
+
private const val TRANSACTION_TYPE_CHECK_CARD = "checkcard"
|
|
32
|
+
|
|
33
|
+
// For consistency with:
|
|
34
|
+
// https://github.com/Judopay/JudoKit-iOS/blob/master/Source/Models/Transaction/JPTransactionType.h#L30
|
|
35
|
+
private enum class TransactionType(val value: Int, val typeAsStrings: List<String>? = null) {
|
|
36
|
+
PAYMENT(1, listOf(TRANSACTION_TYPE_PAYMENT)),
|
|
37
|
+
PRE_AUTH(2, listOf(TRANSACTION_TYPE_PRE_AUTH)),
|
|
38
|
+
REGISTER_CARD(3, listOf(TRANSACTION_TYPE_REGISTER, TRANSACTION_TYPE_REGISTER_CARD)),
|
|
39
|
+
CHECK_CARD(4, listOf(TRANSACTION_TYPE_CHECK_CARD)),
|
|
40
|
+
SAVE_CARD(5, listOf(TRANSACTION_TYPE_SAVE_CARD)),
|
|
41
|
+
UNKNOWN(-1)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// For consistency with:
|
|
45
|
+
// https://github.com/Judopay/JudoKit-iOS/blob/master/Source/Models/Response/JPResponse.m#L32
|
|
46
|
+
private const val STATUS_DECLINED = "declined"
|
|
47
|
+
private const val STATUS_SUCCESS = "success"
|
|
48
|
+
private const val STATUS_ERROR = "error"
|
|
49
|
+
|
|
50
|
+
// For consistency with:
|
|
51
|
+
// https://github.com/Judopay/JudoKit-iOS/blob/abd34bbfe4784fb5f074ed30f93d6743ba295622/Source/Models/Transaction/JPTransactionResult.h#L27
|
|
52
|
+
private enum class TransactionResult(val value: Int, val status: String? = null) {
|
|
53
|
+
ERROR(0, STATUS_ERROR),
|
|
54
|
+
SUCCESS(1, STATUS_SUCCESS),
|
|
55
|
+
DECLINED(2, STATUS_DECLINED),
|
|
56
|
+
UNKNOWN(-1)
|
|
57
|
+
}
|
|
58
|
+
|
|
19
59
|
internal fun getTransactionConfiguration(options: ReadableMap): Judo {
|
|
20
60
|
val widgetType = getTransactionTypeWidget(options)
|
|
21
61
|
return getJudoConfiguration(widgetType, options)
|
|
@@ -45,20 +85,19 @@ internal fun getPaymentMethodsConfiguration(options: ReadableMap): Judo {
|
|
|
45
85
|
}
|
|
46
86
|
|
|
47
87
|
internal fun getMappedType(type: String?): Int {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"Save" -> 4
|
|
53
|
-
else -> 0
|
|
54
|
-
}
|
|
88
|
+
val typeInLowercase = type?.lowercase()
|
|
89
|
+
val typeValue = TransactionType.values().firstOrNull { it.typeAsStrings?.contains(typeInLowercase) ?: false }
|
|
90
|
+
|
|
91
|
+
return typeValue?.value ?: TransactionType.UNKNOWN.value
|
|
55
92
|
}
|
|
56
93
|
|
|
94
|
+
// consistent with:
|
|
95
|
+
// https://github.com/Judopay/JudoKit-iOS/blob/master/Source/Models/Response/JPResponse.m#L125
|
|
57
96
|
internal fun getMappedResult(result: String?): Int {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
97
|
+
val resultInLowercase = result?.lowercase()
|
|
98
|
+
val resultValue = TransactionResult.values().firstOrNull { it.status == resultInLowercase }
|
|
99
|
+
|
|
100
|
+
return resultValue?.value ?: TransactionResult.UNKNOWN.value
|
|
62
101
|
}
|
|
63
102
|
|
|
64
103
|
internal fun getMappedResult(result: JudoResult?): WritableMap {
|
|
@@ -87,6 +126,7 @@ internal fun getMappedResult(result: JudoResult?): WritableMap {
|
|
|
87
126
|
cardDetailsMap.putString("cardCountry", result?.cardDetails?.country)
|
|
88
127
|
cardDetailsMap.putString("cardFunding", result?.cardDetails?.funding)
|
|
89
128
|
cardDetailsMap.putString("cardScheme", result?.cardDetails?.scheme)
|
|
129
|
+
cardDetailsMap.putString("cardHolderName", result?.cardDetails?.cardHolderName)
|
|
90
130
|
|
|
91
131
|
map.putMap("cardDetails", cardDetailsMap)
|
|
92
132
|
|
|
@@ -99,6 +139,27 @@ internal fun getMappedResult(result: JudoResult?): WritableMap {
|
|
|
99
139
|
return map
|
|
100
140
|
}
|
|
101
141
|
|
|
142
|
+
internal fun getJudoConfigurationForApiService(options: ReadableMap): Judo {
|
|
143
|
+
val authorization = getAuthorization(options)
|
|
144
|
+
|
|
145
|
+
val amount = Amount.Builder()
|
|
146
|
+
.setAmount("0.00")
|
|
147
|
+
.setCurrency(Currency.GBP)
|
|
148
|
+
.build()
|
|
149
|
+
|
|
150
|
+
val reference = Reference.Builder()
|
|
151
|
+
.setConsumerReference("reference")
|
|
152
|
+
.build()
|
|
153
|
+
|
|
154
|
+
return Judo.Builder(PaymentWidgetType.CARD_PAYMENT)
|
|
155
|
+
.setIsSandboxed(options.isSandboxed)
|
|
156
|
+
.setJudoId("000000")
|
|
157
|
+
.setAuthorization(authorization)
|
|
158
|
+
.setAmount(amount)
|
|
159
|
+
.setReference(reference)
|
|
160
|
+
.build()
|
|
161
|
+
}
|
|
162
|
+
|
|
102
163
|
internal fun getJudoConfiguration(type: PaymentWidgetType, options: ReadableMap): Judo {
|
|
103
164
|
val authorization = getAuthorization(options)
|
|
104
165
|
val amount = getAmount(options)
|
|
@@ -127,6 +188,7 @@ internal fun getJudoConfiguration(type: PaymentWidgetType, options: ReadableMap)
|
|
|
127
188
|
.setGooglePayConfiguration(googlePayConfiguration)
|
|
128
189
|
.setPBBAConfiguration(pbbaConfiguration)
|
|
129
190
|
.setInitialRecurringPayment(options.isInitialRecurringPayment)
|
|
191
|
+
.setDelayedAuthorisation(options.isDelayedAuthorisation)
|
|
130
192
|
.setNetworkTimeout(timeouts)
|
|
131
193
|
.setChallengeRequestIndicator(challengeRequestIndicator)
|
|
132
194
|
.setScaExemption(scaExemption)
|
|
@@ -191,11 +253,12 @@ internal fun getAuthorization(options: ReadableMap): Authorization {
|
|
|
191
253
|
}
|
|
192
254
|
|
|
193
255
|
internal fun getTransactionTypeWidget(options: ReadableMap) = when (options.getInt("transactionType")) {
|
|
194
|
-
1 -> PaymentWidgetType.
|
|
195
|
-
2 -> PaymentWidgetType.
|
|
196
|
-
3 -> PaymentWidgetType.
|
|
197
|
-
4 -> PaymentWidgetType.
|
|
198
|
-
|
|
256
|
+
1 -> PaymentWidgetType.CARD_PAYMENT
|
|
257
|
+
2 -> PaymentWidgetType.PRE_AUTH
|
|
258
|
+
3 -> PaymentWidgetType.REGISTER_CARD
|
|
259
|
+
4 -> PaymentWidgetType.CHECK_CARD
|
|
260
|
+
5 -> PaymentWidgetType.CREATE_CARD_TOKEN
|
|
261
|
+
else -> throw IllegalArgumentException("Unknown transaction type")
|
|
199
262
|
}
|
|
200
263
|
|
|
201
264
|
internal fun getTransactionModeWidget(options: ReadableMap) = when (options.getInt("transactionMode")) {
|
|
@@ -331,12 +394,110 @@ internal fun getUIConfiguration(options: ReadableMap): UiConfiguration? {
|
|
|
331
394
|
.setShouldPaymentButtonDisplayAmount(options.shouldPaymentButtonDisplayAmount)
|
|
332
395
|
.setShouldPaymentMethodsVerifySecurityCode(options.shouldPaymentMethodsVerifySecurityCode)
|
|
333
396
|
.setShouldAskForBillingInformation(options.shouldAskForBillingInformation)
|
|
397
|
+
.setThreeDSUiCustomization(getThreeDSUiCustomization(options))
|
|
334
398
|
.build()
|
|
335
399
|
} else {
|
|
336
400
|
null
|
|
337
401
|
}
|
|
338
402
|
}
|
|
339
403
|
|
|
404
|
+
internal fun getThreeDSUiCustomization(options: ReadableMap): UiCustomization? {
|
|
405
|
+
return if (options.threeDSUIConfiguration != null) {
|
|
406
|
+
|
|
407
|
+
val uiCustomization = UiCustomization()
|
|
408
|
+
|
|
409
|
+
options.threeDSUIToolbarCustomization?.let {
|
|
410
|
+
uiCustomization.setToolbarCustomization(ToolbarCustomization().apply {
|
|
411
|
+
setTextFontName(it.textFontName)
|
|
412
|
+
setTextColor(it.textColor)
|
|
413
|
+
setTextFontSize(it.textFontSize)
|
|
414
|
+
setBackgroundColor(it.backgroundColor)
|
|
415
|
+
setHeaderText(it.headerText)
|
|
416
|
+
setButtonText(it.buttonText)
|
|
417
|
+
})
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
options.threeDSUILabelCustomization?.let {
|
|
421
|
+
uiCustomization.setLabelCustomization(LabelCustomization().apply {
|
|
422
|
+
setTextFontName(it.textFontName)
|
|
423
|
+
setTextColor(it.textColor)
|
|
424
|
+
setTextFontSize(it.textFontSize)
|
|
425
|
+
setHeadingTextFontName(it.headingTextFontName)
|
|
426
|
+
setHeadingTextColor(it.headingTextColor)
|
|
427
|
+
setHeadingTextFontSize(it.headingTextFontSize)
|
|
428
|
+
})
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
options.threeDSUITextBoxCustomization?.let {
|
|
432
|
+
uiCustomization.setTextBoxCustomization(TextBoxCustomization().apply {
|
|
433
|
+
setTextFontName(it.textFontName)
|
|
434
|
+
setTextColor(it.textColor)
|
|
435
|
+
setTextFontSize(it.textFontSize)
|
|
436
|
+
setBorderWidth(it.borderWidth)
|
|
437
|
+
setBorderColor(it.borderColor)
|
|
438
|
+
setCornerRadius(it.cornerRadius)
|
|
439
|
+
})
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (options.threeDSUIButtonCustomizations != null) {
|
|
443
|
+
|
|
444
|
+
options.threeDSUISubmitButtonCustomization?.let {
|
|
445
|
+
uiCustomization.setButtonCustomization(ButtonCustomization().apply {
|
|
446
|
+
setTextFontName(it.textFontName)
|
|
447
|
+
setTextColor(it.textColor)
|
|
448
|
+
setTextFontSize(it.textFontSize)
|
|
449
|
+
setBackgroundColor(it.backgroundColor)
|
|
450
|
+
setCornerRadius(it.cornerRadius)
|
|
451
|
+
}, UiCustomization.ButtonType.SUBMIT)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
options.threeDSUINextButtonCustomization?.let {
|
|
455
|
+
uiCustomization.setButtonCustomization(ButtonCustomization().apply {
|
|
456
|
+
setTextFontName(it.textFontName)
|
|
457
|
+
setTextColor(it.textColor)
|
|
458
|
+
setTextFontSize(it.textFontSize)
|
|
459
|
+
setBackgroundColor(it.backgroundColor)
|
|
460
|
+
setCornerRadius(it.cornerRadius)
|
|
461
|
+
}, UiCustomization.ButtonType.NEXT)
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
options.threeDSUIContinueButtonCustomization?.let {
|
|
465
|
+
uiCustomization.setButtonCustomization(ButtonCustomization().apply {
|
|
466
|
+
setTextFontName(it.textFontName)
|
|
467
|
+
setTextColor(it.textColor)
|
|
468
|
+
setTextFontSize(it.textFontSize)
|
|
469
|
+
setBackgroundColor(it.backgroundColor)
|
|
470
|
+
setCornerRadius(it.cornerRadius)
|
|
471
|
+
}, UiCustomization.ButtonType.CONTINUE)
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
options.threeDSUICancelButtonCustomization?.let {
|
|
475
|
+
uiCustomization.setButtonCustomization(ButtonCustomization().apply {
|
|
476
|
+
setTextFontName(it.textFontName)
|
|
477
|
+
setTextColor(it.textColor)
|
|
478
|
+
setTextFontSize(it.textFontSize)
|
|
479
|
+
setBackgroundColor(it.backgroundColor)
|
|
480
|
+
setCornerRadius(it.cornerRadius)
|
|
481
|
+
}, UiCustomization.ButtonType.CANCEL)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
options.threeDSUIResendButtonCustomization?.let {
|
|
485
|
+
uiCustomization.setButtonCustomization(ButtonCustomization().apply {
|
|
486
|
+
setTextFontName(it.textFontName)
|
|
487
|
+
setTextColor(it.textColor)
|
|
488
|
+
setTextFontSize(it.textFontSize)
|
|
489
|
+
setBackgroundColor(it.backgroundColor)
|
|
490
|
+
setCornerRadius(it.cornerRadius)
|
|
491
|
+
}, UiCustomization.ButtonType.RESEND)
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
uiCustomization
|
|
496
|
+
} else {
|
|
497
|
+
null
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
340
501
|
internal fun getPrimaryAccountDetails(options: ReadableMap): PrimaryAccountDetails? {
|
|
341
502
|
return if (options.primaryAccountDetails != null) {
|
|
342
503
|
PrimaryAccountDetails.Builder()
|
|
@@ -9,6 +9,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
|
|
9
9
|
import com.facebook.react.bridge.*
|
|
10
10
|
import com.judopay.judokit.android.Judo
|
|
11
11
|
import com.judopay.judokit.android.api.JudoApiService
|
|
12
|
+
import com.judopay.judokit.android.api.error.toJudoError
|
|
12
13
|
import com.judopay.judokit.android.api.factory.JudoApiServiceFactory
|
|
13
14
|
import com.judopay.judokit.android.api.model.response.JudoApiCallResult
|
|
14
15
|
import com.judopay.judokit.android.api.model.response.Receipt
|
|
@@ -31,6 +32,7 @@ import retrofit2.Response
|
|
|
31
32
|
|
|
32
33
|
const val JUDO_PAYMENT_WIDGET_REQUEST_CODE = 65520
|
|
33
34
|
const val JUDO_PROMISE_REJECTION_CODE = "JUDO_ERROR"
|
|
35
|
+
const val REQUEST_FAILED_MESSAGE = "The request was unsuccessful."
|
|
34
36
|
|
|
35
37
|
class JudoReactNativeModule internal constructor(val context: ReactApplicationContext) :
|
|
36
38
|
ReactContextBaseJavaModule(context), CardTransactionManagerResultListener {
|
|
@@ -114,7 +116,6 @@ class JudoReactNativeModule internal constructor(val context: ReactApplicationCo
|
|
|
114
116
|
val manager = CardTransactionManager.getInstance(activity)
|
|
115
117
|
|
|
116
118
|
val judo = getTokenTransactionConfiguration(options)
|
|
117
|
-
|
|
118
119
|
val cardToken = options.cardToken
|
|
119
120
|
|
|
120
121
|
if (cardToken == null) {
|
|
@@ -122,6 +123,8 @@ class JudoReactNativeModule internal constructor(val context: ReactApplicationCo
|
|
|
122
123
|
return
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
manager.configureWith(judo)
|
|
127
|
+
|
|
125
128
|
val details = TransactionDetails.Builder()
|
|
126
129
|
.setCardHolderName(options.cardholderName)
|
|
127
130
|
.setSecurityNumber(options.securityCode)
|
|
@@ -150,6 +153,56 @@ class JudoReactNativeModule internal constructor(val context: ReactApplicationCo
|
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
|
|
156
|
+
@ReactMethod
|
|
157
|
+
fun fetchTransactionDetails(options: ReadableMap, promise: Promise) {
|
|
158
|
+
try {
|
|
159
|
+
val judo = getJudoConfigurationForApiService(options)
|
|
160
|
+
val receiptId = options.receiptId ?: ""
|
|
161
|
+
|
|
162
|
+
val service = JudoApiServiceFactory.createApiService(context, judo)
|
|
163
|
+
|
|
164
|
+
val fetchTransactionDetailsCallback = object : Callback<JudoApiCallResult<Receipt>> {
|
|
165
|
+
override fun onResponse(
|
|
166
|
+
call: Call<JudoApiCallResult<Receipt>>,
|
|
167
|
+
response: Response<JudoApiCallResult<Receipt>>
|
|
168
|
+
) {
|
|
169
|
+
when (val result = response.body()) {
|
|
170
|
+
is JudoApiCallResult.Success -> {
|
|
171
|
+
val receipt = result.data
|
|
172
|
+
if (receipt != null) {
|
|
173
|
+
val judoResult = receipt.toJudoResult()
|
|
174
|
+
promise.resolve(getMappedResult(judoResult))
|
|
175
|
+
} else {
|
|
176
|
+
promise.reject(JUDO_PROMISE_REJECTION_CODE, REQUEST_FAILED_MESSAGE)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
is JudoApiCallResult.Failure -> {
|
|
180
|
+
val message = result.error?.message ?: REQUEST_FAILED_MESSAGE
|
|
181
|
+
promise.reject(JUDO_PROMISE_REJECTION_CODE, message)
|
|
182
|
+
}
|
|
183
|
+
else -> {
|
|
184
|
+
promise.reject(JUDO_PROMISE_REJECTION_CODE, REQUEST_FAILED_MESSAGE)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
override fun onFailure(
|
|
190
|
+
call: Call<JudoApiCallResult<Receipt>>,
|
|
191
|
+
throwable: Throwable
|
|
192
|
+
) {
|
|
193
|
+
promise.reject(JUDO_PROMISE_REJECTION_CODE, throwable.localizedMessage, throwable)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
service
|
|
198
|
+
.fetchTransactionWithReceiptId(receiptId)
|
|
199
|
+
.enqueue(fetchTransactionDetailsCallback)
|
|
200
|
+
|
|
201
|
+
} catch (error: Exception) {
|
|
202
|
+
promise.reject(JUDO_PROMISE_REJECTION_CODE, error.localizedMessage, error)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
153
206
|
private fun ensureIsSubscribedToCardTransactionResults() {
|
|
154
207
|
if (isSubscribedToCardTransactionResults) {
|
|
155
208
|
return
|
package/ios/.xcode.env
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# This `.xcode.env` file is versioned and is used to source the environment
|
|
2
|
+
# used when running script phases inside Xcode.
|
|
3
|
+
# To customize your local environment, you can create an `.xcode.env.local`
|
|
4
|
+
# file that is not versioned.
|
|
5
|
+
|
|
6
|
+
# NODE_BINARY variable contains the PATH to the node executable.
|
|
7
|
+
#
|
|
8
|
+
# Customize the NODE_BINARY variable here.
|
|
9
|
+
# For example, to use nvm with brew, add the following line
|
|
10
|
+
# . "$(brew --prefix nvm)/nvm.sh" --no-use
|
|
11
|
+
export NODE_BINARY=$(command -v node)
|
package/ios/Classes/RNJudo.m
CHANGED
|
@@ -128,13 +128,19 @@ RCT_REMAP_METHOD(fetchTransactionDetails,
|
|
|
128
128
|
properties:(NSDictionary *)properties
|
|
129
129
|
fetchTransactionDetailsWithResolver:(RCTPromiseResolveBlock)resolve
|
|
130
130
|
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
131
|
+
@try {
|
|
132
|
+
self.apiService = [RNWrappers apiServiceFromProperties:properties];
|
|
133
|
+
self.completionBlock = [self completionBlockWithResolve:resolve andReject:reject];
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
self.completionBlock = [self completionBlockWithResolve:resolve andReject:reject];
|
|
134
|
-
|
|
135
|
-
NSString *receiptId = [RNWrappers receiptIdFromProperties:properties];
|
|
135
|
+
NSString *receiptId = [RNWrappers receiptIdFromProperties:properties];
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
[self.apiService fetchTransactionWithReceiptId:receiptId completion:self.completionBlock];
|
|
138
|
+
} @catch (NSException *exception) {
|
|
139
|
+
NSError *error = [[NSError alloc] initWithDomain:RNJudoErrorDomain
|
|
140
|
+
code:0
|
|
141
|
+
userInfo:exception.userInfo];
|
|
142
|
+
reject(kJudoPromiseRejectionCode, exception.reason, error);
|
|
143
|
+
}
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
//----------------------------------------------
|
|
@@ -204,7 +210,17 @@ RCT_REMAP_METHOD(fetchTransactionDetails,
|
|
|
204
210
|
message = description;
|
|
205
211
|
}
|
|
206
212
|
|
|
207
|
-
|
|
213
|
+
// TODO: RCTJSErrorFromCodeMessageAndNSError expects an NSError instane in userInfo[NSUnderlyingErrorKey]
|
|
214
|
+
// which in case of a 3DS SDK error is a NSString ('JP3DSSDKRuntimeException') - so it crashes
|
|
215
|
+
// ! this should be fixed in JudoKit-iOS, and the folowing workaround removed ASAP
|
|
216
|
+
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo];
|
|
217
|
+
[userInfo removeObjectForKey:NSUnderlyingErrorKey];
|
|
218
|
+
NSError *myError = [[NSError alloc] initWithDomain:error.domain
|
|
219
|
+
code:error.code
|
|
220
|
+
userInfo:[NSDictionary dictionaryWithDictionary:userInfo]];
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
reject(kJudoPromiseRejectionCode, message, myError);
|
|
208
224
|
} else {
|
|
209
225
|
NSDictionary *mappedResponse = [RNWrappers dictionaryFromResponse:response];
|
|
210
226
|
resolve(mappedResponse);
|