<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ payments - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ payments - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 05:06:39 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/payments/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Integrate PayPal into Your HTML, CSS, and JS Product Pages ]]>
                </title>
                <description>
                    <![CDATA[ By Shane Duggan Imagine if you had an amazing product landing page, with customers lined up to make a purchase. But your manual JavaScript payment processing with server-side scripts, Authorize.net, or 2Checkout failed you. Frustrated by being unable... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/integrate-paypal-into-html-css-js-product-pages/</link>
                <guid isPermaLink="false">66d460f73dce891ac3a9681c</guid>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 25 Jan 2023 17:35:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/PayPalHTMLCSSJSCoverImage.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shane Duggan</p>
<p>Imagine if you had an amazing product landing page, with customers lined up to make a purchase. But your manual JavaScript payment processing with server-side scripts, Authorize.net, or 2Checkout failed you.</p>
<p>Frustrated by being unable to make the purchase, your customer leaves to go to your competitors.</p>
<p>I imagine that would be a terrible feeling. Surely, there is a better way to do this with modern, widely accepted payment gateways. By the end of this tutorial, I will make sure that you won’t find yourself in that situation.</p>
<p>When it comes to accepting payments online, PayPal is one of the most widely-used and trusted options available. There are many new software startups appearing every day that use PayPal to handle their transactions and clients’ payments. </p>
<p>Integrating PayPal into your own HTML/CSS/JS product pages can greatly improve the user experience and streamline the checkout process for your customers.</p>
<p>PayPal also has great <a target="_blank" href="https://developer.paypal.com/">developer documentation</a> that makes this integration all the more user-friendly.</p>
<p>In this tutorial, we will take a look at the steps involved in integrating PayPal into your product pages. You'll learn how to set up your PayPal for integration and implement the code into your HTML/CSS/JS pages. Then we'll look at how you can use your newfound knowledge going forward.</p>
<h2 id="heading-how-can-you-use-this-tutorial">How Can You Use This Tutorial?</h2>
<p>Now, let me use an example to give you a better idea of how you can use this tutorial. (Fictitious story alert)</p>
<p>Recently, I decided to start a new online startup. After deliberating through countless ideas for software startups, I decided to start an online eBook store. </p>
<p>As my very first product, I published an eBook that covered 10 years of my life experience in programming. Excitedly, I created a product landing page with all my knowledge of HTML, CSS, and JavaScript.</p>
<p>Introducing MyProgrammingBook, a glorious $0.99 programming guide that contains everything you need to know, including how to get all of your searching algorithms to O(1) (not really…). Here is what it looks like:</p>
<p><img src="https://lh6.googleusercontent.com/615Geb0nmIE6CxpOqjvItkMBBDTPv7cPLk0MjkBRJYks2EBHJWosCxEubYKbMnOpz_IAdNBRfKx7f9V1FeUPdqRGy4y_Vc8eu63XgWDTucW4KvW7Xn5KxH9nUwjhmMBEK0ZTazkGU1s31toG-Sgg2oaeITZM_0eYavT37l-6IitZAOP2IcW0q4gLV4dtTw" alt="Image" width="1246" height="1286" loading="lazy">
<em>My first eBook's product landing page</em></p>
<p>I created this product landing page within an hour using some simple vanilla HTML and CSS. Here are the files I used:</p>
<h3 id="heading-indexhtml">index.html</h3>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>MyProgrammingBook<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-image-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"myprogrammingbook.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"MyProgrammingBook"</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-info-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>MyProgrammingBook<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"price"</span>&gt;</span>$0.99<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-description"</span>&gt;</span>
          Want to make all of your code run at O(1) speed? Then let me introduce MyProgrammingBook! Written by the world's leading expert on algorithmic optimization (me), this book will teach you everything you need to know to make your code lightning fast. Plus, it comes with a free unicorn* to help you implement all the techniques you learn. Don't miss out on this once-in-a-lifetime opportunity!
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>*Terms and Conditions Apply<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"address"</span>&gt;</span>Address:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"address"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"address"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-info"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"card-number"</span>&gt;</span>Card Number:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"card-number"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"card-number"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-info"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"expiry-date"</span>&gt;</span>Expiry Date:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"expiry-date"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"expiry-date"</span> <span class="hljs-attr">required</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"cvv"</span>&gt;</span>CVV:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"cvv"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"cvv"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Buy Now"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"submitForm()"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-stylecss">style.css</h3>
<pre><code class="lang-css">* {
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f5f5f5</span>;
  <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
}

<span class="hljs-selector-class">.product-container</span> {
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">600px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">4px</span> <span class="hljs-number">8px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.2</span>);
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-wrap</span>: wrap;
}

<span class="hljs-selector-class">.product-image-container</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">30%</span>;
}

<span class="hljs-selector-class">.product-info-container</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">70%</span>;
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">20px</span>;
}

<span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: auto;
}

<span class="hljs-selector-tag">form</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-wrap</span>: wrap;
}

<span class="hljs-selector-tag">label</span>, <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"text"</span>]</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">12px</span>;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">box-sizing</span>: border-box;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid <span class="hljs-number">#ccc</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
}

<span class="hljs-selector-tag">label</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">30%</span>;
  <span class="hljs-attribute">padding-right</span>: <span class="hljs-number">10px</span>;
}
<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"text"</span>]</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">70%</span>;
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"button"</span>]</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ff5722</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">12px</span> <span class="hljs-number">24px</span>;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">cursor</span>: pointer;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"text"</span>]</span><span class="hljs-selector-attr">[name=<span class="hljs-string">"card-number"</span>]</span>, <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"text"</span>]</span><span class="hljs-selector-attr">[name=<span class="hljs-string">"expiry-date"</span>]</span>, <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"text"</span>]</span><span class="hljs-selector-attr">[name=<span class="hljs-string">"cvv"</span>]</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">30%</span>;
}


<span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-class">.price</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#ff5722</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.5em</span>;
  <span class="hljs-attribute">font-weight</span>: bold;
}
</code></pre>
<h3 id="heading-scriptjs">script.js</h3>
<p>With my outdated knowledge, I accept payment through a form to collect their payment details before manually processing it with a payment provider. A sample JavaScript file might look like this:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Get references to the form elements</span>
<span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"payment-form"</span>);
<span class="hljs-keyword">const</span> cardNumber = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"card-number"</span>);
<span class="hljs-keyword">const</span> expiryDate = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"expiry-date"</span>);
<span class="hljs-keyword">const</span> cvv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"cvv"</span>);
<span class="hljs-keyword">const</span> submitButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"submit-button"</span>);

<span class="hljs-comment">// Handle form submission</span>
form.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.preventDefault();

  <span class="hljs-comment">// Disable the submit button to prevent multiple submissions</span>
  submitButton.disabled = <span class="hljs-literal">true</span>;

  <span class="hljs-comment">// Create an object to hold the form data</span>
  <span class="hljs-keyword">const</span> formData = {
    <span class="hljs-attr">cardNumber</span>: cardNumber.value,
    <span class="hljs-attr">expiryDate</span>: expiryDate.value,
    <span class="hljs-attr">cvv</span>: cvv.value,
  };

  <span class="hljs-comment">// Perform client-side validation on the form data</span>
  <span class="hljs-keyword">if</span> (!validateFormData(formData)) {
    <span class="hljs-comment">// If the data is invalid, re-enable the submit button and return</span>
    submitButton.disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-comment">// Send the form data to the server</span>
  <span class="hljs-comment">// The following is just an example and should not be used in a real-world scenario</span>
  <span class="hljs-comment">// as it lacks security measures and proper payment gateway integration</span>
  fetch(<span class="hljs-string">"/charge"</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(formData),
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    },
  })
    .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> response.json())
    .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
      <span class="hljs-comment">// Handle the server response</span>
      <span class="hljs-keyword">if</span> (data.success) {
        <span class="hljs-comment">// Payment was successful</span>
        alert(<span class="hljs-string">"Payment successful!"</span>);
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// Payment failed</span>
        alert(<span class="hljs-string">"Payment failed. Please try again."</span>);
        submitButton.disabled = <span class="hljs-literal">false</span>;
      }
    })
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.error(error);
      alert(<span class="hljs-string">"An error occurred. Please try again."</span>);
      submitButton.disabled = <span class="hljs-literal">false</span>;
    });
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateFormData</span>(<span class="hljs-params">data</span>) </span>{
  <span class="hljs-comment">// Example validation checks</span>
  <span class="hljs-keyword">if</span> (!data.cardNumber || data.cardNumber.length !== <span class="hljs-number">16</span>) {
    alert(<span class="hljs-string">"Please enter a valid card number."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">if</span> (!data.expiryDate || data.expiryDate.length !== <span class="hljs-number">5</span>) {
    alert(<span class="hljs-string">"Please enter a valid expiry date in the format MM/YY."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">if</span> (!data.cvv || data.cvv.length !== <span class="hljs-number">3</span>) {
    alert(<span class="hljs-string">"Please enter a valid CVV."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>However, this old-school way of taking a payment creates several problems:</p>
<ul>
<li><strong>Security:</strong> Without proper security measures, sensitive information such as credit card numbers and personal information can be vulnerable to hacking and fraud.</li>
<li><strong>Compliance:</strong> A business may face penalties and legal issues without compliance with regulations such as PCI-DSS.</li>
<li><strong>Scalability:</strong> Processing payments using only HTML, CSS, and JavaScript may not be able to handle a high volume of transactions, especially during peak periods.</li>
<li><strong>Maintenance:</strong> Maintaining and updating a custom payment system can be time-consuming and costly.</li>
<li><strong>Limited features:</strong> Collecting payments using only HTML, CSS, and JavaScript may lack features such as recurring payments, subscriptions, refunds, and fraud detection.</li>
<li><strong>Lack of integration with other tools:</strong> Vanilla HTML, CSS, and JavaScript do not have built-in integrations with other tools like accounting software, <a target="_blank" href="https://www.demandsage.com/inventory-management-software/">inventory management software</a>, and shipping providers.</li>
</ul>
<p>So a much simpler way, not to mention more seamless and functional, would be to abstract away all of the payment handlings to a third party. Especially so as customers will more often than not be more familiar with using these third-party payment gateways already.</p>
<p>Even if you are not selling a product, this can be great for websites that are selling some kind of freelance service or consultation, a trend we have been seeing in recent times. Allowing the customer to checkout with a familiar <a target="_blank" href="https://www.yaguara.co/best-payment-gateways/">third-party payment gateway</a> directly from your website will add greatly to the user experience of your service.</p>
<p>It’s a win-win for you and the customer. You program less and they receive more. So let’s dive in to find out how we can implement this into your own websites.</p>
<h2 id="heading-how-to-integrate-paypal-into-your-product-pages">How to Integrate PayPal into Your Product Pages</h2>
<p>Now that we know what we want to achieve, let’s get into action. I have broken down the process into 6 easy-to-follow steps. They are:</p>
<ol>
<li>Access PayPal’s developer tools to get your APIs.</li>
<li>Set up a PayPal sandbox environment.</li>
<li>Create and customize your PayPal button.</li>
<li>Integrate your button into your current files.</li>
<li>Test the integration using the PayPal sandbox environment.</li>
<li>Go live and start accepting real payments.</li>
</ol>
<p>We’ve got a lot to cover, so let’s dive right in and get started!</p>
<h2 id="heading-how-to-access-paypals-developer-tools-to-get-your-apis">How to Access PayPal’s Developer Tools to Get Your APIs</h2>
<p>Step 1 for integrating PayPal into your HTML/CSS/JS product pages is creating a PayPal account. This step is crucial as it will give you access to PayPal's developer tools and APIs, which are necessary for integrating PayPal into your product pages. </p>
<p>If you already have one, just hop straight to the PayPal developer tools.</p>
<p>To create a PayPal account, you'll need to visit the PayPal website and follow the on-screen instructions to sign up. You'll be asked to provide some personal and financial information, such as your name, email address, and credit card details.</p>
<p>Once you've completed the sign-up process, you'll be able to log in to your PayPal account and access the developer tools and APIs needed for integration. It's important to use a valid email address as you will receive important information and updates from PayPal.</p>
<p>Then, you can find the developer tools at the top right of your PayPal dashboard.</p>
<p><img src="https://lh4.googleusercontent.com/a3-V_L-K2tqnzNWOTwGbQvgr0omXa14r-qnA6sd1B8AZqNhi7FxsQGHsH8z_0cXWUhOqmXIwPVtficgBrdci5nWGHOSlfh5L5ZHNHrwpuHNmM6vq7LQQCSA9sU9FzT5cxAF9tlDUZOmsxQmSWFlAqzetprRw-_1o7OyoL8AFePScGgMopJtZJTLRkWf-Gg" alt="Image" width="1600" height="264" loading="lazy">
<em>Developer tab at the top right of your PayPal dashboard</em></p>
<h2 id="heading-how-to-set-up-a-paypal-sandbox-environment">How to Set Up a PayPal Sandbox Environment</h2>
<p>The next step is to create a PayPal sandbox environment.</p>
<p>What is that, you might ask?</p>
<p>Well, a sandbox environment is a testing environment that mimics the live PayPal environment. It allows you to test your integration before going live, which is a great feature from PayPal to ensure that everything is working as expected.</p>
<p>To set up a PayPal sandbox environment, you'll need to log in to your PayPal account and navigate to the developer dashboard. From there, you can create a new sandbox account by following <a target="_blank" href="https://developer.paypal.com/api/rest/sandbox/">the on-screen instructions</a>. </p>
<p>Once the sandbox account is created, you'll be able to use it to test your integration by making test payments. You can use the sandbox account in parallel with your live account.</p>
<p><img src="https://lh4.googleusercontent.com/lXbcuiZbxEb2mawwHyQLqsK8sUDarUl9jMOJeUBbm9jTfsTTWxsS0GZKiFVNl5SG_wNRdbHgBU4fNmo9HpR8Yvv6j4-GvPtRRE-UbbxyuRtBrz3RuYcUQwX1arXRXDHsIQfxN1yQN2QTyTQcdKLfBgorGPU1ilLIZKcD0XfesZeG4e-HPRoflzSGbf1wLg" alt="Image" width="1600" height="206" loading="lazy">
<em>Check your URL to contain "sandbox"</em></p>
<p>It's important to test your integration thoroughly and ensure that everything is working as expected before going live.</p>
<h2 id="heading-how-to-create-and-customize-your-paypal-button">How to Create and Customize Your PayPal Button</h2>
<p>This step involves creating the button that will be placed on your product page, allowing customers to initiate the payment process.</p>
<p>One way to create a PayPal button is by using the PayPal Button Creation Tool, which provides a user-friendly interface for customizing your button. You can choose from 3 different checkout styles, available on <a target="_blank" href="https://developer.paypal.com/docs/checkout/#home">PayPal’s website</a>.</p>
<p><img src="https://lh6.googleusercontent.com/SdtWGXEvNhBbgl_kMWh4EROOAIyRCjkO6z1yTYpr6pwkZnN73H0zKUBgvDco_5yS9pZyjTB0IyuaXJnR0tjULEKmjMnDg_BwpPX0r7mX-Ifh6sqhWEhlUVkseIrvPQw_By2ZncKvpIvPXHs5iqmJbdIevN00K2wmFUZeB9P1FnKWxmOBe2Hp54sfWLV5Kg" alt="Image" width="1600" height="1057" loading="lazy">
<em>Types of smart buttons offered by PayPal</em></p>
<p>Navigate to business tools &gt; PayPal Buttons &gt; Get Started &gt; Smart Buttons. This will bring you to the button customization interface. Adjust the stylings to your liking, then simply click on “Copy Code”.</p>
<p><img src="https://lh5.googleusercontent.com/yVxrqZd7V-NPKd68xnqnKFua8QmQP3Z5bx0NDpThLS5YfQ0KuN6vAUt4G7PqAfgEZ2xzJRCHBWtrlqX-9mZOwnH54hYUKPJ6oqLQEWFR_-NIGNQ8ivczYOb-MRG7NNeh4Sge9_HiYbGOgKKB1PVVUv2GhDC2qjTOI9qGwWuOj6ZGilA_w3PR7ZXYV60Xgg" alt="Image" width="1600" height="964" loading="lazy">
<em>PayPal's smart button customization interface</em></p>
<p>Here is an example of the code for a PayPal Smart Button. Then, we must update our previous files to remove the form input and insert the following code instead. We will be covering that in the next step. Before that, this is the snippet of what you get from <a target="_blank" href="https://www.paypal.com/buttons/">PayPal’s Smart Buttons</a>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"smart-button-container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"text-align: center;"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"paypal-button-container"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.paypal.com/sdk/js?client-id=sb&amp;enable-funding=venmo&amp;currency=USD"</span> <span class="hljs-attr">data-sdk-integration-source</span>=<span class="hljs-string">"button-factory"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initPayPalButton</span>(<span class="hljs-params"></span>) </span>{
        paypal.Buttons({
            <span class="hljs-attr">style</span>: {
                <span class="hljs-attr">shape</span>: <span class="hljs-string">'rect'</span>,
                <span class="hljs-attr">color</span>: <span class="hljs-string">'gold'</span>,
                <span class="hljs-attr">layout</span>: <span class="hljs-string">'vertical'</span>,
                <span class="hljs-attr">label</span>: <span class="hljs-string">'paypal'</span>,
            },

            <span class="hljs-attr">createOrder</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data, actions</span>) </span>{
                <span class="hljs-keyword">return</span> actions.order.create({
                    <span class="hljs-attr">purchase_units</span>: [{<span class="hljs-string">"amount"</span>:{<span class="hljs-string">"currency_code"</span>: <span class="hljs-string">"USD"</span>, <span class="hljs-string">"value"</span>: <span class="hljs-number">0.99</span>}}]
                });
            },

            <span class="hljs-attr">onApprove</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data, actions</span>) </span>{
                <span class="hljs-keyword">return</span> actions.order.capture().then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">orderData</span>) </span>{

                    <span class="hljs-comment">// Full available details</span>
                    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Capture result'</span>, orderData, <span class="hljs-built_in">JSON</span>.stringify(orderData, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>));

                    <span class="hljs-comment">// Show a success message within this page, for example:</span>
                    <span class="hljs-keyword">const</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'paypal-button-container'</span>);
                    element.innerHTML = <span class="hljs-string">''</span>;
                    element.innerHTML = <span class="hljs-string">'&lt;h3&gt;Thank you for your payment!&lt;/h3&gt;'</span>;

                    <span class="hljs-comment">// Or go to another URL:  actions.redirect('thank_you.html');</span>

                });
            },

            <span class="hljs-attr">onError</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
                <span class="hljs-built_in">console</span>.log(err);
            }
        }).render(<span class="hljs-string">'#paypal-button-container'</span>);
    }
    initPayPalButton();
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Do note that you will have different fields for your own needs, so do customize your own button and reference the code for that, not from my tutorial. </p>
<p>There are also different button styles to choose from, so feel free to play around to find something that suits your style.</p>
<p>Now that we’re ready, let’s integrate this code into our current files.</p>
<h2 id="heading-how-to-integrate-your-button-into-your-current-files">How to Integrate Your Button into Your Current Files</h2>
<p>With our button code fresh out of the box, let’s integrate this into our current files. Very simply, we just need to replace the HTML fields that we are not going to use, namely the form and replace it with the button we created.</p>
<p>To remain consistent with the programming style we used for the example, I am going to abstract away the JavaScript to the script.js file. That should give us the following files:</p>
<h3 id="heading-indexhtml-1">index.html</h3>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>MyProgrammingBook<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-image-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"myprogrammingbook.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"MyProgrammingBook"</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-info-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>MyProgrammingBook<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"price"</span>&gt;</span>$0.99<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-description"</span>&gt;</span>
          Want to make all of your code run at O(1) speed? Then let me introduce MyProgrammingBook! Written by the world's leading expert on algorithmic optimization (me), this book will teach you everything you need to know to make your code lightning fast. Plus, it comes with a free unicorn* to help you implement all the techniques you learn. Don't miss out on this once-in-a-lifetime opportunity!
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>*Terms and Conditions Apply<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"smart-button-container"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"text-align: center;"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"paypal-button-container"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.paypal.com/sdk/js?client-id=sb&amp;enable-funding=venmo&amp;currency=USD"</span> <span class="hljs-attr">data-sdk-integration-source</span>=<span class="hljs-string">"button-factory"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-stylecss-1">style.css</h3>
<pre><code class="lang-css">* {
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f5f5f5</span>;
  <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
}

<span class="hljs-selector-class">.product-container</span> {
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">600px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">500px</span>;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">4px</span> <span class="hljs-number">8px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.2</span>);
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-wrap</span>: wrap;
}

<span class="hljs-selector-class">.product-image-container</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">30%</span>;
}

<span class="hljs-selector-class">.product-info-container</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">70%</span>;
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-wrap</span>: wrap;
  <span class="hljs-attribute">align-items</span>: center;
}

<span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: auto;
}

<span class="hljs-selector-class">.product-info-container</span> <span class="hljs-selector-tag">form</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">align-self</span>: flex-end;
}

<span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-class">.price</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#ff5722</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.5em</span>;
  <span class="hljs-attribute">font-weight</span>: bold;
}
</code></pre>
<h3 id="heading-scriptjs-1">script.js</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initPayPalButton</span>(<span class="hljs-params"></span>) </span>{
  paypal.Buttons({
    <span class="hljs-attr">style</span>: {
      <span class="hljs-attr">shape</span>: <span class="hljs-string">'rect'</span>,
      <span class="hljs-attr">color</span>: <span class="hljs-string">'gold'</span>,
      <span class="hljs-attr">layout</span>: <span class="hljs-string">'vertical'</span>,
      <span class="hljs-attr">label</span>: <span class="hljs-string">'paypal'</span>,

    },

    <span class="hljs-attr">createOrder</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data, actions</span>) </span>{
      <span class="hljs-keyword">return</span> actions.order.create({
        <span class="hljs-attr">purchase_units</span>: [{<span class="hljs-string">"amount"</span>:{<span class="hljs-string">"currency_code"</span>:<span class="hljs-string">"USD"</span>,<span class="hljs-string">"value"</span>:<span class="hljs-number">0.99</span>}}]
      });
    },

    <span class="hljs-attr">onApprove</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data, actions</span>) </span>{
      <span class="hljs-keyword">return</span> actions.order.capture().then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">orderData</span>) </span>{

        <span class="hljs-comment">// Full available details</span>
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Capture result'</span>, orderData, <span class="hljs-built_in">JSON</span>.stringify(orderData, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>));

        <span class="hljs-comment">// Show a success message within this page, for example:</span>
        <span class="hljs-keyword">const</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'paypal-button-container'</span>);
        element.innerHTML = <span class="hljs-string">''</span>;
        element.innerHTML = <span class="hljs-string">'&lt;h3&gt;Thank you for your payment!&lt;/h3&gt;'</span>;

        <span class="hljs-comment">// Or go to another URL:  actions.redirect('thank_you.html');</span>

      });
    },

    <span class="hljs-attr">onError</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
      <span class="hljs-built_in">console</span>.log(err);
    }
  }).render(<span class="hljs-string">'#paypal-button-container'</span>);
}
initPayPalButton();
</code></pre>
<p>These files are going to give us the following slick product landing page:</p>
<p><img src="https://lh6.googleusercontent.com/ZpupgG6OYiC0pSk9cdqIXp2SluOZ1Vh31WdzRLmAkvdLxlwWlfGx05JyhPFnf7dJdjcf76aeFRZua31cGKcTCwphR3RLuMvevHp_s0DUxU3lop_0Dq-GZK1tyUh7UcpU9SaC2K2x9GkfrNt1Eio-0Wb8MR1Jb3XPeb5p1X-ZQGoKjDjQLgxtV16CydKJwQ" alt="Image" width="1238" height="1036" loading="lazy">
<em>My new landing page with PayPal's smart buttons</em></p>
<h2 id="heading-how-to-test-the-integration-using-the-paypal-sandbox-environment">How to Test the Integration Using the PayPal Sandbox Environment</h2>
<p>Before going live with your PayPal integration on your product page, it is important to test the integration to ensure that it is working correctly and to identify any issues. </p>
<p>One way to do this is by using the PayPal Sandbox environment that we discussed earlier.</p>
<p>To use the PayPal Sandbox with the account you created earlier, you will be given a set of Sandbox test accounts (buyer and seller) that you can use to test your integration.</p>
<p>With these Sandbox accounts set up, you will need to ensure your PayPal button code on your product page points to the Sandbox environment. </p>
<p>You can do this by checking that the URL in the PayPal button code redirects you to "https://www.sandbox.paypal.com" instead of "https://www.paypal.com".</p>
<p><img src="https://lh5.googleusercontent.com/h_jQc1xmhqmETV2LA_2wsfx2ucRwx_eKhmsWr0ZXVER3c89m73xvBj8L0D3-_meGToje6ElWhfyeGc4Gf_as5fdHdxTtRwCDL5vv7wb9uKK8BYQqCBtLZC3yVzgkX1gjgIAPI_bAbtM_B6ANmSg_NXuibAe-dFjO1yCXI1_qnIPmNsS7AdevCydXiflLmg" alt="Image" width="1052" height="478" loading="lazy">
<em>Check your URL to contain "sandbox"</em></p>
<p>With your PayPal button code working, you can now test the integration by visiting your product page and clicking on the PayPal button. You will be taken to the PayPal Sandbox checkout page where you can enter your Sandbox test account credentials and simulate a purchase.</p>
<p>Once you've completed a test transaction, you can log in to your Sandbox account to view the transaction details and confirm that it was processed correctly.</p>
<h2 id="heading-how-to-go-live-and-start-accepting-real-payments">How to Go Live and Start Accepting Real Payments</h2>
<p>After successfully testing your PayPal integration in the Sandbox environment, you are now ready to go live and start accepting real payments on your product page. </p>
<p>Going live involves a few simple steps to ensure that your integration is set up correctly and ready to process real payments.</p>
<p>The first step is to update your PayPal button code on your product page to point to the live PayPal environment. Conversely to earlier, ensure that the URL in the PayPal button code redirects you to "https://www.paypal.com" instead of "https://www.sandbox.paypal.com".</p>
<p>Next, you will need to update your PayPal account settings to ensure that your account is set up to process live payments. This typically involves confirming your email address and phone number, as well as adding a valid payment method such as a bank card.</p>
<p>It is also important to ensure that your product page is fully functional and that any necessary information such as product details, prices, and shipping costs are accurate.</p>
<p>Finally, you should notify your customers that you are now accepting payments via PayPal, and provide them with clear instructions on how to complete a purchase.</p>
<p>With all these steps complete, you can now start accepting real payments via PayPal on your product page!</p>
<h2 id="heading-where-to-go-from-here">Where To Go From Here?</h2>
<p>Now that you’re all up to speed with getting PayPal integrations up and running on your own websites, why would this be useful to you? Are there no easier ways to integrate payments into your website? Let me give you some context.</p>
<p>Personally, I thought that no-code tools were becoming the norm in recent times, thinking that I probably wouldn’t need to be coding any web pages in vanilla HTML, CSS, and JavaScript soon. But with the new wave of online startups, such as <a target="_blank" href="https://www.misaias.com/best-ai-productivity-tools/">AI tools</a> and <a target="_blank" href="https://lanagerton.com/best-data-analytics-tools-and-software/">data analytics software</a>, revolving around making API requests from a simple user interface, I think the 3 big languages might make a bit of a comeback.</p>
<p>Wanting to start one of my own (so the story earlier wasn’t entirely fictitious…), I found myself coming back to the good old vanilla web development languages to get the job done. And they did so faster than no-code tools – like this simple <a target="_blank" href="https://shaneduggan.com/sentence-length-counter">sentence-length checker</a> I programmed in under an hour.</p>
<p>So I wouldn’t forget about learning how to integrate features, such as this, into standard HTML, CSS, and JavaScript pages. Sometimes, when it comes to wanting to create a simple product or service page that gets the job done, you might want to rely on old ways with new integrations as your solution.</p>
<h2 id="heading-wrapping-up-and-conclusion">Wrapping Up and Conclusion</h2>
<p>Let me give you a quick recap:</p>
<p>If you're looking to get a simple <a target="_blank" href="https://themoneymaniac.com/saas-ideas">SaaS</a> company going, then vanilla HTML, CSS, and JavaScript might be your best friends. When it comes to integrating PayPal into your product pages, it is important to remember a few key points to ensure a smooth and successful integration.</p>
<ul>
<li>Firstly, it is essential to have a PayPal account and to be familiar with the PayPal Developer documentation.</li>
<li>Secondly, ensure that your HTML and CSS files are well structured and designed to match your product page.</li>
<li>Lastly, use the PayPal Sandbox environment for testing to ensure everything is spick and span before going live with real payments.</li>
</ul>
<p>As a reminder, it is important to keep in mind that collecting payments through a form on your website is not a secure way of accepting payments, and it is recommended to use a payment gateway such as PayPal to ensure the security of your customer's sensitive information.</p>
<p>With these points in mind, you can now confidently set up PayPal on your product pages and start accepting payments securely and easily. I hope you enjoyed this tutorial, and if you did, don't hesitate to <a target="_blank" href="https://shaneduggan.com/">get in contact</a>. Wishing you the best of luck selling your products to the masses!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Payment Request API in JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ By  Atta ✨ The Payment Request API provides a cross-browser standard that lets you collect payments, addresses, and contact information from your customers. You can then use this info to process their order.  It also facilitates the exchange of this ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/payment-request-api-javascript/</link>
                <guid isPermaLink="false">66d45d98052ad259f07e4a5b</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 24 Oct 2022 22:40:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/js-payment-request.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By  Atta ✨</p>
<p>The Payment Request API provides a cross-browser standard that lets you collect payments, addresses, and contact information from your customers. You can then use this info to process their order. </p>
<p>It also facilitates the exchange of this information between the browser and the website. The fundamental idea behind this is to improve the user's online shopping experience by making it easy for users to store payment and contact information in the browser.</p>
<h2 id="heading-payment-request-api-browser-support">Payment Request API Browser Support</h2>
<p>The Payment Request API is still in active development and is only supported by the <a target="_blank" href="https://caniuse.com/#feat=payment-request">last few versions</a> of modern browsers. </p>
<p>Before you start making a payment request, you should feature detect to ensure that the API is supported by the browser:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.PaymentRequest) {
  <span class="hljs-comment">// Yes, we can use the API</span>
} <span class="hljs-keyword">else</span> {
  <span class="hljs-comment">// No, fallback to the checkout page</span>
  <span class="hljs-built_in">window</span>.location.href = <span class="hljs-string">'/checkout'</span>
}
</code></pre>
<p>Note that you can only use the Payment Request API on sites serving over <code>https</code>.</p>
<p>Now let's see how this helpful API works.</p>
<h2 id="heading-how-to-create-the-paymentrequest-object">How to Create the PaymentRequest Object</h2>
<p>A payment request is always started by creating a new object of <code>PaymentRequest</code> - using the <code>PaymentRequest()</code> constructor. The constructor takes two mandatory parameters and one optional parameter:</p>
<ul>
<li><code>paymentMethods</code> defines which forms of payment are accepted. For example, you may only accept Visa and MasterCard credit cards.</li>
<li><code>paymentDetails</code> contains the total payment amount due, taxes, shipping cost, display items, and so on.</li>
<li><code>options</code> is an optional argument used to request additional details from the user, such as name, email, phone, and so on.</li>
</ul>
<p>Next we'll create a new payment request with only the required parameters.</p>
<h3 id="heading-how-to-use-the-paymentmethods-parameter">How to use the <code>paymentMethods</code> parameter</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paymentMethods = [
  {
    <span class="hljs-attr">supportedMethods</span>: [<span class="hljs-string">'basic-card'</span>]
  }
]

<span class="hljs-keyword">const</span> paymentDetails = {
  <span class="hljs-attr">total</span>: {
    <span class="hljs-attr">label</span>: <span class="hljs-string">'Total Amount'</span>,
    <span class="hljs-attr">amount</span>: {
      <span class="hljs-attr">currency</span>: <span class="hljs-string">'USD'</span>,
      <span class="hljs-attr">value</span>: <span class="hljs-number">8.49</span>
    }
  }
}

<span class="hljs-keyword">const</span> paymentRequest = <span class="hljs-keyword">new</span> PaymentRequest(paymentMethods, paymentDetails)
</code></pre>
<p>Notice the <code>supportedMethods</code> parameter in the <code>paymentMethods</code> object. When it is set to <code>basic-card</code>, both debit and credit cards of all networks will be accepted. </p>
<p>But you can limit the supported networks and types of cards. For example, with the following only Visa, MasterCard, and Discover credit cards are accepted:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paymentMethods = [
  {
    <span class="hljs-attr">supportedMethods</span>: [<span class="hljs-string">'basic-card'</span>],
    <span class="hljs-attr">data</span>: {
      <span class="hljs-attr">supportedNetworks</span>: [<span class="hljs-string">'visa'</span>, <span class="hljs-string">'mastercard'</span>, <span class="hljs-string">'discover'</span>],
      <span class="hljs-attr">supportedTypes</span>: [<span class="hljs-string">'credit'</span>]
    }
  }
]
<span class="hljs-comment">// ...</span>
</code></pre>
<h3 id="heading-how-to-use-the-paymentdetails-object">How to use the <code>paymentDetails</code> object</h3>
<p>The second parameter passed to the <code>PaymentRequest</code> constructor is the payment details object. It contains the total of the order and an optional array of display items. The <code>total</code> parameter must include a <code>label</code> parameter and an <code>amount</code> parameter with <code>currency</code> and <code>value</code>.</p>
<p>You can also add additional display items to provide a high-level breakdown of the total:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paymentDetails = {
  <span class="hljs-attr">total</span>: {
    <span class="hljs-attr">label</span>: <span class="hljs-string">'Total Amount'</span>,
    <span class="hljs-attr">amount</span>: {
      <span class="hljs-attr">currency</span>: <span class="hljs-string">'USD'</span>,
      <span class="hljs-attr">value</span>: <span class="hljs-number">8.49</span>
    }
  },
  <span class="hljs-attr">displayItems</span>: [
    {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'15% Discount'</span>,
      <span class="hljs-attr">amount</span>: {
        <span class="hljs-attr">currency</span>: <span class="hljs-string">'USD'</span>,
        <span class="hljs-attr">value</span>: <span class="hljs-number">-1.49</span>
      }
    },
    {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Tax'</span>,
      <span class="hljs-attr">amount</span>: {
        <span class="hljs-attr">currency</span>: <span class="hljs-string">'USD'</span>,
        <span class="hljs-attr">value</span>: <span class="hljs-number">0.79</span>
      }
    }
  ]
}
</code></pre>
<p>The <code>displayItems</code> parameter is not meant to display a long list of items. Since space is limited for the browser's payment UI on mobile devices, you should use this parameter to display only top-level fields such as subtotal, discount, tax, shipping cost, and so on.</p>
<p>Keep in mind that the <code>PaymentRequest</code> API does not perform any calculations. So your web application is responsible for providing the pre-calculated <code>total</code> amount.</p>
<h3 id="heading-how-to-use-the-options-argument-to-request-additional-details">How to use the <code>options</code> argument to request additional details</h3>
<p>You can use the third optional parameter to request additional information from the user, such as name, email address, and phone number:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// ...</span>
<span class="hljs-keyword">const</span> options = {
  <span class="hljs-attr">requestPayerName</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">requestPayerPhone</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">requestPayerEmail</span>: <span class="hljs-literal">true</span>
}

<span class="hljs-keyword">const</span> paymentRequest = <span class="hljs-keyword">new</span> PaymentRequest(paymentMethods, paymentDetails, options)
</code></pre>
<p>By default, all of these values are <code>false</code>, but adding any of them to the <code>options</code> object with a value <code>true</code> will result in an extra step in the payment UI. If the user has already stored these details in the browser, they will be pre-populated.</p>
<h2 id="heading-how-to-display-the-payment-ui">How to Display the Payment UI</h2>
<p>After creating a <code>PaymentRequest</code> object, you must call the <code>show()</code> method to display the payment request UI to the user. </p>
<p>The <code>show()</code> method returns a <a target="_blank" href="https://www.freecodecamp.org/news/javascript-promises-for-beginners/">promise</a> that resolves with a <code>PaymentResponse</code> object if the user has successfully filled in the details. If there is an error or the user closes the UI, the promise rejects.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// ...</span>
<span class="hljs-keyword">const</span> paymentRequest = <span class="hljs-keyword">new</span> PaymentRequest(paymentMethods, paymentDetails, options)

paymentRequest
  .show()
  .then(<span class="hljs-function"><span class="hljs-params">paymentResponse</span> =&gt;</span> {
    <span class="hljs-comment">// close the payment UI</span>
    paymentResponse.complete().then(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> call REST API to process the payment at the backend server</span>
      <span class="hljs-comment">// with the data from `paymentResponse`.</span>
    })
  })
  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
    <span class="hljs-comment">// user closed the UI or the API threw an error</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Error:'</span>, err)
  })
</code></pre>
<p>With the above code, the browser will show the payment UI to the user. Once the user has filled in the details and clicked on the 'Pay' button, you will receive a <code>PaymentResponse</code> object in the <code>show()</code> promise. </p>
<p>The payment request UI is closed immediately when you call the <code>PaymentResponse.complete()</code> method. This method returns a new promise so that you can call the backend server with the information collected and process the payment.</p>
<p><img src="https://cdn.attacomsian.com/gims/da91575d-9de1-448e-92dc-9c255083f271.jpg" alt="Payment Request UI" width="600" height="400" loading="lazy"></p>
<p>If you want to call the backend server to process the payment while the payment UI is showing a spinner, you can delay the call to <code>complete()</code>. </p>
<p>Let's create a mock function for payment processing with the backend server. It takes <code>paymentResponse</code> as a parameter and returns a promise after 1.5 seconds that resolves to a <a target="_blank" href="https://www.freecodecamp.org/news/what-is-json-a-json-file-example/">JSON object</a>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> processPaymentWithServer = <span class="hljs-function"><span class="hljs-params">paymentResponse</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve({ <span class="hljs-attr">status</span>: <span class="hljs-literal">true</span> })
    }, <span class="hljs-number">1500</span>)
  })
}

<span class="hljs-comment">//...</span>
paymentRequest
  .show()
  .then(<span class="hljs-function"><span class="hljs-params">paymentResponse</span> =&gt;</span> {
    processPaymentWithServer(paymentResponse).then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
      <span class="hljs-keyword">if</span> (data.status) {
        paymentResponse.complete(<span class="hljs-string">'success'</span>)
      } <span class="hljs-keyword">else</span> {
        paymentResponse.complete(<span class="hljs-string">'fail'</span>)
      }
    })
  })
  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Error:'</span>, err)
  })
</code></pre>
<p>In the example above, the browser payment UI will show a processing screen until the promise returned by the <code>processPaymentWithServer()</code> method is settled. We also used 'success' and 'fail' strings to tell the browser about the transaction outcome. The browser will show an error message to the user if you call <code>complete('fail')</code>.</p>
<h2 id="heading-how-to-cancel-a-payment-request">How to Cancel a Payment Request</h2>
<p>If you want to cancel the payment request due to no activity or any other reason, you can use the <code>PaymentRequest.abort()</code> method. It immediately closes the payment request UI and rejects the <code>show()</code> promise.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// ...</span>
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  paymentRequest
    .abort()
    .then(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// aborted payment request</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Payment request aborted due to no activity.'</span>)
    })
    .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
      <span class="hljs-comment">// error while aborting</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'abort() Error: '</span>, err)
    })
}, <span class="hljs-number">5000</span>)
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>That's the end of a quick introduction to the JavaScript Payment Request API. It provides a browser-based method to collect customer payment and contact information that can be sent to the backend server to process the payment. </p>
<p>The aim is to reduce the number of steps in completing an online payment. It makes the whole checkout process smoother by remembering the user's preferred way of paying for goods and services.</p>
<p>If you want to learn more about the Payment Request API, here is a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Payment_Request_API">good resource</a> that discusses the main concepts and usage of the API.</p>
<h2 id="heading-thank-you-for-reading">Thank you for reading!</h2>
<p>If you want to learn more about JavaScript, you may want to check out my <a target="_blank" href="https://attacomsian.com/">personal blog</a>, where I have published over 235 tutorials on JavaScript objects, arrays, strings, Web APIs, and more.</p>
<p>I am also the founder of <a target="_blank" href="https://acquirebase.com">AcquireBase</a>. You can follow me on <a target="_blank" href="https://twitter.com/attacomsian">Twitter</a> to receive updates when I publish new tutorials or share side projects. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Accept Payments with React and Stripe ]]>
                </title>
                <description>
                    <![CDATA[ Payments are an essential part of any online business. But the process of setting up those payments can be incredibly complex at times.  To accept payments, developers were traditionally required to set up code both on the client and server. This was... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-stripe-payments/</link>
                <guid isPermaLink="false">66d037e964be048ac359a330</guid>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Fri, 16 Sep 2022 18:55:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/mugshotbot.com_customize_color-blue-image-00471e9c-mode-light-pattern-bank_note-theme-two_up-url-https___freecodecamp.org.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Payments are an essential part of any online business. But the process of setting up those payments can be incredibly complex at times. </p>
<p>To accept payments, developers were traditionally required to set up code both on the client and server. This was in addition to learning complex third-party APIs which required parsing through large amounts of documentation. </p>
<p>Fortunately tools like Stripe Checkout make handling purchases on the web and mobile devices easier than ever before. </p>
<p>In this tutorial, you'll take a look at how to set up Stripe Checkout to accept credit card, Apple Pay, and Google Pay payments in our React apps.</p>
<h2 id="heading-what-is-stripe-checkout">What is Stripe Checkout?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.57.01-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example Stripe Checkout page</em></p>
<p>Stripe Checkout is an all-in-one tool that not only streamlines and simplifies the process of checking out for us as developers. It also gives us a user interface for our customers to use that's optimized for performance and usability. </p>
<p>When using Stripe checkout over alternative options such as Stripe Elements, the benefit is that you have to write far less code to achieve the same end result. Additionally, you get features such as automatic translations for global users in their language. </p>
<p>You also get the ability to customize this user interface without having to write a single React component. </p>
<h2 id="heading-stripe-checkout-is-hosted-on-stripe">Stripe Checkout is Hosted on Stripe</h2>
<p>Be aware that Stripe Checkout is hosted on Stripe's servers and it involves taking the user to <em>checkout.stripe.com</em>. This, however, shouldn't be viewed as a downside. </p>
<p>Because trust is such an important part of the checkout process, it's often a large benefit to know that Stripe is handling the payment. As a result, customers can be far more secure and confident in the payment process.</p>
<p>In short, it's a wise decision to use a pre-made solution such as Stripe Checkout, considering it will not only mean less work for you, but will also create higher trust in your product.</p>
<h2 id="heading-how-to-setup-stripe-checkout">How to Setup Stripe Checkout</h2>
<ol>
<li>Go to stripe.com and create a free account.</li>
<li>You will be navigated to your dashboard at <em>dashboard.stripe.com</em></li>
</ol>
<p>In the top right corner of your dashboard, make sure to turn "Test Mode" on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.39.55-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Make sure you are in test mode</em></p>
<ol start="3">
<li>Create a new product in Stripe.</li>
</ol>
<p>The fastest way to get there is to search for "Create Product" in the search and click on the "Create a Product" result. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.41.32-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Go to "Create a Product"</em></p>
<ol start="4">
<li>Add your product information, including its name, description and image.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.42.17-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Provide your product information</em></p>
<ol start="5">
<li>On the same page, add your price information for that product.</li>
</ol>
<p>In this example, we will choose a recurring (monthly) pricing model. Be aware that you can select a one-time payment for your products as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.43.09-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select your pricing details</em></p>
<ol start="6">
<li>Save your new product and get your price id</li>
</ol>
<p>After your product has been created, if you go down to the pricing section, you will see an id beginning with <code>price_</code> next to your price. You will need to this create a checkout session with Stripe.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.44.49-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Grab the created price id for your product</em></p>
<ol start="7">
<li>Get your publishable key.</li>
</ol>
<p>The last step is to get the publishable (test) key from Stripe. We also need this for creating a checkout session with Stripe.</p>
<p>This time, we can search for "api key" and choose the first result.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.47.56-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Search for "api key"</em></p>
<p>On the API keys page (once again, in test mode), you will grab the publishable key that begins with <code>pk_test</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/Screen-Shot-2022-09-16-at-12.49.15-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Grab the publishable key, under "token"</em></p>
<h2 id="heading-how-to-add-stripe-checkout-to-react">How to Add Stripe Checkout to React</h2>
<p>Now that we have everything we need to setup Stripe Checkout with React, namely the price id and the publishable key, we can create our React app.</p>
<p>For this tutorial, I will be using Next.js, which is a React framework. You can create your own Next.js app instantly using StackBlitz by going to <em>next.new</em>.</p>
<p>We'll begin by creating a button to check out on our homepage (pages/index.js). When a user clicks on this button, Stripe will redirect our user to the checkout page.</p>
<pre><code class="lang-js"><span class="hljs-comment">// pages/index.js</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Checkout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>To communicate with Stripe, we need to install the following package with NPM or Yarn:</p>
<pre><code class="lang-bash">npm install @stripe/stripe-js
</code></pre>
<p>Once installed, we will create a new folder and file within it: <code>lib/getStripe.js</code> in the root of our project.</p>
<p>In this file, we will handle loading Stripe only once. To do so, we pass Stripe our publishable key.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { loadStripe } <span class="hljs-keyword">from</span> <span class="hljs-string">'@stripe/stripe-js'</span>;

<span class="hljs-keyword">let</span> stripePromise;
<span class="hljs-keyword">const</span> getStripe = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (!stripePromise) {
    stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
  }
  <span class="hljs-keyword">return</span> stripePromise;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> getStripe;
</code></pre>
<p>Here, we are loading the publishable key from a <code>.env</code> file. Make sure to create that in the root of your project with the following two values, for your publishable key and price key:</p>
<pre><code class="lang-js">NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=<span class="hljs-string">'pk_test_my_key'</span>

NEXT_PUBLIC_STRIPE_PRICE_ID=<span class="hljs-string">'price_my_id'</span>
</code></pre>
<p>Once you have added your environment variables, we'll head back to the home page and create a function called <code>handleCheckout</code>. </p>
<p>It will first call <code>getStripe</code> which we need to await because this function returns a promise. Make sure to import our <code>getStripe</code> function from the lib folder.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> getStripe <span class="hljs-keyword">from</span> <span class="hljs-string">'../lib/getStripe'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleCheckout</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> stripe = <span class="hljs-keyword">await</span> getStripe();
    <span class="hljs-keyword">const</span> { error } = <span class="hljs-keyword">await</span> stripe.redirectToCheckout({
      <span class="hljs-attr">lineItems</span>: [
        {
          <span class="hljs-attr">price</span>: process.env.NEXT_PUBLIC_STRIPE_PRICE_ID,
          <span class="hljs-attr">quantity</span>: <span class="hljs-number">1</span>,
        },
      ],
      <span class="hljs-attr">mode</span>: <span class="hljs-string">'subscription'</span>,
      <span class="hljs-attr">successUrl</span>: <span class="hljs-string">`http://localhost:3000/success`</span>,
      <span class="hljs-attr">cancelUrl</span>: <span class="hljs-string">`http://localhost:3000/cancel`</span>,
      <span class="hljs-attr">customerEmail</span>: <span class="hljs-string">'customer@email.com'</span>,
    });
    <span class="hljs-built_in">console</span>.warn(error.message);
  }

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleCheckout}</span>&gt;</span>Checkout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>Then we will call <code>stripe.redirectToCheckout</code>, which is also a function we need to <code>await</code>.</p>
<p>To this function will pass an object which includes four main properties: </p>
<ol>
<li><code>lineItems</code>: an array of objects including the products and quantity of those products in our order.  </li>
<li><code>mode</code>: whether our transaction is recurring or one-time</li>
<li><code>successUrl</code>: the page the user will be navigated to upon successful purchase (feel free to set this up on your own) </li>
<li><code>cancelUrl</code>: the page the user will be navigated to upon successful purchase (again, easy to setup) </li>
</ol>
<p>There are many more properties that you can pass to this object, such as passing in the <code>customerEmail</code> to pre-populate the user's email input.</p>
<h2 id="heading-how-to-test-stripe-checkout">How to Test Stripe Checkout</h2>
<p>Once we hit our checkout button, we should be directed to a complete page which in test mode will allow us to provide a test credit card number to verify the checkout process (repeat the number 4242 repeating for all fields). </p>
<p>If our user cancels and attempts to go back, they will be taken to the cancelUrl we specified. Otherwise, if they successfully complete this process, they will be taken to the successUrl. </p>
<p>Once you are ready to go live and accept your customers' money, all you need to do is swap out your test publishable key with a non-test one.</p>
<p>Hopefully that gave you a good understanding of how to get started with Stripe Checkout and how to more easily accept payments in your React apps!</p>
<p>You can find the final code for this example here: <a target="_blank" href="https://stackblitz.com/edit/nextjs-4ts4y4?file=pages%2Findex.js">https://stackblitz.com/edit/nextjs-4ts4y4?file=pages%2Findex.js</a></p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up a Payment Gateway in Next.js and React with Razorpay and TailwindCSS ]]>
                </title>
                <description>
                    <![CDATA[ By Manu Arora If you have an e-commerce application, a payment gateway lets you process payments on your website on the fly.  With all the modern payment gateway solutions available these days, there are many ways you can integrate payments and charg... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/integrate-a-payment-gateway-in-next-js-and-react-with-razorpay-and-tailwindcss/</link>
                <guid isPermaLink="false">66d4601fa326133d12440a33</guid>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 21 Dec 2021 18:16:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Blue-and-White-Modern-Corporate-Travel-YouTube-Thumbnail.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Manu Arora</p>
<p>If you have an e-commerce application, a payment gateway lets you process payments on your website on the fly. </p>
<p>With all the modern payment gateway solutions available these days, there are many ways you can integrate payments and charge your users for your product or services.  </p>
<p>In this tutorial, we are going to build a landing page that lets the end user purchase products from a web application. The page looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-20-at-10.54.31-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Live Demo: <a target="_blank" href="https://integrate-payments.vercel.app">Integrate Payments</a>
Source Code: <a target="_blank" href="https://github.com/manuarora700/integrate-payments.git">Integrate Payments Source Code</a></p>
<p>Some of the popular payment gateways that are available are:</p>
<ul>
<li><a target="_blank" href="https://stripe.com">Stripe</a></li>
<li><a target="_blank" href="https://gumroad.com">Gumroad</a></li>
<li><a target="_blank" href="https://paypal.com">PayPal</a></li>
<li><a target="_blank" href="https://razorpay.com">Razorpay</a></li>
</ul>
<p>Today, we are going to learn how to integrate Razorpay with a Next.js (React) application and understand how the flow actually works.</p>
<h2 id="heading-tech-stack"><strong>Tech Stack</strong></h2>
<p>For our Stack, we are going to use the following technologies:</p>
<ul>
<li><a target="_blank" href="https://nextjs.org">Next.js</a> - A framework for React that gives access to serverless functions and React architecture.</li>
<li><a target="_blank" href="https://tailwindcss.com">TailwindCSS</a> - A utility-based CSS framework for easy styling</li>
<li><a target="_blank" href="https://razorpay.com">Razorpay</a> - A payment gateway system that lets users access payments.</li>
<li><a target="_blank" href="https://vercel.com">Vercel</a> - For hosting our Next.js application (if not already hosted)</li>
<li><a target="_blank" href="https://tailwindmasterkit.com">Tailwind Master Kit</a> - For easily accessible Tailwind Components</li>
</ul>
<h2 id="heading-project-setup"><strong>Project Setup</strong></h2>
<p>If you already have a project, then you can directly skip to the integration part of the article. If not, let's get started by creating a Git repository and hosting our project on Vercel.</p>
<h3 id="heading-how-to-set-up-a-nextjs-repository-and-website"><strong>How to Set Up a Next.js Repository and Website</strong></h3>
<p>First, head over to <a target="_blank" href="https://vercel.com">Vercel</a> and create a hobby account for yourself. (If you're going to use it for a commercial project, make sure you buy their plan. Hobby accounts are just for testing and creating playgrounds.)</p>
<p>Once the account is created, click on <code>New Project</code>
<img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-11.56.47-AM.png" alt="Screenshot-2021-12-21-at-11.56.47-AM" width="600" height="400" loading="lazy"></p>
<p>Then, select <code>Next.js</code> from the available options and create a Git Repository on the platform itself.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-11.57.31-AM.png" alt="Screenshot-2021-12-21-at-11.57.31-AM" width="600" height="400" loading="lazy"></p>
<p>Your site will be deployed within seconds and you will get a URL for the live website.</p>
<h3 id="heading-how-to-set-up-tailwindcss"><strong>How to Set Up TailwindCSS</strong></h3>
<p>Now since the website is setup, you can directly go to <a target="_blank" href="https://github.com">GitHub</a>, clone the repository, to run it in your local environment. For that, follow these simple steps:</p>
<ul>
<li>Go to <a target="_blank" href="https://github.com">GitHub</a> and find your newly created repository</li>
<li>Click on the <code>code</code> section and copy the repository URL.</li>
<li>Open your terminal on the desktop and write <code>git clone &lt;repo_name&gt;</code>. This will clone the repository in your local environment so that you can start working.</li>
<li>Once the repository is cloned/copied in your local environment, open the project in your favourite code editor (VSCode is the best in my opinion).</li>
<li>In the terminal, open the location of the application and write <code>npm install</code>. This will install all the related node modules.</li>
<li>You can start the local development server by writing <code>npm run dev</code>.</li>
</ul>
<p>Now the project is up and running in your local environment. To access your website locally, open <code>localhost:3000</code> in your browser and you will be able to see the boilerplate website already there for you.  </p>
<p>Setting up tailwind is very simple. Their <a target="_blank" href="https://tailwindcss.com/docs/guides/nextjs">documentation</a> makes it even simpler. Check out their docs for reference and more on TailwindCSS as a framework.  </p>
<p>To setup Tailwind on your local environment, follow the below steps:</p>
<ul>
<li><code>npm install -D tailwindcss postcss autoprefixer</code> - This will install TailwindCSS along with other important dependencies for compiling and running your Tailwind code.</li>
<li><code>npx tailwindcss init -p</code> - This will initialize a <code>tailwind.config.js</code> file that is just an object which can be manipulated according to the user's needs.</li>
<li>In the <code>tailwind.config.js</code> file, paste the below code which basically tells Tailwind to compile the code present in the <code>/pages</code> and <code>/components</code> directories.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [
    <span class="hljs-string">"./pages/**/*.{js,ts,jsx,tsx}"</span>,
    <span class="hljs-string">"./components/**/*.{js,ts,jsx,tsx}"</span>,
  ],
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {},
  },
  <span class="hljs-attr">plugins</span>: [],
}
</code></pre>
<ul>
<li>Open the <code>globals.css</code> file present in the <code>/styles</code> directory and paste the following code. These code snippets import all the Tailwind related setup code:<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;
</code></pre>
</li>
<li>Restart your website by quitting the terminal and writing <code>npm run dev</code> on the terminal. Now you're ready to harness the power of TailwindCSS.</li>
</ul>
<p>Now that Tailwind and our website are setup, let's jump right into developing the page and integrating payments.</p>
<h2 id="heading-landing-page-development"><strong>Landing Page Development</strong></h2>
<p>The landing page that we are going to use is directly taken from the <a target="_blank" href="https://tailwindmasterkit.com">Tailwind Master Kit</a> that lets you access components built with TailwindCSS.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-12.13.56-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's break down the code and understand it better.</p>
<h3 id="heading-navbarjs"><strong>Navbar.js</strong></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Navbar = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-row items-center  justify-between px-20 py-10"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-row items-center"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold italic text-2xl text-white mr-10"</span>&gt;</span>Payments<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-row space-x-10"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
              <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>
              <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-400 text-sm tracking-wide font-light"</span>
            &gt;</span>
              Pricing
            <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
              <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>
              <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-400 text-sm tracking-wide font-light"</span>
            &gt;</span>
              Product
            <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
              <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>
              <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-400 text-sm tracking-wide font-light"</span>
            &gt;</span>
              Team
            <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
              <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>
              <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-400 text-sm tracking-wide font-light"</span>
            &gt;</span>
              Sales
            <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-row space-x-10 items-center"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-400 text-sm tracking-wide font-light"</span>&gt;</span>
          Sales
        <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-[#272A30] text-gray-300 px-8 text-sm py-2 rounded-md shadow-xl drop-shadow-2xl"</span>&gt;</span>
          Sign in
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
</code></pre>
<p>Building the Navbar is simple. It's a Flexbox container with links and unordered list items aligned in a <code>row</code>. </p>
<p>The button, however, is interesting. It used the new TailwindCSS drop shadow class which drops a background shadow. (We can also use colored shadows in TailwindCSS 3.0+ versions - pretty cool.)</p>
<h3 id="heading-herojs"><strong>Hero.js</strong></h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Hero = <span class="hljs-function">(<span class="hljs-params">{ onClick }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"relative z-10 flex flex-col md:flex-row mt-10 items-center  max-w-6xl justify-evenly mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"md:w-1/3 mb-20 md:mb-0 mx-10"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">" text-white font-bold text-5xl mb-10"</span>&gt;</span>
          Integrate{" "}
          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-clip-text text-transparent bg-gradient-to-r from-pink-500 to-violet-500"</span>&gt;</span>
            payments
          <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>{" "}
          in less than 10 minutes.
        <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-gray-300 font-light tracking-wide w-[300px] mb-10"</span>&gt;</span>
          Learn how to integrate a Payment Gateway with your Next.js and React
          application.
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gradient-to-r from-[#3e4044] to-[#1D2328] p-[1px] rounded-md mb-4"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gradient-to-r from-[#2E3137] to-[#1D2328] rounded-md w-full py-4 shadow-xl drop-shadow-2xl text-gray-300 font-bold"</span>
          &gt;</span>
            Purchase Now!
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gradient-to-r from-[#3e4044] to-[#1D2328] p-[1px] rounded-md"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gradient-to-r from-[#1D2328] to-[#1D2328] rounded-md w-full py-4 shadow-sm drop-shadow-sm text-gray-400 font-light"</span>&gt;</span>
            Read Blog
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      {/* <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"w-2/3 bg-white flex-shrink-0  relative"</span>&gt;</span> */}
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full md:w-[36rem] h-full"</span>
        <span class="hljs-attr">alt</span>=<span class="hljs-string">"stripe payment from undraw"</span>
        <span class="hljs-attr">src</span>=<span class="hljs-string">"/payments.svg"</span>
      /&gt;</span>
      {/* <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> */}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
</code></pre>
<p>The hero section contains our <code>Purchase Now</code> button which will initialise the payments for us (we'll look at the implementation in the next section).</p>
<p>The layout contains two sections: the <code>Left section</code> contains all the text and the <code>Right Section</code> contains a large image (taken from Undraw, a free and open source illustrations website). </p>
<p>The <code>onClick</code> action on the button is important since it is responsible for triggering the action that will initialise the payments. The <code>onClick</code> is nothing but a <code>callback</code> that calls the function which is passed down as a prop to the component.  </p>
<p>That's pretty much it for the UI part. Let's jump into the payments section and understand how to setup a developer account on Razorpay and use their SDK to make payments on our website.</p>
<h2 id="heading-how-to-set-up-a-razorpay-account-and-retrieve-api-keys">How to Set Up a Razorpay Account and Retrieve API Keys</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-12.25.43-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For integrating payments (that is, receiving payments on our website), we need to have two things:</p>
<ol>
<li>A Razorpay account</li>
<li>A set of API Keys that lets us access their services.</li>
</ol>
<p>Let's create an account and retrieve the API keys.</p>
<ul>
<li>Head over to <a target="_blank" href="https://razorpay.com">Razorpay</a> and sign up for an account</li>
<li>After signing up you can access the <a target="_blank" href="https://dashboard.razorpay.com/app/dashboard">Dashboard</a> where you will find all the necessary details that are required for integrating payments.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-12.28.44-PM.png" alt="Screenshot-2021-12-21-at-12.28.44-PM" width="600" height="400" loading="lazy"></li>
<li>For now, we will be in Test mode so that we can test our payments before we actually go live.</li>
<li>In the left panel, scroll down to <code>Settings</code> - There you will find the API keys section along with the configurations you can make to your payments UI.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-12.30.10-PM.png" alt="Screenshot-2021-12-21-at-12.30.10-PM" width="600" height="400" loading="lazy"></li>
<li>Since you will be doing it for the first time, click on <code>Generate API Keys</code> and the download will automatically start. The downloaded file contains <code>Razorpay API Key</code> and <code>Razorpay API Secret</code>.</li>
</ul>
<p>Now you're all set with the API keys and setting up the platform. Let's jump directly into how to actually trigger the Razorpay API and make payments.</p>
<h2 id="heading-how-to-integrate-payments-with-razorpay"><strong>How to Integrate Payments with Razorpay</strong></h2>
<p>For our payments to be integrated, we need a button click that actually initializes the Razorpay <code>checkout</code> module. For this, we already have a button <code>Purchase Now</code> the calls a function <code>onClick</code> that is nothing but a callback. Let's see the actual implementation and understand the code behind it.</p>
<p>To initialise a payment, we need to add Razorpay's <code>checkout</code> script into our code. In React, we can simply do it using the <code>document.body.appendChild(script)</code> code.</p>
<h3 id="heading-initializerazorpay"><strong>initializeRazorpay()</strong></h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> initializeRazorpay = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> script = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"script"</span>);
      script.src = <span class="hljs-string">"https://checkout.razorpay.com/v1/checkout.js"</span>;

      script.onload = <span class="hljs-function">() =&gt;</span> {
        resolve(<span class="hljs-literal">true</span>);
      };
      script.onerror = <span class="hljs-function">() =&gt;</span> {
        resolve(<span class="hljs-literal">false</span>);
      };

      <span class="hljs-built_in">document</span>.body.appendChild(script);
    });
  };
</code></pre>
<p>Now, we are using a promise to achieve this task. We do this because later on, we are going to use the <code>initializeRazorpay()</code> in such a way that every time <code>Purchase Now</code> is clicked, the payments are initialised. We simply have to <code>await</code> this function to create and append a script into the DOM.  </p>
<p>Let's look at the main function which is responsible for creating and initializing payments on the page.</p>
<h3 id="heading-makepayment-function"><strong>makePayment() function</strong></h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> makePayment = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> initializeRazorpay();

    <span class="hljs-keyword">if</span> (!res) {
      alert(<span class="hljs-string">"Razorpay SDK Failed to load"</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Make API call to the serverless API</span>
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/razorpay"</span>, { <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span> }).then(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span>
      t.json()
    );
    <span class="hljs-built_in">console</span>.log(data);
    <span class="hljs-keyword">var</span> options = {
      <span class="hljs-attr">key</span>: process.env.RAZORPAY_KEY, <span class="hljs-comment">// Enter the Key ID generated from the Dashboard</span>
      <span class="hljs-attr">name</span>: <span class="hljs-string">"Manu Arora Pvt Ltd"</span>,
      <span class="hljs-attr">currency</span>: data.currency,
      <span class="hljs-attr">amount</span>: data.amount,
      <span class="hljs-attr">order_id</span>: data.id,
      <span class="hljs-attr">description</span>: <span class="hljs-string">"Thankyou for your test donation"</span>,
      <span class="hljs-attr">image</span>: <span class="hljs-string">"https://manuarora.in/logo.png"</span>,
      <span class="hljs-attr">handler</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
        <span class="hljs-comment">// Validate payment at server - using webhooks is a better idea.</span>
        alert(response.razorpay_payment_id);
        alert(response.razorpay_order_id);
        alert(response.razorpay_signature);
      },
      <span class="hljs-attr">prefill</span>: {
        <span class="hljs-attr">name</span>: <span class="hljs-string">"Manu Arora"</span>,
        <span class="hljs-attr">email</span>: <span class="hljs-string">"manuarorawork@gmail.com"</span>,
        <span class="hljs-attr">contact</span>: <span class="hljs-string">"9999999999"</span>,
      },
    };

    <span class="hljs-keyword">const</span> paymentObject = <span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.Razorpay(options);
    paymentObject.open();
  };
</code></pre>
<p>The <code>makePayment()</code> method is responsible for initialising and opening the Razorpay popup.</p>
<p>The <code>makePayment()</code> function does the following operations:</p>
<ol>
<li>Initializes the Razorpay Checkout script and appends it to the body. This was handled by the <code>initializeRazorpay</code> method as we saw earlier.</li>
<li>Makes a call to the <code>/api/razorpay.js</code> serverless function. (This we will talk about in a minute).</li>
<li><p>Creates an Object which has 4 important keys:</p>
<ol>
<li><code>currency</code> - The currency in which we want the transaction to happen</li>
<li><code>amount</code> - The amount in which the transaction has to happen. Note that it has to be the smallest denomination. Example if you're from the USA, then the amount will be in cents.</li>
<li><code>order_id</code> - This will be generated from the serverless API which we are going to talk about in a minute.</li>
<li><code>handler</code> -  When the payments are successful, this callback function is called.</li>
</ol>
</li>
<li><p>Finally, a <code>paymentObject</code> is created with the <code>options</code> passed down as the parameters to the <code>window.Razorpay</code> method. This is available to us because of the <code>checkout</code> script that we looked at before.</p>
</li>
</ol>
<p>We looked at the above <code>makePayment()</code> method and saw a line of code which is:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/razorpay"</span>, { <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span> }).then(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span>
      t.json()
    );
</code></pre>
<p>But what does it mean?</p>
<p>Next.js allows us to access serverless functions with the help of <code>apis</code> that are available to us in the <code>api</code> folder within Next.js.</p>
<p>The serverless APIs are nothing but <code>Lambda Functions</code> that act as a back-end for our JAMStack applications. Here, we can write our back-end related code easily without having to create a separate back-end.</p>
<p>Here, we need serverless because the <code>order_id</code> that we saw in the <code>makePayments()</code> code is unique and has to be generated at the backend. Not only this but the <code>amount</code> and <code>currency</code> also comes from the backend. This is to ensure that no one can manipulate the amount and the currency and the portal is secure for payments.</p>
<p>Let's have a look at the serverless API code and understand it better.</p>
<h3 id="heading-apirazorpayjs"><strong>/api/razorpay.js</strong></h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Razorpay = <span class="hljs-built_in">require</span>(<span class="hljs-string">"razorpay"</span>);
<span class="hljs-keyword">const</span> shortid = <span class="hljs-built_in">require</span>(<span class="hljs-string">"shortid"</span>);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req, res</span>) </span>{
  <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">"POST"</span>) {
    <span class="hljs-comment">// Initialize razorpay object</span>
    <span class="hljs-keyword">const</span> razorpay = <span class="hljs-keyword">new</span> Razorpay({
      <span class="hljs-attr">key_id</span>: process.env.RAZORPAY_KEY,
      <span class="hljs-attr">key_secret</span>: process.env.RAZORPAY_SECRET,
    });

    <span class="hljs-comment">// Create an order -&gt; generate the OrderID -&gt; Send it to the Front-end</span>
    <span class="hljs-keyword">const</span> payment_capture = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">const</span> amount = <span class="hljs-number">499</span>;
    <span class="hljs-keyword">const</span> currency = <span class="hljs-string">"INR"</span>;
    <span class="hljs-keyword">const</span> options = {
      <span class="hljs-attr">amount</span>: (amount * <span class="hljs-number">100</span>).toString(),
      currency,
      <span class="hljs-attr">receipt</span>: shortid.generate(),
      payment_capture,
    };

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> razorpay.orders.create(options);
      res.status(<span class="hljs-number">200</span>).json({
        <span class="hljs-attr">id</span>: response.id,
        <span class="hljs-attr">currency</span>: response.currency,
        <span class="hljs-attr">amount</span>: response.amount,
      });
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">console</span>.log(err);
      res.status(<span class="hljs-number">400</span>).json(err);
    }
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Handle any other HTTP method</span>
  }
}
</code></pre>
<p>This of <code>razorpay.js</code> as your route which leads to <code>/api/razorpay</code>. Every file you create in the API folder becomes a serverless route. Just like we create APIs in the back-end, we create files here in the APIs folder which becomes a route for us.  </p>
<p>For example: let's say you create a file in the <code>/api</code> folder named <code>posts.js</code>. So the route will become <code>/api/posts</code> which can return anything you want depending upon the use case.  </p>
<p>For our case, we need to make a <code>POST</code> request to our back-end that will create an <code>order_id</code> for us along with <code>amount</code> and <code>currency</code> that can be returned to the front-end for making payments.  </p>
<p>Let's understand the flow for this API.</p>
<ol>
<li>First we need to install the <code>razorpay</code> module along with <code>shortid</code> for generating short unique ids. To do that, head over to your terminal and write <code>npm install razorpay</code> and <code>npm install shortid</code></li>
<li>Now, to access a <code>POST</code> request, we check the request object and access the method by using the below snippet:</li>
</ol>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req, res</span>) </span>{
  <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">"POST"</span>) {
    <span class="hljs-comment">// Initialize razorpay object</span>
    <span class="hljs-keyword">const</span> razorpay = <span class="hljs-keyword">new</span> Razorpay({
      <span class="hljs-attr">key_id</span>: process.env.RAZORPAY_KEY,
      <span class="hljs-attr">key_secret</span>: process.env.RAZORPAY_SECRET,
    });

    <span class="hljs-comment">// rest of the code...</span>
}
</code></pre>
<ol start="3">
<li><p>Here, <code>request.method</code> checks for the method. If the method is <code>POST</code> we go ahead and initialize the Razorpay object.</p>
</li>
<li><p>The Razorpay object takes in 2 parameters: <code>key_id</code> and <code>key_secret</code>. Remember when we downloaded the keys from Razorpay dashboard? Let's put them to use.</p>
</li>
<li><p>Open/create the <code>.env</code> file in your folder structure's root and paste the following code:</p>
</li>
</ol>
<pre><code class="lang-js">RAZORPAY_KEY=YOUR_KEY_HERE
RAZORPAY_SECRET=YOUR_SECRET_HERE
</code></pre>
<p>Here, you can plug in your API key and secret and you will be good to go.</p>
<p>Note: Make sure you restart your development server – otherwise the changes won't be reflected.</p>
<p>Once the <code>razorpay</code> object is setup, it takes in three important options: <code>receipt</code>, <code>amount</code> and <code>currency</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> payment_capture = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">const</span> amount = <span class="hljs-number">499</span>;
    <span class="hljs-keyword">const</span> currency = <span class="hljs-string">"INR"</span>;
<span class="hljs-keyword">const</span> options = {
      <span class="hljs-attr">amount</span>: (amount * <span class="hljs-number">100</span>).toString(),
      currency,
      <span class="hljs-attr">receipt</span>: shortid.generate(),
    };
</code></pre>
<p>Note that amount and currency are being declared in our <code>back-end</code> so that there's no way for attackers to tamper with it.</p>
<p>Once the options are setup, we can create orders with Razorpay's <code>_razorpay_._orders_.create(options)</code> method.</p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> razorpay.orders.create(options);
      res.status(<span class="hljs-number">200</span>).json({
        <span class="hljs-attr">id</span>: response.id,
        <span class="hljs-attr">currency</span>: response.currency,
        <span class="hljs-attr">amount</span>: response.amount,
      });
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">console</span>.log(err);
      res.status(<span class="hljs-number">400</span>).json(err);
    }
</code></pre>
<p>Here, we simply <code>await</code> the <code>create()</code> method provided by Razorpay. When the create method is successful, we get an <code>id</code> which is nothing but the <code>order_id</code> that we need to supply to the front-end in order to generate unique payments.  </p>
<p>Once everything is successful, we send a <code>200 response</code> with <code>id</code>, <code>currency</code> and <code>amount</code> fields. This is all what is required by the front-end to process payments.</p>
<h2 id="heading-how-to-make-payments-with-razorpay"><strong>How to Make Payments with Razorpay</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-21-at-1.14.41-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once everything is integrated and is in place, we can start using Razorpay's charging methods – there are various options available. With this, you can start charging for your services and products by simply accepting payments on your website.</p>
<p>The whole popup is customisable and can be edited directly from Razorpay's dashboard portal.  </p>
<p>Since you're in Test mode, to start using their services in production, you need to complete their Identification process by submitting your proof documents and simply toggle between <code>test mode</code> and <code>live mode</code>. </p>
<p>That's all you need to do from the coding side to make the transition from test to live.</p>
<h2 id="heading-environment-variables"><strong>Environment Variables</strong></h2>
<p>To make sure that our changes are reflected in our live production website, we need to add the same environment variables that we added in the code on the Vercel platform as well.  </p>
<p>For that:</p>
<ol>
<li>Head over to Vercel and open your project</li>
<li>Click on <code>settings</code></li>
<li>Click on <code>environment variables</code>.</li>
<li>You will get 2 input fields - Name and Value.</li>
<li>First, enter <code>RAZORPAY_KEY</code> and add the API key</li>
<li>Second, enter <code>RAZORPAY_SECRET</code> and add the secret value</li>
<li>Redeploy the website and you will be able to make payments in the live environment as well.</li>
</ol>
<h2 id="heading-live-demo-and-source-code"><strong>Live Demo and Source Code</strong></h2>
<p>The entire source code for the application can be found <a target="_blank" href="https://github.com/manuarora700/integrate-payments">here</a>.</p>
<p>The live demo of the website is <a target="_blank" href="https://integrate-payments.vercel.app/">here</a>.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Integrating payments is easy, thanks to Razorpay's excellent documentation that is easy to understand.</p>
<p>I enjoyed coding this website and integrating payments. You can also see a snippet of the code at my website: <a target="_blank" href="https://manuarora.in/snippets">Manu Arora's Code Snippets</a></p>
<p>If you liked this blog, try implementing it in your own website so you can reach out to your end-users and make payments an easy task for yourself.</p>
<p>If you'd like to give any feedback, reach out to me at my <a target="_blank" href="https://twitter.com/mannupaaji">Twitter handle</a> or visit my <a target="_blank" href="https://manuarora.in/">Website</a></p>
<p>Also thanks to <a target="_blank" href="https://tailwindmasterkit.com/">Tailwind Master Kit</a> for the beautiful Landing Page UI.  </p>
<p>Happy Coding. :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Serverless Online Payments with Netlify and Stripe ]]>
                </title>
                <description>
                    <![CDATA[ By Alain Perkaz One of the first steps many young startups take is setting up a static web page, perhaps with an email newsletter, to help them build an audience.  As the weeks go by and the MVP is getting further along, the subject of how to handle ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/serverless-online-payments/</link>
                <guid isPermaLink="false">66d45d9ccc7f04d2549a3728</guid>
                
                    <category>
                        <![CDATA[ Netlify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                    <category>
                        <![CDATA[  Single Page Applications  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 17 Nov 2021 20:54:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/11/----1--2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Alain Perkaz</p>
<p>One of the first steps many young startups take is setting up a static web page, perhaps with an email newsletter, to help them build an audience. </p>
<p>As the weeks go by and the MVP is getting further along, the subject of how to handle payments will eventually emerge.</p>
<p>From one-time payments to SaaS subscriptions, supporting online payments can be daunting and time-consuming. This post will introduce you to an easy way to process online payments with Stripe, without any extra infrastructure other than a static web page.</p>
<p>You don't need a custom backend to store the payment information, or cron jobs to send invoices, and there's no need to track customers in a separate database. This is perfect if you are a single-founder or early-stage startup that wants to validate the idea without creating a custom solution.</p>
<p>Sounds good? Let's dive in! 🤿</p>
<h2 id="heading-high-level-overview-of-the-project">High-level overview of the project</h2>
<p>For the sake of this article, we'll define an early-stage startup use case, where this kind of serverless online payment setup will bring the most value (low cost and fast to implement).</p>
<p>Let's imagine our startup idea is to self-publish a book. As the book is being finalized, we would like to open the lifetime access to the book as a pre-sale.</p>
<p>We will need a way to process payments for lifetime access to the book. For this, we'll need a payment processor and perhaps a way to run some logic away from the client (for example, leveraging the payment processor's API).</p>
<h3 id="heading-payment-processor">Payment processor</h3>
<p>There are plenty of payment processors available, each with different terms, support for payment methods, and public APIs. For our serverless online payment processor, we'll use <a target="_blank" href="https://stripe.com/">Stripe</a>. I chose to use Stripe for two reasons:</p>
<p>First, Stripe is an industry-leading payment processor with an excellent API. Their API is extensively documented, and they offer integration SDKs for many languages (JS included). Setting it up is entirely free, and you only pay a small commission per processed transaction.</p>
<p>Second, Stripe offers Stripe Checkout, a free product specifically built to boost conversions and support various payment options. It's dead-simple to integrate and comes with a great UI.</p>
<h3 id="heading-what-about-the-server">What about the server?</h3>
<p>To be clear, Stripe requires some server-side code to generate a session once a user inputs their payment data. The session is available to the developer to perform payment-related operations (without exposing the sensitive payment details).</p>
<p>Before you get really upset with me, let me clarify that we won't need to set up a dedicated server 😅. It may seem a bit contradictory, but Stripe requires that some of the interaction code is in a server-<strong>like</strong> environment (serverless computing to the rescue!).</p>
<p>Luckily for us, this is 2021, and there are quite a few options to execute on-demand server-side code. Most cloud providers offer this functionality (AWS lambdas, Google Cloud cloud functions, Azure functions…you name it).</p>
<p>Since our startup already has a web page, we'll use <a target="_blank" href="https://www.netlify.com/products/functions/">Netlify functions</a>. It will allow us to run the server-side code with almost no extra configuration, and it plays nicely with the existing web page statics. </p>
<p>The paradigm of combining static web assets with on-demand serverless functions is part of the <a target="_blank" href="https://jamstack.org/">JAM Stack</a> (we'll leave that for another post). Keep reading for the detailed instruction on how to set up serverless payments.</p>
<p><img src="https://paper-attachments.dropbox.com/s_16ACAF73564EBCEEB7494C6A4225B10D5BBA9580C5BBD5452113AF0E1E7CCE6B_1635610448861_image.png" alt="Image" width="600" height="400" loading="lazy">
<em>High-level schema of the solution</em></p>
<h1 id="heading-step-by-step-project-setup">Step-by-step project setup</h1>
<p>Great, now that you have a clear picture of the problem space and the tools we'll use to build our solution, let's build it. 🛠</p>
<p>The complete code example is available at <a target="_blank" href="https://github.com/aperkaz/serverless-payments">https://github.com/aperkaz/serverless-payments</a>.</p>
<h3 id="heading-how-to-set-up-netlify">How to set up Netlify</h3>
<p>First, create a <a target="_blank" href="https://www.netlify.com/">Netlify</a> account (if you don't have one already). The free tier is enough for moderate usage, so no need to worry about that. </p>
<p>Netlify provides CI/CD for automated deployments of our webpage and serverless functions by connecting to a Git repo in Github / Gitlab / Bitbucket. So, let's create a repo in one of those providers with your website assets.</p>
<p>Next, install the <a target="_blank" href="https://cli.netlify.com/getting-started/">Netlify CLI</a>. It will ask you some questions and request access to your Netlify and Git repo provider (GitHub in my case).</p>
<p><img src="https://paper-attachments.dropbox.com/s_16ACAF73564EBCEEB7494C6A4225B10D5BBA9580C5BBD5452113AF0E1E7CCE6B_1635614098858_Screenshot+2021-10-30+at+19.14.47.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing the CLI with <code>npm install netlify-cli -g</code></em></p>
<p>At this point, we can push to the repository’s <code>main</code> / <code>master</code> branch, and Netlify will automatically deploy. You can run <code>netlify open</code> in the console to open Netlify’s admin panel, and visit the deployed URL.</p>
<p><img src="https://paper-attachments.dropbox.com/s_16ACAF73564EBCEEB7494C6A4225B10D5BBA9580C5BBD5452113AF0E1E7CCE6B_1635614710558_Screenshot+2021-10-30+at+19.19.40.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Excellent, with the auto-deploy ready, now let's set up Stripe. 💸</p>
<h3 id="heading-how-to-set-up-stripe">How to set up Stripe</h3>
<p>Create an account in Stripe, validate the email, and sign in. Then, <a target="_blank" href="https://stripe.com/docs/keys">generate a set of API keys</a> (Secret key and Publishable key).</p>
<p>You have to be careful with those keys and never commit the Secret key in the code. Since we will need it in our server-side code, we'll keep it as an <a target="_blank" href="https://www.netlify.com/blog/2021/07/12/managing-environment-variables-from-your-terminal-with-netlify-cli/">environment variable</a>.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a new env variable in Netlify</span>
netlify env:<span class="hljs-built_in">set</span> STRIPE_SECRET <span class="hljs-string">"sk_****"</span>

<span class="hljs-comment"># We can access it on our server-side JS code by:</span>
process.env.STRIPE_SECRET
</code></pre>
<p>For the sake of this tutorial, we will use the <a target="_blank" href="https://stripe.com/docs/payments/accept-a-payment?integration=checkout#set-up-stripe">example API keys</a>, but feel free to use your own. If you use your keys, you will need to add products and prices (<a target="_blank" href="https://support.stripe.com/questions/how-to-create-products-and-prices">documentation</a>).</p>
<h3 id="heading-how-to-add-the-serverless-functions">How to add the serverless functions</h3>
<p>Hang on tight – we are almost there! We only need the server-side code to create Stripe Checkout sessions and complete our demo.</p>
<p>First, to make our function accessible from <a target="_blank" href="https://serverless-payments.netlify.app/api/stripe">https://serverless-payments.netlify.app/api/stripe</a>, we need to add some configurations. Let's start by creating the <code>netlify.toml</code> file, on the root of our repo.</p>
<pre><code class="lang-toml"><span class="hljs-section">[build]</span>
  <span class="hljs-attr">command</span> = <span class="hljs-string">"# no build command"</span>
  <span class="hljs-attr">functions</span> = <span class="hljs-string">"netlify/functions"</span>
  <span class="hljs-attr">publish</span> = <span class="hljs-string">"."</span>

<span class="hljs-section">[[redirects]]</span>
  <span class="hljs-attr">from</span> = <span class="hljs-string">'/api/*'</span>
  <span class="hljs-attr">to</span> = <span class="hljs-string">'/.netlify/functions/:splat'</span>
  <span class="hljs-attr">status</span> = <span class="hljs-number">200</span>
</code></pre>
<p>Then, we can add the session creator function. It’s explained <a target="_blank" href="https://stripe.com/docs/payments/accept-a-payment?integration=checkout#set-up-stripe">here</a>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// netlify/function/stripe.js</span>

<span class="hljs-keyword">const</span> stripe = <span class="hljs-built_in">require</span>(<span class="hljs-string">"stripe"</span>)(process.env.STRIPE_SECRET);

<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> (event, context) =&gt; {
  <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> stripe.checkout.sessions.create({
    <span class="hljs-attr">payment_method_types</span>: [<span class="hljs-string">"card"</span>],
    <span class="hljs-attr">line_items</span>: [
      {
        <span class="hljs-attr">price_data</span>: {
          <span class="hljs-attr">currency</span>: <span class="hljs-string">"usd"</span>,
          <span class="hljs-attr">product_data</span>: {
            <span class="hljs-attr">name</span>: <span class="hljs-string">"T-shirt"</span>,
          },
          <span class="hljs-attr">unit_amount</span>: <span class="hljs-number">2000</span>,
        },
        <span class="hljs-attr">quantity</span>: <span class="hljs-number">1</span>,
      },
    ],
    <span class="hljs-attr">mode</span>: <span class="hljs-string">"payment"</span>,
    <span class="hljs-attr">success_url</span>: <span class="hljs-string">"https://serverless-payments.netlify.app/success"</span>,
    <span class="hljs-attr">cancel_url</span>: <span class="hljs-string">"https://serverless-payments.netlify.app/cancel"</span>,
  });
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
      <span class="hljs-attr">id</span>: session.id,
    }),
  };
};
</code></pre>
<p>Now we can call the serverless functions from our JS body with <code>fetch("/api/stripe")</code>. It will scale depending on the load and you only paid for the invocations. Then it will be deployed on every push to <code>main</code>. Sweet! 🍬</p>
<p>For the sake of brevity, I skipped the remaining code in the HTML files that handles the Stripe Checkout callbacks. The code is available <a target="_blank" href="https://github.com/aperkaz/serverless-payments">here</a>.</p>
<p>The complete example is available at <a target="_blank" href="https://serverless-payments.netlify.app/">https://serverless-payments.netlify.app</a> . You can test a successful payment flow by using <code>4242 4242 4242 4242</code> as a credit card number.</p>
<p><img src="https://paper-attachments.dropbox.com/s_16ACAF73564EBCEEB7494C6A4225B10D5BBA9580C5BBD5452113AF0E1E7CCE6B_1635620255253_Screenshot+2021-10-30+at+20.57.20.png" alt="Image" width="600" height="400" loading="lazy">
<em>Stripe Checkout in all its glory, accessible from [our page](https://serverless-payments.netlify.app" rel="noreferrer nofollow noopener)</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Online payments are critical to many online businesses but are often implemented in a rush or are over-engineered. The solution presented above applies to single-page applications, so you may not need a fully-fledged server for handling payments just yet. 🙂</p>
<p>I hope this article helps shed some light on adding payment processing to your existing web pages easily. Sell your product quickly and make customers happy!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ P2P Definition ]]>
                </title>
                <description>
                    <![CDATA[ P2P, or peer-to-peer, is a general term that describes a network or form of communication where two devices communicate directly. Usually when you visit a website, your browser sends a request to a server. The server then sends you back all the files... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/p2p-definition/</link>
                <guid isPermaLink="false">66c35c73c7095d76345eaff4</guid>
                
                    <category>
                        <![CDATA[ network ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tech Terms ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 06 Apr 2021 09:03:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6075550b776bd507fe31ed37.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>P2P, or peer-to-peer, is a general term that describes a network or form of communication where two devices communicate directly.</p>
<p>Usually when you visit a website, your browser sends a request to a server. The server then sends you back all the files (HTML, CSS, images, and so on) for your browser to render the website.</p>
<p>But if the server has a problem, you wouldn't be able to get all those files, and can't visit the site.</p>
<p>In a peer-to-peer network, a bunch of computers connect to each other and all act as small servers. If one computer in a peer-to-peer network goes offline, the other computers can fill in for it.</p>
<p>Several years ago, Spotify was one of the largest peer-to-peer networks. Back then, they leveraged P2P networking as a way to provide their service using their customer's bandwith. Now Spotify uses central servers that they control.</p>
<p>P2P can also be applied to other things like payments. In this context, it means that the payment gets sent directly to the other person. But the payment might still pass through a company's central servers, unlike a P2P network.</p>
<p>For example, if you send $20 to your friend with a P2P payments app like Venmo, they will receive the money instantly. Your friend can then transfer the money from Venmo to their bank account, or send it to someone else.</p>
<p>But if you use a traditional money wiring service, you will need your friend's bank information to send the money directly to their account. Also, the transfer might have fees, and take several days.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is NFC? Near Field Communication Uses, Chips, Tags, and Readers Explained ]]>
                </title>
                <description>
                    <![CDATA[ NFC is everywhere these days. You've probably seen it in your phone settings, or heard about it online. While the use of NFC for things like contactless payments was growing steadily, it exploded early this year due to the Coronavirus pandemic. In th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-nfc-near-field-communication-uses-chips-tags-and-readers-explained/</link>
                <guid isPermaLink="false">66ac883f33a54a9b1a44793a</guid>
                
                    <category>
                        <![CDATA[ finance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fintech ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kristofer Koishigawa ]]>
                </dc:creator>
                <pubDate>Tue, 03 Nov 2020 18:00:12 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9581740569d1a4ca0d5c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>NFC is everywhere these days. You've probably seen it in your phone settings, or heard about it online.</p>
<p>While the use of NFC for things like contactless payments was growing steadily, it exploded early this year due to the Coronavirus pandemic.</p>
<p>In this article we'll go over what NFC is, what it's used for, some creative ways to use NFC, and more.</p>
<h2 id="heading-what-is-nfc-and-how-does-it-work">What is NFC and how does it work?</h2>
<p>NFC stands for near-field communication. It is a standard for devices to communicate with each other wirelessly from a very close distance.</p>
<p>NFC is a subset of another technology called RFID, so let's dig a bit into that before circling back to NFC.</p>
<h3 id="heading-what-is-rfid">What is RFID?</h3>
<p>Radio-frequency identification, or RFID, is a generic term for technologies that use radio waves from a reader to track specific tags. These tags all include an antenna and a tiny chip, and can come in many shapes and sizes. </p>
<p>Highway toll payment devices and those plastic things on clothes and other expensive items in stores are some common examples of RFID tags.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-123.png" alt="Image" width="600" height="400" loading="lazy">
<em>A diagram of an RFID tag. NFC tags look very similar – <a target="_blank" href="https://www.analogictips.com/rfid-tag-and-reader-antennas/">Source</a></em></p>
<p>If you've ever seen those big devices on either side of a store entrance, those are just big RFID readers. They're constantly transmitting radio waves and listening for a response.</p>
<p>So what happens if you try to leave a store and there's still a tag on the item you bought? </p>
<p>Most RFID tags are unpowered, so when the antenna in the tag picks up radio waves from the reader, it generates a small amount of electricity. That electricity activates the chip inside the tag, and it sends a signal with the information stored on the chip back to the reader. </p>
<p>In this case, when the reader receives a signal back from the tag on your item, it sounds an alarm.</p>
<h3 id="heading-how-are-rfid-and-nfc-related">How are RFID and NFC related?</h3>
<p>NFC is a newer, high-frequency version of RFID, and also involves both tags and readers. </p>
<p>NFC's higher frequency means that, while it can transfer data much faster than RFID, it only works from a distance of about 4 cm/1.6 in or less. Meanwhile, RFID works from a distance of up to 12 m/40 ft.</p>
<h2 id="heading-what-is-nfc-used-for">What is NFC used for?</h2>
<p>There are a lot of use cases for NFC, but here are some of the most common you'll see.</p>
<h3 id="heading-contactless-payments">Contactless payments</h3>
<p>These days, the most common thing that NFC is used for is contactless payment. Many newer credit and debit cards include an NFC tag, so you can just hold your card just above a payment terminal rather than swipe or insert it.</p>
<p>Contactless payment enabled credit and debit cards have a symbol on them similar to these:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-124.png" alt="Image" width="600" height="400" loading="lazy">
_Most contactless payment cards will have a similar symbol on the front or back – <a target="_blank" href="https://www.emvco.com/emv_insights_post/contactless-payments-how-emvco-supports-seamless-and-secure-acceptance/">Source</a>_</p>
<p>Most modern phones include an NFC chip, which can act as both an NFC reader/writer and tag. </p>
<p>This chip, paired with a mobile payment app like Google Pay, Apple Pay, and Samsung Pay, means that you might not even need to take your wallet out anymore. </p>
<p>Instead, your phone can act as a virtual NFC tag for your credit or debit card, even if said card doesn't have an actual NFC tag inside it.</p>
<p>Whether you use your contactless card or a mobile payment app, every payment you make involves tokenization for extra security.</p>
<p>Tokenization is when your card's information is used to generate a random, temporary token for each transaction. Then, your card or mobile payment app can send that temporary token safely, rather than transmit your actual card number, name, and other sensitive information.</p>
<p>However you choose to pay, using a contactless payment card, a mobile payment app, or inserting your card's chip are all <a target="_blank" href="https://www.engadget.com/2019-08-29-how-to-make-online-payments-safely-and-securely.html">much safer than the old method of swiping</a>.</p>
<h3 id="heading-interacting-with-products">Interacting with products</h3>
<p>Traditionally RFID is used for tracking inventory in warehouses and stores. But once a product leaves the store, its RFID tag is disabled.</p>
<p>A lot of products now include NFC tags for additional interaction after you leave the store. Nintendo's Amiibo figures are probably the most common recent example of this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-96.png" alt="Image" width="600" height="400" loading="lazy">
<em>If this isn't the cutest NFC tag, I don't know what is – <a target="_blank" href="https://www.nintendo.com/amiibo/detail/detective-pikachu-amiibo/">Source</a></em></p>
<p>When you scan an Amiibo figure with your Nintendo console, you can get special characters, items, or other additional content, depending on the game and figure you use.</p>
<p>Your Nintendo console can also write information back to the NFC tag in your figure, again, depending on the game and figure.</p>
<p>Other companies like Nike have been including NFC tags in things like sports jerseys and sneakers. This allows you to get personalized content based on the product you scan (recent scores for a team, stats for a specific player, and so on), or even check that a product is genuine.</p>
<h3 id="heading-data-transfer">Data transfer</h3>
<p>Unlike RFID, which is typically one-way communication between a reader and a tag, NFC allows for two-way communication.</p>
<p>Some phones are able to use NFC to transfer data like contacts or photos between two devices if you touch them together.</p>
<h2 id="heading-creative-uses-for-nfc">Creative uses for NFC</h2>
<p>One of the coolest things you can do with NFC is buy a pack of tags online and program them to do different things with your phone.</p>
<p>For example, if you're tired of always giving your WiFi password out to guests, you could program an NFC tag to automatically connect to your network. Then, all your guests need to do is make sure NFC is enabled and hold their phones near the tag.</p>
<p>You could also program NFC tags to control different smart devices around your house. You could have a tag that toggles a smart lamp on or off, or one that sets the thermostat. </p>
<p>The commands triggered by the NFC tags can also be personalized to specific devices. For example, if you like the room a bit cooler than your partner, when you scan the thermostat tag it can lower the temperature. But when your partner scans it, it could raise the temperature to their preferred setting.</p>
<p>There are a lot of other interesting ways to use NFC tags to make your life just a little bit easier. Check out this video for more ideas and to see how to program your own NFC tags in both iOS and Android:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/o9WHrX9cvXA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-in-summary">In summary</h2>
<p>Though you might not have heard much about NFC until earlier this year (I certainly hadn't), it will likely become the standard we pay for things. </p>
<p>And considering all the cool stuff you can do with a phone and a pack of NFC tags, it's surprising that NFC isn't more widely adopted.</p>
<p>If you end up programming your own NFC tags, let me know what you did and how you did it over on <a target="_blank" href="https://twitter.com/kriskoishigawa">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build a shopping cart with Vue and Dinero.js ]]>
                </title>
                <description>
                    <![CDATA[ By Sarah Dayan My friend Cory and I chat almost every day, so you can bet he knows about everything going on in my life. But as we were talking the other day, I realized he had no idea how Dinero.js, my latest project, actually works. Like, what you ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-shopping-cart-with-vue-and-dinero-js-22a7dc4c5352/</link>
                <guid isPermaLink="false">66c34fe24f1fc448a3679047</guid>
                
                    <category>
                        <![CDATA[ money ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Vue.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 09 May 2018 17:50:54 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*zXIPhALV594QhOVSEBVRGA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sarah Dayan</p>
<p>My friend <a target="_blank" href="https://twitter.com/corydhmiller">Cory</a> and I chat almost every day, so you can bet he knows about everything going on in my life. But as we were talking the other day, I realized <strong>he had no idea how <a target="_blank" href="https://github.com/sarahdayan/dinero.js">Dinero.js</a>, my latest project, actually works</strong>. Like, what you can do with it.</p>
<p>I paused and realized it may actually not be <em>that</em> obvious. It’s easier, whatever your skill level is, to understand what a smooth scrolling plugin does than what a money library has to offer.</p>
<blockquote>
<p>“Do you see in JavaScript how you can use a Date constructor to store a date and format it later? Or you use Moment.js to create moment objects and how it’s better than storing dates as strings or any other type?</p>
<p>Well, <strong>Dinero.js is like Moment, but for money</strong>. There’s no native way to handle money, and if you try to do it with <code>Number</code> types, you’re going to run into issues. That’s what Dinero.js helps you avoid. It secures your monetary values in objects and allows you to do whatever you need with them.”</p>
</blockquote>
<p>I was happy with my explanation, as Cory started <em>“a-ha”</em>-ing. But I realized one thing had been missing from the beginning. Something that would speak volumes and help anyone understand the benefits of Dinero.js: a <strong>real-world example</strong>.</p>
<p>In this tutorial, we’ll build a <strong>shopping cart</strong>. We’ll use Vue.js to build the component, then integrate Dinero.js to handle all the money stuff.</p>
<p><strong><em>TL;DR:</em></strong> <em>this post goes in-depth in the how and why. It’s designed to help you grasp the core concepts of Dinero.js. If you want to understand the whole thought process, read on. Otherwise you can look at the final code on <a target="_blank" href="https://codesandbox.io/s/ojvmp7ryk5">CodeSandbox</a>.</em></p>
<p>This post assumes you have basic knowledge of Vue.js. If not, first check my tutorial <a target="_blank" href="https://frontstuff.io/build-your-first-vue-js-component">“Build Your First Vue.js Component</a>.” It will equip you with everything you need to go further.</p>
<h3 id="heading-getting-started">Getting started</h3>
<p>For this project, we’ll use <a target="_blank" href="https://github.com/vuejs/vue-cli">vue-cli</a> and the <a target="_blank" href="https://github.com/vuejs-templates/webpack-simple">webpack-simple</a> Vue.js template. If you don’t have vue-cli installed globally on your machine, fire up your terminal and type the following:</p>
<pre><code>npm install -g vue-cli
</code></pre><p>Then:</p>
<pre><code>vue init webpack-simple path/to/my-project
</code></pre><p>You can keep the default options for all questions. When it’s done, navigate to the new directory, install dependencies, and run the project:</p>
<pre><code>cd path/to/my-project npm install npm run dev
</code></pre><p>Webpack will start serving your project on port <code>8080</code> (if available) and open it in your browser.</p>
<h3 id="heading-setting-up-the-htmlcss">Setting up the HTML/CSS</h3>
<p><strong>I won’t get into page structure and styling in this tutorial</strong>, so I invite you to copy/paste the code. Open the <code>App.vue</code> file, and paste the following snippets.</p>
<p>This goes between the <code>&lt;templa</code>te&gt; tags:</p>
<pre><code>&lt;div id=<span class="hljs-string">"app"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart"</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"title"</span>&gt;</span>Order<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"items"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-preview"</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">""</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-thumbnail"</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-title"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-description"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-quantity"</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-price"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>      Subtotal <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>      Shipping <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>      Total <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price cart-total"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre><p>Ant this between the <code>&lt;sty</code>le&gt; tags:</p>
<pre><code>body {  <span class="hljs-attr">margin</span>: <span class="hljs-number">0</span>;  background: #fdca40;  padding: <span class="hljs-number">30</span>px;}
</code></pre><pre><code>.title {  <span class="hljs-attr">display</span>: flex;  justify-content: space-between;  align-items: center;  margin: <span class="hljs-number">0</span>;  text-transform: uppercase;  font-size: <span class="hljs-number">110</span>%;  font-weight: normal;}
</code></pre><pre><code>.items {  <span class="hljs-attr">margin</span>: <span class="hljs-number">0</span>;  padding: <span class="hljs-number">0</span>;  list-style: none;}
</code></pre><pre><code>.cart {  <span class="hljs-attr">background</span>: #fff;  font-family: <span class="hljs-string">'Helvetica Neue'</span>, Arial, sans-serif;  font-size: <span class="hljs-number">16</span>px;  color: #<span class="hljs-number">333</span>a45;  border-radius: <span class="hljs-number">3</span>px;  padding: <span class="hljs-number">30</span>px;}.cart-line {  <span class="hljs-attr">display</span>: flex;  justify-content: space-between;  align-items: center;  margin: <span class="hljs-number">20</span>px <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span>;  font-size: inherit;  font-weight: normal;  color: rgba(<span class="hljs-number">51</span>, <span class="hljs-number">58</span>, <span class="hljs-number">69</span>, <span class="hljs-number">0.8</span>);}.cart-price {  <span class="hljs-attr">color</span>: #<span class="hljs-number">333</span>a45;}.cart-total {  font-size: <span class="hljs-number">130</span>%;}
</code></pre><pre><code>.item {  <span class="hljs-attr">display</span>: flex;  justify-content: space-between;  align-items: center;  padding: <span class="hljs-number">15</span>px <span class="hljs-number">0</span>;  border-bottom: <span class="hljs-number">2</span>px solid rgba(<span class="hljs-number">51</span>, <span class="hljs-number">58</span>, <span class="hljs-number">69</span>, <span class="hljs-number">0.1</span>);}.item-preview {  <span class="hljs-attr">display</span>: flex;  align-items: center;}.item-thumbnail {  margin-right: <span class="hljs-number">20</span>px;  border-radius: <span class="hljs-number">3</span>px;}.item-title {  <span class="hljs-attr">margin</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">10</span>px <span class="hljs-number">0</span>;  font-size: inherit;}.item-description {  <span class="hljs-attr">margin</span>: <span class="hljs-number">0</span>;  color: rgba(<span class="hljs-number">51</span>, <span class="hljs-number">58</span>, <span class="hljs-number">69</span>, <span class="hljs-number">0.6</span>);}.item-quantity {  max-width: <span class="hljs-number">30</span>px;  padding: <span class="hljs-number">8</span>px <span class="hljs-number">12</span>px;  font-size: inherit;  color: rgba(<span class="hljs-number">51</span>, <span class="hljs-number">58</span>, <span class="hljs-number">69</span>, <span class="hljs-number">0.8</span>);  border: <span class="hljs-number">2</span>px solid rgba(<span class="hljs-number">51</span>, <span class="hljs-number">58</span>, <span class="hljs-number">69</span>, <span class="hljs-number">0.1</span>);  border-radius: <span class="hljs-number">3</span>px;  text-align: center;}.item-price {  margin-left: <span class="hljs-number">20</span>px;}
</code></pre><h3 id="heading-adding-data">Adding data</h3>
<p>When you’re dealing with products, you usually retrieve raw data from a database or an API. We can get close by representing it in a separate JSON file, then importing it asynchronously as if we were querying an API.</p>
<p>Let’s create a <code>products.json</code> file in <code>assets/</code> and add the following:</p>
<pre><code>{  <span class="hljs-string">"items"</span>: [    {      <span class="hljs-string">"title"</span>: <span class="hljs-string">"Item 1"</span>,      <span class="hljs-string">"description"</span>: <span class="hljs-string">"A wonderful product"</span>,      <span class="hljs-string">"thumbnail"</span>: <span class="hljs-string">"https://fakeimg.pl/80x80"</span>,      <span class="hljs-string">"quantity"</span>: <span class="hljs-number">1</span>,      <span class="hljs-string">"price"</span>: <span class="hljs-number">20</span>    },    {      <span class="hljs-string">"title"</span>: <span class="hljs-string">"Item 2"</span>,      <span class="hljs-string">"description"</span>: <span class="hljs-string">"A wonderful product"</span>,      <span class="hljs-string">"thumbnail"</span>: <span class="hljs-string">"https://fakeimg.pl/80x80"</span>,      <span class="hljs-string">"quantity"</span>: <span class="hljs-number">1</span>,      <span class="hljs-string">"price"</span>: <span class="hljs-number">15</span>    },    {      <span class="hljs-string">"title"</span>: <span class="hljs-string">"Item 3"</span>,      <span class="hljs-string">"description"</span>: <span class="hljs-string">"A wonderful product"</span>,      <span class="hljs-string">"thumbnail"</span>: <span class="hljs-string">"https://fakeimg.pl/80x80"</span>,      <span class="hljs-string">"quantity"</span>: <span class="hljs-number">2</span>,      <span class="hljs-string">"price"</span>: <span class="hljs-number">10</span>    }  ],  <span class="hljs-string">"shippingPrice"</span>: <span class="hljs-number">20</span>}
</code></pre><p><strong>This is pretty similar to what we would get from a real API:</strong> data as a collection, with titles and text as strings, and quantity and prices as numbers.</p>
<p>We can go back to <code>App.vue</code> and set empty values in <code>data</code>. This will allow the template to initialize while the actual data is being fetched.</p>
<pre><code>data() {  <span class="hljs-keyword">return</span> {    <span class="hljs-attr">data</span>: {      <span class="hljs-attr">items</span>: [],      <span class="hljs-attr">shippingPrice</span>: <span class="hljs-number">0</span>    }  }}
</code></pre><p>Finally, we can fetch data from <code>products.json</code> with an asynchronous request, and update the <code>data</code> property when it’s ready:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...  created() {    fetch(<span class="hljs-string">'./src/assets/products.json'</span>)      .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())      .then(<span class="hljs-function"><span class="hljs-params">json</span> =&gt;</span> (<span class="hljs-built_in">this</span>.data = json))  }}
</code></pre><p>Now let’s populate our template with this data:</p>
<pre><code>&lt;ul <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"items"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">"item.id"</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"item in data.items"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-preview"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">:src</span>=<span class="hljs-string">"item.thumbnail"</span> <span class="hljs-attr">:alt</span>=<span class="hljs-string">"item.title"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-thumbnail"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-title"</span>&gt;</span>{{ item.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-description"</span>&gt;</span>{{ item.description }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-quantity"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item.quantity"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-price"</span>&gt;</span>{{ item.price }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>...<span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>  Shipping  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price"</span>&gt;</span>{{ data.shippingPrice }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>...</span>
</code></pre><p><strong>You should see all the items in your cart.</strong> Now let’s add some computed properties to calculate the subtotal and total:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...  computed: {    getSubtotal() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.data.items.reduce(        <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a + b.price * b.quantity,        <span class="hljs-number">0</span>      )    },    getTotal() {      <span class="hljs-keyword">return</span> (        <span class="hljs-built_in">this</span>.getSubtotal + <span class="hljs-built_in">this</span>.data.shippingPrice      )    }  }}
</code></pre><p>And add them to our template:</p>
<pre><code>&lt;h3 <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-line"</span>&gt;  Subtotal  &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-price"</span>&gt;{{ getSubtotal }}&lt;<span class="hljs-regexp">/span&gt;&lt;/</span>h3&gt;...&lt;h3 <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-line"</span>&gt;  Total  &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-price cart-total"</span>&gt;{{ getTotal }}&lt;<span class="hljs-regexp">/span&gt;&lt;/</span>h3&gt;
</code></pre><p>There we go! Try changing quantities around — you should see the subtotal and total amounts change accordingly.</p>
<p><strong>Now we have a few issues here.</strong> First, we’re only showing amounts, not currencies. Sure, we could hard code them in the template right next to the reactive amounts. But what if we want to make a multi-lingual website? Not all languages format money the same way.</p>
<p>What if we want to show all amounts with two decimal places, for better alignment? You could try and keep all initial amounts as floats by using the <code>toFixed</code> method, but then you’d be working with <code>String</code> types which are a lot harder and less performant when it comes to doing math. Also, that would mean changing data for purely presentational purposes, which never is a good idea. What if you need the same data for other purposes and it requires a different format?</p>
<p>Finally, the current solution is relying on floating point math, <strong>which is a <a target="_blank" href="https://frontstuff.io/how-to-handle-monetary-values-in-javascript">bad idea when it comes to handling money</a></strong>. Try and change a few amounts:</p>
<pre><code>{  <span class="hljs-string">"items"</span>: [    {      ...      <span class="hljs-string">"price"</span>: <span class="hljs-number">20.01</span>    },    {      ...      <span class="hljs-string">"price"</span>: <span class="hljs-number">15.03</span>    },    ...  ]}
</code></pre><p>Now, look at how broken your shopping cart is ? This isn’t some buggy JavaScript behavior, but a <strong>limitation of how we can represent our decimal numbering system with binary machines.</strong> If you do math with floats, you’ll sooner or later encounter those inaccuracies.</p>
<p>The good news is, <strong>we don’t have to use floats to store money</strong>. That’s exactly where Dinero.js comes into play.</p>
<h3 id="heading-dinerojs-a-wrapper-for-money">Dinero.js, a wrapper for money</h3>
<p><strong>Dinero.js is to money what Moment.js is to dates.</strong> It’s a library that lets you create monetary <a target="_blank" href="https://en.wikipedia.org/wiki/Value_object">value objects</a>, manipulate them, ask them questions, and format them. It relies on Martin Fowler’s <a target="_blank" href="https://martinfowler.com/eaaCatalog/money.html">money pattern</a> and helps you solve all common problems caused by floats, primarily by storing amounts in minor currency unit, as integers.</p>
<p>Open up your terminal and install Dinero.js:</p>
<pre><code>npm install dinero.js --save
</code></pre><p>Then import it into <code>App.vue</code>:</p>
<pre><code><span class="hljs-keyword">import</span> Dinero <span class="hljs-keyword">from</span> <span class="hljs-string">'dinero.js'</span>
</code></pre><pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...}
</code></pre><p>You can now create Dinero objects ?</p>
<pre><code><span class="hljs-comment">// returns a Dinero object with an amount of $50Dinero({ amount: 500, currency: 'USD' })</span>
</code></pre><pre><code><span class="hljs-comment">// returns $4,000.00Dinero({ amount: 500 })  .add(Dinero({ amount: 500 }))  .multiply(4)  .toFormat()</span>
</code></pre><p>Let’s create a factory method to turn our <code>price</code> properties into Dinero objects on demand. We have floats with up to two decimal places. This means if we want to turn them into their equivalents in minor currency units (in our case, dollars), <strong>we need to multiply them by 10 to the power of 2</strong>.</p>
<p>We pass the <code>factor</code> as an argument with a default value, so we can use the method with currencies that have different <a target="_blank" href="https://en.wikipedia.org/wiki/ISO_4217#Treatment_of_minor_currency_units_.28the_.22exponent.22.29">exponents</a>.</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...  methods: {    toPrice(amount, factor = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>)) {      <span class="hljs-keyword">return</span> Dinero({ <span class="hljs-attr">amount</span>: amount * factor })    }  }}
</code></pre><p>Dollars are the default currency, so we don’t need to specify it.</p>
<p>Because we’re doing floating point math during the conversion, some calculations may end up as slightly inaccurate floats. That’s easy to fix by rounding the result to the closest integer.</p>
<pre><code>toPrice(amount, factor = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>)) {  <span class="hljs-keyword">return</span> Dinero({ <span class="hljs-attr">amount</span>: <span class="hljs-built_in">Math</span>.round(amount * factor) })}
</code></pre><p>Now we can use <code>toPrice</code> in our computed properties:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...  computed: {    getShippingPrice() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.toPrice(<span class="hljs-built_in">this</span>.data.shippingPrice)    },    getSubtotal() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.data.items.reduce(        <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span>          a.add(            <span class="hljs-built_in">this</span>.toPrice(b.price).multiply(b.quantity)          ),        Dinero()      )    },    getTotal() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.getSubtotal.add(<span class="hljs-built_in">this</span>.getShippingPrice)    }  }}
</code></pre><p>And in our template:</p>
<pre><code>&lt;ul <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"items"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">"item.id"</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"item in data.items"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-preview"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">:src</span>=<span class="hljs-string">"item.thumbnail"</span> <span class="hljs-attr">:alt</span>=<span class="hljs-string">"item.title"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-thumbnail"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-title"</span>&gt;</span>{{ item.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-description"</span>&gt;</span>{{ item.description }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-quantity"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item.quantity"</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-price"</span>&gt;</span>{{ toPrice(item.price) }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>  Subtotal  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price"</span>&gt;</span>{{ getSubtotal }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>  Shipping  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price"</span>&gt;</span>{{ getShippingPrice }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-line"</span>&gt;</span>  Total  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cart-price cart-total"</span>&gt;</span>{{ getTotal }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span></span>
</code></pre><p>If you look at your shopping cart, you’ll see <code>{}</code> in place of prices. That’s because we’re trying to display an object. Instead, <strong>we need to format them so they can display prices with the right syntax</strong>, alongside their currency symbol.</p>
<p>We can achieve that with Dinero’s <code>[toFormat](https://sarahdayan.github.io/dinero.js/module-Dinero.html#~toFormat)</code> <a target="_blank" href="https://sarahdayan.github.io/dinero.js/module-Dinero.html#~toFormat">method</a>.</p>
<pre><code>&lt;ul <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"items"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">"item.id"</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"item in data.items"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>    ...    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>      ...      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-price"</span>&gt;</span>        {{ toPrice(item.price).toFormat() }}      <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>&lt;<span class="hljs-regexp">/ul&gt;&lt;h3 class="cart-line"&gt;  Subtotal  &lt;span class="cart-price"&gt;    {{ getSubtotal.toFormat() }}  &lt;/</span>span&gt;&lt;<span class="hljs-regexp">/h3&gt;&lt;h3 class="cart-line"&gt;  Shipping  &lt;span class="cart-price"&gt;    {{ getShippingPrice.toFormat() }}  &lt;/</span>span&gt;&lt;<span class="hljs-regexp">/h3&gt;&lt;h3 class="cart-line"&gt;  Total  &lt;span class="cart-price cart-total"&gt;    {{ getTotal.toFormat() }}  &lt;/</span>span&gt;&lt;/h3&gt;
</code></pre><p>Look in your browser: <strong>you now have a well-formatted, fully functional shopping cart</strong> ?</p>
<h3 id="heading-going-further">Going further</h3>
<p>Now that you have a good grasp of the basics of Dinero.js, time to raise the bar a little.</p>
<h4 id="heading-presentation">Presentation</h4>
<p>Let’s change <code>shippingPrice</code> to <code>0</code> in the JSON file. Your cart should now display <em>“Shipping: $0.00”</em>, which is accurate but not user-friendly. Wouldn’t it be nicer for it to say <em>“Free”</em>?</p>
<p>Fortunately, Dinero.js has a plenty of handy methods to ask questions to your instances. In our case, the <code>[isZero](https://sarahdayan.github.io/dinero.js/module-Dinero.html#~isZero)</code> <a target="_blank" href="https://sarahdayan.github.io/dinero.js/module-Dinero.html#~isZero">method</a> is exactly what we need.</p>
<p>In the template, you can display text instead of a formatted Dinero object whenever it represents zero:</p>
<pre><code>&lt;h3 <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-line"</span>&gt;  Shipping  &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-price"</span>&gt;    {{      getShippingPrice.isZero() ?      <span class="hljs-string">'Free'</span> :      getShippingPrice.setLocale(getLocale).toFormat()    }}  &lt;<span class="hljs-regexp">/span&gt;&lt;/</span>h3&gt;
</code></pre><p>Of course, you can generalize this behavior by wrapping it in a method. It would take a Dinero object as an argument and return a <code>String</code>. This way, you could show <em>“Free”</em> whenever you try to display a zero amount.</p>
<h4 id="heading-locale-switching">Locale switching</h4>
<p>Imagine you’re making an e-commerce website. You want to accommodate your international audience, so you translate content and add a language switcher. Yet, there’s one detail that may slip your attention: <strong>money formatting also changes depending on the language</strong>. For example, €10.00 in American English translates to 10,00 € in French.</p>
<p>Dinero.js supports international formatting via the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl">I18n API</a>. This lets you display amounts with localized formatting.</p>
<p>Dinero.js is immutable, so we can’t rely on changing <code>[Dinero.globalLocale](https://sarahdayan.github.io/dinero.js/global.html#Globals)</code> to reformat all existing instances. Instead, we need to use the <code>[setLocale](https://sarahdayan.github.io/dinero.js/module-Dinero.html#~setLocale)</code> <a target="_blank" href="https://sarahdayan.github.io/dinero.js/module-Dinero.html#~setLocale">method</a>.</p>
<p>First, we add a new property <code>language</code> in <code>data</code> and set it to a default value. For locales, you need to use a <a target="_blank" href="http://tools.ietf.org/html/rfc5646">BCP 47 language tag</a> such as <code>en-US</code>.</p>
<pre><code>data() {  <span class="hljs-keyword">return</span> {    <span class="hljs-attr">data</span>: {      ...    },    <span class="hljs-attr">language</span>: <span class="hljs-string">'en-US'</span>  }}
</code></pre><p>Now we can use <code>setLocale</code> directly on Dinero objects. When <code>language</code> changes, the formatting will change as well.</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...  methods: {    toPrice(amount, factor = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>)) {      <span class="hljs-keyword">return</span> Dinero({ <span class="hljs-attr">amount</span>: <span class="hljs-built_in">Math</span>.round(amount * factor) })        .setLocale(<span class="hljs-built_in">this</span>.language)    }  },  <span class="hljs-attr">computed</span>: {    ...    getSubtotal() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.data.items.reduce(        <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span>          a.add(            <span class="hljs-built_in">this</span>.toPrice(b.price).multiply(b.quantity)          ),        Dinero().setLocale(<span class="hljs-built_in">this</span>.language)      )    },    ...  }}
</code></pre><p>All we need is to add <code>setLocale</code> in <code>toPrice</code> and <code>getSubtotal</code>, the only places where we’re creating Dinero objects.</p>
<p>Now we can add our language switcher:</p>
<pre><code><span class="hljs-comment">// HTML&lt;h1 class="title"&gt;  Order  &lt;span&gt;    &lt;span class="language" @click="language = 'en-US'"&gt;English&lt;/span&gt;    &lt;span class="language" @click="language = 'fr-FR'"&gt;French&lt;/span&gt;  &lt;/span&gt;&lt;/h1&gt;</span>
</code></pre><pre><code><span class="hljs-comment">// CSS.language {  margin: 0 2px;  font-size: 60%;  color: rgba(#333a45, 0.6);  text-decoration: underline;  cursor: pointer;}</span>
</code></pre><p>When you click on the switcher, it will reassign <code>language</code>, which will change how the objects are formatted. Because the library is immutable, this will return new objects instead of changing existing ones. It means if you create a Dinero object and decide to display it somewhere, then reference it somewhere else and apply a <code>setLocale</code> on it, <strong>your initial instance won’t be affected</strong>. No pesky side effects!</p>
<h4 id="heading-all-tax-included">All tax included</h4>
<p>It’s common to see a tax line on shopping carts. You can add one with Dinero.js, using the <code>[percentage](https://sarahdayan.github.io/dinero.js/module-Dinero.html#~percentage)</code> <a target="_blank" href="https://sarahdayan.github.io/dinero.js/module-Dinero.html#~percentage">method</a>.</p>
<p>First, let’s add a <code>vatRate</code> property in the JSON file:</p>
<pre><code>{  ...  <span class="hljs-string">"vatRate"</span>: <span class="hljs-number">20</span>}
</code></pre><p>And an initial value in <code>data</code>:</p>
<pre><code>data() {  <span class="hljs-keyword">return</span> {    <span class="hljs-attr">data</span>: {      ...      vatRate: <span class="hljs-number">0</span>    }  }}
</code></pre><p>Now we can use this value to calculate the total of our cart with tax. First, we need to create a <code>getTaxAmount</code> computed property. We can then add it to <code>getTotal</code> as well.</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  ...  computed: {    getTaxAmount() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.getSubtotal.percentage(<span class="hljs-built_in">this</span>.data.vatRate)    },    getTotal() {      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.getSubtotal        .add(<span class="hljs-built_in">this</span>.getTaxAmount)        .add(<span class="hljs-built_in">this</span>.getShippingPrice)    }  }}
</code></pre><p>The shopping cart now shows the total with tax. We can also add a line to show what the tax amount is:</p>
<pre><code>&lt;h3 <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-line"</span>&gt;  VAT ({{ data.vatRate }}%)  &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"cart-price"</span>&gt;{{ getTaxAmount.toFormat() }}&lt;<span class="hljs-regexp">/span&gt;&lt;/</span>h3&gt;
</code></pre><p>And we’re done! We’ve explored several concepts of Dinero.js, but that’s only scratching the surface of what it has to offer. You can <a target="_blank" href="https://sarahdayan.github.io/dinero.js">read through the documentation</a> and check out the project on <a target="_blank" href="https://github.com/sarahdayan/dinero.js">GitHub</a>. Star it, fork it, send me feedback, or even open a pull request! I have a nice little <a target="_blank" href="https://github.com/sarahdayan/dinero.js/blob/master/CONTRIBUTING.md">contributing guide</a> to help you get started.</p>
<p>You can also look at the final code on <a target="_blank" href="https://codesandbox.io/s/ojvmp7ryk5">CodeSandbox</a>.</p>
<p>I’m currently working on bringing a <code>convert</code> method to Dinero.js, as well as better support for all <a target="_blank" href="https://en.wikipedia.org/wiki/ISO_4217">ISO 4217 currencies</a> and cryptos. You can stay tuned by following me on <a target="_blank" href="https://twitter.com/frontstuff_io">Twitter</a>.</p>
<p>Happy coding! ??‍?</p>
<p><em>Originally published at <a target="_blank" href="https://frontstuff.io/build-a-shopping-cart-with-vue-and-dinerojs">frontstuff.io</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
