Unsupported_grant_type error using react native's fetch() when doing POST request

I'm not sure what is wrong with my request format, I tried dozens of format from people around SO and other places but nothing works for me. Here's a snippet of my code:

This is the content of the function that creates the endpoint, header, and body then pass it to an all purpose function on another file called fetchAPI.

var endpoint = "oauth/token";

let userData = {
    "username" : user[0], //MemberCenterLanding
    "password" : user[1], //testpass
    "grant_type" : 'password'

  let header = {
   "Authorization":"Basic TWVtYmVyQ2VudGVyTGFuZGluZzp0ZXN0cGFzcw==",
   "Content-Type": "application/x-www-form-urlencoded",

  return dispatch => {

  return fetchAPI(endpoint,'POST', header, userData)
  .then((json) => { //not relevant after this point

and this is the fetchAPI function.

export function fetchAPI(endpoint, method, header, data) {

let url = '' + endpoint;
   //let url ='http://secure.cbn.net.id:8080/'+ endpoint;

let options = {
        method: method,
        headers: header,
        data: JSON.stringify(data)

return fetch(url, options)
    .then(response => {
        return response.json()
            .then((json) => {
              alert("request content:\n"+ JSON.stringify(options, undefined, 2) + "\n\nurl: \n"+ url + "\n\nresponse status: \n"+ response.status + "\n\nJSON content:\n"+JSON.stringify(json,undefined,2));
                if (response.status === 200 || response.status === 201) {
                    return json;
                } else if (response.status === 408) {
                    throw('Request Timeout');
                else if (response.status === 400){
                      throw ('Bad request');   //the request always end up here
                 else {
                    if (json.errors) {
                      console.log("json error");
                    } else {
                      console.log("unknown error");
                        throw('unknown error');
    .catch(error => {//not relevant after this point

And as you can see I printed the inside of the request options for ease of debugging so I know exactly what's happening along with the url, response status and returned JSON file: enter image description here

I have tried different formats for everything and the only constant I can find is that the body a.k.a data part of the option that contains the username, password and grant-type is wrong. because changing anything else doesn't affect anything.

Everything always result in response status = 400 and JSON content: "unsupported_grant_type". Though some posts suggest that it might not have anything to do with the grant type at all but I tried exactly the same input in postman and it works. I even tried non-stringified version of data, FormData version, as well as the normal string sequence build using array.join() method, but nothing's fruitful.

Current suspicion:

  1. Maybe the api doesn't deal with input from react native somehow
  2. I completely misunderstood the requirement for the request format (I've checked multiple times though even tried copying the code generated from postman directly)
  3. Theres supposed to be some sort of setup/config need to be done for react native to work with api (though I've never encountered such article before)

I don't know where else to look, any insight would be highly appreciated :)