1

I need to integrate my mobile app with paypal. For this I chose Rest API. But I can't get access token! I use Mozilla Firefox just for testing network operations. And here my request

https://api.sandbox.paypal.com/v1/oauth2/token

Here Header

ost: api.sandbox.paypal.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: application/json
Accept-Language: en-US
Accept-Encoding: gzip, deflate
Cache-Control: max-age=0, no-cache
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Pragma: no-cache
Referer: https://www.mozilla.org/ru/firefox/42.0/whatsnew/?oldversion=41.0.2
Content-Length: 172
Origin: https://www.mozilla.org
Connection: keep-alive

And here body with params

username=AWFcJ...FsdE:EFCK..Dfr43d
grant_type=client_credentials

In username I put my Client Id and Secret from dashboard.

Response is

400 Bad request. 
error:invalid_client
eror_description:Client credentials are missing

What I did wrong? Please help me

Mikhail Valuyskiy
  • 1,238
  • 2
  • 16
  • 31

2 Answers2

1

You can try this, the PayPalConfigDto contains some basic stuff that you need to provide. Please bear in mind that the values should be stored in the app settings file of your app and this is only a simple example:

public class PayPalConfigDto
{
    public string BaseUrl { get; set; }

    public string TokenUrl => $"{BaseUrl}/v1/oauth2/token";

    public string ClientId { get; set; }

    public string ClientSecret { get; set; }
}

The PayPal API response object:

public class TokenDto
{
    public string Scope { get; set; }

    public string Access_token { get; set; }

    public string Token_type { get; set; }

    public string App_id { get; set; }

    public string Expires_in { get; set; }

    public string Nonce { get; set; }
}

The PayPalContext class:

public class PayPalContext
{
    private HttpClient _httpClient;

    private PayPalConfigDto _payPalConfig;

    public PayPalContext(HttpClient httpClient, PayPalConfigDto payPalConfig)
    {
        _httpClient = httpClient;
        _payPalConfig = payPalConfig;
    }

    public virtual async Task<string> GetToken()
    {
        var url = $"{_payPalConfig.TokenUrl}?grant_type=client_credentials";
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
            Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_payPalConfig.ClientId}:{_payPalConfig.ClientSecret}")));

        var responseTask = _httpClient.PostAsync(url, null);
        responseTask.Wait();
        var response = responseTask.Result;

        var result = await response.Content.ReadAsStringAsync();
        if (!response.IsSuccessStatusCode)
        {
            var errorMessage = response.ToString();
            throw new Exception($"An issue occurred during the trial of getting PayPal token. {errorMessage}");
        }
        var tokenDto = JsonConvert.DeserializeObject<TokenDto>(result);

        return tokenDto.Access_token;
    }

}

The GetToken method needs to encode the credentials and based on this answer you can do this quite easily with

new AuthenticationHeaderValue("Basic",
            Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_payPalConfig.ClientId}:{_payPalConfig.ClientSecret}")));

To test all the stuff you can just create a simple test class e.g.:

//[Ignore]
public class PayPalContextTests
{
    readonly PayPalConfigDto PayPalConfig = new PayPalConfigDto()
    {
        BaseUrl = "https://api.sandbox.paypal.com",
        ClientId = "your ClientId",
        ClientSecret = "your ClientSecret"
    };

    [Test]
    public async Task Should_return_valid_token()
    {
        var httpClient = new HttpClient();           
        var context = new PayPalContext(httpClient, PayPalConfig);
        var token = await context.GetToken();
        Assert.IsFalse(string.IsNullOrEmpty(token));
    }
}

I also think this can be helpful if you'd like to get a token via Postman, which is a tip to the thing you can find in the main PayPal documentation

GoldenAge
  • 2,918
  • 5
  • 25
  • 63
0

Hi you approach is right

try this

  public string clientId=<your client id>;
  public string secret=<your secret>;
  public string accessToken='';

  public void accessToken()
  {
      string input=clientId+':'+secret;
      Blob myBlob = Blob.valueof(input);
      string paramvalue = EncodingUtil.base64Encode(myBlob);
      Http http=new Http();
      HttpRequest req=new HttpRequest();
      req.setMethod('POST');
      string endpoint='https://api.sandbox.paypal.com/v1/oauth2/token?grant_type=client_credentials';
      req.setEndpoint(endpoint);
      req.setHeader('Authorization','Basic '+paramvalue);
      req.setHeader('Accept','application/json');
      req.setHeader('content-type','application/x-www-form-urlencoded');
      req.setHeader('Accept-Language','en_US');
      req.setHeader('Cache-Control','no-cache');
      req.setBody('grant_type=client_credentials');
      HttpResponse res = new HttpResponse();
      res = http.send(req);
      if(res.getStatusCode()==200)
      {
           Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
           accessToken = (string)results.get('access_token');
           system.debug(accessToken);
      }



  }
  • 1
    I think it would be awesome if you explain your code a little. – Tarvo Mäesepp Aug 16 '16 at 17:57
  • for this I use basic auth and in basic auth ,here " input "is concatination of client id and secret and ':' between them, the Blob.valueof() will convert string to blob and EncodingUtil.base64Encode() will use that value to convert it into a value which is passed a key value with 'Basic' keyword from key "Authorization" as u can see that in code. please tell me if u got any issue thnks – Anuj Huria Aug 16 '16 at 18:36