diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fe5af2e5..43d16f81f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Renamed `type` field to `paymentMethodType` on `PaymentMethod.Result`, `PaymentIntent.Result`, and `SetupIntent.Result` (result of `createPaymentMethod`, `retrieveSetupIntent`, `confirmSetupIntent`, `confirmPayment`, `collectBankAccountForPayment`, `collectBankAccountForSetup`, `verifyMicrodepositsForPayment`, and `verifyMicrodepositsForSetup`). - [#849](https://github.com/stripe/stripe-react-native/pull/849) BREAKING CHANGE: Renamed `placeholder` prop on `` and `` to `placeholders`. - [#849](https://github.com/stripe/stripe-react-native/pull/849) Feat: Added customized styling options to `` on Android. +- [#853](https://github.com/stripe/stripe-react-native/pull/853) Fix: resolve with useful error if attempting to use methods before initializing Stripe ## 0.7.0 diff --git a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt index 28f4fd47e..a0293ddc1 100644 --- a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +++ b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt @@ -31,7 +31,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React override fun getName(): String { return "StripeSdk" } - private lateinit var stripe: Stripe + private var stripe: Stripe? = null private lateinit var paymentLauncherFragment: PaymentLauncherFragment @@ -50,14 +50,19 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React private var initGooglePayPromise: Promise? = null private var presentGooglePayPromise: Promise? = null + private val MISSING_INIT_ERROR = createError( + "Failed", + "Stripe has not been initialized. Make sure you have initialized Stripe in your app with the StripeProvider component or the initStripe method." + ) + private val mActivityEventListener = object : BaseActivityEventListener() { override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) { - if (::stripe.isInitialized) { + if (stripe != null) { paymentSheetFragment?.activity?.activityResultRegistry?.dispatchResult(requestCode, resultCode, data) googlePayFragment?.activity?.activityResultRegistry?.dispatchResult(requestCode, resultCode, data) try { val result = AddPaymentMethodActivityStarter.Result.fromIntent(data) - if (data?.getParcelableExtra("extra_activity_result") != null) { + data?.getParcelableExtra("extra_activity_result")?.let { onFpxPaymentMethodResult(result) } } catch (e: java.lang.Exception) { @@ -214,7 +219,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React PaymentConfiguration.init(reactApplicationContext, publishableKey, stripeAccountId) - paymentLauncherFragment = PaymentLauncherFragment(stripe, publishableKey, stripeAccountId) + paymentLauncherFragment = PaymentLauncherFragment(stripe!!, publishableKey, stripeAccountId) getCurrentActivityOrResolveWithError(promise)?.let { it.supportFragmentManager.beginTransaction() .add(paymentLauncherFragment, "payment_launcher_fragment") @@ -236,6 +241,11 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React @ReactMethod fun initPaymentSheet(params: ReadableMap, promise: Promise) { + if (stripe == null) { + promise.resolve(MISSING_INIT_ERROR) + return + } + getCurrentActivityOrResolveWithError(promise)?.let { activity -> this.initPaymentSheetPromise = promise @@ -251,14 +261,24 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React @ReactMethod fun presentPaymentSheet(promise: Promise) { - this.presentPaymentSheetPromise = promise - paymentSheetFragment?.present() + paymentSheetFragment?.let { + this.presentPaymentSheetPromise = promise + it.present() + } ?: run { + promise.resolve( + createError("Failed", "Payment sheet has not been initialized.")) + } } @ReactMethod fun confirmPaymentSheetPayment(promise: Promise) { - this.confirmPaymentSheetPaymentPromise = promise - paymentSheetFragment?.confirmPayment() + paymentSheetFragment?.let { + this.confirmPaymentSheetPaymentPromise = promise + it.confirmPayment() + } ?: run { + promise.resolve( + createError("Failed", "Payment sheet has not been initialized.")) + } } private fun payWithFpx() { @@ -310,7 +330,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React val billingDetailsParams = mapToBillingDetails(getMapOrNull(paymentMethodData, "billingDetails"), cardAddress) val paymentMethodCreateParams = PaymentMethodCreateParams.create(cardParams, billingDetailsParams) - stripe.createPaymentMethod( + stripe?.createPaymentMethod( paymentMethodCreateParams, callback = object : ApiResultCallback { override fun onError(e: Exception) { @@ -321,7 +341,9 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React val paymentMethodMap: WritableMap = mapFromPaymentMethod(result) promise.resolve(createResult("paymentMethod", paymentMethodMap)) } - }) + }) ?: run { + promise.resolve(MISSING_INIT_ERROR) + } } @ReactMethod @@ -363,8 +385,12 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React ) CoroutineScope(Dispatchers.IO).launch { runCatching { - val token = stripe.createBankAccountToken(bankAccountParams, null, stripeAccountId) - promise.resolve(createResult("token", mapFromToken(token))) + stripe?.let { + val token = it.createBankAccountToken(bankAccountParams, null, stripeAccountId) + promise.resolve(createResult("token", mapFromToken(token))) + } ?: run { + promise.resolve(MISSING_INIT_ERROR) + } }.onFailure { promise.resolve(createError(CreateTokenErrorType.Failed.toString(), it.message)) } @@ -393,11 +419,15 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React CoroutineScope(Dispatchers.IO).launch { try { - val token = stripe.createCardToken( - cardParams = cardParams, - stripeAccountId = stripeAccountId - ) - promise.resolve(createResult("token", mapFromToken(token))) + stripe?.let { + val token = it.createCardToken( + cardParams = cardParams, + stripeAccountId = stripeAccountId + ) + promise.resolve(createResult("token", mapFromToken(token))) + } ?: run { + promise.resolve(MISSING_INIT_ERROR) + } } catch (e: Exception) { promise.resolve(createError(CreateTokenErrorType.Failed.toString(), e.message)) } @@ -406,7 +436,7 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React @ReactMethod fun createTokenForCVCUpdate(cvc: String, promise: Promise) { - stripe.createCvcUpdateToken( + stripe?.createCvcUpdateToken( cvc, callback = object : ApiResultCallback { override fun onSuccess(result: Token) { @@ -420,7 +450,9 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React promise.resolve(createError("Failed", e)) } } - ) + ) ?: run { + promise.resolve(MISSING_INIT_ERROR) + } } @ReactMethod @@ -498,11 +530,15 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React @ReactMethod fun retrievePaymentIntent(clientSecret: String, promise: Promise) { CoroutineScope(Dispatchers.IO).launch { - val paymentIntent = stripe.retrievePaymentIntentSynchronous(clientSecret) - paymentIntent?.let { - promise.resolve(createResult("paymentIntent", mapFromPaymentIntentResult(it))) + stripe?.let { stripe -> + val paymentIntent = stripe.retrievePaymentIntentSynchronous(clientSecret) + paymentIntent?.let { + promise.resolve(createResult("paymentIntent", mapFromPaymentIntentResult(it))) + } ?: run { + promise.resolve(createError(RetrievePaymentIntentErrorType.Unknown.toString(), "Failed to retrieve the PaymentIntent")) + } } ?: run { - promise.resolve(createError(RetrievePaymentIntentErrorType.Unknown.toString(), "Failed to retrieve the PaymentIntent")) + promise.resolve(MISSING_INIT_ERROR) } } } @@ -510,11 +546,15 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React @ReactMethod fun retrieveSetupIntent(clientSecret: String, promise: Promise) { CoroutineScope(Dispatchers.IO).launch { - val setupIntent = stripe.retrieveSetupIntentSynchronous(clientSecret) - setupIntent?.let { - promise.resolve(createResult("setupIntent", mapFromSetupIntentResult(it))) + stripe?.let { stripe -> + val setupIntent = stripe.retrieveSetupIntentSynchronous(clientSecret) + setupIntent?.let { + promise.resolve(createResult("setupIntent", mapFromSetupIntentResult(it))) + } ?: run { + promise.resolve(createError(RetrieveSetupIntentErrorType.Unknown.toString(), "Failed to retrieve the SetupIntent")) + } } ?: run { - promise.resolve(createError(RetrieveSetupIntentErrorType.Unknown.toString(), "Failed to retrieve the SetupIntent")) + promise.resolve(MISSING_INIT_ERROR) } } } @@ -646,6 +686,10 @@ class StripeSdkModule(private val reactContext: ReactApplicationContext) : React @ReactMethod fun verifyMicrodeposits(isPaymentIntent: Boolean, clientSecret: String, params: ReadableMap, promise: Promise) { + val stripe = stripe ?: run { + promise.resolve(MISSING_INIT_ERROR) + return + } val amounts = params.getArray("amounts") val descriptorCode = params.getString("descriptorCode") diff --git a/ios/StripeSdk.swift b/ios/StripeSdk.swift index 7cc29c2f7..4e143d1ab 100644 --- a/ios/StripeSdk.swift +++ b/ios/StripeSdk.swift @@ -10,6 +10,8 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi private var paymentSheet: PaymentSheet? private var paymentSheetFlowController: PaymentSheet.FlowController? + private var apiClient: STPAPIClient? = nil + private var paymentHandler: STPPaymentHandler? = nil var urlScheme: String? = nil @@ -25,6 +27,8 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi var shippingMethodUpdateHandler: ((PKPaymentRequestShippingMethodUpdate) -> Void)? = nil var shippingContactUpdateHandler: ((PKPaymentRequestShippingContactUpdate) -> Void)? = nil + static let MISSING_INIT_ERROR = Errors.createError(ErrorType.Failed, "Stripe publishableKey has not been set. Make sure you have initialized Stripe in your app with the StripeProvider component or the initStripe method.") + override func supportedEvents() -> [String]! { return ["onDidSetShippingMethod", "onDidSetShippingContact"] } @@ -38,32 +42,41 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi let publishableKey = params["publishableKey"] as! String let appInfo = params["appInfo"] as! NSDictionary let stripeAccountId = params["stripeAccountId"] as? String - let params3ds = params["threeDSecureParams"] as? NSDictionary + let threeDSParams = params["threeDSecureParams"] as? NSDictionary let urlScheme = params["urlScheme"] as? String let merchantIdentifier = params["merchantIdentifier"] as? String - if let params3ds = params3ds { - configure3dSecure(params3ds) - } - self.urlScheme = urlScheme - - STPAPIClient.shared.publishableKey = publishableKey - STPAPIClient.shared.stripeAccount = stripeAccountId - + let name = RCTConvert.nsString(appInfo["name"]) ?? "" let partnerId = RCTConvert.nsString(appInfo["partnerId"]) ?? "" let version = RCTConvert.nsString(appInfo["version"]) ?? "" let url = RCTConvert.nsString(appInfo["url"]) ?? "" - STPAPIClient.shared.appInfo = STPAppInfo(name: name, partnerId: partnerId, version: version, url: url) self.merchantIdentifier = merchantIdentifier + + STPAPIClient.shared.publishableKey = publishableKey + STPAPIClient.shared.stripeAccount = stripeAccountId + STPAPIClient.shared.appInfo = STPAppInfo(name: name, partnerId: partnerId, version: version, url: url) + self.apiClient = STPAPIClient.shared + + self.paymentHandler = STPPaymentHandler.shared() + self.paymentHandler?.apiClient = self.apiClient! + if let it = threeDSParams { + self.paymentHandler?.threeDSCustomizationSettings.uiCustomization = Mappers.mapUICustomization(it) + } + resolve(NSNull()) } @objc(initPaymentSheet:resolver:rejecter:) func initPaymentSheet(params: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { + guard apiClient != nil else { + resolve(StripeSdk.MISSING_INIT_ERROR) + return + } + var configuration = PaymentSheet.Configuration() self.paymentSheetFlowController = nil @@ -249,13 +262,17 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi return; } - STPAPIClient.shared.createToken(forCVCUpdate: cvc) { (token, error) in - if error != nil || token == nil { - resolve(Errors.createError(ErrorType.Failed, error?.localizedDescription ?? "")) - } else { - let tokenId = token?.tokenId - resolve(["tokenId": tokenId]) + if let it = apiClient { + it.createToken(forCVCUpdate: cvc) { (token, error) in + if error != nil || token == nil { + resolve(Errors.createError(ErrorType.Failed, error?.localizedDescription ?? "")) + } else { + let tokenId = token?.tokenId + resolve(["tokenId": tokenId]) + } } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -298,26 +315,29 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi setupIntentParams.returnURL = Mappers.mapToReturnURL(urlScheme: urlScheme) } - let paymentHandler = STPPaymentHandler.shared() - paymentHandler.confirmSetupIntent(setupIntentParams, with: self) { status, setupIntent, error in - switch (status) { - case .failed: - resolve(Errors.createError(ErrorType.Failed, error)) - break - case .canceled: - if let lastError = setupIntent?.lastSetupError { - resolve(Errors.createError(ErrorType.Canceled, lastError)) - } else { - resolve(Errors.createError(ErrorType.Canceled, "The payment has been canceled")) + if let it = paymentHandler { + it.confirmSetupIntent(setupIntentParams, with: self) { status, setupIntent, error in + switch (status) { + case .failed: + resolve(Errors.createError(ErrorType.Failed, error)) + break + case .canceled: + if let lastError = setupIntent?.lastSetupError { + resolve(Errors.createError(ErrorType.Canceled, lastError)) + } else { + resolve(Errors.createError(ErrorType.Canceled, "The payment has been canceled")) + } + break + case .succeeded: + let intent = Mappers.mapFromSetupIntent(setupIntent: setupIntent!) + resolve(Mappers.createResult("setupIntent", intent)) + @unknown default: + resolve(Errors.createError(ErrorType.Unknown, error)) + break } - break - case .succeeded: - let intent = Mappers.mapFromSetupIntent(setupIntent: setupIntent!) - resolve(Mappers.createResult("setupIntent", intent)) - @unknown default: - resolve(Errors.createError(ErrorType.Unknown, error)) - break } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -516,13 +536,6 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi reject(ErrorType.Failed, "Payment not completed", nil) } } - - func configure3dSecure(_ params: NSDictionary) { - let threeDSCustomizationSettings = STPPaymentHandler.shared().threeDSCustomizationSettings - let uiCustomization = Mappers.mapUICustomization(params) - - threeDSCustomizationSettings.uiCustomization = uiCustomization - } @objc(createPaymentMethod:options:resolver:rejecter:) func createPaymentMethod( @@ -551,20 +564,25 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi return } - if let paymentMethodParams = paymentMethodParams { - STPAPIClient.shared.createPaymentMethod(with: paymentMethodParams) { paymentMethod, error in + guard let paymentMethodParams = paymentMethodParams else { + resolve(Errors.createError(ErrorType.Unknown, "Unhandled error occured")) + return + } + + if let it = apiClient { + it.createPaymentMethod(with: paymentMethodParams) { paymentMethod, error in if let createError = error { resolve(Errors.createError(ErrorType.Failed, createError.localizedDescription)) return } - + if let paymentMethod = paymentMethod { let method = Mappers.mapFromPaymentMethod(paymentMethod) resolve(Mappers.createResult("paymentMethod", method)) } } } else { - resolve(Errors.createError(ErrorType.Unknown, "Unhandled error occured")) + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -610,13 +628,16 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi bankAccountParams.routingNumber = routingNumber bankAccountParams.accountHolderType = Mappers.mapToBankAccountHolderType(accountHolderType) - - STPAPIClient.shared.createToken(withBankAccount: bankAccountParams) { token, error in - if let token = token { - resolve(Mappers.createResult("token", Mappers.mapFromToken(token: token))) - } else { - resolve(Errors.createError(ErrorType.Failed, error as NSError?)) + if let it = apiClient { + it.createToken(withBankAccount: bankAccountParams) { token, error in + if let token = token { + resolve(Mappers.createResult("token", Mappers.mapFromToken(token: token))) + } else { + resolve(Errors.createError(ErrorType.Failed, error as NSError?)) + } } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -640,12 +661,16 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi cardSourceParams.name = params["name"] as? String cardSourceParams.currency = params["currency"] as? String - STPAPIClient.shared.createToken(withCard: cardSourceParams) { token, error in - if let token = token { - resolve(Mappers.createResult("token", Mappers.mapFromToken(token: token))) - } else { - resolve(Errors.createError(ErrorType.Failed, error as NSError?)) + if let it = apiClient { + it.createToken(withCard: cardSourceParams) { token, error in + if let token = token { + resolve(Mappers.createResult("token", Mappers.mapFromToken(token: token))) + } else { + resolve(Errors.createError(ErrorType.Failed, error as NSError?)) + } } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -655,28 +680,31 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock ){ - let paymentHandler = STPPaymentHandler.shared() - paymentHandler.handleNextAction(forPayment: paymentIntentClientSecret, with: self, returnURL: nil) { status, paymentIntent, handleActionError in - switch (status) { - case .failed: - resolve(Errors.createError(ErrorType.Failed, handleActionError)) - break - case .canceled: - if let lastError = paymentIntent?.lastPaymentError { - resolve(Errors.createError(ErrorType.Canceled, lastError)) - } else { - resolve(Errors.createError(ErrorType.Canceled, "The payment has been canceled")) - } - break - case .succeeded: - if let paymentIntent = paymentIntent { - resolve(Mappers.createResult("paymentIntent", Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent))) + if let it = paymentHandler { + it.handleNextAction(forPayment: paymentIntentClientSecret, with: self, returnURL: nil) { status, paymentIntent, handleActionError in + switch (status) { + case .failed: + resolve(Errors.createError(ErrorType.Failed, handleActionError)) + break + case .canceled: + if let lastError = paymentIntent?.lastPaymentError { + resolve(Errors.createError(ErrorType.Canceled, lastError)) + } else { + resolve(Errors.createError(ErrorType.Canceled, "The payment has been canceled")) + } + break + case .succeeded: + if let paymentIntent = paymentIntent { + resolve(Mappers.createResult("paymentIntent", Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent))) + } + break + @unknown default: + resolve(Errors.createError(ErrorType.Unknown, "Cannot complete payment")) + break } - break - @unknown default: - resolve(Errors.createError(ErrorType.Unknown, "Cannot complete payment")) - break } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -792,7 +820,11 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi if (error != nil) { resolve(error) } else { - STPPaymentHandler.shared().confirmPayment(paymentIntentParams, with: self, completion: onCompleteConfirmPayment) + if let it = paymentHandler { + it.confirmPayment(paymentIntentParams, with: self, completion: onCompleteConfirmPayment) + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) + } } } @@ -846,22 +878,25 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void { - STPAPIClient.shared.retrievePaymentIntent(withClientSecret: clientSecret) { (paymentIntent, error) in - guard error == nil else { - if let lastPaymentError = paymentIntent?.lastPaymentError { - resolve(Errors.createError(ErrorType.Unknown, lastPaymentError)) + if let it = apiClient { + it.retrievePaymentIntent(withClientSecret: clientSecret) { (paymentIntent, error) in + guard error == nil else { + if let lastPaymentError = paymentIntent?.lastPaymentError { + resolve(Errors.createError(ErrorType.Unknown, lastPaymentError)) + } else { + resolve(Errors.createError(ErrorType.Unknown, error?.localizedDescription)) + } + return + } + + if let paymentIntent = paymentIntent { + resolve(Mappers.createResult("paymentIntent", Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent))) } else { - resolve(Errors.createError(ErrorType.Unknown, error?.localizedDescription)) + resolve(Errors.createError(ErrorType.Unknown, "Failed to retrieve the PaymentIntent")) } - - return - } - - if let paymentIntent = paymentIntent { - resolve(Mappers.createResult("paymentIntent", Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent))) - } else { - resolve(Errors.createError(ErrorType.Unknown, "Failed to retrieve the PaymentIntent")) } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -871,22 +906,25 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void { - STPAPIClient.shared.retrieveSetupIntent(withClientSecret: clientSecret) { (setupIntent, error) in - guard error == nil else { - if let lastSetupError = setupIntent?.lastSetupError { - resolve(Errors.createError(ErrorType.Unknown, lastSetupError)) + if let it = apiClient { + it.retrieveSetupIntent(withClientSecret: clientSecret) { (setupIntent, error) in + guard error == nil else { + if let lastSetupError = setupIntent?.lastSetupError { + resolve(Errors.createError(ErrorType.Unknown, lastSetupError)) + } else { + resolve(Errors.createError(ErrorType.Unknown, error?.localizedDescription)) + } + return + } + + if let setupIntent = setupIntent { + resolve(Mappers.createResult("setupIntent", Mappers.mapFromSetupIntent(setupIntent: setupIntent))) } else { - resolve(Errors.createError(ErrorType.Unknown, error?.localizedDescription)) + resolve(Errors.createError(ErrorType.Unknown, "Failed to retrieve the SetupIntent")) } - - return - } - - if let setupIntent = setupIntent { - resolve(Mappers.createResult("setupIntent", Mappers.mapFromSetupIntent(setupIntent: setupIntent))) - } else { - resolve(Errors.createError(ErrorType.Unknown, "Failed to retrieve the SetupIntent")) } + } else { + resolve(StripeSdk.MISSING_INIT_ERROR) } } @@ -898,6 +936,11 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void { + guard let apiClient = apiClient else { + resolve(StripeSdk.MISSING_INIT_ERROR) + return + } + let amounts = params["amounts"] as? NSArray let descriptorCode = params["descriptorCode"] as? String @@ -912,14 +955,14 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi return } if (isPaymentIntent) { - STPAPIClient.shared.verifyPaymentIntentWithMicrodeposits( + apiClient.verifyPaymentIntentWithMicrodeposits( clientSecret: clientSecret as String, firstAmount: amounts[0] as! Int, secondAmount: amounts[1] as! Int, completion: onCompletePaymentVerification ) } else { - STPAPIClient.shared.verifySetupIntentWithMicrodeposits( + apiClient.verifySetupIntentWithMicrodeposits( clientSecret: clientSecret as String, firstAmount: amounts[0] as! Int, secondAmount: amounts[1] as! Int, @@ -928,13 +971,13 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi } } else if let descriptorCode = descriptorCode { if (isPaymentIntent) { - STPAPIClient.shared.verifyPaymentIntentWithMicrodeposits( + apiClient.verifyPaymentIntentWithMicrodeposits( clientSecret: clientSecret as String, descriptorCode: descriptorCode, completion: onCompletePaymentVerification ) } else { - STPAPIClient.shared.verifySetupIntentWithMicrodeposits( + apiClient.verifySetupIntentWithMicrodeposits( clientSecret: clientSecret as String, descriptorCode: descriptorCode, completion: onCompleteSetupVerification @@ -986,9 +1029,8 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi if let urlScheme = urlScheme { paymentIntentParams.returnURL = Mappers.mapToReturnURL(urlScheme: urlScheme) } - let paymentHandler = STPPaymentHandler.shared() bankViewController.dismiss(animated: true) - paymentHandler.confirmPayment(paymentIntentParams, with: self, completion: onCompleteConfirmPayment) + paymentHandler?.confirmPayment(paymentIntentParams, with: self, completion: onCompleteConfirmPayment) } func onCompleteConfirmPayment(status: STPPaymentHandlerActionStatus, paymentIntent: STPPaymentIntent?, error: NSError?) {