SMS Provider
The SMS gateways for VikAppointments can be extended by creating a PHP file containing the VikSmsApi
class.
The created file have to be placed via FTP in the directory:
/wp-content/plugins/vikappointments/admin/smsapi/
Follow the schema below to see the structure of the Class File:
<?php
// No direct access to this file
defined('ABSPATH') or die('No script kiddies please!');
class VikSmsApi
{
private $order_info;
private $params;
private $log = '';
public static function getAdminParameters()
{
return array();
}
public function __construct($order, $params = array())
{
$this->order_info = $order;
$this->params = $params;
}
public function sendMessage($phone_number, $msg_text)
{
/** See the code below to build this method */
return new stdClass;
}
public function estimate($phone_number, $msg_text)
{
/** See the code below to build this method */
return new stdClass;
}
public function validateResponse($response_obj)
{
/** See the code below to build this method */
return true;
}
public function getLog()
{
return $this->log;
}
}
The parameters form for the administrator can be built through the getAdminParameters() static method, to fill in private data required to the creation and validation of the payment, such as an API key or a secret password.
The parameters of the form are returned as an associative array with the following structure:
{
"param_1" : {
"label" : "Label 1",
"type" : "text"
},
"param_2" : {
"label" : "Label 2",
"type" : "select"
}
}
- param_1 is the key of the array and have to be unique (required).
It represents the name of the parameter to use. - label indicates the text to assign for the parameter in the administrator section (optional).
By placing a double slash (//) after the label, the next text will be displayed as a tip near the field of the parameter (e.g. "Sender//max 11 characters"). - type is used to render the right type of input in the administrator section (required).
The assumed value can be only one of the followings: custom, select, text, password. - html will be used only when the type of the parameter is custom (optional).
- options is an array containing all the possible values to use in the dropdown (required only when the type is select).
public static function getAdminParameters()
{
return array(
'apikey' => array(
'label' => 'API Key',
'type' => 'text',
),
'apisecret' => array(
'label' => 'API Secret',
'type' => 'password',
),
'sender' => array(
'label' => 'Sender Name//max 11 characters',
'type' => 'text',
),
'sandbox' => array(
'label' => 'Sandbox',
'type' => 'select',
'default' => 0,
'options' => array(
1 => 'Yes',
0 => 'No',
),
),
);
}
The code above will generate a parameters form in the administrator section as follows.
If your form doesn't come up, probably there is a syntax error on your file.
When you fill in the admin form, the parameters are stored in the $params property and you are able to get those values with the instructions below:
$api_key = $this->params['apikey']; /* returns "TS8KJSGV20E7SG2K" */
$api_secret = $this->params['apisecret']; /* returns "ks03bsoaqsdlew83hdswlsn2ie7d2hndmwq" */
$sender_name = $this->params['sender']; /* returns "e4j.com" */
$sandbox = $this->params['sandbox']; /* returns "0" */
The sendMessage($phone_number, $msg_text) method of the VikSmsApi class is invoked every time an order becomes CONFIRMED (e.g. after a payment). Here you have to post the details of your account, the phone number of the customer and the message to send through the gateway of your provider. Generally you need to post these fields via cURL to a certain end-point provided from your gateway.
The sendMessage function requires 2 arguments:
- $phone_number - (string) the phone number of the customer. This value have to be validate before to send the message, because it could not contain the prefix or could contain unrecognized characters (like @ or / and so on)
- $msg_text - (string) the full text to send to the customer. A lot of providers allow to send only 160 characters per message, so you should consider this limitation.
The code below is only an example how it should work a cURL connection to the gateway of the provider.
public function sendMessage($phone_number, $msg_text)
{
$phone_number = $this->sanitizePhoneNumber($phone_number);
$request = array(
"apikey" => $this->params['apikey'],
"apisecret" => $this->params['apisecret'],
"from" => $this->params['sender'],
"to" => $phone_number,
"msg" => $msg_text,
"sandbox" => (int) $this->params['sandbox'],
);
$json = json_encode($request);
$curl_opts = array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Content-Type: application/json;charset=UTF-8',
'Content-Length: ' . strlen($json),
),
CURLOPT_VERBOSE => true,
);
$ch = curl_init('https://secure.sms.fakeprovider.com/send');
curl_setopt_array($ch, $curl_opts);
$response = curl_exec($ch);
return json_decode($response);
}
The sanitizePhoneNumber function used above is not a native function of the VikSmsApi class, so you have to write this method on your code.
Here you can find a simple code to sanitize a phone number.
protected function sanitizePhoneNumber($phone_number)
{
$str = '';
for ($i = 0; $i < strlen($phone_number); $i++)
{
if (($phone_number[$i] >= '0' && $phone_number[$i] <= '9') || $phone_number[$i] == '+')
{
$str .= $phone_number[$i]; // copy only numbers and plus character
}
}
$default_prefix = '+1'; // US, Canada phone prefix
if ($phone_number[0] != '+')
{
// $phone_number doesn't contain the phone prefix
$str = $default_prefix . $str;
}
return $str;
}
The validateResponse($response_obj) method is used to validate the object returned from the gateway during the sending of the message. Some gateways return an object containing a short error message and the http status code.
{
"httpcode" : 200,
"errmsg" : "",
}
{
"httpcode" : 401,
"errmsg" : "BAD_CREDENTIALS",
}
{
"httpcode" : 402,
"errmsg" : "BAD_CREDIT",
}
While, sometimes, the object returned is a simple boolean value (true/false).
In this method you have to return only a boolean value to communicate to the program the status of the message. With TRUE status, nothing will be notified, otherwise an error e-mail will be sent to the administrator containing the text in the $log attribute.
public function validateResponse($response_obj)
{
if ($response_obj->httpcode == 200)
{
return true;
}
$this->log .= $response_obj->errmsg;
return false;
}
The estimate($phone_number, $msg_text) is an optional method used to retrieve the remaining credit from the back-end of the program. A lot of providers don't have an API call to retrieve the credit of a certain account, so you can decide to skip this method.
$phone_number and $msg_text are only used as example from the gateway.
The returned value from this function have to be an object containing the errCode and userCredit attributes:
{
"errCode" : 0, // no error
"userCredit" : 85.47, // in decimals
}
Generally the estimate function is similar to the sendMessage function, but it makes a call to a different gateway of the provider.
public function estimate($phone_number, $msg_text)
{
$phone_number = $this->sanitizePhoneNumber($phone_number);
$request = array(
"apikey" => $this->params['apikey'],
"apisecret" => $this->params['apisecret'],
"from" => $this->params['sender'],
"to" => $phone_number,
"msg" => $msg_text,
"sandbox" => (int) $this->params['sandbox'],
);
$json = json_encode($request);
$curl_opts = array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Content-Type: application/json;charset=UTF-8',
'Content-Length: ' . strlen($json),
),
CURLOPT_VERBOSE => true,
);
$ch = curl_init('https://secure.sms.fakeprovider.com/estimate');
curl_setopt_array($ch, $curl_opts);
$response = curl_exec($ch);
$response = json_decode($response);
$fixedResponse = new stdClass;
$fixedResponse->errCode = $response->httpcode;
$fixedResponse->userCredit = 0.0;
if ($fixedResponse->errCode == 200)
{
$fixedResponse->errCode = 0;
$fixedResponse->userCredit = $response->credit;
}
return $fixedResponse;
}
The code above will generate automatically a button in the configuration of the program to estimate the remaining credit.
You can get HERE the complete code of this example gateway.