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 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.
If you’re using Nuxt 3 to build your application, you may have noticed that Paystack’s official Vue package is not compatible with Nuxt 3 out of the box. In this article, we’ll show you how to implement a Paystack popup in Nuxt 3 using inline JavaScript.
Prerequisites
Before we begin, you’ll need the following:
- A Paystack account
- A Nuxt 3 project set-up and running
Step 1: Implement the design of your form
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’s data binding and form validation capabilities to facilitate user input and processing.
<template>
<form>
<div>
<label>First Name</label>
<input type="text" />
</div>
<div>
<label>Email Address</label>
<input type="email" required v-model="form.name" />
</div>
<div>
<label>Phone Number</label>
<input
required
v-model="form.phoneNumber"
type="tel"
/>
</div>
<div>
<label>Amount</label>
<input type="number" v-model="form.amount" required />
</div>
<div>
<button>Pay</button>
</div>
</form>
</template>
Step 2: Initialize Form Data and Load Paystack Library
The code sets up the form fields and defines the data structure for the form using an interface named FormType
. It creates a reactive object form
with properties for name
, phoneNumber
, email
, and amount
, initializing them with empty values or a default value of 0.
Moving on to the next step in the process, in your Nuxt 3 JavaScript, you can utilize the onMounted
lifecycle hook to handle the dynamic creation of a <script>
tag. This snippet allows you to set the src
attribute of the <script>
tag to the URL of the Paystack inline JavaScript library. Once the script is created, it can be appended to the <body>
element of the current HTML page. This enables the loading of the Paystack library and facilitates further integration with the payment service.
<script setup lang="ts">
//some codes...
//initialize form data
interface FormType {
name: string;
phoneNumber: string;
email: string;
amount: number;
}
const form = reactive({
name: "",
phoneNumber: "",
email: "",
amount: 0,
} as FormType);
//Load Paystack Library
onMounted(() => {
const script = document.createElement("script");
script.setAttribute("src", "https://js.paystack.co/v1/inline.js");
document.body.appendChild(script);
});
</script>
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 plugin.
Step 3: Linking Form Details to Paystack and Initiating Checkout Popup
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.
const initializePayment = () => {
const handler = PaystackPop.setup({
key: "YOUR_PAYSTACK_PUBLIC_KEY", //Replace with your public key
email: form.email, //replace with user email
amount: form.amount * 100, // the amount value is multiplied by 100 to convert to the lowest currency unit
currency: "NGN", // Use GHS for Ghana Cedis or USD for US Dollars
ref: random, // Replace with a reference you generated
callback: function (response: any) {
//this happens after the payment is completed successfully
var reference = response.reference;
alert("Payment complete! Reference: " + reference);
//this happens after the payment is completed successfully
router.push({
path: "/success",
query: {
name: `${form.name}`,
},
});
// Make an AJAX call to your server with the reference to verify the transaction
},
onClose: function () {
alert("Transaction was not completed, window closed.");
},
});
handler.openIframe();
};
If you have followed these steps correctly, your vue component should be similar to the following code:
<template>
<form>
<div>
<label>First Name</label>
<input type="text" />
</div>
<div>
<label>Email Address</label>
<input type="email" required v-model="form.name" />
</div>
<div>
<label>Phone Number</label>
<input
required
v-model="form.phoneNumber"
type="tel"
/>
</div>
<div>
<label>Amount</label>
<input type="number" v-model="form.amount" required />
</div>
<div>
<button>Pay</button>
</div>
</form>
</template>
<script setup lang="ts">
//some codes...
interface FormType {
name: string;
phoneNumber: string;
email: string;
amount: number;
}
const form = reactive({
name: "",
phoneNumber: "",
email: "",
amount: 0,
} as FormType);
//router allows navigation and manipulation of the application's routing system.
const router = useRouter();
function generateReference(prefix: string): string {
// Function to generate a random transaction reference with a given prefix
const length = 10;
const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let result = prefix;
// Generate random characters and append them to the prefix
for (let i = length; i > 0; --i) {
result += chars[Math.floor(Math.random() * chars.length)];
}
// Return the generated transaction reference
return result;
}
const random: string = generateReference("My Transaction Reference");
const initializePayment = () => {
const handler = PaystackPop.setup({
key: "YOUR_PUBLIC_KEY", //Replace with your public key
email: form.email, //replace with user email
amount: form.amount * 100, // the amount value is multiplied by 100 to convert to the lowest currency unit
currency: "NGN", // Use GHS for Ghana Cedis or USD for US Dollars
ref: random, // Replace with a reference you generated or use the provided function above
callback: function (response: any) {
//this happens after the payment is completed successfully
var reference = response.reference;
alert("Payment complete! Reference: " + reference);
//this happens after the payment is completed successfully
router.push({
path: "/success",
query: {
name: `${form.name}`,
},
});
// Make an AJAX call to your server with the reference to verify the transaction
},
onClose: function () {
alert("Transaction was not completed, window closed.");
},
});
handler.openIframe();
};
onMounted(() => {
const script = document.createElement("script");
script.setAttribute("src", "https://js.paystack.co/v1/inline.js");
document.body.appendChild(script);
});
</script>
Step 4: Trigger the payment function
To proceed with the next step, let’s first recap the initial phase where we implemented the UI design of the form. Now, we’ll enhance its functionality by adding event listeners. To trigger the payment function, you can associate it with the @submit
event of your form in the template like so:
<template>
<form @submit.prevent="initializePayment">
<div>
<label>First Name</label>
<input type="text" />
</div>
<div>
<label>Email Address</label>
<input type="email" required v-model="form.name" />
</div>
<div>
<label>Phone Number</label>
<input
required
v-model="form.phoneNumber"
type="tel"
/>
</div>
<div>
<label>Amount</label>
<input type="number" v-model="form.amount" required />
</div>
<div>
<button type="submit">Pay</button>
</div>
</form>
</template>
In the updated form code snippet above, the following changes have been made:
- The
@submit.prevent="initializePayment"
event listener has been added to the<form>
tag. This ensures that theinitializePayment
method is called when the form is submitted, preventing the default form submission behavior. - The
<button>
element has been updated with thetype="submit"
attribute. This specifies that the button acts as a submit button within the form and triggers the form submission when clicked.
Other than these changes, the structure and form fields remain the same as the previously shared code.
Conclusion
To sum up, we’ve covered the implementation of the Paystack popup in Nuxt 3 using inline JavaScript. This approach enables you to overcome compatibility problems with Paystack’s official Vue package and effectively integrate the Paystack payment service into your Nuxt 3 project.
To learn more about PayStack pop-up, visit the official documentation and also feel free to ask your questions by commenting below.