admin管理员组文章数量:1399935
I'm trying to create an E-merce website with JavaScript, React, and Stripe.
For the life of me I can't figure out how to include a billing and shipping address in my checkout. I've tried to find an answer online but cant find a working solution I can adapt. Maybe the answer is obvious except to me.
I appreciate any help! I've posted me code below. Thank you.
import React, { useState, useEffect } from "react";
import CheckoutProduct from "./CheckoutProduct";
import "./Payment.css";
import { useStateValue } from "./StateProvider";
import { Link, useHistory } from "react-router-dom";
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
import CurrencyFormat from "react-currency-format";
import { getBasketTotal } from "./reducer";
import axios from "./axios";
import { db } from "./firebase";
function Payment() {
const [{ basket, user }, dispatch] = useStateValue();
const history = useHistory();
const stripe = useStripe();
const elements = useElements();
const [succeeded, setSucceeded] = useState(false);
const [processing, setProcessing] = useState("");
const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState(true);
useEffect(() => {
const getClientSecret = async () => {
const response = await axios({
method: "post",
url: `/payments/create?total=${getBasketTotal(basket) * 100}`,
});
setClientSecret(response.data.clientSecret);
};
getClientSecret();
}, [basket]);
console.log("THE SECRET IS >>>", clientSecret);
const handleSubmit = async (event) => {
event.preventDefault();
setProcessing(true);
const payload = await stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
})
.then(({ paymentIntent }) => {
db.collection("users")
.doc(user?.uid)
.collection("orders")
.doc(paymentIntent.id)
.set({
basket: basket,
amount: paymentIntent.amount,
created: paymentIntent.created,
});
setSucceeded(true);
setError(null);
setProcessing(false);
dispatch({
type: "EMPTY_BASKET",
});
history.replace("/orders");
});
};
const handleChange = (event) => {
setDisabled(event.empty);
setError(event.error ? event.error.message : "");
};
return (
<div className="payment">
<div className="payment__container">
<h1>
Checkout (<Link to="/checkout">{basket?.length} items</Link>)
</h1>
<div className="payment__section">
<div className="payment__title">
<h3>Delivery Address</h3>
</div>
<div className="payment__address">
<p>{user?.email}</p>
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Review Items and Delivery</h3>
</div>
<div className="payment__items">
{basket.map((item) => (
<CheckoutProduct
id={item.id}
title={item.title}
image={item.image}
price={item.price}
rating={item.rating}
/>
))}
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Payment Method</h3>
</div>
<div className="payment__details">
<form onSubmit={handleSubmit}>
<CardElement onChange={handleChange} />
<div className="payment__priceContainer">
<CurrencyFormat
renderText={(value) => (
<>
<h3>Order Total: {value}</h3>
</>
)}
decimalScale={2}
value={getBasketTotal(basket)}
displayType={"text"}
thousandSeparator={true}
prefix={"$"}
/>
<button disabled={processing || disabled || succeeded}>
<span>{processing ? <p>Processing</p> : "Buy Now"}</span>
</button>
</div>
{error && <div>{error}</div>}
</form>
</div>
</div>
</div>
</div>
);
}
export default Payment;
I'm trying to create an E-merce website with JavaScript, React, and Stripe.
For the life of me I can't figure out how to include a billing and shipping address in my checkout. I've tried to find an answer online but cant find a working solution I can adapt. Maybe the answer is obvious except to me.
I appreciate any help! I've posted me code below. Thank you.
import React, { useState, useEffect } from "react";
import CheckoutProduct from "./CheckoutProduct";
import "./Payment.css";
import { useStateValue } from "./StateProvider";
import { Link, useHistory } from "react-router-dom";
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
import CurrencyFormat from "react-currency-format";
import { getBasketTotal } from "./reducer";
import axios from "./axios";
import { db } from "./firebase";
function Payment() {
const [{ basket, user }, dispatch] = useStateValue();
const history = useHistory();
const stripe = useStripe();
const elements = useElements();
const [succeeded, setSucceeded] = useState(false);
const [processing, setProcessing] = useState("");
const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState(true);
useEffect(() => {
const getClientSecret = async () => {
const response = await axios({
method: "post",
url: `/payments/create?total=${getBasketTotal(basket) * 100}`,
});
setClientSecret(response.data.clientSecret);
};
getClientSecret();
}, [basket]);
console.log("THE SECRET IS >>>", clientSecret);
const handleSubmit = async (event) => {
event.preventDefault();
setProcessing(true);
const payload = await stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
})
.then(({ paymentIntent }) => {
db.collection("users")
.doc(user?.uid)
.collection("orders")
.doc(paymentIntent.id)
.set({
basket: basket,
amount: paymentIntent.amount,
created: paymentIntent.created,
});
setSucceeded(true);
setError(null);
setProcessing(false);
dispatch({
type: "EMPTY_BASKET",
});
history.replace("/orders");
});
};
const handleChange = (event) => {
setDisabled(event.empty);
setError(event.error ? event.error.message : "");
};
return (
<div className="payment">
<div className="payment__container">
<h1>
Checkout (<Link to="/checkout">{basket?.length} items</Link>)
</h1>
<div className="payment__section">
<div className="payment__title">
<h3>Delivery Address</h3>
</div>
<div className="payment__address">
<p>{user?.email}</p>
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Review Items and Delivery</h3>
</div>
<div className="payment__items">
{basket.map((item) => (
<CheckoutProduct
id={item.id}
title={item.title}
image={item.image}
price={item.price}
rating={item.rating}
/>
))}
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Payment Method</h3>
</div>
<div className="payment__details">
<form onSubmit={handleSubmit}>
<CardElement onChange={handleChange} />
<div className="payment__priceContainer">
<CurrencyFormat
renderText={(value) => (
<>
<h3>Order Total: {value}</h3>
</>
)}
decimalScale={2}
value={getBasketTotal(basket)}
displayType={"text"}
thousandSeparator={true}
prefix={"$"}
/>
<button disabled={processing || disabled || succeeded}>
<span>{processing ? <p>Processing</p> : "Buy Now"}</span>
</button>
</div>
{error && <div>{error}</div>}
</form>
</div>
</div>
</div>
</div>
);
}
export default Payment;
Share
Improve this question
edited May 24, 2023 at 16:39
Super Kai - Kazuya Ito
1
asked Sep 8, 2021 at 17:39
heretolearnheretolearn
831 silver badge10 bronze badges
4 Answers
Reset to default 4Stripe allows you collect shipping address for item(s) delivery by adding shipping_address_collection
when you create a Checkout session.
According to stripe:
You must also specify which countries to allow shipping to by configuring the allowed countries property with an array of two-letter ISO country codes. These countries appear in the Country dropdown in the Shipping Address form on Checkout.
const session = await stripe.checkout.sessions.create({
//other details
shipping_address_collection: {
allowed_countries: ['US', 'CA'],
},
});
Check stripe documentation for more detail https://stripe./docs/payments/checkout/shipping
Stripe doesn't have an element to collect billing details directly but it's something you can build yourself in your form. Assuming you collect the relevant fields, you would pass the information at the time you call confirmCardPayment
as documented here by passing the billing_details
parameter:
const payload = await stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
billing_details: {
name: 'Jenny Rosen',
address: {
line1: '1 Main street',
city: 'San Francisco',
postal_code: '90210',
state: 'CA',
country: 'US',
},
},
},
});
Similarly, you can pass the shipping details in the same call in the shipping
parameter
const payload = await stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
shipping: {
name: 'Jenny Shipping',
address: {
line1: '1 Main street',
city: 'San Francisco',
postal_code: '90210',
state: 'CA',
country: 'US',
},
},
});
You can bine both in one call.
if using reactjs, you can require billing address like this
billing_address_collection: 'required'
You can use shipping_address_collection as shown below:
const session = await stripe.checkout.sessions.create({
...
shipping_address_collection: {
allowed_countries: ['US', 'CA'],
},
...
});
Also, you can use payment_intent_data.shipping to pass a shipping address to Shipping section in Payments on Stripe Dashboard as shown below. *This doesn't pass a shipping address to Stripe Checkout but does pass to Shipping section in Payments on Stripe Dashboard and you cannot use both shipping_address_collection
and payment_intent_data.shipping
at the same time otherwise there is an error:
const session = await stripe.checkout.sessions.create({
...
payment_intent_data: {
shipping: {
name: 'John Smith',
address: {
country: 'USA',
state: 'California',
city: 'San Francisco',
line1: '58 Middle Point Rd',
line2: '',
postal_code: '94124'
}
}
},
/*
shipping_address_collection: {
allowed_countries: ['US', 'CA'],
},
*/
...
});
本文标签: javascriptHow to add shipping and delivery addresses with StripeStack Overflow
版权声明:本文标题:javascript - How to add shipping and delivery addresses with Stripe - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744158441a2593220.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论