How to call an external API in magento 2.2? - magento2

I am new to Magento 2. I need help in the following query.
How to call an external API on page load or on click of a button in Magento 2.2?
Do we need to create an observer for the same or is there a better way to do it. Will appreciate if any links are provided for step by step process.

First of all, we need to know how to call a basic API. Here is example about GET:
$externalAPI = 'https://your/external/api_url'
$ch = curl_init($externalAPI);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$result = curl_exec($ch);
var_dump($result);
From the Magento side, we can use \Magento\Framework\HTTP\Client\Curl class:
$apiUrl = '';
$this->curl->addHeader('Content-Type', 'application/json');
$this->curl->get($apiUrl);
$body = $this->curl->getBody();
$httpCode = $this->curl->getStatus();
//Quick decoding body
$dataResponse = \Zend_Json::decode($body);
How to call an external API on page load or on click of a button in
Magento 2.2?
Do we need to create an observer for the same or is there
a better way to do it.
It depends on the requirements. When do you need to connect to API? Or just display it on the frontend?
Once you know when(or where?) you need to call the external API. You can choose the Plugin, Observer, or Ajax solution.

Related

PayPal Payments Advanced Setup Error

I am trying to integrate PayPal advanced payments into my website so that users can make payments directly on the website, however I am having trouble with setting it up. This is what my code looks like:
$amt = 10.00;
$txt = "Pay Now!";
$PF_HOST_ADDR = "https://pilot-payflowpro.paypal.com";
$secureTokenId = uniqid('', true);
$postData = "USER=" . "username"
. "&VENDOR=" . "username"
. "&PARTNER=" . "PayPalCA"
. "&PWD=" . "Password"
. "&CREATESECURETOKEN=Y"
. "&SECURETOKENID=" . $secureTokenId
. "&TRXTYPE=S"
. "&AMT=" . $amt;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $PF_HOST_ADDR);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$resp = curl_exec($ch);
if (!$resp) {echo "<p>To order, please contact us.</p>";}
parse_str($resp, $arr);
if ($arr['RESULT'] != 0) {echo "<p>To order, please contact us.</p>";}
echo "<iframe src='https://pilot-payflowlink.paypal.com?SECURETOKEN=" . $arr['SECURETOKEN'] . "&SECURETOKENID=" . $secureTokenId . "&MODE=TEST' width='490' height='565' border='0' frameborder='0' scrolling='no' allowtransparency='true'>";
I'm using layout C (embedded iframe) instead of A or B (Hosted checkout pages, which would use a form at the end instead of an iframe).
The result I get looks like this:
Array ( [RESULT] => 1 [RESPMSG] => User authentication failed )
And the iframe gives the following error:
Error: Invalid Merchant or Merchant doesn't exist!
I am entering the same information I use to log into my account at https://manager.paypal.com/ and I have done all the required setup on that website. Any help would be greatly appreciated.
The code you have provided works fine as long as the manager credentials are working properly.
The only way I was able to get that error with correct credentials is changing from TEST to LIVE inside of the hosted checkout setup page inside the manager account.
You may want to try creating a secondary user in your manager account if those settings are correct.
I solved this by logging into the PayPal Manager, going to Service Settings->Customize and clicking Save and Publish.

How do i do api calls using models on my laravel api client?

So am basically building a restful client with laravel that will not have a database. So if anyone has any ideas on how to structure this, I would be very grateful.
Cheers
I think that the more generic and robust design for your app is the MVC pattern like a standard Laravel app. In fact the only difference is that the model layer will not interact with a database but with an API.
You will have to forget Eloquent model and build your own model layer with the classic Object Oriented practices (constructor, accessors...). Then you will be able to deal with objects in your controller and not with an API. If you want to build something enough generic to be reused you can adopt the same syntax as Eloquent and write models like that :
<?php
class User {
protected $url = "http://myapi.com/users/"
protected $id;
protected $name;
public function save()
{
$data = json_encode(array(
'id' => $this->id,
'name' => $this->name,
))
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
return true;
}
}
Then you will be able to call $user->save(); with the exact same behavior that an Eloquent model. Of course, a lot of improvements and generalisation (why not a super class named EloquentAPI...) are needed but you can see the idea. If the job is well done with methods all(), find(), save() and few others implemented, you could switch between a database or a web service implementations easily. The other big interest of this approach is to clean up your controllers and let all the curl's mess in a separate layer.
The second option is to forget the model layer and directly call your REST API in your controllers. It could be a good idea if your app is small and don't need to be scalable but, be careful, if you do that the maintenance of your app could be painful, for example if there is changes in the REST API.
A better way is to use the PHP API Wrapper. Basically a wrapper around your API which can be used by Eloquent:
https://github.com/CristalTeam/php-api-wrapper

How to make a personal facebook app

I'm trying to make a facebook application that would do something on my own timeline. I can't understand facebook's own manual about this so i'm not really sure how things work there, so i'm hoping someone can clarify things here. I don't want anyone installing that application or somehow abusing it to post things on my timeline in my name. What steps should i take to prevent these things if possible?
Beyond what you have learned yet, you can use the php-sdk to authenticate and then check the visitors user id.
"i will edit in code as we discover what you are trying to accomplish, action wise."
php sdk example.
// init php sdk here.
// check if we have a user
// call api to get info about use
$user_profile = $facebook->api('/me');
// if we have a user, we can use that user id as a wrapper to filter content.
if($user_profile[id]==='000000000'){
// 000000000 is your facebook id for this example.
// i am logged in, and only i can see this.
// get some info, make a few posts, add photos etc; here.
}
cURL example
when you curl 'me', it ensures that it is the current session user, then when you compare that to your actual user id, you can gate "so to speak" content that only you can see and use.
cURL'ing to the me connection is only needed to create gate, you can do all your other curl calls after you know it is you doing it.
http://anotherfeed.com/curl.api.php?objid=me
here is an example, when i curl me, it looks for a logged in user, if there is an access token which for this example i excluded, it will return an array with my "me" info including my id.
Hard coded i will use $me=$curlresults[id] which is my user id returned by the session call.
to gate i simply
$me=$curlresults[id]
if($me==='myfacebookuserid'){
// do my other curl calls here, i know only i can see this.
}
Full cURL example.
get your user access token for your app from the token tool below, store it somewhere safe so you can pass it in via url param or session param.... https://developers.facebook.com/tools/access_token/
add your facebook user id where it says myfacebookuserid
to secure this you will need to pass the access token in with post, get or session.
for this example we will use the get method.
yourpage.php?user_token=youruseraccesstoken is how it is passed in this example.
$access_token = $_GET['user_token'];
$build = 'https://graph.facebook.com/me?'.$access_token.'';
function GetCH($url){
$ch=null;
if(!$ch){
$ch = curl_init();
}
curl_setopt($ch, CURLOPT_URL, "".$url."");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$return=curl_exec($ch);
if(!curl_errno($ch)){
return $return;
}else{
$fb_fail=curl_error($ch);
return $fb_fail;
}
curl_close($ch);
unset($ch);
};
$returned=GetCH($build);
$locs=json_decode($returned, true);
$meid=$locs[id];
if($meid==='myfacebookuserid'){
// do my other curl calls here, i know only i can see this.
}

Delete requests returns true, but request still exists?

Possible answer or bug: Using the user access token seems to work, it deletes the request and will throw an error when trying to read it in the future, but it still exists in the graph and providing apptoken still shows it, and for some reason wouldn't delete it. Seems contrary to documentation, but changing apptoken to access token seemed to at least provide a workaround for me.
First, the code I'm using (as the one in the documentation always returned an entity not visible by user type message)
function do_delete_request($url, $optional_headers = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//include array of additional headers
if (count($optional_headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $optional_headers);
}
return curl_exec($ch);
}
$full_request_id = build_full_request_id($request_id, $user_id);
$delete_url = "https://graph.facebook.com/" .$full_request_id. "?access_token=".$apptoken;
$result = do_delete_request($delete_url);
I'm sorry if that's messy, I don't know how to format stuff here. I'm at a loss after a lot of googling, I never ask this stuff.
$result returns true, over and over again. Graph explorer shows the request still exists.
By deleting it, does that just mean I remove it from the requests interface for a user? Or am I doing something wrong in my delete process?
I need a way to tell whether or not a request has been accepted already or not. Thanks for any help.
Facebook sends the user to your app with the Request ID(s) in the URL, that's how you tell when a request has been accepted. It's up to you to check for a process a response to a request.
https://apps.facebook.com/[app_name]/?request_ids=[request_ids]
As far as delete not working, is the request still their after some time? Facebook, and many busy sites, do heavy caching so things like delete may not be processed immediately.

creating dynamic unique email address pipes in cpanel with php

Im trying to make something similar to twitpic.com's email submission feature.
Their address schema is something like username.key#twitpic.com. When you send an email to that address it processes it and uploads your picture.
What im wondering is how they generate and handle those addresses in php. I know how to pipe a single email address to a program using cpanel, but how is this done dynamically?
Ill settle on what this is even called or some google search results so i can do my own research, but i just want a place to start.
There's an option in cpanel to set a default address that catches all email sent to addresses that don't exist. This is probably the easiest way to do it.
In fact, in the version of cpanel I have, if you go to Default Address, and go to Advanced Options there an option to pipe to a program all mail without a valid address.
Ok i found this.
http://twiki.cpanel.net/twiki/bin/view/AllDocumentation/AutomationIntegration/Api2AddForwarder
Trying to find out how/where i can do this using PHP
update
Found a cpanel api class here
http://www.phpclasses.org/browse/file/17045.html
Im trying to contact the author of the class to see how to add the functionality of the api to that class (which can already handle creation of forwarders)
Juse copy and pase below code and replace the desired variables and it will be work :
/*Host Credentials*/
$host = "Host Name";
$port = "Port Number ex. 2083";
$HostUserName = "Your cpanel username";
$HostPassword = "Your cpanel password";
/*-------------------------*/
/*Email details which you want to create*/
$email = "email name which you want to create";
$domain = "Domain name on which you want to create the email for subdomain you can write ex. subdomain.domain.com";
$password = "Password for your email"
$quota = "limit which you want to assign for this account."
/*--------------------*/
$query = 'https://'.$host.':'.$port.'/frontend/x3/mail/doaddpop.html?email='.$email.'&domain='.$domain.'&password='.$password.'&quota='.$quota;
$curl = curl_init(); // Create Curl Object
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // Allow self-signed certs
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // Allow certs that do not match the hostname
curl_setopt($curl, CURLOPT_HEADER, 0); // Do not include header in output
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // Return contents of transfer on curl_exec
$header[0] ="Authorization: Basic " . base64_encode($HostUserName.":".$HostPassword) . "\n\r";
curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // set the username and password
curl_setopt($curl, CURLOPT_URL, $query); // execute the query
$result = curl_exec($curl);
curl_close($curl);