@stripe/stripe-react-native 0.9.0 → 0.12.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/CHANGELOG.md +46 -0
- package/README.md +1 -1
- package/android/build.gradle +1 -1
- package/android/gradle.properties +2 -2
- package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +31 -4
- package/android/src/main/java/com/reactnativestripesdk/CardFormViewManager.kt +1 -1
- package/android/src/main/java/com/reactnativestripesdk/Errors.kt +14 -1
- package/android/src/main/java/com/reactnativestripesdk/GooglePayFragment.kt +68 -52
- package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherFragment.kt +127 -37
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +173 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +59 -36
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +49 -177
- package/ios/PaymentSheetAppearance.swift +209 -0
- package/ios/StripeSdk.swift +9 -5
- package/ios/StripeSdk.xcodeproj/project.pbxproj +2 -2
- package/lib/typescript/example/src/screens/PaymentSheetAppearance.d.ts +3 -0
- package/lib/typescript/src/types/PaymentSheet.d.ts +154 -1
- package/package.json +4 -5
- package/src/types/PaymentSheet.ts +159 -2
- package/stripe-react-native.podspec +1 -1
- package/android/src/main/java/com/reactnativestripesdk/Constants.kt +0 -10
|
@@ -1,63 +1,50 @@
|
|
|
1
1
|
package com.reactnativestripesdk
|
|
2
2
|
|
|
3
3
|
import android.app.Activity
|
|
4
|
-
import android.content.BroadcastReceiver
|
|
5
|
-
import android.content.Context
|
|
6
4
|
import android.content.Intent
|
|
7
|
-
import android.content.IntentFilter
|
|
8
5
|
import android.os.Parcelable
|
|
9
6
|
import android.util.Log
|
|
10
7
|
import androidx.appcompat.app.AppCompatActivity
|
|
11
|
-
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
|
12
8
|
import com.facebook.react.bridge.*
|
|
13
9
|
import com.facebook.react.module.annotations.ReactModule
|
|
14
10
|
import com.stripe.android.*
|
|
15
11
|
import com.stripe.android.core.AppInfo
|
|
16
12
|
import com.stripe.android.core.ApiVersion
|
|
17
|
-
import com.stripe.android.googlepaylauncher.GooglePayLauncher
|
|
18
|
-
import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher
|
|
19
13
|
import com.stripe.android.model.*
|
|
20
14
|
import com.stripe.android.payments.bankaccount.CollectBankAccountConfiguration
|
|
21
|
-
import com.stripe.android.paymentsheet.PaymentSheetResult
|
|
22
15
|
import com.stripe.android.view.AddPaymentMethodActivityStarter
|
|
23
16
|
import kotlinx.coroutines.CoroutineScope
|
|
24
17
|
import kotlinx.coroutines.Dispatchers
|
|
25
18
|
import kotlinx.coroutines.launch
|
|
26
19
|
|
|
27
20
|
@ReactModule(name = StripeSdkModule.NAME)
|
|
28
|
-
class StripeSdkModule(
|
|
29
|
-
var cardFieldView: CardFieldView? = null
|
|
30
|
-
var cardFormView: CardFormView? = null
|
|
31
|
-
|
|
21
|
+
class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
32
22
|
override fun getName(): String {
|
|
33
23
|
return "StripeSdk"
|
|
34
24
|
}
|
|
35
|
-
private lateinit var stripe: Stripe
|
|
36
25
|
|
|
37
|
-
|
|
26
|
+
var cardFieldView: CardFieldView? = null
|
|
27
|
+
var cardFormView: CardFormView? = null
|
|
38
28
|
|
|
29
|
+
private lateinit var stripe: Stripe
|
|
39
30
|
private lateinit var publishableKey: String
|
|
40
31
|
private var stripeAccountId: String? = null
|
|
32
|
+
private var urlScheme: String? = null
|
|
33
|
+
|
|
41
34
|
private var paymentSheetFragment: PaymentSheetFragment? = null
|
|
35
|
+
private var googlePayFragment: GooglePayFragment? = null
|
|
36
|
+
private var paymentLauncherFragment: PaymentLauncherFragment? = null
|
|
42
37
|
|
|
43
|
-
private var urlScheme: String? = null
|
|
44
38
|
private var confirmPromise: Promise? = null
|
|
45
|
-
private var confirmPaymentSheetPaymentPromise: Promise? = null
|
|
46
|
-
private var presentPaymentSheetPromise: Promise? = null
|
|
47
|
-
private var initPaymentSheetPromise: Promise? = null
|
|
48
39
|
private var confirmPaymentClientSecret: String? = null
|
|
49
40
|
|
|
50
|
-
private var googlePayFragment: GooglePayFragment? = null
|
|
51
|
-
private var initGooglePayPromise: Promise? = null
|
|
52
|
-
private var presentGooglePayPromise: Promise? = null
|
|
53
|
-
|
|
54
41
|
private val mActivityEventListener = object : BaseActivityEventListener() {
|
|
55
42
|
override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
|
|
56
43
|
if (::stripe.isInitialized) {
|
|
57
44
|
// BEGIN - Necessary on older versions of React Native (~0.64 and below)
|
|
58
45
|
paymentSheetFragment?.activity?.activityResultRegistry?.dispatchResult(requestCode, resultCode, data)
|
|
59
46
|
googlePayFragment?.activity?.activityResultRegistry?.dispatchResult(requestCode, resultCode, data)
|
|
60
|
-
paymentLauncherFragment
|
|
47
|
+
paymentLauncherFragment?.activity?.activityResultRegistry?.dispatchResult(requestCode, resultCode, data)
|
|
61
48
|
// END
|
|
62
49
|
try {
|
|
63
50
|
val result = AddPaymentMethodActivityStarter.Result.fromIntent(data)
|
|
@@ -91,108 +78,6 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
91
78
|
)
|
|
92
79
|
}
|
|
93
80
|
|
|
94
|
-
private val googlePayReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
|
95
|
-
override fun onReceive(context: Context?, intent: Intent) {
|
|
96
|
-
if (intent.action == ON_INIT_GOOGLE_PAY) {
|
|
97
|
-
val isReady = intent.extras?.getBoolean("isReady") ?: false
|
|
98
|
-
if (isReady) {
|
|
99
|
-
initGooglePayPromise?.resolve(WritableNativeMap())
|
|
100
|
-
} else {
|
|
101
|
-
initGooglePayPromise?.resolve(
|
|
102
|
-
createError(
|
|
103
|
-
GooglePayErrorType.Failed.toString(),
|
|
104
|
-
"Google Pay is not available on this device. You can use isGooglePaySupported to preemptively check for Google Pay support."
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (intent.action == ON_GOOGLE_PAYMENT_METHOD_RESULT) {
|
|
110
|
-
intent.extras?.getString("error")?.let {
|
|
111
|
-
presentGooglePayPromise?.resolve(createError(GooglePayErrorType.Failed.toString(), it))
|
|
112
|
-
return
|
|
113
|
-
}
|
|
114
|
-
when (val result = intent.extras?.getParcelable<GooglePayPaymentMethodLauncher.Result>("paymentResult")) {
|
|
115
|
-
is GooglePayPaymentMethodLauncher.Result.Completed -> {
|
|
116
|
-
presentGooglePayPromise?.resolve(createResult("paymentMethod", mapFromPaymentMethod(result.paymentMethod)))
|
|
117
|
-
}
|
|
118
|
-
GooglePayPaymentMethodLauncher.Result.Canceled -> {
|
|
119
|
-
presentGooglePayPromise?.resolve(createError(GooglePayErrorType.Canceled.toString(), "Google Pay has been canceled"))
|
|
120
|
-
}
|
|
121
|
-
is GooglePayPaymentMethodLauncher.Result.Failed -> {
|
|
122
|
-
presentGooglePayPromise?.resolve(createError(GooglePayErrorType.Failed.toString(), result.error))
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (intent.action == ON_GOOGLE_PAY_RESULT) {
|
|
127
|
-
intent.extras?.getString("error")?.let {
|
|
128
|
-
presentGooglePayPromise?.resolve(createError(GooglePayErrorType.Failed.toString(), it))
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
when (val result = intent.extras?.getParcelable<GooglePayLauncher.Result>("paymentResult")) {
|
|
132
|
-
GooglePayLauncher.Result.Completed -> {
|
|
133
|
-
presentGooglePayPromise?.resolve(WritableNativeMap())
|
|
134
|
-
}
|
|
135
|
-
GooglePayLauncher.Result.Canceled -> {
|
|
136
|
-
presentGooglePayPromise?.resolve(createError(GooglePayErrorType.Canceled.toString(), "Google Pay has been canceled"))
|
|
137
|
-
}
|
|
138
|
-
is GooglePayLauncher.Result.Failed -> {
|
|
139
|
-
presentGooglePayPromise?.resolve(createError(GooglePayErrorType.Failed.toString(), result.error))
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private val mPaymentSheetReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
|
147
|
-
override fun onReceive(context: Context?, intent: Intent) {
|
|
148
|
-
if (intent.action == ON_PAYMENT_RESULT_ACTION) {
|
|
149
|
-
when (val result = intent.extras?.getParcelable<PaymentSheetResult>("paymentResult")) {
|
|
150
|
-
is PaymentSheetResult.Canceled -> {
|
|
151
|
-
val message = "The payment has been canceled"
|
|
152
|
-
confirmPaymentSheetPaymentPromise?.resolve(createError(PaymentSheetErrorType.Canceled.toString(), message))
|
|
153
|
-
presentPaymentSheetPromise?.resolve(createError(PaymentSheetErrorType.Canceled.toString(), message))
|
|
154
|
-
}
|
|
155
|
-
is PaymentSheetResult.Failed -> {
|
|
156
|
-
confirmPaymentSheetPaymentPromise?.resolve(createError(PaymentSheetErrorType.Failed.toString(), result.error))
|
|
157
|
-
presentPaymentSheetPromise?.resolve(createError(PaymentSheetErrorType.Failed.toString(), result.error))
|
|
158
|
-
}
|
|
159
|
-
is PaymentSheetResult.Completed -> {
|
|
160
|
-
confirmPaymentSheetPaymentPromise?.resolve(WritableNativeMap())
|
|
161
|
-
presentPaymentSheetPromise?.resolve(WritableNativeMap())
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
} else if (intent.action == ON_PAYMENT_OPTION_ACTION) {
|
|
165
|
-
val label = intent.extras?.getString("label")
|
|
166
|
-
val image = intent.extras?.getString("image")
|
|
167
|
-
|
|
168
|
-
if (label != null && image != null) {
|
|
169
|
-
val option: WritableMap = WritableNativeMap()
|
|
170
|
-
option.putString("label", label)
|
|
171
|
-
option.putString("image", image)
|
|
172
|
-
presentPaymentSheetPromise?.resolve(createResult("paymentOption", option))
|
|
173
|
-
} else {
|
|
174
|
-
presentPaymentSheetPromise?.resolve(WritableNativeMap())
|
|
175
|
-
}
|
|
176
|
-
presentPaymentSheetPromise = null
|
|
177
|
-
}
|
|
178
|
-
else if (intent.action == ON_INIT_PAYMENT_SHEET) {
|
|
179
|
-
initPaymentSheetPromise?.resolve(WritableNativeMap())
|
|
180
|
-
} else if (intent.action == ON_CONFIGURE_FLOW_CONTROLLER) {
|
|
181
|
-
val label = intent.extras?.getString("label")
|
|
182
|
-
val image = intent.extras?.getString("image")
|
|
183
|
-
|
|
184
|
-
if (label != null && image != null) {
|
|
185
|
-
val option: WritableMap = WritableNativeMap()
|
|
186
|
-
option.putString("label", label)
|
|
187
|
-
option.putString("image", image)
|
|
188
|
-
initPaymentSheetPromise?.resolve(createResult("paymentOption", option))
|
|
189
|
-
} else {
|
|
190
|
-
initPaymentSheetPromise?.resolve(WritableNativeMap())
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
81
|
override fun getConstants(): MutableMap<String, Any> =
|
|
197
82
|
hashMapOf(
|
|
198
83
|
"API_VERSIONS" to hashMapOf(
|
|
@@ -225,37 +110,13 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
225
110
|
stripe = Stripe(reactApplicationContext, publishableKey, stripeAccountId)
|
|
226
111
|
|
|
227
112
|
PaymentConfiguration.init(reactApplicationContext, publishableKey, stripeAccountId)
|
|
228
|
-
|
|
229
|
-
paymentLauncherFragment = PaymentLauncherFragment(stripe, publishableKey, stripeAccountId)
|
|
230
|
-
getCurrentActivityOrResolveWithError(promise)?.let {
|
|
231
|
-
try {
|
|
232
|
-
it.supportFragmentManager.beginTransaction()
|
|
233
|
-
.add(paymentLauncherFragment, "payment_launcher_fragment")
|
|
234
|
-
.commit()
|
|
235
|
-
} catch (error: IllegalStateException) {
|
|
236
|
-
promise.resolve(createError(ErrorType.Failed.toString(), error.message))
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
val localBroadcastManager = LocalBroadcastManager.getInstance(reactApplicationContext)
|
|
240
|
-
localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_PAYMENT_RESULT_ACTION))
|
|
241
|
-
localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_PAYMENT_OPTION_ACTION))
|
|
242
|
-
localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_CONFIGURE_FLOW_CONTROLLER))
|
|
243
|
-
localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_INIT_PAYMENT_SHEET))
|
|
244
|
-
|
|
245
|
-
localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_INIT_GOOGLE_PAY))
|
|
246
|
-
localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_GOOGLE_PAY_RESULT))
|
|
247
|
-
localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_GOOGLE_PAYMENT_METHOD_RESULT))
|
|
248
|
-
|
|
249
|
-
promise.resolve(null)
|
|
250
|
-
}
|
|
113
|
+
promise.resolve(null)
|
|
251
114
|
}
|
|
252
115
|
|
|
253
116
|
@ReactMethod
|
|
254
117
|
fun initPaymentSheet(params: ReadableMap, promise: Promise) {
|
|
255
118
|
getCurrentActivityOrResolveWithError(promise)?.let { activity ->
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
paymentSheetFragment = PaymentSheetFragment().also {
|
|
119
|
+
paymentSheetFragment = PaymentSheetFragment(reactApplicationContext, promise).also {
|
|
259
120
|
val bundle = toBundleObject(params)
|
|
260
121
|
it.arguments = bundle
|
|
261
122
|
}
|
|
@@ -271,14 +132,12 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
271
132
|
|
|
272
133
|
@ReactMethod
|
|
273
134
|
fun presentPaymentSheet(promise: Promise) {
|
|
274
|
-
|
|
275
|
-
paymentSheetFragment?.present()
|
|
135
|
+
paymentSheetFragment?.present(promise)
|
|
276
136
|
}
|
|
277
137
|
|
|
278
138
|
@ReactMethod
|
|
279
139
|
fun confirmPaymentSheetPayment(promise: Promise) {
|
|
280
|
-
|
|
281
|
-
paymentSheetFragment?.confirmPayment()
|
|
140
|
+
paymentSheetFragment?.confirmPayment(promise)
|
|
282
141
|
}
|
|
283
142
|
|
|
284
143
|
private fun payWithFpx() {
|
|
@@ -295,13 +154,17 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
295
154
|
when (result) {
|
|
296
155
|
is AddPaymentMethodActivityStarter.Result.Success -> {
|
|
297
156
|
if (confirmPaymentClientSecret != null && confirmPromise != null) {
|
|
298
|
-
paymentLauncherFragment.
|
|
157
|
+
paymentLauncherFragment = PaymentLauncherFragment.forPayment(
|
|
158
|
+
context = reactApplicationContext,
|
|
159
|
+
stripe,
|
|
160
|
+
publishableKey,
|
|
161
|
+
stripeAccountId,
|
|
162
|
+
confirmPromise!!,
|
|
163
|
+
confirmPaymentClientSecret!!,
|
|
299
164
|
ConfirmPaymentIntentParams.createWithPaymentMethodId(
|
|
300
165
|
result.paymentMethod.id!!,
|
|
301
166
|
confirmPaymentClientSecret!!
|
|
302
|
-
)
|
|
303
|
-
confirmPaymentClientSecret!!,
|
|
304
|
-
confirmPromise!!
|
|
167
|
+
)
|
|
305
168
|
)
|
|
306
169
|
} else {
|
|
307
170
|
Log.e("StripeReactNative", "FPX payment failed. Promise and/or client secret is not set.")
|
|
@@ -445,9 +308,13 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
445
308
|
|
|
446
309
|
@ReactMethod
|
|
447
310
|
fun handleNextAction(paymentIntentClientSecret: String, promise: Promise) {
|
|
448
|
-
paymentLauncherFragment.
|
|
449
|
-
|
|
450
|
-
|
|
311
|
+
paymentLauncherFragment = PaymentLauncherFragment.forNextAction(
|
|
312
|
+
context = reactApplicationContext,
|
|
313
|
+
stripe,
|
|
314
|
+
publishableKey,
|
|
315
|
+
stripeAccountId,
|
|
316
|
+
promise,
|
|
317
|
+
paymentIntentClientSecret
|
|
451
318
|
)
|
|
452
319
|
}
|
|
453
320
|
|
|
@@ -505,10 +372,14 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
505
372
|
confirmParams.returnUrl = mapToReturnURL(urlScheme)
|
|
506
373
|
}
|
|
507
374
|
confirmParams.shipping = mapToShippingDetails(getMapOrNull(paymentMethodData, "shippingDetails"))
|
|
508
|
-
paymentLauncherFragment.
|
|
509
|
-
|
|
375
|
+
paymentLauncherFragment = PaymentLauncherFragment.forPayment(
|
|
376
|
+
context = reactApplicationContext,
|
|
377
|
+
stripe,
|
|
378
|
+
publishableKey,
|
|
379
|
+
stripeAccountId,
|
|
380
|
+
promise,
|
|
510
381
|
paymentIntentClientSecret,
|
|
511
|
-
|
|
382
|
+
confirmParams
|
|
512
383
|
)
|
|
513
384
|
} catch (error: PaymentMethodCreateParamsException) {
|
|
514
385
|
promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), error))
|
|
@@ -553,10 +424,14 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
553
424
|
urlScheme?.let {
|
|
554
425
|
confirmParams.returnUrl = mapToReturnURL(urlScheme)
|
|
555
426
|
}
|
|
556
|
-
paymentLauncherFragment.
|
|
557
|
-
|
|
427
|
+
paymentLauncherFragment = PaymentLauncherFragment.forSetup(
|
|
428
|
+
context = reactApplicationContext,
|
|
429
|
+
stripe,
|
|
430
|
+
publishableKey,
|
|
431
|
+
stripeAccountId,
|
|
432
|
+
promise,
|
|
558
433
|
setupIntentClientSecret,
|
|
559
|
-
|
|
434
|
+
confirmParams
|
|
560
435
|
)
|
|
561
436
|
} catch (error: PaymentMethodCreateParamsException) {
|
|
562
437
|
promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), error))
|
|
@@ -566,7 +441,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
566
441
|
@ReactMethod
|
|
567
442
|
fun isGooglePaySupported(params: ReadableMap?, promise: Promise) {
|
|
568
443
|
val fragment = GooglePayPaymentMethodLauncherFragment(
|
|
569
|
-
|
|
444
|
+
reactApplicationContext,
|
|
570
445
|
getBooleanOrFalse(params, "testEnv"),
|
|
571
446
|
getBooleanOrFalse(params, "existingPaymentMethodRequired"),
|
|
572
447
|
promise
|
|
@@ -585,14 +460,12 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
585
460
|
|
|
586
461
|
@ReactMethod
|
|
587
462
|
fun initGooglePay(params: ReadableMap, promise: Promise) {
|
|
588
|
-
googlePayFragment = GooglePayFragment().also {
|
|
463
|
+
googlePayFragment = GooglePayFragment(promise).also {
|
|
589
464
|
val bundle = toBundleObject(params)
|
|
590
465
|
it.arguments = bundle
|
|
591
466
|
}
|
|
592
467
|
|
|
593
468
|
getCurrentActivityOrResolveWithError(promise)?.let {
|
|
594
|
-
initGooglePayPromise = promise
|
|
595
|
-
|
|
596
469
|
try {
|
|
597
470
|
it.supportFragmentManager.beginTransaction()
|
|
598
471
|
.add(googlePayFragment!!, "google_pay_launch_fragment")
|
|
@@ -609,15 +482,15 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
609
482
|
promise.resolve(createError(GooglePayErrorType.Failed.toString(), "you must provide clientSecret"))
|
|
610
483
|
return
|
|
611
484
|
}
|
|
612
|
-
|
|
485
|
+
|
|
613
486
|
if (getBooleanOrFalse(params, "forSetupIntent")) {
|
|
614
487
|
val currencyCode = getValOr(params, "currencyCode") ?: run {
|
|
615
488
|
promise.resolve(createError(GooglePayErrorType.Failed.toString(), "you must provide currencyCode"))
|
|
616
489
|
return
|
|
617
490
|
}
|
|
618
|
-
googlePayFragment?.presentForSetupIntent(clientSecret, currencyCode)
|
|
491
|
+
googlePayFragment?.presentForSetupIntent(clientSecret, currencyCode, promise)
|
|
619
492
|
} else {
|
|
620
|
-
googlePayFragment?.presentForPaymentIntent(clientSecret)
|
|
493
|
+
googlePayFragment?.presentForPaymentIntent(clientSecret, promise)
|
|
621
494
|
}
|
|
622
495
|
}
|
|
623
496
|
|
|
@@ -631,8 +504,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
631
504
|
promise.resolve(createError(GooglePayErrorType.Failed.toString(), "you must provide amount"))
|
|
632
505
|
return
|
|
633
506
|
}
|
|
634
|
-
|
|
635
|
-
googlePayFragment?.createPaymentMethod(currencyCode, amount)
|
|
507
|
+
googlePayFragment?.createPaymentMethod(currencyCode, amount, promise)
|
|
636
508
|
}
|
|
637
509
|
|
|
638
510
|
@ReactMethod
|
|
@@ -669,7 +541,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React
|
|
|
669
541
|
)
|
|
670
542
|
|
|
671
543
|
val fragment = CollectBankAccountLauncherFragment(
|
|
672
|
-
|
|
544
|
+
reactApplicationContext,
|
|
673
545
|
publishableKey,
|
|
674
546
|
clientSecret,
|
|
675
547
|
isPaymentIntent,
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PaymentSheetAppearance.swift
|
|
3
|
+
// stripe-react-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Charles Cruzan on 5/11/22.
|
|
6
|
+
//
|
|
7
|
+
import Stripe
|
|
8
|
+
|
|
9
|
+
extension StripeSdk {
|
|
10
|
+
func buildPaymentSheetAppearance(userParams: NSDictionary) throws -> PaymentSheet.Appearance {
|
|
11
|
+
var appearance = PaymentSheet.Appearance()
|
|
12
|
+
|
|
13
|
+
if let fontParams = userParams[PaymentSheetAppearanceKeys.FONT] as? NSDictionary {
|
|
14
|
+
appearance.font = try buildFont(params: fontParams)
|
|
15
|
+
}
|
|
16
|
+
if let colorParams = userParams[PaymentSheetAppearanceKeys.COLORS] as? NSDictionary {
|
|
17
|
+
appearance.colors = try buildColors(params: colorParams)
|
|
18
|
+
}
|
|
19
|
+
if let shapeParams = userParams[PaymentSheetAppearanceKeys.SHAPES] as? NSDictionary {
|
|
20
|
+
appearance.cornerRadius = shapeParams[PaymentSheetAppearanceKeys.BORDER_RADIUS] as? CGFloat ?? PaymentSheet.Appearance.default.cornerRadius
|
|
21
|
+
appearance.borderWidth = shapeParams[PaymentSheetAppearanceKeys.BORDER_WIDTH] as? CGFloat ?? PaymentSheet.Appearance.default.borderWidth
|
|
22
|
+
if let shadowParams = shapeParams[PaymentSheetAppearanceKeys.SHADOW] as? NSDictionary {
|
|
23
|
+
appearance.shadow = try buildShadow(params: shadowParams)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if let primaryButtonParams = userParams[PaymentSheetAppearanceKeys.PRIMARY_BUTTON] as? NSDictionary {
|
|
27
|
+
appearance.primaryButton = try buildPrimaryButton(params: primaryButtonParams)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return appearance
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private func buildFont(params: NSDictionary) throws -> Stripe.PaymentSheet.Appearance.Font {
|
|
34
|
+
var font = Stripe.PaymentSheet.Appearance.Font()
|
|
35
|
+
if let fontName = params[PaymentSheetAppearanceKeys.FAMILY] as? String {
|
|
36
|
+
guard let customFont = UIFont(name: fontName, size: UIFont.systemFontSize) else {
|
|
37
|
+
throw PaymentSheetAppearanceError.missingFont(fontName)
|
|
38
|
+
}
|
|
39
|
+
font.base = customFont
|
|
40
|
+
}
|
|
41
|
+
font.sizeScaleFactor = params[PaymentSheetAppearanceKeys.SCALE] as? CGFloat ?? PaymentSheet.Appearance.default.font.sizeScaleFactor
|
|
42
|
+
return font
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private func buildColors(params: NSDictionary) throws -> Stripe.PaymentSheet.Appearance.Colors {
|
|
46
|
+
var colors = Stripe.PaymentSheet.Appearance.Colors()
|
|
47
|
+
|
|
48
|
+
if (params.object(forKey: PaymentSheetAppearanceKeys.LIGHT) != nil && params.object(forKey: PaymentSheetAppearanceKeys.DARK) == nil ||
|
|
49
|
+
params.object(forKey: PaymentSheetAppearanceKeys.DARK) != nil && params.object(forKey: PaymentSheetAppearanceKeys.LIGHT) == nil) {
|
|
50
|
+
throw PaymentSheetAppearanceError.missingAppearanceMode
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let lightModeParams = params[PaymentSheetAppearanceKeys.LIGHT] as? NSDictionary ?? params
|
|
54
|
+
let darkModeParams = params[PaymentSheetAppearanceKeys.DARK] as? NSDictionary ?? params
|
|
55
|
+
|
|
56
|
+
colors.primary = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.PRIMARY, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.primary
|
|
57
|
+
colors.background = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.BACKGROUND, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.background
|
|
58
|
+
colors.componentBackground = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.COMPONENT_BACKGROUND, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.componentBackground
|
|
59
|
+
colors.componentBorder = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.COMPONENT_BORDER, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.componentBorder
|
|
60
|
+
colors.componentDivider = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.COMPONENT_DIVIDER, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.componentDivider
|
|
61
|
+
colors.text = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.PRIMARY_TEXT, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.text
|
|
62
|
+
colors.textSecondary = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.SECONDARY_TEXT, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.textSecondary
|
|
63
|
+
colors.componentText = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.COMPONENT_TEXT, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.componentText
|
|
64
|
+
colors.componentPlaceholderText = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.PLACEHOLDER_TEXT, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.componentPlaceholderText
|
|
65
|
+
colors.icon = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.ICON, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.icon
|
|
66
|
+
colors.danger = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.ERROR, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.colors.danger
|
|
67
|
+
|
|
68
|
+
return colors
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private func buildShadow(params: NSDictionary) throws -> PaymentSheet.Appearance.Shadow {
|
|
72
|
+
var shadow = PaymentSheet.Appearance.Shadow()
|
|
73
|
+
|
|
74
|
+
if let color = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.SHADOW_COLOR, lightParams: params, darkParams: params) {
|
|
75
|
+
shadow.color = color
|
|
76
|
+
}
|
|
77
|
+
if let opacity = params[PaymentSheetAppearanceKeys.OPACITY] as? CGFloat {
|
|
78
|
+
shadow.opacity = opacity
|
|
79
|
+
}
|
|
80
|
+
if let radius = params[PaymentSheetAppearanceKeys.BLUR_RADIUS] as? CGFloat {
|
|
81
|
+
shadow.radius = radius
|
|
82
|
+
}
|
|
83
|
+
if let offsetParams = params[PaymentSheetAppearanceKeys.OFFSET] as? NSDictionary {
|
|
84
|
+
if let x = offsetParams[PaymentSheetAppearanceKeys.X] as? CGFloat, let y = offsetParams[PaymentSheetAppearanceKeys.Y] as? CGFloat {
|
|
85
|
+
shadow.offset = CGSize(width: x, height:-y)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return shadow
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private func buildPrimaryButton(params: NSDictionary) throws -> PaymentSheet.Appearance.PrimaryButton {
|
|
93
|
+
var primaryButton = PaymentSheet.Appearance.PrimaryButton()
|
|
94
|
+
|
|
95
|
+
if let fontName = (params[PaymentSheetAppearanceKeys.FONT] as? NSDictionary)?[PaymentSheetAppearanceKeys.FAMILY] as? String {
|
|
96
|
+
guard let customFont = UIFont(name: fontName, size: UIFont.systemFontSize) else {
|
|
97
|
+
throw PaymentSheetAppearanceError.missingFont(fontName)
|
|
98
|
+
}
|
|
99
|
+
primaryButton.font = customFont
|
|
100
|
+
}
|
|
101
|
+
if let shapeParams = params[PaymentSheetAppearanceKeys.SHAPES] as? NSDictionary {
|
|
102
|
+
if let borderRadius = shapeParams[PaymentSheetAppearanceKeys.BORDER_RADIUS] as? CGFloat {
|
|
103
|
+
primaryButton.cornerRadius = borderRadius
|
|
104
|
+
}
|
|
105
|
+
if let borderWidth = shapeParams[PaymentSheetAppearanceKeys.BORDER_WIDTH] as? CGFloat {
|
|
106
|
+
primaryButton.borderWidth = borderWidth
|
|
107
|
+
}
|
|
108
|
+
if let shadowParams = shapeParams[PaymentSheetAppearanceKeys.SHADOW] as? NSDictionary {
|
|
109
|
+
primaryButton.shadow = try buildShadow(params: shadowParams)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if let colorParams = params[PaymentSheetAppearanceKeys.COLORS] as? NSDictionary {
|
|
113
|
+
if (colorParams.object(forKey: PaymentSheetAppearanceKeys.LIGHT) != nil && colorParams.object(forKey: PaymentSheetAppearanceKeys.DARK) == nil ||
|
|
114
|
+
colorParams.object(forKey: PaymentSheetAppearanceKeys.DARK) != nil && colorParams.object(forKey: PaymentSheetAppearanceKeys.LIGHT) == nil) {
|
|
115
|
+
throw PaymentSheetAppearanceError.missingAppearanceMode
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let lightModeParams = colorParams[PaymentSheetAppearanceKeys.LIGHT] as? NSDictionary ?? colorParams
|
|
119
|
+
let darkModeParams = colorParams[PaymentSheetAppearanceKeys.DARK] as? NSDictionary ?? colorParams
|
|
120
|
+
|
|
121
|
+
primaryButton.backgroundColor = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.BACKGROUND, lightParams: lightModeParams, darkParams: darkModeParams)
|
|
122
|
+
primaryButton.textColor = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.TEXT, lightParams: lightModeParams, darkParams: darkModeParams)
|
|
123
|
+
primaryButton.borderColor = try StripeSdk.buildUserInterfaceStyleAwareColor(key: PaymentSheetAppearanceKeys.BORDER, lightParams: lightModeParams, darkParams: darkModeParams) ?? PaymentSheet.Appearance.default.primaryButton.borderColor
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return primaryButton
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private static func buildUserInterfaceStyleAwareColor(key: String, lightParams: NSDictionary, darkParams: NSDictionary) throws -> UIColor? {
|
|
130
|
+
guard let lightHexString = lightParams[key] as? String, let darkHexString = darkParams[key] as? String else {
|
|
131
|
+
return nil
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let darkCount = darkHexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted).count
|
|
135
|
+
let lightCount = lightHexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted).count
|
|
136
|
+
if (lightCount != 6 && lightCount != 8) {
|
|
137
|
+
throw PaymentSheetAppearanceError.unexpectedHexStringLength(lightHexString)
|
|
138
|
+
} else if (darkCount != 6 && darkCount != 8) {
|
|
139
|
+
throw PaymentSheetAppearanceError.unexpectedHexStringLength(darkHexString)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let lightColor = UIColor(hexString: lightHexString)
|
|
143
|
+
let darkColor = UIColor(hexString: darkHexString)
|
|
144
|
+
|
|
145
|
+
if #available(iOS 13.0, *) {
|
|
146
|
+
return UIColor.init { traits in
|
|
147
|
+
return traits.userInterfaceStyle == .dark ? darkColor : lightColor
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
return lightColor
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
enum PaymentSheetAppearanceError : Error {
|
|
156
|
+
case missingFont(String)
|
|
157
|
+
case missingAppearanceMode
|
|
158
|
+
case unexpectedHexStringLength(String)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
extension PaymentSheetAppearanceError: LocalizedError {
|
|
162
|
+
public var errorDescription: String? {
|
|
163
|
+
switch self {
|
|
164
|
+
case .missingFont(let fontFamily):
|
|
165
|
+
return NSLocalizedString("Failed to set Payment Sheet appearance. Unable to find font: \(fontFamily)", comment: "Failed to set font")
|
|
166
|
+
case .missingAppearanceMode:
|
|
167
|
+
return NSLocalizedString("Failed to set Payment Sheet appearance. When providing 'colors.light' or 'colors.dark', you must provide both.", comment: "Failed to set colors")
|
|
168
|
+
case .unexpectedHexStringLength(let hexString):
|
|
169
|
+
return NSLocalizedString("Failed to set Payment Sheet appearance. Expected hex string of length 6 or 8, but received: \(hexString)", comment: "Failed to set color")
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private struct PaymentSheetAppearanceKeys {
|
|
175
|
+
static let COLORS = "colors"
|
|
176
|
+
static let LIGHT = "light"
|
|
177
|
+
static let DARK = "dark"
|
|
178
|
+
static let PRIMARY = "primary"
|
|
179
|
+
static let BACKGROUND = "background"
|
|
180
|
+
static let COMPONENT_BACKGROUND = "componentBackground"
|
|
181
|
+
static let COMPONENT_BORDER = "componentBorder"
|
|
182
|
+
static let COMPONENT_DIVIDER = "componentDivider"
|
|
183
|
+
static let COMPONENT_TEXT = "componentText"
|
|
184
|
+
static let PRIMARY_TEXT = "primaryText"
|
|
185
|
+
static let SECONDARY_TEXT = "secondaryText"
|
|
186
|
+
static let PLACEHOLDER_TEXT = "placeholderText"
|
|
187
|
+
static let ICON = "icon"
|
|
188
|
+
static let ERROR = "error"
|
|
189
|
+
|
|
190
|
+
static let FONT = "font"
|
|
191
|
+
static let FAMILY = "family"
|
|
192
|
+
static let SCALE = "scale"
|
|
193
|
+
|
|
194
|
+
static let SHAPES = "shapes"
|
|
195
|
+
static let BORDER_RADIUS = "borderRadius"
|
|
196
|
+
static let BORDER_WIDTH = "borderWidth"
|
|
197
|
+
|
|
198
|
+
static let SHADOW = "shadow"
|
|
199
|
+
static let SHADOW_COLOR = "color"
|
|
200
|
+
static let OPACITY = "opacity"
|
|
201
|
+
static let OFFSET = "offset"
|
|
202
|
+
static let BLUR_RADIUS = "blurRadius"
|
|
203
|
+
static let X = "x"
|
|
204
|
+
static let Y = "y"
|
|
205
|
+
|
|
206
|
+
static let PRIMARY_BUTTON = "primaryButton"
|
|
207
|
+
static let TEXT = "text"
|
|
208
|
+
static let BORDER = "border"
|
|
209
|
+
}
|
package/ios/StripeSdk.swift
CHANGED
|
@@ -76,6 +76,15 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi
|
|
|
76
76
|
var configuration = PaymentSheet.Configuration()
|
|
77
77
|
self.paymentSheetFlowController = nil
|
|
78
78
|
|
|
79
|
+
if let appearanceParams = params["appearance"] as? NSDictionary {
|
|
80
|
+
do {
|
|
81
|
+
configuration.appearance = try buildPaymentSheetAppearance(userParams: appearanceParams)
|
|
82
|
+
} catch {
|
|
83
|
+
resolve(Errors.createError(ErrorType.Failed, error.localizedDescription))
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
79
88
|
if params["applePay"] as? Bool == true {
|
|
80
89
|
if let merchantIdentifier = self.merchantIdentifier, let merchantCountryCode = params["merchantCountryCode"] as? String {
|
|
81
90
|
configuration.applePay = .init(merchantId: merchantIdentifier,
|
|
@@ -94,11 +103,6 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi
|
|
|
94
103
|
configuration.returnURL = returnURL
|
|
95
104
|
}
|
|
96
105
|
|
|
97
|
-
if let buttonColorHexStr = params["primaryButtonColor"] as? String {
|
|
98
|
-
let primaryButtonColor = UIColor(hexString: buttonColorHexStr)
|
|
99
|
-
configuration.primaryButtonColor = primaryButtonColor
|
|
100
|
-
}
|
|
101
|
-
|
|
102
106
|
if let allowsDelayedPaymentMethods = params["allowsDelayedPaymentMethods"] as? Bool {
|
|
103
107
|
configuration.allowsDelayedPaymentMethods = allowsDelayedPaymentMethods
|
|
104
108
|
}
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
isa = XCBuildConfiguration;
|
|
181
181
|
buildSettings = {
|
|
182
182
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
183
|
-
CLANG_CXX_LANGUAGE_STANDARD = "
|
|
183
|
+
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
|
184
184
|
CLANG_CXX_LIBRARY = "libc++";
|
|
185
185
|
CLANG_ENABLE_MODULES = YES;
|
|
186
186
|
CLANG_ENABLE_OBJC_ARC = YES;
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
isa = XCBuildConfiguration;
|
|
231
231
|
buildSettings = {
|
|
232
232
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
233
|
-
CLANG_CXX_LANGUAGE_STANDARD = "
|
|
233
|
+
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
|
234
234
|
CLANG_CXX_LIBRARY = "libc++";
|
|
235
235
|
CLANG_ENABLE_MODULES = YES;
|
|
236
236
|
CLANG_ENABLE_OBJC_ARC = YES;
|