
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:02 Now that the front-facing part of the app is already looking great, there's only one thing left to implement.
00:00:08 Payments, so our users can actually book the trip.
00:00:12 And for that, we're going to use Stripe.
00:00:14 Head over to dashboard.stripe.com to log in, and you can sign in however you wish.
00:00:21 Once you're in, you'll want to turn on the test mode, and head over to the sandbox.
00:00:26 Create a new sandbox.
00:00:28 You can call it something like travel dashboard, and we can start an account from scratch.
00:00:34 Right here on the right side, you'll be able to find a Stripe secret and publishable key.
00:00:38 Copy the secret key.
00:00:40 Head back over to your application within your .env.local, and right at the bottom, add a Stripe key and call it Stripe secret key.
00:00:55 Perfect.
00:00:56 Now, open up your second terminal and run npm install stripe.
00:01:03 This will allow us to start using it from within our app.
00:01:06 So head over to your app, lib, and right next to utils, create a stripe.ts file.
00:01:15 This is where we're gonna implement our Stripe logic.
00:01:18 So, let's create a function that will allow us to create a product on Stripe once we actually create a trip.
00:01:26 So say exportConst createProduct is equal to an asynchronous function that needs to accept a couple of different fields about that product.
00:01:41 For example, a name, description, maybe some images to display.
00:01:46 We can also get the price and the trip ID.
00:01:50 We might as well give all of these properties a TypeScript type, so name is a string, description is a string.
00:01:57 Images is an array of strings, price will be a number, and a TripID will be a string.
00:02:04 Now that we have all of these properties, we are ready to create a product.
00:02:09 With Stripe, that is super simple.
00:02:11 You first have to create a Stripe instance by saying export const Stripe is equal to new Stripe instance And we're gonna import this stripe right at the
00:02:25 top by saying import stripe from stripe.
00:02:28 Make sure that the one on top is uppercased.
00:02:32 And then this one will be an instance of stripe.
00:02:35 So to generate it, we have to provide it with the secret key.
00:02:39 So process.env.stripeSecretKey.
00:02:44 And we can give it an exclamation mark since we know that it's there.
00:02:47 And you can also choose to provide an API version.
00:02:51 I think by default, it'll get this one, 2025.0331.basil.
00:02:57 But in case it got updated, since I recorded this video, that's totally okay as well.
00:03:02 So now that we have this instance of Stripe, we can create a new product by saying const product.
00:03:09 is equal to await stripe.products.create And you simply have to give it a name, a description, and some images.
00:03:21 That's it.
00:03:21 You have a Stripe product.
00:03:23 For each product, you also have to create a price object.
00:03:26 So let's say const price object is equal to await stripe.prices.create And you can attach this price object with a specific product ID.
00:03:39 You have to define the unit amount.
00:03:41 What this does is the price.
00:03:43 Stripe stores prices in cents to avoid rounding errors.
00:03:47 So we're gonna take the current price that is in dollars, and we're gonna multiply it by 100. And finally, you can choose the currency.
00:03:56 In this case, I'll set it to USD.
00:03:58 Perfect.
00:03:59 Now that we have the product and the price object, we're ready to create a payment link.
00:04:04 So we'll say const payment link is equal to await stripe.paymentlinks.create And to it, you have to provide the line items.
00:04:20 In this case, it's gonna be an array of a single object where price is equal to priceObject.id and the quantity will be 1. You can also provide the metadata
00:04:31 for that specific purchase and it'll be equal to an object that contains the trip ID.
00:04:37 Finally, After completion, we will do a type of redirect, and we will redirect to the following URL.
00:04:47 Process.env.vet base URL, we'll update this depending on the local or the deployed application, forward slash travel, forward slash trip ID,
00:05:00 forward slash success, so that we know which trip have we booked and whether our payment had been successful.
00:05:08 Finally, at the bottom, you can return the payment link.
00:05:12 That's because this function has done its job.
00:05:15 It has created the product and also returned the payment link.
00:05:21 Great.
00:05:22 I gotta say, Stripe seems to be even easier to use than I remember when I last used it.
00:05:28 They have by far the best developer experience.
00:05:31 I mean just how simple this was.
00:05:33 It is super function-based.
00:05:35 You simply call Stripe, you call the sub-objects such as products, prices, payment links, and you call the .create method on them.
00:05:43 Super simple, super easy.
00:05:46 So now that we have this payment link created, we'll need to call this functionality just after we create a trip.
00:05:55 So head over to createTrip.ts within our API.
00:06:02 and head below this result where we actually create the trip for the first time.
00:06:08 Now after the trip is created, we'll have to pass this data to this new function we just created.
00:06:15 So I'll say const tripDetail is equal to parse tripData to which I'll pass the result.tripDetail as trip.
00:06:26 Then I'll also get the tripPrice by calling the parseInt method and to it I'll pass the tripDetail.estimatedPrice.replace and I will replace the dollar
00:06:41 sign with an empty string.
00:06:42 And then we will use the decimal system so I'll add 10 as the radix to the parseInteger function.
00:06:48 Finally, we are ready to get the payment link by saying const paymentLink is equal to await to the call of the function we just created,
00:06:59 createProduct and now we can pass over the tripDetail.name We can pass over the trip detail dot description.
00:07:09 We can pass the image URLs, the trip price, as well as the result dot dollar sign ID.
00:07:17 So now, this function should have everything it needs to create a payment link.
00:07:22 And once we get that payment link, we want to update the created document with it.
00:07:28 So it's stored in the database, so that whenever somebody in the future tries to book that field, we have the payment link for it.
00:07:35 So I'll say await database.updateDocument.
00:07:41 We want to do the same thing as we have done here.
00:07:44 AppWrite database ID.
00:07:46 Apprite trip collection ID, but the update also requests the actual ID that we're trying to update.
00:07:54 And finally, the data that you want to update, which will be the payment link is paymentlink.url.
00:08:03 In this case, make sure to put the payment underscore link right here.
00:08:07 And then we are returning the created trip as usual.
00:08:10 Okay, great.
00:08:11 So now we're creating a new Stripe product and attaching a price to it when it gets created.
00:08:17 So this is a very important takeaway or a disclaimer.
00:08:22 Our Stripe payments will not work for the products we have created so far because they don't have a payment link attached to them.
00:08:32 We need to create a new product in order to be able to attach a payment link to it.
00:08:38 So let's head over to the admin panel and let's head over to AI Trips and create a new trip.
00:08:45 We can once again choose some random countries.
00:08:48 I'll do everything at random and select budget as well.
00:08:54 and let's generate a trip.
00:08:56 We're going to Africa.
00:08:57 Okay, we weren't redirected, which means that something went wrong with trip creation.
00:09:02 So if I head over to the terminal, you can see that it says that value is not JSON-seriesable, and it's talking about the estimated price right here.
00:09:13 I don't think it's the estimated price that is the problem.
00:09:16 It's actually the fact that we were trying to parse the undefined value.
00:09:21 So right before we tried to get the estimated price out of the trip detail, it's the trip detail that actually fails.
00:09:29 I think I called it details right here.
00:09:33 So it's my mistake.
00:09:33 Sometimes I keep calling it details, sometimes details with an S.
00:09:37 Whatever you choose to use, make sure to stick with it.
00:09:41 So I'll fix this over to details and then it should actually get access to the right data.
00:09:46 So I'll try it one more time.
00:09:47 Maybe this time I pick your country.
00:09:50 Let's do some more stuff right here.
00:09:54 And we are good.
00:09:56 This time, we're going to the Netherlands.
00:09:59 But it looks like we're not going anywhere, because again, we weren't redirected.
00:10:03 So in the console, it says, Stripe invalid request error, invalid URL, must begin with HTTPS.
00:10:12 Oh, so it looks like I have to provide the Vite base URL.
00:10:16 Remember, within the Stripe file right here, we said that we're going to use this base URL.
00:10:22 So if I head over to our .env.local, right at the top I will create a new VEAT base URL and I'll set it to HTTP colon forward slash forward slash localhost 5173.
00:10:41 Later on in production we'll replace this with a real URL.
00:10:45 Now, make sure that your application gets restarted.
00:10:48 And then let's try it one more time.
00:10:51 Netherlands sounds fun.
00:10:53 Actually, I'm going to Amsterdam this year to hold a talk at the React Summit Conference.
00:10:59 So let's see what it suggests for a five-day business trip.
00:11:03 Let's generate it.
00:11:05 Let's go to the Netherlands.
00:11:06 This time, we actually got redirected, so that's great.
00:11:10 And if you head over to Databases in your AppRite, you'll be able to see that under Trips, we have this new trip that was created just now,
00:11:20 going to Netherlands, and it also has the payment link from Stripe right here.
00:11:28 So, I'll copy that link, And I'll make sure to paste it into all of our other trips as well, just so our app doesn't break if any of the previous trips
00:11:38 are clicked.
00:11:39 What you could also totally do is just delete all the previous trips and make the new ones have the right payment link.
00:11:48 So you could go ahead and create a few more trips to test your application out.
00:11:52 Whatever you choose to do, that's okay.
00:11:54 So with that in mind, now we can head over to where we implemented this buy button.
00:12:00 Oh, but look at that.
00:12:01 I am on the admin side.
00:12:03 I actually want to head over to our homepage to check out our website as a user, check out this new historical adventure,
00:12:10 and I want to implement the logic for this pay to join the trip button.
00:12:14 Doing that is very easy right now.
00:12:17 You just have to head over to the travel detail page, find the button, and add an href to this anchor tag of payment link.
00:12:29 And where are you going to get this payment link from?
00:12:32 Well, it's going to come directly from the trip.
00:12:36 So see if you have access to the trip.
00:12:38 There we go, trip data.
00:12:40 And then right here below, you can get const payment link is equal to loader data.
00:12:47 Question mark dot trip.
00:12:48 Question mark dot payment underscore URL.
00:12:52 I believe that's how we called it.
00:12:55 So now we're passing it right here to this href.
00:12:59 We can also give this anchor tag a class name of flex.
00:13:04 So it nicely shows the elements within a button.
00:13:07 And you can also maybe give it a type of submit because we actually want to submit this page and continue to the next one.
00:13:13 So if I now click, pay to join this trip, it looks like nothing is happening.
00:13:19 So let me see, this payment link, oh, it should have been a payment link here too, payment underscore link.
00:13:26 So now, if I click on it, I got redirected to a beautiful Stripe checkout.
00:13:33 You can see that it is fully optimized for mobile devices, and of course looks great on desktop.
00:13:39 You can see that the metadata has also been passed in, such as the title, the price, the description, and the photo.
00:13:45 So, what do you say that we give it a shot and buy this trip to the Netherlands?
00:13:50 The default Stripe credit card info is just 424242, so you can keep mashing those numbers until you have the credit card info.
00:13:58 Same thing for the years, you can type any valid year that is in the future and anything for the last three numbers.
00:14:05 You can also enter your card holder name and click pay.
00:14:10 In a second, we'll be redirected to our success page.
00:14:15 Now, we got a 404, but that's totally okay because I can see by the URL that we are on the right page.
00:14:22 So, make sure to copy this URL just so we don't lose it.
00:14:25 And now, we can collapse the screen and implement this success page.
00:14:30 So, let's do that next.