 Fantastic. Okay. Where are my slides? All right. Thanks for having me everyone. There's going to be a lot of puns in this presentation. As you can see, you know, easy e-commerce and then static because Gatsby, so ecstatic commerce. This is a pretty fancy location. I think normally there's a ballroom. I think the mirror is very distracting. At least I found that to be. So please look in the middle, not at yourself. Cool. Now normally when I'm in this country, I'm sweating a lot, but this is very comfortable for me. The temperatures is perfect. So I'm actually visiting our Singapore office this week, last week and this week. And normally I'm based in our Amsterdam office in the Netherlands. So this is the view from my window normally. Down there is the swimming flower market. It's on the canal. And what you can see the church is a melodic church. So every hour we get a little melody. That's great. And what you see on the rice there, that's Sir Nelson. You might be able to see a dock down there. And Sir Nelson is on call. As you can see, the API is up and running. So he can chill. This is actually a poster of increment. It's a magazine about building and deploying software at scale. So if you're interested in that, you can look it up online. It's pretty cool. There's some good issues. Now, quickly about myself. My name is Thorsten Scheff. I'm originally from Northern Germany. But because no one can pronounce that, you can just call me Thor. I think being in Northern Germany, that's close enough to the Norse kind of mythology. Yeah, so Thor. And then I guess my Twitter handle is pretty self-explanatory. Thorweb.dev. I also got my .dev domain. So can you guess what it is? Thorweb.dev. Yeah, cool. So what I do, I'm an integration engineer at Stripe, which means I work with many of our largest customers and partners, helping them build great payment experiences, checkout experiences. Generally more complex integrations like multi-sided marketplaces. So if you think of booking.com where a customer pays, and then the payment has to be routed to a hotel or a property, that's kind of a marketplace. Uber or Grab. Oh yeah, Grab is a good example here, right? Payment goes in, needs to be routed to a driver. That's what we do. And I do that in continental Europe. Now, what I want to do with you today is what I call a Jamstack Jam session. Have you heard of the term Jamstack before? Raise your hand. Brilliant, yeah. So Jam stands for JavaScript, APIs, and markup. And it's pretty much aesthetic size, like Gatsby is sort of a Jamstack application where you use JavaScript and APIs and potentially markdown, markup, aesthetic files to surf your content. And so a Jamstack Jam session actually means if you have your laptop with you, you can join me, you can pull it out now, open it up. I think there's a guest network and we can actually get cracking or you can follow along and the resources are available on Thor.News slash ecsthetic if you want to follow along. Okay, if you have your laptop now, it's the time. Crack it open. I can see you there in the front row. Put that water away. Okay, now let me see, can you see that? Yeah, so Gatsby has a fantastic documentation. There's also Jason Langstorff. He's on the DevRel team at Gatsby and he does many live streams, which are really great to follow along. And there's the Gatsby CLI that you can install. I've already done that. And then we can simply run Gatsby new to scaffold a new project. So we're going to do that here. I'm in my document folder, Gatsby new. We're going to call it Gatsby, let's say Singapore. Cool. Now, while that is running, and I hope it is running, we can actually look at hooks. Quick show of hands. Who here has used hooks in React? Okay, yeah, good amount of. Sorry? Okay, yeah, no, that's fair enough. So the reason why we need to send, actually what we're going to use is the effect hook. You're probably familiar with the component did mount function that you would use in your class components. Now, in function components, we can use the use effect function, which is exposed by React to get sort of the same effect of component did mount. And the reason we need that is because later on, we're going to load Stripe.js, which is our JavaScript library, which is going to be available on the window object. But because Gatsby site are server-side rendered, we can't actually access the window object in our normal React code. So that's why we need to wait until everything is mounted, and then we can access the window object. Cool, let's see if we... Oh, wow. Still running. Should we talk a bit more about hooks? What's there to say? Can you read the size? Is that good? Bit bigger. Bit bigger? Like that? Even bigger? Right, right, right. I mean, we're not actually really going to look at that. We're just sort of fantastic. Okay, time has passed. Let's open this in VS code. I guess it didn't work, sir. Whatever. Just going to... Come on. Open folder, sorry. There we have it. It's like I've never used the laptop before. Okay. Here we are. The structure is here. We have our pages. We have our index page in here, and what you can see, our index page is a function component that simply returns here our layout, the SEO, and all of that stuff. Now, we actually want to use the... use effect hook in there, so we need to turn this into a quick function. I'm just going to return that, and then what we can do is simply copy this. We don't have the variable here. We're just going to set this to 10 just to see if it works, and then let's actually... Is that size? Okay, can you read that? Higher. Well, now that's a bit awkward. I'm going to zoom in when it gets important. Can you see that? Yeah, cool. So what we actually can do now is we can use Gatsby develop to run our development server, and then when we go back, our local host... Oh, already have an error. Fantastic. Use effect is not defined yet. That makes sense. We need to actually load it. What did I do? Oh, yeah. Look at me. This is very collaborative. I like this. This is great. Ha! There we are. Can you always come to work with me? That would be good. Awesome. And as you can see, okay, our effect is working. Great. So we have that set up. Now, what do we need to do? Yeah, so actually now we'll quickly register a Stripe account because we're going to use the new Stripe hosted checkout because we're building a static website. We're actually not having a server, so we're sort of outsourcing the whole checkout piece to Stripe. So what we can do is we can go to Stripe.com slash register. Actually, have you heard of Stripe? Anyone doesn't know Stripe? Okay, wow. Is that everyone? Oh, yeah, that's okay. So what we do is online payments infrastructure. So you can sign up and within five minutes, well, probably 20 minutes, what we're doing here with all my talking, you can accept payments online as a developer. It's really, really easy to do that. And that's sort of what I'm trying to demonstrate. Now, let's do this. Let's quickly sign up in your account. I'm going to do Thor plus Singapore React.js. Well, actually, maybe. That's straight. Stripe.com. Thor. Now, can we get like a great Google password or something? Or actually, let's just do... Yeah, I mean, this is really, when you have your laptop and you follow along, it's not as boring. Cool. Oh, what? That is crazy now, okay. Let's do React SG. SG React.js. What? Not a robot. Come on. Let's quickly pin that tab. And what we want to do is we want to use checkout. So we're going to go into the settings, into the checkout settings, and we're going to enable checkout. Cool. When we're operating in life mode, and we have a client-only implementation without a server, we actually specify our domain in life mode to make sure that actually only your domain can redirect off to the checkout page. And now, what we need to do, because we don't have a server site component that can validate the products and the SKUs and actually calculate what we need to charge, we need to tell Stripe about the products that we're selling. So my cool ebook, and we see if I can do Singapore dollars. Let's do 10 Singapore dollars. I'm not going to upload a picture with that internet. Good luck. And now, once that happens, what we do in the background is actually we spin up the product object with an associated SKU. SKU stands for Stock Keeping Unit. And so we can see our SKU here. We have a SKU ID. Can you see that? We have a SKU ID. And then we actually have a button used with checkout, and we're just going to follow along there what we have to do. So you can look at the steps here. We need to load Stripe.js. We need to provide a button. The button has a raw link because it actually redirects off to a Stripe hoster checkout. We then need to initialize the Stripe library with our publishable key. And that is here going to be living on the window object. And that's why we're using hooks. And then lastly, when the button is clicked, we can simply call redirect to checkout with our SKU ID to then kick off the checkout process. And here we can specify success URL where we return back to if the payment was successful or a canceled URL if the customer doesn't actually go through the checkout. Cool. And I hope that is clear. So with Gatsby, because the server side ran it, the way you load Stripe.js is actually, well, at least what I do is use a plugin. So we can here find our Gatsby Stripe plugin. We're not using the Stripe checkout. That's for the old Stripe checkout. What we want here is the Stripe.js library. So what we can do now is we can install that plugin. Now let's quickly kill the server. Install the plugin. And then what we need to do is in our Gatsby config, we need to register our plugin. Gatsby config.js. There we are. So I'm actually going to make it the first plugin. And then yeah, what's more to say here. The internet is slow. We can sort of look at the next steps that we'll need to do is we actually need a button. So let's still running, wow. Let's simply put a button here. Okay, we're going to call this by my ebook. Let's give that a quick save. Are we still? Wow, okay. Still running. There we are. Now, if we fire this up again, just to quickly verify that the loading of the plugin all worked fine. We can go back to our page here. Hmm. Let's see. And if we now check on the window objects and actually let me zoom that in. We can now see that we have the Striper library loaded. We also have the buy my ebook function here. Button, sorry. And we actually now need a function that triggers when the button is clicked. So we're going to just put a redirect to check out function here. We don't really have any input parameters. We're just going to hard coat the skew ID in. So actually empty there. And then what we do for now is just console lock that were clicked. And then the button here we can simply do on click. And then we can specify the redirect to check out reference to our function. That is now compiled. And so, okay. That is all hooked up. The pipes are working. So let's have a look what we need to do next. Yeah, so we need to initialize Stripe. And then make Stripe available in our function later. So let's quickly give that a copy. So as I mentioned, because the Striper library is on the window object, we actually need to do that here in the effect hook. So I can actually we need a variable here. That would be helpful. And you can see now Stripe is not defined. That's because it's on the window. So if we give this a save now, that's all good. Warning, yeah. Okay, Stripe. And now we can, can you see that? If I ask people, I'm just going to say it needs to be bigger. That's a good question. So what we need to do is redirect to checkout. But actually, let me, maybe zoom in here and give you a quick. So what you can see is actually the Stripe redirect to checkout returns a promise because what happens here is we're actually sending off a request to Stripe with the skew ID with our publishable key, the quantity, all of that. And then Stripe goes off and we evaluate does this skew ID actually belong to the account with this publishable key? And then we do the calculation for the total amount and all of that on our end. And then once that was successful, we return a checkout session back to the client which is then used to redirect off to the checkout. And so the reason why this is a promise, if there was an error, for example, we actually return back instead of redirecting off, we return back an error object to you when the promise resolves. So on the result object, you can then extract the error message if there was one. Cool. So we actually want to, because we have a promise here, we can use async await. So that is what we're going to do. And as I mentioned, we can extract the error object from the results. You know, because we're using await here, we need to declare our function asasync. Okay. That looks good. Now we get a warning because the error is actually not used. You know, to get rid of that, we just simply do install, warn, paste, and get rid of that. Cool. Now, is that it? I think that might be it. Let's give that a reload just to be fresh. Actually, you can see a stripe generated warning here. You know, you can test Stripe.js with an unsecure connection, but when you put this into production, you actually want this to be secure. Cool. Now, if we click here, in order to use checkout, you must set an account or business name. Okay. This is actually a pretty helpful error message. So the error message actually links us off into our Stripe account. We can just thaws. I know I'm selling ebooks, just came to mind right now. Now, okay, I think that is the only one. Let's give that a try again. Here we are. We send that request to Stripe. We can assume in here a little. And now, we can use any Stripe test card. I have them here in a sort of auto-expander. Boom. And now, in test mode, where Google wants to save it. And as you can see, I didn't change the result URL. So, yeah, this page doesn't exist. So we would actually have to modify that here. And I guess what we could do is we could go to local host. Was it 8,000? What was it? Yes. 8,000. And then we have page 2. So actually, page 2 on success. Let's go there. And if it's not successful, we just no, sorry, for the cancel URL, we just go back to our index page. Now, let's quickly see if that works. Note what success must start with, oh, yes. Okay. Okay. Now that isn't secure, but let's try that. Cool. And we can actually go back here cancel URL. Cool. So that worked fine. How are we on time? Five minutes. Yeah, so there's kind of two things we could do now. We could actually take this and deploy it to Netlify. If you're interested in that, we could do that. Or alternatively, we could look at using the Stripe API to retrieve all the products we have on the account using GraphQL as Thomas laid out earlier and sort of built a dynamic version that serves up all the products we have in Stripe dynamically. So what's your preference? Looking at the GraphQL. Okay. I'm not going to hook it in, but actually we can so I've written a tutorial here in Gatsby. And so what we've done right now is sort of the easy one button example. And then we can look at the advanced example where we're importing SKUs via a source plugin. Let's see. So as Thomas mentioned a source plugin, what it does is at build time it goes off to the Stripe API. It pulls the data about our products and SKUs from Stripe and then makes it available as static data. I believe it's just JSON that is stored as part of the build process into our page. So in the end it's static but it's sort of dynamic at build time. And actually the cool thing we can do is that Stripe generates webhooks when products are changed for example in the dashboard and we can actually point that webhook at a Netlify build hook to then automatically rebuild our page pulling in that new content. And so we can actually set up this continuous deployment with our static page and I think JSON has actually done a pretty cool example where he's built a clock that literally redeploys I think every second like rebuilds every second and sort of shows you that idea of you probably wouldn't do that in real life but the idea that building this based on some trigger is actually a pretty valid approach. So what we can do then here is we can use the Gatsby source Stripe plugin we say we want to pull in all the SKUs at build time and now in this case actually the SKUs can't be accessed with our publishable key so here what we actually would do is we would generate a restricted key and the restricted key can access, can read our products and SKUs and then we would put that into an environment variable and later on for example with Netlify you could specify it as a build variable in the process. And once we've done that what we can actually do that's the .nf here we can create a component that lists all our SKUs and Thomas mentioned there's sort of different queries so here we use a static query and we can then query all the SKUs for our products what we want to get is all the Stripe SKUs we go down in the etcher so at build time what the plugin actually does is go off to Stripe get the data and then insert the nodes into kind of our unified GraphQL API within Gatsby and then we can specify exactly all the attributes that we want we need the ID, the SKU ID later that's what we need to tell Stripe about the currency, the price and the name of the SKU and then we can simply render a component with the return data that maps all of our SKUs and here just outputting the name of the SKU in a paragraph cool I think we're at time what's interesting there I mean we can look at this so we would then have, and here I'm still in the tutorial using a class component and we can actually look I think I have this deployed so if we look at the advanced example here now we have three products and when I click the buy me button depending on that we go off to buy that product there's also an example that builds a cart you can build that in as well if you want to support multiple products buying but here really what it does is it renders and this component here what you've seen if we go back this component renders I've called it SKU card and then the SKU card again has here our async function redirect to checkout and the SKU in this case is now handed in from the SKU card so when we generate the SKU card we render it with the SKU ID as a parameter on that component and then on the onclick event we actually hand that in and so build this once and kind of hand it off to our marketing or operations team whatever and they can for example then use the Stripe dashboard or some content management system to modify the data and when that happens a web org is fired which kicks off our redeploy pipeline to pull in the new data okay I'm going to stop here but again well actually I have I think I have some most lights sorry well it's really just Stripe is also hiring sorry we're not sponsoring I'm sort of hijacking this here but just want to mention we have a couple offices around the globe as well as remotely here the Singapore team has actually grown quite immensely it's a really sweet team if you're interested here in the second row there's actually a bunch of them sitting there if you want to chat with them or you know come up to me later yeah that's it from me thank you very much for having me and for your attention and please do tweet at me with your questions feedback this is very much a learning experience for me as well or you know shout out your questions now thanks so as I understood you were showing how to deploy Stripe or is it a Gatsby do you guys also use Gatsby at Stripe? do we use Gatsby at Stripe is that the question so we don't as far as I know we don't use it at Stripe so our documentation or things like that that sort of bespoke systems that we've built in terms of content management there is experiments going on sort of using Gatsby for tutorials for example I think that that would be a great use case if yeah I think anything really that isn't changed a lot but it's read a lot so you sort of you write it once and then you know it's basically just a bunch of read operations that's where Gatsby is really good as one example so that could be a potential area but as it stands today we don't use Gatsby in production at Stripe now but many of our users do well yeah that's a good question I mean so actually all of our dashboard is a react nowadays so it is a single page application and the dashboard actually uses GraphQL to access data so if you want to use GraphQL with Stripe you can just join us and then you can use it we're actively looking into that but yeah so that's sort of the stack for the dashboard react application we actually have the design team manages all of our react components so we have kind of an internal component library you know for anything in the dashboard buttons pop-ups all of that is kind of in our own internal component library and then we have the API which is built in Ruby I think custom version of Sinatra and then MongoDB kind of sitting all on AWS as it stands today your customers use like what size? yeah I think it's it's different there was this one good example which I now forgot I think it was some sanitary product so that was more kind of a medium-sized company you know kind of a good good size was working with sort of kind of marketing agency to set that all up but yeah I think in that space well as it stands today it's sort of more kind of the SMB world that is using it yeah I think it's that Harry's yeah the women's razor cool yeah so go talk to that guy he knows his stuff yeah awesome any more questions? on Gatsby not on Stripe cool I guess chatting networking yeah thank you