Open tamodaleko opened 4 years ago
Hi Can you please give more information like any error messages or negative response that you see while using Payouts API for third party payments? This will help us to understand the issue better.
Hey @thisisbalajibabu,
I tried sending request directly using Postman, as well as using this SDK - but always getting the same error, although "PayPal-Auth-Assertion" header is formatted well using official documentation.
Screenshot of error using Postman:
Screenshot of error using SDK:
Screenshot of my code (with auth assertion header):
In official documentation it's mentioned that 3rd party calls can be used for REST API, but i don't understand what's wrong here?
Thanks for the help!
HI @tamodaleko Lets debug your problem one after another.
I will suggest lets fix it using the Postman client where you directly hit the REST API followed which we can see how your SDK integration works.
I believe you should be familiar with below understanding. For 3rd pary payments, we have an account which will be the Subject Which grants permission to another account actor using which the payments is requested for Subject.
I see that you get an error mentioning "Subject Authentication failed" in your postman client.
_One quick request here. Next time when you try hitting using the postman, in the response Headers, you will see debug_id which if you can share will help us to exactly find the reason for the error message returned._
For now, looking at Subject Authentication failed error message, this happens due to several reasons. Very quickly can you validate 1) Basically your account from where you wanted to process payments might not have been given with correct signature credentials while generating access token. 2) if there is an issue with PayPal-Auth-assertion header value wherein you are using the values interchanged between the 2 parties. 3) if your email ID format is not valid
Can you try reviewing once on the first 2 items? I see from your sour code screenshot, the email seems to be fine. Also when you try reviewing it and retrying it using postman, please do get the debug_id in response headers and share it with us.
Hey @thisisbalajibabu
I have created two REST API clients, using two different sandbox merchant accounts:
Client #1
Client #2
Then i logged in using second sandbox account (client named "Msp") and granted access to first sandbox account (client named "Prism").
I guess the issue here is that i've used NVP/SOAP API username (from client #1) when granting access. But i'm clearly not using NVP/SOAP, i'm using REST API.
But there is no option to grant permissions for REST API, if i try to use client ID as API username i get the not found error...
What am i doing wrong? How to grant permissions for REST API properly?
Here is debug_id: 37ec6c2be6482
@tamodaleko - Apologies for the delay.
For providing grant permission, kindly follow the documentation as below, https://developer.paypal.com/docs/connect-with-paypal/#user-experience https://developer.paypal.com/docs/connect-with-paypal/integrate/#5-get-authorization-code
The client Id and secret for MSP has to be accurate and it should not mix with Prism credential details while forming the JWT, else the user might not be recognized as a valid user at all. Also, can you make sure, you have the emails of the mentioned accounts to be confirmed email in PayPal account?
@thisisbalajibabu
The links you provided have nothing to do with my issue. I'm trying to do the batch payouts on behalf of other users.
With the information you provided i can only get user's basic information, they can't grant me permissions to do the batch payouts on their behalf.
I've contacted Paypal technical support and they told me that "PayPal-Auth-Assertion" header is not available for REST API. It's only available for NVP/SOAP Api.
They told me that i have to use Paypal Partner Program and Partner-Referrals API, but i'm still in the dark here.
You can close this since you are not understanding my issue.
Thanks for the help.
Hi @tamodaleko PayPal-Auth-Assertion header is available for REST. I am not sure about the other version you mention. Let me try to engage an integration engineer to help you here.
@thisisbalajibabu Any update on this? I happen to be in almost exactly same boat as @tamodaleko. I'm trying to proof-of-concept a site that will support taking payments on behalf of multiple merchants. Per the "API Requests" page in the REST documentation, my choices appear to be either storing a clientId and secret for every merchant and doing some kind of caching of bearer tokens per merchant, or to use the PayPal-Auth-Assertion header, as documented here:
You might want to use a JWT if you act on behalf of multiple merchants at the same time, because it is difficult and expensive to generate and manage multiple access tokens. Instead of managing multiple access tokens, you can use this header to provide a JWT assertion that identifies the merchant when you call the API.
However, when I build it as per that page (or the example on the Refund page it points to) and call https://api.sandbox.paypal.com/v1/oauth2/token, I get
{
"error": "invalid_subject",
"error_description": "Subject Authentication failed"
}
This happens regardless of whether I use the application's client Id or the target merchant's client ID in building the value. I'm using the application's client ID and secret for a basic Authorization
header.
@Bobsson
You should quit trying to achieve this using Paypal Payouts API. I was going back and forth with their Paypal technical support and it appears they have no idea if this is possible or not, but their documentation clearly says they support this option.
They suggested using Paypal Partner Program - https://developer.paypal.com/docs/api/partner-referrals/v1/ I've also signed up for this program and tried everything (also contacted the support - they couldn't help me at all) - and i wasn't able to configure 3rd party payouts.
So i had to stick with getting client id / secret from clients directly....
I was tried a lot for the same issue to fix it. So finally what I realized was made mistake when the generating base64 token.
Actually, I have faced the same issue with different APIs. I'll give my solution below
/**
*@description For generating assertion token for refund API call
* @param email correspond merchant email for generating this header for refund
* @returns string - base64 assertion token
*/
const generateAuthAssertionHeader = async email => {
const auth_1 = Buffer.from('{"alg":"none"}').toString('base64');
const auth_2 = Buffer.from(`{"email":"${email}","iss":"${PAYPAL_CLIENT_ID}"}`).toString('base64');
const auth_assertion_header = `${auth_1}.${auth_2}.`;
return auth_assertion_header;
};
const refundAmount = async (capture_id) => {
try {
const request = new checkout_nodeJs_sdk.payments.CapturesRefundRequest(capture_id);
const auth_header = await generateAuthAssertionHeader(order.owner_email);
request.headers['PayPal-Auth-Assertion'] = auth_header; // * Important
request.requestBody({});
refund = await paypal_client.client().execute(request);
return { id: refund.id, status: refund.status };
} catch (e) {
throw new UnprocessableEntity("Refund couldn't be processed.");
}
}
Finally, It was work for me. Hopefully, someone can fix the same issue in the future.
I was faced two errors Error: 1 before added "Paypal-Auth-Assertion" header.
{
statusCode: 403,
headers: {
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
'content-length': '441',
'content-type': 'application/json',
date: 'Thu, 15 Apr 2021 19:35:27 GMT',
'paypal-debug-id': 'f9185671ebddd',
connection: 'close'
},
_originalError: {
text: '{"name":"NOT_AUTHORIZED","message":"Authorization failed
due to insufficient permissions.","debug_id":"f9185671ebddd","details":[{"issue":"PERMISSION_DENIED","field":"capture_id","value":"39B3775678444273N","description":"You do not have permission to access or perform operations on this resource.","location":"path"}],"links":[{"href":"https://developer.paypal.com/docs/api/payments/v2/#error-PERMISSION_DENIED","rel":"information_link"}]}',
statusCode: 403,
headers: {
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
'content-length': '441',
'content-type': 'application/json',
date: 'Thu, 15 Apr 2021 19:35:27 GMT',
'paypal-debug-id': 'f9185671ebddd',
connection: 'close'
}
}
}
Error - 2: After made mistake while generating base64 token.
{
statusCode: 401,
headers: {
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
'content-length': '79',
'content-type': 'application/json',
date: 'Thu, 15 Apr 2021 19:36:35 GMT',
'paypal-debug-id': '893902251901e',
connection: 'close'
},
_originalError: {
text: '{"error":"invalid_subject","error_description":"Subject Authentication failed"}',
statusCode: 401,
headers: {
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
'content-length': '79',
'content-type': 'application/json',
date: 'Thu, 15 Apr 2021 19:36:35 GMT',
'paypal-debug-id': '893902251901e',
connection: 'close'
}
}
}
It was resolved after properly generated the base64 token.
Hi @all. If someone is still stuck on this here is the nodejs solution that worked for me.
const header = Buffer.from(JSON.stringify({ alg: "none" })).toString("base64");
const payload = Buffer.from(JSON.stringify({ iss: PAYPAL_CLIENT_ID, payer_id: merchant_id })).toString("base64")
Just in case someone is as careless as I am, pay attention, there is a trailing dot at the end:
const auth_assertion_header = `${auth_1}.${auth_2}.`;
I was literally spent so much wasted time while following the PayPal standard checkout documentation. The first example for generating the auth assertion ALWAYS returns a "Subject Authentication failed" error.
Don't follow the first example PayPal gives for generating the header, use the SECOND ONE. This is a working function I made in node.js:
export const getAuthAssertionValue = (paypal_client_id, sellerPayerId) => {
const clientID = paypal_client_id;
const merchantIDOrEmail = sellerPayerId;
const auth1 = Buffer.from('{"alg":"none"}').toString("base64");
const auth2 = Buffer.from(`{"iss":${clientID},"payer_id":${merchantIDOrEmail}}`).toString("base64");
return `${auth1}.${auth2}.`;
}
Hello!
Is third party payments working for Payouts API? In documentation it clearly says that we can use this header to do the third party api calls, but this is not working?
https://developer.paypal.com/docs/api/reference/api-requests/#http-request-headers