@stripe/stripe-react-native 0.54.1 → 0.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +120 -57
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +5 -0
- package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +4 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherFragment.kt +1 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +54 -8
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +18 -0
- package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +84 -1
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +4 -0
- package/ios/Errors.swift +3 -2
- package/ios/Mappers.swift +111 -18
- package/ios/OldArch/StripeSdkEventEmitterCompat.h +1 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.m +6 -0
- package/ios/PaymentSheetAppearance.swift +15 -0
- package/ios/StripeSdk.mm +7 -0
- package/ios/StripeSdkEmitter.swift +1 -0
- package/ios/StripeSdkImpl+Embedded.swift +26 -4
- package/ios/StripeSdkImpl+PaymentSheet.swift +37 -15
- package/ios/StripeSdkImpl.swift +18 -1
- package/lib/commonjs/components/AddToWalletButton.js +1 -1
- package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
- package/lib/commonjs/components/AddressSheet.js +1 -1
- package/lib/commonjs/components/AddressSheet.js.map +1 -1
- package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
- package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
- package/lib/commonjs/components/CardField.js +1 -1
- package/lib/commonjs/components/CardField.js.map +1 -1
- package/lib/commonjs/components/CardForm.js +1 -1
- package/lib/commonjs/components/CardForm.js.map +1 -1
- package/lib/commonjs/components/PlatformPayButton.js +1 -1
- package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
- package/lib/commonjs/components/StripeContainer.js +1 -1
- package/lib/commonjs/components/StripeContainer.js.map +1 -1
- package/lib/commonjs/events.js.map +1 -1
- package/lib/commonjs/functions.js +1 -1
- package/lib/commonjs/functions.js.map +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/commonjs/types/ConfirmationToken.js +2 -0
- package/lib/commonjs/types/ConfirmationToken.js.map +1 -0
- package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/types/PaymentSheet.js +1 -1
- package/lib/commonjs/types/PaymentSheet.js.map +1 -1
- package/lib/commonjs/types/index.js +1 -1
- package/lib/commonjs/types/index.js.map +1 -1
- package/lib/module/components/AddToWalletButton.js +1 -1
- package/lib/module/components/AddToWalletButton.js.map +1 -1
- package/lib/module/components/AddressSheet.js +1 -1
- package/lib/module/components/AddressSheet.js.map +1 -1
- package/lib/module/components/AuBECSDebitForm.js +1 -1
- package/lib/module/components/AuBECSDebitForm.js.map +1 -1
- package/lib/module/components/CardField.js +1 -1
- package/lib/module/components/CardField.js.map +1 -1
- package/lib/module/components/CardForm.js +1 -1
- package/lib/module/components/CardForm.js.map +1 -1
- package/lib/module/components/PlatformPayButton.js +1 -1
- package/lib/module/components/PlatformPayButton.js.map +1 -1
- package/lib/module/components/StripeContainer.js +1 -1
- package/lib/module/components/StripeContainer.js.map +1 -1
- package/lib/module/events.js.map +1 -1
- package/lib/module/functions.js +1 -1
- package/lib/module/functions.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/module/types/ConfirmationToken.js +2 -0
- package/lib/module/types/ConfirmationToken.js.map +1 -0
- package/lib/module/types/EmbeddedPaymentElement.js +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/module/types/PaymentSheet.js +1 -1
- package/lib/module/types/PaymentSheet.js.map +1 -1
- package/lib/module/types/index.js +1 -1
- package/lib/module/types/index.js.map +1 -1
- package/lib/typescript/src/events.d.ts +4 -0
- package/lib/typescript/src/events.d.ts.map +1 -1
- package/lib/typescript/src/functions.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +1 -0
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/ConfirmationToken.d.ts +59 -0
- package/lib/typescript/src/types/ConfirmationToken.d.ts.map +1 -0
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentSheet.d.ts +52 -3
- package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
- package/lib/typescript/src/types/index.d.ts +2 -1
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/events.ts +4 -0
- package/src/functions.ts +16 -0
- package/src/index.tsx +1 -0
- package/src/specs/NativeStripeSdkModule.ts +3 -0
- package/src/types/ConfirmationToken.ts +76 -0
- package/src/types/EmbeddedPaymentElement.tsx +21 -0
- package/src/types/PaymentSheet.ts +60 -11
- package/src/types/index.ts +2 -0
- package/stripe-react-native.podspec +1 -1
- package/android/.idea/AndroidProjectSystem.xml +0 -6
- package/android/.idea/caches/deviceStreaming.xml +0 -703
- package/android/.idea/compiler.xml +0 -6
- package/android/.idea/gradle.xml +0 -18
- package/android/.idea/migrations.xml +0 -10
- package/android/.idea/misc.xml +0 -10
- package/android/.idea/runConfigurations.xml +0 -17
- package/android/.idea/vcs.xml +0 -6
- package/android/local.properties +0 -8
package/README.md
CHANGED
|
@@ -282,3 +282,14 @@ If you're still having troubles, please [open an issue](https://github.com/strip
|
|
|
282
282
|
### `Apple Pay Is Not Available in "My App Name"`
|
|
283
283
|
|
|
284
284
|
This can occur if you attempt to process an Apple Pay payment on a physical device (even in test mode) without having created **and uploaded** your Apple Pay Certificate to the Stripe Dashboard. Learn how to do that [here](https://stripe.com/docs/apple-pay#csr).
|
|
285
|
+
|
|
286
|
+
### `UnsupportedModulePropertyParserError` on iOS
|
|
287
|
+
|
|
288
|
+
While installing pods in your iOS project using a Stripe React Native version before 0.52, the old architecture, and a React Native version after 0.74, you may encounter the following error:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
UnsupportedModulePropertyParserError: Module NativeStripeSdkModule: TypeScript interfaces extending TurboModule must only contain 'FunctionTypeAnnotation's. Property 'onConfirmHandlerCallback' refers to a 'TSTypeReference'.
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
If possible, update to version 0.52 or above of the Stripe React Native SDK.
|
|
295
|
+
If you are unable to do so, please follow our [guide to apply the fix patch](https://github.com/stripe/stripe-react-native/tree/master/patches).
|
|
@@ -3,4 +3,4 @@ StripeSdk_compileSdkVersion=30
|
|
|
3
3
|
StripeSdk_targetSdkVersion=28
|
|
4
4
|
StripeSdk_minSdkVersion=21
|
|
5
5
|
# Keep StripeSdk_stripeVersion in sync with https://github.com/stripe/stripe-identity-react-native/blob/main/android/gradle.properties
|
|
6
|
-
StripeSdk_stripeVersion=21.
|
|
6
|
+
StripeSdk_stripeVersion=21.29.0
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.reactnativestripesdk
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint
|
|
3
4
|
import android.content.Context
|
|
4
5
|
import android.content.Intent
|
|
5
6
|
import android.util.Log
|
|
@@ -23,6 +24,7 @@ import com.facebook.react.bridge.Arguments
|
|
|
23
24
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
24
25
|
import com.reactnativestripesdk.toWritableMap
|
|
25
26
|
import com.reactnativestripesdk.utils.KeepJsAwakeTask
|
|
27
|
+
import com.reactnativestripesdk.utils.mapFromConfirmationToken
|
|
26
28
|
import com.reactnativestripesdk.utils.mapFromCustomPaymentMethod
|
|
27
29
|
import com.reactnativestripesdk.utils.mapFromPaymentMethod
|
|
28
30
|
import com.stripe.android.model.PaymentMethod
|
|
@@ -63,10 +65,16 @@ class EmbeddedPaymentElementView(
|
|
|
63
65
|
var latestElementConfig: EmbeddedPaymentElement.Configuration? = null
|
|
64
66
|
|
|
65
67
|
val rowSelectionBehaviorType = mutableStateOf<RowSelectionBehaviorType?>(null)
|
|
68
|
+
val useConfirmationTokenCallback = mutableStateOf(false)
|
|
66
69
|
|
|
67
70
|
private val reactContext get() = context as ThemedReactContext
|
|
68
71
|
private val events = Channel<Event>(Channel.UNLIMITED)
|
|
69
72
|
|
|
73
|
+
fun setUseConfirmationTokenCallback(value: Boolean) {
|
|
74
|
+
useConfirmationTokenCallback.value = value
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@SuppressLint("RestrictedApi")
|
|
70
78
|
@OptIn(ExperimentalCustomPaymentMethodsApi::class)
|
|
71
79
|
@Composable
|
|
72
80
|
override fun Content() {
|
|
@@ -153,73 +161,128 @@ class EmbeddedPaymentElementView(
|
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
|
|
156
|
-
val
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
cause =
|
|
167
|
-
Exception(
|
|
168
|
-
"Tried to call confirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
|
|
169
|
-
),
|
|
170
|
-
displayMessage = "An unexpected error occurred",
|
|
171
|
-
)
|
|
164
|
+
val useConfirmationToken by remember { useConfirmationTokenCallback }
|
|
165
|
+
|
|
166
|
+
val resultCallback =
|
|
167
|
+
remember {
|
|
168
|
+
{ result: EmbeddedPaymentElement.Result ->
|
|
169
|
+
val map =
|
|
170
|
+
Arguments.createMap().apply {
|
|
171
|
+
when (result) {
|
|
172
|
+
is EmbeddedPaymentElement.Result.Completed -> {
|
|
173
|
+
putString("status", "completed")
|
|
172
174
|
}
|
|
173
175
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
is EmbeddedPaymentElement.Result.Canceled -> {
|
|
177
|
+
putString("status", "canceled")
|
|
178
|
+
}
|
|
177
179
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
putBoolean("shouldSavePaymentMethod", shouldSavePaymentMethod)
|
|
180
|
+
is EmbeddedPaymentElement.Result.Failed -> {
|
|
181
|
+
putString("status", "failed")
|
|
182
|
+
putString("error", result.error.message ?: "Unknown error")
|
|
182
183
|
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementFormSheetConfirmComplete(map)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
183
189
|
|
|
184
|
-
|
|
190
|
+
val builder =
|
|
191
|
+
remember(type, useConfirmationToken) {
|
|
192
|
+
if (useConfirmationToken) {
|
|
193
|
+
EmbeddedPaymentElement
|
|
194
|
+
.Builder(
|
|
195
|
+
createIntentCallback = { confirmationToken ->
|
|
196
|
+
val stripeSdkModule =
|
|
197
|
+
try {
|
|
198
|
+
requireStripeSdkModule()
|
|
199
|
+
} catch (ex: IllegalArgumentException) {
|
|
200
|
+
return@Builder CreateIntentResult.Failure(
|
|
201
|
+
cause =
|
|
202
|
+
Exception(
|
|
203
|
+
"Tried to call confirmationTokenConfirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
|
|
204
|
+
),
|
|
205
|
+
displayMessage = "An unexpected error occurred",
|
|
206
|
+
)
|
|
207
|
+
}
|
|
185
208
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
209
|
+
// Make sure that JS is active since the activity will be paused when stripe ui is presented.
|
|
210
|
+
val keepJsAwakeTask =
|
|
211
|
+
KeepJsAwakeTask(reactContext.reactApplicationContext).apply { start() }
|
|
189
212
|
|
|
190
|
-
|
|
213
|
+
val params =
|
|
214
|
+
Arguments.createMap().apply {
|
|
215
|
+
putMap("confirmationToken", mapFromConfirmationToken(confirmationToken))
|
|
216
|
+
}
|
|
191
217
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
+
stripeSdkModule.eventEmitter.emitOnConfirmationTokenHandlerCallback(params)
|
|
219
|
+
|
|
220
|
+
val resultFromJavascript = stripeSdkModule.embeddedConfirmationTokenCreationCallback.await()
|
|
221
|
+
// reset the completable
|
|
222
|
+
stripeSdkModule.embeddedConfirmationTokenCreationCallback = CompletableDeferred()
|
|
223
|
+
|
|
224
|
+
keepJsAwakeTask.stop()
|
|
225
|
+
|
|
226
|
+
resultFromJavascript.getString("clientSecret")?.let {
|
|
227
|
+
CreateIntentResult.Success(clientSecret = it)
|
|
228
|
+
} ?: run {
|
|
229
|
+
val errorMap = resultFromJavascript.getMap("error")
|
|
230
|
+
CreateIntentResult.Failure(
|
|
231
|
+
cause = Exception(errorMap?.getString("message")),
|
|
232
|
+
displayMessage = errorMap?.getString("localizedMessage"),
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
resultCallback = resultCallback,
|
|
237
|
+
)
|
|
238
|
+
} else {
|
|
239
|
+
EmbeddedPaymentElement
|
|
240
|
+
.Builder(
|
|
241
|
+
createIntentCallback = { paymentMethod, shouldSavePaymentMethod ->
|
|
242
|
+
val stripeSdkModule =
|
|
243
|
+
try {
|
|
244
|
+
requireStripeSdkModule()
|
|
245
|
+
} catch (ex: IllegalArgumentException) {
|
|
246
|
+
return@Builder CreateIntentResult.Failure(
|
|
247
|
+
cause =
|
|
248
|
+
Exception(
|
|
249
|
+
"Tried to call confirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
|
|
250
|
+
),
|
|
251
|
+
displayMessage = "An unexpected error occurred",
|
|
252
|
+
)
|
|
218
253
|
}
|
|
254
|
+
|
|
255
|
+
// Make sure that JS is active since the activity will be paused when stripe ui is presented.
|
|
256
|
+
val keepJsAwakeTask =
|
|
257
|
+
KeepJsAwakeTask(reactContext.reactApplicationContext).apply { start() }
|
|
258
|
+
|
|
259
|
+
val params =
|
|
260
|
+
Arguments.createMap().apply {
|
|
261
|
+
putMap("paymentMethod", mapFromPaymentMethod(paymentMethod))
|
|
262
|
+
putBoolean("shouldSavePaymentMethod", shouldSavePaymentMethod)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
stripeSdkModule.eventEmitter.emitOnConfirmHandlerCallback(params)
|
|
266
|
+
|
|
267
|
+
val resultFromJavascript = stripeSdkModule.embeddedIntentCreationCallback.await()
|
|
268
|
+
// reset the completable
|
|
269
|
+
stripeSdkModule.embeddedIntentCreationCallback = CompletableDeferred()
|
|
270
|
+
|
|
271
|
+
keepJsAwakeTask.stop()
|
|
272
|
+
|
|
273
|
+
resultFromJavascript.getString("clientSecret")?.let {
|
|
274
|
+
CreateIntentResult.Success(clientSecret = it)
|
|
275
|
+
} ?: run {
|
|
276
|
+
val errorMap = resultFromJavascript.getMap("error")
|
|
277
|
+
CreateIntentResult.Failure(
|
|
278
|
+
cause = Exception(errorMap?.getString("message")),
|
|
279
|
+
displayMessage = errorMap?.getString("localizedMessage"),
|
|
280
|
+
)
|
|
219
281
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
282
|
+
},
|
|
283
|
+
resultCallback = resultCallback,
|
|
284
|
+
)
|
|
285
|
+
}.confirmCustomPaymentMethodCallback(confirmCustomPaymentMethodCallback)
|
|
223
286
|
.rowSelectionBehavior(
|
|
224
287
|
if (type == RowSelectionBehaviorType.Default) {
|
|
225
288
|
EmbeddedPaymentElement.RowSelectionBehavior.default()
|
|
@@ -80,6 +80,11 @@ class EmbeddedPaymentElementViewManager :
|
|
|
80
80
|
) {
|
|
81
81
|
val readableMap = cfg.asMap()
|
|
82
82
|
if (readableMap == null) return
|
|
83
|
+
|
|
84
|
+
// Detect which callback type to use based on the presence of the confirmation token handler
|
|
85
|
+
val useConfirmationTokenCallback = readableMap.hasKey("confirmationTokenConfirmHandler")
|
|
86
|
+
view.setUseConfirmationTokenCallback(useConfirmationTokenCallback)
|
|
87
|
+
|
|
83
88
|
val intentConfig = parseIntentConfiguration(readableMap)
|
|
84
89
|
view.latestIntentConfig = intentConfig
|
|
85
90
|
view.latestElementConfig?.let { elemCfg ->
|
|
@@ -24,6 +24,10 @@ class EventEmitterCompat(
|
|
|
24
24
|
invoke("onConfirmHandlerCallback", value)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
fun emitOnConfirmationTokenHandlerCallback(value: ReadableMap?) {
|
|
28
|
+
invoke("onConfirmationTokenHandlerCallback", value)
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
fun emitOnFinancialConnectionsEvent(value: ReadableMap?) {
|
|
28
32
|
invoke("onFinancialConnectionsEvent", value)
|
|
29
33
|
}
|
|
@@ -384,6 +384,7 @@ class PaymentLauncherFragment : StripeFragment() {
|
|
|
384
384
|
StripeIntent.NextActionType.VerifyWithMicrodeposits,
|
|
385
385
|
StripeIntent.NextActionType.DisplayMultibancoDetails,
|
|
386
386
|
StripeIntent.NextActionType.DisplayPayNowDetails,
|
|
387
|
+
StripeIntent.NextActionType.DisplayPromptPayDetails,
|
|
387
388
|
-> true
|
|
388
389
|
StripeIntent.NextActionType.RedirectToUrl,
|
|
389
390
|
StripeIntent.NextActionType.UseStripeSdk,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.reactnativestripesdk
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint
|
|
3
4
|
import android.app.Activity
|
|
4
5
|
import android.app.Application
|
|
5
6
|
import android.content.Context
|
|
@@ -30,6 +31,7 @@ import com.reactnativestripesdk.utils.PaymentSheetException
|
|
|
30
31
|
import com.reactnativestripesdk.utils.StripeFragment
|
|
31
32
|
import com.reactnativestripesdk.utils.createError
|
|
32
33
|
import com.reactnativestripesdk.utils.createResult
|
|
34
|
+
import com.reactnativestripesdk.utils.mapFromConfirmationToken
|
|
33
35
|
import com.reactnativestripesdk.utils.mapFromCustomPaymentMethod
|
|
34
36
|
import com.reactnativestripesdk.utils.mapFromPaymentMethod
|
|
35
37
|
import com.reactnativestripesdk.utils.mapToPreferredNetworks
|
|
@@ -38,6 +40,7 @@ import com.reactnativestripesdk.utils.removeFragment
|
|
|
38
40
|
import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
|
|
39
41
|
import com.stripe.android.model.PaymentMethod
|
|
40
42
|
import com.stripe.android.paymentelement.ConfirmCustomPaymentMethodCallback
|
|
43
|
+
import com.stripe.android.paymentelement.CreateIntentWithConfirmationTokenCallback
|
|
41
44
|
import com.stripe.android.paymentelement.CustomPaymentMethodResult
|
|
42
45
|
import com.stripe.android.paymentelement.CustomPaymentMethodResultHandler
|
|
43
46
|
import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi
|
|
@@ -73,8 +76,10 @@ class PaymentSheetFragment :
|
|
|
73
76
|
private var presentPromise: Promise? = null
|
|
74
77
|
private var paymentSheetTimedOut = false
|
|
75
78
|
internal var paymentSheetIntentCreationCallback = CompletableDeferred<ReadableMap>()
|
|
79
|
+
internal var paymentSheetConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
|
|
76
80
|
private var keepJsAwake: KeepJsAwakeTask? = null
|
|
77
81
|
|
|
82
|
+
@SuppressLint("RestrictedApi")
|
|
78
83
|
@OptIn(ExperimentalCustomPaymentMethodsApi::class)
|
|
79
84
|
override fun prepare() {
|
|
80
85
|
val merchantDisplayName = arguments?.getString("merchantDisplayName").orEmpty()
|
|
@@ -102,6 +107,10 @@ class PaymentSheetFragment :
|
|
|
102
107
|
initPromise.resolve(createError(ErrorType.Failed.toString(), error))
|
|
103
108
|
return
|
|
104
109
|
}
|
|
110
|
+
|
|
111
|
+
// Determine which callback type to use based on what's provided
|
|
112
|
+
val intentConfigBundle = arguments?.getBundle("intentConfiguration")
|
|
113
|
+
val useConfirmationTokenCallback = intentConfigBundle?.containsKey("confirmationTokenConfirmHandler") == true
|
|
105
114
|
val appearance =
|
|
106
115
|
try {
|
|
107
116
|
buildPaymentSheetAppearance(arguments?.getBundle("appearance"), context)
|
|
@@ -212,6 +221,32 @@ class PaymentSheetFragment :
|
|
|
212
221
|
}
|
|
213
222
|
}
|
|
214
223
|
|
|
224
|
+
val createConfirmationTokenCallback =
|
|
225
|
+
CreateIntentWithConfirmationTokenCallback { confirmationToken ->
|
|
226
|
+
val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
|
|
227
|
+
val params =
|
|
228
|
+
Arguments.createMap().apply {
|
|
229
|
+
putMap("confirmationToken", mapFromConfirmationToken(confirmationToken))
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
stripeSdkModule?.eventEmitter?.emitOnConfirmationTokenHandlerCallback(params)
|
|
233
|
+
|
|
234
|
+
val resultFromJavascript = paymentSheetConfirmationTokenCreationCallback.await()
|
|
235
|
+
// reset the completable
|
|
236
|
+
paymentSheetConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
|
|
237
|
+
|
|
238
|
+
return@CreateIntentWithConfirmationTokenCallback resultFromJavascript.getString("clientSecret")?.let {
|
|
239
|
+
CreateIntentResult.Success(clientSecret = it)
|
|
240
|
+
}
|
|
241
|
+
?: run {
|
|
242
|
+
val errorMap = resultFromJavascript.getMap("error")
|
|
243
|
+
CreateIntentResult.Failure(
|
|
244
|
+
cause = Exception(errorMap?.getString("message")),
|
|
245
|
+
displayMessage = errorMap?.getString("localizedMessage"),
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
215
250
|
val billingDetailsConfig =
|
|
216
251
|
PaymentSheet.BillingDetailsCollectionConfiguration(
|
|
217
252
|
name = mapToCollectionMode(billingConfigParams?.getString("name")),
|
|
@@ -271,11 +306,18 @@ class PaymentSheetFragment :
|
|
|
271
306
|
if (arguments?.getBoolean("customFlow") == true) {
|
|
272
307
|
flowController =
|
|
273
308
|
if (intentConfiguration != null) {
|
|
274
|
-
|
|
275
|
-
.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
309
|
+
val builder =
|
|
310
|
+
PaymentSheet.FlowController
|
|
311
|
+
.Builder(
|
|
312
|
+
resultCallback = paymentResultCallback,
|
|
313
|
+
paymentOptionResultCallback = paymentOptionCallback,
|
|
314
|
+
)
|
|
315
|
+
if (useConfirmationTokenCallback) {
|
|
316
|
+
builder.createIntentCallback(createConfirmationTokenCallback)
|
|
317
|
+
} else {
|
|
318
|
+
builder.createIntentCallback(createIntentCallback)
|
|
319
|
+
}
|
|
320
|
+
builder
|
|
279
321
|
.confirmCustomPaymentMethodCallback(this)
|
|
280
322
|
.build(this)
|
|
281
323
|
} else {
|
|
@@ -290,9 +332,13 @@ class PaymentSheetFragment :
|
|
|
290
332
|
} else {
|
|
291
333
|
paymentSheet =
|
|
292
334
|
if (intentConfiguration != null) {
|
|
293
|
-
PaymentSheet
|
|
294
|
-
|
|
295
|
-
.createIntentCallback(
|
|
335
|
+
val builder = PaymentSheet.Builder(paymentResultCallback)
|
|
336
|
+
if (useConfirmationTokenCallback) {
|
|
337
|
+
builder.createIntentCallback(createConfirmationTokenCallback)
|
|
338
|
+
} else {
|
|
339
|
+
builder.createIntentCallback(createIntentCallback)
|
|
340
|
+
}
|
|
341
|
+
builder
|
|
296
342
|
.confirmCustomPaymentMethodCallback(this)
|
|
297
343
|
.build(this)
|
|
298
344
|
} else {
|
|
@@ -94,7 +94,9 @@ class StripeSdkModule(
|
|
|
94
94
|
private var customerSheetFragment: CustomerSheetFragment? = null
|
|
95
95
|
|
|
96
96
|
internal var embeddedIntentCreationCallback = CompletableDeferred<ReadableMap>()
|
|
97
|
+
internal var embeddedConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
|
|
97
98
|
internal var customPaymentMethodResultCallback = CompletableDeferred<ReadableMap>()
|
|
99
|
+
internal var paymentSheetConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
|
|
98
100
|
|
|
99
101
|
internal var composeCompatView: StripeAbstractComposeView.CompatView? = null
|
|
100
102
|
|
|
@@ -323,6 +325,22 @@ class StripeSdkModule(
|
|
|
323
325
|
promise?.resolve(null)
|
|
324
326
|
}
|
|
325
327
|
|
|
328
|
+
@ReactMethod
|
|
329
|
+
override fun confirmationTokenCreationCallback(
|
|
330
|
+
params: ReadableMap,
|
|
331
|
+
promise: Promise,
|
|
332
|
+
) {
|
|
333
|
+
embeddedConfirmationTokenCreationCallback.complete(params)
|
|
334
|
+
paymentSheetConfirmationTokenCreationCallback.complete(params)
|
|
335
|
+
|
|
336
|
+
if (paymentSheetFragment == null) {
|
|
337
|
+
promise.resolve(PaymentSheetFragment.createMissingInitError())
|
|
338
|
+
return
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
paymentSheetFragment?.paymentSheetConfirmationTokenCreationCallback?.complete(params)
|
|
342
|
+
}
|
|
343
|
+
|
|
326
344
|
@ReactMethod
|
|
327
345
|
override fun createPaymentMethod(
|
|
328
346
|
data: ReadableMap,
|
|
@@ -18,6 +18,7 @@ import com.stripe.android.model.BankAccountTokenParams
|
|
|
18
18
|
import com.stripe.android.model.Card
|
|
19
19
|
import com.stripe.android.model.CardBrand
|
|
20
20
|
import com.stripe.android.model.ConfirmPaymentIntentParams
|
|
21
|
+
import com.stripe.android.model.ConfirmationToken
|
|
21
22
|
import com.stripe.android.model.GooglePayResult
|
|
22
23
|
import com.stripe.android.model.MicrodepositType
|
|
23
24
|
import com.stripe.android.model.PaymentIntent
|
|
@@ -152,6 +153,7 @@ internal fun mapPaymentMethodType(type: PaymentMethod.Type?): String =
|
|
|
152
153
|
PaymentMethod.Type.Affirm -> "Affirm"
|
|
153
154
|
PaymentMethod.Type.CashAppPay -> "CashApp"
|
|
154
155
|
PaymentMethod.Type.RevolutPay -> "RevolutPay"
|
|
156
|
+
PaymentMethod.Type.Link -> "Link"
|
|
155
157
|
else -> "Unknown"
|
|
156
158
|
}
|
|
157
159
|
|
|
@@ -183,6 +185,7 @@ internal fun mapToPaymentMethodType(type: String?): PaymentMethod.Type? =
|
|
|
183
185
|
"Affirm" -> PaymentMethod.Type.Affirm
|
|
184
186
|
"CashApp" -> PaymentMethod.Type.CashAppPay
|
|
185
187
|
"RevolutPay" -> PaymentMethod.Type.RevolutPay
|
|
188
|
+
"Link" -> PaymentMethod.Type.Link
|
|
186
189
|
else -> null
|
|
187
190
|
}
|
|
188
191
|
|
|
@@ -561,6 +564,7 @@ internal fun mapNextAction(
|
|
|
561
564
|
NextActionType.UseStripeSdk,
|
|
562
565
|
NextActionType.UpiAwaitNotification,
|
|
563
566
|
NextActionType.DisplayPayNowDetails,
|
|
567
|
+
NextActionType.DisplayPromptPayDetails,
|
|
564
568
|
null,
|
|
565
569
|
-> {
|
|
566
570
|
return null
|
|
@@ -1028,7 +1032,16 @@ internal fun mapToPreferredNetworks(networksAsInts: ArrayList<Int>?): List<CardB
|
|
|
1028
1032
|
internal fun mapFromFinancialConnectionsEvent(event: FinancialConnectionsEvent): WritableMap =
|
|
1029
1033
|
Arguments.createMap().apply {
|
|
1030
1034
|
putString("name", event.name.value)
|
|
1031
|
-
|
|
1035
|
+
|
|
1036
|
+
// We require keys to use pascal case, but the original map uses snake case.
|
|
1037
|
+
val tweakedMap =
|
|
1038
|
+
buildMap {
|
|
1039
|
+
put("institutionName", event.metadata.institutionName)
|
|
1040
|
+
put("manualEntry", event.metadata.manualEntry)
|
|
1041
|
+
put("errorCode", event.metadata.errorCode)
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
putMap("metadata", tweakedMap.toReadableMap())
|
|
1032
1045
|
}
|
|
1033
1046
|
|
|
1034
1047
|
private fun List<Any?>.toWritableArray(): WritableArray {
|
|
@@ -1118,3 +1131,73 @@ internal fun mapFromCustomPaymentMethod(
|
|
|
1118
1131
|
)
|
|
1119
1132
|
putMap("billingDetails", mapFromBillingDetails(billingDetails))
|
|
1120
1133
|
}
|
|
1134
|
+
|
|
1135
|
+
@SuppressLint("RestrictedApi")
|
|
1136
|
+
internal fun mapFromConfirmationToken(confirmationToken: ConfirmationToken): WritableMap {
|
|
1137
|
+
val token: WritableMap = WritableNativeMap()
|
|
1138
|
+
|
|
1139
|
+
token.putString("id", confirmationToken.id)
|
|
1140
|
+
token.putDouble("created", confirmationToken.created.toDouble())
|
|
1141
|
+
token.putDouble("expiresAt", confirmationToken.expiresAt?.toDouble() ?: 0.0)
|
|
1142
|
+
token.putBoolean("liveMode", confirmationToken.liveMode)
|
|
1143
|
+
token.putString("paymentIntentId", confirmationToken.paymentIntentId)
|
|
1144
|
+
token.putString("setupIntentId", confirmationToken.setupIntentId)
|
|
1145
|
+
token.putString("returnURL", confirmationToken.returnUrl)
|
|
1146
|
+
token.putString("setupFutureUsage", mapFromSetupFutureUsage(confirmationToken.setupFutureUsage))
|
|
1147
|
+
|
|
1148
|
+
// PaymentMethodPreview
|
|
1149
|
+
confirmationToken.paymentMethodPreview?.let { preview ->
|
|
1150
|
+
val paymentMethodPreview = WritableNativeMap()
|
|
1151
|
+
paymentMethodPreview.putString("type", mapPaymentMethodType(preview.type))
|
|
1152
|
+
paymentMethodPreview.putMap("billingDetails", mapFromBillingDetails(preview.billingDetails))
|
|
1153
|
+
paymentMethodPreview.putString("allowRedisplay", mapFromAllowRedisplay(preview.allowRedisplay))
|
|
1154
|
+
paymentMethodPreview.putString("customerId", preview.customerId)
|
|
1155
|
+
token.putMap("paymentMethodPreview", paymentMethodPreview)
|
|
1156
|
+
} ?: run {
|
|
1157
|
+
token.putNull("paymentMethodPreview")
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// Shipping details
|
|
1161
|
+
confirmationToken.shipping?.let { shippingDetails ->
|
|
1162
|
+
val shipping = WritableNativeMap()
|
|
1163
|
+
shipping.putString("name", shippingDetails.name)
|
|
1164
|
+
shipping.putString("phone", shippingDetails.phone)
|
|
1165
|
+
|
|
1166
|
+
shippingDetails.address?.let { address ->
|
|
1167
|
+
val addressMap = WritableNativeMap()
|
|
1168
|
+
addressMap.putString("city", address.city)
|
|
1169
|
+
addressMap.putString("country", address.country)
|
|
1170
|
+
addressMap.putString("line1", address.line1)
|
|
1171
|
+
addressMap.putString("line2", address.line2)
|
|
1172
|
+
addressMap.putString("postalCode", address.postalCode)
|
|
1173
|
+
addressMap.putString("state", address.state)
|
|
1174
|
+
shipping.putMap("address", addressMap)
|
|
1175
|
+
} ?: run {
|
|
1176
|
+
shipping.putMap("address", WritableNativeMap())
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
token.putMap("shipping", shipping)
|
|
1180
|
+
} ?: run {
|
|
1181
|
+
token.putNull("shipping")
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
return token
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
@SuppressLint("RestrictedApi")
|
|
1188
|
+
private fun mapFromSetupFutureUsage(setupFutureUsage: ConfirmPaymentIntentParams.SetupFutureUsage?): String? =
|
|
1189
|
+
when (setupFutureUsage) {
|
|
1190
|
+
ConfirmPaymentIntentParams.SetupFutureUsage.OnSession -> "on_session"
|
|
1191
|
+
ConfirmPaymentIntentParams.SetupFutureUsage.OffSession -> "off_session"
|
|
1192
|
+
ConfirmPaymentIntentParams.SetupFutureUsage.Blank -> ""
|
|
1193
|
+
ConfirmPaymentIntentParams.SetupFutureUsage.None -> "none"
|
|
1194
|
+
null -> null
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
private fun mapFromAllowRedisplay(allowRedisplay: PaymentMethod.AllowRedisplay?): String? =
|
|
1198
|
+
when (allowRedisplay) {
|
|
1199
|
+
PaymentMethod.AllowRedisplay.ALWAYS -> "always"
|
|
1200
|
+
PaymentMethod.AllowRedisplay.LIMITED -> "limited"
|
|
1201
|
+
PaymentMethod.AllowRedisplay.UNSPECIFIED -> "unspecified"
|
|
1202
|
+
null -> null
|
|
1203
|
+
}
|
|
@@ -158,6 +158,10 @@ public abstract class NativeStripeSdkModuleSpec extends ReactContextBaseJavaModu
|
|
|
158
158
|
@DoNotStrip
|
|
159
159
|
public abstract void intentCreationCallback(ReadableMap result, Promise promise);
|
|
160
160
|
|
|
161
|
+
@ReactMethod
|
|
162
|
+
@DoNotStrip
|
|
163
|
+
public abstract void confirmationTokenCreationCallback(ReadableMap result, Promise promise);
|
|
164
|
+
|
|
161
165
|
@ReactMethod
|
|
162
166
|
@DoNotStrip
|
|
163
167
|
public abstract void customPaymentMethodResultCallback(ReadableMap result, Promise promise);
|
package/ios/Errors.swift
CHANGED
|
@@ -14,9 +14,10 @@ class Errors {
|
|
|
14
14
|
|
|
15
15
|
static internal let isSetiClientSecretValidRegex: NSRegularExpression? = try? NSRegularExpression(
|
|
16
16
|
pattern: "^seti_[^_]+_secret_[^_]+$", options: [])
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
// The `uk_` prefix is used by the Stripe Dashboard Mobile App for MOTO
|
|
18
19
|
static internal let isEKClientSecretValidRegex: NSRegularExpression? = try? NSRegularExpression(
|
|
19
|
-
pattern: "^ek_[^_](.)+$", options: [])
|
|
20
|
+
pattern: "^(ek_|uk_)[^_](.)+$", options: [])
|
|
20
21
|
|
|
21
22
|
class func isPIClientSecretValid(clientSecret: String) -> Bool {
|
|
22
23
|
return (Errors.isPIClientSecretValidRegex?.numberOfMatches(
|