![](/img/trans.png)
[英]Stripe jQuery validation - how to verify a validate of an entered coupon?
[英]Stripe coupon validation
我希望用户能够在有优惠券的情况下添加优惠券,并且通过按下按钮,代码应该检查优惠券是否存在于我的 Stripe 仪表板中。 到目前为止,我已经这样做了(见下面的代码),我想我并没有遗漏太多,但我想不出一种方法来将 validCoupon 从客户端发送到服务器端,并且他们能够在那里应用折扣。
Cart.js(客户端)
import React, {useRef, useState} from 'react';
import Link from 'next/link';
import {AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping} from 'react-icons/ai';
import {TiDeleteOutline} from 'react-icons/ti';
import toast from 'react-hot-toast';
import {useStateContext} from '../context/StateContext';
import {urlFor} from '../lib/client';
import getStripe from '../lib/getStripe';
const Cart = () => {
const cartRef = useRef();
const {
totalPrice,
totalQuantities,
cartItems,
setShowCart,
toggleCartItemQuanitity,
onRemove
} = useStateContext();
const [coupontext, setCouponText] = useState('');
const [isCouponAdded, setisCouponAdded] = useState(false);
const [validCoupon, setValidCoupon] = useState("");
const handleChange = (event) => {
setCouponText(event.target.value);
};
const checkCoupon = async () => {
if(!isCouponAdded){
const response = await fetch('https://api.stripe.com/v1/coupons', {
headers: {
'Authorization': `Bearer ${process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY}`
}
});
if (!response.ok) {
toast.error("Error fetching coupons");
return;
}
const {data} = await response.json();
const validcoupon = data.find((c) => c.id === coupontext);
if (validcoupon) {
toast.success("Coupon is valid!");
setValidCoupon(validcoupon);
setisCouponAdded(true);
} else {
toast.error("Coupon is invalid!");
}
}else{
toast.success("Coupon already added!");
}
}
const handleCheckout = async () => {
const stripeClient = await getStripe();
const response = await fetch('/api/stripe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(cartItems)
});
if (response.statusCode === 500)
return;
const data = await response.json();
toast.loading('Redirecting...');
stripeClient.redirectToCheckout({sessionId: data.id});
}
.....
页面/api/stripe.js
import Stripe from 'stripe';
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY);
export default async function handler(req, res) {
if (req.method === 'POST') {
try {
const params = {
submit_type: 'pay',
mode: 'payment',
payment_method_types: ['card'],
billing_address_collection: 'auto',
shipping_address_collection: {
allowed_countries: ["PT"],
},
shipping_options: [
{ shipping_rate: 'shr_1MMq2YJFNgzNJo7sbwDNnqhz' },
{ shipping_rate: "shr_1MMq3iJFNgzNJo7s2nVvfATq"}
],
line_items: req.body.map((item) => {
const img = item.image[0].asset._ref;
const newImage = img.replace('image-', 'https://cdn.sanity.io/images/REDACTED/production/').replace('-png', '.png');
return {
price_data: {
currency: 'eur',
product_data: {
name: item.name,
images: [newImage],
},
unit_amount: item.price * 100,
},
adjustable_quantity: {
enabled:true,
minimum: 1,
},
quantity: item.quantity
}
}),
success_url: `${req.headers.origin}/success`,
cancel_url: `${req.headers.origin}/`,
}
// Create Checkout Sessions from body params.
const session = await stripe.checkout.sessions.create(params);
res.status(200).json(session);
} catch (err) {
res.status(err.statusCode || 500).json(err.message);
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
//////////////////////////////////////// 更新 ///////// ///////////////////////////////
好的,现在我将 validCoupon object 添加到 cartsItems 并传入正文。 在服务器端,我遇到了问题,因为从来没有应用过折扣,我不知道为什么,但我觉得我真的很接近解决这个问题,只是缺少一些简单的东西。
购物车.js
import React, {useRef, useState} from 'react';
import Link from 'next/link';
import {AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping} from 'react-icons/ai';
import {TiDeleteOutline} from 'react-icons/ti';
import toast from 'react-hot-toast';
import {useStateContext} from '../context/StateContext';
import {urlFor} from '../lib/client';
import getStripe from '../lib/getStripe';
const Cart = () => {
const cartRef = useRef();
const {
totalPrice,
totalQuantities,
cartItems,
setShowCart,
toggleCartItemQuanitity,
onRemove
} = useStateContext();
const [coupontext, setCouponText] = useState('');
const [isCouponAdded, setisCouponAdded] = useState(false);
const [validCoupon, setValidCoupon] = useState(null);
const handleChange = (event) => {
setCouponText(event.target.value);
};
const checkCoupon = async () => {
if(!isCouponAdded){
const response = await fetch('https://api.stripe.com/v1/coupons', {
headers: {
'Authorization': `Bearer ${process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY}`
}
});
if (!response.ok) {
toast.error("Error fetching coupons");
return;
}
const {data} = await response.json();
console.log(data);
const validcoupon = data.find((c) => c.id === coupontext);
if (validcoupon) {
toast.success("Coupon is valid!");
setValidCoupon(validcoupon);
setisCouponAdded(true);
} else {
toast.error("Coupon is invalid!");
}
}else{
toast.success("Coupon already added!");
}
}
const handleCheckout = async () => {
const stripeClient = await getStripe();
cartItems['validCoupon'] = validCoupon;
console.log(cartItems);
const response = await fetch('/api/stripe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(cartItems)
});
if (response.statusCode === 500)
return;
const data = await response.json();
toast.loading('Redirecting...');
stripeClient.redirectToCheckout({sessionId: data.id});
}
页面/api/stripe.js
import Stripe from 'stripe';
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY);
export default async function handler(req, res) {
if (req.method === 'POST') {
try {
const discounts = [];
if(req.body.validCoupon && req.body.validCoupon.id) {
discounts.push({coupon: req.body.validCoupon.id});
}
let shipping_options = [];
const line_items = req.body;
let total_amount = 0;
for (const item of line_items) {
total_amount += item.price * item.quantity;
}
if (total_amount >= 40) {
shipping_options = [
{ shipping_rate: 'shr_1MMq3iJFNgzNJo7s2nVvfATq' },
];
} else {
shipping_options = [
{ shipping_rate: "shr_1MMq2YJFNgzNJo7sbwDNnqhz"}
];
}
const params = {
submit_type: 'pay',
mode: 'payment',
discounts: discounts,
payment_method_types: ['card'],
billing_address_collection: 'auto',
shipping_address_collection: {
allowed_countries: ["PT"],
},
shipping_options: shipping_options,
line_items: req.body.map((item) => {
const img = item.image[0].asset._ref;
const newImage = img.replace('image-', 'https://cdn.sanity.io/images/REDACTED/production/').replace('-png', '.png');
return {
price_data: {
currency: 'eur',
product_data: {
name: item.name,
images: [newImage],
},
unit_amount: item.price * 100,
},
quantity: item.quantity
}
}),
success_url: `${req.headers.origin}/success`,
cancel_url: `${req.headers.origin}/`,
}
// Create Checkout Sessions from body params.
const session = await stripe.checkout.sessions.create(params);
res.status(200).json(session);
} catch (err) {
res.status(err.statusCode || 500).json(err.message);
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
您需要通过将优惠券添加到 cartItems 将优惠券传递给服务器,并且需要在 session 参数中传递discount
数组中的条带优惠券名称
import React, {useRef, useState} from 'react';
import Link from 'next/link';
import {AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping} from 'react-icons/ai';
import {TiDeleteOutline} from 'react-icons/ti';
import toast from 'react-hot-toast';
import {useStateContext} from '../context/StateContext';
import {urlFor} from '../lib/client';
import getStripe from '../lib/getStripe';
const Cart = () => {
const cartRef = useRef();
const {
totalPrice,
totalQuantities,
cartItems,
setShowCart,
toggleCartItemQuanitity,
onRemove
} = useStateContext();
const [coupontext, setCouponText] = useState('');
const [isCouponAdded, setisCouponAdded] = useState(false);
const [validCoupon, setValidCoupon] = useState("");
const handleChange = (event) => {
setCouponText(event.target.value);
};
const checkCoupon = async () => {
if(!isCouponAdded){
const response = await fetch('https://api.stripe.com/v1/coupons', {
headers: {
'Authorization': `Bearer ${process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY}`
}
});
if (!response.ok) {
toast.error("Error fetching coupons");
return;
}
const {data} = await response.json();
const validcoupon = data.find((c) => c.id === coupontext);
if (validcoupon) {
toast.success("Coupon is valid!");
setValidCoupon(validcoupon);
setisCouponAdded(true);
} else {
toast.error("Coupon is invalid!");
}
}else{
toast.success("Coupon already added!");
}
}
const handleCheckout = async () => {
const stripeClient = await getStripe();
cartItems['validCoupon'] = validCoupon;
const response = await fetch('/api/stripe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(cartItems)
});
if (response.statusCode === 500)
return;
const data = await response.json();
toast.loading('Redirecting...');
stripeClient.redirectToCheckout({sessionId: data.id});
}
.....
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY);
export default async function handler(req, res) {
if (req.method === 'POST') {
try {
const params = {
submit_type: 'pay',
mode: 'payment',
discounts: [
{
coupon: "Your_coupon_name_asper_stripe"
}
]
payment_method_types: ['card'],
billing_address_collection: 'auto',
shipping_address_collection: {
allowed_countries: ["PT"],
},
shipping_options: [
{ shipping_rate: 'shr_1MMq2YJFNgzNJo7sbwDNnqhz' },
{ shipping_rate: "shr_1MMq3iJFNgzNJo7s2nVvfATq"}
],
line_items: req.body.map((item) => {
const img = item.image[0].asset._ref;
const newImage = img.replace('image-', 'https://cdn.sanity.io/images/REDACTED/production/').replace('-png', '.png');
return {
price_data: {
currency: 'eur',
product_data: {
name: item.name,
images: [newImage],
},
unit_amount: item.price * 100,
},
adjustable_quantity: {
enabled:true,
minimum: 1,
},
quantity: item.quantity
}
}),
success_url: `${req.headers.origin}/success`,
cancel_url: `${req.headers.origin}/`,
}
// Create Checkout Sessions from body params.
const session = await stripe.checkout.sessions.create(params);
res.status(200).json(session);
} catch (err) {
res.status(err.statusCode || 500).json(err.message);
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
我将 validCoupon 包含在 POST 请求的正文中。
const handleCheckout = async () => {
const stripeClient = await getStripe();
const response = await fetch('/api/stripe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
cartItems,
validCoupon
})
});
if (response.statusCode === 500)
return;
const data = await response.json();
toast.loading('Redirecting...');
stripeClient.redirectToCheckout({sessionId: data.id});
}
然后在服务器端,我像这样将每个 object 从身体中拉出来。
const {cartItems, validCoupon} = req.body;
然后分别使用每个 object。
validCoupon.id or cartItems.map
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.