I am trying to execute a PayPal Payout on a Node.Js environment, but I can't seem to wrap my head around it. The payment doesn't get made.
I think that I am not getting the parameters right, and, or maybe my code needs re-organizing.
Please help me wrap my head around it, and eventually start heading in the right direction?
Thank you all in advance.
LOCALLY ON THE CLIENT BROWSER:
<script>
paypal.Button.render({
env: 'sandbox', // Or 'production'
// Set up the payment:
// 1. Add a payment callback
payment: function(data, actions) {
// 2. Make a request to your server
return actions.request.post('/my-api/create-payment/')
.then(function(res) {
// 3. Return res.id from the response
return res.id;
});
},
// Execute the payment:
// 1. Add an onAuthorize callback
onAuthorize: function(data, actions) {
// 2. Make a request to your server
return actions.request.post('/my-api/execute-payment/', {
paymentID: data.paymentID,
payerID: data.payerID
})
.then(function(res) {
// 3. Show the buyer a confirmation message.
});
}
}, '#paypal-button');
</script>
ON THE NODE ENVIRONMENT
const path = require("path");
var express = require("express");
var cors = require("cors");
var app = express();
var request = require("request");
const port = process.env.PORT || 3000;
app.use(cors());
var bodyParser = require("body-parser");
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.use(bodyParser.json());
app.get("/", function (req, res) {
res.sendFile(path.join(__dirname + "/index.html"));
});
/** - - - - - - - */
var requestBody = {
"sender_batch_header": {
"sender_batch_id": "Payouts_2018_100007",
"email_subject": "You have a payout!",
"email_message": "You have received a payout! Thanks for using our service!",
},
"items": [
{
"note": "Your 1$ Payout!",
"amount": {
"currency": "USD",
"value": "100.00",
},
"receiver": "[email protected]",
"sender_item_id": "Test_txn_1",
},
{
"note": "Your 1$ Payout!",
"amount": {
"currency": "USD",
"value": "200.00",
},
"receiver": "business.example.com",
"sender_item_id": "Test_txn_2",
},
],
};
// Add your credentials:
// Add your client ID and secret
var CLIENT = "abc-def-ZAFupw-kq6-ghi";
var SECRET = "xyz-ns0xjKT0dkbpJrkvnkMG4ZUZEHd-mnop567";
var PAYPAL_API = "https://api-m.sandbox.paypal.com";
var PAYOUTS_URL = "https://api-m.sandbox.paypal.com/v1/payments/payouts?";
// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
app.post("/my-api/create-payment/", function (req, res) {
// 2. Call /v1/payments/payment to set up the payment
request.post(
PAYPAL_API + "/v1/payments/payment",
{
auth: {
user: CLIENT,
pass: SECRET,
},
body: {
intent: "sale",
payer: {
payment_method: "paypal",
},
transactions: [
{
amount: {
total: "300.00",
currency: "USD",
},
},
],
redirect_urls: {
return_url: "https://mighty-oasis-92039.herokuapp.com/",
cancel_url: "https://mighty-oasis-92039.herokuapp.com/",
},
},
json: true,
},
function (err, response) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
// 3. Return the payment ID to the client
res.json({
id: response.body.id,
});
}
);
});
/** START PAYOUTS */
app.post("/my-api/execute-payment/", function (req, res) {
// 2. Get the payment ID and the payer ID from the request body.
var paymentID = req.body.paymentID;
var payerID = req.body.payerID;
// 3. Call /v1/payments/payment/PAY-XXX/execute to finalize the payment.
request.post(
`${PAYOUTS_URL}paymentID`,
{
auth: {
user: CLIENT,
pass: SECRET,
},
requestBody,
},
function (err, response) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
// 4. Return a success response to the client
res.json({
status: "success",
});
}
);
});
/** END PAYOUTS */
app.listen(port, () => console.log(`listening on port ${port}!`));
The button code in your question is for checkout.js and v1/payments, both of which are deprecated integrations, and which are for receiving payments.
Your server side code is for Payouts, which is for sending payments from your own account. These are entirely separate things.
If you want buyers to be able to directly pay another account, first integrate the current version of PayPal Checkout.
Server side 'Create Order' and 'Capture Order' are documented here: https://developer.paypal.com/docs/business/checkout/server-side-api-calls/#server-side-api-calls
Pair those two routes that return JSON data with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
And in the create call, configure the
payee
who will receive the payment: https://developer.paypal.com/docs/checkout/integration-features/pay-another-account/