{"id":296,"date":"2023-05-19T16:58:13","date_gmt":"2023-05-19T15:58:13","guid":{"rendered":"https:\/\/chigisoft.com\/blog\/?p=296"},"modified":"2023-07-15T14:29:23","modified_gmt":"2023-07-15T13:29:23","slug":"how-to-implement-paystack-popup-in-nuxt-3","status":"publish","type":"post","link":"https:\/\/chigisoft.com\/blog\/how-to-implement-paystack-popup-in-nuxt-3\/","title":{"rendered":"How to implement Paystack popup in Nuxt 3"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"512\" src=\"https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-1024x512.jpg\" alt=\"\" class=\"wp-image-297\" srcset=\"https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-1024x512.jpg 1024w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-300x150.jpg 300w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-768x384.jpg 768w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-1536x768.jpg 1536w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-2048x1024.jpg 2048w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-390x195.jpg 390w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-820x410.jpg 820w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack-1180x590.jpg 1180w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/04\/NuxtPaystack.jpg 2400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>When building an e-commerce <a href=\"https:\/\/chigisoft.com\/blog\/4-reasons-for-website-speed\/\" data-type=\"post\" data-id=\"151\">website<\/a> or any other application that requires online payments, Paystack is always the first option that comes to mind and is often the preferred payment processing platform. It is a popular payment gateway in Nigeria and in many other African countries. Paystack provides an easy-to-use API that allows you to accept payments from your customers securely.<\/p>\n\n\n\n<p>If you&#8217;re using Nuxt 3 to build your application, you may have noticed that Paystack&#8217;s official Vue package is not compatible with Nuxt 3 out of the box. In this article, we&#8217;ll show you how to implement a Paystack popup in Nuxt 3 using inline JavaScript.<\/p>\n\n\n\n<h4 id=\"prerequisites\" class=\"wp-block-heading\" style=\"line-height:0\"><strong>Prerequisites<\/strong><\/h4>\n\n\n\n<p>Before we begin, you&#8217;ll need the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"line-height:1.5\">A Paystack account<\/li>\n\n\n\n<li style=\"line-height:1.5\">A Nuxt 3 project set-up and running<\/li>\n<\/ul>\n\n\n\n<h4 id=\"step-1-implement-the-design-of-your-form\" class=\"wp-block-heading\">Step 1: Implement the design of your form<\/h4>\n\n\n\n<p>The code below is a simple HTML template, it sets up a basic form for collecting user information, including the first name, email address, phone number, and payment amount. It uses Vue.js&#8217;s data binding and form validation capabilities to facilitate user input and processing.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n  &lt;form&gt;\n    &lt;div&gt;\n      &lt;label&gt;First Name&lt;\/label&gt;\n      &lt;input type=\"text\" \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Email Address&lt;\/label&gt;\n      &lt;input type=\"email\" required v-model=\"form.name\" \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Phone Number&lt;\/label&gt;\n      &lt;input\n        required\n        v-model=\"form.phoneNumber\"\n        type=\"tel\"\n      \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Amount&lt;\/label&gt;\n      &lt;input type=\"number\" v-model=\"form.amount\" required \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;button&gt;Pay&lt;\/button&gt;\n    &lt;\/div&gt;\n  &lt;\/form&gt;\n&lt;\/template&gt;<\/code><\/pre>\n\n\n\n<h4 id=\"step-2-initialize-form-data-and-load-paystack-library\" class=\"wp-block-heading\">Step 2: Initialize Form Data and Load Paystack Library<\/h4>\n\n\n\n<p>The code sets up the form fields and defines the data structure for the form using an interface named <code>FormType<\/code>. It creates a reactive object <code>form<\/code> with properties for <code>name<\/code>, <code>phoneNumber<\/code>, <code>email<\/code>, and <code>amount<\/code>, initializing them with empty values or a default value of 0.<\/p>\n\n\n\n<p>Moving on to the next step in the process, in your Nuxt 3 JavaScript, you can utilize the <code>onMounted<\/code> lifecycle hook to handle the dynamic creation of a <code>&lt;script&gt;<\/code> tag. This snippet allows you to set the <code>src<\/code> attribute of the <code>&lt;script&gt;<\/code> tag to the URL of the Paystack inline JavaScript library. Once the script is created, it can be appended to the <code>&lt;body&gt;<\/code> element of the current HTML page. This enables the loading of the Paystack library and facilitates further integration with the payment service.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script setup lang=\"ts\"&gt;\n\n\/\/some codes...\n\n\/\/initialize form data \ninterface FormType {\n  name: string;\n  phoneNumber: string;\n  email: string;\n  amount: number;\n}\nconst form = reactive({\n  name: \"\",\n  phoneNumber: \"\",\n  email: \"\",\n  amount: 0,\n} as FormType);\n\n\n\/\/Load Paystack Library\nonMounted(() =&gt; {\n  const script = document.createElement(\"script\");\n  script.setAttribute(\"src\", \"https:\/\/js.paystack.co\/v1\/inline.js\");\n  document.body.appendChild(script);\n});\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p><em>NOTE The code snippet above will only load the Paystack inline script dynamically for the component where it is used. If you want to make the script available globally across your Nuxt 3 application, you can add it to the head section of your HTML file by creating a <mark style=\"background-color:#ffeed7\" class=\"has-inline-color has-luminous-vivid-orange-color\">plugin<\/mark>.<\/em><\/p>\n\n\n\n<h4 id=\"step-3-linking-form-details-to-paystack-and-initiating-checkout-popup\" class=\"wp-block-heading\">Step 3: Linking Form Details to Paystack and Initiating Checkout Popup<\/h4>\n\n\n\n<p>After obtaining all the necessary transaction details from the form, the subsequent step involves linking them to a JavaScript function that transfers the details to Paystack and presents the checkout popup modal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const initializePayment = () =&gt; {\n  const handler = PaystackPop.setup({\n    key: \"YOUR_PAYSTACK_PUBLIC_KEY\", \/\/Replace with your public key\n    email: form.email, \/\/replace with user email\n    amount: form.amount * 100, \/\/ the amount value is multiplied by 100 to convert to the lowest currency unit\n\n    currency: \"NGN\", \/\/ Use GHS for Ghana Cedis or USD for US Dollars\n\n    ref: random, \/\/ Replace with a reference you generated\n    callback: function (response: any) {\n      \/\/this happens after the payment is completed successfully\n      var reference = response.reference;\n      alert(\"Payment complete! Reference: \" + reference);\n\n      \/\/this happens after the payment is completed successfully\n      router.push({\n        path: \"\/success\",\n        query: {\n          name: `${form.name}`,\n        },\n      });\n      \/\/ Make an AJAX call to your server with the reference to verify the transaction\n    },\n    onClose: function () {\n      alert(\"Transaction was not completed, window closed.\");\n    },\n  });\n  handler.openIframe();\n};<\/code><\/pre>\n\n\n\n<p>If you have followed these steps correctly, your <mark style=\"background-color:#ffeed7\" class=\"has-inline-color has-luminous-vivid-orange-color\">vue component<\/mark> should be similar to the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n  &lt;form&gt;\n    &lt;div&gt;\n      &lt;label&gt;First Name&lt;\/label&gt;\n      &lt;input type=\"text\" \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Email Address&lt;\/label&gt;\n      &lt;input type=\"email\" required v-model=\"form.name\" \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Phone Number&lt;\/label&gt;\n      &lt;input\n        required\n        v-model=\"form.phoneNumber\"\n        type=\"tel\"\n      \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Amount&lt;\/label&gt;\n      &lt;input type=\"number\" v-model=\"form.amount\" required \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;button&gt;Pay&lt;\/button&gt;\n    &lt;\/div&gt;\n  &lt;\/form&gt;\n&lt;\/template&gt;\n\n&lt;script setup lang=\"ts\"&gt;\n\/\/some codes...\n\ninterface FormType {\n  name: string;\n  phoneNumber: string;\n  email: string;\n  amount: number;\n}\nconst form = reactive({\n  name: \"\",\n  phoneNumber: \"\",\n  email: \"\",\n  amount: 0,\n} as FormType);\n\n\/\/router allows navigation and manipulation of the application's routing system.\nconst router = useRouter();\n\n\nfunction generateReference(prefix: string): string {\n  \/\/ Function to generate a random transaction reference with a given prefix\n  const length = 10;\n  const chars = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n  let result = prefix;\n\n  \/\/ Generate random characters and append them to the prefix\n  for (let i = length; i &gt; 0; --i) {\n    result += chars&#91;Math.floor(Math.random() * chars.length)];\n  }\n\n  \/\/ Return the generated transaction reference\n  return result;\n}\n\nconst random: string = generateReference(\"My Transaction Reference\");\n\nconst initializePayment = () =&gt; {\n  const handler = PaystackPop.setup({\n    key: \"YOUR_PUBLIC_KEY\", \/\/Replace with your public key\n    email: form.email, \/\/replace with user email\n    amount: form.amount * 100, \/\/ the amount value is multiplied by 100 to convert to the lowest currency unit\n\n    currency: \"NGN\", \/\/ Use GHS for Ghana Cedis or USD for US Dollars\n\n    ref: random, \/\/ Replace with a reference you generated or use the provided function above\n    callback: function (response: any) {\n      \/\/this happens after the payment is completed successfully\n      var reference = response.reference;\n      alert(\"Payment complete! Reference: \" + reference);\n\n      \/\/this happens after the payment is completed successfully\n      router.push({\n        path: \"\/success\",\n        query: {\n          name: `${form.name}`,\n        },\n      });\n      \/\/ Make an AJAX call to your server with the reference to verify the transaction\n    },\n    onClose: function () {\n      alert(\"Transaction was not completed, window closed.\");\n    },\n  });\n  handler.openIframe();\n};\n\nonMounted(() =&gt; {\n  const script = document.createElement(\"script\");\n  script.setAttribute(\"src\", \"https:\/\/js.paystack.co\/v1\/inline.js\");\n  document.body.appendChild(script);\n});\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<h4 id=\"step-4-trigger-the-payment-function\" class=\"wp-block-heading\"><strong>Step 4: Trigger the payment function<\/strong><\/h4>\n\n\n\n<p>To proceed with the next step, let&#8217;s first recap the initial phase where we implemented the UI design of the form. Now, we&#8217;ll enhance its functionality by adding event listeners. To trigger the payment function, you can associate it with the <code>@submit<\/code> event of your form in the template like so:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n  &lt;form @submit.prevent=\"initializePayment\"&gt;\n    &lt;div&gt;\n      &lt;label&gt;First Name&lt;\/label&gt;\n      &lt;input type=\"text\" \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Email Address&lt;\/label&gt;\n      &lt;input type=\"email\" required v-model=\"form.name\" \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Phone Number&lt;\/label&gt;\n      &lt;input\n        required\n        v-model=\"form.phoneNumber\"\n        type=\"tel\"\n      \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;label&gt;Amount&lt;\/label&gt;\n      &lt;input type=\"number\" v-model=\"form.amount\" required \/&gt;\n    &lt;\/div&gt;\n    &lt;div&gt;\n      &lt;button type=\"submit\"&gt;Pay&lt;\/button&gt;\n    &lt;\/div&gt;\n  &lt;\/form&gt;\n&lt;\/template&gt;\n\n\n<\/code><\/pre>\n\n\n\n<p>In the updated form code snippet above, the following changes have been made:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The <code>@submit.prevent=\"initializePayment\"<\/code> event listener has been added to the <code>&lt;form&gt;<\/code> tag. This ensures that the <code>initializePayment<\/code> method is called when the form is submitted, preventing the default form submission behavior.<\/li>\n\n\n\n<li>The <code>&lt;button&gt;<\/code> element has been updated with the <code>type=\"submit\"<\/code> attribute. This specifies that the button acts as a submit button within the form and triggers the form submission when clicked.<\/li>\n<\/ol>\n\n\n\n<p>Other than these changes, the structure and form fields remain the same as the previously shared code.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/learn.chigisoft.com\/product-design\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"414\" data-id=\"506\" src=\"https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-1024x414.png\" alt=\"\" class=\"wp-image-506\" srcset=\"https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-1024x414.png 1024w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-300x121.png 300w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-768x310.png 768w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-390x158.png 390w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-820x331.png 820w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1-1180x477.png 1180w, https:\/\/chigisoft.com\/blog\/wp-content\/uploads\/2023\/07\/Product-Bootcamp-Registration-2023-1.png 1332w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/figure>\n\n\n\n<h4 id=\"conclusion\" class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h4>\n\n\n\n<p>To sum up, we&#8217;ve covered the implementation of the Paystack popup in Nuxt 3 using inline JavaScript. This approach enables you to overcome compatibility problems with Paystack&#8217;s official Vue package and effectively integrate the Paystack payment service into your Nuxt 3 project.<\/p>\n\n\n\n<p>To learn more about PayStack pop-up, visit the&nbsp;<a href=\"https:\/\/paystack.com\/docs\/payments\/accept-payments\/\" target=\"_blank\" data-type=\"URL\" data-id=\"https:\/\/paystack.com\/docs\/payments\/accept-payments\/\" rel=\"noreferrer noopener\">official documentation<\/a>&nbsp;and also feel free to ask your questions by commenting below.<\/p>\n","protected":false},"excerpt":{"rendered":"When building an e-commerce website or any other application that requires online payments, Paystack is always the first option that comes to mind and is often the preferred payment processing&hellip;\n","protected":false},"author":8,"featured_media":297,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13,6],"tags":[78,76,77,18,51,69],"class_list":{"0":"post-296","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-tech","8":"category-code","9":"tag-nuxt-paystack","10":"tag-nuxt3","11":"tag-paystack","12":"tag-softwaredevelopment","13":"tag-tech","14":"tag-typescript"},"_links":{"self":[{"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":6,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"predecessor-version":[{"id":508,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions\/508"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/media\/297"}],"wp:attachment":[{"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chigisoft.com\/blog\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}