Search code examples
reactjsnext.jsreact-context

How to get data from Context API in getstaticprops function?


I'm making payment function for my static e-commerce Next.js app.

For payment I've several stages:

  1. Making cart page with shipping information form and button "Pay" which redirect to /payment page;
  2. On /payment page I connect with my payment service and need to get cart info from Context API, but I can't use Context API in getStaticProps it's my problem. Payment page needs just get cart data and redirects on external service payment form.

Code for page /payment is below:

import { useEffect, useContext } from "react"
import QiwiBillPaymentsAPI from "@qiwi/bill-payments-node-js-sdk"

import { CartContext } from "@/context/GlobalState"

export default function Payment ({ payUrl }) {
    useEffect(() => window.location.assign(payUrl))
    return (
        <span>Redirect</span>
    )
}


export async function getStaticProps() {
    const qiwiApi = new QiwiBillPaymentsAPI(process.env.QIWI_SECRET_KEY)

    const { state, dispatch } = useContext(CartContext)
    const { cart } = state

    const billId = qiwiApi.generateId()
    const lifetime = qiwiApi.getLifetimeByDay(1);
    const fields = {
        amount: 1.00,
        currency: "RUB",
        expirationDateTime: lifetime,
    }

    const payment_data = await qiwiApi.createBill( billId, fields )
    const payUrl = payment_data.payUrl

    return { props: { payUrl }}
}

Please, help me with any ideas.


Solution

  • Possible solution!

    I've made API Route with code from my getStaticProps function (it gets total price and make query to payment service, then it return payment url). Code of api route is below:

    import QiwiBillPaymentsAPI from "@qiwi/bill-payments-node-js-sdk"
    
    export default async function handler(req, res) {
        const { 
            query: { total },
        } = req
    
        const qiwiApi = new QiwiBillPaymentsAPI(process.env.QIWI_SECRET_KEY)
        const billId = qiwiApi.generateId()
        const lifetime = qiwiApi.getLifetimeByDay(1);
        const fields = {
            amount: total,
            currency: "RUB",
            expirationDateTime: lifetime,
        }
    
        const payment_data = await qiwiApi.createBill( billId, fields )
        const payUrl = payment_data.payUrl
    
        res.json({ url: payUrl })
    }
    

    Then /payment page code (do query to my API route and get payment url, then redirect to payment form):

    export default function Payment () {
        const { state, dispatch } = useContext(CartContext)
        const { cart } = state
    
        const fetcher = (...args) => fetch(...args).then(res => res.json())
    
        const { data, error } = useSWR(`/api/qiwi-pay?total=${cart.total}`, fetcher)
    
        if (error) return <div>failed to load</div>
        if (!data) return <div>loading...</div>
    
        window.location.assign(data.url)
    
        return (
            <>
                <span>Redirect to payment form.</span>
            </>
        )
    }
    

    This approach works very well!