Connection to Amazon Selling Partner API with curl - amazon

I have to add more details in my question, so here is my try to get orders from my seller central account:
$host = 'sellingpartnerapi-na.amazon.com'; // is this the right URL for REST API to get Orders from my seller central account?
$accessKey = 'AK...YOX.........';
$secretKey = 'K...........';
$region = 'us-east-1';
$service = 'execute-api';
$requestUrl = 'https://sandbox.sellingpartnerapi-na.amazon.com/orders/v0/orders'; // '<full url>';
$uri = '/orders/v0/orders'; // '<method path>';
$httpRequestMethod = 'GET'; // '<http verb>';
I used this sample files: https://github.com/avi-wish/aws4-signature-php
unfortunately there is no example URL for variable $host
If I test the connection, this is my response:
Response:403
{
"errors": [
{
"message": "Access to requested resource is denied.",
"code": "Unauthorized",
"details": "Access token is missing in the request header."
}
]
}
I found a possible solution here:
https://github.com/amzn/selling-partner-api-docs/issues/52#issuecomment-713522351
but it's not working for me.
Is that necessary to create a IAM User before? Here is the way I created it:
https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#registering-your-selling-partner-api-application
I think a lot of people have the same problem. Hope someone can give me a hint.
after getting the access token, the curl return the error :
[message] => Access to requested resource is denied. [code] => MissingAuthenticationToken
function get_orders(){
$this->host = 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders';
debug('>>get list of orders');
$data = "x-amz-date&access_token={$this->access_token}";
$curl = curl_init($this->host . '/orders/v0/orders');
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json;charset=UTF-8')
);
$result = curl_exec($curl);
curl_close($curl);
$obj = json_decode($result,true);
debug($obj);
}

Unfortunately you give very little information about what you want to do. There are two ways to authorize the SP-API that is set via the grant-type.
I suppose you want to authorize yourself and not a vendor.
Then you have to send your request to the following endpoint:
api.amazon.com/auth/o2/token
You have to specify the $host with api.amazon.com.
The request method will be POST.
You pass the parameters to the http Body:
grant_type, refresh_token, client_id, client_secret
Please have a look at the following link:
Connecting to the Selling Partner API
After you have done all this the same way, you will get the following answer:
{
"access_token":"Atza|IwEBIJR-9fxxxxxxxxxxxxxxxxxxxxxx",
"refresh_token":"Atzr|IwEBIxxxxxxxxxxxxxxxxxxxxxxxx",
"token_type":"bearer",
"expires_in":3600
}
Now you can use the access_token to sign your requests.
In the following, I also recommend you to use my post from another answer to sign a request and successfully send a request.
Answer: 64858116

public function GetAcessToken()
{
$RefeshToken = $this->RefreshToken;
$data = "grant_type=refresh_token"
."&refresh_token=". $RefeshToken
."&client_id=".$this->ClientID
."&client_secret=".$this->ClientSecret;
$curl = curl_init($this->UrlForAmazonToken);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8')
);
$result = curl_exec($curl);
curl_close($curl);
$obj = json_decode($result,true);
$this->AccessToken = $obj['access_token'] ;
return $this->AccessToken;
}
It works for me.

Related

Azure: Get TTS File with Curl -Cognitive Speech

How do I get a correct TTS Response back, with an audio file?
The token works, but the TTS request not!
{"code":"404","message": "Resource not found"}
For the Token iam using this URL: https://westeurope.api.cognitive.microsoft.com/sts/v1.0/issuetoken
i found this Code Example on Azure this site, but its not working :-/ (https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/rest-text-to-speech#sample-request-1)
$token=getToken();
$cont="<speak version='1.0' xml:lang='en-US'><voice xml:lang='en-US' xml:gender='Male'
name='en-US-ChristopherNeural'>
Microsoft Speech Service Text-to-Speech API
</voice></speak>";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://westeurope.api.cognitive.microsoft.com/cognitiveservices/v1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($cont));
$headers = array();
#$headers[] = 'Ocp-Apim-Subscription-Key: xxxxxxxxxxxx';
$headers[] = 'X-Microsoft-OutputFormat: raw-24khz-16bit-mono-pcm';
$headers[] = 'Content-Type: application/ssml+xml';
#$headers[] = 'Host: westus.tts.speech.microsoft.com';
$headers[] = 'Content-Length: '.strlen($cont);
$headers[] = 'Authorization: Bearer '.$token;//Token okay
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
print_r($result); //{"code":"404","message": "Resource not found"}
OK, now it works,
i put the option curl_setopt($ch, CURLOPT_HEADER, 1);
to get some more information about the response, and it shows me this error
Required header User-Agent missing.
so i add one more headerParameter to it and now it works:
$headers[] = 'User-Agent: myApp/1.0.0';

Impossible to get an access_token for Instagram Basic Display API

I'm trying to get an access_token from Instagram to use their Basic Display API for a new app (simply display tweets on a webpage).
I followed these steps: https://developers.facebook.com/docs/instagram-basic-display-api/getting-started
But I'm stuck at Step 5: Exchange the Code for a Token
The cURL request always returns a 400 error with the message: "Matching code was not found or was already used"
However, after many tests, I got an access_token one time only, but it expired about one hour later. This seems to be very random.
The Instagram Basic Display API seems rather new. A while ago, I have used apps created on the https://www.instagram.com/developer/ website and it used to work. Now this site display this message:
UPDATE: Starting October 15, 2019, new client registration and permission review on Instagram API platform are discontinued in favor of the Instagram Basic Display API.
... with a link to the developers.facebook.com.
I tried using the command-line tool as per the original docs(https://developers.facebook.com/docs/instagram-basic-display-api/getting-started), but no luck...
Here's what to do in 3 easy steps:
First thing: Install Postman https://www.postman.com/downloads/
Make a POST request to https://api.instagram.com/oauth/access_token with the parameters in the body, NOT the params. Make sure that the x-www-form-urlencoded option is enable.
You should now get a status of 200 OK and a response with both access_token and user_id.
{
"access_token": "IGQVJYUXlDN...",
"user_id": 17841400...
}
Happy days!!
See the screenshot for the correct settings:
I just succeeded by removing the trailing #_ at the end in the code they give you. Not sure if that was your issue?
https://developers.facebook.com/support/bugs/436837360282557/
I had this problem when i was trying implement a application.
My problem was the code generated when you allow the permissions.
Try to remove #_ from the end of the generated code and try generate the token again
Generated code example:
AQBvrqqBJJTM49U1qTQWRMD96oRyMR3B_04JSfjc-nUIi0iGbSc3x_EceggQi9IyG3B3Rj3ocreMThQoPJbPpeXLUM4exJMy4o01fXcRtT_I9NovaNAqmWSneFt3MYv_k7ifAUUeMlC050n5xnjQP6oAvDBfCFQvTdrFaR95-5i71YsfQlmjYWDG6fcWRvOB9nqr6J9mbGMXMi9Y4tKlSfElaYm0YKRijZQDG2B5PaxQ8A #_
Generated code edited:
AQBvrqqBJJTM49U1qTQWRMD96oRyMR3B_04JSfjc-nUIi0iGbSc3x_EceggQi9IyG3B3Rj3ocreMThQoPJbPpeXLUM4exJMy4o01fXcRtT_I9NovaNAqmWSneFt3MYv_k7ifAUUeMlC050n5xnjQP6oAvDBfCFQvTdrFaR95-5i71YsfQlmjYWDG6fcWRvOB9nqr6J9mbGMXMi9Y4tKlSfElaYm0YKRijZQDG2B5PaxQ8A
I was also having the same problem, I solved clearing the cache, coockie and other browser data.
Then I made a new request.
Try it, it worked with me.
I found the solution.
The direct uri must the same as you use in the beginning.
ex. You use
www.abc.com/auth
to get the code. When you exchange the token the redirect_uri must be the same as
www.abc.com/auth
I was using the old Instagram API as well. I had to change a few things to make my code work on the new API. Not sure what you're using, this is how I did it with PHP.
$url = 'https://api.instagram.com/oauth/access_token';
$fields = array(
'app_id' => 'YOUR_APP_ID',
'app_secret' => 'YOUR_APP_SECRET_ID',
'grant_type' => 'authorization_code',
'redirect_uri' => 'YOUR_REDIRECT_URL',
'code' => $code
);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
//get the access token from the string sent from Instagram
$splitString = explode('"access_token":', $result);
$removeRest = explode(',', $splitString[1]);
$withSpace = str_replace('"','', $removeRest[0]);
$access_token = str_replace(' ','', $withSpace);
I am using PHP but without using any lib. Maybe this one help you.
curl.php
class InstagramApi
{
public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) {
$url = 'https://api.instagram.com/oauth/access_token';
$curlPost = 'app_id='. $client_id . '&redirect_uri=' . $redirect_uri . '&app_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($http_code != '200')
throw new Exception('Error : Failed to receieve access token');
return $data;
}
index.php
include "curl.php";
include "instagram_keys.php"; // holding APP ID, SECRET KEY, REDIRECT URI
$instagram_ob = new InstagramApi();
$insta_data = $instagram_ob->GetAccessToken(INSTAGRAM_CLIENT_ID, INSTAGRAM_REDIRECT_URI, INSTAGRAM_CLIENT_SECRET, $_GET['code']);
echo $insta_data['access_token'];
echo $insta_data['user_id'];
NOTE: $_GET['code'] is required and you should know how to get the code. Read here

Download envelope pdf with curl

I'm trying to download a docusign envelope with curl. I'm accessing the envelope but the pdf won't show. I see a web page with symbols and can't save the pdf of the envelope. Any help appreciated.
require_once('rest/autoload.php');
$url = "https://demo.docusign.net/restapi/v2/login_information";
$header = "<DocuSignCredentials><Username>" .
$config['username_docusign'] . "</Username><Password>" .
$config['password_docusign'] . "</Password><IntegratorKey>" .
$config['api_firmadoc'] . "</IntegratorKey></DocuSignCredentials>";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("X-DocuSign-Authentication:
$header"));
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 200 ) {
echo "error calling webservice, status is:" . $status;
exit(-1);
}
$response = json_decode($json_response, true);
$accountId = $response["loginAccounts"][0]["accountId"];
$baseUrl = $response["loginAccounts"][0]["baseUrl"];
curl_close($curl);
$curl = curl_init("https://demo.docusign.net/restapi/v2/accounts/1319127/envelopes/cc4aa62f-506c-4ee4-b6a3-dc9ae3e5fa14/documents/combined" );
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/pdf',
'X-DocuSign-Authentication: { "Username":"****", "Password":"****",
"IntegratorKey":"*****" }' )
);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
echo $json_response;
I expected a pdf but i receive a web page with symbols
You're using the obsolete legacy authentication. Much better idea would be to use OAuth.
You're not setting the Content-Type of your php page, instead you're setting the Content-Type of your request to DocuSign. (Which is also wrong, you should be setting the Accept header to application/pdf)
To set the Content-Type of your page, add the following at the top of your php script: header("Content-type:application/pdf"); See this SO answer.
Check out the PHP JWT and Authorization Code Grant examples for more info.
Thank you for integrating with DocuSign!

Sorry, this page isn't available in instagram

I am having difficulty in getting the latest post in Instagram.
function fetchData($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$result = fetchData("https://api.instagram.com/v1/users/{clientid}/media/recent/?access_token={accesstoken}&count=3");
$result = json_decode($result);
But I get the message like this:
Sorry the page is not available. The link you followed may be broken,
or the page may have been removed.
Usually happens if you have username instead of user-id in the API url
you have {clientid}, what is the value?, it should be user-id not a username, and definitely not your app's client-id, it should be all numbers.
You can get user-id by using the users/search URL
https://api.instagram.com/v1/users/self/?access_token={Access_token}
API to search for a username and get the corresponding user-id that matches the username you searched in the API response.

Instagram API Enforce Signed Requests Signature Does Not Match Error

Instagram Documentation: https://instagram.com/developer/secure-api-requests/
Goal: Comply with the [now mandatory] Enforce Signed Requests feature using Instagram API.
Functional issue: without compliance IG Like limits are 30 per hour. Complying allows for 100 Likes per hour
Technical issue: The following error is returned when making a simple call to the API for media:
{"code": 403, "error_type": "OAuthForbiddenException", "error_message": "Invalid signed-request: Signature does not match"}
Instagram Client Set Up: Client ID, Client Secret, Redirect URI have all been verified to match those used in all portions of the PHP code. Both "Disable implicit OAuth" and "Enforce signed requests" are checked.
Code Explanation: Three distinct pieces of code are needed to create the handshake with IG: 1. Header 2. Access Token [i.e. "access_token"] 3. Call with Sig [i.e. "sig" - not to be confused with "signature"]. I have confirmed that the same client_id, client_secret and access_token are used throughout all pieces of code. NOTE: Parts 1 and 2 work[ed] fine prior to the mandatory compliance. They still work fine, but I only get 30 Likes/hr [i.e. the main functional issue]
Header Code:
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$this->signature = $ip .'|'. hash_hmac('sha256', $ip, $this->settings['client_secret'], false);
Access Token Code, which returns successfully with an array similar to {"access_token":"11deadbee7.7dded5e.c0d656eead134218beef31a61b45e4d9",...}
$apiData = array(
'grant_type' => 'authorization_code',
'client_id' => $this->getApiKey(),
'client_secret' => $this->getApiSecret(),
'redirect_uri' => $this->getApiCallback(),
'code' => $code
);
$ch = curl_init();
$xHeaderFront = 'X-Insta-Forwarded-For:';
$xHeader = $xHeaderFront.$this->signature;
curl_setopt($ch, CURLOPT_URL, $apiHost);
curl_setopt($ch, CURLOPT_POST, count($apiData));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($apiData));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$jsonData = curl_exec($ch);
curl_close($ch);
Call with Sig. This returns the error {"code": 403, "error_type": "OAuthForbiddenException", "error_message": "Invalid signed-request: Signature does not match"}:
$params = array(); //temporary to force a simple set of parameters
$params['count']=10;
$params['access_token'] = $this->getAccessToken(); //11deadbee7.7dded5e.c0d656eead134218beef31a61b45e4d9 masked, but kept for ease of comparison]
$endpoint = '/media/657988443280050001_25025320'; //temporary
$sig = $endpoint;
ksort($params);
foreach ($params as $key => $val) {
$sig .= "|$key=$val";
}
$enforcedSig = hash_hmac('sha256', $sig, $secret, false);
$apiCall = 'https://api.instagram.com/v1/media/657988443280050001_25025320/likes?sig='.$enforcedSig.'&count=10&access_token='.$params['access_token'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiCall);
$xHeaderFront = 'X-Insta-Forwarded-For:';
$xHeader = $xHeaderFront.$this->signature;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json',$xHeader));
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$jsonData = curl_exec($ch);
curl_close($ch);
Your $endpoint seems to be wrong.
Add "/likes".
$endpoint = '/media/657988443280050001_25025320/likes'; //temporary

Resources