#Etienne-apple-pay

1 messages ยท Page 1 of 1 (latest)

clever scaffoldBOT
slate birch
#

HI ๐Ÿ‘‹

What is the issue? What docs are you following?

waxen valve
#

i am following that docs

#

along with the ios videos on youtube from stripe. My issue is when the paymentIntent is created, and the apple pay comes up, it rejects my payment. I will provide the exact issue momentarly

#

Here is the id: pi_3OC3jAIpmrzcezdL2TLk3eae

#

this is the issue:
"status": "requires_payment_method",

#

my console: Apple Pay Error: There was an unexpected error -- try again in a few seconds

slate birch
#

So you are presenting the payment sheet and that is working just fine? It's only when you click the Apple Pay button this error occurs?

waxen valve
#

it happens when i click the power button twice on the apple pay sheet

#

when it is processing the payment

#

i don't know if the issue is in my applePayModel or the stripe prepare paymentIntentModel

#

it seems simple as on stripe dashboard it is saying that the customer did not enter payment method

#

in my code, i listed it as "card"

slate birch
#

What do you mean "power button" on the Apple Pay sheet? That modal isn't something Stripe controls.

Have you registered your iOS payment domain for this application?

waxen valve
#

yes

#

What i mean is that the payment is getting rejected with Apple Pay, and then on stripes dashboard it is detecting the payment intent but not allowing the payment ot go through. I do not understand the issue i am having

slate birch
#

If Apple Pay rejects the payment then essentially you haven't provided a payment method to charge

#

So Stripe has nothing to charge

waxen valve
#

but i am passing in the card value in my node.js server

#

as well as testing it on a real card

slate birch
waxen valve
#

req_eLacMy0HGdJJIB

slate birch
#

This payment Intent doesn't have a payment method attached to it.

waxen valve
#

i'm aware of the issue

#

what i do not know is where the issue is, wether it is on my node.js server or in my swift code

#

can I share my code with you

slate birch
#

You can but I'm not sure it will help.

#

Since, from your description, the error occurring is happening during the Apple Pay process

waxen valve
#

app.post('/create-payment-intent', async (req, res) => {
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: req.body.amount, // specify amount
currency: 'usd', // specify currency
payment_method_types: ['card'],
});
res.send({
clientSecret: paymentIntent.client_secret,
});
} catch (error) {
res.status(500).send({ error: error.message });
}
});

#

that is my node.js paymentIntent

slate birch
#

Yes and that is working just fine as I can see in the API request

waxen valve
#

and thisis my swift paymentIntent:

func preparePaymentIntent(paymentMethodType: String, currency: String, amount: String) {
self.paymentMethodType = paymentMethodType
self.currency = currency
self.amount = amount
// MARK: Fetch the PaymentIntent from the backend
// Create a PaymentIntent by calling the sample server's /create-payment-intent endpoint.
let url = URL(string: backendURL + "create-payment-intent")!
let json: [String: Any] = [
"currency": currency,
"paymentMethodTypes": paymentMethodType,
"amount": NSDecimalNumber(string: amount)
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: json)
let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (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],
let clientSecret = json["clientSecret"] as? String else {
let message = """
Failed to decode response from server.
Error: (error?.localizedDescription ?? "N/A")
HTTP Status Code: ((response as? HTTPURLResponse)?.statusCode ?? -1)
Data: (String(data: data ?? Data(), encoding: .utf8) ?? "N/A")
"""
print(message)
return
}
print("Created PaymentIntent")
// MARK: Create the PaymentIntent
DispatchQueue.main.async {
self!.paymentIntentParams = STPPaymentIntentParams(clientSecret: clientSecret)

#

}
})
task.resume()
}

#

i have the apple pay func pay method, but i'm not sure you will need that. My issue is that following the docs completly with the video, something is not matching up

slate birch
#

Right and I am saying I think that has to do with Apple Pay

waxen valve
#

would you like to see my apple pay model?

slate birch
#

no

#

Have you configured your iOS app in XCode to use the merchant identifier you registered with Apple?

waxen valve
#

yes

#

if not the apple pay sheet would not appear

slate birch
#

Okay can you wrap the Apple Pay submission in a guard statement and log any exceptions that may be thrown?

waxen valve
#

i cannot wrap it in a guard statement because it doesn't thrown an error

#

unless your looking for something specific

#

like a clientSecret key being nil

#

the only error i am receiving, however, is this: Apple Pay Error: There was an unexpected error -- try again in a few seconds

slate birch
#

Does that error share a code line where it is generated from?

waxen valve
#

func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPPaymentStatus, error: Error?) {
// When the payment is complete, display the status.
self.paymentStatus = status
self.lastPaymentError = error

    if let error = error {
            print("Apple Pay Error: \(error.localizedDescription)")
        }
}
clever scaffoldBOT
waxen valve
#

?

slate birch
#

Unfortunately that still looks like the error is coming from Apple Pay

waxen valve
#

I debugged it more, before the apple pay sheet comes up, it sends a payment Intent to my api server and there its getting flagged as no payment method, before the sheet even appears. Then when the sheet appears, nothing in the console on my api server detects anything with the apple pay sheet

#

{ paymentMethodType: 'card', currency: 'USD', amount: 500 }
2023-11-13T18:22:32.507504+00:00 heroku[router]: at=info method=POST path="/create-payment-intent" host=yshuapayment-8a9b7b255884.herokuapp.com request_id=b64e5fae-3e35-4719-8fb2-6bc485bbca22 fwd="98.208.158.73" dyno=web.1 connect=0ms service=242ms status=200 bytes=286 protocol=https

#

am i not adding something?

slate birch
#

That first request is to create the Payment Intent, correct?

waxen valve
#

yes

slate birch
#

The expected status is requires_payment_method

#

That is where it should be at that time

waxen valve
#

yes but when i go look at it in the stripe dashboard, it tells me that it requires_payment_method

slate birch
#

That is the point

#

That is exactly the status it should be in

waxen valve
#

that status is only 200 because it can communicate to the stripe api

#

i'm very confused because this is my first time working with stripe, and i followed all of the videos and documentation with swift and node.js multiple times

#

i do not understand where i am going wrong

slate birch
#

Yout get the client secret back and then you call the applePayContext function passing in that client secret

waxen valve
#

am i calling the payment intent before the apple pay sheet?

slate birch
#

Look at the documentation you provided, in your client-side code in Step 8 you need to provide the client secret

#
extension CheckoutViewController {
    func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: StripeAPI.PaymentMethod, paymentInformation: PKPayment, completion: @escaping STPIntentClientSecretCompletionBlock) {
        let clientSecret = ... // <- SET PAYMENT INTENT CLIENT SECRET HERE
        // Call the completion block with the client secret or an error
        completion(clientSecret, error)
    }

    func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPApplePayContext.PaymentStatus, error: Error?) {
          switch status {
        case .success:
            // Payment succeeded, show a receipt view
            break
        case .error:
            // Payment failed, show the error
            break
        case .userCancellation:
            // User canceled the payment
            break
        @unknown default:
            fatalError()
        }
    }
}
#

There are two applePayContext functions here. The first one completes the payment and confirms the payment intent

#

The second block is designed to handle any post-payment actions

waxen valve
#

''''''

#
        // Confirm the PaymentIntent
        if (self.clientSecret != nil) {
            // Call the completion block with the PaymentIntent's client secret.
            completion(clientSecret, nil)
        } else {
            let error = NSError(domain: "ApplePayModel", code: 1000, userInfo: [NSLocalizedDescriptionKey: "Client Secret is missing"])
            completion(nil, error)

            
        }
    }

    func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPPaymentStatus, error: Error?) {
        // When the payment is complete, display the status.
        self.paymentStatus = status
        self.lastPaymentError = error
        
        
        
        if let error = error {
                print("Apple Pay Error: \(error.localizedDescription)")
            }
    }
#

i have both of them

slate birch
#

Can you log the client secret in the first block before you get to the if..else block?

#

And paste it here?

waxen valve
#

one moment

#

it appears that it does not print anything

#

as it the function is never ran

slate birch
#

Okay it seems like there is a breakdown between the creation of the payment intent and the confirmation.

#

In our example code, the Payment Intent is created and the clientSecret is returned within the first applePayContext function.

#

Can you modify your code to use that approach?

waxen valve
#

Please check: req_zPL126dpIS7vyV

CLIENT SECRET: nil
Apple Pay Error: Client Secret is missing

slate birch
#

Okay, now we are getting somewhere

waxen valve
#

i forgot to add the client publishable key in app delegate

#

or defaultPublishableKey i mean

#

but we are still not getting the client secret

slate birch
#

Okay but we know you are creating it because the request hits your node server

#

So you need to debug your code that makes that request and make sure it returns the client secret to your Swift code

waxen valve
#

req_mi5koFJMWCanYi

slate birch
#

Alright! Successful payment intent confirmation

waxen valve
#

!!!

#

Thank you @slate birch

slate birch
#

๐ŸŽ‰ I'm happy we could figure it out together ๐Ÿ™‚

waxen valve
#

๐Ÿ™‚