Node.js Paypal Payout api error in Live enviornment - node.js

I am using a PayPal payout API to transfer money, its working perfect in sandbox environment but when I changed it to live environment it is throwing some error:
text: '{"name":"VALIDATION_ERROR","message":"Invalid request - see details","debug_id":"a641429b40e07","information_link":"https://developer.paypal.com/docs/api/payments.payouts-batch/#errors","details":[{"field":"items[0].receiver","location":"body","issue":"may not be null"}],"links":[]}'
This is the code I am using to request a payout
let requestBody = {
"sender_batch_header": {
"recipient_type": "EMAIL",
"email_message": "SDK payouts test txn",
"note": "Enjoy your Payout!!",
"sender_batch_id": 'asd12432',
"email_subject": "This is a test transaction from SDK"
},
"items": [{
"note": "Your 5$ Payout!",
"amount": {
"currency": "USD",
"value": 20
},
"receiver": 'payment#reciever.com',
"sender_item_id": "Test_txn_1"
}]
}
// Construct a request object and set desired parameters
// Here, PayoutsPostRequest() creates a POST request to /v1/payments/payouts
let request = new paypal.payouts.PayoutsPostRequest();
request.requestBody(requestBody);
// Call API with your client and get a response for your call
let createPayouts = async function () {
let response = await client.execute(request);
console.log(`Response: ${JSON.stringify(response.statusCode)}`);
// If caladfl returns body in response, you can get the deserialized version from the result attribute of the response.
console.log(`Payouts Create Response: ${JSON.stringify(response.result)}`);
//res.redirect('/adam?payment=success');
res.redirect('/adam?payment=success');
}
createPayouts();

Related

What is the correct JSON format for googles classroom.create?

Im trying to create a classroom using googles classroom API. Whenever run the classroom.create function I always receive the same error message. I'm using the JSON format from their docs but I just can't get it to work. I think I must be missing something.
This is the function:
async function listCourses(auth) {
const classroom = google.classroom({ version: 'v1', auth });
//Read data from JSON
let data = fs.readFileSync("class.json");
let course = JSON.parse(data);
//Try and create course
try {
const res = await classroom.courses.create(course);
console.log(res.data);
}
catch (error) {
console.log(error)
}
//List all current courses
classroom.courses.list({
pageSize: 10,
}, (err, res) => {
if (err) return console.error('The API returned an error: ' + err);
const courses = res.data.courses;
if (courses && courses.length) {
console.log('Courses:');
courses.forEach((course) => {
console.log(`${course.name} (${course.id})`);
});
} else {
console.log('No courses found.');
}
});
}
This is the JSON:
{
"id": "157942918368",
"name": "English - 9Y",
"section": "Period 2",
"ownerId": "me",
"courseState": "ACTIVE"
}
This is the error message:
code: 400,
errors: [
{
message: `Invalid JSON payload received. Unknown name "name": Cannot bind query parameter. Field 'name' could not be found in request message.\n` +
`Invalid JSON payload received. Unknown name "ownerId": Cannot bind query parameter. Field 'ownerId' could not be found in request message.\n` +
`Invalid JSON payload received. Unknown name "courseState": Cannot bind query parameter. Field 'courseState' could not be found in request message.\n` +
`Invalid JSON payload received. Unknown name "id": Cannot bind query parameter. Field 'id' could not be found in request message.\n` +
`Invalid JSON payload received. Unknown name "section": Cannot bind query parameter. Field 'section' could not be found in request message.`,
reason: 'invalid'
}
]
I believe your goal as follows.
You want to create new course using googleapis for Node.js.
Modification points:
At googleapis for Node.js, please put the request body to resource and/or requestBody.
I think that the reason of your error message is due to this.
When "id": "157942918368", is used, an error of Request contains an invalid argument. occurs.
When "courseState": "ACTIVE" is used, an error of "#CourseStateDenied This user cannot create or transition courses into the requested state." occurs.
"PROVISIONED" can be used in this case.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
const res = await classroom.courses.create(course);
To:
const res = await classroom.courses.create({ requestBody: course });
or
const res = await classroom.courses.create({ resource: course });
And also, please modify your request body as follows.
From:
{
"id": "157942918368",
"name": "English - 9Y",
"section": "Period 2",
"ownerId": "me",
"courseState": "ACTIVE"
}
To:
{
"name": "English - 9Y",
"section": "Period 2",
"ownerId": "me",
}
Note:
In this modification, it supposes that your const classroom = google.classroom({ version: 'v1', auth }); can be used for using the method of courses.create in Classroom API.
References:
Method: courses.create
googleapis for Node.js

Custom response Express Validator as JSON

I'm using Express Validator for validate user req. I'm trying to create custom response like this:
{
"code": 300,
"status": false,
"message": "Your email is not valid",
"param": "email",
"value": "kevin"
}
but what I got is
[
{
"code": 300,
"status": false,
"message": "Your email is not valid",
"param": "email",
"value": "kevin"
}
]
Here is my code:
controller.js:
const errors = validationResult(req).formatWith(utils.error);
if(!errors.isEmpty()){
res.status(300).json(errors.array());
}
ResUtils.js
error({msg, param, value, nestedErrors}) {
var code = 300;
var format = {code, status:false, message:msg, param:param, value:value, nestedErrors:nestedErrors};
return format;
}
How do I can get the response as Json, without [].
Thankyou.
Well, this state is good in my opinion, there is possibility of multiple errors so you should process all messages in a frontend app (or mobile or whatever) to give user informations about all invalid fields (or options or whatever). If you really need only a object, you can pick a first error message from an array for example.
if(!errors.isEmpty()){
const errorsArray = errors.array();
res.status(300).json(errorsArray[0]);
}
But as I said it is better approach to handle all error messages.

The id provided does not exist razorpay in nodejs

i'm implementing razorpay payment gateway in my React.js app with backend nodejs.
here frontend.jsx
razorpayHandler = () =>{
const payment_amount = this.props.TotalPrice;
const backend_url = 'https://25234399bb.ngrok.io';
const self = this;
const options = {
key: config.RAZOR_PAY_KEY,
amount: payment_amount * 100,
name: 'StanPlus',
description: 'pay your ambulance fare',
handler(response) {
const paymentId = response.razorpay_payment_id;
const url = backend_url+'/razorpay/'+paymentId+'/'+payment_amount+'/'+self.id;
console.log(paymentId)
// Using my server endpoints to capture the payment
fetch(url, {
method: 'get',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
}
})
.then(resp => resp.json())
.then(function (data) {
console.log(data)
})
.catch(function (error) {
console.log('Request failed', error);
});
},
theme: {
color: '#40A9FF',
},
};
const rzp1 = new window.Razorpay(options);
rzp1.open();
}
backend.js(nodejs)
var express = require('express');
var router = express.Router();
var config = require('../config');
const Razorpay = require('razorpay');
const instance = new Razorpay({
key_id: config.razorpay_live_key,
key_secret: config.razorpay_live_secret,
});
router.get('/:payment_id/:amount/:BID',function(req,res,next){
const {payment_id } = req.params;
const {BID} = req.params;
const amount = Number(req.params.amount*100);
instance.payments.capture(payment_id, amount).then((data) => {
data.Bid = BID;
res.json(data);
}).catch((error) => {
res.json(error);
});
})
module.exports = router;
it showing me error
"statusCode":400,"error":{"code":"BAD_REQUEST_ERROR","description":"The id provided does not exist"
but if the same code if do process using test key its getting successfully completed but it is not working with live api.
here i'm passing an extra parameter to the backend which required for us but if removed that parameter then also it is not working.but with parameter it is working with test api.
when we send request to backend it is generating id and sending to backend also but still it showing The id provided does not exist.
if you are using test mode then just remove order_id parameter from json object.
I also faced this error a week ago. This error arrived when we changed the test keys to the production keys for final payment to work.
So I faced this issue The id provided does not exist because of the mismatch of Razorpay Keys on the frontend and backend side(node.js side.)
So make sure you have the same client key and secret of the production environment on both backend and frontend side.
Let me know in comments if it still is not resolved.
For Test Remove the OrderId from your options json data.
For Live mode Pass the autogenerated Orderid From the user Control.
Removing order_id is not good practice we should follow documentation.
To get order_id in React you have to first create a order in your backend eg(node.js). follow this steps to get order_id from Razorpay.
Step - 1
var instance = new Razorpay({ key_id: 'YOUR_KEY_ID', key_secret: 'YOUR_KEY_SECRET'})
this will initiate new Razorpay object.
Step - 2
MyOrder = instance.orders.create({amount, currency, receipt, notes})
this will create an order for you and then you have access to order_id. You can log MyOrder to see more available attributes or just console.log(MyOrder.id) to get order_id
and finally you have to pass your order_id in your case you have to pass order_id in options.
Note : You can access order id like this MyOrder.id
for more information check official doc.
you can find Razorpay SDKs for various Platform here
If you are using for payments, than remove order_id from options JSON value.
var options = {
"key": "xxxxxxxxxxxxxxx", // Enter the Key ID generated from the Dashboard
"amount": "50000", // Amount is in currency subunits. Default currency is INR. Hence, 50000 refers to 50000 paise
"currency": "INR",
"name": "Acme Corp",
"description": "Test Transaction",
"image": "https://example.com/your_logo",
// "order_id": "order_9A33XWu170gUtm", //This is a sample Order ID. Pass the `id` obtained in the response of Step 1
"handler": function (response){
alert(response.razorpay_payment_id);
alert(response.razorpay_order_id);
alert(response.razorpay_signature)
},
"prefill": {
"name": "Gaurav Kumar",
"email": "gaurav.kumar#example.com",
"contact": "9999999999"
},
"notes": {
"address": "Razorpay Corporate Office"
},
"theme": {
"color": "#3399cc"
}
};
This error happens when you pass an incorrect order_id to trigger the payment modal. Basically an order_id that does not belong to your razorpay account, or an invalid one.
Example: if you generated an order_id with one set of credentials and use another set of credentials afterwards, this issue can happen.
I too faced the same problem while integrating Razorpay for subscription payments
Initially, I passed order_id in the options param, which yielded the error -
{
"code": "BAD_REQUEST_ERROR",
"description": "The id provided does not exist",
"source": "business",
"step": "payment_initiation",
"reason": "input_validation_failed",
"metadata": {}
}
Hence replaced order_id with subscription_id.
Works now!
Check for the rp_type,
for subscription pass options["subscription_id"],
for orders pass options["order_id"]

Cannot read the whole webview callback from Gupshup.io API inside my cloud function

I have a Google Cloud function written in Node-js that gets invoked each time somebody submits a Gupshup's serverless webview form
I expect to receive the following input in my web service:
{
"linkId": "f42414e2-ce1a-4bf5-b40a-e88e4d4d9aee",
"payload": [{
"fieldname": "name",
"fieldvalue": "Alice"
},{
"fieldname": "gender",
"fieldvalue": "Male"
},{
"fieldname": "account",
"fieldvalue": "savings"
},{
"fieldname": "interest",
"fieldvalue": "Cooking"
}],
"time": 1479904354249,
"userid": "UserID"
}
But i'm having trouble getting the objects inside "payload", time and userid objects.
This is my code:
exports.orderForm = (req, res) => {
const data = req.body;
const ref = data.userid;
var propValue;
console.log(req.method); // POST
console.log(req.get('content-type')); // application/x-www-form-urlencoded
console.log(req.body.linkid); // undefined
console.log(req.body.payload[0].fieldname); // cannot read property from undefined error
console.log(req.body.time); //undefined
console.log(req.body.userid); // undefined
// I attemp to print the properties, but they won't print
for(var propName in req.body.payload) {
propValue = req.body.payload[propName];
console.log(propName, propValue);
}
console.log('JSON.stringify: ' + JSON.stringify(req.body)); // This prints the following:
// JSON.stringify: {"{\"linkId\":\"f42414e2-ce1a-4bf5-b40a-e88e4d4d9aee\",\"payload\":":{"{\"fieldname\":\"account\",\"fieldvalue\":\"savings\"},{\"fieldname\":\"name\",\"fieldvalue\":\"Alice\"},{\"fieldname\":\"gender\",\"fieldvalue\":\"Male\"},{\"fieldname\":\"interest\",\"fieldvalue\":\"Cooking\"}":""}}
res.sendStatus(200);
};
As you can see stringify allows to see all payload properties, but before that i cannot access them in the js object.
The second problem is that event after stringify i can't see time and userid.
What i suspect is i must handle requests of content-type="application/x-www-form-urlencoded" differently from what i'm used to, but i couldn't find any examples for that.
The response you receive from Gupshup to your callback after submission of the serverless webview form is already a stringified object.
Hence you need to parse it using JSON.parse() to get the JSON object and then you will be able to get the values.
Sample code
exports.orderForm = (req, res) => {
const data = JSON.parse(req.body);
console.log(data.linkid); // undefined
console.log(data.payload[0].fieldname);
console.log(data.time);
console.log(data.userid);
};
This should resolve your issue.

Paypal single payout: TRANSACTION_LIMIT_EXCEEDED API Error

I'm trying to make a singe payout with the REST API of PayPal with Node.js and get this error:
//...
"errors": {
"name": "TRANSACTION_LIMIT_EXCEEDED",
"message": "Either the sender or receiver exceeded the transaction limit",
}
//...
What I do:
I use this example Code:
var paypal = require('paypal-rest-sdk');
module.exports = {
payMe: function (req, res,next) {
var mail = req.param('mail'); //this email comes from the paypal sandbox
paypal.configure({
'mode': 'sandbox',
'client_id': 'mycliendID',
'client_secret': 'myClientSecret'
});
var sender_batch_id = Math.random().toString(36).substring(9);
var create_payout_json = {
"sender_batch_header": {
"sender_batch_id": sender_batch_id,
"email_subject": "You have a payment"
},
"items": [
{
"recipient_type": "EMAIL",
"amount": {
"value": 0.90,
"currency": "CHF" //changed from Dollar to CHF
},
"receiver": mail,
"note": "Thank you.",
"sender_item_id": "item_3"
}
]
};
var sync_mode = 'true'; //for single payout
paypal.payout.create(create_payout_json, sync_mode, function (error, payout) {
if (error) {
console.log(error.response);
res.json(error.response);
throw error;
} else {
console.log("Create Single Payout Response");
console.log(payout);
payout.status= "You are in the else";
res.json(payout);
}
});
}
}
=>The Email-Address comes from my sandbox account - the Balance of this User is set to 900.00 CHF! (Much more than the 0.90 CHF which I want to payout)
=>I created under My Apps and Credentials a new REST API App and select the previous created User (with 900.00CHF balance). Those credentials are used in the above code snipped in paypal.configure()
"Either the sender or receiver exceeded the transaction limit"
Where can I change the transaction limit for the App and User in the sandbox?
OK Solved.
I logged in with the sandbox email address - there you can see all transactions.
Under "Denied" I saw the 0.90CHF - With a popup: "The receiver decided to deny the payment"
Then I realised that I used the same E-Mail Address for the Receiver and the Sender. That accused the Error. - The error-message is not very clear.
Maybe someone else is also doing the same mistake, so I let this here.

Resources