<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: stets</title>
    <description>The latest articles on Forem by stets (@giraffeman).</description>
    <link>https://forem.com/giraffeman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F102102%2Fe69ed8d2-cf6b-458f-a3e9-5fe12145e3b2.webp</url>
      <title>Forem: stets</title>
      <link>https://forem.com/giraffeman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/giraffeman"/>
    <language>en</language>
    <item>
      <title>Building a Serverless Ecommerce Store</title>
      <dc:creator>stets</dc:creator>
      <pubDate>Thu, 09 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/giraffeman/building-a-serverless-ecommerce-store-48hf</link>
      <guid>https://forem.com/giraffeman/building-a-serverless-ecommerce-store-48hf</guid>
      <description>&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;, it's true! &lt;/p&gt;

&lt;p&gt;You can build a storefront in an hour without spinning up a server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WTF, how?! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-- you, probably&lt;/p&gt;

&lt;p&gt;Gone are the days of paying expensive devs or fiddling with strange Wordpress extensions. &lt;/p&gt;

&lt;p&gt;I run a Facebook group, &lt;a href="http://bit.ly/ITSupportGroup/" rel="noopener noreferrer"&gt;This is an IT Support Group&lt;/a&gt;, and I wanted to sell a few stickers of the group's logo. I didn't want to configure another server, pay for a Shopify subscription, or anything else that required a ton of work. &lt;/p&gt;

&lt;p&gt;I'm lazy like that. &lt;/p&gt;

&lt;p&gt;I'll show you exactly how to build a storefront that can accept payments and manage inventory. &lt;/p&gt;

&lt;p&gt;If you want to skip ahead to the finished product, it's here: &lt;a href="http://bit.ly/ITSupportStickers" rel="noopener noreferrer"&gt;http://bit.ly/ITSupportStickers&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the front-end
&lt;/h2&gt;

&lt;p&gt;I'm a big fan of &lt;a href="http://bit.ly/carrd_stets" rel="noopener noreferrer"&gt;carrd.co&lt;/a&gt; -- Carrd allows you to build simple, one-page websites with a visual editor. It's great for testing ideas quickly and getting content out quickly. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://bit.ly/carrd_stets" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fph-files.imgix.net%2Fcd9baf19-2d79-4369-9932-191a9a4cb29b%3Fauto%3Dformat" width="936" height="610"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I started by choosing a starter landing page in Carrd.co. I deleted any elements that weren't helpful and added a couple of pictures of my sticker and a description with the text and image elements. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy67a3a4t1gz4luda3axb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy67a3a4t1gz4luda3axb.png" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  WTF is a Snipcart?
&lt;/h1&gt;

&lt;p&gt;Next, we'll sign up for &lt;a href="https://snipcart.com/" rel="noopener noreferrer"&gt;Snipcart&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Snipcart is an ecommerce solution that works in a unique way -- all of the config and inventory is held in html attributes on the store page! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"What if some joker just changes the html and gets my stuff for free, that's not cool and serverless sucks"&lt;/em&gt; -you again, maybe&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Snipcart takes security seriously. Before orders are processed, their servers crawl your store's front page and verify the pricing and details are all correct.&lt;/p&gt;

&lt;p&gt;Best of all, Snipcart will let us set up an ecommerce store with zero(ish) code. Okay, some code, but zero server configuration. Nice. &lt;/p&gt;

&lt;h2&gt;
  
  
  Snipcart Config
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Add the default stylesheet
&lt;/h3&gt;

&lt;p&gt;On your Carrd page, add an &lt;code&gt;&amp;lt;/&amp;gt; Embed&lt;/code&gt; element. Be sure to set the type as Code, Style to Hidden and paste the stylesheet element under the code section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.snipcart.com/themes/v3.0.5/default/snipcart.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding Snipcart
&lt;/h3&gt;

&lt;p&gt;Add another &lt;code&gt;&amp;lt;/&amp;gt; Embed&lt;/code&gt; element to Carrd with the same settings as above, but this time, grab your API key code from Snipcart under &lt;code&gt;Dashboard &amp;gt; Account &amp;gt; API keys&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.snipcart.com/themes/v3.0.4/default/snipcart.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.snipcart.com/themes/v3.0.4/default/snipcart.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"snipcart"&lt;/span&gt; &lt;span class="na"&gt;data-api-key=&lt;/span&gt;&lt;span class="s"&gt;"ZjZlZDA4ZWItMzI4OC00MDcxLWFjY2UtODlmZTZhZmMwNjc1NjM3MTEyNzIxMDk4Nzg4NTgy"&lt;/span&gt; &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxovbc7zagrg5vtwmczj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxovbc7zagrg5vtwmczj.png" width="630" height="1532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These API keys are special and don't need to be protected like you normally might do with super-secret API keys. &lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Inventory
&lt;/h3&gt;

&lt;p&gt;Let's add our first product and a way to checkout!&lt;/p&gt;

&lt;p&gt;Attributes are where we'll set our item's price, description and title!&lt;/p&gt;

&lt;p&gt;I've set my attributes as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;type=button
data-item-name=Two IT Support Stickers
data-item-url=https://shop.thisisanitsupportgroup.com
data-item-price=5.00
data-item-description=Two 2" by 2" This is an IT Support Group stickers. Each Quantity is 2 stickers. 
data-item-id=it-support-logo-sticker
data-item-url=https://shop.thisisanitsupportgroup.com/
data-item-custom1-options=US Shipping|Non-US Shipping[+2.00]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Name, id and price are mandatory fields. The others just add a little more detail to the item, like a description and a picture for the cart. &lt;/p&gt;

&lt;p&gt;Here's more details from Snipcart's &lt;a href="https://docs.snipcart.com/v3/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  Add an Add-To-Cart Button
&lt;/h3&gt;

&lt;p&gt;Add a &lt;code&gt;buttons&lt;/code&gt; element to your Carrd page and open the settings gear. Name your button &lt;code&gt;Add to Cart&lt;/code&gt; or whatever you want. &lt;/p&gt;

&lt;p&gt;Hit the gear icon and under classes and paste: &lt;code&gt;snipcart-add-item&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Cool. that works well, but if users go back to the item page they'll have no option to check out, just add another item. &lt;/p&gt;

&lt;h3&gt;
  
  
  Add a Check-out Button
&lt;/h3&gt;

&lt;p&gt;Add another button element to Carrd, named &lt;code&gt;Checkout&lt;/code&gt;, &lt;code&gt;My Cart&lt;/code&gt; or similar.&lt;/p&gt;

&lt;p&gt;This time, set the &lt;code&gt;Classes&lt;/code&gt; section to &lt;code&gt;snipcart-checkout&lt;/code&gt;. No Attributes needed!&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Our Shop
&lt;/h3&gt;

&lt;p&gt;It's time to test our checkout flow! Make sure you're on Test mode with the toggle in your Snipcart dashboard.&lt;/p&gt;

&lt;p&gt;Go to your landing page, add the item to your cart. &lt;br&gt;
You can checkout with the test card number 4242 4242 4242 4242 CVC of 123 and a date in future. &lt;/p&gt;

&lt;p&gt;If all goes well, you'll see the fake transaction in your dashboard. &lt;/p&gt;
&lt;h3&gt;
  
  
  Add a Payment Gateway
&lt;/h3&gt;

&lt;p&gt;You'll have to add a payment gateway to actually receive payments. I use Stripe. Set up an account with Stripe and connect it to Snipcart in your dashboard. &lt;/p&gt;
&lt;h2&gt;
  
  
  Go live!
&lt;/h2&gt;

&lt;p&gt;The Snipcart code we added earlier for our API keys will need to be replaced with our Live API keys. Get those from your Snipcart dashboard, replace the code, turn on the switch in Snipcart to make the shop live!&lt;/p&gt;

&lt;p&gt;My shop, The IT Support Group shop, is live &lt;a href="http://bit.ly/ITSupportStickers" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to the future. 😎&lt;/p&gt;
&lt;h2&gt;
  
  
  Bonus / Adding Code
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I didn't think there'd be any code, wtf is this.&lt;/em&gt; - you, again&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We don't really need any code, but code can be fun.&lt;/p&gt;

&lt;p&gt;Snipcart supports webhooks for any event or transaction that occurs. When a sale is made, Snipcart will send event data to your configured web hook. &lt;/p&gt;

&lt;p&gt;I really enjoy using Slack for real-time notifications. Let's set up a Slack alert every time we make a sale. &lt;/p&gt;

&lt;p&gt;Let's spin up an endpoint with &lt;a href="https://chalice.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Chalice&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Chalice is an AWS fork of the python framework, Flask.&lt;/p&gt;

&lt;p&gt;Flask is great for writing simple API's or serving websites. &lt;/p&gt;

&lt;p&gt;chalice is seriously cool, we can spin up an API endpoint in minutes for totaly FREE via usage of the Lambda service and API gateway. &lt;/p&gt;

&lt;p&gt;You'll need an AWS account for this part, but it'll be totally free. &lt;/p&gt;

&lt;p&gt;I'm assuming you have an AWS account. If not, they are free and have a generous free-tier. &lt;/p&gt;

&lt;p&gt;We won't spend any money here. I'm cheap. &lt;/p&gt;

&lt;p&gt;First, set up a &lt;a href="https://slack.com/help/articles/115005265063-Incoming-WebHooks-for-Slack" rel="noopener noreferrer"&gt;Slack webhook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make a new virtualenv to contain our packages, activate it, install chalice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;virtualenv
&lt;span class="nv"&gt;$ &lt;/span&gt;virtualenv ~/.virtualenvs/chalice-demo
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.virtualenvs/chalice-demo/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html" rel="noopener noreferrer"&gt;AWS Access keys&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.aws
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.aws/config
&lt;span class="o"&gt;[&lt;/span&gt;default]
&lt;span class="nv"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_ACCESS_KEY_HERE
&lt;span class="nv"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_SECRET_ACCESS_KEY
&lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_REGION &lt;span class="o"&gt;(&lt;/span&gt;such as us-west-2, us-west-1, etc&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a new Chalice project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;chalice new-project snipcart_webhook
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;snipcart_webhook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file called &lt;code&gt;requirements.txt&lt;/code&gt; and add &lt;code&gt;requests&lt;/code&gt; to it. We'll use the &lt;code&gt;requests&lt;/code&gt; library to call Slack and POST our message details. &lt;/p&gt;

&lt;p&gt;Next, open your app.py and paste the following in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;chalice&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chalice&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Chalice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;helloworld&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# paste your own SlackWebhook here 👇
&lt;/span&gt;&lt;span class="n"&gt;slackWebhook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://hooks.slack.com/services/x/x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slackAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#snipcart&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;slack_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Snipcart&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;channel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;slackWebhook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;slack_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Request to slack returned an error %s, the response is:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/snipcart&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;snipcart&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_request&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json_body&lt;/span&gt;
    &lt;span class="n"&gt;fullName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;shippingAddress&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fullName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;shippingAddress&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;New sticker order for {} in {}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;eventName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;order.completed&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;slackAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Thanks, Snipcart!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/hello&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello! 👋&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we setup our Slack webhook, create a function (&lt;code&gt;slackAlert&lt;/code&gt;) for sending Slack messages and then create a "route" at &lt;code&gt;/route&lt;/code&gt; that receives our webhook from Snipcart, parses out details and passes it back to the &lt;code&gt;slackAlert&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;We'll also add a simple route for testing at &lt;code&gt;/hello&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finally, push your code to AWS with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$chalice&lt;/span&gt; deploy
...
Initiating first &lt;span class="nb"&gt;time &lt;/span&gt;deployment...
https://qxea58oupc.execute-api.us-west-2.amazonaws.com/api/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chalice will return an API endpoint url. Go ahead and test the test endpoint we made and checkout the reply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://mbazi1dxs8.execute-api.us-east-2.amazonaws.com/api/hello
Hello! 👋%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have test mode turned on in your store, you can make another test transaction to see our results. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhrueeerbwjxl1dr6lnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhrueeerbwjxl1dr6lnx.png" width="744" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BOOM 💥&lt;/p&gt;

&lt;p&gt;The transaction was made, an endpoint was called, another webhook was called to Slack. Webhooks within webhooks. Webhookception. &lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;I hope this was a helpful introduction to Carrd.Co and Snipcart. &lt;br&gt;
No-code tools are gaining a lot of traction lately and I think that's a great thing. &lt;/p&gt;

&lt;p&gt;The more people that have the opportunity to access technology and entrepreneurship, the better off society is. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://bit.ly/ITSupportGroup/" rel="noopener noreferrer"&gt;This is an IT Support Group&lt;/a&gt; is a growing community for IT professionals to gather and discuss their careers, technical issues and post memes. It's a lot of fun. &lt;/p&gt;

&lt;p&gt;The IT Support Group shop, is live &lt;a href="http://bit.ly/ITSupportStickers" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comments, Questions? I'm at &lt;a href="mailto:stetson@heliositservices.com"&gt;stetson@heliositservices.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>html</category>
      <category>ecommerce</category>
      <category>python</category>
    </item>
  </channel>
</rss>
