Stripe Checkout 问题(Nextjs 和 Django)

问题描述 投票:0回答:1

我正在尝试使用 stripe 在 nextjs 中创建一个支付页面。如果我 guendo 指南它工作正常,但我不想使用表单来调用

/create-checkout-session
端点,但我想在 div 上使用 onClick 函数来使用 axios 进行调用。

前端代码

'use client';
import React, {useEffect, useState} from 'react';
import Container from "@/components/Container";
import axios from "axios";

const PagamentiPage = () => {

    const data = {
        product_id: 1,
        price: 599,
        name: "Test",
        description: "lorem ipsum dolor sit amet consectetur adipisicing elit.",
    }

    return (
        <Container>
            <div className="product">
                <img
                    src="https://i.imgur.com/EHyR2nP.png"
                    alt="The cover of Stubborn Attachments"
                />
                <div className="description">
                    <h3>{data.name}</h3>
                    <h5>Price: {data.price/100} €</h5>
                </div>
            </div>
            <form
                action="http://127.0.0.1:8000/pagamenti/create-checkout-session"
                method="POST"
            >
                <input type="hidden" name="product_id" value={1}/>
                <input type="hidden" name="price" value={70000}/>
                <input type="hidden" name="name" value={"Test"}/>
                <input type="hidden" name="description" value={"Frf"}/>
                <input
                    type="hidden"
                    name="username"
                    value={"Federiko98"}
                />
                <button type={"submit"} className={"bg-red-300 p-2 rounded"}>
                    Checkout
                </button>
            </form>
        </Container>
    );
};

export default PagamentiPage;

后端代码

class StripeCheckoutView(APIView):
    def post(self, request, *args, **kwargs):
        data = request.data
        try:
            checkout_session = stripe.checkout.Session.create(
                line_items=[{
                    'price_data': {
                        'currency': 'eur',
                        'unit_amount': data.get("price"),  # centesimi
                        'product_data': {
                            'name': data.get("name"),
                            'description': data.get("description"),
                        },
                    },
                    'quantity': 1,
                }],
                metadata={
                    'username': data.get("username"),
                    'product_id': data.get("product_id"),
                },
                mode='payment',
                success_url=f'{YOUR_DOMAIN}?success=true',
                cancel_url=f'{YOUR_DOMAIN}?canceled=true',
            )
            return redirect(checkout_session.url)
        except Exception as e:
            return Response(
                {'error': f"Errore {e}"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

在这种情况下它有效,因为我正在使用表单向后端发出请求。

如果我尝试创建一个像这样的 onClick 函数。

const PagamentiPage = () => {

    const data = {
        product_id: 1,
        price: 599,
        name: "Test",
        description: "lorem ipsum dolor sit amet consectetur adipisicing elit.",
    }

    const handleClick = async () => {
        axios.post(`http://127.0.0.1:8000/pagamenti/create-checkout-session`, data).then((res) => {
            console.log(res);
        }).catch((err) => {
            console.log(err);
        })
    }

    return (
        <Container>
            <div className="product">
                <img
                    src="https://i.imgur.com/EHyR2nP.png"
                    alt="The cover of Stubborn Attachments"
                />
                <div className="description">
                    <h3>{data.name}</h3>
                    <h5>Price: {data.price / 100} €</h5>
                </div>
            </div>
            <div onClick={handleClick}>
                Checkout
            </div>
        </Container>
    );
};

export default PagamentiPage;

我收到以下错误返回:

Blocked multi-origin request (cross-origin): the origin matching policy does not allow reading the remote resource from https://checkout.stripe.com/c/pay/cs_test_a1eRHeGL4xxJiduP9byAbmJkNpWxVSDnpJhpugqmVUsKvT0vDw74my6Mib6#fidkdWxOYHwnPyd1blpxYHZxWjA0SGc3MWBNPXNtdUZAclNDTXRJd2NcbEM2bmZVSVxJNE1idWZXcl9GbTFvRG0xQjBLbE9xQmN9f0BsT2dBTFF%2FTFE1SDZnT1x9Z1IyaGx2f2xzQ29%2FQTdfNTU0a2JBXGJsRCcpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl.

但是我的 django cors 配置允许访问所有内容,因为我正在使用:

CORS_ALLOW_ALL_ORIGINS = True

我想找到一种通过 onClick 函数进行此调用的方法,因为我需要通过表单请求不支持的标头在请求中发送身份验证令牌。

我还想在请求中发送自定义正文

reactjs django next.js stripe-payments checkout
1个回答
0
投票

看起来您正在使用 Django REST Framework (DRF) 作为后端。当您使用 DRF UI 时,

redirect(checkout_session.url)
方法有效,因为它的行为类似于服务器渲染的 Django 页面,具有服务器端重定向(返回 HTTP 状态 302 并告诉您的浏览器要去哪里)。但实际的 REST API 并不是这样工作的,它只是返回数据,并由您的 Next.js 代码决定如何处理该数据。

我使用 DRF 作为后端,使用 Nuxt.js 作为前端。创建结帐会话时,我从结帐会话返回 URL,然后在 JavScript 代码中执行重定向,如下所示:

后端

# apis.py
class CheckoutView(APIView):
...
try:
    session = stripe.checkout.Session.create(**checkout_kwargs)
    return Response(data={'url': session.url}, status=200)
except Exception as ex:
    return Response(data={'error': str(ex)}, status=400)

前端

const {url, error} = await this.$axios.$post('/checkout_sessions/', payload)
if (error) {
   console.error(error)
   this.processing = false
} else {
   window.location.replace(url)
}

这应该允许您执行重定向而不会遇到 CORS 错误。

© www.soinside.com 2019 - 2024. All rights reserved.