0

POST EDITED

I have a CheckoutViewController that I copied from the Stripe git repository and I implemented it into my app. At first I was trying to setup the STPPaymentContext in a different vc but it was giving a bad access but now when I try to set it up in the Checkout vc, I get an assertion failure saying the JSON couldn't be parsed.

This is what I have in my MyAPIClient class:

class MyAPIClient: NSObject, STPCustomerEphemeralKeyProvider {


let baseURL = "https://us-central1-attend-41f12.cloudfunctions.net/createEphemeralKeys"


let ticketVC: TicketFormViewController = TicketFormViewController()


func createCustomerKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
    ticketVC.getUsersStripeCustomerID { (customerid) in
        if let id = customerid {
            let url = URL(string:self.baseURL)!
            var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)!
            urlComponents.queryItems = [URLQueryItem(name: "api_version", value: apiVersion), URLQueryItem(name: "customer_id", value: id)]
            var request = URLRequest(url: urlComponents.url!)
            request.httpMethod = "POST"
            let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
                guard let response = response as? HTTPURLResponse,
                      response.statusCode == 200,
                      let data = data,
                      let json = ((try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]) as [String : Any]??) else {
                    completion(nil, error)
                    return
                }
                completion(json, nil)
            })
            task.resume()
        }
    }
}

}

This is my Cloud Functions function that I created to try and get the ephemeral key:

exports.createEphemeralKeys = functions.https.onRequest(async (req, 
res) => {
var api_version = req.body.api_version;
var customerId = req.body.customer_id;

if (!api_version) {
 res.status(400).end();
 return;
}

let key = await stripe.ephemeralKeys.create(
  { customer: customerId },
  { stripe_version: api_version }
 );
 res.json(key);

});

This is looking like it's causing the problem, I know it's not the URL because I made another API call this morning with a paymentIntent Cloud Function and it had a 200 Status Code. I copied the code from the Stripe docs and had faith that it would work but it let me down. Any suggestions.

UPDATE I also checked the Cloud Functions server logs, and the function is executing with a 400 Error Status Code, so it's definitely the Cloud Function that is the issue, isn't the json in the exports.createEphemeralKeys function unmodified already, what else do I need to add for it to work?

dsonawave
  • 137
  • 2
  • 12
  • Do you have an error message in console when this happens? Also is `TicketFormViewController` supposed to be a ViewController with its own `TicketFormViewController.xib`? Or are you using a Storyboard for it? – Larme Mar 18 '21 at 22:28
  • I just get a warning, saying `warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.`. No the `TicketFormViewController` does not have a `.xib` file, I'm using storyboards. @Larme – dsonawave Mar 18 '21 at 22:34
  • So `super.init(nibName: nil, bundle: nil)` doesn't make sens since you are configured it in a Storyboard. https://stackoverflow.com/questions/24035984/instantiate-and-present-a-viewcontroller-in-swift But `MyAPIClient` shouldn't know about `TicketFormViewController` Don't put `getUsersStripeCustomerID` inside it. – Larme Mar 18 '21 at 22:35
  • That's how they had it in the [docs](https://stripe.com/docs/mobile/ios/basic#prepare-your-api). I need the `getUsersStripeCustomerID`, the user could be different every time, so that's a must have, plus I removed it to see and it was still giving the same error regardless. @Larme – dsonawave Mar 18 '21 at 22:39
  • Im going to edit the question I moved the block of code into a CheckoutViewController and it's giving a different error now. @Larme – dsonawave Mar 18 '21 at 22:40
  • Code in Step 2 is independ of ViewController, and it should be independ from it. – Larme Mar 18 '21 at 22:41
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/230102/discussion-between-dsonawave-and-larme). – dsonawave Mar 18 '21 at 22:50
  • What is the assertion failure message? – Paulw11 Mar 18 '21 at 23:09
  • Cannot parse the ephmeral key. Make sure backend is sending unmodified JSON @Paulw11 – dsonawave Mar 18 '21 at 23:27

1 Answers1

0

After days of just trying to figure it out, I finally got help from a member in the Slack chat.

I got rid of the if statement, changed stripe_version to apiVersion because it was deprecated.

exports.createEphemeralKeys = functions.https.onRequest(async (req, res) => {
var api_version = req.query.api_version;
var customerId = req.query.customer_id;

const key = await stripe.ephemeralKeys.create(
  { customer: customerId },
  { apiVersion: api_version}
);
res.json(key);

});

I also changed req.body to req.query. The JSON now prints in the console, but there's still a lot left I need to figure out.

Dharman
  • 30,962
  • 25
  • 85
  • 135
dsonawave
  • 137
  • 2
  • 12