Coinbase - php curl sendmoney - invalid signature error - php

I am trying coinbase api to send and get money and going to use in game,on running below code for sending money getting invalid signature error, not sure where I am wrong. I tried getting account detail, which is working fine and I am able to get account details.
<?php
$API_VERSION = '2016-02-01';
$curl = curl_init();
$timestamp = json_decode(file_get_contents("https://api.coinbase.com/v2/time"), true)["data"]["epoch"];
$req = "/v2/accounts/:account_id/transactions";
$url = "https://api.coinbase.com".$req;
$cle = "xxxxxxx";
$secret = "xxxxxxxx";
$params=['type'=>'send', 'to'=>'xxxxxxxxxx', 'amount'=>0.0001, 'currency'=>'BTC'];
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_USERAGENT, 'local server',
CURLOPT_POSTFIELDS => json_encode($params),
CURLOPT_HTTPHEADER => array(
"CB-VERSION:" . $API_VERSION,
"CB-ACCESS-SIGN:" . hash_hmac('sha256', $timestamp."GET".$req, $secret),
"CB-ACCESS-KEY:" . $cle,
"CB-ACCESS-TIMESTAMP:" . $timestamp,
'Content-Type: application/json'
),
CURLOPT_SSL_VERIFYPEER => false
));
$rep = curl_exec($curl);
curl_close($curl);
print_r($rep);
?>

In the $req URL, you need to replace :account_id with an actual account ID such as 3c04e35e-8e5a-5ff1-9155-00675db4ac02.
Most importantly, since this is a post request, the OAuth signature needs to include the payload (POST data) in the signature.
hash_hmac('sha256', $timestamp."POST".$req.json_encode($params), $secret),

When I encountered this error, it ended up being the account id, which is different for each of your currency accounts. Spent way too much time trying to figure out what was wrong with my signature... Anyways, I'd definitely try that out as GETs worked for me, but every other request type ended up with the invalid signature error.

Related

Struggling to Get Token for REST API in PHP OAuth 2 Client. Have Successfully Tested with Postman

I need to add some functionality to my site to connect via REST to a provider and exchange data. I've used Postman for several years to test these APIs for myself and customers, but this is the first time I have tried to add the functionality to my site.
I've Googled numerous sites. I tried a few different things. First I tried the league/oauth2-client library. The requests went through without any errors, but all I received back was a response like this.
JSON response = {"status":"400","timeStamp":"2022-01-22T16:21:19+0000","error":{"errorId":"ea7bc74d-21ca-4503-92ad-3a76b05d7554","message":null,"code":"invalid_request","description":"Cannot generate token. Bad request","details":null}}
So I went to look at other examples. I found this nice and simple code from
UC San Diego Example for Client Credentials. I tried it and got the same type of results. "Cannot generate token. Bad request." For now, I like the simple option of the UCSD example if I can make it work.
As I said, I can successfully make this request and use the API all day long in Postman. So I know the Client ID, Client Secret, and URL are correct.
Unfortunately, I don't know how to troubleshoot this in PHP. I looked in the server log and I didn't find any errors. I tried to echo something out to see if I could see what was wrong, but I couldn't get the request to echo to the page. I tried using Fiddler to see if I could find the request with no luck.
Here's where I am right now. Any suggestions for what I am missing?
Thanks in advance for your help!
<?php
$token_url = "https://xxxx.xxxxx.com/services/api/oauth2/token";
$test_api_url = "https://xxxx.xxxxx.com/services/api/x/users/v2/employees/12345";
// client (application) credentials on xxxx.xxxxxx.com
$client_id = "xxxxxxxxxxx";
$client_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$access_token = getAccessToken();
$resource = getResource($access_token);
echo "</br>access_token = " . $access_token;
echo "</br>resource = " . $resource;
// step A, B - single call with client credentials as the basic auth header
// will return access_token
function getAccessToken() {
global $token_url, $client_id, $client_secret;
$content = "grant_type=client_credentials";
$authorization = base64_encode("$client_id:$client_secret");
$header = array("Authorization: Basic {$authorization}","Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $token_url,
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $content
));
$response = curl_exec($curl);
curl_close($curl);
echo "</br>JSON response = " . $response;
return json_decode($response)->access_token;
}
// step B - with the returned access_token we can make as many calls as we want
function getResource($access_token) {
global $test_api_url;
$header = array("Authorization: Bearer {$access_token}");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $test_api_url,
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true
));
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response, true);
}
?>
So it seems that with a little bit of research and learning on my part the answer to my question was in Postman. Postman includes a feature that will translate your request into any number of code languages.
All I had to do was select the PHP option and copy and paste the results into my project. Boom, there you go. That was easy.
Here's a YouTube video showing how it works.
Postman: Import/Export and Generating Code Samples

Generate Public API Key from USAePay Rest API Returning Error

I have been trying to generate a Public API key for my USAePay account to use with a USAePay Client JS iFrame using PHP.
The CURL request keeps returning error code 80: Transaction type not allowed from this source.
I have tried with and without a pin and in both test mode using sandbox.usaepay. . . and in regular mode without the sandbox in the URL (changing the SourceKey in the console appropriately).
Is it possible that there is something wrong with my PHP code, or am I missing some other setting?
$seed = "abcdefghijklmnop";
$apikey = "mysourcekeyfromconsole";
$apipin = "1234";
$prehash = $apikey . $seed . $apipin;
$apihash = "s2/" . $seed . "/" . hash("sha256",$prehash);
$authKey = base64_encode($apikey . ':' . $apihash);
//print("Authorization: Basic " . $authKey);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.usaepay.com/api/v2/publickey",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET"
]);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Content-Type: application.json",
"Authorization: Basic " . $authKey
]);
$response = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
It seems that this does not work from the sandbox, only from "https://usaepay.com/api/v2/publickey". I don't know why it did not work initially when I tried that, unless I changed some other code or setting. Now, though, when I try to change my code to sandbox, it returns an error, and without sandbox, it returns the public key.

Discord/PHP - Assign user role

Is it possible, using PHP/Discord API to assign a role to a user?
I currently use OAuth2 for my website visitors to register with Discord. I would then later want to assign the registered website users with a role on a discord server when an admin have reviewed their membership, and I've already configured a bot that have been granted the required permissions on the server.
I have been looking at the documents - but unfortunately they do not really give me the dummy-proof guidance I need. https://discordapp.com/developers/docs/resources/guild#modify-guild-member
Could I do this with Curl maybe?
https://discord.com/developers/docs/resources/guild#add-guild-member-role
You can make a cURL call to this API-endpoint, passing a bot token who has the MANAGE_ROLES permission. Here is a code snippet:
$authToken = "bot_token";
$guildid = "guild_id";
$userid = "user_id";
$roleid = "role_id";
$url = "https://discordapp.com/api/v6/guilds/" . $guildid . "/members/" . $userid . "/roles/" . $roleid;
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => array(
'Authorization: Bot '.$authToken,
"Content-Length: 0"
),
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => 0
));
$response = curl_exec($ch);
//It's possible to output the response at this place for debugging, so remove the comment if needed
/*
print $response;
print "<pre>";
print_r(json_decode($response));
print "</pre>";
*/
curl_close($ch);

Getting Twitch clip data via Twitch API and php

I am trying to get data of certain Twitch clip, for example this one https://clips.twitch.tv/MushyJollyWalrusUWot
$videosApi = 'https://api.twitch.tv/kraken/clips/savjz/MushyJollyWalrusUWot';
$clientId = 'my client id';
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_HTTPHEADER => array(
'Client-ID: ' . $clientId
),
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $videosApi
));
$response = curl_exec($ch);
curl_close($ch);
$json = json_decode($response, TRUE);
print_r($json);
I am getting an array with 404 error, but this code works fine with another Twitch api stuff, for example Twitch vod:
$videosApi = 'https://api.twitch.tv/kraken/videos/125820676';
//the rest is same
Like I have found with videos, clips are addressed by their name and nothing else, so I removed the username from your example.
I ended up using this URL https://api.twitch.tv/kraken/clips/MushyJollyWalrusUWot, which successfully returned a slightly large JSON blob containing the clip's information, and I have saved it at this URL: PasteBin - "SO Answer - Getting Twitch clip data via Twitch API and php"
I used to be able to query some base URL like https://api.twitch.tv/kraken/ in order to see a list of available resources that I could query from then on by successively adding to the path, but the /kraken and /kraken/ roots give user information, and /kraken/base does not seem to be a valid resource.
The API documentation for accessing this from the shell seems to be here: Twitch Developers - Twitch API Overview
By the way, I just used the shell, and may have had to provide both a Client ID and an OAuth token with user_read scope. I followed this guide for my reoccurring situation: GitHub - raine/twitch-cli - Setup.
It's not PHP, so I did not review your code in full detail, but some of these steps may help you along with your conceptual troubleshooting.
just add your key
parameters(optional):
limit=10
game=Overwatch
trending=true
//set header for pretty print
header('Content-Type: application/json');
$videosApi = 'https://api.twitch.tv/kraken/clips/top?limit=100&channel=ratirl';
$clientId = 'secret app id provided by twitch';
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_HTTPHEADER => array(
//standard api requirement from twitch api headers
'Accept: application/vnd.twitchtv.v5+json',
'Client-ID: ' . $clientId
),
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $videosApi
));
$response = curl_exec($ch);
curl_close($ch);
//decode the response
$json = json_decode($response, JSON_PRETTY_PRINT);
//print response
print_r($json);

Accessing Picasa Web API using PHP

Does anyone here know about how to access Google Photos API now that Google has started using OAuth2? The PHP client library in their developer website is now obsolete and does not work!
I have used OAuth to work with Google Drive but Photos does not work! :(
First I use Google_Client to successfully authenticate user. Then in the redirect page I am trying following:
require_once("Google/Client.php");
//set up path for Zend GData, because Google Documentation uses that lib
$clientLibraryPath = '/path/to/ZendGData/library';
$oldPath = set_include_path(get_include_path() . PATH_SEPARATOR . $clientLibraryPath);
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Photos');
try
{
$authCode = $_GET['code']; //authorization code returned from google
//next create google OAuth Client object and validate...
$webAuth= new Google_Client();
$webAuth->setClientId($clientId);
$webAuth->setClientSecret($clientSecret);
$webAuth->authenticate($authCode); //this authenticate() works fine...
//now my problem is HOW do I tie this to GData API for Picasa :(
//I tried following but it throws error
//*Token invalid - Invalid token: Request token used when not allowed.*
$client = Zend_Gdata_AuthSub::getHttpClient($authCode);
$gp = new Zend_Gdata_Photos($client, "GData:2.0");
$userFeed = $gp->getUserFeed("default");
I have also tried a bunch of third party libraries, tried hooking up my $webAuth into Zend_GData_Photos in everywhich way I can try...I even tried raw curl calls, but nothing is working!
Can anyone help me please? I am at my wits end....I can't believe Google left a fully functional library (PicasaWeb PHP API Ver 1.0) hanging like that when they updated their authentication to OAuth.
I had the same problem but finally I got it working again.
The best thing is, that you do not need any client library to get access to private photos.
I have spent two days trying to make it work with 'service account' but with no luck.
Then I have found this page:
https://holtstrom.com/michael/blog/post/522/Google-OAuth2-with-PicasaWeb.html
which helped me to achieve what I wanted.
It is pretty long article but it should not take to long to sort it out and get it working. Basically you will need to use 'OAuth 2.0 client ID' instead of 'Service account' in your project at https://console.developers.google.com
Within your 'OAuth 2.0 client ID' you will have following information:
Client ID (something-random.apps.googleusercontent.com)
Client Secret (random-client-secret)
Name (www.yoursite.com)
Authorized JavaScript origins (https://www.yoursite.com)
Authorized redirect URIs (https://www.yoursite.com/oauth2.php)
You will use this data in your verification process.
Before you begin, you will need to complete OAuth Consent Screen.
In that tutorial there is a note to store these tokens in DB, but in this case I'd rather suggest to display them directly in web page. This is much easier.
There is suggestion to use https rather than http but it should work on both.
I have used https for my application.
This is shorter version of the article from the link above.
Create oauth2.php file and place it on https://www.yoursite.com/oauth2.php
<?php
if (isset($_GET['code']))
{
$clientId = 'your-client-id.apps.googleusercontent.com';
$clientSecret = 'your-client-secret';
$referer = 'https://www.yoursite.com/oauth2.php';
$postBody = 'code='.urlencode($_GET['code'])
.'&grant_type=authorization_code'
.'&redirect_uri='.urlencode($referer)
.'&client_id='.urlencode($clientId)
.'&client_secret='.urlencode($clientSecret);
$curl = curl_init();
curl_setopt_array( $curl,
array( CURLOPT_CUSTOMREQUEST => 'POST'
, CURLOPT_URL => 'https://accounts.google.com/o/oauth2/token'
, CURLOPT_HTTPHEADER => array( 'Content-Type: application/x-www-form-urlencoded'
, 'Content-Length: '.strlen($postBody)
, 'User-Agent: www.yoursite.com/0.1 +https://www.yoursite.com/'
)
, CURLOPT_POSTFIELDS => $postBody
, CURLOPT_REFERER => $referer
, CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
, CURLOPT_TIMEOUT => 15 // max seconds to wait
, CURLOPT_FOLLOWLOCATION => 0 // don't follow any Location headers, use only the CURLOPT_URL, this is for security
, CURLOPT_FAILONERROR => 0 // do not fail verbosely fi the http_code is an error, this is for security
, CURLOPT_SSL_VERIFYPEER => 1 // do verify the SSL of CURLOPT_URL, this is for security
, CURLOPT_VERBOSE => 0 // don't output verbosely to stderr, this is for security
) );
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
echo($response);
echo($http_code);
}
else { echo 'Code was not provided.'; }
?>
Prepare and visit this link:
https://accounts.google.com/o/oauth2/auth?scope=https://picasaweb.google.com/data/&response_type=code&access_type=offline&redirect_uri=https://www.yoursite.com/oauth2.php&approval_prompt=force&client_id=your-client-id.googleusercontent.com
fields to adjust: redirect_uri and client_id
After visiting link from step 2. you should see your consent screen where you will have to approve it and you will be redirected to your oauth.php page but this time with code parameter:
https://www.yoursite.com/oauth2.php?code=some-random-code
'code' parameter will be then sent by oauth.php to: https://accounts.google.com/o/oauth2/token
which will return(print) json formatted data containing: access_token, token_type, expires_in and refresh_token.
Http Response code should be 200.
Access_token will be the one to use to get privet albums data.
Create index.php with content:
<?php
$curl = curl_init();
$url = 'https://picasaweb.google.com/data/entry/api/user/default';
curl_setopt_array( $curl,
array( CURLOPT_CUSTOMREQUEST => 'GET'
, CURLOPT_URL => $url
, CURLOPT_HTTPHEADER => array( 'GData-Version: 2'
, 'Authorization: Bearer '.'your-access-token' )
, CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
) );
$response = curl_exec($curl);
$http_code = curl_getinfo($curl,CURLINFO_HTTP_CODE);
curl_close($curl);
echo($response . '<br/>');
echo($http_code);
?>
After running script from step 5. you should receive your default feed from picasaweb API. When I say 'default' it ,eans default when you are logged that is with private albums. From now on, you should be able to use that approach to get access to your picasa photo library.
Access token will expire after 3600 seconds (1 hour) so you will have to get new one. this can be achieved with script like this one below:
$clientId = 'your-client-id.apps.googleusercontent.com';
$clientSecret = 'your-client-secret';
$referer = 'https://www.yoursite.com/oauth2.php';
$refreshToken = 'your-refresh-token';
$postBody = 'client_id='.urlencode($clientId)
.'&client_secret='.urlencode($clientSecret)
.'&refresh_token='.urlencode($refreshToken)
.'&grant_type=refresh_token';
$curl = curl_init();
curl_setopt_array( $curl,
array( CURLOPT_CUSTOMREQUEST => 'POST'
, CURLOPT_URL => 'https://www.googleapis.com/oauth2/v3/token'
, CURLOPT_HTTPHEADER => array( 'Content-Type: application/x-www-form-urlencoded'
, 'Content-Length: '.strlen($postBody)
, 'User-Agent: www.yoursite.com/0.1 +https://www.yoursite.com/'
)
, CURLOPT_POSTFIELDS => $postBody
, CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
, CURLOPT_TIMEOUT => 15 // max seconds to wait
, CURLOPT_FOLLOWLOCATION => 0 // don't follow any Location headers, use only the CURLOPT_URL, this is for security
, CURLOPT_FAILONERROR => 0 // do not fail verbosely fi the http_code is an error, this is for security
, CURLOPT_SSL_VERIFYPEER => 1 // do verify the SSL of CURLOPT_URL, this is for security
, CURLOPT_VERBOSE => 0 // don't output verbosely to stderr, this is for security
) );
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if (strlen($response) < 1)
{ echo('fail 01'); }
$NOW = time();
$responseDecoded = json_decode($response, true); // convert returned objects into associative arrays
$expires = $NOW - 60 + intval($responseDecoded['expires_in']);
if ( empty($responseDecoded['access_token'])
|| $expires <= $NOW )
{ echo('fail 02'); }
echo($http_code . '<br/>');
echo($response . '<br/>');
echo($expires . '<br/>');
?>
You can run code from step 7. in separate script manually, just to get new access-token for another 3600 seconds, but normally you would want to have it automated so when access_token expires, you automatically ask for new one using a call with refresh_token from step 4.
Ufff. That is is. I hope you'll get this up and running.

Categories