Issue while integrating SMS gateway in PHP - php

In my PHP project I want to integrate SMS gateway.
I have integrated HSPSMS SMS gateway.
They have given one API for this,but unfortunately I am unable to call this in proper way. I have called API after user successfully registered to site for sending SMS to user regarding same to notify he had successfully registered. Currently I am sending SMS for same but API's can send response back for SMS delivery(Successfully SMS sent or not in a JSON format).
Here is a problem- I am unable to caught the return response of SMS gateway,so it causes the Response is showing on user/Web Page.
It is a problematic for user.
For calling SMS gateway I have used PHP Header function like:
header("Location:URL of SMS Gateway");
My Code as Bellow,
<?php
include("otherpages/connection.php");
if(isset($_POST['submit1'])) {
$mname=$_POST['mname'];
$cdate=$_POST['cdate'];
$maddress1=$_POST['maddress'];
$mschool=$_POST['mschool'];
$mkendra=$_POST['centrename'];
$mmobile=$_POST['mmobile'];
$user=$_POST['user'];
$pass=$_POST['pass'];
$approved="0";
$qr="insert into tempregistration values('','$cdate','$mname','$maddress1','$mschool','$mschool','$mkendra','$mmobile','$user','$pass','$approved')";
// Code for Registration SMS
$url = 'http://sms.hspsms.com/sendSMS?username=#USERNAME#&message=Dear User,You Have Succeffully Registered to ABC.com ,Thanks&sendername=HSPSMS&smstype=PROMO&numbers=9503808004&apikey=#APIKey#';
header("Location:$url");
?>
Please help me on same or guide where I am doing right or wrong?
Any help will be appreciable.

You're sending the user's browser to the API, what you want to do is have PHP make the request and then tell the user if it was successful or not.
You may be able to use get_file_contents, but curl will give you more control.
You should have a function that will send the request to the API and return a success/failure and then display a message to the user.
Something like this (untested):
if(isset($_POST['submit1'])) {
$mname=$_POST['mname'];
$cdate=$_POST['cdate'];
$maddress1=$_POST['maddress'];
$mschool=$_POST['mschool'];
$mkendra=$_POST['centrename'];
$mmobile=$_POST['mmobile'];
$user=$_POST['user'];
$pass=$_POST['pass'];
$approved="0";
$qr="insert into tempregistration values('',
'$cdate','$mname','$maddress1','$mschool',
'$mschool','$mkendra','$mmobile','$user','$pass','$approved')";
//update to encode parameters which contain spaces
$message = urlencode('Dear User, You have successfully registered ...');
// other parametes might also contain spaces ...
$username = urlencode('#USERNAME');
$sendername = urlencode('HSPSMS');
//etc
$url = 'http://sms.hspsms.com/sendSMS?username='.$username
.'&message='.$message
.'&sendername='.$sendername
.'&smstype=PROMO&numbers=9503808004&apikey=#APIKey#';
if ($result = do_api_call($url)){
echo "SMS API returned:<br>";
echo $result;//for debugging
}else {
echo "Failure"
}
}
...
function do_api_call($url){
//this is very simplistic code to get you going ...
//use curl instead for more control
return file_get_contents($url);
}

Related

PHP verify Paypal webhook signature

I'm having trouble trying to verify paypal webhook signatures with PHP. Using the new V2 of paypals APIs I am receiving the paypal webhook on my page.
However I can not seem to successfully validate the signature.
From the link HERE I got some sample webhook validation PHP code from paypal.
I can not get it working, I don't know where I am supposed to get bootstrap.php from in the paypal code. The paypal information seems incomplete or half baked. Paypal seems to be terrible to set-up compared to Stripe.
Has anyone got experience of validating paypal webhook signatures with PHP when using V2 of the paypal APIs ?
Well I have come to the conclusion that the Paypal developer information is rather poor, it is scatted all over the place, on multiple different pages and sites. The examples they give on the paypal developer website HERE are not a complete picture of what is required to validate a webhook signature. Stripe developer documentation is much better formatted and concise.
Installing Paypal Checkout V2 SDK does not give you the necessary development tools to validate paypal webhook signatures i.e. you can process payments and receive webhooks but you can not validate the webhook signatures....I know stupid. Tip do not download the SDK directly as you will not include the required autoload.php file. Use composer to install Paypal Checkout V2 SDK so that you get the autoload.php file.
Once you are to a point that you can process payments and receive webhooks form paypal you need to install the another SKD called Paypal Rest API SDK. Again use composer to install the SDK so that you get a autoload.php file which you will need.
When you install Paypal Rest API SDK amazingly you will still be missing files that are required to validate the payapl webhook signatures. I can find no mention of these anywhere on the paypal developer website.
bootstrap.php & common.php
Thanks to #Grumpy I got some samples provided on github HERE
Note you will probably need to modify the samples a bit in order to get them working with your website. Tip set the logger to false and save yourself some bother if you don't have the necessary access permissions to write.
Once you have bootstrap.php & common.php files created you can write the code for your webhook endpoint page i.e. the page that paypal sends the webhook to. I have included my PHP code below for how to validate and then process the paypal webhook. Tip in the below code you need to specify the webhook ID, each webhook that you create in paypal has a unique ID. Also when you are testing you can not use webhook simulator as this will fail validation, you can make manually a payment with your sandbox account details which will trigger a webhook payment event.
Paypal sure don't make it easy, their documentation is all over the place compared to Stripe. The Paypal webhooks can sometimes take several minutes to arrive after a payment is made, very frustrating when trying to debug. Also it's a bit ridiculous that they have a webhook simulator on the paypal developer website that can not be used to validate signatures...if stripe can do it why can't paypal.
<?php
//get the webhook payload
$requestBody = file_get_contents('php://input');
//check if webhook payload has data
if($requestBody) {
//request body is set
} else {
//request body is not set
exit();
}
use \PayPal\Api\VerifyWebhookSignature;
use \PayPal\Api\WebhookEvent;
$apiContext = require __DIR__ . '/bootstrap.php';
//Receive HTTP headers that you received from PayPal webhook.
$headers = getallheaders();
//need header keys to be UPPERCASE
$headers = array_change_key_case($headers, CASE_UPPER);
/*
example header paypal signature content for webhook, these values are recieved as an array, we then need to use this data to verify the payload
CONTENT-LENGTH : 1376
CORRELATION-ID : 6db85170269e7
USER-AGENT : PayPal/AUHD-214.0-54377828
CONTENT-TYPE: application/json
PAYPAL-AUTH-ALGO : SHA256withRSA
PAYPAL-CERT-URL : https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a784-5edc0ebc
PAYPAL-AUTH-VERSION : v2
PAYPAL-TRANSMISSION-SIG : Hc2lsDedYdSjOM4/t3T/ioAVQqFPNVB/AY/EyPNlavXk5WYUfnAmt9dyEP6neAPOjFHiVkXMK+JlLODbr6dalw6i26aFQdsPXqGl38Mafuu9elPE74qgsqNferUFgHi9QFXL+UZCNYcb4mvlDePXZIIAPbB0gOuFGOdEv2uqNwTCSAa/D8aguv1/51FWb3RkytFuVwXK/XNfIEy2oJCpDs8dgtYAZeojH8qO6IAwchdSpttMods5YfNBzT7oCoxO80hncVorBtjj1zQrkoynEB9WNNN9ytepNCkT8l29fQ4Sx/WRndm/PESCqxqmRoYJoiSosxYU3bZP7QTtILDykQ==
PAYPAL-TRANSMISSION-TIME : 2020-04-05T14:40:43Z
PAYPAL-TRANSMISSION-ID : 6dec99b0-774b-11ea-b306-c3ed128f0c4b
*/
//if any of the relevant paypal signature headers are not set exit()
if(
(!array_key_exists('PAYPAL-AUTH-ALGO', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-ID', $headers)) ||
(!array_key_exists('PAYPAL-CERT-URL', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-SIG', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-TIME', $headers))
)
{
exit();
}
//specify the ID for the webhook that you have set up on the paypal developer website, each web hook that you create has a unique ID
$webhookID = "ENTER_YOUR_WEBHOOK_ID_HERE";
//start paypal webhook signature validation
$signatureVerification = new VerifyWebhookSignature();
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setWebhookId($webhookID);
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);
$signatureVerification->setRequestBody($requestBody);
$request = clone $signatureVerification;
try {
$output = $signatureVerification->post($apiContext);
} catch (Exception $ex) {
//error during signature validation, capture error and exit
ResultPrinter::printError("Validate Received Webhook Event", "WebhookEvent", null, $request->toJSON(), $ex);
exit(1);
}
$sigVerificationResult = $output->getVerificationStatus();
// $sigVerificationResult is a string and will either be "SUCCESS" or "FAILURE"
//if not webhook signature failed validation exit
if($sigVerificationResult != "SUCCESS"){
exit();
}
else if($sigVerificationResult == "SUCCESS"){
//paypay webhook signature is valid
//proceed to process webhook payload
//decode raw request body
$requestBodyDecode = json_decode($requestBody);
//pull whatever info required from decoded request body, some examples below
$paymentSystemID = $requestBodyDecode->id;
$eventType = $requestBodyDecode->event_type;
//do something with info captured from the webhook payload
}
This seems to work with php 8.1:
if (openssl_verify(
data: implode(separator: '|', array: [
$httpPayPalTransmissionId,
$httpPayPalTransmissionTime,
$webhookID,
crc32(string: $rawRequestBody),
]),
signature: base64_decode(string: $httpPayPalTransmissionSignature),
public_key: openssl_pkey_get_public(public_key: file_get_contents(filename: $cachedHttpPayPalCertUrl)),
algorithm: 'sha256WithRSAEncryption'
) === 1) {
die('OK');
} else {
die('FAILED');
}

FB Messenger Bot: Webhook updates not being delivered

i am working with Facebook Checkbox Plugin everything is working fine except facebook is not sending request to my webhook url when Confirming Opt-in.
in facebook docs it is mentioned that
After the opt-in event, we will post a webhook event to your server if the checkbox state was checked. This callback has the same format as the opt-in callback, but instead of a sender field, it has an optin object with a user_ref field.
But it is not sending any data. here is my webhook code
if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] == 'subscribe' && $_REQUEST['hub_verify_token'] == 'verificationtoken') {
echo $_REQUEST['hub_challenge'];
}
$data = file_get_contents("php://input");
$fp = file_put_contents( PROTECH_FBB_DIR.'/data.log', $data);
i have also tried hitting my webhook manually and see if it responds. and it does work perfectly normal, so it means facebook is not posting data or maybe i am doing something wrong?
Any help would be highly appreciated. thanks
I am not php developer but have implemented the same logic in javascript, node.js. I would like to share the steps in detail and also the javascript code and hope you can figure out what you can do with it to make your life better :P
As you said, you are receiving the user_ref from the api call. That's correct. Read the documentation once again they have mentioned the user_ref will be received when user check the checkbox plugin. This user_ref is set by you and every-time the page loads this user_ref must be unique then only the checkbox plugin will render, if it is not unique the plugin wont render. And here is the complete logic behind it. You generate the user_ref, when user check the checkbox, you receive this unqiue user_ref, using this user_ref you send message to the user(you can send message to user using user_ref as many time as you want but I will suggest you rather use senderId). When you send the message to user using user_ref, the webhook api will give you a response containing senderId of the user which is actually psid we normally use in our app. This is what you need to save in your db.
Now I will put my code here how I did it.
Receiving the user_ref and sending message to user:
My payload:
function sendTextMessageRef(user_ref, messageText,md) {
var messageData = {
recipient: {
user_ref: user_ref
},
message: {
text: messageText,
metadata: md
}
};
callSendAPI(messageData);
}
function callSendAPI(messageData) {
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
Now, after sending the message, I receive a response in this json format which will include the sender id of the user:
{"sender":{"id":"xxxxxxx"},"recipient":{"id":"xxxxxWhat you are looking for is this*******"},"timestamp":1504698781373,"message":{"is_echo":true,"app_id":xxxxxxxxxxxxxxx,"metadata":"INVITATION__REPLY__qwe__2017-09-05T02xo20__xxxxxxxx__063__yes","mid":"mid.$cAAGcxxxxxxxxVxuAtJ","seq":120162,"text":":)"}}
In above received json data, the recipient.id is what you are looking for.
Here To make you understand what I did in my chat bot is first user select the checkbox plugin, I receive the call on my server, if check if it contains user_ref, if yes then I send a text message to user with a custom metadata using user_ref. When user receives the message, the webhook send me a json data in the above given format. To identify for which user_ref I have received this response, I set custom metadata which is combination of some string+user_ref. Using this I identify the sender.id of the user for which I previously sent message using user_ref. The sender.id is my pageid and recipient.id the the user id which you are trying to get and using which we generally send message to the user and is also know as psid.
Hope this helps, if you still get some issue using the above mentioned solution, then do update about it :)

Receiving multiple webhook notification for Facebook Feed

I am facing issue with Facebook Webhook for feed while messages are working perfectly. For one post i keep on getting multiple notification from Facebook. I have already raised a bug with Facebook and their team is saying that my server is failing to send back 200 OK HTTP status. Also in their doc i have found that
"Your webhook callback should always return a 200 OK HTTP response when invoked by Facebook. Failing to do so may cause your webhook to be unsubscribed by the Messenger Platform."
My code goes like this:
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'password')
{
echo $challenge;
}
/*........RECEIVING INPUT FROM fACEBOOK.........*/
$input = json_decode(file_get_contents('php://input') , true);
error_log(print_r($input, true));
/*after this i am calling AI and then replying back*/
Is there any way to send back 200 OK status before calling AI in php.
For the Workaround, I have stored the notification in DB and for every notification i am checking existing data (timestamp, senderId, post) in the DB to eliminate the duplicate post.
If anyone is having better option in terms of complexity please let us know.
I a similar issue and in my case I was subscribed to my test app and actual production app. Thus 2 events being sent

WhatsApp chat-api registration process error

I am using WhatsApp Chat-API.
For registration process I follow the documentation as provided at
Documentation.
So for registration process I use the below code
$username = "mynumber";
$debug = true;
$r = new Registration($username, $debug);
$r->codeRequest('sms');
Now till here I get the msg for verification but the problem is how I can use code received on phone as next line of code is as given below
$code = '123456';// this is hard coded in documentation how i can use my verification code which i received on my phone
$r->codeRegister($code);
So after getting verification code how I use the above code to get login password?
What I did was to comment out $r->codeRegister($code) during the first run. Then I wait for WhatsApp to send the code. When I get the code on my phone, I comment out $r->codeRequest('sms') and uncomment$r->codeRegister($code); replacing$code` with the code the WhatsApp API sent.
It's a hackneyed way of doing this but it works.
Ideally, you should get $code from STDIN which waits for the user to type it in.

Facebook Messenger Bot Webhook trouble

I'm trying to get the FB Messenger Bot API to work. I'm currently on the step where I'm trying to subscribe a webhook. I currently have a script of the following form:
#!/usr/bin/php
<?php
$challenge = $_REQUEST['hub_challenge'];
echo $challenge; # HERE!
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token') {
echo $challenge;
}
?>
However when I try to "Verify and Save" the callback URL I get an error of the form:
The URL couldn't be validated. Response does not match challenge, expected value = '401537941', received=''
namely that my script is sending an empty string. However, if I change the line marked "HERE!" above to "echo 'cat' ", the error message is the same except "received='cat'" as expected. Thus, my script is being executed and is trying to send some content back to FB, but for some reason the $challenge variable is empty. Why could this be the case?
Thanks!
if($_GET['hub_verify_token'] === "validation_token"){
echo($_GET["hub_challenge"]);
} else {
echo("error");
}
There are probably extra string in your response as you are not exiting after printing challenge. Try your script in browser and inspect html to see if there is anything extra.
Use the following code as you would need to seperate verification code from your work webhook calls. Also verify token is not something you create from Facebook, its your own keyword
/* validate verify token needed for setting up web hook */
if (isset($_GET['hub_verify_token'])) {
if ($_GET['hub_verify_token'] === 'YOUR_SECRET_TOKEN') {
echo $_GET['hub_challenge'];
return;
} else {
echo 'Invalid Verify Token';
return;
}
}
So in this case your verify token is YOUR_SECRET_TOKEN, now when you are setting up web hook, Type YOUR_SECRET_TOKEN in the verification token.
I wrote recently a step by step guide with screen shots here.

Categories