我如何创建 Stripe 订阅,并集成 3D Secure,以便它可以在印度使用

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

问题是我无法创建订阅来解决印度付款问题。

当我输入印度的条纹测试卡详细信息时出现错误,它正在安慰这样的事情:

type: 'StripeInvalidRequestError', raw: { message: '由于印度支付法规,如果没有 3DS,卡类型的 PaymentMethods 无法直接附加到客户。请提供 PaymentMeth od 和 Customer,以及带有“setup_future_usag e 参数”的 SetupIntent 或 PaymentIntent。请参阅 https://support.stripe.c om/questions/guide-for- saving-cards-in-ind ia 了解更多详情

订阅表格.tsx


import {

CardElement,

useElements,

useStripe,

} from "@stripe/react-stripe-js";

import React, { useState,  useEffect } from "react";

import axios from "axios";

import Button from "./Button";

import Page from "./Page";

import FormBox from "./FormBox";

import { createCustomer,createProduct, createSubscription,createfull  } from "./api";





interface SubscriptionFormProps {

plan: string;

}



interface  userDataprops{

name: string,

email: string,

PlanId: string,

PlanTitle: string,

PlanPrice: null|number,

paymentMethod: null|string,

}



export default function SubscriptionForm({ plan }: SubscriptionFormProps) {

const [name, setName] = useState("");

const [email, setEmail] = useState("");

const stripe = useStripe();

const elements = useElements();

 const [planPrice,setPlanPrice] = useState<number|null>(null)



useEffect(() => {

 if(plan.charAt(0) === "1"){

 setPlanPrice(99)

}else if(plan.charAt(0) === '2'){

 setPlanPrice(149)

}else{

 setPlanPrice(299)

 }

},[])





const subscribe = async () => {

if (!stripe || !elements) {

 return;

}



const cardElement = elements.getElement(CardElement);



try{

const { error, paymentMethod }

= await stripe.createPaymentMethod({

type: "card",

card: cardElement,

});

if (error) {

 

 alert(error.message)

 return;

}



const { id } = paymentMethod;



const fullResponse = await createfull({

 name: name,

 email: email,

 plan: plan.slice(2),

 planPrice: planPrice,

 stripeToken: id,

})



if(fullResponse.message !== 'Subscription created successfully!') return alert("payment unsuccessful")

const clientSecret = await fullResponse.clientSecret

const confirm = await stripe.confirmCardPayment(clientSecret)

if(confirm.error){

 console.log(confirm.error.message)

 alert(confirm.error.message)

}

alert('payment confirmed')

              

console.log(fullResponse.message)

} catch (error) {

alert(error.message)

}



};

 











return (

 <Page classes={'items-center'}>

   <FormBox>

     <form

       onSubmit={(e) => {

         e.preventDefault();

         subscribe()

       }}

     >

       <span className="font-family-inter flex justify-center p-2 text-4xl font-bold">

         SUBSCRIBE

       </span>

       <div className="flex h-[190px] w-[280px] flex-col items-center justify-around">

         <div className="flex flex-col justify-center">

           <label>Name</label>

           <input

             type="text"

             value={name}

             onChange={(e) => setName(e.target.value)}

             className="mt-1 flex h-[35px] w-[240px] justify-center rounded-sm p-2 text-brand-secondary"

           />

         </div>

         <div className="mt-4 flex flex-col justify-center">

           <label>Email</label>

           <input

             type="email"

             value={email}

             onChange={(e) => setEmail(e.target.value)}

             className="mt-1 flex h-[35px] w-[240px] justify-center rounded-sm p-2 text-brand-secondary"

           />

         </div>

         <div className="mt-4 flex flex-col justify-center">

                     <label >Card Details</label>

 <div className = 'h-[35px] w-[240px] rounded-sm bg-brand-primary p-2 text-brand-secondary '>

   <CardElement />

   </div>

 </div>

       </div>

       <div className="mt-[60px] flex justify-center">

         <Button disable={false}>SUBSCRIBE TO {plan.slice(2)}</Button>

       </div>

     </form>

   </FormBox>

 </Page>

);

}

api.tsx


const response = await fetch("https://dfdfc0c8-b50e-4037-aa34-cea130730c3f-00-3eebp8qm9h0io.sisko.repl.co:3000/create-customer", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify(data),

})



return response.json();



};



export const createProduct = async (data) => {

const response = await fetch("https://dfdfc0c8-b50e-4037-aa34-cea130730c3f-00-3eebp8qm9h0io.sisko.repl.co:3000/create-product", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify(data),

})



return response.json();



};



export const createSubscription = async (data) => {

const response = await fetch("https://dfdfc0c8-b50e-4037-aa34-cea130730c3f-00-3eebp8qm9h0io.sisko.repl.co:3000/create-subscription", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify(data),

})



return response.json();



};



export const createfull = async (data) => {

const response = await fetch("https://dfdfc0c8-b50e-4037-aa34-cea130730c3f-00-3eebp8qm9h0io.sisko.repl.co:3000/full", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify(data),

})



return response.json();



};


订阅.js


import express from 'express';

import cors from 'cors';

import Stripe from 'stripe';



const stripe = new Stripe("sk_test_51P4GkwSIHDx0a39om9wZv8CSOoDsVPGZs7EgaV0pjVOqxGInUV0Ytr0RNkXaAOSjH3THCCfYGzusW8xUZBqL");

const app = express();



let corsOptions = {

origin: '*',

optionsSuccessStatus: 200,

credentials: true,

}



app.use(cors(corsOptions))



app.use(express.json());



app.get('/api',(_,res) => {

res.send("Hello from Browser")

})



app.post("/full", async(req,res) => {

const customer = await stripe.customers.create({

 name: req.body.name,

 email: req.body.email,

 payment_method: req.body.stripeToken,

 invoice_settings: {

     default_payment_method: req.body.stripeToken,

 }

});



const product = await stripe.products.create({

 name: req.body.plan,

});



 const subscription = await stripe.subscriptions.create({

 customer: customer.id,

       items: [

     {

     price_data: {

       currency: 'INR' ,

       product: product.id,

       unit_amount: req.body.planPrice,

       recurring: {

         interval: "month",

       },

     },

    },

   ], 

payment_settings: {

payment_method_types: ['card'],

save_default_payment_method: "on_subscription"

   },

 expand: ["latest_invoice.payment_intent"]  



});



res.json({

message: 'Subscription created successfully!',

clientSecret: subscription.latest_invoice.payment_intent.client_secret,

subscriptionId: subscription.id,

 subscription: subscription,

});



})





app.listen(3000,() => {

console.log("server Started at Port 3000")

})





这就是我的全部代码

我无法为此进行全部设置。我如何修改代码才能使我的代码能够运行并可以轻松处理印度的测试付款?

我已经尝试过chatgpt以及Gemini,也尝试从文档中理解事情,但事情看起来有点复杂,我也使用了一些博客来处理一些事情,但它并没有完全工作,事情仍然是一半,所以如果有人可以帮助并让我了解问题并解决该错误,因此如果有人可以帮助我以正确的方式进行条带订阅集成并在印度可行。

reactjs node.js stripe-payments
1个回答
0
投票

Stripe 有一个详细文档页面,用于将定期付款与印度客户集成。在较高级别上,您需要首先在服务器上使用

payment_behavior: 'default_incomplete'
创建订阅。 根据您是否预先付款,这将使您能够访问
pending_setup_intent
中的 SetupIntent 或
latest_invoice[payment_intent]
中的 PaymentIntent,您可以使用它们在收集卡详细信息的地方呈现 PaymentElement 客户端。

您永远不必自己附加 PaymentMethod,因为这是会给您带来错误的部分。相反,它将作为确认 PaymentIntent 或 SetupIntent 客户端的结果而附加。

或者,您可以使用 Stripe 的新集成路径,首先在客户端创建 PaymentMethod,然后将其附加到订阅服务器端。这记录在本页中。

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