I am trying to get an OAuth2 Token via XHR-Request in TypeScript like mentioned on this side(https://developer.paypal.com/docs/integration/direct/make-your-first-call/). My code so far:
var clientID = <clientID>;
var secret = <mySecret>;
var oReq = new XMLHttpRequest();
oReq.open("POST", "https://api.sandbox.paypal.com/v1/oauth2/token", true);
oReq.setRequestHeader('grant_type', "client_credentials");
oReq.setRequestHeader('Username', this.clientID);
oReq.setRequestHeader('Password', this.secret);
oReq.setRequestHeader('Content-type', "application/x-www-form-urlencoded");
oReq.setRequestHeader('Accept', "application/json");
oReq.setRequestHeader('Accept-Language', "en_US");
oReq.onreadystatechange = function () {
if (oReq.readyState === 4) {
if (oReq.status === 200) {
console.log(oReq.responseText);
} else {
console.log("Error: " + oReq.status);
}
}
console.log("Status: " + oReq.status);
};
console.log("Status: " + oReq.status);
oReq.send();
Sadly I keep getting 401 as response. I already tried the curl command with the same clientID and secret, which worked for me. Can someone tell me whats wrong with me code?
The request you’re getting the 401 response for isn’t your POST
request but instead the CORS preflight OPTIONS
request that the browser automatically does on its own.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests has details about what triggers browsers to do a preflight but what it comes down to in this specific case is that you’re adding grant_type
, Username
, and Password
request headers to the request in order to do the authentication needed—but your browser makes the preflight OPTIONS
request without those headers (because the purpose of the preflight is to ask the server to indicate whether it’s OK with receiving requests that include those request headers).
And so what happens is the following (reproduced using curl
just for illustration purposes):
$ curl -X OPTIONS -i -H "Origin: http://example.com" \
'https://api.sandbox.paypal.com/v1/oauth2/token'
HTTP/1.1 401 Unauthorized
Date: Wed, 09 Aug 2017 09:08:32 GMT
Server: Apache
paypal-debug-id: f8963606c5654
Access-Control-Allow-Origin: http://example.com
Access-Control-Expose-Headers: False
HTTP_X_PP_AZ_LOCATOR: sandbox.slc
Paypal-Debug-Id: f8963606c5654
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.API.1%26silo_version%3D1880%26app%3Dapiplatformproxyserv%26TIME%3D282167897%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Wed, 09 Aug 2017 09:38:32 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Content-Length: 0
Connection: close
Content-Type: text/plain; charset=ISO-8859-1
That is, the https://api.sandbox.paypal.com/v1/oauth2/token
endpoint apparently requires authentication even for OPTIONS
requests. Because it does, there’s no way you can make POST
requests to that endpoint directly from your frontend JavaScript code running in a browser.
So you’ll instead need to make the request from your backend code.