Assertion failed: `secret` format does not match expected client secret formatting in iOS Swift

66 views Asked by At

Implementation of first API Stripe has three APIs and I've implemented these three APIs properly which showing their result properly but I have issue while opening the payment sheet, Half payment sheet is opened and then app crashed.

func postRequestForCustomer() {
        let headers: HTTPHeaders = [
            Constants.authorization: Constants.bearer
        ]
        AF.request(Constants.stripeBaseURL + Constants.customers, method: .post, encoding: JSONEncoding.default, headers: headers)
            .validate(statusCode: 200..<300)
            .response { [self] response in
                switch response.result {
                case .success(let value):
                    if let jsonData = value {
                        do {
                            let json = try JSON(data: jsonData)
                            if let customerId = json["id"].string {
                                postRequestForEphemeralKey(customerID: customerId)
                            }
                        } catch {
                            print("Error parsing JSON for customer creation: \(error.localizedDescription)")
                        }
                    } else {
                        print("Unexpected response format for customer creation")
                    }
                case .failure(let error):
                    print("Customer Creation Error: \(error.localizedDescription)")
                }
            }
    }

Implementation of second API

func postRequestForEphemeralKey(customerID: String) {
        let headers: HTTPHeaders = [
            Constants.authorization: Constants.bearer,
            Constants.stripe_Version: Constants.stripe_Version_date
        ]
        let params: [String: Any] = [
            Constants.Params.customer: customerID
        ]
        AF.request(Constants.stripeBaseURL + Constants.ephemeral_keys, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: headers)
            .validate(statusCode: 200..<300)
            .response { [self] response in
                switch response.result {
                case .success(let value):
                    if let jsonData = value {
                        print("Ephemeral Key Response: \(String(data: jsonData, encoding: .utf8) ?? "")")
                        postRequestForPayment(customerID: customerID, amount: 10000)
                    } else {
                        print("Unexpected response format for ephemeral key")
                    }
                case .failure(let error):
                    if let data = response.data, let errorMessage = String(data: data, encoding: .utf8) {
                        print("Ephemeral Key Error: \(errorMessage)")
                    } else {
                        print("Ephemeral Key Error: \(error.localizedDescription)")
                    }
                }
            }
    }

Implementation of third API

func postRequestForPayment(customerID: String, amount: Int) {
        let headers: HTTPHeaders = [
            Constants.authorization: Constants.bearer,
        ]

        let params: [String: Any] = [
            Constants.Params.customer: customerID,
            Constants.Params.amount: amount,
            Constants.Params.currency: Constants.Params.usd
        ]

        AF.request(Constants.stripeBaseURL + Constants.payment_intents, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: headers)
            .validate(statusCode: 200..<300)
            .response { [self] response in
                switch response.result {
                case .success(let value):
                    if let jsonData = value {
                        do {
                            let json = try JSON(data: jsonData)
                            if let ephKeyID = json["id"].string {
                                openPaymentSheet()
                                print("Ephemeral Key ID: \(ephKeyID)")
                            } else {
                                print("Ephemeral Key ID not found in response")
                            }
                        } catch {
                            print("Error parsing JSON for ephemeral key: \(error.localizedDescription)")
                        }
                    } else {
                        print("Unexpected response format for ephemeral key")
                    }

                case .failure(let error):
                    if let data = response.data, let errorMessage = String(data: data, encoding: .utf8) {
                        print("Ephemeral Key Error: \(errorMessage)")
                    } else {
                        print("Ephemeral Key Error: \(error.localizedDescription)")
                    }
                }
            }
    }

Opening the payment sheet

func openPaymentSheet() {
        if let paymentSheet = paymentSheet {
            paymentSheet.present(from: self) { paymentResult in
                // MARK: Handle the payment result
                switch paymentResult {
                case .completed:
                    print("Your order is confirmed")
                case .canceled:
                    print("Canceled!")
                case .failed(let error):
                    print("Payment failed: \(error)")
                }
            }
        } else {
            print("Payment sheet is nil. Check the configuration.")
        }
    }

Here is the viewDidLoad method

override func viewDidLoad() {
        super.viewDidLoad()
        xibRegister()
        setUI()
        let configuration = PaymentSheet.Configuration()
        paymentSheet = PaymentSheet(paymentIntentClientSecret: Constants.secret_Key, configuration: configuration)
    }

I've issue to open the payment sheet.

1

There are 1 answers

0
karbi On

Are you passing in your Stripe secret key (format would be sk_test_123) when initializing PaymentSheet? If so, that would explain the error you're getting.

The paymentIntentClientSecret param expects a Payment Intent client_secret (format would be pi_xxx_secret_yyy), which is not the same as your account-wide secret key. You need to be creating a Payment Intent through Stripe's API, and use the client_secret value you get back after creation to correctly set up Payment Sheet. They talk about all of this in their "Accept a Payment" docs here