43
loading...
This website collects cookies to deliver better user experience
// in a terminal
npx create-react-app react-stripe
cd react-stripe
yarn add @stripe/stripe-js @stripe/react-stripe-js axios
loadStripe
from @stripe/stripe-js
, Elements
from @stripe/react-stripe-js
, and a PaymentForm
.// App.js
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import PaymentForm from "./PaymentForm"; // not implemented yet
// when you toggle to live mode, you should add the live publishale key.
const stripePromise = loadStripe(STRIPE_PK_TEST);
function App() {
return (
<div className="App">
{/* Elements is the provider that lets us access the Stripe object.
It takes the promise that is returned from loadStripe*/}
<Elements stripe={stripePromise}>
<PaymentForm />
</Elements>
</div>
);
}
export default App;
PaymentForm
can be like this:// PaymentForm.js
import { CardElement } from "@stripe/react-stripe-js";
import axios from "axios";
const PaymentForm = () => {
const handleSubmit = async (e) => {
e.preventDefault();
// stripe code here
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
<button>BUY</button>
</form>
);
};
export default PaymentForm;
//PaymentForm.js
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
import axios from "axios";
const PaymentForm = () => {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not loaded yet. Make sure to disable
// form submission until Stripe.js has loaded.
return;
}
// Get a reference to a mounted CardElement. Elements knows how
// to find your CardElement because there can only ever be one of
// each type of element.
const cardElement = elements.getElement(CardElement);
// use stripe.createToken to get a unique token for the card
const { error, token } = await stripe.createToken(cardElement);
if (!error) {
// Backend is not implemented yet, but once there isn’t any errors,
// you can pass the token and payment data to the backend to complete
// the charge
axios
.post("http://localhost:5000/api/stripe/charge", {
token: token.id,
currency: "EGP",
price: 1000, // or 10 pounds (10*100). Stripe charges with the smallest price unit allowed
})
.then((resp) => {
alert("Your payment was successful");
})
.catch((err) => {
console.log(err);
});
} else {
console.log(error);
}
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
<button>PAY</button>
</form>
);
};
export default PaymentForm;
<CardElement/>
here but you can use <CardNumberElement/>
, <CardExpiryElement/>
, and <CardCvcElement/>
and then use elements.getElement(CardNumberElement)
to access the card number element.client
directory inside stripe-react
. Run yarn init
so that the outer directory can have the package.json
for the backend code and then create server.js
.yarn add express stripe dotenv cors
yarn add --dev concurrently nodmon
package.json
:"scripts": {
"client": "cd client && yarn start",
"server": "nodemon server.js",
"start": "node server.js",
"dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
},
server.js
, create the post api/route that will recieve the payment data and Stripe token from the FE to complete the charge.require("dotenv").config();
const express = require("express");
const app = express();
const cors = require("cors");
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
const PORT = process.env.PORT || 5000;
const stripe = require("stripe")(env.process.STRIPE_SECRET_KEY_TEST);
// same api we used in the frondend
app.post("/api/stripe/charge", async (req, resp) => {
const { token, currency, price } = req.body;
const charge = await stripe.charges.create({
amount: price,
currency,
source: token,
});
if (!charge) throw new Error("charge unsuccessful");
});
app.listen(PORT, () => {
console.log(`Server running on port: ${PORT}`);
});
yarn dev
and use one of these test cards to test the integration.