Search code examples
paypalpaypal-sandboxpaypal-rest-sdk

I don't understand how to get a token to make API calls


I'm using the Payouts API and to do so I have to specify an access token when calling https://api-m.sandbox.paypal.com/v1/payments/payouts

To get an access token, as specified here I have to send a POST request with Postman to https://developer.paypal.com/docs/api/overview/#get-an-access-token and it returns in the response the token

My problem is that this token has an expiration time, which is an issue because I can't go in my app every 15 minutes to change the token in the Authorization header. How can I get a "permanent" or rather an "auto refreshed" token ?

I tried to make a call from my app instead of Postman but it doesn't seem to work, it says my credentials are invalid

This is my code in case it can be useful (I'm managing everything from the front-end):

 window.paypal
        .Buttons({
          createOrder: (data, actions) => {
            return actions.order.create({
              purchase_units: [
                {
                  description: this.product.description,
                  amount: {
                    value: this.product.price
                  }
                }
              ]
            });
          },
          onApprove: (data, actions) => {
            const timestamp = new Date().getUTCMilliseconds();
            const id = timestamp;
            return actions.order.capture().then(details => {
              axios
                .post(
                  "https://api-m.sandbox.paypal.com/v1/payments/payouts",
                  {
                    sender_batch_header: {
                      sender_batch_id: id,
                      email_subject: "You have a payout!",
                      email_message:
                        "You have received a payout! Thanks for using our service!",
                      recipient_type: "EMAIL"
                    },
                    items: [
                      {
                        amount: {
                          value: this.product.price,
                          currency: "USD"
                        },
                        note: "congrats someone bought your stuff",
                        sender_item_id: id,
                        receiver: "[email protected]"
                      }
                    ]
                  },
                  {
                    headers: {
                      Authorization:
                        "Bearer <my token that I get from postman>"
                    }
                  }
                )
                .then(() => {
                  alert(
                    "Transaction completed by " + details.payer.name.given_name
                  );
                })
                .catch(err => console.log(err));
            });
          }
        })
        .render(".paypal");
    }
  },

Solution

  • Update

    Reading the code a second time and noticing how your Payout is for the same this.product.price as the original payment, that makes no sense. Don't use payouts at all for this use case. The full amount will go to your account normally, but if you want the full amount to go somewhere else instead, set the payee variable for this checkout: https://developer.paypal.com/docs/checkout/integration-features/pay-another-account/

    (original answer below)


    Using Payouts from the client side is an absolutely terrible idea, anyone with your client credentials will be able to send money from your account to wherever they want

    The payouts API must be used from your server only. Your server needs to do an API call to get an access token, similar to what you mention about postman -- except using whatever backend environment you have. You can integrate direct HTTPS calls, or there are also Payouts SDKs available which will handle getting the access token automatically.

    As for how to trigger that backend action when capturing a payment, use a proper server integration:


    Create two routes, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return JSON data. Before returning JSON data, that last route (the capture one) should record the successful transaction in your database and trigger any Payout logic you want.

    Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server