Yahoo/OAuth Could Not Get Access Token - php

I am trying to implement OAuth on my site using php. I don't have access to the server so I can't install a OAuth library. Instead I have the following code provided to me by yahoo, but I can't figure out how to get it to work.
Here's there error I keep getting:
Hey! Go to this URL and tell us the verifier you get at the end. https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=bhppbwq Type the verifier and hit enter... Here's the verifier you gave us: Could not get access token
It looks like it's trying to give some type of interaction, but It doesn't give me a chance. Instead it goes straight to a blank page and spits that error out.
Here is the yahoo code I was given:
<?php
// **** POTENTIAL CONFIGURATION STARTS HERE ****
// MODIFY: Insert your own consumer key and secret here!
$consumer_data = array();
$consumer_data['test']['key'] = 'xxxxxxxxxxxxxx';
$consumer_data['test']['secret'] = 'xxxxxxxxxxxxxx';
// **** HELPER FUNCTIONS START HERE ****
///////////////////////////////////////////////////////////////////////////////
// FUNCTION _make_signed_request
/// #brief Helper function to make a signed OAuth request. Only allows GET
/// requests at the moment. Will add on standard OAuth params, but
/// you may need to fill in non-generic ones ahead of time.
///
/// #param[in] $consumer_key Application consumer key
/// #param[in] $consumer_secret Application consumer secret
/// #param[in] $token Token (request or access token)
/// #param[in] $token_secret Token secret
/// #param[in] $signature_method 'PLAINTEXT' or 'HMAC-SHA1'
/// #param[in] $url URL to make request to
/// #param[in] $params Array of key=>val for params. Don't
/// urlencode ahead of time, we'll do that here.
///////////////////////////////////////////////////////////////////////////////
function _make_signed_request( $consumer_key, $consumer_secret, $token, $token_secret, $signature_method, $url, $params = array() ) {
// Only support GET in this function
$method = 'GET';
$signature_method = strtoupper( $signature_method );
if( $signature_method != 'PLAINTEXT' && $signature_method != 'HMAC-SHA1' ) {
print "Invalid signature method: ${signature_method}\n";
return false;
}
$oauth_nonce = rand( 0, 999999 );
$oauth_timestamp = time();
$oauth_version = '1.0';
$params['oauth_consumer_key'] = $consumer_key;
$params['oauth_nonce'] = $oauth_nonce;
$params['oauth_signature_method'] = $signature_method;
$params['oauth_timestamp'] = $oauth_timestamp;
$params['oauth_version'] = $oauth_version;
if( $token ) {
$params['oauth_token'] = $token;
}
if( ! $token_secret ) {
$token_secret = '';
}
// Params need to be sorted by key
ksort( $params, SORT_STRING );
// Urlencode params and generate param string
$param_list = array();
foreach( $params as $key => $value ) {
$param_list[] = urlencode( $key ) . '=' . urlencode( $value );
}
$param_string = join( '&', $param_list );
// Generate base string (needed for SHA1)
$base_string = urlencode( $method ) . '&' . urlencode( $url ) . '&' .
urlencode( $param_string );
// Generate secret
$secret = urlencode( $consumer_secret ) . '&' . urlencode( $token_secret );
if( $signature_method == 'PLAINTEXT' ) {
$signature = $secret;
} else if( $signature_method == 'HMAC-SHA1' ) {
$signature = base64_encode( hash_hmac( 'sha1', $base_string, $secret, true ) );
}
// Append signature
$param_string .= '&oauth_signature=' . urlencode( $signature );
$final_url = $url . '?' . $param_string;
// Make curl call
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $final_url );
curl_setopt( $ch, CURLOPT_AUTOREFERER, 1 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 0 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
$timeout = 2; // seconds
curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
$contents = curl_exec($ch);
$ret_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
$errno = curl_errno($ch);
$error_str = curl_error($ch);
if( $errno || $error_str ) {
//print "Error: ${error_str} (${errno})\n";
}
//print "Response code: ${ret_code}\n";
//print "Contents:\n${contents}\n\n";
curl_close($ch);
$data = array(
'return_code' => $ret_code,
'contents' => $contents,
'error_str' => $error_str,
'errno' => $errno
);
return $data;
}
///////////////////////////////////////////////////////////////////////////////
// FUNCTION oauth_response_to_array
/// #brief Break up the oauth response data into an associate array
///////////////////////////////////////////////////////////////////////////////
function oauth_response_to_array( $response ) {
$data = array();
foreach( explode( '&', $response ) as $param ) {
$parts = explode( '=', $param );
if( count( $parts ) == 2 ) {
$data[urldecode($parts[0])] = urldecode($parts[1]);
}
}
return $data;
}
///////////////////////////////////////////////////////////////////////////////
// FUNCTION get_request_token
/// #brief Get a request token for a given application.
///////////////////////////////////////////////////////////////////////////////
function get_request_token( $consumer_key, $consumer_secret ) {
$url = 'https://api.login.yahoo.com/oauth/v2/get_request_token';
$signature_method = 'plaintext';
$token = NULL;
$token_secret = NULL;
// Add in the lang pref and callback
$xoauth_lang_pref = 'en-us';
$oauth_callback = 'oob'; // Set OOB for ease of use -- could be a URL
$params = array( 'xoauth_lang_pref' => $xoauth_lang_pref,
'oauth_callback' => $oauth_callback );
// Make the signed request without any token
$response_data = _make_signed_request( $consumer_key, $consumer_secret, $token, $token_secret, $signature_method, $url, $params );
if( $response_data && $response_data['return_code'] == 200 ) {
$contents = $response_data['contents'];
$data = oauth_response_to_array( $contents );
//print_r( $data );
return $data;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
// FUNCTION get_access_token
/// #brief Get an access token for a certain user and a certain application,
/// based on the request token and verifier
///////////////////////////////////////////////////////////////////////////////
function get_access_token( $consumer_key, $consumer_secret, $request_token, $request_token_secret, $verifier ) {
$url = 'https://api.login.yahoo.com/oauth/v2/get_token';
$signature_method = 'plaintext';
// Add in the oauth verifier
$params = array( 'oauth_verifier' => $verifier );
// Make the signed request using the request_token data
$response_data = _make_signed_request( $consumer_key, $consumer_secret, $request_token, $request_token_secret, $signature_method, $url, $params );
if( $response_data && $response_data['return_code'] == 200 ) {
$contents = $response_data['contents'];
$data = oauth_response_to_array( $contents );
//print_r( $data );
return $data;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
// FUNCTION make_request
/// #brief Make an actual request to the fantasy API.
///////////////////////////////////////////////////////////////////////////////
function make_request( $consumer_key, $consumer_secret, $access_token, $access_token_secret, $url ) {
$signature_method = 'hmac-sha1';
// Make the signed request to fantasy API
$response_data = _make_signed_request( $consumer_key, $consumer_secret, $access_token, $access_token_secret, $signature_method, $url );
return $response_data;
}
// **** MAIN PROGRAM STARTS HERE ****
$consumer_key = $consumer_data['test']['key'];
$consumer_secret = $consumer_data['test']['secret'];
// 1. Get Request Token
$request_token_data = get_request_token( $consumer_key, $consumer_secret );
if( ! $request_token_data ) {
print "Could not retrieve request token data\n";
exit;
}
$request_token = $request_token_data['oauth_token'];
$request_token_secret = $request_token_data['oauth_token_secret'];
$auth_url = $request_token_data['xoauth_request_auth_url'];
// 2. Direct user to Yahoo! for authorization (retrieve verifier)
print "Hey! Go to this URL and tell us the verifier you get at the end.\n";
print ' ' . $auth_url . "\n\n";
print "Type the verifier and hit enter...\n";
$verifier = fgets( STDIN );
print "Here's the verifier you gave us: ${verifier}\n";
// 3. Get Access Token
$access_token_data =
get_access_token( $consumer_key, $consumer_secret, $request_token, $request_token_secret, $verifier );
if( ! $access_token_data ) {
print "Could not get access token\n";
exit;
}
$access_token = $access_token_data['oauth_token'];
$access_token_secret = $access_token_data['oauth_token_secret'];
// 4. Make request using Access Token
$base_url = 'http://fantasysports.yahooapis.com/';
if( isset( $argv[1] ) ) {
$request_uri = $argv[1];
} else {
$request_uri = 'fantasy/v2/game/nfl';
}
$request_url = $base_url . $request_uri;
print "Making request for ${request_url}...\n";
$request_data = make_request( $consumer_key, $consumer_secret, $access_token, $access_token_secret, $request_url );
if( ! $request_data ) {
print "Request failed\n";
}
$return_code = $request_data['return_code'];
$contents = $request_data['contents'];
print "Return code: ${return_code}\n";
print "Contents:\n${contents}\n\n";
print "Successful\n";
?>

It looks like the code provided by Yahoo wasn't meant to be run as a web page, given this line:
$verifier = fgets( STDIN );
Instead it should be run in the console so that it can take advantage of STDIN and properly wait for user input.
But that doesn't really answer your question. If you want something that the user can enter -- at least as a quick test to prove that your code works -- use a form to grab user input, like below:
<?php
echo $_POST['value'];
?>
<form method="post" action="">
<input type="text" name="value">
<input type="submit">
</form>
I'm not too familiar with PHP, but the next step would be to wrap this script into several functions, then execute the second half of the script once you have $verifier defined by the user via a form.

Related

Invalid signature on amazon v2

I have a problem on setting signature in this part of the guide (http://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-checkout/set-payment-info.html). Here' my code:
<?
header('Content-Type: application/json');
define("STORE_ID", "amzn1.application-oa2-client.fb120c0b541e4007aaf987a73b365a3e");
define("VENDOR_ID", "A6SFQPANHYSL0");
define("PUBLIC_KEY_ID", "AGBUUNBAKQW5OMTKHP5WZH55");
define("PRIVATE_KEY_ID", "AmazonPay_AGBUUNBAKQW5OMTKHP5WZH55.pem");
$method = 'POST';
// API Merchant Scan
$url = 'https://pay-api.amazon.eu/sandbox/v2/checkoutSessions/'.$_GET['amazonCheckoutSessionId'];
$payload = array(
'webCheckoutDetails' => array(
'checkoutResultReturnUrl'=> 'https://a.com/merchant-confirm-page'
),
'paymentDetails' => array(
'paymentIntent'=> 'AuthorizeWithCapture',
'canHandlePendingAuthorization'=>false,
'softDescriptor'=> 'Descriptor',
'chargeAmount'=> array(
'amount'=> '1',
'currencyCode'=> 'EUR'
),
),
'merchantMetadata'=> array(
'merchantReferenceId'=> 'Merchant reference ID',
'merchantStoreName'=> 'Merchant store name',
'noteToBuyer'=> 'Note to buyer',
'customInformation'=> 'Custom information'
)
);
// Convert to json string
$payload = json_encode($payload);
$requestParameters = array();
include 'amazon-pay-api-sdk-php-master/vendor/autoload.php';
$amazonpay_config = array(
'public_key_id' => PUBLIC_KEY_ID,
'private_key' => PRIVATE_KEY_ID,
'region' => 'EU',
'sandbox' => true
);
$client = new Amazon\Pay\API\Client($amazonpay_config);
// Create an array that will contain the parameters for the charge API call
$pre_signed_headers = array();
$pre_signed_headers['Accept'] = 'application/json';
$pre_signed_headers['Content-Type'] = 'application/json';
$pre_signed_headers['X-Amz-Pay-Region'] = 'eu';
$timestamp_data = date("Ymd");
$timestamp_orario = date("His");
$timestamp = $timestamp_data."T".$timestamp_orario."Z";
$signedInput = $client->createSignature($method, $url, $requestParameters, $pre_signed_headers, $payload, $timestamp);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://pay-api.amazon.eu/sandbox/v2/checkoutSessions/'.$_GET['amazonCheckoutSessionId']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$headers = array();
$headers[] = 'Authorization: AMZN-PAY-RSASSA-PSS PublicKeyId=AGBUUNBAKQW5OMTKHP5WZH55, SignedHeaders=accept;content-type;x-amz-pay-date;x-amz-pay-host;x-amz-pay-region, Signature= '.$signedInput;
$headers[] = 'X-Amz-Pay-Date: '.$timestamp;
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$json = json_decode($result);
print_r($json);
?>
The class for $client->createSignature is:
public function createSignature($http_request_method, $request_uri, $request_parameters, $pre_signed_headers, $request_payload, $timeStamp)
{
$rsa = $this->setupRSA();
$pre_signed_headers['X-Amz-Pay-Date'] = $timeStamp;
$pre_signed_headers['X-Amz-Pay-Host'] = $this->getHost($request_uri);
$hashedPayload = $this->hexAndHash($request_payload);
$canonicalURI = $this->getCanonicalURI($request_uri);
$canonicalQueryString = $this->createCanonicalQuery($request_parameters);
$canonicalHeader = $this->getHeaderString($pre_signed_headers);
$signedHeaders = $this->getCanonicalHeadersNames($pre_signed_headers);
$canonicalRequest = (
$http_request_method . "\n" .
$canonicalURI . "\n" .
$canonicalQueryString . "\n" .
$canonicalHeader . "\n" .
$signedHeaders . "\n" .
$hashedPayload
);
$hashedCanonicalRequest = self::AMAZON_SIGNATURE_ALGORITHM . "\n" . $this->hexAndHash($canonicalRequest);
$signature = $rsa->sign($hashedCanonicalRequest);
if ($signature === false) {
throw new \Exception('Unable to sign request, is your RSA private key valid?');
}
return base64_encode($signature);
}
The problem i received from the page i want to laod is:
[reasonCode] => InvalidRequestSignature
[message] => Unable to verify signature, signing String ...
Do you know how i can get a valid signature? I can use the one i got 2 steps before (the one that create the button for amazon pay) but i don't think it is the same.
Thank you for your time.

Need to connect iTunes Connect API, always shows not authorized for JWT

I'm trying to generate a token to sign my requests to the iTunes Connect API. That's my PHP file:
function encode($data)
{
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($data));
}
function sign($data)
{
if (!$key = openssl_pkey_get_private('file://AuthKey_qwerty.p8')) {
throw new \Exception('Failed to read PEM');
}
if (!openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA256)) {
throw new \Exception('Claims signing failed');
}
return $signature;
}
function create()
{
$header = encode(
json_encode([
'kid' => 'frfc343r4',
'alg' => 'ES256',
'typ' => 'JWT',
])
);
$claims = encode(
json_encode([
'iss' => 'ddd-aaa-bbbb-cccc-ddddd',
'exp' => time() + (20 * 60),
'aud' => 'appstoreconnect-v1',
])
);
$signature = encode(
sign("$header.$claims")
);
return $header . '.' . $claims . '.' . $signature;
}
echo create();
which gives an error, "Authentication credentials are missing or invalid.",App Store Connect API must be signed with ES256 encryption
require_once '../vendor/autoload.php';
use Curl\Curl;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Ecdsa\Sha256;
$signer = new Sha256();
$privateKey = new Key('file://AuthKey_ed2erd424.p8');
$time = time();
$Issuer_ID = "3455355-3535-4f8g-8x2r-3dcfrr43ed33";
$Key_ID = "4DD3R45DT45";
$token = (new Builder())->issuedBy($Issuer_ID)// Configures the issuer (iss claim)
->permittedFor("appstoreconnect-v1")// Configures the audience (aud claim)
//->identifiedBy('XXYYZZ', true)// Configures the id (jti claim), replicating as a header item
->withHeader('kid', $Key_ID)
->withHeader('type', 'JWT')
->withHeader('alg', 'ES256')
->issuedAt($time)// Configures the time that the token was issue (iat claim)
->expiresAt($time + 1200)// Configures the expiration time of the token (exp claim)
->withClaim('uid', 1)// Configures a new claim, called "uid"
->getToken($signer, $privateKey); // Retrieves the generated token
$token->getHeaders(); // Retrieves the token headers
$token->getClaims(); // Retrieves the token claims
$date = $_GET['date'];
$url ='https://api.appstoreconnect.apple.com/v1/salesReports';
$dataArray = array(
'filter[frequency]'=>'DAILY',
'filter[reportDate]'=>$date,
'filter[reportSubType]'=>'SUMMARY',
'filter[reportType]'=>'SALES',
'filter[vendorNumber]'=>'345434463',
'filter[version]'=>'1_0'
);
$ch = curl_init();
$data = http_build_query($dataArray);
$getUrl = $url."?".$data;
$authorization = "Authorization: Bearer ".$token; // Prepare the authorisation token
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization )); // Inject the token into the header
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $getUrl);
curl_setopt($ch, CURLOPT_TIMEOUT, 80);
$response = curl_exec($ch);
if(curl_error($ch)){
echo 'Request Error:' . curl_error($ch);
}
else
{
// if(!gzdecode($response)){ echo $response; exit; }
$uncompressed = $fp = #gzdecode($response);
if ($uncompressed === false) {
// do something related to error here
echo $response; exit;
}
;
$fp1 = array();
$myArray = [];
$lines = explode(PHP_EOL, $uncompressed);
$l = 0;
foreach($lines as $line) {
if($line == ''){continue;}
if($l == 0){ $myArray[$l] = explode("\t", $line); $l++; continue;}
//explode("\t", $line);
$key =0;
foreach(explode("\t", $line) as $value){
$myArray[$l][$myArray[0][$key]] = $value;
$key++;
}
$fp1[] = $myArray[$l];
$l++;
}
echo json_encode($fp1);
//echo $response;
}
curl_close($ch);

How to cancel a PayPal subscription without a PayPal account?

My current project allows users to subscribe to a membership without registering for a paypal account.
The users' username and password is created and managed by my own application, not PayPal.
Can anyone tell me how to create an hTMl form that would cancel that subscription? Could I perhaps cancel a subscription by sending the txn_id??
I believe I can capture this info with the IPN.
I should also mention that I'm a DBA and not really a developer so bear with me if i'm a little newbish.
Thanks in advance.
Here's what I ended up doing.
<?php
require 'core/init.php';
require 'core/conn.php';
/*The paypal_transactions table is a table I'm using to store the IPN data. This is necessary to capture the Profile_ID/Subscr_ID. The Custom parameter is being used to pass the username.*/
$profileid_sql = "select subscr_id from paypal_transactions where custom ='". escape($user->data()->username)."'";
$result=mysql_query($profileid_sql);
while($row=mysql_fetch_array($result)){
$profileid = $row['subscr_id'];
}
include 'functions/change_subscription_status.php';
change_subscription_status( $profileid, 'Cancel' );
header('Location: Cancelled.php');
?>
The change_subscription_status function is here...
<?php
/**
* Performs an Express Checkout NVP API operation as passed in $action.
*
* Although the PayPal Standard API provides no facility for cancelling a subscription, the PayPal
* Express Checkout NVP API can be used.
*/
function change_subscription_status( $profile_id, $action ) {
$api_request = 'USER=' . urlencode( 'API_username' )
. '&PWD=' . urlencode( 'API_Password' )
. '&SIGNATURE=' . urlencode( 'API_Signature' )
. '&VERSION=76.0'
. '&METHOD=ManageRecurringPaymentsProfileStatus'
. '&PROFILEID=' . urlencode( $profile_id )
. '&ACTION=' . urlencode( $action )
. '&NOTE=' . urlencode( 'Profile cancelled at store' );
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'https://api-3t.sandbox.paypal.com/nvp' ); // For live transactions, change to 'https://api-3t.paypal.com/nvp'
curl_setopt( $ch, CURLOPT_VERBOSE, 1 );
// Uncomment these to turn off server and peer verification
// curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
// curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_POST, 1 );
// Set the API parameters for this transaction
curl_setopt( $ch, CURLOPT_POSTFIELDS, $api_request );
// Request response from PayPal
$response = curl_exec( $ch );
// If no response was received from PayPal there is no point parsing the response
if( ! $response )
die( 'Calling PayPal to change_subscription_status failed: ' . curl_error( $ch ) . '(' . curl_errno( $ch ) . ')' );
curl_close( $ch );
// An associative array is more usable than a parameter string
parse_str( $response, $parsed_response );
return $parsed_response;
}
?>
Use paypal api method ManageRecurringPaymentsProfileStatus ( API Operation NVP ), using ACTION parameter you can:
Cancel – Only profiles in Active or Suspended state can be canceled.
Suspend – Only profiles in Active state can be suspended.
Reactivate – Only profiles in a suspended state can be reactivated.
Paypal Documentation - https://developer.paypal.com/docs/classic/api/merchant/ManageRecurringPaymentsProfileStatus_API_Operation_NVP/
To create a recurring profile follow this (PHP) example:
// Parameters for SetExpressCheckout, which will be sent to PayPal
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Product description';
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] .
' $'.$product->price.'/month';
$padata['L_PAYMENTREQUEST_0_DESC0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] .
' $'.$product->price.'/month';$padata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn';
$padata['PAYMENTREQUEST_0_DESC'] = $product->name;
$padata['RETURNURL'] = 'http://site_url/paypal/returnurl';
$padata['CANCELURL'] = 'http://site_url/paypal/cancelurl';
$padata['PAYMENTREQUEST_0_CURRENCYCODE'] = 'USD';
$padata['PAYMENTREQUEST_0_PAYMENTACTION'] = 'SALE';
$padata['PAYMENTREQUEST_0_ITEMAMT'] = $product->price;$padata['PAYMENTREQUEST_0_AMT'] = $product->price;$padata['L_BILLINGTYPE0'] = 'RecurringPayments';$padata['L_PAYMENTREQUEST_0_NAME0'] = $product->name;$padata['L_PAYMENTREQUEST_0_NUMBER0']= '322';$padata['L_PAYMENTREQUEST_0_QTY0'] = '1';$padata['L_PAYMENTREQUEST_0_AMT0'] = $product->price;
$paypal_data = http_build_query($padata);
$httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $paypal_data);
//Respond according to message we receive from Paypal
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){
//Redirect user to PayPal store with Token received.
$paypalurl ='https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].'';
header('Location: '.$paypalurl);
}else{
echo 'Error : '.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'';
}
Page returnurl:
$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Recurring Description';$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$pr->price.'/month';$hosteddata['L_PAYMENTREQUEST_0_NAME0'] = $pr->name;$hosteddata['PROFILEREFERENCE'] = $GetExpressCheckoutDetails['L_PAYMENTREQUEST_0_NUMBER0'];$hosteddata['PROFILESTARTDATE'] = date('Y-m-d') . 'T' . date('H:i:s').'Z';$hosteddata['SUBSCRIBERNAME'] = $GetExpressCheckoutDetails['FIRSTNAME'] . ' ' . $GetExpressCheckoutDetails['LASTNAME'];$hosteddata['TOKEN'] = urlencode($_POST['token']);$hosteddata['DESC'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'];$hosteddata['AMT'] = $pr->price;$hosteddata['BILLINGPERIOD'] = 'Month';$hosteddata['BILLINGFREQUENCY'] = '1';$hosteddata['TOTALBILLINGCYCLES'] = '12';$hosteddata['REGULARTOTALBILLINGCYCLES'] = '1';$hosteddata['VERSION'] = '74.0';$hosteddata['MAXFAILEDPAYMENTS'] = '1';$hosteddata['L_PAYMENTREQUEST_0_QTY0'] = '1';$hosteddata['L_BILLINGTYPE0'] = 'RecurringPayments';$hosteddata['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Digital';$hosteddata['L_PAYMENTREQUEST_0_AMT0'] = $pr->price;$hosteddata['INITAMT'] = $pr->price;$hosteddata['L_PAYMENTREQUEST_0_NUMBER0'] = $pr->id;$hosteddata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn';
$paypal_data = http_build_query($hosteddata);
$hosted_saas_response = $this->PPHttpPost('CreateRecurringPaymentsProfile', $paypal_data);
I used a separate method to post parameters to paypal
private function PPHttpPost( $methodName_, $nvpStr_ ) {
$api_username = 'yourpaypal#email.com';
$api_password = 'QWEQWEWQEQWEQEQWE';$api_signature = 'WQEQWEQWEQWEWQEQWEQWEQWEQWEQWE.cT';$api_endpoint = "https://api-3t.paypal.com/nvp";$version = '124.0';
$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $api_endpoint); curl_setopt($ch, CURLOPT_VERBOSE, 1);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$api_password&USER=$api_username&SIGNATURE=$api_signature&$nvpStr_";
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $api_endpoint.");
}
return $httpParsedResponseAr;
}
The other way to cancel is inside the user account:
Log in to your PayPal account.
Click Profile near the top of the page.
Click My money.
Click Update in the My preapproved payments section.
Click Cancel, Cancel automatic billing, or Cancel subscription and follow the instructions.

disqus oauth2 login issue

I am trying to use disqus login here: http://beta.perfectquiver.com/include/disqus/index.php
Also i set redirect URL : http://beta.perfectquiver.com/include/disqus/index.php in disqus configuration.
But it showing me error
Invalid parameter: redirect_uri (values for POST and GET arguments differ)" ["error"]=> string(13) "invalid_grant" }
After google it, someone said it is issue with mismatch of redirect URL, it should be identical.
But here its already identical.
Still same error.
Here id the code which i am using.
$PUBLIC_KEY = "PUBLIC_KEY";
$SECRET_KEY = "SECRET_KEY";
$redirect = urlencode("http://beta.perfectquiver.com/include/disqus/index.php");
$endpoint = 'https://disqus.com/api/oauth/2.0/authorize?';
$client_id = $PUBLIC_KEY;
$scope = 'read,write';
$response_type = 'code';
$auth_url = $endpoint.'&client_id='.$client_id.'&scope='.$scope.'&response_type='.$response_type.'&redirect_uri='.$redirect;
echo "<h3>Trigger authentication -> <a href='".$auth_url."'>OAuth</a></h3>";
$CODE = $_GET['code'];
if($CODE){
extract($_POST);
$authorize = "authorization_code";
$url = 'https://disqus.com/api/oauth/2.0/access_token/';
$fields = array(
'grant_type'=>urlencode($authorize),
'client_id'=>urlencode($PUBLIC_KEY),
'client_secret'=>urlencode($SECRET_KEY),
'redirect_uri'=>urlencode($redirect),
'code'=>urlencode($CODE)
);
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, "&");
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$data = curl_exec($ch);
curl_close($ch);
$auth_results = json_decode($data);
echo "<p><h3>The authentication information returned:</h3>";
var_dump($auth_results);
echo "</p>";
$access_token = $auth_results->access_token;
echo "<p><h3>The access token you'll use in API calls:</h3>";
echo $access_token;
echo "</p>";
echo $auth_results->access_token;
function getData($url, $SECRET_KEY, $access_token){
//Setting OAuth parameters
$oauth_params = (object) array(
'access_token' => $access_token,
'api_secret' => $SECRET_KEY
);
$param_string = '';
//Build the endpiont from the fields selected and put add it to the string.
//foreach($params as $key=>$value) { $param_string .= $key.'='.$value.'&'; }
foreach($oauth_params as $key=>$value) { $param_string .= $key.'='.$value.'&'; }
$param_string = rtrim($param_string, "&");
// setup curl to make a call to the endpoint
$url .= $param_string;
//echo $url;
$session = curl_init($url);
// indicates that we want the response back rather than just returning a "TRUE" string
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($session,CURLOPT_FOLLOWLOCATION,true);
// execute GET and get the session backs
$results = curl_exec($session);
// close connection
curl_close($session);
// show the response in the browser
return json_decode($results);
}
//Setting the correct endpoint
$cases_endpoint = 'https://disqus.com/api/3.0/users/details.json?';
//Calling the function to getData
$user_details = getData($cases_endpoint, $SECRET_KEY, $access_token);
echo "<p><h3>Getting user details:</h3>";
var_dump($user_details);
echo "</p>";
//Setting the correct endpoint
$forums_endpoint = 'https://disqus.com/api/3.0/users/listForums.json?';
//Calling the function to getData
$forum_details = getData($forums_endpoint, $SECRET_KEY, $access_token);
echo "<p><h3>Getting forum details:</h3>";
var_dump($forum_details);
echo "</p>";
}

Google Tracks API "Bad Request" using PHP

I am using Google Tracks API to build a simple web based program to track a vehicle that has a tracking device sending latitude and longitude coordinates.
I am using PHP and the OAuth2 PHP library to make an authorized connection.
After authorizing and getting an access token I am making a request to create entities. Though I can't seem to get this working and keep getting a "400 Bad Request" response. Following all the steps shown in the documentation.
Here is my code:
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$parsedAuth['access_token'];
$data = array('entities' => array( "name"=> "Chevrolet" ));
$json_data = json_encode($data);
$data_length = http_build_query($data);
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n". "Content-Length: " . strlen($data_length) . "\r\n",
'method' => 'POST',
'content' => $json_data
),
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
var_dump($response);
Exact Error is: "failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request"
Why am I getting a bad request? What would be a good request that will register these entities and return id's?
Thank you
The answer given here is wrong. The documentation states that it must be a POST see here My issue was not with the Auth but with the Tracks API itself. I ended up moving to create the request with CURL and it works just fine.
Please. This is PHP with CURL. It works 100%.
//Google maps tracks connection
//Get Files From PHP Library
require_once 'google-api-php-client/src/Google/autoload.php';
require_once 'google-api-php-client/src/Google/Service/MapsEngine.php';
//Set Client Credentials
$client_id = '*************.apps.googleusercontent.com'; //Client ID
$service_account_name = '************#developer.gserviceaccount.com'; //Email Address
$client_email = '*************#developer.gserviceaccount.com';
$private_key = file_get_contents('************.p12');
$scopes = array('https://www.googleapis.com/auth/tracks');
//Create Client
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//Send Credentials
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key
);
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$client->setAssertionCredentials($credentials);
$_SESSION['service_token'] = $client->getAccessToken();
foreach ($_SESSION as $key=> $value) {
$vars = json_decode($value);
}
$parsedAuth = (array) $vars;
$token = $parsedAuth['access_token'];
//all functions in the program use this auth token- It should be global for easy accesses.
global $token;
function createEntities(){
global $token;
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$token;
//FIX ME: fields is temporarily hard coded- should be brought from DB
$fields = array(
'entities' => array(
'name' => "DemoTruck",
'type' => "AUTOMOBILE"
),
);
//json string the data for the POST
$query_string = '';
foreach($fields as $key => $array) {
$query_string .= '{"' . urlencode($key).'":[{';
foreach($array as $k => $v) {
$query_string .= '"' . urlencode($k) . '":"' . urlencode($v) . '",';
}
}
$str = rtrim($query_string , ',');
$fstr = $str.'}]}';
$length = strlen( $fstr );
//open connection
$ch = curl_init();
//test connection
if (FALSE === $ch)
throw new Exception('failed to initialize');
//set options
$header = array('Content-type: application/json');
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fstr);
$result = curl_exec($ch);
//dump in case of error
if (FALSE === $result){
var_dump( curl_error($ch) );
var_dump( curl_getinfo($ch) );
}
//close connection
curl_close($ch);
}

Categories