<<

STATE OF THE JAMSTACK NATION STATE OF THE JAMSTACK NATION

Ethernet

JAMstack

• JavaScript • API • Markup DNS BROWSER CDN

DATABASE LOAD BALANCER STORAGE

CACHING SERVICE WEB APP SERVERS

JOB QUEUE

SERVICES JOB SERVERS DNS BROWSER CDN DNS BROWSER CDN

SERVICES JAMstack

A modern architecture — Create fast and secure sites and dynamic apps with JavaScript, , and prerendered Markup,

… served without web servers.

SARAH DRASNER @SARAH_EDO DNS BROWSER CDN

SERVICES

• Nuxt (Vue.js) • Next (React.js) • Gatsby (React.js) • Eleventy (Vanilla JS) • Jekyll (Ruby) • Hugo (Go) • More and more… • Contentful • Forestry • Sanity • CMS • CraftCMS • Decoupled Wordpress • Decoupled Drupal • More and more… Netlify Function

Stripe

Vuex Store

Layouts

Pages Components Vue Single File Components

@sarah_edo Templates in the pages directory

Product

@sarah_edo

Deployed!

@sarah_edo Netlify Function

Stripe

Vuex Store

Layouts

Pages Components functions/index.js exports.handler = async (event, context) =" { return { statusCode: 200, body: JSON.stringify({ message: "Hi there Tacos", event }) } }

netlify.toml

[build] functions = "functions"

yarn add dotenv

require("dotenv").config() const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY), headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type" } exports.handler = async (event, context) =" { if (!event.body || event.httpMethod !$$ "POST") { return { statusCode: 400, headers, body: JSON.stringify({ status: "invalid http method" }) } }

const data = JSON.parse(event.body)

if (!data.stripeToken || !data.stripeAmt || !data.stripeIdempotency) { console.error("Required information is missing.")

return { statusCode: 400, headers, body: JSON.stringify({ status: "missing information" }) } } // stripe payment processing begins here try { await stripe.customers .create({ email: data.stripeEmail, source: data.stripeToken }) .then(customer =" { console.log( `starting the charges, amt: ${data.stripeAmt}, email: ${data.stripeEmail}` ) return stripe.charges .create( { currency: "usd", amount: data.stripeAmt, receipt_email: data.stripeEmail, customer: customer.id, description: "Sample Charge" }, { idempotency_key: data.stripeIdempotency } ) .then(result =" { console.log(`Charge created: ${result}`) }) }) Netlify Function

Stripe

Vuex Store AppCard.vue Layouts

Pages Components yarn add vue-stripe-elements-plus

Please enter your payment details:

AppCard.vue pay() { createToken().then(data =" { const stripeData = { data, stripeEmail: this.stripeEmail }; this.$store.dispatch("postStripeFunction", stripeData); }); }, Vuex store export const actions = { async postStripeFunction({ getters, commit }, payload) { commit("updateCartUI", "loading")

try { await axios .post( "https://ecommerce-netlify.netlify.com/.netlify/functions/index", { stripeEmail: payload.stripeEmail, stripeAmt: Math.floor(getters.cartTotal * 100), //it expects the price in cents stripeToken: "tok_visa", //testing token, later we would use payload.data.token stripeIdempotency: uuidv1() //we use this library to create a unique id }, { headers: { "Content-Type": "application/json" } } ) .then(res =" { if (res.status =&& 200) { commit("updateCartUI", "success") setTimeout(() =" commit("clearCart"), 3000) … Success!

DEMO github.com/sdras/ecommerce-netlify

REPO ecommerce-netlify.netlify.com

@sarah_edo • Centered around a developer friendly, Git-based workflow

• Designed modularly, consuming other services via APIs

• Prebuilt and optimized before being served

• Globally distributed and resilient to heavy traffic • Better performance

• Reduced operations cost

• Increased security

• Cheaper, easier scaling

• 65% LESS EXPENSIVE • AVERAGE CONNECTION TIME +57% 6x faster

NETLIFY.COM/CASE-STUDIES/SMASHING/

What are you going to build? Thank you! @saah_edo