iamraphson / vue-paystack

Paystack Vue Plugin for Vue 2.X

Home Page:https://www.npmjs.com/package/vue-paystack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

window is not defined

devshittu opened this issue · comments

Just trying out this plugin on my nuxtjs app I got "Reference Error! window is not defined" in "node_modules/vue-paystack/dist/paystack.min.js", please anyone with a workaround this?

The plugin is probable being rendered server side.

Try adding it like this: { src: "~/plugins/vue-paystack", ssr: false },

@devshittu

Were you able to get it to work?
I am using NuxtJS and I am having the same issues.

create a vue-paystack file in your plugins folder directory then import paystack like this:
import Vue from 'vue'
import paystack from 'vue-paystack'
Vue.use(paystack)

in your nuxt.config.js
set this { src: "~/plugins/vue-paystack", ssr: false } in your plugins array
then import paystack as component like this:
import paystack from 'vue-paystack/src'

Tried the above solution and still not working. Somehow it still gets rendered server side.
My error logs:

2021-09-17T15:10:48.630182Z ERROR window is not defined

2021-09-17T15:10:48.630214Z

2021-09-17T15:10:48.630224Z at Object.<anonymous> (node_modules/vue-paystack/dist/paystack.min.js:1:280)

2021-09-17T15:10:48.630233Z at Module.o._compile (node_modules/jiti/dist/v8cache.js:2:2778)
 
2021-09-17T15:10:48.630244Z at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
 
2021-09-17T15:10:48.630264Z at Module.load (internal/modules/cjs/loader.js:937:32)
 
2021-09-17T15:10:48.630274Z at Function.Module._load (internal/modules/cjs/loader.js:778:12)
 
2021-09-17T15:10:48.630282Z at Module.require (internal/modules/cjs/loader.js:961:19)
 
2021-09-17T15:10:48.630290Z at n (node_modules/jiti/dist/v8cache.js:2:2472)
 
2021-09-17T15:10:48.630301Z at node_modules/vue-server-renderer/build.prod.js:1:77944
 
2021-09-17T15:10:48.630310Z at Object.<anonymous> (webpack:/external "vue-paystack":1:0)
 
2021-09-17T15:10:48.630318Z at __webpack_require__ (webpack/bootstrap:25:0)

@marvelefe can you share your Nuxt Config?

@marvelefe for next.js if this lib does not work, you can use this https://www.npmjs.com/package/nuxt-paystack

@Devdre1909 My plugins array in Nuxt Config:

......other plugins above
    {src: '~/plugins/mixitup.js', mode: 'client' },
    {src: '~/plugins/vue-paystack.js', mode: 'client' },
    {src: '~/plugins/moment.js', mode: 'client' }  
  ],

I'm using Nuxt @iamraphson

@marvelefe try that package. Any issue, let me know. Thanks

Aii. Package looks good. Thanks @iamraphson

pls help out on step by step on how to use this paystack on nuxt app

@devshittu

Were you able to get it to work? I am using NuxtJS and I am having the same issues.

Yes I did boss

I was able to get it to work in my app. If you need further help can you reproduce a repo to show what you are getting then we can collaborate and resolve this together.

Hi, i am getting this error on next.js
page file
`
"use client"
import { ChevronRight } from "react-feather"
import { useRouter } from "next/navigation"
import { useContext, useEffect, useState } from "react"
import Image from "next/image"
import { RegisterForm } from "@/components/auth"
import { BtnMain, LoadingBtn, RegisterInput } from "@/components/shared"
import { FormProvider, useForm } from "react-hook-form"
import {
OrderInformationInterface,
DrugItemInterface,
UploadPrescriptionInterface,
deliveryInformationSchema,
uploadPrescriptionSchema,
} from "@/utils"
import { userService } from "@/services"
import { toast } from "@/components/ui/use-toast"
import { useShoppingCart } from "@/providers/ShoppingCartContext"
import CartItem from "@/components/CartItem"
import { CurrentUserContext } from "@/providers/CurrentUserProvider"
import { Telemetry } from "next/dist/telemetry/storage"
import { ToastAction } from "@/components/ui/toast"
import Payment from "@/components/Payment"

const Upload: React.FC<{}> = () => {
const router = useRouter()

const { currentUser } = useContext(CurrentUserContext)

const [file, setFile] = useState(null)

const [isLoading, setIsLoading] = useState(false)

const goBack = () => {
router.push("/")
}
const { clearCart, removeFromCart, cartItems } = useShoppingCart()

const [cartItemsWithDetails, setCartItemsWithDetails] = useState<
DrugItemInterface[]

([])

const [currentStep, setCurrentStep] = useState(1)

useEffect(() => {
const fetchData = async () => {
const updatedCartItems: DrugItemInterface[] = []
for (const item of cartItems) {
const data = await userService.getDrugItemsByID(item.id)
updatedCartItems.push({ ...data.data, quantity: item.quantity })
}
setCartItemsWithDetails(updatedCartItems)
}

fetchData()

}, [cartItems])

return (




Home



Cart






Shopping Cart


    {currentStep === 1 && (
      <div className=' flex  items-start gap-10  w-full'>
        <div className=' min-w-full  '>
          <div className=' flex pb-6 border-b border-b-[#F4F0F2] w-full '>
            <h3 className=' font-semibold text-t-14 text-left  basis-1/3   '>
              Item
            </h3>
            <h3 className=' font-semibold text-t-14 text-left  basis-2/3  '></h3>
            <h3 className=' font-semibold text-t-14 text-left    basis-1/4  '>
              Price
            </h3>
            <h3 className=' font-semibold text-t-14 text-left   basis-1/6   '>
              Qty
            </h3>
            <h3 className=' font-semibold text-t-14 text-left   basis-1/3  '>
              Subtotal
            </h3>
            <div className=' basis-1/12 '></div>
          </div>
          {cartItems.map((item) => (
            <CartItem key={item.id} {...item} />
          ))}
          {cartItems.length === 0 && (
            <div className='flex justify-center items-center w-full h-40'>
              <p className='text-t-32 text-[#676063] font-bold '>
                No items in cart
              </p>
            </div>
          )}

          <div className=' flex flex-col lg:flex-row gap-2 max-w-[500px] mt-6  '>
            <BtnMain
              btnText='Continue Shopping '
              btnStyle=' flex-1 border-[#0060AF] border-[2px] text-[#0060AF] font-semiBold py-[7px] rounded-full '
              onClick={() => router.push("/")}
            />
            <BtnMain
              btnText='Clear Shopping Cart'
              btnStyle=' flex-1 bg-[#5F5F5F] text-white font-semiBold rounded-full py-[7px] '
              onClick={() => clearCart()}
            />
            <BtnMain
              btnText='Checkout'
              btnStyle=' flex-1 bg-secondary-pink text-white font-semiBold rounded-full py-[7px] '
              onClick={() => setCurrentStep(2)}
            />
          </div>
        </div>
      </div>
    )}

    {currentStep === 2 && <Payment />}
  </div>
  cart
</div>

)
}

export default Upload

`

component file
`import React, { useEffect, useState } from "react"
import { FormProvider, useForm } from "react-hook-form"
import { BtnMain, LoadingBtn, RegisterInput } from "@/components/shared"
import Image from "next/image"
import { useShoppingCart } from "@/providers/ShoppingCartContext"
import { toast } from "@/components/ui/use-toast"
import { ToastAction } from "@/components/ui/toast"
import { yupResolver } from "@hookform/resolvers/yup"
import { deliveryInformationSchema } from "@/utils"
import PaystackPop from "@paystack/inline-js"
import { userService } from "@/services"
import { useRouter } from "next/navigation"

export default function Payment() {
const paystack = typeof window !== "undefined" && new PaystackPop()
const router = useRouter()

const methods = useForm({
defaultValues: {
email: "",
firstName: "",
lastName: "",
phonenumber: "",
streetAddress: "",
city: "Lagos",
state: "Lagos",
country: "Nigeria",
},
resolver: yupResolver(deliveryInformationSchema),
mode: "onChange",
})

const deliveryPrice = 1000

const [cartItemsWithDetails, setCartItemsWithDetails] = useState([])
const { clearCart, removeFromCart, cartItems } = useShoppingCart()

useEffect(() => {
const fetchData = async () => {
const updatedCartItems = []
for (const item of cartItems) {
const data = await userService.getDrugItemsByID(item.id)
updatedCartItems.push({ ...data.data, quantity: item.quantity })
}
setCartItemsWithDetails(updatedCartItems)
}

fetchData()

}, [cartItems])

const handleSubmit = async (data) => {
if (!userService.userValue) {
toast({
title: "Error",
description: Please Login to make payment,
variant: "destructive",
style: {
backgroundColor: "#f44336",
color: "#fff",
top: "20px",
right: "20px",
},
action: (
<ToastAction
altText='Accept Terms and conditions'
onClick={() => router.push("/login")}
>
Login

),
})
}
try {
const orderData = {
items: cartItemsWithDetails.map((item) => ({
drugItemId: item.id,
quantity: item.quantity,
})),
state: data.state,
address: data.streetAddress,
fullName: ${data.firstName} ${data.lastName},
phonenumber: data.phonenumber,
email: data.email,
discountCode: "0",
}
console.log(orderData)
const response = await userService.createOrder(orderData)
if (response) {
if (typeof window !== "undefined") {
paystack.newTransaction({
key: process.env.NEXT_PUBLIC_PAYSTACKKEY,
email: data.email,
amount: response.data.amount,
reference: response.data.reference,
onSuccess: (transaction) => {
clearCart()
router.push(/order/success)
},
onCancel: () => {
router.push(/cart)
},
})
}
}
} catch (error) {}
}

const totalPrice = cartItemsWithDetails.reduce((acc, item) => {
return acc + item.price * item.quantity
}, 0)

return (


<FormProvider {...methods}>




Summary








We currently deliver to LAGOS ONLY.

          <RegisterInput
            name='firstName'
            inputPlaceholder='Enter full name'
            label=' First name'
          />
          <RegisterInput
            name='lastName'
            inputPlaceholder='Enter full name'
            label=' Last name'
          />
          <RegisterInput
            name='email'
            inputPlaceholder='Enter email address'
            label=' Email address'
          />
          <div className='   flex flex-col gap-2'>
            <RegisterInput
              name={`phonenumber`}
              inputPlaceholder='080 0000 0000'
              extraClass={`mt-6`}
              label='Phone Number'
              onInput={(e) => {
                e.currentTarget.value = e.currentTarget.value.replace(
                  /[^0-9]/g,
                  ""
                )
              }}
              maxLength={11}
            />
            <span className=' text-t-12 text-secondary-pink  '>
              We currently deliver to LAGOS ONLY.
            </span>
          </div>
          <RegisterInput
            name='streetAddress'
            inputPlaceholder='Enter address'
            label=' Street Address'
          />
          <RegisterInput
            name='city'
            inputPlaceholder='Enter city'
            label=' City'
            disabled
          />
        </div>

        <div
          className=' bg-white  p-4 flex
             flex-col gap-2  my-6 '
        >
          <h3 className=' text-t-14 font-semibold  '>Delivery Fee</h3>

          <div className=' flex items-start gap-4 '>
            <Image
              src={`/assets/icons/delivery.svg`}
              width={24}
              height={24}
              alt=''
            />
            <span className=' text-t-12 lg:text-t-14 '>
              Our flat-rate delivery fee for your selected address/state is{" "}
              <span className=' font-bold '>
                {" "}
                &#8358;
                {deliveryPrice?.toLocaleString("en-us", {
                  style: "decimal",
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                })}
              </span>
              . Our customer service will contact you.{" "}
            </span>
          </div>
        </div>

        <div className=' gap-6 flex flex-col '>
          <div className=' flex flex-col gap-6  '>
            <div className=' flex justify-between text-t-14 font-semibold  '>
              {" "}
              <span className=''> Subtotal </span>{" "}
              <span className=''>
                {" "}
                &#8358;
                {totalPrice?.toLocaleString("en-us", {
                  style: "decimal",
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                })}{" "}
              </span>{" "}
            </div>
            <div className=' flex justify-between text-t-14 font-semibold  '>
              {" "}
              <span className=''> Delivery fee </span>{" "}
              <span className=''>
                {" "}
                &#8358;
                {deliveryPrice?.toLocaleString("en-us", {
                  style: "decimal",
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                })}
              </span>{" "}
            </div>
          </div>
          <BtnMain
            btnText={`Proceed to Pay ( ₦${(
              deliveryPrice + totalPrice
            )?.toLocaleString("en-us", {
              style: "decimal",
              minimumFractionDigits: 2,
              maximumFractionDigits: 2,
            })})`}
            btnStyle=' mb-8 w-full bg-secondary-pink text-white font-semibold   rounded-full py-4'
            type='submit'
          />
        </div>
      </div>{" "}
    </form>
  </FormProvider>
</div>

)
}
`