#Yerin-checkout-redirect-lambda
1 messages ยท Page 1 of 1 (latest)
const stripe = require('stripe')(process.env.GATSBY_STRIPE_SECRET_KEY);
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: process.env.GATSBY_FIREBASE_API_KEY,
authDomain: process.env.GATSBY_FIREBASE_AUTH_DOMAIN,
projectId: process.env.GATSBY_FIREBASE_PROJECT_ID,
storageBucket: process.env.GATSBY_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.GATSBY_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.GATSBY_FIREBASE_APP_ID
});
} else {
firebase.app(); // if already initialized, use that one
}
exports.handler = async (event) => {
//const { customerEmail, justomerEmail } = JSON.parse(JSON.stringify(event.body));
const { error } = await stripe.checkout.sessions ({
mode: "payment",
customerEmail: 'jhgfb@gmail.com',
clientReferenceId: 'jj',
lineItems: [{ price: "price_1JxA61DtAqr0NEuGxiGjREiC", quantity: 1 }],
successUrl: 'http://localhost:8000/app/profile',
cancelUrl: 'http://localhost:8000/app/profile',
})
if (error) {
console.warn("Error:", error)
}
};
Object.exports.handler (/Users/name/PerfectWeb/Portfolio/functions/create-standard-checkout.js:22:34)```
I am trying to use stripe in a lambda function but I am getting the follow issue
I can do a workout with use redirectToCheckout, but I like the interface it gives.
If I go the other path, that is use sessions.checkout, I understand that I will have to fill most of the information myself (there's no interface already built)
Is redirectToCheckout the only out of the box interface?
The reason being if I go the latter path, as i said sessions.checkout, I would need to code my own interface i.e. getting card data, zip code, ect.
correct?
redirectToCheckout is part of our Stripe-JS library and should be used by your frontend:
https://stripe.com/docs/js/checkout/redirect_to_checkout
Complete reference documentation for the Stripe JavaScript SDK.
It doesn't use any backend then correct?
I am using gatsby and netlify and when I run my website locally everything works fine
However, when I host it, checkout doesn't work
Another reason is that netlify won't let me run it without using lambda functions from what i've found
I am going through this currently
Please correct me if my understanding is wrong, but it sounds like you're trying to use a lambda function, to serve as your backend, to create a checkout session. Then you need to redirect your user to the session's URL.
That's correct. So I would essentially just follow the code in the snippet I just posted and I should be good to go
So you'd create the session as you are, and then either return a redirect as part of the response (similar to what's shown in the docs) or return the checkout session's ID and invoke redirectToCheckout via javascript on your frontend.
Ok, I will see if it works. Fingers crossed
I am not quite sure of the difference of these two methods...
Can you elaborate?
The first method being if I have a button that when clicked does the following:
const stripe = await getStripe()
const { error } = await stripe.redirectToCheckout({
mode: "payment",
customerEmail: customer.email,
clientReferenceId: customer.uid,
lineItems: [{ price: "price_1JxA61DtAqr0NEuGxiGjREiC", quantity: 1 }],
successUrl: 'http://localhost:8000/app/profile',
cancelUrl: 'http://localhost:8000/app/profile',
})
The other being sending a post and using a lambda function to create the session and then calling it from the front end
const stripe = Stripe(response.publishableKey);
const { error } = await stripe.redirectToCheckout({
sessionId: response.sessionId,
});
Does the latter just allow you to customize the checkout process more?
The latter approach allows more options to be passed in. For example with the first approach (client-only) we don't let you pass ad-hoc prices because a savvy user could manipulate the JS and change how much they pay.
This is how stripe does it with netlify for serverless
Which is the latter, but the former doesn't seem to work. At least once deployed
Can you elaborate on what you mean by 'the former doesn't seem to work'?
const purchaseStandardVersion = async event => {
console.log('starting purchase standard...')
event.preventDefault()
const stripe = await getStripe()
const { error } = await stripe.redirectToCheckout({
mode: "payment",
customerEmail: customer.email,
clientReferenceId: customer.uid,
lineItems: [{ price: "price_1JxA61DtAqr0NEuGxiGjREiC", quantity: 1 }],
successUrl: 'http://localhost:8000/app/profile',
cancelUrl: 'http://localhost:8000/app/profile',
})
if (error) {
console.warn("Error:", error)
}
}
When run on developer mode with netlify/gatsby I get no issues
I can make a payment with test cards and retrieve info from the webhook
but once I deploy
stripe won't popup
๐ I'm hopping in since @compact sky has to head out
I would highly recommend you don't use the client-only version of Checkout because it has so many limitations and is no longer being worked on - you can see a list of those limitation here: https://stripe.com/docs/payments/checkout/client
With that said, do you see any errors in the console when you deploy and try and run it?
DO you have a site I can take a look at to try it myself?
currently I am trying to use the webhook though and that's what is recently deployed
otherwise that button doesn't do anything I think because of how netlify handles things
That's why I am trying to go through lambda functions but I also want the nice interface that checkout has
Which button should i be pressing?
I'm not seeing anything that says standard on this site.... am I looking in the wrong place?
Oh sorry
If you go to the study guide section (click products on Navbar)
Click learn more the log in using google auth you should see standard
All data will be wiped before I make it live
๐
When I try it out I get this error message: "errorMessage":"create-standard-checkout.handler is undefined or not exported"
Are you sure you're properly set up the create-standard-account function?
Let me revert it to what I had before
To save you the effort
The code now is:
const firebase = require('firebase')
require("firebase/firestore");
const reactUse = require('react-use');
const stripe = require('stripe')(process.env.GATSBY_STRIPE_SECRET_KEY);
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: process.env.GATSBY_FIREBASE_API_KEY,
authDomain: process.env.GATSBY_FIREBASE_AUTH_DOMAIN,
projectId: process.env.GATSBY_FIREBASE_PROJECT_ID,
storageBucket: process.env.GATSBY_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.GATSBY_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.GATSBY_FIREBASE_APP_ID
});
} else {
firebase.app(); // if already initialized, use that one
}
exports.handler = async (event) => {
const session = await stripe.checkout.sessions.create({
mode: 'payment',
payment_method_types: ['card'],
success_url: 'http://localhost:8000/app/profile',
cancel_url: 'http://localhost:8000/app/profile',
line_items: [{ price: "price_1JxA61DtAqr0NEuGxiGjREiC", quantity: 1 }],
});
return {
statusCode: 200,
body: JSON.stringify({
sessionId: session.id,
publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
}),
};
};
When you click the button you get the following:
{"sessionId":"cs_test_a15BbeLtV65rblKbsBYBMZNxbuuv0b6ZUqhGAEVkX67QnYB2lc08jIJM0T"}
What is the name of the file that this is in?
How are you deploying?
this was in local, but it works the same once deployed
I am using netlify
so I upload to github and it deploys using my code from there
my project is gatsby/netlify
and firebase
I'm not the most familiar with netlify, but from some searching it looks like you can check your deploy and see what functions are on it - do you know how to do that?
Yup
any files in my functions directory are used as lambda functions
so the code above is one file
the other file I am using is to catch data after successful checkouts
so i'm trying to go from the sessionId above into making a checkout for the user to purchase something
Sorry let me clarify - do you have a link to your deploy that shows a summary and that it was successful? I'm hoping to see something like this:
to put the above in better wording: I have the start and end done
When I click the link it's been loading for awhile
oh no
good catch
oh but that's from the previous code
let me update it after the revert
Well, now I get a new error
if you go to my site again, there's a red block which, if you click, just calls the front end api which... does nothing ๐ฆ
If you click the standard, it cals the lambda function but that has a new error now saying I don't have an api key which I do
@hard hawk one sec
let
let me start here
I'm not super familiar with Firebase myself so you'll have to look on your end to unblock on the Firebase specific parts
I can try to help you help yourself and guide you but I won't have end to end answers
let's start here -
if you click, just calls the front end api which... does nothing
what are you expecting there? something on the lambda/Firebase side to happen? if so, what are you logging out to the console in your Firebase?
seeing logs in the console will help form an understanding on what is happening
So firebase all works fine
For the section you quoted, I was referring to the purchase button
during development it redirected to checkout
but once deployed, it doesn't
can you provide more details though? like we are speaking in general terms but
I was referring to the purchase button
that does something on the client-side and on the lambda side right
what does that do? what is logged, what code paths are hit etc? that is what the debugging process typically entails and I'm asking you to start doing that and share that info
When you click Purchase Standard it makes a post request /.netlify/functions/create-standard-checkout which is a serverless function on netlify (the code is above) and returns {"sessionId":"cs_test_a1qXlSXatAyLVZ8wF6thNb0Jp8grxfXMNk9paM0atUEdTWW5ppHicV3WJj"}
ok so that is promising
I want to use this sessionId to create a checkout session however
When I use the client-only redirectToCheckout, it doesn't do anything
it'll log to the console indicating the function is called
I am updating it to live and seeing if it'll have the same results (it hasn't been for some reason)
So when I run the same code when it's deployed
I get:
{"errorType":"Error","errorMessage":"You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.","trace":["Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/."," at IncomingMessage.<anonymous> (/var/task/node_modules/stripe/lib/StripeResource.js:184:21)"," at Object.onceWrapper (events.js:420:28)"," at IncomingMessage.emit (events.js:326:22)"," at endReadableNT (_stream_readable.js:1241:12)"," at processTicksAndRejections (internal/process/task_queues.js:84:21)"]}```
๐ข
const stripe = require('stripe')(process.env.GATSBY_STRIPE_SECRET_KEY);
Is this not the correct way to do it?
well log out what the value of process.env.GATSBY_STRIPE_SECRET_KEY is on your end (do NOT paste it here PLEASE!)
it clearly looks like that value is not being pulled from your env variables
that is the first place I would look
You were correct, I forgot to prefix GATSBY_
So everything worked on local, I am deploying to see if it works deployed also
sure but did you figure out if there was a problem with what I mentioned?
that you did/did not have a secret key being pulled up from your env variables?
Sorry, that's what I was referring to. a secret key wasn't being pulled because I didn't prefix my env variable with GATSBY_
after I prefixed it, everything seems to work in local
However, it doens't work after deployment
{errorType: "Error",โฆ}
errorMessage: "You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/."
errorType: "Error"
trace: [,โฆ]
0: "Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/."
1: " at IncomingMessage.<anonymous> (/var/task/node_modules/stripe/lib/StripeResource.js:184:21)"
2: " at Object.onceWrapper (events.js:420:28)"
3: " at IncomingMessage.emit (events.js:326:22)"
4: " at endReadableNT (_stream_readable.js:1241:12)"
5: " at processTicksAndRejections (internal/process/task_queues.js:84:21)"
looks like the same issue
This error appears under Network using Google Chrome Dev Tools when I test the same function
you are setting something to stripe instance
but it isn't being set, your secret key
so you'll have to troubleshoot that
Shouldn't this issue appear in both local and live if it can't find a secret key?
I don't know!
because I don't know what platforms you are working with
like I've not use Gatsby at all, barely used Firebase
so I'm not sure if there are any differences in their local vs deployed states
so you would have to look into that but we do know where the issue is
it is where-ever you are pulling in your secret key
log it out on your deployed app and see what it is
that is my generic advice on debugging as I'm not familiar with the dev ecosystem you're working in so there might be more pointed debugging steps you can take to look into it
Im about as experienced with it as you are.. ๐
Ill keep working at it
Thank you so much for everything you, and the rest of the stripe team, have done so far
np! we're here to help