#Svenson
1 messages · Page 1 of 1 (latest)
Hi there,
I invite you test it, but I think when using Apple Simulators you have already a test card added
So here you are not using Stripe SDK ?
this is after that fake class you provide
addPaymentPassViewController trying to use this, this is also from your doc
second section
Ah ok so your are trying to use issuing cards, sorry I didn't get the information at the beginning
yeah
addPaymentPassViewController from what I see expects the real controller, not the fake one
and I can not replace it
The error message shows that you exceed the 10sec timeout, in your test scenario are you having a delay ?
otherwise for test, did you check this section :
https://stripe.com/docs/issuing/cards/digital-wallets?platform=iOS&locale=fr-FR#testing
yeah, I am trying that
the error I get is after this step
after I click next
it waits for around 10sec and gives me the error
OK I'll ask for another feedback from one of my colleague
thank you!
hi again @mystic jungle can you share the full code of your ViewController in text form?
hi
yeah sure
public class Wallet: UIViewController {
var pushProvisioningContext: STPPushProvisioningContext? = nil
@IBOutlet weak var addPassButton: PKAddPassButton!
public weak var delegate: PKAddPaymentPassViewControllerDelegate? = nil
func beginPushProvisioning() {
let config = STPPushProvisioningContext.requestConfiguration(
withName: "Jenny Rosen", // the cardholder's name
description: "RocketRides Card", // optional; a description of your card
last4: "4242", // optional; the last 4 digits of the card
brand: .visa // optional; the brand of the card
)
let controller = STPFakeAddPaymentPassViewController(requestConfiguration: config, delegate: self)
print(11111)
let a = Data.init()
DispatchQueue.main.async {
let vc = self.findViewControllerPresenter(from: UIApplication.shared.delegate?.window??.rootViewController ?? UIViewController())
print(22222222)
vc.present(controller!, animated: true, completion: nil)
print(33333333)
}
}
```
first part
func findViewControllerPresenter(from uiViewController: UIViewController) -> UIViewController {
// Note: creating a UIViewController inside here results in a nil window
// This is a bit of a hack: We traverse the view hierarchy looking for the most reasonable VC to present from.
// A VC hosted within a SwiftUI cell, for example, doesn't have a parent, so we need to find the UIWindow.
var presentingViewController: UIViewController =
uiViewController.view.window?.rootViewController ?? uiViewController
// Find the most-presented UIViewController
while let presented = presentingViewController.presentedViewController {
presentingViewController = presented
}
return presentingViewController
}
extension Wallet: PKAddPaymentPassViewControllerDelegate {
public func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController, generateRequestWithCertificateChain certificates: [Data], nonce: Data, nonceSignature: Data, completionHandler handler: @escaping (PKAddPaymentPassRequest) -> Void) {
self.pushProvisioningContext = STPPushProvisioningContext(keyProvider: self)
self.pushProvisioningContext?.addPaymentPassViewController(controller, generateRequestWithCertificateChain: certificates, nonce: nonce, nonceSignature: nonceSignature, completionHandler: handler);
}
public func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController, didFinishAdding pass: PKPaymentPass?, error: Error?) {
self.dismiss(animated: true, completion: nil)
print(error)
}
}
extension Wallet: STPIssuingCardEphemeralKeyProvider {
public func createIssuingCardKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
// This example uses Alamofire for brevity, but you can make the request however you want
AF.request("",
method: .post,
parameters: ["api_version": apiVersion])
.responseJSON { response in
switch response.result {
case .failure(let error):
completion(nil, error)
case .success:
if let data = response.data {
do {
let obj = try JSONSerialization.jsonObject(with: data, options: []) as! [AnyHashable: Any]
completion(obj, nil)
} catch {
completion(nil, error)
}
}
}
}
}
}
sorry I could not place it all one one message
seems correct enough to me but I've never built this integration so aren't too familiar with debugging it
to confirm, is your backend call working?
i.e. in createIssuingCardKey are you contacting your backend, confirmed your backend received the request and responded promptly with valid data, and if you add some logs after the let obj = <get json> line, is that logging something sensible?
my understanding was that I do not need ephKeys for a testing env
hmm, is that understanding based on something? I don't see that mentioned in the docs
just base on this
"To make testing easier, we provide a mock version of PKAddPaymentPassViewController called STPFakeAddPaymentPassViewController that can be used interchangeably during testing"
I could be wrong however
maybe thats just for that fake class
should I call createIssuingCardKey() after vc.present
I would suspect you are wrong yes, the test implementation is probably just to mock out the Apple library. But the basics of using our product and SDK(creating an IssuingCard object ic_xxx for the customer user and using that in conjunction with your app(via the eph key)) are the actual integration that you're building
you don't have to call it at all yourself, it gets called 'automatically' by the rest of the code
i.e when you create STPPushProvisioningContext and pass self, that context object knows to call your implemented createIssuingKey method when it needs to(when addPaymentPassViewController is called)
yeah, seems like i am not getting into that createIssuingCardKeys
as in it's never called when you do the full flow in your app?
correct
at least full flow until I get the error
I understand the error, I am missing something in my completionHandler
but
when try to call addPaymentPassViewController
it seems that it expects real class and not STPFakeAddPaymentPassViewController
and I can not edit that, even if I change the type I get some other error for delegate
maybe I do not need to call that addPaymentPassViewController
same as you said for ephKeys
is there a specific error you get that indicates that?
Cannot convert value of type 'STPFakeAddPaymentPassViewController' to expected argument type 'PKAddPaymentPassViewController'
on which line, can you share the full context?
self.addPaymentPassViewController(
controller!,
generateRequestWithCertificateChain: [a],
nonce: a,
nonceSignature: a,
completionHandler: { request in
var contents: String?
if request.encryptedPassData != nil {
if let encryptedPassData1 = request.encryptedPassData {
contents = String(data: encryptedPassData1, encoding: .utf8)
}
}
if false {
var error =
"123"
as? String
if error == nil {
error = "123"
}
} else if contents == "TESTMODE_CONTENTS" {
} else {
}
})
on controller
this 123 are just there for a testing purposes
not sure if I need certificates for testing too
or if my app wont allow paying with apple pay
just adding to apple pay
not sure if I need those if I wont allow payments
just adding to wallet
how does the code snippet above relate to the VC you posted earlier? I'm a bit lost
i am calling that after vc.present
from the error message in screenshot, from exceeding the timout I think that this is needed
that completionHandler
I don't know why you call that, there's no code like that in our example React Native implementation or in the docs
the timeout is likely because of a missing/broken implementation of createEphemeralKey not calling your backend. Revisiting that, what's the status there?
so you think it's not needed?
did you update createIssuingKey to use a real backend URL instead of "" and test the backend/confirm the app is contacting it and getting the ephemeral key back?
I don't think so, since if you use localhost the simulator will probably try to connect to a service on the simulated device, not your Mac
gotcha, will need to release then to test it
not necessarily, I contact backend servers from my local testing/sandbox iOS apps all the time, by using services like ngrok.com or glitch.com or heroku to throw some HTTP servers online
you can also probably hard code an ephemeral key if you manually write some script to call the API and get the key. createIssuingCardKey just has to call completion(<an object that is an ephemeral key object>) , naturally that is calling a backend server and passing the object that way but it is possible to hard code it too. Probably easier for you to build the normal backend flow though.
even with actual URL it does not get called
func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController, generateRequestWithCertificateChain certificates, ...........){
.....
}
does that function get called?
and you do present the controller? i.e. your print(33333333) gets called?
correct
ok at this point I'd suggest writing in to https://support.stripe.com/?contact=true so you can talk to someone familiar with this integration over email as we're at this point deep into this integration which no one on my team is really deeply familiar with. Or if you're working with our sales team(most users using something this advanced are) then perhaps there's someone there can help.
When you write in please write a detailed email with complete context, all of your code, a screen recording of the flow you're seeing, links to all the docs you're using, and so on. Feel free to mention you were talking to me.
okay, I understand