meteor http post to other domain - javascript

So I want to use an sms service from 46elks in my meteor project. The following php script allows you to send an sms:
<?
// Example to send SMS using the 46elks service
// Change $username, $password and the mobile number to send to
function sendSMS ($sms) {
// Set your 46elks API username and API password here
// You can find them at https://dashboard.46elks.com/
$username = 'u2c11ef65b429a8e16ccb1f960d02c734';
$password = 'C0ACCEEC0FAFE879189DD5D57F6EC348';
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => "Authorization: Basic ".
base64_encode($username.':'.$password). "\r\n".
"Content-type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query($sms),
'timeout' => 10
)));
return false !== file_get_contents(
'https://api.46elks.com/a1/SMS', false, $context );
}
$sms = array(
'from' => 'DummyFrom', /* Can be up to 11 alphanumeric characters */
'to' => '+46400000000', /* The mobile number you want to send to */
'message' => 'Hello hello!'
);
sendSMS ($sms);
?>
Now I need this in my meteor project and I've been trying to convert it to meteors http.call():
HTTP.call("POST", "https://api.46elks.com/a1/SMS", {
headers:
{
"Authorization": "Basic SomeLongBase46EncodedString",
"Content-type": "application/x-www-form-urlencoded"
},
data:
{
"from": "testFrom",
"to": "+46701111111",
"message": "test message"
}
},
function (error, result)
{
if (error)
{
console.log("error: " + error);
}
else
{
console.log("result: " + result);
}
});
But what I keep getting is the following error:
error: Error: failed [403] Missing key from

Change data to params:
params: {
"from": "testFrom",
"to": "+46701111111",
"message": "test message"
}
and use auth instead of Authorization (docs):
"auth": username + ":" + password

ok, I had to replace data: { ... } with the following formatted string:
content: "from=testFrom&to=+46701111111&message=test message"
This to convert the php http_build_query() correctly.

Related

Error handling with Async/Await in Stripe API JS

I'm playing with the Stripe API. Everything works great, but I want to show possible configurations fails in the frontend. Those fails are handled as an 500.
So this is the condensed code
JS
async function initialize() {
const { clientSecret } = await fetch("index.php?format=json", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: myid, lang: mylang }),
}).then((r) => {
if (r.status >= 400 && r.status < 600) {
// throw new Error(r.status);
}
return r.json()
}
).catch((error) => {
console.log(error)
}
);
console.log(clientSecret);
}
PHP
header('Content-Type: application/json');
try {
// code doing some stuff ...
$output = [
'secret' => 12345
];
echo json_encode($output);
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
When having a misconfiguration, this is (for example) what the fetch call outputs:
{
"error": true,
"code": 0,
"message": "The payment method type provided: acss_debit is invalid. This payment method is available to Stripe accounts in CA and US and your Stripe account is in XX.",
}
So how can I catch that error message in JS and display it to the user?
I tried all kind of stuff in the initialize function.
I managed to access the catched error message by doing this:
if (r.status >= 400 && r.status < 600) {
return r.text()
.then((text) => {
throw (JSON.parse(text));
});
}

Posting nested JSON to WordPress Admin Ajax - can't access object data

I'm trying to mock a payload my WordPress webhook will be receiving once an integration is setup. The payload will contain nested JSON. I've not been able to access data in the JSON object in my PHP function.
This is the structure of the payload I can expect:
data: {
attributes: {
user_name: "John Doe",
user_email: "johndoe#xyz.com"
}
}
Here's my JavaScript that's attempting to POST the same data:
fetch(wp_ajax.ajax_url, {
method: 'POST',
body: new URLSearchParams({
action: 'course_signup',
data: {
attributes: {
user_name: "John Doe",
user_email: "johndoe#xyz.com"
}
}
})
})
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.log(err));
Here's my PHP:
<?php
add_action('wp_ajax_course_signup', 'course_signup');
add_action('wp_ajax_nopriv_course_signup', 'course_signup');
function course_signup()
{
$data = json_decode($_POST['data']);
$user_name = $data['attributes']['user_name'];
$user_email = $data['attributes']['user_email'];
$data = $_POST['data'];
echo json_encode(array(
"action" => $_POST["action"],
"user_name" => $user_name,
"user_email" => $user_email
));
die();
}
Here's the response of my console.log(response)):
{
action: "course_signup",
user_email: null,
user_name: null
}
In the Network tab for the POST request I see the payload as:
action: course_signup
data: [object Object]
Thanks CBroe,
Using Postman helped simplify this.
I updated my PHP to the following which allowed me to access the data I wanted:
$payload = json_decode(file_get_contents('php://input'), true);
$user_name = $payload['data']['attributes']['user_name'];
$user_email = $payload['data']['attributes']['user_email'];

Laravel 8 api how to send token via Authorization

I am using Laravel 8 as a APIrest and I am trying to send my token in the ajax petition but in laravel I get null, I cannot see why. I do not have problems with log in or petitions without token.
In JavaScript I have an AJAX petition like this: (Before sending token is not null, I save it in localStorage)
var settings = {
"url": apiUrl+"bookings/"+userIdentified.id,
"method": "GET",
"timeout": 0,
"headers": {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": token
},
};
$.ajax(settings).done((response) => {
console.log(response);
});
In Laravel, I have a middleware with the following:
// Check user identified
$token = $request->header('Authorization');
$jwtAuth = new \JwtAuth();
$checkToken = $jwtAuth->checkToken($token);
// If it is continue
if ($checkToken) return $next($request);
// If it is not then return an error
$data = array(
'status' => 'error',
'code' => '400',
'message' => $token, // I tested that and it return null
'test' => $request->all()
);
return response()->json($data, $data['code']);
The route:
Route::get('/bookings/{id}', [BookingController::class, 'getBookingsByUser'])->middleware('auth');
And this is the response:
{
code: "400",
status: "error",
message: null, // that have to be the token for testing that exists and is not null
test: []
}
In web console:
GET https://my-url/api/bookings/4 400 (Bad Request)
In laravel, I commented VerifyCsrfToken in kernel.php to not have problems with it.
I have the api in a subdomain but I do not have problem doing register and log in, that works without token. For some reason the token is not arriving to my api :(
There is something that I am missing?
You are missing bearer which specifies the token type.
Change:
"Authorization": token
To:
"Authorization": "bearer token"
Also, if you are making an API request add this header:
"accept": "application/json"

Stripe - Payment Intents (3d secure issue)

I did implement Payment intents on my website and now works perfectly with this testing card 4242 4242 4242 4242, but for other cards that need 3d secure methods, I take this error "Invalid PaymentIntent status".
the Code that I have used is the same standard code that exists on the Stripe documentation-flow enriched with some code to manage mysql, emails, metadata etc.
Where do I go wrong? Thanks in Advance.
simplified js code connected to index.php
var stripe = Stripe('pk_test_xxx');
var elements = stripe.elements();
var cardElement = elements.create('card', {style: style});
cardElement.mount('#card-element');
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var amount = $('#amount').val();
cardButton.addEventListener('click', function(ev) {
ev.preventDefault();
stripe.createPaymentMethod('card', cardElement, {
billing_details: {name: cardholderName.value}
}).then(function(result) {
if (result.error) {
} else {
$body.addClass("loading");
fetch('https://test.com/server.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_method_id: result.paymentMethod.id,
amount: amount
})
}).then(function(result) {
// Handle server response (see Step 3)
result.json().then(function(json) {
handleServerResponse(json);
})
});
}
});
});
function handleServerResponse(response) {
if (response.error) {
} else if (response.requires_action) {
stripe.handleCardAction(
response.payment_intent_client_secret
).then(function(result) {
if (result.error) {
} else {
// The card action has been handled
// The PaymentIntent can be confirmed again on the server
fetch('https://test.com/server.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_method_id: result.paymentMethod.id,
amount: amount
})
}).then(function(confirmResult) {
console.log(confirmResult);
return confirmResult.json();
}).then(handleServerResponse);
}
});
} else {
}
}
simplified code on server.php
<?php
# vendor using composer
require_once('stripe6400/init.php');
\Stripe\Stripe::setApiKey('sk_test_xxx');
header('Content-Type: application/json');
# retrieve json from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$paymentid = $json_obj->payment_method_id;
$amount = $json_obj->amount;
$intent = null;
try {
if (isset($json_obj->payment_method_id)) {
# Create the PaymentIntent
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $json_obj->payment_method_id,
'amount' => $json_obj->amount,
'payment_method_types' => ["card"],
'currency' => 'gbp',
'confirmation_method' => 'manual',
'confirm' => true,
]);
}
if (isset($json_obj->payment_intent_id)) {
$intent = \Stripe\PaymentIntent::retrieve(
$json_obj->payment_intent_id
);
$intent->confirm();
}
generatePaymentResponse($intent);
} catch (\Stripe\Error\Base $e) {
# Display error on client
echo json_encode([
'error' => $e->getMessage()
]);
}
function generatePaymentResponse($intent) {
if ($intent->status == 'requires_action' &&
$intent->next_action->type == 'use_stripe_sdk') {
echo json_encode([
'requires_action' => true,
'payment_intent_client_secret' => $intent->client_secret
]);
} else if ($intent->status == 'succeeded') {
Stripe\Customer::create([
"email" => $email,
"name" => $customer_name,
"source" => "tok_visa" // obtained with Stripe.js
]);
echo json_encode([
"success" => true
]);
} else {
# Invalid status
http_response_code(500);
echo json_encode(['error' => 'Invalid PaymentIntent status']);
}
}
?>
It looks like you might have the same error I just had. The status of the response from stripe is requires_source_action not requires_action so your if statement falls through to Invalid PaymentIntent status.
// change this
// $intent->status == 'requires_action'
// to this
$intent->status == 'requires_source_action'
In my case I'm checking for both so my code is ready for when I do update the stripe SDK.
https://stripe.com/docs/payments/payment-intents/quickstart#confirm-again
(line 33 in the code)
Also on Customer::create your source attribute "tok_visa" must be a real token.id from create token in javascript https://stripe.com/docs/stripe-js/reference#stripe-create-token

how to call curl cmd in Ajax

Here is my curl command is there anyway to execute this command using ajax
curl -X POST -u "CONVERSATION_USERNAME":"CONVERSATION_PASSWORD" -H "Content-Type:application/json" -d "{\"input\": {\"text\":\" \"}}" "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11"
This should work.
$.ajax({
url: "https://conversation_username:conversation_password#gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11",
method: "POST",
headers: {
"Content-Type": "application/json"
},
data: {
input: {
text: " "
}
}
})
done(function(data) {
// handle success response
})
.fail(function(err) {
// handle error response
});
http://api.jquery.com/jquery.ajax/
edit - updated to handle success and error responses using promises.
Create a php file, put that command inside that file, return from it whatever you need from the curl response and call this php file via ajax.
file ajax_curl.php
<?php
//do your curl call here
//curl -X POST -u "CONVERSATION_USERNAME":"CONVERSATION_PASSWORD" -H "Content-Type:application/json" -d "{\"input\": {\"text\":\" \"}}" "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11"
//see http://php.net/manual/en/curl.examples-basic.php
//do a return like so if $url is you url
$defaults = array(
CURLOPT_URL => $url,
your_other_params => go_here,
CURLOPT_RETURNTRANSFER => 1
);
$ch = curl_init();
curl_setopt_array($ch, $defaults);
$result= curl_exec($ch);
if( ! $result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
echo json_encode($result);
?>
your calling js looks like
$.post( "ajax_curl.php", { passed_data: "pass_whatever_you_need" }, function( data ) {
console.log( data );
}, "json");
'data' now contains a json with the response from your curl call
Create a PHP file.here file name is chat.php
<?php
if(isset($_POST['conversation'])) {
$data = array("input"=>array("text"=>$_POST["conversation"]));
$url = "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/a9379972-d820-4cdf-b1cb-ad0af898a534/message?version=2016-07-11";
$ch = curl_init($url);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_USERPWD => "username:password",
CURLOPT_HTTPHEADER => array("Content-Type:application/json"),
CURLOPT_POSTFIELDS => json_encode($data),
));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response));
}
?>
and call this by using Ajax
var xhr = new XMLHttpRequest();
//xhr.open('get', 'chat.php');
xhr.open("GET", "chat.php?data=" + data to be pass, false);
// Track the state changes of the request.
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
//alert(xhr.responseText);
talking = true;
botMessage=xhr.responseText;// 'This is the returned text.'
} else {
// console.log('Error: ' + xhr.status); // An error occurred during the request.
alert ('Error: ' + xhr.status);
}
}
};
// Send the request to send-ajax-data.php
xhr.send();

Categories