Declare the product id instead of the product informations - node.js

I'm trying to implement Stripe into my nodeJS script.
app.post('/create-checkout-session/', async (req, res) => {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [
{
price_data: {
currency: 'usd',
product_data: {
name: '100 points',
},
unit_amount: 100,
},
quantity: 1,
},
],
mode: 'payment',
success_url: 'http://localhost:4200/success',
cancel_url: 'http://localhost:4200/cancel',
});
res.json({ id: session.id });
});
But that's not what I want, I would like to add the id of the product in the HTML and then show this product or that product according to, in the checkout :
<button (click)="checkout('price_1L4kj8FkiBiEQqb0n2Huec06')" class="p-10 bg-green-200 text-black m-10">
1$
</button>
.ts :
checkout(priceId) {
// Check the server.js tab to see an example implementation
this.http.post('http://localhost:3001/create-checkout-session/', { priceId })
.pipe(
switchMap(session => {
return this.stripeService.redirectToCheckout({ sessionId: session['id'] })
})
)
.subscribe(result => {
// If `redirectToCheckout` fails due to a browser or network
// error, you should display the localized error message to your
// customer using `error.message`.
if (result.error) {
alert(result.error.message);
}
});
}

Related

Stripe error :"You must specify either `product` or `product_data` when creating a price"

Stripe checkout is throwing the error despite having product, product_data declared in the stripe backend(nodejs).
I don't understand what I'm doing wrong, pls help!
Code.
import express from "express";
import Stripe from "stripe";
import dotenv from "dotenv";
dotenv.config();
const stripeRouter = express.Router();
const stripe = new Stripe(process.env.STRIPE_KEY);
stripeRouter.post("/payment", async (req, res) => {
const { cartItems, total } = req.body;
console.log(...cartItems, total);
try {
const session = await stripe.checkout.sessions.create({
submit_type: "pay",
mode: "payment",
payment_method_types: ["card"],
billing_address_collection: "auto",
shipping_options: [
{ shipping_rate: "shr_1Lkm2USAcQw5wr3Edpx6IHaC" },
{ shipping_rate: "shr_1Lkm3hSAcQw5wr3E2hMHSqQI" },
],
line_items: cartItems.map((item, i) => {
return {
price_data: {
currency: "inr",
product_data: {
name: item.name,
},
unit_amount: item.price * 100,
},
adjustable_quantity: {
enabled: true,
minimum: 1,
},
quantity: item.cartQuantity,
};
}),
mode: "payment",
success_url: `http://localhost:4000?success=true`,
cancel_url: `http://localhost:6000?canceled=true`,
});
res.status(200).json(session);
} catch (error) {
res.status(500).json({ message: error });
}
});
export default stripeRouter;
You may want to take a look at the stripe api doc :
https://stripe.com/docs/api/checkout/sessions/create?lang=node
line_items needs an array to be functional. You are returning an object.

PAYPAL : going from sandbox to live REST-SDK-JS

Hello ,Since everything is working perfect in sandbox mode im trying to switch to live mode .. i created a live app and got the live credentials but the issue is the backend still generating a sandbox.paypal.com link ... any solution ?
const express = require("express");
const router = express.Router();
const paypal = require("paypal-rest-sdk");
const User = require("../../../Database/User");
const Order = require("../../../Database/Orders");
const { isUserAuthenticated } = require("../../Oauth/middlewares/auth");
const { Clean_input } = require("../../utils/utils");
paypal.configure({
mode: "live", //sandbox or live
client_id:
"LIVE CLIENT ID",
client_secret:
"LIVE CLIENT SECRET",
});
router.post("/pay",isUserAuthenticated, async (req, res) => {
const order_data = req.body.order_data;
var create_payment_json = {
intent: "sale",
payer: {
payment_method: "paypal",
}, application_context: {
brand_name:'BRAND NAME',
shipping_preference: 'NO_SHIPPING'
},
redirect_urls: {
return_url:
"https://rturn",
cancel_url: "cancel",
},
transactions: [
{
item_list: {
items: [
{
name: order_data.order_name,
sku: order_data.order_name,
price: order_data.price,
currency: "USD",
quantity: 1,
},
],
},
amount: {
currency: "USD",
total: order_data.price,
},
application_context: {
NOSHIPPING: 1,
},
description: order_data.order_details.msg,
},
],
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
throw error;
} else {
for (let i = 0; i < payment.links.length; i++) {
if (payment.links[i].rel === "approval_url") {
const OrderStart = new Order({
order_owner: req.user._id,
order_name: order_data.order_name,
order_details: order_data.order_details,
order_account: {
email : Clean_input(order_data.Email) ,
password : Clean_input(order_data.pwd) ,
},
order_statue: "waiting payment",
order_price: {
price: order_data.price,
taxes: "0",
total_price: order_data.price,
},
payment_methode: order_data.payment_method,
payment_info: {
payment_id: payment.id,
payment_link: payment.links[i].href,
payment_status: "waiting",
payment_data: execute_payment_json,
},
});
OrderStart.save(function (err, user) {
if (err) console.log(err);
if (user) {
console.log(user);
res.status(201).json({ payment_link: payment.links[i].href });
}
});
}
}
}
});
});
module.exports = router;
**FYI : In my code all credentials and redirects are well placed **
SOLVED : I WAS USING WEBHOOKS.JS WITH SAME SANDBOX CONFIG THAT WAS THE PROBLEM

How to terminate My function, it is working but never ending

I use the api mangopay for my app. The function to transfered worked but it never end until I refresh my page. I have no error code, the function still working but we can't get the message: 'the money is transfered'
Maybe I forgot something on my function ?
transfertMangoReferent: (req, res) => {
Serveur.findOne(
{ email: req.body.email },
"mangoWallet abonne",
(err, user) => {
if (user.abonne === true) {
api.Transfers.create(
{
AuthorId: req.user.mangoID,
DebitedFunds: {
Currency: "EUR",
Amount: req.body.amount * 100,
},
Fees: {
Currency: "EUR",
Amount: req.body.amount * 100 * 0.15,
},
DebitedWalletId: req.user.mangoWalletReferent,
CreditedWalletId: user.mangoWallet,
Tag: "Versement du pot Commun",
},
(model) => {
(error) => {
if (error) {
res.status(500).json({
message: "An error has occured with MANGO users",
});
}else{
res.json(model)
}
};
}
);
} else {
api.Transfers.create(
{
AuthorId: req.user.mangoID,
DebitedFunds: {
Currency: "EUR",
Amount: req.body.amount * 100,
},
Fees: {
Currency: "EUR",
Amount: req.body.amount * 100 * 0.25,
},
DebitedWalletId: req.user.mangoWalletReferent,
CreditedWalletId: user.mangoWallet,
Tag: "Versement du pot Commun",
},
(model) => {
(error) => {
if (error) {
res.status(500).json({
message: "An error has occured with MANGO users",
});
} else {
res.json(model)
}
};
}
);
}
}
);
},
On my network when i click to my button validate i have just the code 200
I can give you also my fetch in a react js
<Button
className="CollectButton"
type="submit"
onClick={() => {
const headers = new Headers({
"Content-Type": "application/json",
Authorization: "bearer " + localStorage.getItem("token"),
});
const data = {
email: element.serveurMail,
amount: this.state.referent.amount,
};
const options = {
method: "POST",
headers: headers,
body: JSON.stringify(data),
};
fetch("https://back-end.osc-fr1.scalingo.io/serveur/referentTransfert", options)
.then((response) => {
return response;
})
.then(
(data) => {
console.log(data);
},
(error) => {
console.log(error);
}
);
}}
>
Envoyez
</Button>

Passing data to express backend

I'm adding a stripe checkout to my website with this code in my react front end
const response = await fetch('/create-checkout-session', {
method: 'POST',
});
const session = await response.json();
// When the customer clicks on the button, redirect them to Checkout.
const result = await stripe.redirectToCheckout({
sessionId: session.id,
});
and this one on my express server :
app.post("/create-checkout-session", async (req, res) => {
const session = await stripe.checkout.sessions.create({
shipping_address_collection: {
allowed_countries: ["BE", "FR", "DE", "CH"],
},
payment_method_types: ["card"],
line_items: [
{
price_data: {
currency: "usd",
product_data: {
name: "T-shirt",
},
unit_amount: 10 * 100,
},
description: "Product 1",
quantity: 1,
},
{
price_data: {
currency: "usd",
product_data: {
name: "Tsklip",
},
unit_amount: 2000,
},
description: "Product 2",
quantity: 2,
},
],
mode: "payment",
success_url: "https://localhost:3000",
cancel_url: "https://localhost:3000/cart",
});
res.json({ id: session.id });
});
I'd like to pass from my frontend to my backend some info.
How could I do that ? Is it possible with this code ?
Thanks !
You can pass data to body, then you can access them in express from req.body
const response = await fetch('/create-checkout-session', {
method: 'POST',
body: JSON.stringify({ info: 'my info message', id: 1})
});
Also you should use
body-parser middleware to parse incoming request body

Must provide source or customer stripe live mode

this is my first time using stripe and I am getting an error Must provide source or customer. once I went live. In the test mode I used "tok_mastercard" as my source but clearly when I went live it isn't valid. What am I missing here please help.
This is my POST request in the backend
stripe.charges
.create({
amount: req.renter.rent * 100,
currency: "usd",
source: req.body.token,
application_fee_amount: req.renter.rent * 0.05 * 100,
transfer_data: {
//the destination needs to not be hard coded it needs to
//come from what property the renter is in
destination: req.renter.stripeConnectId,
// destination: "acct_1GOCMqDfw1BzXvj0",
},
})
.then((charge) => {
console.log(req.renter);
res.send(charge);
})
.catch((err) => {
console.log(err);
});
});
this is my two functions in the frontend using react-native and node
handleCardPayPress = async () => {
try {
this.setState({ loading: true, token: null });
const token = await stripe.paymentRequestWithCardForm({
// Only iOS support this options
smsAutofillDisabled: true,
requiredBillingAddressFields: "full",
prefilledInformation: {
billingAddress: {
name: "",
line1: "",
line2: "",
city: "",
state: "",
country: "US",
postalCode: "",
email: "",
},
},
});
this.setState({ loading: false, token });
} catch (error) {
this.setState({ loading: false });
}
};
makePayment = async () => {
try {
//Mate the payment
const response = await unitApi.post("/payments", {
data: {
amount: this.state.renter.rent,
currency: "usd",
token: this.state.token,
},
});
Alert.alert("Success!", `Confirmation ID: ${response.data.id}`, [
{ text: "Done" },
]);
console.log(response.data);
// navigate("Home");
} catch (err) {
//failiur and showing the error message
console.log(err);
Alert.alert("Failed!", "Card declined.", [{ text: "Declined" }]);
}
};
Odds are pretty good that this.state.token doesn't contain what you think it does in the unitApi.post() function call; I'd recommend logging that and seeing if that helps, and also logging req.body.token server-side.

Resources