Getting oxwall to submit a JSON document - php

I am working on a billing plugin for oxwall. The lack of documentation is hell and I wonder why this is not a priority.
I have used the paypal and ccbill plugins as guides, and up till now things have been well, manageable.
Now, I need to submit the order to the gateway. For paypal and ccbill, they expect the details in a html POST. However, for this gateway (Paystack) the order detail has to be submitted as a JSON document, with an Authorization header...then a header redirect to the authorization_url.
I'd appreciate all the help.

Ok, I figured this out by
1. Taking advantage of a PHP library for the gateway...which supports guzzle and cURL as fallback.
2. calling the transaction initialize inside of form()
See snippet below...
if ( $billingService->prepareSale($adapter, $sale) )
{
$totalAmount = floatval($sale->totalAmount * 100); //convert to kobo
$saleHash = $sale->hash;
$userEmail = $userService->findUserById($sale->userId)->getEmail();
$metadata = array(
'itemName' => $sale->entityDescription,
'itemID' => $sale->entityKey,
);
$response = $paystack->transaction->initialize([
'reference' => $saleHash,
'amount' => $totalAmount, // in kobo
'email' => $userEmail,
'callback_url' => $fields['notify_url'],
'metadata' => json_encode($metadata),
]);
$url = $response->data->authorization_url;
$masterPageFileDir = OW::getThemeManager()->getMasterPageTemplate('blank');
OW::getDocument()->getMasterPage()->setTemplate($masterPageFileDir);
header('Location: '.$url);
$billingService->unsetSessionSale();
}

Related

Communicating between two WordPress site using REST API & without any authentication

I have 2 WordPress sites in 2 different domains. One is my server & another one is my client site. In my server WordPress, I have a custom WordPress REST API endpoint that accepts POST requests. The client will send some custom data to the server. Then the server processes the data & returns an output.
The issue is that I can't use any authentication method here. The API must be public & any WordPress site can send some data to the server. In the server's REST API callback function, I have added some custom sanitization & validation. Also, nothing to be saved in the DATABASE.
I have added the below code snippet to make a public API endpoint in my server.
add_action( 'rest_api_init', 'register_rest_route_abcd' );
function register_rest_route_abcd() {
register_rest_route(
'mycustomapi', 'v1/abcd',
array(
'methods' => 'POST',
'callback' => array( 'my_callback_function'),
'permission_callback' => '__return_true',
)
);
}
Then in the client file, I have used wp_safe_remote_post to post my custom data.
wp_safe_remote_post( $target_url, array('body' => $request_data) )
The requested data is custom data & there are no authentication parameters there. I got the error given below.
{"code":"rest_not_logged_in","message":"You are not currently logged in.","data":{"status":401}}
I need a public API endpoint where anyone can submit some data.
NOTE: I have a custom string like a key in the submitted data & can I use that string to authenticate API response?
Update: The issue was automatically resolved. I haven't done any changes in the code or file.
I have attached the code snippet that will be useful for someone else. Public API that accepts POST requests is always vulnerable. So be careful. I believe that later we can get some suggestions regarding it.
In server-side
add_action( 'rest_api_init', 'register_rest_route_abcd');
function register_rest_route_abcd() {
register_rest_route(
'myapi', 'v1/myroute',
array(
'methods' => 'POST,GET',
'callback' => 'my_callback_function',
'permission_callback' => '__return_true',
)
);
}
function my_callback_function($request){
//Do logic here
// Prepare response
$response = array();
$response['status'] = true;
$response['message'] = 'done';
return $response;
}
In clint side
add_action( 'template_redirect', 'ed45r_my_action', 5 );
function ed45r_my_action(){
$target_url = 'http://localhost/server-sys/wp-json/myapi/v1/myroute';
$data = array(
'key_1' => 'value_1',
'key_2' => 'value_2',
);
$request = wp_safe_remote_get( $target_url, array('body' => $data) );
if(is_wp_error($request) || wp_remote_retrieve_response_code($request) != 200){
// Know the errror
} else {
$response = wp_remote_retrieve_body( $request );
$response = json_decode($response, true);
// Process the response
}
}
In my case, the action is not a template_redirect. It is a form submission.

GoCardless API - List Subscriptions

I am using the GoCardless Documentation here to try list all subscriptions for a customer.
I have followed the instructions as you can see below, however nothing at all is displaying when I run this script - does anyone know what I may have done wrong?
require 'vendor/autoload.php';
$client = new \GoCardlessPro\Client(array(
'access_token' => 'XXXXXx',
'environment' => \GoCardlessPro\Environment::LIVE
));
$client->subscriptions()->list([
"params" => ["customer" => "CU000R3B8512345"]
]);
Calling a method on its own doesn’t do anything. It’ll execute the given method, but it’s not going to print anything to your browser screen on its own.
As RiggsFolly says (and is documented in GoCardless’s API documentation), calling $client->subscriptions()->list() will return a cursor-paginated response object. So you need to do something with this result. What that is, I don’t know as it’s your application’s business logic and only you know that.
<?php
use GoCardlessPro\Client;
use GoCardlessPro\Environment;
require '../vendor/autoload.php';
$client = new Client(array(
'access_token' => 'your-access-token-here',
'environment' => Environment::SANDBOX,
));
// Assign results to a $results variable
$results = $client->subscriptions()->list([
'params' => ['customer' => 'CU000R3B8512345'],
]);
foreach ($results->records as $record) {
// $record is a variable holding an individual subscription record
}
Pagination with Gocardless:
function AllCustomers($client)
{
$list = $client->customers()->list(['params'=>['limit'=>100]]);
$after = $list->after;
// DO THINGS
print_r($customers);
while ($after!="")
{
$customers = $list->records;
// DO THINGS
print_r($customers);
// NEXT
$list = $client->customers()->list(['params'=>['after'=>$after,'limit'=>100]]);
$after = $list->after;
}
}

adding script tag in shopify using php

We are using this GitHub PHP library for adding javascript in to the head of shopify pages using script tag but we have got stuck somewhere,
it redirects well. We go to app screen to get permission also when we click on install it redirects to redirect page and gives error. in my error log.
Uncaught PHPShopify\Exception\ApiException: script_tag -
expected Array to be a Hash in
This is our app code
<?php
require '/home/xxx/public_html/shopify/1/vendor/autoload.php';
$config = array(
'ShopUrl' => 'xyyy.myshopify.com',
'ApiKey' => 'a07235d5cxx4af2239ea02fe197',
'SharedSecret' => '7ae8a450xxxx2576cf5e7a606c3',
);
PHPShopify\ShopifySDK::config($config);
$shopify = new PHPShopify\ShopifySDK;
$scopes = array('read_orders','read_script_tags','read_products', 'write_script_tags');
$redirectUrl = 'https://xxxx.com/shopify/1/99.php/auth/callback';
$auth = \PHPShopify\AuthHelper::createAuthRequest($scopes, $redirectUrl);
$src = "https://xxxx.com/modules/script72paid.js";
$finalurl='https://xxxxx.myshopify.com/admin/script_tags.json'.
$shopify->ScriptTag->post(array("post"), ''.$finalurl.'', array( "script_tag" => array( "event"=>"onload", "src"=>$src)));
?>
and this is our redirect link code
<?php
require '/home/xxxxxx/public_html/shopify/1/vendor/autoload.php';
$config = array(
'ShopUrl' => 'xxxx.myshopify.com',
'ApiKey' => 'a07235d5cxxxxxx9ea02fe197',
'SharedSecret' => '7ae8a45xxxxxxx76cf5e7a606c3',
);
PHPShopify\ShopifySDK::config($config);
$shopify = new PHPShopify\ShopifySDK;
$accessToken = \PHPShopify\AuthHelper::getAccessToken();
$config2 = array(
'ShopUrl' => 'xxxx.myshopify.com',
'AccessToken' => $accessToken,
);
$shopify2 = new PHPShopify\ShopifySDK($config2);
$src = "https://xxxxx.com/modules/script72paid.js";
$finalurl='https://xxxxx.myshopify.com/admin/script_tags.json'.
$shopify2->ScriptTag->post(array("post"), ''.$finalurl.'', array( "script_tag" => array( "event"=>"onload", "src"=>$src)));
?>
How do we avoid this error with expected Array to be a Hash?
Any help will be great.
Check that you are passing the correct parameters to $shopify->ScriptTag->post() by looking at the function in your copy of the library. Different versions of the library and documentation may have changed something.
Check that those parameters are in the correct order.
Check that all of the arrays you are passing are not actually meant to be objects.
Check if any of the arrays need to wrapped in another array.

webhook error when trying to do ajax

I modified it all now I have this file that makes my api work.
auth.php:
<?php
include 'Unirest.php';
function login()
{
$headers = array('Accept' => 'application/json');
$data = array(
"grant_type" => "password",
"client_id" => "myclientid",
"client_secret" => "myclientsecret",
"username" => "username",
"password" => "password"
);
$response = Unirest\Request::post('http://i-scent.fr/api/oauth_token', $headers, $data);
// $response->code;
// $response->headers;
return $response->body->access_token;
}
function device_info($device_id,$token){
$header = array('Accept' => 'application/json',
'Authorization' => 'Bearer '.$token );
$response = Unirest\Request::get('http://i-scent.fr/api/devices/'.$device_id,$header);
echo $response->body->name;
echo "</br>";
}
function diffuse($device_id,$token,$duration,$intensity){
$header = array('Accept' => 'application/json', 'Authorization' => 'Bearer '.$token );
$data = array('time' => 1, 'percent' => 50);
$body = Unirest\Request\Body::form($data);
$response = Unirest\Request::put('http://i-scent.fr/app_dev.php/api/device/'.$device_id.'/actions/diffusion',$header,$body);
echo $response->code;
echo "</br>";
}
When I use all the functions in a simple script it works perfectly on my website. But when I put it like this in my webhook, I have error 500 internal server error. I have all the unirest libraries.
<?php
include "auth.php";
function processMessage($update) {
if($update["result"]["action"] == "sayHello"){
$token = login();
$name = device_info("1966",$token);
diffuse("1966",$token,"0.5","50");
sendMessage(array(
"source" => $update["result"]["source"],
"speech" => "bonjour webhook",
"displayText" => "bonjour webhook",
"contextOut" => array()
));
}
}
function sendMessage($parameters) {
echo json_encode($parameters);
}
$update_response = file_get_contents("php://input");
$update = json_decode($update_response, true);
if (isset($update["result"]["action"])) {
processMessage($update);
}
Error 500 is supposed to mean that the webhokk's script crashed somewhere but I don't know where and why.
Update 2
Based on your most recent code, you're including "auth.php", which works in the original environment (which is being called as part of a web page, it sounds like).
Your code has two functions, device_info() and diffuse(), which output their results instead of returning them. This output isn't JSON, and includes HTML markup. This is being sent as part of the result of your webhook and will cause what is returned to be invalid.
Update
Based on your latest code, there are still many logical, and a few syntactical, problems.
A "500 Internal Server Error" indicates that your program didn't run correctly and crashed for some reason. As posted, it is missing a closing }, which could be the problem if that isn't in your actual code.
Even if you fix that, there are many issues with the code:
It isn't clear what you intend to do with the results of calling your "test1" script. You store them in $data and don't do anything with it.
You're calling the other website (test1) before you look at what the user has asked you to do. Which is fine, but then why do you care what the user is asking you?
Original Answer
There are a few errors here, but the underlying problem is that you're mixing up where things run and the capabilities of the caller to your webhook.
For a Dialogflow webhook, Google/Dialogflow is sending JSON (which you seem to be handling ok), and expecting back JSON. Although it looks like you send this back as part of send_message(), you're also sending something back when you call connexion(). What you're sending back in this case is not JSON, but HTML with JavaScript.
Which leads to the second problem - If this was php that was generating an HTML page that included a script, you'd be in fine shape. But it isn't. You have to send back only JSON.
You can do something like this to call the other API and get back the contents:
$body = file_get_contents("http://google-home.exhalia.fr/test1");
Which will set $body to the body of the page you've called. What you do with that, at that point, is up to you. But you need to make this call before your call to send_message() because you want to represent the contents as part of what you're saying.
(See How to send a GET request from PHP? for a discussion of other methods available to you in case you need to do a POST, use header information, etc.)

laravel-soap - can't get the response outside of the wrapper

All,
I'm trying to get https://github.com/artisaninweb/laravel-soap to work, but no love. This is likely not a problem with the package, but a gap in my understanding of PHP (which I haven't used in a number of years).
The doco says:
SoapWrapper::add(function ($service) {
$service->name('currency')->wsdl('http://currencyconverter.kowabunga.net/converter.asmx?WSDL');
});
$data = [
'CurrencyFrom' => 'USD',
'CurrencyTo' => 'EUR',
'RateDate' => '2014-06-05',
'Amount' => '1000'
];
SoapWrapper::service('currency',function($service) use ($data) {
var_dump($service->getFunctions());
var_dump($service->call('GetConversionAmount',$data)->GetConversionAmountResult);
});
Now that all works great... But how on earth do I get the response from $service->call... back out into my application?
I've tried
$response = SoapWrapper::service('currency',function($service) use ($data) {
$service->call('GetConversionAmount',$data)->GetConversionAmountResult;
});
but that just returns the soap client response.
I've tried:
$response = '';
SoapWrapper::service('currency',function($service) use ($data) {
$response = $service->call('GetConversionAmount',$data)->GetConversionAmountResult;
});
but that does nothing as it seems anything inside that wrapper call only exists inside that block.
They are really the only two things I could think of doing as I'm not very familiar with all these singleton calls that seem to occur in Laravel (I was also of the opinion that they should be avoided like the plague).
Any help would be greatly appreciated.
I'm the creator of the laravel-soap package.
You can give the data back like so:
$response = '';
$data = [
'CurrencyFrom' => 'USD',
'CurrencyTo' => 'EUR',
'RateDate' => '2014-06-05',
'Amount' => '1000'
];
SoapWrapper::service('currency',function($service) use ($data,&$response) {
$response = $service->call('GetConversionAmount',$data)->GetConversionAmountResult;
});
var_dump($response);
This is called passing by reference: http://php.net/manual/en/language.references.pass.php
I've you got some issues with the laravel-soap package please create a issue on Github.

Categories