I am having a problem debugging my paypal integration with Node and the rest api https://github.com/paypal/rest-api-sdk-nodejs
I created a Paypal account
I got the creditials for the app
I created an app and set a password for a user
I log into the sandbox with that user
I don`t see any transaction history
The code snippet is as follows :
var config_opts = {
'host': 'api.sandbox.paypal.com',
'port': '',
'client_id': 'my id',
'client_secret': 'my secret'
};
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://localhost:3000",
"cancel_url": "http://localhost:3000"
},
"transactions": [{
"amount": {
"currency": "USD",
"total": "10.00"
},
"description": "This is the payment description."
}]
};
paypal_sdk.payment.create(create_payment_json, config_opts, function (err, res) {
if (err) {
console.log( err );
}
if (res) {
console.log("Create Payment Response");
console.log(res);
}
});
The response I get is as follows:
{ id: 'PAY-55J119327J2030636KLXMVJI',
create_time: '2014-02-02T22:45:57Z',
update_time: '2014-02-02T22:45:57Z',
state: 'created',
intent: 'sale',
payer:
{ payment_method: 'paypal',
payer_info: { shipping_address: {} } },
transactions:
[ { amount: [Object],
description: 'This is the payment description.' } ],
links:
[ { href: 'https://api.sandbox.paypal.com/v1/payments/payment/PAY- 55J119327J2030636KLXMVJI',
rel: 'self',
method: 'GET' },
{ href: 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-90D3081342725343U',
rel: 'approval_url',
method: 'REDIRECT' },
{ href: 'https://api.sandbox.paypal.com/v1/payments/payment/PAY-55J119327J2030636KLXMVJI/execute',
rel: 'execute',
method: 'POST' } ] }
I am wondering if there is some additional step in authenticating that I am missing ?
First, you have to declare a proper return_url (not just localhost:3000). I suggest that you change your return_url to "http://localhost:3000/success". Then, insert this one above your payment POST METHOD:
app.get('/success', function(req, res) {
var paymentId = req.query.paymentId;
var payerId = { 'payer_id': req.query.PayerID };
paypal.payment.execute(paymentId, payerId, function(error, payment){
if(error){
console.error(error);
} else {
if (payment.state === 'approved'){
res.send('payment completed successfully');
console.log(payment);
} else {
res.send('payment not successful');
}
}
});
});
This GET method will execute your payment. But, before it can execute, you must redirect first your server's response to paypal sandbox for payment confirmation.
Edit the content of your paypal_sdk.payment.create() function like this one:
paypal_sdk.payment.create(create_payment_json, config_opts, function (err, res) {
if (err) {
console.log( err );
}
else {
console.log("Create Payment Response");
console.log(res);
//you forgot to redirect your response to paypal sandbox
var redirectUrl;
for(var i=0; i < payment.links.length; i++) {
var link = payment.links[i];
if (link.method === 'REDIRECT') {
redirectUrl = link.href;
}
}
res.redirect(redirectUrl);
}
});
I hope this can help (especially to those who are still looking for answers)
You must go to Dashboard -> Rest API transactions.
See the attached screenshot:
Related
I have a User model and trying to add education field to mongoDB as json object as follows,
User model
education: {
"school": String,
"years":Number
},
Client
//add Education section
const updateEducation = async (e) => {
e.preventDefault();
await fetch(`http://localhost:5000/api/user/updateEducation`, {
method: "PUT",
headers: { "Content-Type": "application/JSON", token: accessToken },
body: JSON.stringify({ userid: userid, educationSchool: educationSchool,
educationYearText: EducationYear}),
})
.then((res) => res.json())
.then((data) => {
console.log("User education is:", data.education +""+data.educationYear);
});
};
Server
const updateEducation = async (req, res) => {
try {
const user = await User.findOneAndUpdate(
{ _id: req.body.userid },
{
$set: {
'education.school': req.body.educationSchool,
'education.years': req.body.educationYearText,
},
}
);
if (!user) {
res.status(404).json("user not exist");
}
res
.status(200)
.json({
education: user.education.School,
educationYear: user.education.years,
});
} catch (error) {
res.status(500).send({ error: error.message });
}
};
When im hitting this endpoint in postman http://localhost:5000/api/user/updateEducation
{
"userid":"63bbe4df75dca5aac7576e47",
"educationSchool":"Test college",
"educationYearText":"2018"
}
Im getting {
"error": "Plan executor error during findAndModify :: caused by :: Cannot create field 'school' in element {education: []}"
}
Whats wrong?
You should $push into an array:
const user = await User.findOneAndUpdate(
{ _id: req.body.userid },
{
$push: {
education: {
school: req.body.educationSchool,
years: req.body.educationYearText,
}
},
},
{ new: true }
);
I want to Transfer amount in PayPal with Only Email Address in order Form.
I am integrate the PayPal REST API in Nodejs and Express js but its not working. I want to send payment by register user PayPal email address, but its not working and give me ERROR Site can't reach.If any one know please help me to solve this problem ..
const paypal = require('paypal-rest-sdk');
paypal.configure({
'mode': 'sandbox', //sandbox or live
'client_id': 'XXXXXCLIENT_IDXXXXX',
'client_secret': 'XXXXXXXClientSECRETXXXXX'
});
app.post('/buy',(req,res)=>{
const {email}=req.body;
const create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://localhost:4000/success",
"cancel_url": "http://localhost:4000/cancel"
},
"payee": {
"email_address": email
},
"transactions": [{
"item_list": {
"items": [{
"name": "Redhock Bar Soap",
"sku": "001",
"price": "25.00",
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": "25.00"
},
"description": "Washing Bar soap"
}]
};
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'){
res.redirect(payment.links[i].href);
}
}
}
});
console.log(req.body);
});
app.get('/success', (req, res) => {
const payerId = req.query.PayerID;
const paymentId = req.query.paymentId;
const execute_payment_json = {
"payer_id": payerId,
"transactions": [{
"amount": {
"currency": "USD",
"total": "25.00"
}
}]
};
// Obtains the transaction details from paypal
paypal.payment.execute(paymentId, execute_payment_json, function (error, payment) {
//When error occurs when due to non-existent transaction, throw an error else log the transaction details in the console then send a Success string reposponse to the user.
if (error) {
console.log(error.response);
throw error;
} else {
console.log(payment);
console.log(JSON.stringify(payment));
res.send(payment);
}
});
});
Please Help ....
Thank You
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
when i am creating subscription through stripe it gives err message
As i am doing subscription through stripe
i am also giving some msg about authentication in dashboard like 3d secure authenticatio.
and my cvc_check is unavailable in showing dashboard
1.first issue is 3d secure authentication.
2.cvc check unavailbel in India.
My account is also india
TypeError: stripe.confirmCardPayment is not a function
my code is pls what i am doing wrong
stripe.customers.create(
{
name: name,
email: email,
phone: reqObj.phone,
address: { "city": reqObj.address, "country": "IN",
"line1": "", "line2": "", "state":"India" },
},
function (err, customer) {
if (err) {res.json({ "status": false, "error": err })
console.log(err)
}else {
customer_id=customer.id;
stripe.tokens.create(
{
card: {
number: reqObj.card_no,
exp_month: reqObj.exp_month,
exp_year: reqObj.exp_year,
cvc: reqObj.cvc
},
},
function (err, token) {
if (err) {
res.json({ "status": false, "errorT": err})
} else {
// stripe.customers.createSource(
// customer_id,
// { source: token.id },
// function (err, card) {
// if (err) {
// res.json({ status: "false", "error": err })
// }else {
stripe.plans.list(
{ product: "prod_IMGu6PI2mJbBCi", active: true },
function (err, plans) {
if (!err) {
for(i in plans.data){
if(plans.data[i].amount==reqObj.amount){
var myId=plans.data[i].id
stripe.paymentMethods.create({
type: 'card',
card: {
number: reqObj.card_no,
exp_month: reqObj.exp_month,
exp_year: reqObj.exp_year,
cvc: reqObj.cvc
},
},function(err,result){
// console.log(err,result)
stripe.paymentMethods.attach(result.id, {
customer: customer_id,
},function(err,result1){
// console.log(err,"result1",result1)
stripe.customers.update(
customer_id,
{
invoice_settings: {
default_payment_method: result.id,
},
},function(err,res2){
// console.log(err,"res2")
stripe.subscriptions.create({
customer: customer_id,
items: [{ price: myId}],
expand: ['latest_invoice.payment_intent'],
},function(err,res3){
console.log(err,"res3",
res3.latest_invoice.payment_intent.client_secret)
a=res3.latest_invoice.payment_intent.client_secret
stripe.confirmCardPayment(
res3.latest_invoice.payment_intent.client_secret,
function(err,paymentIntent)
{
console.log(err,"paymentIntent",paymentIntent)
}
)}
);
} );
});
});
}
});
}
// asynchronously called
});
Your code is mixing up client-side and server-side code together which will not work. The stripe.confirmCardPayment() method comes from Stripe.js and should be called client-side in Javascript inside the browser, not server-side with Node.js.
The beginning of your code is updating a Customer with the right default payment method id. Then it's creating a Subscription. And then, if the creation fails to have the first invoice paid, for example if the card is declined or requires 3D Secure, you have to then go back to the client, in the browser, to run the next step which is to confirm the PaymentIntent associated with the Subscription's Invoice.
So you need to go back to the client, where you originally created the PaymentMethod id pm_123456 that you passed in result.id and then try to confirm the PaymentIntent.
I have a button in my node.js application to buy the product whatever user wants. I want to know how to pass that product details (amount etc) to paypal so that user can pay me via paypal. Is there any in-built library?
Yes. You can use paypal-rest-sdk module.
https://github.com/paypal/rest-api-sdk-nodejs
Here's a sample code taken from here.
var paypal_api = require('paypal-rest-sdk');
var config_opts = {
'host': 'api.sandbox.paypal.com',
'port': '',
'client_id': 'EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM',
'client_secret': 'EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM'
};
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http:\/\/localhost\/test\/rest\/rest-api-sdk-php\/sample\/payments\/ExecutePayment.php?success=true",
"cancel_url": "http:\/\/localhost\/test\/rest\/rest-api-sdk-php\/sample\/payments\/ExecutePayment.php?success=false"
},
"transactions": [{
"amount": {
"currency": "USD",
"total": "1.00"
},
"description": "This is the payment description."
}]
};
paypal_api.payment.create(create_payment_json, config_opts, function (err, res) {
if (err) {
throw err;
}
if (res) {
console.log("Create Payment Response");
console.log(res);
}
});