The fulfilment response is visible in diagnostic info in the Dialogflow environment. But it's not showing up when I test it in Actions on Google. Anyone who knows how to let it work? Here is my webhook code:
<?php
$method = $_SERVER['REQUEST_METHOD'];
if($method == 'POST'){
$requestBody = file_get_contents('php://input');
$json = json_decode($requestBody);
$text = $json->queryResult->queryText;
$date = (!empty($json->queryResult->parameters->date)) ? $json->queryResult->parameters->date : '';
$environment = (!empty($json->queryResult->parameters->environment)) ? $json->queryResult->parameters->environment : '';
$intent = (!empty($json->queryResult->intent->displayName)) ? $json->queryResult->intent->displayName : '';
$responseText = prepareResponse($intent, $text, $date, $environment);
$response = new \stdClass();
$response->speech = $responseText;
$response->displayText = $responseText;
$response->source = "webhook";
header("Content-type:application/json");
echo json_encode($response);
}
else
{
echo "Method not allowed";
}
function prepareResponse($intent, $text, $date, $environment)
{
return "You said: " . $text . " | I found Intent: " . $intent . " | with parameters: date=" . $date . " environment=" . $environment;
}
?>
Responses for Actions on Google should be in an object under the payload attribute that contains a single attribute google with the AoG response format.
I haven't tested it, and this may not be the best way to build it, but something like the following should work:
$response->payload = array(
"google" => array(
"expectUserResponse" => TRUE,
"richResponse" => array(
"items" => array(
array(
"simpleResponse" => array(
"textToSpeech" => $responseText
)
)
)
)
)
);
I am Trying to get the Response back after the success payment with the sofort integration but not getting anything in response;
Error: Error: 7000:Invalid XML.
Here is the success function:
public function successAction()
{
$configkey = 'my_key';
$SofortLib_Notification = new Notification();
$TestNotification = $SofortLib_Notification->getNotification(file_get_contents('php://input'));
echo $SofortLib_Notification->getTransactionId();
echo '<br />';
echo $SofortLib_Notification->getTime();
echo '<br />';
$SofortLibTransactionData = new TransactionData($configkey);
$SofortLibTransactionData->addTransaction($TestNotification);
$SofortLibTransactionData->setApiVersion('2.0');
$SofortLibTransactionData->setTime('2012-11-14T18:00+02:00', '2012-12-13T00:00+02:00');
$SofortLibTransactionData->setNumber(5, 1);
$SofortLibTransactionData->sendRequest();
echo '<pre>'; print_r($SofortLibTransactionData);
//exit();
$output = array();
$methods = array(
'getAmount' => '',
'getAmountRefunded' => '',
'getCount' => '',
'getPaymentMethod' => '',
'getConsumerProtection' => '',
'getStatus' => '',
'getStatusReason' => '',
'getStatusModifiedTime' => '',
'getLanguageCode' => '',
'getCurrency' => '',
'getTransaction' => '',
'getSenderAccountNumber' => '',
'getSenderBankCode' => '',
'getSenderCountryCode' => '',
'getSenderBankName' => '',
'getSenderBic' => '',
'getSenderIban' => '',
);
foreach($methods as $method => $params) {
if(count($params) == 2) {
$output[] = $method . ': ' . $SofortLibTransactionData->$method($params[0], $params[1]);
} else if($params !== '') {
$output[] = $method . ': ' . $SofortLibTransactionData->$method($params);
} else {
$output[] = $method . ': ' . $SofortLibTransactionData->$method();
}
}
if($SofortLibTransactionData->isError()) {
echo $SofortLibTransactionData->getError();
} else {
echo implode('<br />', $output);
}
// $sofortTans = new TransactionData;
// echo '<pre>';print_r($sofortTans);
// $viewModel = new ViewModel(array('status' => $sofortTans));
// $viewModel->setTemplate('layout/pay_done');
// return $viewModel;
}
And Here the Action method in my contrller to send the request can you please guide me how i can get the Response back?
$configkey = 'my_config_key';
$Sofortueberweisung = new SofortUeberWeisung($configkey);
$Sofortueberweisung->setAmount($request->getPost('grandtotal_price'));
$Sofortueberweisung->setCurrencyCode('EUR');
$Sofortueberweisung->setReason('Single Coupon Order', 'Voucher Codes');
$Sofortueberweisung->setSuccessUrl('http://localhost:8088/payment/success', false);
$Sofortueberweisung->setCustomerprotection(true);
$Sofortueberweisung->sendRequest();
if($Sofortueberweisung->isError()) {
// SOFORT-API didn't accept the data
echo $Sofortueberweisung->getError();
} else {
// get unique transaction-ID useful for check payment status
$transactionId = $Sofortueberweisung->getTransactionId();
// buyer must be redirected to $paymentUrl else payment cannot be successfully completed!
$paymentUrl = $Sofortueberweisung->getPaymentUrl();
$this->redirect()->toUrl($paymentUrl);
//header('Location: '.$paymentUrl);
}
And I am Using this API Library, Sofort API Library
Add parameter ?transId=-TRANSACTION- with your success_url and than you will be able to get that from Response !
$transNumber = $this->getRequest()->getQuery('transId');
$fields = $sofortObj->getTransactionData($transNumber);
You've all transaction data with you in $fields
Previously i was used http server for my linkedin login. Now I changed https server for my entire site. But now i cannot show login details after changed that. Here i post my function, In this fuction i also changed https. But yet not i show the details. I use this function in codeigniter.
public function login(){
$client_id = $this->config->item('linkedin_app_id');
$redirect_uri = base_url().'linkedinLogin';
if (isset($_GET['error'])) {
echo $_GET['error'] . ': ' . $_GET['error_description'];
} elseif (isset($_GET['code'])) {
$this->loginAccessToken();
$user = $this->login_fetch('GET', '/v1/people/~:(id,firstName,lastName,email-address,picture-url)');//get name
$email = $user->emailAddress;
$user_name = $user->firstName;
$last_name = $user->lastName;
$social_id = $user->id;
$profile_image_url = 'user-thumb.png';
echo "<pre>";print_r($user); die;
if($email != '')
{
$googleLoginCheck = $this->user_model->googleLoginCheck($email);
if($googleLoginCheck > 0)
{
//echo "login";
$getGoogleLoginDetails = $this->user_model->google_user_login_details($email);
//echo "<pre>";print_r($getGoogleLoginDetails);die;
$userdata = array(
'fc_session_user_id' => $getGoogleLoginDetails['id'],
'session_user_email' => $getGoogleLoginDetails['email']
);
//echo "<pre>";print_r($userdata);die;
$this->session->set_userdata($userdata);
if($this->data['login_succ_msg'] != '')
$lg_err_msg = $this->data['login_succ_msg'];
else
$lg_err_msg = 'You are Logged In ...';
$this->setErrorMessage('success',$lg_err_msg);
redirect(base_url());
}
else
{
$google_login_details = array('social_login_name'=>$user_name,'social_login_unique_id'=>$social_id,'screen_name'=>$user_name,'social_image_name'=>'','social_email_name'=>$email,'loginUserType'=>'google');
//echo "<pre>";print_r($google_login_details);die;
//echo "redirect to registration page";
$social_login_name = $user_name;
$this->session->set_userdata($google_login_details);
$firstname = $user_name;
$lastname = $last_name;
$orgPass = time();
$pwd = md5($orgPass);
$Confirmpwd = $orgPass;
$username = $user_name;
$condition = array ('email' => $email);
$duplicateMail = $this->user_model->get_all_details ( USERS, $condition );
$expireddate = date ( 'Y-m-d', strtotime ( '+15 days' ) );
$dataArr = array('firstname'=>$firstname,'lastname'=>$lastname,'user_name'=>$firstname,'group'=>'User','image'=>$profile_image_url,'email'=>$email,'password'=>$pwd,'status'=>'Active','expired_date'=>$expireddate,'is_verified'=>'No','loginUserType'=>'linkedin','google'=>'Yes','created'=>date('Y-m-d H:i:s'));
$this->user_model->simple_insert(USERS,$dataArr);
$lstID = $this->db->insert_id();
//echo $this->db->last_query(); die;
$userdata = array (
'quick_user_name' => $firstname,
'quick_user_email' => $email,
'fc_session_user_id' => $lstID,
'session_user_email' => $email
);
$this->session->set_userdata ( $userdata );
$this->setErrorMessage('success','Registered & Login Successfully');
redirect(base_url());
}
}
else
{
redirect('');
}
}else {
header("Location:https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=$client_id&redirect_uri=$redirect_uri&state=987654321&scope=r_basicprofile%20r_emailaddress%20w_share");
}
}
public function loginAccessToken() {
$params = array(
'grant_type' => 'authorization_code',
'client_id' => $this->config->item('linkedin_app_id'),
'client_secret' => $this->config->item('linkedin_app_key'),
'code' => $_GET['code'],
'redirect_uri' => base_url().'linkedinLogin'
);
// Access Token request
$url = 'https://www.linkedin.com/uas/oauth2/accessToken?' . http_build_query($params);
// Tell streams to make a POST request
$context = stream_context_create(
array('https' =>
array('method' => 'POST',
)
)
);
// Retrieve access token information
$response = file_get_contents($url, false, $context);
// Native PHP object, please
$token = json_decode($response);
// Store access token and expiration time
$_SESSION['access_token'] = $token->access_token; // guard this!
$_SESSION['expires_in'] = $token->expires_in; // relative time (in seconds)
$_SESSION['expires_at'] = time() + $_SESSION['expires_in']; // absolute time
return true;
}
public function login_fetch($method, $resource, $body = '') {
$opts = array(
'https' => array(
'method' => $method,
'header' => "Authorization: Bearer " .
$_SESSION['access_token'] . "\r\n" .
"x-li-format: json\r\n"
)
);
$url = 'https://api.linkedin.com' . $resource;
// if (count($params)) {
// $url .= '?' . http_build_query($params);
// }
$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);
return json_decode($response);
}
Here look the login() fuction. I print the user details. But i got empty window only
echo "<pre>";print_r($user); die;
But when i use http, i got the user details. Can help me anyone?
I only want to grab information using the Quickbooks API (that seems like this should be possible via their API). I setup an App on their Development site, linked it to the Quickbooks Company I created, and am trying to run this code to get anything from the curl response, but all I am getting are Authorization Failure (401) Messages. Why is it not being authorized? Been studying this site for 12 hours and none of their examples that they provide even work. Am using this page as a reference: https://developer.intuit.com/docs/0050_quickbooks_api/0010_your_first_request/rest_essentials_for_the_quickbooks_api and this: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/0015_calling_data_services#/The_authorization_header
My index.php file is as follows:
<?php
define('IS_SANDBOX', 1);
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'oAuth.php');
// GET baseURL/v3/company/companyID/resourceName/entityID
// consumer and consumer_secret
$oAuth = new QuickBooks_IPP_OAuth('qyprdwX21R3klmiskW3AaYLnDRGNLn', 'FDPpxScC6CIgoA07Uc2NYtZJk45CqNDI1Gw4zntn');
$request = array(
'url' => array(
'base_request_uri' => IS_SANDBOX == 1 ? 'https://sandbox-quickbooks.api.intuit.com' : 'https://quickbooks.api.intuit.com',
'version' => 'v3',
'company' => 'company',
'companyID' => '123145768959777'
),
'query' => 'SELECT * FROM ESTIMATE',
'headers' => array(
'Host' => IS_SANDBOX == 1 ? 'sandbox-quickbooks.api.intuit.com' : 'quickbooks.api.intuit.com',
'Accept' => 'application/json',
'User-Agent' => 'APIExplorer'
)
);
$request_url = implode('/', $request['url']) . '/query?query=' . str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($request['query']))) . '&minorversion=4';
// token, and token_secret
$headers = $oAuth->sign('GET', $request_url, 'qyprdaiy37CxGCuB8ow8XK76FYii3rnRU4AIQrHsZDcVFNnV', 'wWcpmPffdPABp6LNNyYgnraTft7bgdygAmTML0aB');
$request['headers']['Authorization'] = 'OAuth ' . array_pop($headers);
$response = curl($request_url, $request['headers']);
echo '<pre>', var_dump($response), '</pre>';
echo '<pre>', var_dump($request['headers']), '</pre>';
function curl($url, $headers) {
try {
$request_headers = array();
$ch = curl_init();
if (FALSE === $ch)
throw new Exception('failed to initialize');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (!empty($headers)) {
foreach($headers as $key => $value)
{
if ($key == 'GET')
{
$request_headers[] = $key . ' ' . $value;
continue;
}
$request_headers[] = $key . ': ' . $value;
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable SSL Verfication, so we can get all info from non-SSL site!
}
$data = curl_exec($ch);
$header = curl_getinfo($ch);
echo '<h2>Curl Get Info</h2>';
echo '<pre>', var_dump($header), '</pre>';
if (FALSE === $data)
throw new Exception(curl_error($ch), curl_errno($ch));
else
return $data;
curl_close($ch);
} catch(Exception $e) {
trigger_error(sprintf(
'Curl failed with error #%d: %s',
$e->getCode(), $e->getMessage()), E_USER_ERROR);
}
}
echo '<pre>', var_dump($request_url), '</pre>';
?>
My oAuth.php file looks like this:
<?php
/**
* QuickBooks PHP DevKit
*
* Copyright (c) 2010 Keith Palmer / ConsoliBYTE, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* #author Keith Palmer <keith#consolibyte.com>
* #license LICENSE.txt
*
* #package QuickBooks
*/
class QuickBooks_IPP_OAuth
{
private $_secrets;
protected $_oauth_consumer_key;
protected $_oauth_consumer_secret;
protected $_oauth_access_token;
protected $_oauth_access_token_secret;
protected $_version = null;
protected $_signature = null;
protected $_keyfile;
/**
*
*/
const NONCE = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const METHOD_POST = 'POST';
const METHOD_GET = 'GET';
const METHOD_PUT = 'PUT';
const METHOD_DELETE = 'DELETE';
const DEFAULT_VERSION = '1.0';
const DEFAULT_SIGNATURE = 'HMAC-SHA1';
const SIGNATURE_PLAINTEXT = 'PLAINTEXT';
const SIGNATURE_HMAC = 'HMAC-SHA1';
const SIGNATURE_RSA = 'RSA-SHA1';
/**
* Create our OAuth instance
*/
public function __construct($oauth_consumer_key, $oauth_consumer_secret)
{
$this->_oauth_consumer_key = $oauth_consumer_key;
$this->_oauth_consumer_secret = $oauth_consumer_secret;
$this->_version = QuickBooks_IPP_OAuth::DEFAULT_VERSION;
$this->_signature = QuickBooks_IPP_OAuth::DEFAULT_SIGNATURE;
}
/**
* Set the signature method
*
*
*/
public function signature($method, $keyfile = null)
{
$this->_signature = $method;
$this->_keyfile = $keyfile;
}
/**
* Sign an OAuth request and return the signing data (auth string, URL, etc.)
*
*
*/
public function sign($method, $url, $oauth_token = null, $oauth_token_secret = null, $params = array())
{
/*
print('got in: [' . $method . '], ' . $url);
print_r($params);
print('<br /><br /><br />');
*/
if (!is_array($params))
{
$params = array();
}
$params = array_merge($params, array(
'oauth_consumer_key' => $this->_oauth_consumer_key,
'oauth_signature_method' => $this->_signature,
'oauth_nonce' => $this->_nonce(),
'oauth_timestamp' => $this->_timestamp(),
'oauth_version' => $this->_version,
));
// Add in the tokens if they were passed in
if ($oauth_token)
{
$params['oauth_token'] = $oauth_token;
}
if ($oauth_token_secret)
{
$params['oauth_secret'] = $oauth_token_secret;
}
// Generate the signature
$signature_and_basestring = $this->_generateSignature($this->_signature, $method, $url, $params);
$params['oauth_signature'] = $signature_and_basestring[1];
/*
print('<pre>');
print('BASE STRING IS [' . $signature_and_basestring[0] . ']' . "\n\n");
print('SIGNATURE IS: [' . $params['oauth_signature'] . ']');
print('</pre>');
*/
$normalized = $this->_normalize($params);
/*
print('NORMALIZE 1 [' . $normalized . ']' . "\n");
print('NORMZLIZE 2 [' . $this->_normalize2($params) . ']' . "\n");
*/
if (false !== ($pos = strpos($url, '?')))
{
$url = substr($url, 0, $pos);
}
$normalized_url = $url . '?' . $normalized; // normalized URL
return array (
0 => $signature_and_basestring[0], // signature basestring
1 => $signature_and_basestring[1], // signature
2 => $normalized_url,
3 => $this->_generateHeader($params, $normalized), // header string
);
}
protected function _generateHeader($params, $normalized)
{
// oauth_signature="' . $this->_escape($params['oauth_signature']) . '",
$str = '';
if (isset($params['oauth_token']))
$str .= rawurlencode('oauth_token') . '="' . rawurlencode($params['oauth_token']) . '", ';
$nonce = rawurlencode(md5(mt_rand()));
$nonce_chars = str_split($nonce);
$formatted_nonce = '';
foreach($nonce_chars as $n => $chr)
{
if (in_array($n, array(8, 12, 16, 20)))
$formatted_nonce .= '-';
$formatted_nonce .= $chr;
}
$str .= rawurlencode('oauth_nonce') . '="' . $formatted_nonce . '", ' .
rawurlencode('oauth_consumer_key') . '="' . rawurlencode($params['oauth_consumer_key']) . '", ' .
rawurlencode(oauth_signature_method) . '="' . rawurlencode($params['oauth_signature_method']) . '", ' .
rawurlencode(oauth_timestamp) . '="' . rawurlencode($params['oauth_timestamp']) . '", ' .
rawurlencode(oauth_version) . '="' . rawurlencode($params['oauth_version']) . '", ' .
rawurlencode(oauth_signature) . '="' . $this->_escape($params['oauth_signature']) . '"';
return str_replace(array(' ', ' ', ' '), '', str_replace(array("\r", "\n", "\t"), ' ', $str));
}
/**
*
*
*/
protected function _escape($str)
{
if ($str === false)
{
return $str;
}
else
{
return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($str)));
}
}
protected function _timestamp()
{
//return 1326976195;
//return 1318622958;
return time();
}
protected function _nonce($len = 5)
{
//return '1234';
$tmp = str_split(QuickBooks_IPP_OAuth::NONCE);
shuffle($tmp);
//return 'kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg';
return substr(implode('', $tmp), 0, $len);
}
protected function _normalize($params)
{
$normalized = array();
ksort($params);
foreach ($params as $key => $value)
{
// all names and values are already urlencoded, exclude the oauth signature
if ($key != 'oauth_secret')
{
if (is_array($value))
{
$sort = $value;
sort($sort);
foreach ($sort as $subkey => $subvalue)
{
$normalized[] = $this->_escape($key) . '=' . $this->_escape($subvalue);
}
}
else
{
$normalized[] = $this->_escape($key) . '=' . $this->_escape($value);
}
}
}
return implode('&', $normalized);
}
protected function _generateSignature($signature, $method, $url, $params = array())
{
/*
print('<pre>params for signing');
print_r($params);
print('</pre>');
*/
//if (false !== strpos($url, 'get_access'))
/*if (true)
{
print($url . '<br />' . "\r\n\r\n");
die('NORMALIZE MINE [' . $this->_normalize($params) . ']');
}*/
/*
print('<pre>');
print('NORMALIZING [' . "\n");
print($this->_normalize($params) . "]\n\n\n");
print('SECRET KEY FOR SIGNING [' . $secret . ']' . "\n");
print('</pre>');
*/
if (false !== ($pos = strpos($url, '?')))
{
$tmp = array();
parse_str(substr($url, $pos + 1), $tmp);
// Bad hack for magic quotes... *sigh* stupid PHP
if (get_magic_quotes_gpc())
{
foreach ($tmp as $key => $value)
{
if (!is_array($value))
{
$tmp[$key] = stripslashes($value);
}
}
}
$params = array_merge($tmp, $params);
$url = substr($url, 0, $pos);
}
//print('url [' . $url . ']' . "\n");
//print_r($params);
$sbs = $this->_escape($method) . '&' . $this->_escape($url) . '&' . $this->_escape($this->_normalize($params));
//print('sbs [' . $sbs . ']' . "\n");
// Which signature method?
switch ($signature)
{
case QuickBooks_IPP_OAuth::SIGNATURE_HMAC:
return $this->_generateSignature_HMAC($sbs, $method, $url, $params);
case QuickBooks_IPP_OAuth::SIGNATURE_RSA:
return $this->_generateSignature_RSA($sbs, $method, $url, $params);
}
return false;
}
/*
// Pull the private key ID from the certificate
$privatekeyid = openssl_get_privatekey($cert);
// Sign using the key
$sig = false;
$ok = openssl_sign($base_string, $sig, $privatekeyid);
// Release the key resource
openssl_free_key($privatekeyid);
base64_encode($sig)
*/
protected function _generateSignature_RSA($sbs, $method, $url, $params = array())
{
// $res = ...
$res = openssl_pkey_get_private('file://' . $this->_keyfile);
/*
print('key id is: [');
print_r($res);
print(']');
print("\n\n\n");
*/
$signature = null;
$retr = openssl_sign($sbs, $signature, $res);
openssl_free_key($res);
return array(
0 => $sbs,
1 => base64_encode($signature),
);
}
/*
$key = $request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret);
$signature = base64_encode(hash_hmac("sha1", $base_string, $key, true));
*/
protected function _generateSignature_HMAC($sbs, $method, $url, $params = array())
{
$secret = $this->_escape($this->_oauth_consumer_secret);
$secret .= '&';
if (!empty($params['oauth_secret']))
{
$secret .= $this->_escape($params['oauth_secret']);
}
//print('generating signature from [' . $secret . ']' . "\n\n");
return array(
0 => $sbs,
1 => base64_encode(hash_hmac('sha1', $sbs, $secret, true)),
);
}
}
?>
$request['headers'] looks like this:
array(4) {
["Host"]=>
string(33) "sandbox-quickbooks.api.intuit.com"
["Accept"]=>
string(16) "application/json"
["User-Agent"]=>
string(11) "APIExplorer"
["Authorization"]=>
string(306) "OAuth oauth_token="qyprdaiy37CxGCuB8ow8XK76FYii3rnRU4AIQrHsZDcVFNnV",oauth_nonce="189f7f21-6dd9-c136-e208-0f33141feea5",oauth_consumer_key="qyprdwX21R3klmiskW3AaYLnDRGNLn",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1462545676",oauth_version="1.0",oauth_signature="BIpYveqCxlfVT4Ps4qJypS%2BXHh8%3D""
}
The response looks like this:
message=ApplicationAuthenticationFailed; errorCode=003200; statusCode=401
SignatureBaseString: GET&https%3A%2F%2Fsandbox-quickbooks.api.intuit.com%2Fv3%2Fcompany%2F123145768959777%2Fquery&minorversion%3D4%26oauth_consumer_key%3DqyprdwX21R3klmiskW3AaYLnDRGNLn%26oauth_nonce%3D189f7f21-6dd9-c136-e208-0f33141feea5%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1462545676%26oauth_token%3Dqyprdaiy37CxGCuB8ow8XK76FYii3rnRU4AIQrHsZDcVFNnV%26oauth_version%3D1.0%26query%3DSELECT%2520%252A%2520FROM%2520ESTIMATE
The $request_url looks like this:
https://sandbox-quickbooks.api.intuit.com/v3/company/123145768959777/query?query=SELECT%20%2A%20FROM%20ESTIMATE&minorversion=4
Am I forgetting to do something here? Or perhaps something is not correct somehow? I should be getting All Estimates from within the Quickbook Company with ID of 123145768959777, but all I'm getting is 401 Authorization Failure messages.
Am I forgetting to do something here? Or perhaps something is not correct somehow?
Yes, definitely. See below for specifics:
$headers = $oAuth->sign(null, ...
null is not a valid HTTP request method. Valid HTTP request methods are things like GET, POST, etc. Please refer to the HTTP spec and the OAuth spec.
$headers = $oAuth->sign(null, $_SERVER['REQUEST_URI'],
Why are you signing the server request URI? You should be signing the URL that you are sending your curl request to and not the URL the user is visiting on your own website.
$headers = $oAuth->sign(null, $_SERVER['REQUEST_URI'], 'qyprdaiy37CxGCuB8ow8XK76FYii3rnRU4AIQrHsZDcVFNnV', 'wWcpmPffdPABp6LNNyYgnraTft7bgdygAmTML0aB');
You can not hard-code the OAuth access token and secret. They change every 6 months, and thus have to be stored in a database/file somewhere so that you can change them without editing your code every 6 months.
$request_url = implode('/', $request['url']) . '/query?query=' . str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($request['query']))) . '&minorversion=4';
This is the URL you should be signing.
I should be getting All Estimates from within the Quickbook Company with ID of 123145768959777, but all I'm getting is 401 Authorization Failure messages.
If you need further help, it would make a lot of sense to post your actual HTTP requests and responses. There's not a lot anyone will be able to tell you without really seeing the requests being sent, and the responses being received.
Also... you realize that all of this hard work has already been done for you, using the library you've grabbed code from, right? e.g. You don't need to do any of what you're doing - it's just re-inventing the wheel. Just do:
require_once dirname(__FILE__) . '/config.php';
$EstimateService = new QuickBooks_IPP_Service_Estimate();
$estimates = $EstimateService->query($Context, $realm, "SELECT * FROM Estimate STARTPOSITION 1 MAXRESULTS 10");
foreach ($estimates as $Estimate)
{
print('Estimate # ' . $Estimate->getDocNumber() . "\n");
}
Helpful links:
https://github.com/consolibyte/quickbooks-php
https://github.com/consolibyte/quickbooks-php/blob/master/docs/partner_platform/example_app_ipp_v3/
https://github.com/consolibyte/quickbooks-php/blob/master/docs/partner_platform/example_app_ipp_v3/example_invoice_query.php
I need to call the Amazon MWS action 'RequestReport' and specify the ReportType as '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_'. i have successfully connected to get the FulfillmentInventory/ListInventorySupply, so i know that the cURL and amazon settings are correct, but every time i submit i get 'The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.' back from the server. i have tried both sort and ksort on line 23 and 14 - in the call to the FulfillmentInventory/ListInventorySupply i had to set it up with two ksorts in order to keep the list of SKUs in the correct order for the API
Here is the code, as i say, the secret, merchant, and keyid are correct:
header('Content-type: application/xml');
$secret = 'secretcodehere';
$param = array();
$param['AWSAccessKeyId'] = 'accessidhere';
$param['Action'] = 'RequestReport';
$param['Merchant'] = 'merchantidhere';
$param['SignatureVersion'] = '2';
$param['Timestamp'] = gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time());
$param['Version'] = '2009-01-01';
$param['SignatureMethod'] = 'HmacSHA256';
$param['ReportType'] = '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_';
ksort($param);
$url = array();
foreach ($param as $key => $val) {
$key = str_replace("%7E", "~", rawurlencode($key));
$val = str_replace("%7E", "~", rawurlencode($val));
$url[] = "{$key}={$val}";
}
sort($url);
$arr = implode('&', $url);
$sign = 'POST' . "\n";
$sign .= 'mws.amazonservices.com';
$sign .= '/doc/2009-01-01' . "\n";
$sign .= $arr;
$signature = hash_hmac("sha256", $sign, $secret, true);
$signature = urlencode(base64_encode($signature));
$link = "https://mws.amazonservices.com/doc/2009-01-01/?";
$link .= $arr . "&Signature=" . $signature;
/*
echo($link);//for debugging
exit(); */
$ch = curl_init($link);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: text/xml'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
print_r($response);
i have tried it in MWS scratchpad and the info is correct and generates the 200 response, and when i check the url against the one generated by the scratchpad it 'looks' correct, so i must be missing something and i hope it is obvious to someone out there, 'cause i am baffled.
btw-scratchpad lists it as SellerId, but the url shows it as Merchant - i have tried both with no joy
Not to throw a curve ball at you, but the only success I've had in using the RequestReport has been through using the PHP library that Amazon created. If you don't have it already here's the link.
This is the code that I just confirmed works to request the report:
<?php
define('AWS_ACCESS_KEY_ID', $am_aws_access_key);
define('AWS_SECRET_ACCESS_KEY', $am_secret_key);
define('MERCHANT_ID', $am_merchant_id);
define('MARKETPLACE_ID', $am_marketplace_id);
include_once ('/link/to/Amazon/library/MarketplaceWebService/Samples/.config.inc.php');
include_once ('functions.php');
$serviceUrl = "https://mws.amazonservices.com";
$config = array (
'ServiceURL' => $serviceUrl,
'ProxyHost' => null,
'ProxyPort' => -1,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebService_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
$config,
APPLICATION_NAME,
APPLICATION_VERSION);
echo '<br />';
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'ReportType' => '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_',
);
echo '<br /><br/>Request Report Request:<br><br>';
$request = new MarketplaceWebService_Model_RequestReportRequest($parameters);
print_r($request);
invokeRequestReport($service, $request);
echo '<br /><br/>';
And the functions.php file (basically is the important function in the last half of the code in the MarketplaceWebService\Samples\RequestReportSample.php file:
function invokeRequestReport(MarketplaceWebService_Interface $service, $request)
{
try {
$response = $service->requestReport($request);
echo ("Service Response\n");
echo ("=============================================================================\n");
echo(" RequestReportResponse\n");
if ($response->isSetRequestReportResult()) {
echo(" RequestReportResult\n");
$requestReportResult = $response->getRequestReportResult();
if ($requestReportResult->isSetReportRequestInfo()) {
$reportRequestInfo = $requestReportResult->getReportRequestInfo();
echo(" ReportRequestInfo\n");
if ($reportRequestInfo->isSetReportRequestId())
{
echo(" ReportRequestId\n");
echo(" " . $reportRequestInfo->getReportRequestId() . "\n");
}
$report_request_id = $reportRequestInfo->getReportRequestId();
$report_type = '';
if ($reportRequestInfo->isSetReportType())
{
echo(" ReportType\n");
echo(" " . $reportRequestInfo->getReportType() . "\n");
$report_type = $reportRequestInfo->getReportType();
}
if ($reportRequestInfo->isSetStartDate())
{
echo(" StartDate\n");
echo(" " . $reportRequestInfo->getStartDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetEndDate())
{
echo(" EndDate\n");
echo(" " . $reportRequestInfo->getEndDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetSubmittedDate())
{
echo(" SubmittedDate\n");
echo(" " . $reportRequestInfo->getSubmittedDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetReportProcessingStatus())
{
echo(" ReportProcessingStatus\n");
echo(" " . $reportRequestInfo->getReportProcessingStatus() . "\n");
}
if($report_type == '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_') {
if(!empty($report_request_id)) {
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'Report' => #fopen('php://memory', 'rw+'),
'ReportRequestIdList' => $report_request_id,
);
$report = new MarketplaceWebService_Model_GetReportRequestListRequest($parameters);
print_r($report);
}
}
}
}
if ($response->isSetResponseMetadata()) {
echo(" ResponseMetadata\n");
$responseMetadata = $response->getResponseMetadata();
if ($responseMetadata->isSetRequestId())
{
echo(" RequestId\n");
echo(" " . $responseMetadata->getRequestId() . "\n");
}
}
} catch (MarketplaceWebService_Exception $ex) {
echo("Caught Exception: " . $ex->getMessage() . "\n");
echo("Response Status Code: " . $ex->getStatusCode() . "\n");
echo("Error Code: " . $ex->getErrorCode() . "\n");
echo("Error Type: " . $ex->getErrorType() . "\n");
echo("Request ID: " . $ex->getRequestId() . "\n");
echo("XML: " . $ex->getXML() . "\n");
}
}
EDIT
Here's the important parts of the .config.inc.php file:
<?php
define ('DATE_FORMAT', 'Y-m-d\TH:i:s\Z');
date_default_timezone_set('America/Denver');
$app_name = "Just make up a name like 'Awesome Sync'";
$app_version = "1.0";
define('APPLICATION_NAME', $app_name);
define('APPLICATION_VERSION', $app_version);
set_include_path('/link/to/Amazon/library/');
...rest of code...
EDIT
This code will create the request for the report, however, it doesn't actually create the report. You have to continue to poll Amazon using this same code until you receive a "Complete" or something similar (can't remember the exact word Amazon send back when the report has been created). Then you need to actually retrieve the report.