private prepaid subscriptions · web viewthis php script is called every-time for all pages by the...

84
[1'e99'1 subscriptions] PRIVATE PREPAID SUBSCRIPTION INTERFACE AND SURVEY SCRIPT Document created on 2014-11-24 Nicolas Bondier Contents Introduction.............................................................. Web interface............................................................. Files of web interface folder main elements.............................. All sources.............................................................. Initialization scripts................................................... Login page............................................................... Backend................................................................... Customer class........................................................... Account class............................................................ Prepaid subscription survey............................................... Introduction This document describes the prepaid subscription web interface and the scripts used to manage prepaid private subscriptions. Page 1/84

Upload: others

Post on 10-Dec-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

[1'e99'1 subscriptions]

PRIVATE PREPAID SUBSCRIPTION INTERFACE AND SURVEY SCRIPT

Document created on 2014-11-24Nicolas Bondier

ContentsIntroduction...........................................................................................................................................................

Web interface........................................................................................................................................................

Files of web interface folder main elements.......................................................................................................

All sources...........................................................................................................................................................

Initialization scripts.............................................................................................................................................

Login page...........................................................................................................................................................

Backend.................................................................................................................................................................

Customer class....................................................................................................................................................

Account class......................................................................................................................................................

Prepaid subscription survey...................................................................................................................................

IntroductionThis document describes the prepaid subscription web interface and the scripts used to manage prepaid private subscriptions.

Web interfaceThe customer web interface is composed of views called by Ajax. The common ones that we retrieve in each page are located in the common folder. The other views are in the views folder and the pages that only accomplish an action when called are in the action folder.

We will not describe each of these elements.

Page 1/67

Page 2: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

Here are some captures of the web interface.

Page 2/67

Page 3: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

Files of web interface folder main elements

.├── actions/│   ├── buy_device_with_balance.php│   ├── buy_device_with_checkout.php│   ├── check_active_customer.php│   ├── save_payment_method.php│   ├── updateCustomer.php│   ├── update_json_customer.php│   └── update_subscription_plan.php

Page 3/67

Page 4: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

├── classes/│   ├── Account.php│   └── Customer.php├── common/│   ├── check_auth.php│   ├── footer.php│   ├── header.php│   └── updateCustomer.php├── config/│   └── index.html├── css/│   ├── app.min.css│   ├── common.css│   ├── grids-responsive-min.css│   ├── grids-responsive-old-ie-min.css│   ├── mobile.css│   ├── pure-min.css│   └── toggle-switch.css├── end_private_area.php├── etc/│   ├── Devices.php│   ├── index.html│   ├── OtherPrices.php│   ├── shop/│   └── SubscriptionPlans.php├── img/│   ├── logo-switzernet-com.png│   ├── switzernet-logo.png│   ├── triangle-bas.png│   ├── triangle-droite.png│   ├── triangle-gauche.png│   └── triangle-haut.png├── index.php├── init_common.php├── init_private_area.php├── init_public_area.php├── js/│   ├── isotope-layouts/│   ├── isotope.pkgd.min.js│   ├── jquery-1.11.1.min.js│   ├── jquery.color-2.1.2.min.js│   ├── jquery.dropdown.css│   ├── jquery.dropdown.js│   ├── maintainscroll.jquery.min.js│   ├── masonry.pkgd.min.js│   ├── master│   ├── nav.js│   ├── scripts.js│   └── yui-min.js

Page 4/67

Page 5: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

├── languages/│   ├── db/│   ├── languages.php│   └── manage.php├── login/│   ├── css/│   ├── index.php│   └── js/├── logout.php└── views/ ├── index.html ├── main_view.php ├── nav-menu.php ├── view_billing.php ├── view_change_subscription_plan.php ├── view_choose_new_subscription_plan.php ├── view_dynamic.php ├── view_general.php ├── view_prepaid_account_id.php ├── view_prepaid_accounts.php ├── view_prepaid_subscription_plan.php ├── view_select_automatic_payment_method.php ├── view_set_automatic_payment_method.php ├── view_shop_device_details.php ├── view_shop_order.php ├── view_shop.php ├── view_shop_selected_device.php └── view_toggle_automatic_renewal.php

All sources

Initialization scriptsThe customer logins and logouts a well as customer data is managed globally.

[.htaccess]

php_value auto_prepend_file "/absolute/path/to/current/directory/init_private_area.php"php_value auto_append_file "/absolute/path/to/current/directory/end_private_area.php"Options -Indexes

Page 5/67

Page 6: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

[init_common.php]

This PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global variables if not defined and includes the language files, the classes to be used and other scripts with important variables such as the prices per currencies.

Note that we define an ‘AppId’ constant in order to save the session variable without overwriting other variables the user could have in session.

<?php

if(session_id() == '') { session_start(); }

define('AppId', 'xxxxxxxxxxxxxxxxxx'); define('ServerURL', '/absolute/path/to/current/directory'); define('RootDir', $_SERVER['DOCUMENT_ROOT'].'/path/to/current/directory/relative/to/apache/document/root');

if ( ! isset($_SESSION[AppId] ) ){ $_SESSION[AppId] = array(); $_SESSION[AppId]['AUTHENTICATED'] = FALSE; }

include_once 'languages/languages.php';

require_once dirname(__FILE__) . "/" . "classes/Customer.php"; require_once dirname(__FILE__) . "/" . "classes/Account.php";

require_once dirname(__FILE__) . "/" . "etc/SubscriptionPlans.php"; require_once dirname(__FILE__) . "/" . "etc/OtherPrices.php";

?>

[init_private_area.php]

Following the .htaccess file directives, this file is called for each pages. It also calls the init_common.php page.

<?php

require_once dirname(__FILE__) . "/" . 'init_common.php';

Page 6/67

Page 7: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

Then we check if we received an external authentication. From the billing for example.

if ( isset( $_GET['i_customer'] ) && preg_match('/^[0-9]+$/', $_GET['i_customer'] ) ){ $AUTH_KEY = ''; $ALLOWED_GET_PARAMS = array( 'i_customer' => true, ); $GET_PARAMS = $_GET; $URL_PARAMS = ''; $SHA1_KEY = ''; foreach ($ALLOWED_GET_PARAMS as $key => $value) { if ( $value && isset( $GET_PARAMS[$key] ) ){ $SHA1_KEY .= urlencode($key."=".$GET_PARAMS[$key]).$AUTH_KEY; $URL_PARAMS .= urlencode($key)."=".urlencode($value)."&"; } } $SHA1_KEY = preg_replace('/\+/', '%20', $SHA1_KEY); $SHA1_KEY = sha1($SHA1_KEY); if ( $SHA1_KEY != $_GET['AUTH_KEY'] ){ echo "You are not authenticated !\n"; exit; } else { $Customer = new Customer; $Customer->set_customer( $_GET['i_customer'] ); $Customer->load_customer_info(); $_SESSION[AppId]['Customer'] = serialize($Customer); $_SESSION[AppId]['show_prepaid_account_id'] = ''; $_SESSION[AppId]['AUTHENTICATED'] = TRUE; $uri_parts = explode('?', $_SERVER['REQUEST_URI'], 2); header( "Location: http://".$_SERVER['HTTP_HOST']. $uri_parts[0] ); exit; } }

We check if the user has been authenticated before. If not, we redirect the browser to the login page.

if ( !isset( $_SESSION[AppId]['AUTHENTICATED'] ) || $_SESSION[AppId]['AUTHENTICATED'] !== TRUE ){ echo ' You are not logged in. Go to login page <a href="' . ServerURL . '/login">[link]</a> <script type="text/javascript"> window.location="' . ServerURL . '/login"; </script>';

Page 7/67

Page 8: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

exit; }

If we are logged, we check in the session variables if the customer was saved and load it in the session

if ( isset( $_SESSION[AppId]['Customer'] ) ){ $Customer = unserialize( $_SESSION[AppId]['Customer'] ); } if ( isset( $_SESSION[AppId]['DisplayedAccount'] ) && isset( $_SESSION[AppId]['show_prepaid_account_id'] ) ){ $Account = unserialize( $_SESSION[AppId]['DisplayedAccount'] ); }?>

[init_public_area.php]

This file is called when the browser call a page from the login subdirectory and is not yet logged. If the user is authenticated, he is redirected to the main web interface page.

<?php require_once dirname(__FILE__) . "/" . 'init_common.php';

if ( isset( $_SESSION[AppId]['AUTHENTICATED'] ) && $_SESSION[AppId]['AUTHENTICATED'] === TRUE ){ header( "Location: ".ServerURL ); }?>

[logout.php]

This page is called when the user has logged out. It remove the session variables and reload the page.

<?phpinclude_once dirname(__FILE__) . "/" . 'init_common.php';

if ( isset( $_SESSION[AppId]['AUTHENTICATED'] ) && $_SESSION[AppId]['AUTHENTICATED'] === TRUE ){ session_destroy(); header( "Location: ".ServerURL );

Page 8/67

Page 9: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

exit;}?>

[login/.htaccess]

This is the .htaccess file of the login subfolder. It loads the init_public_area.php file for checking if the user is logged in and eventually redirecting to the main web interface.

php_value auto_prepend_file "/absolute/path/to/current/directory/init_public_area.php"php_value auto_append_file none

[end_private_area.php]

This page is called at the end of all scripts. It saves the customer and last viewed account objects in the session.

<?phpif ( isset($Customer) ){ $_SESSION[AppId]['Customer'] = serialize($Customer);}

if ( isset($Account) ){ $_SESSION[AppId]['DisplayedAccount'] = serialize($Account);}?>

Login page

[login/index.php]

This is the login page. Here we request the user to enter its username and password. If we receive a post we try to authenticate the user, load the information and redirect him to the main web interface if the authentication was successful.

Page 9/67

Page 10: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

Here is the code:

[index.php]

<?phpif(session_id() == '') { session_start();}$error=''; // Variable To Store Error Messageif (isset($_POST['submit'])) { if (empty($_POST['username']) || empty($_POST['password'])) { $error = "Username or Password is invalid"; } else { $username=$_POST['username'];

Page 10/67

Page 11: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$password=$_POST['password']; $Customer = new Customer; $auth_response = FALSE; $auth_response = $Customer->authenticate( $username, $password ); if ( $auth_response == TRUE ){ $Customer->load_customer_info(); $_SESSION[AppId]['Customer'] = serialize($Customer); $_SESSION[AppId]['show_prepaid_account_id'] = ''; $_SESSION[AppId]['AUTHENTICATED'] = TRUE; header( "Location: http://".$_SERVER['HTTP_HOST']."/".$_SERVER['REQUEST_URI'] ); exit; } else { $error = l("Username or Password is invalid"); } }}?><!DOCTYPE html><html lang="en" class="ng-scope"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title class="ng-binding">Switzernet</title> <link rel="stylesheet" media="screen,projection" href="../css/pure-min.css"> <link rel="stylesheet" media="screen,projection" href="css/login.css"> <script src="../js/jquery-1.11.1.min.js"></script> <link rel="shortcut icon" href="images/favicon.ico"> </head> <body> <div id="container"> <div id="logo_header"> <a> <img id="logo" src="../img/switzernet-logo.png" alt="Switzernet"> </a> </div> <div class="page"> <div id="login_form"> <?php if ( $error != '' ){ echo "<span style='color:red'>".$error."</span>"; } ?>

Page 11/67

Page 12: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

<form class="pure-form pure-form-aligned" action="" method="post"> <fieldset> <div class="pure-control-group"> <label for="name"><?= l("Username") ?></label> <input id="name" name="username" type="text" placeholder="Username" required> </div> <div class="pure-control-group"> <label for="password"><?= l("Password") ?></label> <input id="password" name="password" type="password" placeholder="Password" required> </div> <div class="pure-controls"> <input name="submit" type="submit" value="Connect" class="pure-button pure-button-primary"/> </div> </fieldset> </form> </div> </div> </div> </body></html>

BackendThe following scripts are used to get information about customer and account and modify them.

Customer class[classes/Customer.php]

Code Comment<?php

/*** */

class Customer{ public $customer_info; public $update_flag; public $porta_billing_customer = FALSE;

Declaring public properties.

Page 12/67

Page 13: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

public $web_subscription = FALSE;

private $LocalMysqli; private $MasterMysqli; private $ServiceCustomer; private $ServiceAccount; private $SOAP_session_id = '';

Declaring private properties.

function __construct() { $this->web_db_connect(); $this->master_db_connect(); $this->soap_connect(); }

function __destruct(){ $this->LocalMysqli->close(); $this->MasterMysqli->close(); } function __wakeup(){ $this->soap_connect(); $this->web_db_connect(); $this->master_db_connect(); }

Constructors and destructors. They are called when the class is loaded or closed or serialized.

public function load_customer_info( $check_update = FALSE ){

This function is used to load customer information. We privileged MySQL for such queries as is faster than SOAP.

If the $check_update variable is set to true, the function will set a global $update_flag to true. This is needed if we want to continuously check if updates are available in

Page 13/67

Page 14: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

the web interface.

$old_customer_info = $this->customer_info;In order to tell if info has been updated we first get the current customer info.

if ( $this->porta_billing_customer === FALSE && $this->web_subscription === TRUE ){ $sql = "SELECT active_in_porta_billing, pb_i_customer FROM Web_Subscriptions WHERE i_web_subscription = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "i", $this->customer_info['i_web_subscription'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); if ( $res['active_in_porta_billing'] == 1 ){ $sql = "SELECT IF(COUNT(*) > 0, 'true', 'false') as found FROM Customers WHERE i_customer = ?"; $stmt = $this->MasterMysqli->prepare($sql); $state = $stmt->bind_param( "i", $res['i_customer'] ); $res2=array(); $this->stmt_bind_assoc($stmt, $res2); $stmt->fetch(); $stmt->close(); if ( $res2['found'] == 'true' ){ $this->porta_billing_customer = TRUE; $this->load_customer_info(); } else { $sql = "UPDATE Web_Subscriptions SET active_in_porta_billing = 0, pb_i_customer = NULL WHERE i_web_subscription = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "ii", $amount, $this->customer_info['i_web_subscription'] ); $stmt->execute(); $stmt->close(); } } }

If the customer is marked as not yet in the porta-billing, we check if it is still true.

In this case we update the web subscription database and set the porta_billing_customer flag to ‘true’ in order to process as a portabilling customer.

if ( $this->porta_billing_customer ){ $sql = "SELECT c.*, a.id, a.i_account FROM Customers c INNER JOIN Accounts a ON a.i_customer=c.i_customer WHERE c.i_customer = ? AND

If the customer is in the porta-billing database, we select all its

Page 14/67

Page 15: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

a.bill_status = 'O'"; $stmt = $this->MasterMysqli->prepare($sql); $state = $stmt->bind_param( "i", $this->customer_info['i_customer'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); if ( $res['i_customer'] > 0 ){ foreach ($res as $key => $value) { $this->customer_info[$key] = $value; } } else { return FALSE; }

data.

$this->customer_info['Active'] = TRUE; $this->customer_info['Email'] = $this->customer_info['email']; $this->customer_info['Firstname'] = $this->customer_info['firstname']; $this->customer_info['Lastname'] = $this->customer_info['lastname']; $this->customer_info['Address'] = ''; foreach (array( 'baddr1', 'baddr2', 'baddr3', 'baddr4', 'baddr5' ) as $value) { $this->customer_info['Address'] .= $this->customer_info[$value]; } $this->customer_info['NPA'] = $this->customer_info['zip']; $this->customer_info['City'] = $this->customer_info['city']; $this->customer_info['Country'] = $this->customer_info['country']; $this->customer_info['Balance'] = number_format($this->customer_info['balance'],2); $this->customer_info['Currency'] = $this->customer_info['iso_4217']; $this->customer_info['WebLogin'] = $this->customer_info['login']; $this->customer_info['Company'] = $this->customer_info['companyname']; $this->customer_info['WebPassword'] = $this->customer_info['password']; $this->customer_info['CreditLimit'] = $this->customer_info['credit_limit'];

And we also set the values used by the web interface.

$this->get_payment_method(); Getting the payment

Page 15/67

Page 16: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

method.

} elseif ( $this->web_subscription === TRUE ) {

$sql = "SELECT * FROM Web_Subscriptions WHERE i_web_subscription = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "i", $this->customer_info['i_web_subscription'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); if ( $res['i_web_subscription'] > 0 ){ //print_r($res); $this->customer_info = $res; } else { return FALSE; } $this->customer_info['Active'] = FALSE;

// Map the subscription with the class variables

$this->customer_info['AutomaticPaymentMethod'] = ''; $this->customer_info['AutomaticPaymentStatus'] = ''; $this->customer_info['WebLogin'] = $this->customer_info['web_login']; $this->customer_info['Balance'] = $this->customer_info['Total_order']; $this->customer_info['Company'] = $this->customer_info['Company_Name']; $this->customer_info['WebPassword'] = $this->customer_info['web_password']; $this->customer_info['CreditLimit'] = 0; }

In case it is a web subscription, we get the data from the database and set the values used by the web interface.

$this->customer_info['AvailableFunds'] = max( ( $this->customer_info['CreditLimit'] - $this->customer_info['Balance'] ), 0 ); $this->customer_info['AvailableFunds'] = ( $this->customer_info['CreditLimit'] - $this->customer_info['Balance'] );

We calculate the available funds of the customer.

$this->get_customer_prepaid_accounts();Get the list of accounts. This is for verifying if it changed in the database since the last update.If the

Page 16/67

Page 17: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$new_customer_info = $this->customer_info; if ( $check_update == TRUE && $new_customer_info != $old_customer_info ){ $this->update_flag = TRUE; } else { $this->update_flag = FALSE; } $sql = "SELECT NOW() as CurrentTime"; $stmt = $this->MasterMysqli->prepare($sql); $stmt->execute(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); $Customer->customer_info['CurrentTime'] = $res['CurrentTime']; //print_r($this); return TRUE;

$check_update variable is true, with check the customer has been update since the last update.

}Ending of the load_customer_info() function.

public function authenticate( $user, $password ){ //print_r($this); $sql = "SELECT i_customer FROM Customers WHERE login = ? AND password = ?"; //echo $sql; $stmt = $this->MasterMysqli->prepare($sql); /* Prepared statement, stage 1: prepare */ $state = $stmt->bind_param( "ss", $user, $password ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close();

//print_r($res);

if ( $res['i_customer'] > 0 ){ $this->customer_info['i_customer'] = $res['i_customer']; $this->porta_billing_customer = TRUE; return TRUE; } else { $sql = "SELECT i_web_subscription FROM Web_Subscriptions WHERE web_login = ? AND web_password = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "ss", $user, $password ); $stmt->execute(); $res2=array(); $this->stmt_bind_assoc($stmt, $res2); $stmt->fetch(); $stmt->close();

This function authenticate the customer with its username and password.It first check in the billing database the username and password pair exists, else it checks in the web subscriptions database.

Page 17/67

Page 18: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

if ( $res2['i_web_subscription'] > 0 ){ $this->customer_info['i_web_subscription'] = $res2['i_web_subscription']; $this->web_subscription = TRUE; return TRUE; } } return FALSE; }

public function set_customer ($i_customer){ //print_r($this); $sql = "SELECT i_customer FROM Customers WHERE i_customer = ?"; //echo $sql; $stmt = $this->MasterMysqli->prepare($sql); /* Prepared statement, stage 1: prepare */ $state = $stmt->bind_param( "i", $i_customer ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); if ( $res['i_customer'] > 0 ){ $this->customer_info['i_customer'] = $res['i_customer']; $this->porta_billing_customer = TRUE; return TRUE; } return FALSE; }

This function is used to set the i_customer of the current object if it exists.

public function charge( $amount, $visible_comment = 'order', $internal_comment = 'prepaid interface order' ){

$MakeCustomerTransactionRequest = array( 'i_customer' => $this->customer_info['i_customer'], 'visible_comment' => $visible_comment, 'internal_comment' => $internal_comment, 'action' => 'Manual charge', 'amount' => $amount, 'suppress_notification' => 0, ); try { $MakeCustomerTransactionResponse = $this->ServiceCustomer->make_transaction($MakeCustomerTransactionRequest); $this->load_customer_info(); return true; } catch (SoapFault $fault) { throw new Customer_Exception("Soap error :".$fault); return false;

This function is used to charge the balance of the customer.

Page 18/67

Page 19: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

} }

public function update_payment_method( $payment_method_data ){

This function save the payment method to the porta-billing.

$pm = $payment_method_data['AutomaticPaymentMethod'];

$return = array( 'status' => NULL, 'message' => NULL );

if ( $pm != 'VISA' && $pm != 'MasterCard' && $pm != 'PayPal' && $pm != '' ){ $return = array( 'status' => 'error', 'message' => l('Wrong payment method'),

); return $return; }

Validating the available payment methods.

if ( $pm == 'VISA' || $pm == 'MasterCard' ){

if ( ! isset( $payment_method_data['card_owner'] ) || $payment_method_data['card_owner'] == '' ){ $return = array( 'status' => 'error', 'message' => l('Card owner is missing'), ); return $return; }

if ( ! isset( $payment_method_data['card_number'] ) || $payment_method_data['card_number'] == '' ){ $return = array( 'status' => 'error', 'message' => ('Card number is missing'), ); return $return; }

if ( ! isset( $payment_method_data['cvv'] ) || $payment_method_data['cvv'] == '' ){ $return = array( 'status' => 'error', 'message' => l('Card cvv is missing'), );

First we check all necessary fields is this is a credit card.

Page 19/67

Page 20: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

return $return; }

if ( ! isset( $payment_method_data['card_month'] ) || $payment_method_data['card_month'] == '' ){ $return = array( 'status' => 'error', 'message' => l('Card month is missing'), ); return $return; }

if ( ! isset( $payment_method_data['card_year'] ) || $payment_method_data['card_year'] == '' ){ $return = array( 'status' => 'error', 'message' => l('Card year is missing'), ); return $return; }

if ( preg_match( '/[0-9]{2}/', $payment_method_data['card_month'] ) && ( $payment_method_data['card_month'] > 12 || $payment_method_data['card_month'] < 1) ){ $return = array( 'status' => 'error', 'message' => l('Wrong card expiration date'), ); return $return; }

if ( preg_match( '/[0-9]{4}/', $payment_method_data['card_year'] ) && ( $payment_method_data['card_year'] < date('Y') ) && ( $payment_method_data['card_month] < date('m') ) ){ $return = array( 'status' => 'error', 'message' => l('Card expiration date is in the past'), ); return $return; }

$expiration_date = '0000-00-00'; $expiration_date = $payment_method_data['card_year'] . '-' . $payment_method_data['card_month'] . '-' . '01';

if ( isset($this->customer_info['zip']) && $this->customer_info['zip'] != '' ){ $payment_method_data['zip'] = $this-

Setting default card values for other fields.

Page 20/67

Page 21: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

>customer_info['zip']; } else { $payment_method_data['city'] = 'none'; }

if ( isset($this->customer_info['city']) && $this->customer_info['city'] != '' ){ $payment_method_data['city'] = $this->customer_info['city']; } else { $payment_method_data['city'] = 'none'; }

if ( isset($this->customer_info['address']) && $this->customer_info['address'] != '' ){ $payment_method_data['address'] = $this->customer_info['address']; } else { $payment_method_data['address'] = 'none'; }

$PaymentMethodInfo = array( 'payment_method' => $pm, 'name' => $payment_method_data['card_owner'], 'address' => '', 'zip' => $payment_method_data['zip'], 'city' => $payment_method_data['city'], 'number' => $payment_method_data['card_number'], 'cvv' => $payment_method_data['cvv'], 'exp_date' => $expiration_date, 'address' => $payment_method_data['cvv'] );

try { $UpdateCustomerPaymentMethodRequest = $this->ServiceCustomer->update_payment_method( array( 'i_customer' => $this->customer_info['i_customer'], 'payment_method_info' => $PaymentMethodInfo, ) ); $this->load_customer_info(); return true; } catch (SoapFault $fault) { throw new Customer_Exception("Soap error :".$fault); return false; }

And finaly we save the data whith SOAP XML API.

Page 21/67

Page 22: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

} elseif ( $pm == 'PayPal' ) {

$PaymentMethodInfo = array( 'payment_method' => 'PayPal' );

try { $UpdateCustomerPaymentMethodRequest = $this->ServiceCustomer->update_payment_method( array( 'i_customer' => $this->customer_info['i_customer'], 'payment_method_info' => $PaymentMethodInfo, ) ); $this->load_customer_info(); return true; } catch (SoapFault $fault) { throw new Customer_Exception("Soap error :".$fault); return false; }

If new payment method is PayPal we only update the master database with SOAP.

} else {

$PaymentMethodInfo = array( 'payment_method' => NULL ); try { $UpdateCustomerPaymentMethodRequest = $this->ServiceCustomer->update_payment_method( array( 'i_customer' => $this->customer_info['i_customer'], 'payment_method_info' => $PaymentMethodInfo, ) ); $this->load_customer_info(); $this->remove_all_accounts_renewal_options(); return true; } catch (SoapFault $fault) { throw new Customer_Exception("Soap error :".$fault); return false; } } }

Finally, if the customer did not choose any of the payment method, we delete all renewal options of the accounts.

private function remove_all_accounts_renewal_options(){

The function used for

Page 22/67

Page 23: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

file_put_contents('/tmp/AccountsList.txt', print_r( $this->customer_info['AccountsList'] , true ) ); foreach ( $this->customer_info['AccountsList'] as $i_account => $number) { try { $CustomFieldsValuesInfo = array( 'name' => 'Auto renewal subscription plan', //'db_value' => $i_subscription_plan, 'text_value' => 'no' ); $custom_fields_values = array(); array_push($custom_fields_values, $CustomFieldsValuesInfo);

$UpdateAccountCustomFieldsValuesRequest = array( 'i_account' => $i_account, 'custom_fields_values' => $custom_fields_values ); $UpdateAccountCustomFieldsValuesResponse = $this->ServiceAccount->update_custom_fields_values($UpdateAccountCustomFieldsValuesRequest); } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } } return true; }

removing all renewal options of all account. Generally this is when the customer does not have payment method. The values are in the custom fields values of the database.

private function get_payment_method(){ if ( $this->customer_info['i_credit_card'] != NULL && $this->customer_info['i_credit_card'] > 0 ){ $cols = array(); $cols_array = array();

$sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'Credit_Cards'"; if (!($stmt = $this->MasterMysqli->prepare($sql))) { echo "Echec de la préparation : (" . $MasterMysqli->errno . ") " . $MasterMysqli->error; } $stmt->execute(); $this->stmt_bind_assoc($stmt, $res); while ( $stmt->fetch() ) { array_push($cols_array, $res['COLUMN_NAME']); } $stmt->close();

$cols_string = implode($cols_array,"`,`");

Here we get the information about the payment method of the user.

In order to limit credit card transfer, we check if we have the same data has in billing data-base.

Page 23/67

Page 24: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$sql = "SELECT SHA1(CONCAT_WS(`".$cols_string."`)) as credit_card_hash FROM Credit_Cards WHERE i_credit_card = ?"; //echo $sql; if (!($stmt = $this->MasterMysqli->prepare($sql))) { echo "Echec de la préparation : (" . $MasterMysqli->errno . ") " . $MasterMysqli->error; } $stmt->bind_param( "i", $this->customer_info['i_credit_card'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch();

if ( !isset( $this->customer_info['AutomaticPaymentMethod'] ) ) $this->customer_info['AutomaticPaymentMethod'] = ''; if ( !isset( $this->customer_info['AutomaticPaymentCustomNumber'] ) ) $this->customer_info['AutomaticPaymentCustomNumber'] = ''; if ( !isset( $this->customer_info['AutomaticPaymentStatus'] ) ) $this->customer_info['AutomaticPaymentStatus'] = '';

if ( !isset( $this->customer_info['credit_card_hash'] ) || $this->customer_info['credit_card_hash'] != $res['credit_card_hash'] ){

$this->customer_info['credit_card_hash'] = $res['credit_card_hash']; $GetCustomerPaymentMethodInfoRequest = array( 'i_customer' => $this->customer_info['i_customer'] ); $GetCustomerPaymentMethodInfoResponse = $this->ServiceCustomer->get_payment_method_info($GetCustomerPaymentMethodInfoRequest); error_log(print_r($GetCustomerPaymentMethodInfoResponse->payment_method_info, true));

if ( isset( $this->customer_info['AutomaticPaymentCustomNumber'] ) ){ $this->customer_info['AutomaticPaymentCustomNumber'] = $GetCustomerPaymentMethodInfoResponse->payment_method_info->number; } else { $this-

If this is the case, we get the credit card number and the payment method.

Page 24/67

Page 25: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

>customer_info['AutomaticPaymentCustomNumber'] = ''; } if ( isset( $this->customer_info['AutomaticPaymentMethod'] ) ){ $this->customer_info['AutomaticPaymentMethod'] = $GetCustomerPaymentMethodInfoResponse->payment_method_info->payment_method; } else { $this->customer_info['AutomaticPaymentMethod'] = ''; } $this->customer_info['AutomaticPaymentStatus'] = ''; }

if ( $this->customer_info['AutomaticPaymentMethod'] == 'PayPal' ){ $sql = "SELECT * FROM CustomerPayPalPreapprovedPayments WHERE i_customer = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "i", $this->customer_info['i_customer'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); if ( $res['i_customer'] > 0 ){ $this->customer_info['AutomaticPaymentCustomNumber'] = $res['senderEmail']; if ( $res['approved'] == 1 ){ $this->customer_info['AutomaticPaymentStatus'] = 'approved'; } else { $this->customer_info['AutomaticPaymentStatus'] = 'pending'; } } else { $this->customer_info['AutomaticPaymentStatus'] = 'unknown'; } } } }

If this is PayPal, we must also verify the status of the authorization in order to display to the customer.

public function get_customer_prepaid_accounts(){

$accounts = array();

if ( $this->porta_billing_customer ){ $sql = 'SELECT a.i_account, a.id as ID FROM Accounts a INNER JOIN Products p ON a.i_product = p.i_product WHERE a.i_customer = ? AND a.bill_status = "O" and p.name like "%prepaid%" ';

This function return the list of prepaid accounts the customer has or the list of ordered accounts if the

Page 25/67

Page 26: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

if (!($stmt = $this->MasterMysqli->prepare($sql))) { echo "Echec de la préparation : (" . $MasterMysqli->errno . ") " . $LocalMysqli->error; } $state = $stmt->bind_param( "i", $this->customer_info['i_customer'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); while ( $stmt->fetch() ) { $accounts[$res['i_account']] = $res['ID']; } $this->customer_info['AccountsList'] = $accounts; return $accounts; } else { $sql = "SELECT i_web_subscription_reserved_number, h323_id as ID FROM Web_Subscription_Selected_Numbers wssn INNER JOIN Web_Subscriptions ws ON wssn.i_web_subscription = ws.i_web_subscription WHERE wssn.i_web_subscription = ? AND Account_Type = 'pre'"; if (!($stmt = $this->LocalMysqli->prepare($sql))) { echo "Echec de la préparation : (" . $this->LocalMysqli->errno . ") " . $this->LocalMysqli->error; } $state = $stmt->bind_param( "i", $this->customer_info['i_web_subscription'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); while ( $stmt->fetch() ) { $accounts[$res['i_web_subscription_reserved_number']] = $res['ID']; } $this->customer_info['AccountsList'] = $accounts; return $accounts; } }

customer is not yet in the billing database.

public function get_customer_accounts(){

$accounts = array(); if ( $this->porta_billing_customer ){ $sql = 'SELECT a.i_account, a.id as ID FROM Accounts a WHERE a.i_customer = ? AND a.bill_status = "O"'; if (!($stmt = $this->MasterMysqli->prepare($sql))) { echo "Echec de la préparation : (" . $MasterMysqli->errno . ") " . $LocalMysqli->error; } $state = $stmt->bind_param( "i", $this->customer_info['i_customer'] );

This function return the list of accounts the customer has or the list of ordered accounts if the customer is not yet in the billing database.

This is not used

Page 26/67

Page 27: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); while ( $stmt->fetch() ) { $accounts[$res['i_account']] = $res['ID']; } //$this->customer_info['AccountsList'] = $accounts; return $accounts; } else { $sql = "SELECT i_web_subscription_reserved_number, h323_id as ID FROM Web_Subscription_Selected_Numbers wssn INNER JOIN Web_Subscriptions ws ON wssn.i_web_subscription = ws.i_web_subscription WHERE wssn.i_web_subscription = ? AND Account_Type = 'pre'"; if (!($stmt = $this->LocalMysqli->prepare($sql))) { echo "Echec de la préparation : (" . $this->LocalMysqli->errno . ") " . $this->LocalMysqli->error; } $state = $stmt->bind_param( "i", $this->customer_info['i_web_subscription'] ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); while ( $stmt->fetch() ) { $accounts[$res['i_web_subscription_reserved_number']] = $res['ID']; } //$this->customer_info['AccountsList'] = $accounts; return $accounts; } }

for the moment as we only display the prepaid accounts.

private function web_db_connect(){ $filename = '/home/site_lib/connections/local.mysqli.class.php'; if(!@include_once( $filename ) ) throw new Customer_Exception( "Failed to include ". $filename ); try { $LocalMysql = new LocalMysqli; $this->LocalMysqli = $LocalMysql->connection; $this->LocalMysqli->set_charset("utf8"); return $this->LocalMysqli; } catch (mysqli_sql_exception $e) { throw new Customer_Exception("Could not connect to mysql server !".$e); } }

Connection to the web database.

private function master_db_connect(){ $filename = 'connections/master.mysqli.class.php';

Connection to the master database.

Page 27/67

Page 28: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

if(!@include_once( $filename ) ) throw new Customer_Exception( "Failed to include ". $filename ); try { $MasterMysqli = new MasterMysqli; $this->MasterMysqli = $MasterMysqli->connection; return $this->MasterMysqli; } catch (mysqli_sql_exception $e) { throw new Customer_Exception("Could not connect to mysql server !".$e); } }

private function soap_connect(){

$filename = "credentials/soap.conf.php"; if(!@include_once( $filename ) ) throw new Customer_Exception( "Failed to include ". $filename );

$filename = 'classes/PortaBillingSoapClient.php'; if(!@include_once( $filename ) ) throw new Customer_Exception( "Failed to include ". $filename );

$SOAPCredentials = new SOAPCredentials; $SOAP_user = $SOAPCredentials->get_user(); $SOAP_pass = $SOAPCredentials->get_password();

if ( isset( $this->SOAP_session_id ) && $this->SOAP_session_id != '' ){ try { $this->ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer'); $session_id = $this->ServiceCustomer->_setSessionId( $this->SOAP_session_id ); $this->ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account'); $this->ServiceAccount->_setSessionId( $this->SOAP_session_id ); error_log("[Customer.php] USING SOAP SESSION ID : ".$this->SOAP_session_id); //print_r($this->ServiceAccount, TRUE); return $this->SOAP_session_id; } catch (SoapFault $e) { throw new Customer_Exception("Could not connect to porta-billing SOAP server !"); } } else { try { $this->ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer'); $session_id = $this->ServiceCustomer-

Connection to SOAP.

Page 28/67

Page 29: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

>_login($SOAP_user, $SOAP_pass); $this->SOAP_session_id = $session_id; $this->ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account'); //$session_id2 = $this->ServiceAccount->_login($SOAP_user, $SOAP_pass); $this->ServiceAccount->_setSessionId( $this->SOAP_session_id ); error_log("[Customer.php] NEW SOAP SESSION ID : ".$this->SOAP_session_id); return $session_id; } catch (SoapFault $e) { throw new Customer_Exception("Could not connect to porta-billing SOAP server !"); } } }

private function stmt_bind_assoc (&$stmt, &$out) { global $mysqli; $data = $stmt->result_metadata(); $fields = array(); $out = array(); $fields[0] = $stmt; $count = 1; while($field = $data->fetch_field()) { $fields[$count] = &$out[$field->name]; $count++; } call_user_func_array('mysqli_stmt_bind_result', $fields); }

A function for saving MySQL results.

public function _close(){ $this->LocalMysqli->close(); $this->MasterMysqli->close(); }}

Function to call for closing the object.

class Customer_Exception extends Exception{ public function __construct($message = null, $code = 0, Exception $previous = null) { try { mail('[email protected]', 'Customer management error', $message . "\n\n" . "Message sent from web server :" . __FILE__); echo "Erreur :".$message; } catch(Exception $e) { echo $e."\n"; } }

This class is an extension of the Exception class and send an email in case of error in try { … } catch { … } for example.

Page 29/67

Page 30: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

}

?>

Account class[classes/Account.php]

Code Comments<?php

/*** */

class Account{

Account class. This class provides information on the accounts.

public $account_info; public $porta_billing_account = FALSE;

Public properties.

private $LocalMysqli; private $MasterMysqli; private $ServiceCustomer; private $ServiceAccount;

Private properties.

function __construct() { $this->web_db_connect(); $this->master_db_connect(); $this->soap_connect(); }

function __wakeup(){ $this->web_db_connect(); $this->master_db_connect(); $this->soap_connect(); }

public function _close(){ $this->LocalMysqli->close(); $this->MasterMysqli->close(); }

function __destruct(){ $this->LocalMysqli->close(); $this->MasterMysqli->close(); }

Constructors and destructors. They are called when the class is loaded or closed or serialized.

public function load_account_info(){Function for getting

Page 30/67

Page 31: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

the account info.

if ( $this->porta_billing_account == TRUE ){ $param = ''; if ( isset( $this->account_info['ID'] ) ){ $param = $this->account_info['ID']; $sql = "SELECT *,NOW() as CurrentTime FROM Accounts WHERE id = ?"; $stmt = $this->MasterMysqli->prepare($sql); $state = $stmt->bind_param( "s", $param ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); if ( $res['i_account'] > 0 ){ $this->account_info = $res; $this->account_info['ID'] = $res['id']; } else { return false; } } elseif( isset( $this->account_info['i_account'] ) ){ $param = $this->account_info['i_account']; $sql = "SELECT *,NOW() as CurrentTime FROM Accounts WHERE i_account = ?"; $stmt = $this->MasterMysqli->prepare($sql); $state = $stmt->bind_param( "i", $param ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); if ( $res['i_account'] > 0 ){ $this->account_info = $res; $this->account_info['ID'] = $res['id']; } else { return false; } }

In case the account is a porta-billing account, we get the list from it. We check before which element we have, the i_account or ID.

$this->account_info['CurrentSubscriptionType'] = 0; $this->account_info['CurrentSubscriptionExpirationDate'] = '0000-00-00 00:00:00'; $this->account_info['SubscriptionAutoRenewal'] = '0'; $this->account_info['IsPrepaidPrivate'] = false; $this->get_subscription_plan(); $this->account_info['Active'] = 1;

We set the default variable for the subscription type, expiration date and the get_subscription plan get the

Page 31/67

Page 32: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

current values.

} else {If the customer is not yet in the billing.

$param = ''; if ( isset( $this->account_info['ID'] ) ){ $param = $this->account_info['ID']; $sql = "SELECT *, NOW() as CurrentTime FROM Web_Subscription_Selected_Numbers WHERE h323_id = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "s", $param ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); if ( $res['i_web_subscription_reserved_number'] > 0 ){ $this->account_info = $res; $this->account_info['CurrentSubscriptionType'] = 0; $this->account_info['CurrentSubscriptionExpirationDate'] = '0000-00-00 00:00:00'; $this->account_info['SubscriptionAutoRenewal'] = '0'; $this->account_info['IsPrepaidPrivate'] = false; $this->account_info['Active'] = 0; $this->account_info['ID'] = $res['h323_id']; } else { return false; }

We select the values from the web subscription database and set the info about subscription to defaults values.

} elseif( isset( $this->account_info['i_web_subscription_reserved_number'] ) ){ $param = $this->account_info['i_web_subscription_reserved_number']; $sql = "SELECT *, NOW() as CurrentTime FROM Web_Subscription_Selected_Numbers WHERE i_web_subscription_reserved_number = ?"; $stmt = $this->LocalMysqli->prepare($sql); $state = $stmt->bind_param( "i", $param ); $stmt->execute(); $res=array(); $this->stmt_bind_assoc($stmt, $res); $stmt->fetch(); if ( $res['i_web_subscription_reserved_number'] > 0 ){ $this->account_info = $res; $this->account_info['CurrentSubscriptionType'] = 0; $this->account_info['CurrentSubscriptionExpirationDate'] = '0000-

Page 32/67

Page 33: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

00-00 00:00:00'; $this->account_info['SubscriptionAutoRenewal'] = '0'; $this->account_info['IsPrepaidPrivate'] = false; $this->account_info['Active'] = 0; $this->account_info['ID'] = $res['h323_id']; } else { return false; } }

} return TRUE; }

End of loading account.

public function set_i_account($i_account){ $this->account_info['i_account'] = $i_account; }

Function for setting i_account to the object.

public function set_account_id($id){ $this->account_info['ID'] = $id; }

Function for setting id to the object.

public function get_subscription_plan(){ include dirname(__FILE__) . '/../etc/' . "SubscriptionPlans.php";

Function for getting subscription plans. We include the file containing the information for each subscription plan.

if ( isset( $PB_Private_Prepaid_Products[ $this->account_info['iso_4217'] ] ) && $this->account_info['i_product'] == $PB_Private_Prepaid_Products[ $this->account_info['iso_4217'] ] ){ $this->account_info['IsPrepaidPrivate'] = true; } else { $this->account_info['IsPrepaidPrivate'] = false; }

We look to the products of the customer to see if it is prepaid private.

if ( isset( $this->account_info['expiration_date'] ) &&

As well as

Page 33/67

Page 34: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$this->account_info['expiration_date'] != '' ){ $this->account_info['CurrentSubscriptionExpirationDate'] = $this->account_info['expiration_date']; } else { $this->account_info['CurrentSubscriptionExpirationDate'] = NULL; }

the expiration date.

try { $GetAccountCustomFieldsValuesRequest = array( 'i_account' => $this->account_info['i_account'] ); $GetAccountCustomFieldsValuesResponse = $this->ServiceAccount->get_custom_fields_values($GetAccountCustomFieldsValuesRequest); //error_log(print_r($GetAccountCustomFieldsValuesResponse, TRUE)); } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; }

$custom_fields_values = $GetAccountCustomFieldsValuesResponse->custom_fields_values; foreach ($custom_fields_values as $custom_fields_value) { if ( $custom_fields_value->name == 'Auto renewal subscription plan' ){ $this->account_info['SubscriptionAutoRenewal'] = $custom_fields_value->db_value; } if ( $custom_fields_value->name == 'Prepaid subscription plan' ){ $this->account_info['CurrentSubscriptionType'] = $custom_fields_value->db_value; } } }

And we get the custom fields values to get the subscription auto renewal state and the type of subscription.

public function update_subscription_plan( $i_subscription_plan, $update_expiration_date = TRUE ){

Function for updating the subscription plan.

include dirname(__FILE__) . '/../etc/' . "SubscriptionPlans.php"; if ( !isset( $SubscriptionPlans[$i_subscription_plan] ) ){

First we check if we need to update the

Page 34/67

Page 35: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

return FALSE; } if ( $update_expiration_date !== TRUE && $update_expiration_date !== FALSE ){ return FALSE; } if ( $update_expiration_date ){ $expiration_date = date( 'Y-m-d' , max( strtotime( date('Y-m-d') ) , strtotime( $this->account_info['expiration_date'] ) ) ) ; $AccountInfo = array( 'i_account' => $this->account_info['i_account'], 'expiration_date' => date('Y-m-d', strtotime('+'.$SubscriptionPlans[$i_subscription_plan]['RenewalPeriodMonths'].' months', strtotime( $expiration_date ) ) ), ); $UpdateAccountRequest = array( 'account_info' => $AccountInfo, ); try { $AddUpdateAccountResponse = $this->ServiceAccount->update_account($UpdateAccountRequest); $updated = TRUE; } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } if ( $updated == FALSE ){ $subscription = array( 'i_subscription' => $PB_Prepaid_Subscription_Plans[$this->account_info['iso_4217']], 'finish_date' => date('Y-m-d', strtotime( '+'.$SubscriptionPlans[$i_subscription_plan]['RenewalPeriodMonths'].' months' ) ), ); $AddAccountSubscriptionRequest = array( 'i_account' => $this->account_info['i_account'], 'subscription_info' => $subscription ); try { $AddUpdateAccountSubscriptionResponse = $this->ServiceAccount->add_subscription($AddAccountSubscriptionRequest); $updated = TRUE; } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } } } }

expiration date and process.

try {Then we

Page 35/67

Page 36: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$text_value = 'no subscription plan'; if ( $i_subscription_plan == 1 ){ $text_value = '1 month'; } elseif ( $i_subscription_plan > 1 ){ $text_value = $SubscriptionPlans[$i_subscription_plan]['RenewalPeriodMonths'].' months'; } $CustomFieldsValuesInfo = array( 'name' => 'Prepaid subscription plan', //'db_value' => $i_subscription_plan, 'text_value' => $text_value ); $custom_fields_values = array(); array_push($custom_fields_values, $CustomFieldsValuesInfo); $UpdateAccountCustomFieldsValuesRequest = array( 'i_account' => $this->account_info['i_account'], 'custom_fields_values' => $custom_fields_values ); $UpdateAccountCustomFieldsValuesResponse = $this->ServiceAccount->update_custom_fields_values( $UpdateAccountCustomFieldsValuesRequest ); } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } $this->load_account_info(); return true; }

set the id of the prepaid subscription plan in the custom field values.

public function set_auto_renewal( $flag ){ $text_value = 'no'; if ( $flag ) { $text_value = 'yes'; } if ( !isset( $this->account_info['CurrentSubscriptionType'] ) || $this->account_info['CurrentSubscriptionType'] == 0 ){ $this->account_info['CurrentSubscriptionType'] = 1; $this->update_subscription_plan( 1, FALSE ); } try { $CustomFieldsValuesInfo = array( 'name' => 'Auto renewal subscription plan', //'db_value' => $i_subscription_plan, 'text_value' => $text_value ); $custom_fields_values = array(); array_push($custom_fields_values, $CustomFieldsValuesInfo);

$UpdateAccountCustomFieldsValuesRequest = array( 'i_account' => $this->account_info['i_account'], 'custom_fields_values' => $custom_fields_values );

Function to toggle on or off the auto-renewal in the billing database.

Page 36/67

Page 37: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$UpdateAccountCustomFieldsValuesResponse = $this->ServiceAccount->update_custom_fields_values( $UpdateAccountCustomFieldsValuesRequest ); } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } return true; }

public function set_prepaid_private_product(){ include dirname(__FILE__) . '/../etc/' . "SubscriptionPlans.php";

$i_product = 33;

if ( isset( $PB_Private_Prepaid_Products[ $this->account_info['iso_4217'] ] ) ){ $i_product = $PB_Private_Prepaid_Products[ $this->account_info['iso_4217'] ]; } else { error_log("new i_product not found. using default ".$i_product ); }

$AccountInfo = array( 'i_account' => $this->account_info['i_account'], 'i_product' => $i_product, );

$UpdateAccountRequest = array( 'account_info' => $AccountInfo, );

try { $AddUpdateAccountResponse = $this->ServiceAccount->update_account($UpdateAccountRequest); } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } return true; }

Function for updating the product to prepaid private.

private function web_db_connect(){ $filename = '/home/site_lib/connections/local.mysqli.class.php'; if(!@include_once( $filename ) ) throw new Account_Exception( "Failed to include ". $filename ); try { $LocalMysql = new LocalMysqli; $this->LocalMysqli = $LocalMysql->connection; $this->LocalMysqli->set_charset("utf8"); return $this->LocalMysqli; } catch (mysqli_sql_exception $e) {

Connection to the web database.

Page 37/67

Page 38: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

throw new Account_Exception("Could not connect to mysql server !".$e); } }

private function soap_connect(){

$filename = "credentials/soap.conf.php"; if(!@include_once( $filename ) ) throw new Customer_Exception( "Failed to include ". $filename );

$filename = 'classes/PortaBillingSoapClient.php'; if(!@include_once( $filename ) ) throw new Customer_Exception( "Failed to include ". $filename );

$SOAPCredentials = new SOAPCredentials; $SOAP_user = $SOAPCredentials->get_user(); $SOAP_pass = $SOAPCredentials->get_password();

if ( isset( $this->SOAP_session_id ) && $this->SOAP_session_id != '' ){ try { $this->ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer'); $session_id = $this->ServiceCustomer->_setSessionId( $this->SOAP_session_id ); $this->ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account'); $this->ServiceAccount->_setSessionId( $this->SOAP_session_id ); error_log("[Account.php] USING SOAP SESSION ID : ".$this->SOAP_session_id); //print_r($this->ServiceAccount, TRUE); return $this->SOAP_session_id; } catch (SoapFault $e) { throw new Customer_Exception("Could not connect to porta-billing SOAP server !"); } } else { try { $this->ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer'); $session_id = $this->ServiceCustomer->_login($SOAP_user, $SOAP_pass); $this->SOAP_session_id = $session_id; $this->ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account'); //$session_id2 = $this->ServiceAccount->_login($SOAP_user, $SOAP_pass); $this->ServiceAccount->_setSessionId( $this->SOAP_session_id ); error_log("[Account.php] NEW SOAP SESSION ID : ".

Connection to SOAP. We check that we do not have a valid connection with the session id before and reuse it if it exists.

Page 38/67

Page 39: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$this->SOAP_session_id); return $session_id; } catch (SoapFault $e) { throw new Customer_Exception("Could not connect to porta-billing SOAP server !"); } } }

private function master_db_connect(){ $filename = 'connections/master.mysqli.class.php'; if(!@include_once( $filename ) ) throw new Account_Exception( "Failed to include ". $filename ); try { $MasterMysqli = new MasterMysqli; $this->MasterMysqli = $MasterMysqli->connection; return $this->MasterMysqli; } catch (mysqli_sql_exception $e) { throw new Account_Exception("Could not connect to mysql server !".$e); } }

Connection to the master database.

private function stmt_bind_assoc (&$stmt, &$out) { global $mysqli; $data = $stmt->result_metadata(); $fields = array(); $out = array(); $fields[0] = $stmt; $count = 1; while($field = $data->fetch_field()) { $fields[$count] = &$out[$field->name]; $count++; } call_user_func_array('mysqli_stmt_bind_result', $fields); }

A function for saving MySQL results.

}End of the account class.

class Account_Exception extends Exception{ public function __construct($message = null, $code = 0, Exception $previous = null) { try { mail('[email protected]', 'Customer management error', $message . "\n\n" . "Message sent from web server :" . __FILE__); echo "Erreur :".$message; } catch(Exception $e) { echo $e."\n"; }

This class is an extension of the Exception class and send an email in case of error in try

Page 39/67

Page 40: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

}}

?>

{ … } catch { … } for example.

Prepaid subscription surveyThis script treats the prepaid subscriptions expiration dates and renewals.

[/home/site_lib/scripts/141119-prepaid-private-survey/a1.php]

Code Comments

<?php

#

$site_lib = '/home/site_lib';set_include_path( get_include_path() . PATH_SEPARATOR . $site_lib);

$path = dirname(__FILE__);

$LANGUAGE = 'en';

require_once $path.'/languages/languages.php';require_once 'classes/PHPMailer/class.phpmailer.php';require_once 'credentials/paypal.app1.conf.php';require_once 'configurations/SubscriptionPlans.php';require_once 'configurations/products.conf.php';require_once($path.'/PPBootStrap.php');require_once 'classes/PHPMailer/class.phpmailer.php';include "configurations/currency_prices.php";

Including all necessary files.

$prepaid_interface_url = 'http://switzernet.com/3/company/141029-prepaid-subscription-web-interface/';

$ServiceAccount;$ServiceCustomer;$SlaveMysqli;$MasterMysqli;$LocalMysqli;

Declaring the global variables that will be used later.

$pid = new pid($path.'/lock');if($pid->already_running) {

In order to do

Page 40/67

Page 41: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

echo "Already running.\n"; exit;}else { echo "Running...\n";}

not have multiple instances of this script running, we verify that no other instance is currently running.

start();Connections to the required databases and SOAP API.

$sql = 'SELECT NOW() AS mysql_datetime, DATE(NOW()) as mysql_date, CURTIME() as mysql_time, UNIX_TIMESTAMP() as unix_timestamp';

$results = $SlaveMysqli->query($sql);

$current_time = $results->fetch_object();

First, we get the current time from the porta-billing server where are store the data.

$hours_to_wake_before_midnight = 3;We set the interval in which the script must process

Page 41/67

Page 42: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

the last charge attempt on last dayon the customer credit card or PayPal account in case of the renewal option is set.

$list_to_process = array();$sql = 'SELECT a.*, p.name as product_name from Accounts a INNER JOIN Products p ON a.i_product=p.i_product WHERE p.i_product IN (33,34,35);';$stmt = $SlaveMysqli->prepare($sql);$stmt->execute();$res=array();$tmp = array();stmt_bind_assoc($stmt, $res);

while ( $stmt->fetch() ){ $list_to_process[$res['i_account']] = new stdClass; $list_to_process[$res['i_account']]->account_info = ar_def($res);}$stmt->close();

Getting all accounts with the prepaid private subscriptions (CHF, EUR and USD) and save the data in a hash.

foreach ($list_to_process as $i_account => $account) {

$sql = "SELECT * FROM Customers WHERE i_customer = ?"; $s = $stmt = $SlaveMysqli->prepare($sql) ; if ( !$s ){err($SlaveMysqli->error);} $s = $stmt->bind_param( "i", $account->account_info['i_customer'] ); if ( !$s ){err($SlaveMysqli->error);} $s = $stmt->execute(); if ( !$s ){err($SlaveMysqli->error);} stmt_bind_assoc($stmt, $res); if ( $stmt->fetch() ){ $account->customer_info = ar_def($res); } else {

For each of thiese accounts, we complete the data with the customer data, payment

Page 42/67

Page 43: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$account->customer_info = NULL; } $stmt->close(); if ( $account->customer_info['i_credit_card'] != NULL ){ try { $GetCustomerPaymentMethodInfoRequest = array( 'i_customer' => $account->customer_info['i_customer'] ); $GetCustomerPaymentMethodInfoResponse = $ServiceCustomer->get_payment_method_info($GetCustomerPaymentMethodInfoRequest); $account->payment_method_info = $GetCustomerPaymentMethodInfoResponse->payment_method_info; } catch (SoapFault $fault) { throw new Custom_Exception("Soap error :".$fault); return false; } } else { $account->payment_method_info = NULL; } try { $GetAccountCustomFieldsValuesRequest = array( 'i_account' => $account->account_info['i_account'] ); $GetAccountCustomFieldsValuesResponse = $ServiceAccount->get_custom_fields_values($GetAccountCustomFieldsValuesRequest); $account->custom_fields_values = $GetAccountCustomFieldsValuesResponse->custom_fields_values; } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; }

$account->account_info['auto_renew_subscription_plan'] = FALSE; $account->account_info['subscription_plan_id'] = 0; $account->account_info['subscription_plan_name'] = '';

foreach ($account->custom_fields_values as $custom_field) { if ( $custom_field->name == 'Prepaid subscription plan' ) { $account->account_info['subscription_plan_id'] = $custom_field->db_value; $account->account_info['subscription_plan_name'] = $custom_field->text_value; } if ( $custom_field->name == 'Auto renewal subscription plan' ) { $account->account_info['auto_renew_subscription_plan'] = $custom_field->db_value; } if ( $custom_field->name == 'Survey timestamp' ) { $account->account_info['survey_last_processed'] = $custom_field->db_value; } } if ( $account->payment_method_info->payment_method == 'PayPal' ){ $sql = "SELECT * FROM CustomerPayPalPreapprovedPayments

method and the option of this account like the renewal option, the free prepaid type and the last date the account was processed by this script.

Page 43/67

Page 44: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

WHERE i_customer = ?"; $stmt = $LocalMysqli->prepare($sql); $state = $stmt->bind_param( "i", $account->customer_info['i_customer'] ); $stmt->execute(); $res=array(); stmt_bind_assoc($stmt, $res); $stmt->fetch(); $stmt->close(); if ( $res['i_customer'] > 0 ){ $account->payment_method_info->senderEmail = $res['senderEmail']; if ( $res['approved'] == 1 ){ $account->payment_method_info->status = 'approved'; } else { $account->payment_method_info->status = 'pending'; } } else { $account->payment_method_info->status = 'unknown'; } }}

foreach ($list_to_process as $i_account => $account) { $LANGUAGE = strtolower( $account->customer_info['i_lang'] );

All accounts data are now complete. We process accounts one by one.

echo "\n######################################\n";

echo "i_account : ".$account->account_info['i_account']."\n"; echo "id : ".$account->account_info['id']."\n";

echo "survey_last_processed : ".$account->account_info['survey_last_processed']."\n";

$has_been_charged = false; $last_attempt_before_closing = false;

Initiating the variables and displaying account.

if ( $account->account_info['expiration_date'] != NULL ){If the expiration date is set. This is verificati

Page 44/67

Page 45: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

on. Later, if it is not set we replace the product.

$remove_if_no_payment = false; $last_payment_attempt_failed = true;

$tomorrow = new stdClass; $tomorrow->mysql_date = date('Y-m-d', strtotime($current_time->mysql_datetime . '+1 days') ); $tomorrow->unix_timestamp = strtotime($current_time->mysql_datetime . '+1 days');

We get the date for tomorrow.

$day_diff = floor( ( strtotime( $account->account_info['expiration_date'] ) - strtotime( $tomorrow->mysql_date ) ) / ( 60*60*24 ) ); echo "days left : ".$day_diff." days.\n";

And we calculate the remaining days before the account will be expired.

if ( $day_diff == 0 ){ echo "This is the last day\n"; if ( $current_time->mysql_date == date( 'Y-m-d', strtotime( $account->account_info['survey_last_processed'] ) ) ){ echo "We have processed today\n"; $daily_time_s = date( 's' , $current_time->unix_timestamp ) + date( 'i' , $current_time->unix_timestamp ) * 60 + date( 'H' , $current_time->unix_timestamp ) * 60 * 60 ; $day_s = ( 60*60*24 ) ; $start_last_interval = $day_s - ( $hours_to_wake_before_midnight * 60 * 60 ); $processed_daily_time_s = date( 's' , strtotime($account->account_info['survey_last_processed']) ) + date( 'i' , strtotime($account->account_info['survey_last_processed']) ) * 60 + date( 'H' , strtotime($account->account_info['survey_last_processed']) ) * 60 * 60 ;

/* echo '$daily_time_s :'.$daily_time_s ."\n"; echo '$day_s :'.$day_s ."\n";

If we are on the last day and we have processed today, we check if it was before the last interval before midnight during which we must do a last

Page 45/67

Page 46: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

echo '$start_last_interval :'.$start_last_interval ."\n"; echo '$processed_daily_time_s:'.$processed_daily_time_s."\n"; */

if ( $start_last_interval < $processed_daily_time_s && $daily_time_s > $start_last_interval ){ echo "but it was before the last period attempt\n"; $remove_if_no_payment = true; $last_payment_attempt_failed = true; } else { //echo "and it was before the last X hours before midnight\n"; continue; } } else { echo "We have processed today yet\n"; }

attempt. If we are before or if we are in the last interval but an attempt was made in this interval, we continue and do not attempt to charge the customer payment method.

} elseif ( $day_diff > 0 ){ if ( $current_time->mysql_date == date( 'Y-m-d', strtotime( $account->account_info['survey_last_processed'] ) ) ){ echo "We have processed today\n"; continue; } else { echo $current_time->mysql_date . " =/= " . date( 'Y-m-d', strtotime( $account->account_info['survey_last_processed'] ) ) ."\n"; } }

If this is not the last day, we only check if an attempt was made this day. If yes, we skip.

if ( 0 <= $day_diff && $day_diff <= 2 ) { if ( $account->account_info['auto_renew_subscription_plan'] && $account->account_info['subscription_plan_id'] > 0 ){

Then we process the accounts we filtered.

Page 46/67

Page 47: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

We check the prepaid subscription type is a valid subscription plan and that the renewal option is activated.

update_renew_timestamp( $i_account, $current_time->mysql_datetime ); echo "auto renewal is set. we must process.\n";

In this case, we update the timestamp in porta-billing to say that it is proceed now.

$amount = ( $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ][ 'MonthlyFees' ][ $account->account_info['iso_4217'] ] ) * $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ]['RenewalPeriodMonths'] ; $visible_comment = l('Subscription plan') . ' ' . $account->account_info['subscription_plan_name']; $internal_comment = 'Sub. plan ' . $account->account_info['subscription_plan_name'];

Preparing to charge. We calculate the amount and set the comments that will be visible in the CDRs.

Page 47/67

Page 48: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

echo "subscription plan is : ".$account->account_info['subscription_plan_name'].".\n"; echo "we will charge ".$amount." ".$account->account_info['iso_4217'].".\n";

Displaying the subscription plan that will be charged and the amount and currency (which is in reality the account currency).

if ( $account->payment_method_info->payment_method == 'VISA' || $account->payment_method_info->payment_method == 'MasterCard' ){

In case of credit card.

$transaction_result = make_credit_card_transation( $account->account_info['i_customer'], $amount, $visible_comment, $internal_comment );

We make the payment with the SOAP API and we get the transaction result back.

if ( $transaction_result == TRUE ){ $last_payment_attempt_failed = false; echo "credit card transaction was OK.\n"; $expiration_date = ''; $expiration_date = date( 'Y-m-d' , max( strtotime( $current_time->mysql_date ) , strtotime( $account->account_info['expiration_date'] ) ) ) ; $expiration_date = date('Y-m-d', strtotime('+'.$SubscriptionPlans[ $account->account_info['subscription_plan_id'] ]['RenewalPeriodMonths'].' months', strtotime( $expiration_date ) ) );

If the transaction was done well, we update the expiration date, set the

Page 48/67

Page 49: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

echo "expiration date will be updated to ".$expiration_date.".\n"; $r = update_expiration_date( $i_account, $expiration_date ); if ( $r ){ if (!set_prepaid_private_product( $i_account, $account->account_info['iso_4217'] ) ){ err("unable to set_prepaid_private_product for i_account " . $account->account_info['i_account'] ); } else { echo "prepaid private product is set.\n"; } } else { err("unable to update_expiration_date for i_account " . $account->account_info['i_account'] ); echo "updating expiration date failed.\n"; }

product of the account to private prepaid.

} else { err("credit card transaction failed " . $account->account_info['i_account'] ); email_automatic_payment_method_failed( $account ); echo "credit card transaction failed.\n"; }

Else we send an email to the customer, informing the transaction could not be finished.

} elseif ( $account->payment_method_info->payment_method == 'PayPal' ) { update_renew_timestamp( $i_account, $current_time->mysql_datetime );

In case the payment method is paypal, we update the timestamp too.

if ( $account->payment_method_info->status == "approved" ){

And we check the authorization is

Page 49/67

Page 50: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

approved.

$transaction_result = make_paypal_transaction( $account->account_info['i_customer'], $amount, $account->account_info['iso_4217'], $visible_comment, $internal_comment );

Then we make the paypal transaction.

if ( $transaction_result == TRUE ){

$last_payment_attempt_failed = false; echo "credit card transaction was OK.\n"; $expiration_date = ''; $expiration_date = date( 'Y-m-d' , max( strtotime( $current_time->mysql_date ) , strtotime( $account->account_info['expiration_date'] ) ) ) ; $expiration_date = date('Y-m-d', strtotime('+'.$SubscriptionPlans[ $account->account_info['subscription_plan_id'] ]['RenewalPeriodMonths'].' months', strtotime( $expiration_date ) ) ); echo "expiration date will be updated to ".$expiration_date.".\n"; $r = update_expiration_date( $i_account, $expiration_date ); if ( $r ){ if (!set_prepaid_private_product( $i_account, $account->account_info['iso_4217'] ) ){ err("unable to set_prepaid_private_product for i_account " . $account->account_info['i_account'] ); } else { echo "prepaid private product is set.\n"; } } else { err("unable to update_expiration_date for i_account " . $account->account_info['i_account'] ); echo "updating expiration date failed.\n"; }

If the transaction was made well, we update the expiration date and set the account’s product to prepaid private.

} else { err("paypal transaction failed " . $account->account_info['i_account'] ); email_automatic_payment_method_failed( $account ); echo "paypal transaction failed.\n"; }

If the transaction failed, we send an email to the customer.In case

Page 50/67

Page 51: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

} else { email_automatic_payment_paypal_not_approved( $account ); echo "paypal is not approved. customer must check it emails\n"; }

the authorization is not approved, we send an email to the customer.

} else { echo "no payment method and auto renewal. we will remove the auto renewal\n"; set_auto_renewal( $account->account_info['i_account'], FALSE ); }

In case there was a renewal option but not set payment method, we have to remove the renewal option.

} else { echo "no auto renew.\n"; update_renew_timestamp( $i_account, $current_time->mysql_datetime ); email_no_renewal_expiration_date_ends_in_X_days( $account , $day_diff ); }

In case that there was no auto-renwal, we must tell that we processed this account today in the billing database and

Page 51/67

Page 52: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

send an email to the customer inviting him to update the its subscription plan himself.

} elseif ( $day_diff < 0 ) { echo "expiration is reached. we must set the product back to normal prepaid and remove subscription date.\n"; $r = remove_prepaid_private_product( $i_account, $account->account_info['iso_4217'] ); if ( $r ){ echo "private prepaid product removed.\n"; if ( remove_expiration_date( $i_account ) ){ echo "expiration date removed.\n"; email_subscription_plan_has_been_removed( $account ); } else { err("could not remove expiration date : " . $account->account_info['i_account'] ); } } else { err("could not remove prepaid private account. leave the account blocked : " . $account->account_info['i_account'] ); }

This may no occurs but if we are after the expiration date, we must set back the product to normal prepaid and remove expiration date.

} else { echo "expiration date is in the future and no need to renew now.\n"; }

When the expiration date above the X days in which we must try to renew the account, we do

Page 52/67

Page 53: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

nothing.

} else { echo "no expiration date.\n"; remove_prepaid_private_product( $account->account_info['i_account'], $account->account_info['iso_4217'] ); }

We di not find expiration date but the account is prepaid private. We must change the product back to prepaid product.

if ( $last_payment_attempt_failed && $remove_if_no_payment ){ $r = remove_prepaid_private_product( $i_account, $account->account_info['iso_4217'] ); if ( $r ){ echo "private prepaid product removed.\n"; if ( remove_expiration_date( $i_account ) ){ echo "expiration date removed.\n"; } else { err("could not remove expiration date : " . $account->account_info['i_account'] ); } } else { err("could not remove prepaid private account. leave the account blocked : " . $account->account_info['i_account'] ); } }

This only occurs for the last payment attempt. If it fails, we remove the expiration date and the prepaid private product.

}End of the loop through accounts.

stop();Closing databases connecti

Page 53/67

Page 54: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

ons.

function make_credit_card_transation( $i_customer, $amount = 1, $visible_comment = NULL, $internal_comment = NULL ){ global $ServiceCustomer; global $ServiceAccount;# print_r( 'Credit card transaction' ); $visible_comment = substr($visible_comment, 0, 32); $internal_comment = substr($internal_comment, 0, 32); $MakeCustomerTransactionRequest = array( 'i_customer' => $i_customer, 'action' => 'e-commerce payment', 'amount' => number_format($amount,5), 'visible_comment' => $visible_comment, 'internal_comment' => $internal_comment ); try { $MakeCustomerTransactionResponse = $ServiceCustomer->make_transaction($MakeCustomerTransactionRequest); } catch (SoapFault $fault) { # throw new Custom_Exception("Soap error :".$fault); # return false; err("transaction error for i_customer ".$i_customer); } #echo "CONTINUE"; if ( !isset( $MakeCustomerTransactionResponse ) || !$MakeCustomerTransactionResponse ){ return false; } return true; #print_r($MakeCustomerTransactionResponse);}

Making a transaction with credit card with SOAP API.

function make_paypal_transaction( $i_customer, $amount, $currency, $visible_comment = NULL, $internal_comment = NULL ){ global $ServiceCustomer; global $ServiceAccount; global $preappouved;

$conf = Configuration::getAcctAndConfig();

echo "we will make a transaction for i_customer ".$i_customer." of ".$amount." ".$currency."\n"; $actionType = "PAY"; //$returnUrl = 'http://' . $_SERVER['SERVER_NAME'] . ':' . dirname($_SERVER['PHP_SELF'])."/"; //$cancelUrl = 'http://' . $_SERVER['SERVER_NAME'] . ':' . dirname($_SERVER['PHP_SELF'])."/"; $returnUrl = "https://account.switzernet.com/customer_info.html"; $cancelUrl = "https://account.switzernet.com/customer_info.html";

$receiver = array(); $receiver[0] = new Receiver();

Making a paypal transaction.

Page 54/67

Page 55: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$receiver[0]->email = $conf['ReceiverEmail']; $receiver[0]->amount = $amount; $receiver[0]->primary = "false"; $receiver[0]->paymentType = "SERVICE";

$receiverList = new ReceiverList($receiver);

$payRequest = new PayRequest(new RequestEnvelope("en_US"), $actionType, $cancelUrl, $currency, $receiverList, $returnUrl); $payRequest->preapprovalKey = $preappouved[$i_customer]['preapproval_key']; $payRequest->ipnNotificationUrl = $conf['IPN_URL']; $payRequest->senderEmail = $preappouved[$i_customer]['senderEmail'];

$service = new AdaptivePaymentsService(Configuration::getAcctAndConfig());

try { $response = $service->Pay($payRequest); } catch(Exception $ex) { err("transaction error for i_customer ".$i_customer ); #require_once '../Common/Error.php';

} $ack = strtoupper($response->responseEnvelope->ack); if($ack != "SUCCESS") { echo "ERROR\n"; print_r($response); send_info_mail("[error] PayPal prepaid private automatic renewal", "Error during automatic payment with PayPal for i_customer $i_customer \n\n-------------\n\n". print_r($response, TRUE) ); return FALSE; } else { $payKey = $response->payKey; if(($response->paymentExecStatus == "COMPLETED" )) { send_info_mail("PayPal prepaid private automatic renewal / status: paid ", "i_customer: $i_customer \n\nDATA:\n " . print_r($response, TRUE) ); $MakeCustomerTransactionRequest = array( 'i_customer' => $i_customer, 'action' => 'Manual charge', 'amount' => sprintf('%.5f', $amount ), 'visible_comment' => $visible_comment, 'internal_comment' => $internal_comment ); try { $MakeCustomerTransactionResponse = $ServiceCustomer->make_transaction( $MakeCustomerTransactionRequest ); } catch (SoapFault $e) { err("Unable to make manual refund (for paypal payment) on i_customer ".$i_customer); } return TRUE; } else { send_info_mail("[unknown] PayPal prepaid private

Page 55/67

Page 56: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

automatic renewal / status: unknown", "UNknown status of payment with PayPal for i_customer $i_customer \n\n-------------\n\n". print_r($response, TRUE) ); } } return FALSE;}

function update_expiration_date( $i_account, $expiration_date = NULL ){ global $ServiceCustomer; global $ServiceAccount; $AccountInfo = array( 'i_account' => $i_account, 'expiration_date' => $expiration_date, ); $UpdateAccountRequest = array( 'account_info' => $AccountInfo, ); try { $AddUpdateAccountResponse = $ServiceAccount->update_account($UpdateAccountRequest); } catch (SoapFault $fault) { err("Soap error :".$fault); return false; } return true;}

Removing the expiration date with the SOAP API.

function remove_expiration_date( $i_account ){ global $ServiceCustomer; global $ServiceAccount; $AccountInfo = array( 'i_account' => $i_account, 'expiration_date' => '', ); $UpdateAccountRequest = array( 'account_info' => $AccountInfo, ); try { $AddUpdateAccountResponse = $ServiceAccount->update_account($UpdateAccountRequest); } catch (SoapFault $fault) { err("Soap error :".$fault); return false; } return true;}

Removing the expiration date with the SOAP API.

function set_auto_renewal( $i_account , $flag ){ $text_value = 'no'; if ( $flag ) { $text_value = 'yes';

Setting the auto renewal

Page 56/67

Page 57: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

} try { $CustomFieldsValuesInfo = array( 'name' => 'Auto renewal subscription plan', 'text_value' => $text_value ); $custom_fields_values = array(); array_push($custom_fields_values, $CustomFieldsValuesInfo); $UpdateAccountCustomFieldsValuesRequest = array( 'i_account' => $i_account, 'custom_fields_values' => $custom_fields_values ); $UpdateAccountCustomFieldsValuesResponse = $ServiceAccount->update_custom_fields_values($UpdateAccountCustomFieldsValuesRequest); } catch (SoapFault $fault) { throw new Account_Exception("Soap error :".$fault); return false; } return true;}

to on or of with the SOAP API.

function set_prepaid_private_product( $i_account, $currency ){ global $ServiceCustomer; global $ServiceAccount; global $PB_Private_Prepaid_Products; $i_product = 33; if ( isset( $PB_Private_Prepaid_Products[ $currency ] ) ){ $i_product = $PB_Private_Prepaid_Products[ $currency ]; } else { error_log("new i_product not found. using default ".$i_product ); } $AccountInfo = array( 'i_account' => $i_account, 'i_product' => $i_product, ); $UpdateAccountRequest = array( 'account_info' => $AccountInfo ); try { $AddUpdateAccountResponse = $ServiceAccount->update_account($UpdateAccountRequest); } catch (SoapFault $fault) { err("Soap error :".$fault); return false; } return true;}

Function to set the product to prepaid private. It uses the id of the subscription plan and the general config file to subscription plans.

function remove_prepaid_private_product( $i_account, $currency ){ global $ServiceCustomer;

Removing of the prepaid

Page 57/67

Page 58: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

global $ServiceAccount; global $PRODUCT; $i_product = 4; if ( isset( $PRODUCT[ $currency ]['pre']['i_product'] ) ){ $i_product = $PRODUCT[ $currency ]['pre']['i_product']; } else { error_log("new i_product not found. using default ".$i_product ); } $AccountInfo = array( 'i_account' => $i_account, 'i_product' => $i_product, ); $UpdateAccountRequest = array( 'account_info' => $AccountInfo ); try { $AddUpdateAccountResponse = $ServiceAccount->update_account($UpdateAccountRequest); } catch (SoapFault $fault) { err("Soap error :".$fault); return false; } return true;}

private product. The global variable ‘PRODUCT’ is set in the general comfiguration file for the products. It looks for the prepaid product in the corresponding currencies.

function update_renew_timestamp( $i_account, $datetime ){ global $ServiceCustomer; global $ServiceAccount; echo "updating the auto renew\n"; try { $text_value = $datetime;

$CustomFieldsValuesInfo = array( 'name' => 'Survey timestamp', //'db_value' => $i_subscription_plan, 'text_value' => $text_value ); $custom_fields_values = array(); array_push($custom_fields_values, $CustomFieldsValuesInfo);

$UpdateAccountCustomFieldsValuesRequest = array( 'i_account' => $i_account, 'custom_fields_values' => $custom_fields_values ); $UpdateAccountCustomFieldsValuesResponse = $ServiceAccount->update_custom_fields_values($UpdateAccountCustomFieldsValuesRequest); } catch (SoapFault $fault) {

This function update the custom field that represents the timestamp on which the script processed the account.

Page 58/67

Page 59: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

throw new Account_Exception("Soap error :".$fault); return false; } return true;}

function send_info_mail( $subject, $body ){

$mail_From = "[email protected]"; $mail_Footer = "\nRegards\n\n--\n\nThis is an automatic message.\n\nhost ".php_uname('n')."\nscript ".__FILE__."\n\n\nSwitzernet ©2014 - Nicolas Bondier\n"; $mail_To = "[email protected]"; $mail_Header = ""; $mail_Header .= 'From: ' . $mail_From . "\r\n"; $mail_Header .= 'Reply-To: '.$mail_To . "\r\n"; $mail_Header .= 'X-Priority: 1' . "\r\n"; $mail_Header .= 'X-MSMail-Priority: High' . "\r\n"; $mail_Header .= 'Importance: High' . "\r\n"; $mail_Header .= 'Content-type: text/plain; charset=utf-8' . "\r\n"; $mail_Header .= 'X-Mailer: PHP/' . phpversion() . "\r\n";

mail($mail_To, $subject, $body, $mail_Header);}

A general function to send emails.

function start(){ slave_db_connect(); master_db_connect(); web_db_connect(); soap_connect();}

Connection to all the databases.

function stop(){ global $LocalMysqli ; global $MasterMysqli ; global $SlaveMysqli ; global $ServiceAccount ; global $ServiceCustomer; $LocalMysqli ->close(); $MasterMysqli ->close(); $SlaveMysqli ->close(); $ServiceAccount ->_logout(); $ServiceCustomer ->_logout();}

Disconnect everything before closing.

Page 59/67

Page 60: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

function slave_db_connect(){ global $SlaveMysqli; $filename = 'connections/slave.mysqli.class.php'; if(!@include_once( $filename ) ) throw new Custom_Exception( "Failed to include ". $filename ); try { $tmp = new SlaveMysqli; $SlaveMysqli = $tmp->connection; $SlaveMysqli->set_charset("utf8"); } catch (mysqli_sql_exception $e) { throw new Custom_Exception("Could not connect to mysql server !".$e); } return $SlaveMysqli;}

Connection to the slave database.

function master_db_connect(){ global $MasterMysqli; $filename = 'connections/master.mysqli.class.php'; if(!@include_once( $filename ) ) throw new Custom_Exception( "Failed to include ". $filename ); try { $tmp = new MasterMysqli; $MasterMysqli = $tmp->connection; } catch (mysqli_sql_exception $e) { throw new Custom_Exception("Could not connect to mysql server !".$e); } return $MasterMysqli;}

Connection to the master database.

function web_db_connect(){ global $LocalMysqli; $filename = 'connections/local.mysqli.class.php'; if(!@include_once( $filename ) ) throw new Custom_Exception( "Failed to include ". $filename );

try { $tmp = new LocalMysqli; $LocalMysqli = $tmp->connection; $LocalMysqli->set_charset("utf8"); } catch (mysqli_sql_exception $e) { throw new Custom_Exception("Could not connect to mysql server !".$e); } return $LocalMysqli;}

Connection to the web database.

function soap_connect(){Connection to

Page 60/67

Page 61: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

global $ServiceCustomer; global $ServiceAccount;

$filename = "credentials/soap.conf.php"; if(!@include_once( $filename ) ) throw new Custom_Exception( "Failed to include ". $filename );

$filename = 'classes/PortaBillingSoapClient.php'; if(!@include_once( $filename ) ) throw new Custom_Exception( "Failed to include ". $filename );

$SOAPCredentials = new SOAPCredentials; $SOAP_user = $SOAPCredentials->get_user(); $SOAP_pass = $SOAPCredentials->get_password();

try { $ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer'); $session_id = $ServiceCustomer->_login($SOAP_user, $SOAP_pass); $ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account'); $ServiceAccount->_setSessionId($session_id); } catch (SoapFault $e) { throw new Custom_Exception("Could not connect to porta-billing SOAP server !"); } return $session_id;}

SOAP API.

function stmt_bind_assoc (&$stmt, &$out) { $data = $stmt->result_metadata(); $fields = array(); $out = array(); $fields[0] = $stmt; $count = 1; while($field = $data->fetch_field()) { $fields[$count] = &$out[$field->name]; $count++; } call_user_func_array('mysqli_stmt_bind_result', $fields);}

Function to retrieve results of a MySQL query with prepaid statements. It return the data in a hash.

function err( $message , $mail = TRUE ){ try { mail('[email protected]','prepay private survey error', $message . "\n\n" . "Message sent from web

An error function that send

Page 61/67

Page 62: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

server script:" . __FILE__); echo $message."\n"; } catch(Exception $e) { echo $e."\n"; }}

emails.

class Custom_Exception extends Exception{ public function __construct($message = null, $code = 0, Exception $previous = null) { $this->err( $message , $mail = TRUE ); }

function err( $message , $mail = TRUE ){ try { mail('[email protected]','prepay private survey error', $message . "\n\n" . "Message sent from web server script:" . __FILE__); echo $message."\n"; } catch(Exception $e) { echo $e."\n"; } }}

# emails :

An extension of the extension class that send emails. It is useful for SOAP request for example.

function email_automatic_payment_method_failed ( $account ){ #print_r($account); global $current_time; global $SubscriptionPlans; global $prepaid_interface_management_url; include "configurations/currency_prices.php"; $amount = ( $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ][ 'MonthlyFees' ][ $account->account_info['iso_4217'] ] ) * $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ]['RenewalPeriodMonths']; $subject = ''; $body = ''; $subject .= l('The automatic paiment for the renewal of your subscription failed'); $body .= '<p>'.l('Dear') . ' ' . $account->customer_info['firstname'] . ' ' . $account->customer_info['lastname'].",</p>"; $body .= '<p>'.l('On').' ' . $current_time->mysql_datetime .', '; $body .= l('the automatic payment of'). ' ' . number_format( $amount , 2 ) . ' ' . $account->account_info['iso_4217'] . ' ' . l('for the renewal of the subscription that you choosed for your VoIP account ') . $account->account_info['id'].'

The email sent to customer informing that its automatic payment failed.

Page 62/67

Page 63: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

'.l('failed.') . '</p>'; $body .= '<p>'.l('In order to continue to benefit of your prepaid subscription, thank you to update your automatic payment information in your').' <a href="'.$prepaid_interface_management_url.'">'.l('prepaid subscription management web interface'). '</a> ' . l('and also to verify that your credit card/paypal account have available funds to process the payment.').'</p>'; $body .= '<p>'.l('We would remind you that your actual subscription, which includes free calls to many countries and advantaging rates to numerous other destinations, will end up on ') . date('Y-m-d', strtotime($account->account_info['expiration_date'] . ' -1 days' )) . ' ' . l('if it is not renewed.'); $body .= ' ' . l('Calls made with your account ') . $account->account_info['id'] . ' ' . l("will be charged with the 'prepaid' rates (no free destination, calls at "). $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] .l("/min minimum, connection fees at ") . $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] . ').<p>'; $body .= '<p>'.l('Best regards').',<br>'; $body .= l('Switzernet team').'</p>';

# . number_format( $amount , 2 ) . ' ' . $account->account_info['iso_4217'] . ' ' . l('for the renewal of the subscription that you choosed for your VoIP account ') . $account->account_info['id'].' '.l('failed.'); send_email_to_customer( $account->customer_info['email'], $subject, $body );}

function email_automatic_payment_paypal_not_approved ( $account ){ global $current_time; global $SubscriptionPlans; global $prepaid_interface_management_url; include "configurations/currency_prices.php"; $amount = ( $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ][ 'MonthlyFees' ][ $account->account_info['iso_4217'] ] ) * $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ]['RenewalPeriodMonths']; $subject = ''; $body = ''; $subject .= l('The automatic paiment for the renewal of your subscription failed'); $body .= '<p>'.l('Dear') . ' ' . $account->customer_info['firstname'] . ' ' . $account->customer_info['lastname'].",</p>"; $body .= '<p>'.l('On').' ' . $current_time->mysql_datetime .', '; $body .= l('the automatic payment of'). ' ' . number_format( $amount , 2 ) . ' ' . $account->account_info['iso_4217'] . '

An email to the customer informaing that the PayPal account authorization is not approved.

Page 63/67

Page 64: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

' . l('for the renewal of the subscription that you choosed for your VoIP account ') . $account->account_info['id'].' '.l('could not be processed you did not approved the PayPal authorization.') . '</p>'; $body .= '<p>'.l('In order to continue to benefit of your prepaid subscription, thank you to approve the PayPal authorization in your').' <a href="'.$prepaid_interface_management_url.'">'.l('prepaid subscription management web interface'). '</a> ' . l('and also to verify that your paypal account have available funds to process the payment.').'</p>'; $body .= '<p>'.l('We would remind you that your actual subscription, which includes free calls to many countries and advantaging rates to numerous other destinations, will end up on ') . date('Y-m-d', strtotime($account->account_info['expiration_date'] . ' -1 days' )) . ' ' . l('if it is not renewed.'); $body .= ' ' . l('Calls made with your account ') . $account->account_info['id'] . ' ' . l("will be charged with the 'prepaid' rates (no free destination, calls at "). $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] .l("/min minimum, connection fees at ") . $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] . ').<p>'; $body .= '<p>'.l('Best regards').',<br>'; $body .= l('Switzernet team').'</p>';

send_email_to_customer( $account->customer_info['email'], $subject, $body );}

function email_no_renewal_expiration_date_ends_in_X_days( $account, $number_of_days ){ global $current_time; global $SubscriptionPlans; global $prepaid_interface_management_url; include "configurations/currency_prices.php"; $amount = ( $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ][ 'MonthlyFees' ][ $account->account_info['iso_4217'] ] ) * $SubscriptionPlans[ $account->account_info['subscription_plan_id'] ]['RenewalPeriodMonths']; $subject = ''; $body = ''; $subject .= l('Your subscription for your VoIP account') . ' ' . $account->account_info['id'] . ' ' . l('will expire soon.');

$body .= '<p>'.l('Dear') . ' ' . $account->customer_info['firstname'] . ' ' . $account->customer_info['lastname'].",</p>";

$body .= '<p>'.l('We would like to inform you that the subscription you choosed for your VoIP account') . ' ' .

This email is sent when the customer has no renewal option activated or no credit card set. It informs the customer in how

Page 64/67

Page 65: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

$account->account_info['id'] . ' ' . l('will expire in') . ' ' . $number_of_days . ( $number_of_days > 1 ? l('days') : l('day') ) . '.</p>' ;

$body .= '<p>'.l('In order to continue to benefit its advantages, thank you to renew it from your').' <a href="'.$prepaid_interface_management_url.'">' . l('prepaid subscription management web interface') . '</a></p>';

$body .= '<p>'.l('Your actual subscription, which includes free calls to many countries and advantaging rates to numerous other destinations, will end up on') . ' ' . date('Y-m-d', strtotime($account->account_info['expiration_date'] . ' -1 days' )) . ' ' . l('if it is not renewed.');

$body .= ' ' . l('Calls made with your account') . ' ' . $account->account_info['id'] . ' ' . l("will be charged with the 'prepaid' rates (no free destination, calls at")." ". $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] .l("/min minimum, connection fees at") . ' ' . $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] . ').<p>';

$body .= '<p>'.l('Best regards').',<br>'; $body .= l('Switzernet team').'</p>'; send_email_to_customer( $account->customer_info['email'], $subject, $body );

}

many days the subscription plan expires.

function email_subscription_plan_has_been_removed( $account ){ global $PRICES; $subject = '';

$subject .= l('Your subscription for your VoIP account') . ' ' . $account->account_info['id'] . ' ' . l('has expired.');

$body = '';

$body .= '<p>'.l('Dear') . ' ' . $account->customer_info['firstname'] . ' ' . $account->customer_info['lastname'].",</p>";

$body .= '<p>'.l('We would like to inform you that the subscription you choosed for your VoIP account') . ' ' . $account->account_info['id'] . ' ' . l('has expired.');

$body .= '<p>' . l('Calls made with your account') . ' ' . $account->account_info['id'] . ' ' . l("will be charged with the 'prepaid' rates (no free destination, calls at")." ". $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account-

The email informing that the subscription plan has been removed and the product has changed.

Page 65/67

Page 66: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

>account_info['iso_4217'] .l("/min minimum, connection fees at") . ' ' . $PRICES[$account->account_info['iso_4217']]['RATE_PREPAID_MINIMUM'] . " " . $account->account_info['iso_4217'] . ').<p>';

send_email_to_customer( $account->customer_info['email'], $subject, $body );

}

function send_email_to_customer( $email, $subject, $body ){ if (filter_var($email, FILTER_VALIDATE_EMAIL)) { $mail = new PHPMailer; $mail->CharSet = 'UTF-8'; $mail->From = '[email protected]'; $mail->FromName = 'Switzernet'; $mail->addAddress( $email ); // Add a recipient $mail->addAddress( '[email protected]' ); // Add a recipient $mail->AddReplyTo( '[email protected]' , 'Billing'); $mail->Subject = $subject; $mail->Body = $body; $mail->IsHTML(); return $mail->send(); } else { return false; }}

General function to send the email to customer.

class pid { protected $filename; public $already_running = false; function __construct($directory) { $this->filename = $directory . '/' . basename($_SERVER['PHP_SELF']) . '.pid'; if(is_writable($this->filename) || is_writable($directory)) { if(file_exists($this->filename)) { $pid = (int)trim(file_get_contents($this->filename)); if(posix_kill($pid, 0)) { $this->already_running = true; } } } else { die("Cannot write to pid file '$this->filename'. Program execution halted.\n"); } if(!$this->already_running) { $pid = getmypid(); file_put_contents($this->filename, $pid); } } public function __destruct() { if(!$this->already_running && file_exists($this->filename)

This class manage the running process and permit to check if anyone is running in the same tim.

Page 66/67

Page 67: Private prepaid subscriptions · Web viewThis PHP script is called every-time for all pages by the init_private_area.php and init_public_area.php. It starts the session, define global

&& is_writeable($this->filename)) { unlink($this->filename); } }}

?>

* * *

Copyright © 2023 by Switzernet

Page 67/67