I am using string in this application perviously but all the things done by backend developer but now stripe change their implementation and give support for European payment change (Supporting 3D Secure Authentication) with SCA so now i need to add library in my local code but i stuck at this place.
I got the client id from server but handle next action will give me error something like this.
Error Domain=STPPaymentHandlerErrorDomain Code=1 "There was an unexpected error -- try again in a few seconds" UserInfo={com.stripe.lib:ErrorMessageKey=The PaymentIntent requires a PaymentMethod or Source to be attached before using STPPaymentHandler., NSLocalizedDescription=There was an unexpected error -- try again in a few seconds}
I did not find any relative document here
Here is my code
//Api called on server for client id
MyAPIClient.sharedClient.createAndConfirmPaymentIntent(paymentResult,
amount: self.paymentContext.paymentAmount,
returnURL: "payments-example://stripe-redirect",
shippingAddress: self.paymentContext.shippingAddress,
shippingMethod: self.paymentContext.selectedShippingMethod) { (clientSecret, error) in
guard let clientSecret = clientSecret else {
completion(.error, error ?? NSError(domain: StripeDomain, code: 123, userInfo: [NSLocalizedDescriptionKey: "Unable to parse clientSecret from response"]))
return
}
STPPaymentHandler.shared().handleNextAction(forPayment: clientSecret, authenticationContext: paymentContext, returnURL: "payments-example://stripe-redirect") { (status, handledPaymentIntent, actionError) in
switch (status) {
case .succeeded:
guard let handledPaymentIntent = handledPaymentIntent else {
completion(.error, actionError ?? NSError(domain: StripeDomain, code: 123, userInfo: [NSLocalizedDescriptionKey: "Unknown failure"]))
return
}
if (handledPaymentIntent.status == .requiresConfirmation) {
// Confirm again on the backend
MyAPIClient.sharedClient.confirmPaymentIntent(handledPaymentIntent) { clientSecret, error in
guard let clientSecret = clientSecret else {
completion(.error, error ?? NSError(domain: StripeDomain, code: 123, userInfo: [NSLocalizedDescriptionKey: "Unable to parse clientSecret from response"]))
return
}
// Retrieve the Payment Intent and check the status for success
STPAPIClient.shared().retrievePaymentIntent(withClientSecret: clientSecret) { (paymentIntent, retrieveError) in
guard let paymentIntent = paymentIntent else {
completion(.error, retrieveError ?? NSError(domain: StripeDomain, code: 123, userInfo: [NSLocalizedDescriptionKey: "Unable to parse payment intent from response"]))
return
}
if paymentIntent.status == .succeeded {
completion(.success, nil)
}
else {
completion(.error, NSError(domain: StripeDomain, code: 123, userInfo: [NSLocalizedDescriptionKey: "Authentication failed."]))
}
}
}
} else {
// Success
completion(.success, nil)
}
case .failed:
completion(.error, actionError)
case .canceled:
completion(.userCancellation, nil)
}
}
My fix was to call paymentManager.confirmPayment(withParams: params, authenticationContext: self)
instead of handleNextAction