Paypal batch payout not working in node js api - node.js

I am trying to create a batch payout with a test sandbox account.
The 'create payment' function is working absolutely fine with correct response:
var paypal_sdk = require('paypal-rest-sdk');
var config_opts = {
'host': host, //host defined
'port':'',
'mode':'sandbox',
'client_id': client_id, //clientID defined
'client_secret': client_secret, //clientSecret defined
};
var makePayment = function (req, res, next) {
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://mystore.in",
"cancel_url": "http://mystore.in/contact"
},
"transactions": [
{
"amount": {
"currency": "USD",
"total": "1.00"
},
"description": "This is the payment description."
}
]
};
paypal_sdk.payment.create(create_payment_json,config_opts, function (err, data) {
if (err) console.log("ERRRRR", err);
console.log("Create Payment Response");
console.log(data);
//res.send('201');
});
}
makePayment(); //CALLING THE FUNCTION
But, when I am trying to create a new payout, by editing create_payment_json as:
var create_payment_json = {
"sender_batch_header": {
"email_subject": "You have a Payout!",
"recipient_type": "EMAIL"
},
"items": [
{
"recipient_type": "EMAIL",
"amount": {
"value": "1.0",
"currency": "USD"
},
"note": "Thanks for your patronage!",
"sender_item_id": "201403140001",
"receiver": "shirt-supplier-one#mail.com"
}
]
};
And main function as:
paypal_sdk.payout.create(create_payment_json,config_opts, function (err, data) {
if (err) console.log("ERRRRR", err);
console.log("Create Payment Response");
console.log(data);
//res.send('201');
});
I am receiving an error as follows:
{ [Error: Response Status : 401]
response:
{ error: 'invalid_client',
error_description: 'Client Authentication failed',
httpStatusCode: 401 },
httpStatusCode: 401 }
However, I am sure that credentials passed are correct and they are working perfectly in case of payment creation.
I am doing all this for the testing first. Also, the payout feature is enabled for this respective test paypal developer account.
Is there any possible solution?

I just got the solution. Well, to add, I must say paypal should provide proper error handling to let the developers know the reason behind each error.
The error was because of the currency that I had set in the configuration. The testing developer account was of some other country and the currency code was set as "USD".
Just make a new account and set currency code in config according to the country you had selected during the creation of that test developer account.

I test payout , as below code, it works fine. You can compare your code with my sample, you can add'sender_batch_id' parameter to have a try.
curl -v https://api.sandbox.paypal.com/v1/payments/payouts/ \
-H "Content-Type:application/json" \
-H "Authorization: *****" \
-d '{
"sender_batch_header": {
"sender_batch_id": "batch_25",
"email_subject": "You have a payment"
},
"items": [
{
"recipient_type": "EMAIL",
"amount": {
"value": 0.99,
"currency": "USD"
},
"receiver": "aaabbb#email.com",
"note": "Thank you.",
"sender_item_id": "item_1"
},
{
"recipient_type": "EMAIL",
"amount": {
"value": 0.90,
"currency": "USD"
},
"receiver": "bbbb#gmail.com",
"note": "Thank you.",
"sender_item_id": "item_2"
},
{
"recipient_type": "EMAIL",
"amount": {
"value": 2.00,
"currency": "USD"
},
"receiver": "cccc#gmail.com",
"note": "Thank you.",
"sender_item_id": "item_3"
}
]
}'

Related

Having issue passing data from Form in Paypal-rest-sdk using Node

This is my code. Can you please tell me how to pass the form field in PayPal API?
The Issue I am getting here is when I am trying to pass Dummy data mine API is working fine but when I am trying to pass Fields from mine Form its not working. I have console.log and check it I am getting data on this API.
router.post('/checkout/pay',function(req,res){
var title="req.body.title";
var price="req.body.price";
var qty=1
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://localhost:3000/success",
"cancel_url": "http://localhost:3000/cancel"
},
"transactions": [{
"item_list": {
"items": [{
"name": title,
"sku": "001",
"price":price ,
"currency": "USD",
"quantity": 1,
}]
},
"amount": {
"currency": "USD",
"total": price,
},
"description": "This is the payment description."
}]
};
function handleError(error) {
console.log(error);
}
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
console.log(error);
handleError(error);
} else {
console.log("Create Payment Response");
console.log(JSON.stringify(payment));
res.send('test');
}
});
})
The issue was with my form I was trying
I was trying to do something like this
value=$nbsp;"<%= parseFloat(total).toFixed(2) %>"
Instead of it should be like this
value="<%= parseFloat(total).toFixed(2) %>"
I forget that their would be a validation in Paypal Service

Accept PayPal payments without website

I do not have a website and I would like to just send a link to the user and get the appropriate response whether they paid or not on the PayPal website and handle the rest.
Basically I dont want to redirect the user anywhere.
After configuring my PayPal credentials I have the following
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
// I WANT TO REMOVE THAT BUT IF I DO I GET AN ERROR IN RESPONSE
"redirect_urls": {
"return_url": "http://return.url",
"cancel_url": "http://cancel.url"
},
"transactions": [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": "1.00",
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": "1.00"
},
"description": "This is the payment description."
}]
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
}
});
var paymentId = 'PAYMENT id created in previous step';
//check if user payed or not
paypal.payment.execute(paymentId, execute_payment_json, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log("Get Payment Response");
console.log(JSON.stringify(payment));
}
});

Getting HTTP 400 error when trying to make Paypal payment

I was getting this error when building my little toy payment gateway form, but now I realized I can't even properly run the sample code after cloning the repository here.
I have entered my client ID and secret into configure.js. I'm in sandbox mode.
The file I'm running:
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "credit_card",
"funding_instruments": [{
"credit_card": {
"type": "visa",
"number": "4417119669820331",
"expire_month": "11",
"expire_year": "2018",
"cvv2": "874",
"first_name": "Joe",
"last_name": "Shopper",
"billing_address": {
"line1": "52 N Main ST",
"city": "Johnstown",
"state": "OH",
"postal_code": "43210",
"country_code": "US"
}
}
}]
},
"transactions": [{
"amount": {
"total": "7.00",
"currency": "USD",
"details": {
"subtotal": "5.00",
"tax": "1.00",
"shipping": "1.00"
}
},
"description": "This is the payment transaction description."
}]
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
}
});
When running, I get
> node create_with_credit_card.js
{ [Error: Response Status : 400]
response:
{ name: 'UNKNOWN_ERROR',
message: 'An unknown error has occurred',
information_link: 'https://developer.paypal.com/webapps/developer/docs/api/#UNKNOWN_ERROR',
debug_id: '599dd3222e6fb',
httpStatusCode: 400 },
httpStatusCode: 400 }
C:\cygwin64\home\Ryan\PayPal-node-SDK\samples\payment\create_with_credit_card.js:47
throw error;
^
Error: Response Status : 400
at IncomingMessage.<anonymous> (C:\cygwin64\home\Ryan\PayPal-node-SDK\lib\client.js:136:23)
at IncomingMessage.emit (events.js:117:20)
at _stream_readable.js:944:16
at process._tickCallback (node.js:442:13)
I'm desperate to find out where I am going wrong here.
The card you use (4417119669820331) is not unique. When testing a payment in REST API especially for Credit Card number, try not to use the default credit card number such 4417119669820331. Try with some other number like example 4532371704016199.
Alternatively, use this site (http://www.fakenamegenerator.com/) to generate the fake credit card for testing.

Payment Authorization & Capture the Payment (Future) using PayPal-node-SDK (PayPal Express Checkout)

I'm working with PayPal Express Checkout and and what i need to do is Authorize and Capture the payment later separately, my current PayPal flow is,
1) I create a payment using following code:
var paypal = require('paypal-rest-sdk');
function createPayPal(req, res, itemsArray, redirectsTos) {
var payment = {
"intent": "sale",
"payer": {},
"transactions": [{
"amount": {
"currency": sails.config.currency,
"total": itemsArray.totalArrayAmount,
"details": {
"subtotal": itemsArray.totalArrayAmount,
"fee": sails.config.PayPalCreateFee
}
},
"invoice_number": req.session.invNum,
"item_list": {
"items": itemsArray.itemsArray
}
}]
};
sails.log.info('payment obj :', JSON.stringify(payment))
payment.payer.payment_method = sails.config.PayPalPaymentMethod;
payment.redirect_urls = {
"return_url": res.locals.return_url_buy,
"cancel_url": res.locals.cancel_url_buy
};
paypal.payment.create(payment, function(error, payment) {
if (error) {
sails.log.error(error);
redirectsTos(({
message: 'failure',
redirect: '/paypal/error'
}), null);
} else {
sails.log.info('Payment ID = ', payment.id);
sails.log.info('User ID = ', req.session.userSession);
var redirectUrl;
for (var i = 0; i < payment.links.length; i++) {
var link = payment.links[i];
if (link.method === 'REDIRECT') {
redirectUrl = link.href;
sails.log.info('goto:', redirectUrl)
redirectsTos(null, ({
message: 'success',
redirect: redirectUrl
}));
}
}
}
});
}
and Paypal returns me the order information and the redirect urls and i redirected the user to the href in links object. then when the payflow returns to me website it sends me
{
paymentId: 'PAY-5FB60654T5508144abcxyzZLQ',
token: 'EC-26U68825EW2123428',
PayerID: 'QSABTRW6AHYH6'
}
and then i executed the payment using following code.
function executePayPal(req, paymentId, payerId, executedPayPal) {
sails.log.info('in executedPayPal');
var details = {
"payer_id": payerId
};
var payment = paypal.payment.execute(paymentId, details, function(error, payment) {
if (error) {
sails.log.error('error in payment id in executePayPal function of paypal controller', error);
var err = JSON.stringify(error);
var errParsed = JSON.parse(err);
crashHandlingService.appCrash(errParsed, 101202);
executedPayPal(({
message: 'failure',
redirect: '/paypal/error/'
}), null);
} else {
executedPayPal(({
message: 'success',
redirect: '/paypal/success/'
}), null);
}
});
}
Now what this code basically do is
Create the payment,
Redirect the user to paypal page C
Capture the payment.
and what i actually want to achieve is
authorize the payment ->
capturing the payment so that i can capture the payment some later time in some cronJob or service.
And redirect the user to paypal page in the middle of above flow, i really don't know how to authorize, redirect and then capture payment.
So please guide me in this regards.
Note: i've read the following paypal documentation but not able to understand. and please keep in mind that i need to show payment detail on paypal page and also the coupon code and its discount on the payment page.
https://developer.paypal.com/docs/integration/direct/capture-payment/#authorize-the-payment
https://developer.paypal.com/docs/classic/express-checkout/ht_ec-singleAuthPayment-curl-etc/
Thanks in advance :) .
Finally I've found the solution and i thought i should post it here so that it could be helpful for other.
So there are basically 4 following steps and one have to you use PayPal Node SDK
Create Payment.
Redirect User to PayPal.
Execute Authorized Payment.
Capture Authorized Payment.
To Create Payment you can use payment.create method of PayPal Node sdk here.
.Create Method will return url links in "href" to redirect user to PayPal page so redirect the user to PayPal page.
After returning from pay PayPal page you have to run .execute method of PayPal Node SDK here, using payer_id and paymentId recived from PayPal.
and finally when you need to capture the amount of the authorized transaction you had to .authorization.capture method of PayPal Node SDK here, by providing amount and the 17 digits authorization id recived in execute authorize response.
Code & Response sample are provided below in case if the links doesn't works in future.
.create Code
var create_payment_json = {
"intent": "authorize",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://return.url",
"cancel_url": "http://cancel.url"
},
"transactions": [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": "1.00",
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": "1.00"
},
"description": "This is the payment description."
}]
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
for (var index = 0; index < payment.links.length; index++) {
//Redirect user to this endpoint for redirect url
if (payment.links[index].rel === 'approval_url') {
console.log(payment.links[index].href);
}
}
console.log(payment);
}
});
Response Sample
{
"id": "PAY-17S8410768582940NKEE66EQ",
"create_time": "2013-01-31T04:12:02Z",
"update_time": "2013-01-31T04:12:04Z",
"state": "approved",
"intent": "authorize",
"payer": {
"payment_method": "credit_card",
"funding_instruments": [
{
"credit_card": {
"type": "visa",
"number": "xxxxxxxxxxxx0331",
"expire_month": "11",
"expire_year": "2018",
"first_name": "Betsy",
"last_name": "Buyer",
"billing_address": {
"line1": "111 First Street",
"city": "Saratoga",
"state": "CA",
"postal_code": "95070",
"country_code": "US"
}
}
}
]
},
"transactions": [
{
"amount": {
"total": "7.47",
"currency": "USD",
"details": {
"tax": "0.03",
"shipping": "0.03"
}
},
"description": "This is the payment transaction description.",
"related_resources": [
{
"sale": {
"id": "4RR959492F879224U",
"create_time": "2013-01-31T04:12:02Z",
"update_time": "2013-01-31T04:12:04Z",
"state": "completed",
"amount": {
"total": "7.47",
"currency": "USD"
},
"parent_payment": "PAY-17S8410768582940NKEE66EQ",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/4RR959492F879224U",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/4RR959492F879224U/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-17S8410768582940NKEE66EQ",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-17S8410768582940NKEE66EQ",
"rel": "self",
"method": "GET"
}
]
}
.execute Code
var paymentId = 'PAYMENT id created in previous step';
paypal.payment.execute(paymentId, execute_payment_json, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log("Get Payment Response");
console.log(JSON.stringify(payment));
}
});
Response Sample
{
"id": "PAY-34629814WL663112AKEE3AWQ",
"create_time": "2013-01-30T23:44:26Z",
"update_time": "2013-01-30T23:44:28Z",
"state": "approved",
"intent": "aurthorize",
"payer": {
"payment_method": "paypal",
"payer_info": {
"email": "bbuyer#example.com",
"first_name": "Betsy",
"last_name": "Buyer",
"payer_id": "CR87QHB7JTRSC"
}
},
"transactions": [
{
"amount": {
"total": "7.47",
"currency": "USD",
"details": {
"tax": "0.04",
"shipping": "0.06"
}
},
"description": "This is the payment transaction description.",
"related_resources": [
{
"sale": {
"id": "1KE4800207592173L",
"create_time": "2013-01-30T23:44:26Z",
"update_time": "2013-01-30T23:44:28Z",
"state": "completed",
"amount": {
"currency": "USD",
"total": "7.47"
},
"transaction_fee": {
"value": "0.50",
"currency": "USD"
},
"parent_payment": "PAY-34629814WL663112AKEE3AWQ",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/1KE4800207592173L",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/1KE4800207592173L/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-34629814WL663112AKEE3AWQ",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-34629814WL663112AKEE3AWQ",
"rel": "self",
"method": "GET"
}
]
}
.authorization.capture Code
var capture_details = {
"amount": {
"currency": "USD",
"total": "4.54"
},
"is_final_capture": true
};
paypal.authorization.capture("5RA45624N3531924N", capture_details, function (error, capture) {
if (error) {
console.error(error);
} else {
console.log(capture);
}
});
Response Sample
{
"id": "6BA17599X0950293U",
"create_time": "2013-05-06T22:32:24Z",
"update_time": "2013-05-06T22:32:25Z",
"amount": {
"total": "4.54",
"currency": "USD"
},
"is_final_capture": true,
"state": "completed",
"parent_payment": "PAY-44664305570317015KGEC5DI",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/capture/6BA17599X0950293U",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/capture/6BA17599X0950293U/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/authorization/5RA45624N3531924N",
"rel": "authorization",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-44664305570317015KGEC5DI",
"rel": "parent_payment",
"method": "GET"
}
]
}
You can get more information from REST API Reference And PayPal-node-SDK.
Forgive me if the response sample are somehow a little bit change because i've copied it from PayPal web.
Thanks.

Create a payment with Paypal REST API

This is how I create Paypal payment from my webapp :
paypal.configure(paypal_config.api);
var payment = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
//"receiver_email": "business#place.fr",
"redirect_urls": {
"return_url": "http://yoururl.com/execute",
"cancel_url": "http://yoururl.com/cancel"
},
"transactions": [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": "1.00",
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": "1.06",
"details": {
"subtotal": "1.00",
"tax": "0.03",
"shipping": "0.03"
}
},
"description": "This is the payment description."
}]
};
paypal.payment.create(payment, function (error, payment) {
if (error) {
console.log(error);
} else {
if(payment.payer.payment_method === 'paypal') {
req.session.paymentId = payment.id;
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);
}
}
});
It works perfectly but I have 2 problems, I need to set the receiver email, and the request is said to be malformed when I add the key "receiver_email".
My second problem is more a question in fact, with this method I know directly if the payment is validated or not, but what happened when a payment need more time to be validated (bank transfer etc..), there's no ipn url to give ?
Thank you !
Currently with PayPal rest payments, you cannot configure the receiver, so the payee has to be the one with the client_id/client_secret pair.
To your second question, currently ipn support is not there for REST payments but the "http post to your server when payment status changes" feature will be coming for REST payments soon. Currently the best option is to fetch the payment with the PAY-XXX id by doing a GET to check change of status.
I don't think setting receiver to be different from the client_id is supported at the moment.

Resources