Credit card payments

Document created on 2014-09-23
Nicolas Bondier

 

[pdf][doc][htm]

 

 

 

 

 

*                  *                  *

Copyright © 2014 by Switzernet

Contents

Introduction. 4

Postfinance integration with portabilling. 4

Postfinance e-payment configuration. 4

Direclink activation. 4

Create an API user. 4

Allow access for portabilling slave IP address. 7

Configure return parameters. 7

Porta-billing configuration. 8

Use PostFinance gateway in Ogone payment processing module on slave. 8

Add PostFinance to the Porta-Billing payments systems. 9

Payments on website. 10

Main payment page. 12

PayPal 29

Process PayPal payments. 29

PayPal payment notifications and update payment on billing. 35

PostFinance. 45

Process Postfinance payments. 45

Postfinance payment notifications and update payment in portabilling. 49

Liens. 61

 


Introduction

This document describes the configuration and scripts used for setting different payments systems in Porta-Billing and on the main website pay.switzernet.com.

Postfinance integration with portabilling 

PostFinance e-payment have a partnership with Ogone for their e-payment gateway.  As the billing permit to use Ogone as payment processor, we could set-up the payment gateway for Postfinance using Ogone as processor with some modifications.

Postfinance e-payment configuration

Direclink activation

First, it is required to set-up the Postfinance account e-payment.postfinance.ch.

Go to ‘Configuration’ è  ‘Abonnement’ è ‘Vos options’. DirectLink is the method used by the billing for processing the payments. The options showed in the picture bellow must be activated.

To activate them, we had to contact Postfinance e-payment and send an order letter.

Create an API user

Go to ‘Configuration’ è  ‘Utilisateurs’ and click the add user button.

In the form, enter the data of the new user as bellow and choose ‘”API” user’ option. Save and manually choose a password for your new API user.

Allow access for portabilling slave IP address

Under "Configuration" è "Informations Techniques" è "Controles de données et d’origine", fill the section "Contrôles pour PostFinance DirectLink".

The IP addresses to authorize are separated with ";". Here I put all the slave portabilling IP addresses.

Configure return parameters

Under "Configuration" -> "Informations Techniques" -> "Retour d'information sur la transaction", go to section "DirectLink".

Move all parameters to "Seléctionné" as bellow and save.

Porta-billing configuration

Use PostFinance gateway in Ogone payment processing module on slave.

Connect with ssh to the portabilling slave server and edit the file ‘/home/porta-admin/site_lib/Business/OnlinePayment/Ogone.pm’.

Under the ‘set_fefaults’ subroutine, we have the connection settings to Ogone. The server ‘secure.ogone.com’ must be replaced with ‘e-payment.postfinance.ch’ as bellow.

 

sub set_defaults{

  my $self = shift;

  $self->server('e-payment.postfinance.ch');

  $self->port('443');

  $self->build_subs('test_path');

  $self->build_subs('order_number');

  $self->test_path('/ncol/test/orderdirect.asp');

  $self->path('/ncol/prod/orderdirect.asp');

}

 

Add PostFinance to the Porta-Billing payments systems.

In the slave portabilling server, add a new payment system as follow [link].

Under the login field, enter PostFinance PSID followed by the API user id created before. The both logins must be separated with ‘:’ like ‘PSID:API_userid’.

The password to fill is the API user password created before.

Then, we can set the Payment System for each currencies [link]. Here is an example.

Payments on website

In order to facilitate customer’s payments, it is possible to pay directly from the main website or directly access the payment page through pay.switzernet.com.

The sections bellow describe the main script made for using PayPal and Postfinance on the website.

          Files and folders

There are three new subfolders added to the /public/ directory on Switzernet.com web site. 140819-epay contains the payment page for the customer and 140824-paypal-notification and 140915-postfinance-notification contain the notification system for PayPal and PostFinance.

140819-epay/

├── custom_icon.png

├── images

│   ├── menubar.gif

│   └── switzernet.gif

├── include

│   ├── db.config.php

│   ├── geoiploc.php

│   ├── languages

│   │   ├── get_language.php

│   │   ├── language_DE.php

│   │   ├── language_EN.php

│   │   ├── language_ES.php

│   │   ├── language_FR.php

│   │   └── language_RU.php

│   ├── Mobile-Detect-master

│   │   ├── composer.json

│   │   ├── composer.lock

│   │   ├── examples

│   │   │   ├── demo.php

│   │   │   └── session_example.php

│   │   ├── export

│   │   │   └── exportToJSON.php

│   │   ├── LICENSE.txt

│   │   ├── Mobile_Detect.json

│   │   ├── Mobile_Detect.php

│   │   ├── namespaced

│   │   │   └── Detection

│   │   │       └── MobileDetect.php

│   │   ├── README.md

│   │   └── tests

│   │       ├── BasicsTest.php

│   │       ├── bootstrap.php

│   │       ├── phpunit.xml

│   │       ├── UA_List.inc.php

│   │       ├── UA_List.pending.txt

│   │       ├── ualist.json

│   │       ├── UserAgentTest.php

│   │       └── VendorsTest.php

│   ├── pay.config.php

│   ├── paypal.class.php

│   └── paypal.config.php

├── index.php

├── js

│   ├── parsley.min.js

│   └── parsley_locales

│       ├── de.js

│       ├── en.js

│       ├── es.js

│       ├── fr.js

│       └── ru.js

├── paypalProcess.php

├── postfinanceProcess.php

├── postfinanceTemplate.css

├── postfinanceTemplate.php

└── style

    ├── ie.css

    ├── mobile.css

    ├── parsley.css

    ├── style.css

    └── style2.css

 

140824-paypal-notification/

├── live.php

├── PortaBillingSoapClient.php

└── sandbox.php

 

140915-postfinance-notification

├── index.php

└── PortaBillingSoapClient.php


 

Main payment page

 

[index.php]

CODE

COMMENT

<?

if(!isset($_SESSION)){session_start();}

 

include_once "include/pay.config.php";

 

Session start

 

Including general configuration file.

 

if ( isset($_GET['amount']) ){

  if ( preg_match('/^[0-9]+(\.[0-9]{0,2})?$/', $_GET['amount']) ){

    $price = $_GET['amount'];

  }

}

 

if ( isset($_POST['amount']) ){

  if ( preg_match('/^[0-9]+(\.[0-9]{0,2})?$/', $_POST['amount']) ){

    $price = $_POST['amount'];

  }

}

 

$number = "";

 

if ( isset( $_POST['action'] ) ){

  $_SESSION['action'] = $_POST['action'];

}

if ( isset( $_GET['action'] ) ){

  $_SESSION['action'] = $_GET['action'];

}

 

Getting information posted to this page.

 

 

$debug_IE = TRUE;

$using_ie6 = (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6.') !== FALSE);

 

?>

Debug for displaying on old web browsers

 

<!DOCTYPE html>

<html>

<head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1.0">

  <meta name="apple-mobile-web-app-status-bar-style" content="black">

  <link rel="apple-touch-icon" href="custom_icon.png">

  <meta name="format-detection" content="telephone=no">

<?php if ( $debug_IE ) { ?>

  <meta http-equiv="X-UA-Compatible" content="IE=6" />

<?php } else { ?>

  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />

<?php } ?>

  <meta name="author" content="Nicolas Bondier - Switzernet">

  <link rel="stylesheet" href="../070608-subscribe/pure-min.css">

  <link href="../060801-web/style.css" rel="stylesheet" type="text/css">

  <link href="style/style2.css" rel="stylesheet" type="text/css">

  <link href="style/mobile.css" rel="stylesheet" type="text/css">

  <script type="text/javascript" src="../070608-subscribe/jquery-1.7.2.min.js"></script>

  <script type="text/javascript" src="js/parsley.min.js" ></script>

  <link href="style/parsley.css" rel="stylesheet" type="text/css">

 

HTML begins here.

 

The head content contains information for better displaying on mobile applications and old browser.

 

 

<?php

  if ( isset( $_SESSION['language']['code'] ) && file_exists( "js/parsley_locales/".strtolower($_SESSION['language']['code']).".js") ) {

?>

  <script src="js/parsley_locales/<?= strtolower($_SESSION["language"]["code"]) ?>.js"></script>

  <script type="text/javascript">

    window.ParsleyValidator.setLocale('<?= strtolower($_SESSION["language"]["code"]) ?>');

  </script>

<?php

  }

?>

Getting the localization files (language) for error handling for the customer.

 

 

  <script type="text/javascript">

    function changeLanguage(selectLanguage){

      var lang = selectLanguage.value;

      var form = document.getElementById("formLanguage");

      form.submit();

    }

    function changeCurrency(selectCurrency){

      var value = selectCurrency.options[selectCurrency.selectedIndex].value;

      window.location.href = '?currency_code='+value+'';

    }

 

Some JavaScript functions for submitting language and currency changes.

 

    function getParentElementByTagName( element , tag ){

      while( element.tagName.toLowerCase() != tag.toLowerCase() ){

        element = element.parentNode;

        if (!element.tagName) {

          return;

        }

      }

      return element;

    }

  </script>

 

A function to simplify the selection of a parent element.

 

<!--[if lte IE 8]>

    <link rel="stylesheet" href="style/ie.css" type="text/css" media="screen,projection" />

<![endif]-->

 

Special CSS style sheet for internet explorer.

 

  <script type="text/javascript">

    function initFormAction(){

      var select = document.getElementById("paymentType");

      if ( select !== null ){

        updateFormAction(select);

      }

    }

    function updateFormAction(select){

      var form=document.getElementById("payForm");

      var option = select.options[select.selectedIndex].value;

      var ts = "ts="+Date.now();

      if ( option == "creditcard" ){

        form.action="postfinanceProcess.php?"+ts;

      } else {

        form.action="paypalProcess.php?"+ts;

      }

    }

  </script>

 

Function to update the “action” parameter of the form after having choose the payment method. It changes the “action” parameter to the PostFinance processing script or PayPal processing script.

 

  <!-- Piwik -->

<script type="text/javascript">

  var _paq = _paq || [];

  _paq.push(["trackPageView"]);

  _paq.push(["enableLinkTracking"]);

 

  (function() {

    var u=(("https:" == document.location.protocol) ? "https" : "http") + "://switzernet.com/3/public/120427-site-stats/";

    _paq.push(["setTrackerUrl", u+"piwik.php"]);

    _paq.push(["setSiteId", "1"]);

    var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";

    g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);

  })();

</script>

<!-- End Piwik Code -->

   <title><?= TITLE_PAYMENT_SWITZERNET ?></title>

</head>

 

Piwik script for getting statistics.

 

<body style="" onload="initFormAction()">

  <div id="container">

    <div id="head" style="text-align: center;">

        <table style="">

          <tbody>

            <tr>

              <td align="left">

                <a href="http://www.switzernet.com/">

                <img style="" class="pure-img" src="../060801-web/images/switzernet.gif" alt="Switzernet VoIP téléphonie IP Suisse"></a>

                <img id="calltheworld" class="pure-img" style="margin:10px"

src="../060801-web/images/slogan_6.gif" alt="appeler le monde pour presque rien">

              </td>

              <td style="vertical-align: top;" align="right">

                <div class="pure-form pure-form-aligned">

 

Starting of the body and the page header.

 

                <form id="formLanguage" action="#" method="get">

                  <fieldset>

                    <select name="language" id="language_select" onchange="changeLanguage(this)">

                      <?php

                      foreach ($LANGUAGES as $ISO => $text) {

                        if$_SESSION['language']['code'] == $ISO ){

                          echo "<option value='".$ISO."' selected='selected'>".$text."</option>";

                        } else {

                          echo "<option value='".$ISO."'>".$text."</option>";

                        }

                      }

                      ?>

                    </select>

                  </fieldset>

                </form>

 

Language selection

 

                </div>

              </td>  

            </tr>

          </tbody>

        </table>

    </div>

 

End of page header

 

    <div id="pay_div" style="">

 

      <?php

      if ( $_SERVER['REMOTE_ADDR'] == '46.14.170.24' && FALSE ){

        echo time();

      }

 

Starting of the man content div.

 

      if ( isset( $_SESSION['action'] ) && $_SESSION['action'] == 'cancel' ) {

      ?>

        <h1 style="text-align:center;"><?= H1_PAYMENT_CANCELED ?></h1>

        <table>

          <tr>

            <td><?= TEXT_PAYMENT_CANCELED_1 ?></td>

          </tr>

          <tr style="text-align:center;">

            <td><br><button class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button></td>

          </tr>

        </table>

 

When the action received is cancel (from PayPal or PostFinance), we display the corresponding content.

 

      <?php

        } elseif ( isset( $_SESSION['action'] ) && $_SESSION['action'] == 'paymentok' ){

      ?>

        <h1 style="text-align:center;"><?= H1_PAYMENT_OK ?></h1>

        <table>

          <tr>

            <td><?= TEXT_PAYMENT_OK_1 ?><?= $_SESSION['ItemNumber'] ?><?= TEXT_PAYMENT_OK_2 ?></td>

 

          </tr>

          <tr style="text-align:center;">

            <td><br><button class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button></td>

          </tr>

        </table>

      <?php

 

When the action received is paymentok (from PayPal or PostFinance), we display the corresponding content.

 

        } elseif ( isset( $_SESSION['action'] ) && $_SESSION['action'] == 'paymentpending' ){

      ?>

        <h1 style="text-align:center;"><?= H1_PAYMENT_PENDING ?></h1>

        <table>

          <tr>

            <td><?= TEXT_PAYMENT_PENDING_1 ?></td>

          </tr>

          <tr style="text-align:center;">

            <td><br><button class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button></td>

          </tr>

        </table>

      <?php

 

When the action received is paymentpending (from PayPal), we display the corresponding content.

        } elseif ( isset( $_SESSION['action'] ) && $_SESSION['action'] == 'paymentfailed' ){

      ?>

        <h1 style="text-align:center;"><?= H1_PAYMENT_FAILED ?></h1>

        <table>

          <tr>

            <td><?= TEXT_PAYMENT_FAILED_1 ?></td>

          </tr>

 

          <tr style="text-align:center;">

            <td><br><button class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button></td>

          </tr>

        </table>

      <?php

When the action received is paymentfailed (from PayPal or Postfinance), we display the corresponding content.

 

       } elseif ( isset( $_SESSION['action'] ) && $_SESSION['action'] == 'paymenterror' ){

      ?>

        <h1 style="text-align:center;"><?= H1_PAYMENT_FAILED ?></h1>

        <table>

          <tr>

            <td><?= TEXT_PAYMENT_FAILED_1 ?></td>

          </tr>

          <tr style="text-align:center;">

            <td><br><button class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button></td>

          </tr>

        </table>

      <?php

Error during the payment (from PayPal), we display the corresponding content.

        } elseif ( ( isset( $_SESSION['action'] ) && $_SESSION['action'] == "payment" ) ){

      $number = "";

      if ( isset( $_SESSION["postdata"]["num_part_1"] ) && isset( $_SESSION["postdata"]["num_part_2"] ) ){

        $_SESSION['accountToCredit'] = $_SESSION["postdata"]["num_part_1"]."-".$_SESSION["postdata"]["num_part_2"];

        unset($_SESSION["postdata"]["num_part_1"]);

        unset($_SESSION["postdata"]["num_part_2"]);

      }

      if ( isset( $_SESSION["postdata"]['number'] ) ){

        $_SESSION['accountToCredit'] = $_SESSION["postdata"]['number'];

        unset($_SESSION["postdata"]["number"]);

      }

      $number = $_SESSION['accountToCredit'];

      $number = preg_replace('/[^0-9,]|,[0-9]*$/','',$number);

      $number = preg_replace('/^0([0-9]{9})$/', "41$1", $number);

      if ( ! preg_match('/^41[0-9]{9}$/', $number) ){

      ?>

      <h1 style="text-align:center;"><?= H1_PAYMENT ?></h1>

      <table>

        <tr>

          <td><?= TEXT_INVALID_NUMBER_1 ?><?= $number ?><?= TEXT_INVALID_NUMBER_2 ?></td>

        </tr>

        <tr style="text-align:center;">

            <td><br><button class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button></td>

        </tr>

      </table>

      <?php

        } else {

Text when received an action called payment. It refers to the last page before submitting the payment to PostFinance or PayPal.

 

We get the numbers from different post forms and test if it match a valid number format (41XXXXXXXXX).

 

If the number format is wring we inform with a text.

          $accountFound = FALSE;

          $currency = 'CHF';

          $connection2=mysql_connect(DB2_SERVER.':'.DB2_SERVER_PORT,DB2_SERVER_USERNAME, DB2_SERVER_PASSWORD) or die(mysql_error().' : erreur de connexion a la base de donnee !');

 

          mysql_select_db(DB2_DATABASE) or die("erreur de connexion a la base de donnees");

 

          $sql = "SELECT iso_4217 FROM Accounts WHERE id = '".$number."' LIMIT 1";

          $result = mysql_query($sql,$connection2);

 

If the format is correct, we get the account currency to display it on the web page.

 

          if ( mysql_num_rows($result) == 1 ){

            $accountFound = TRUE;

            $value = mysql_fetch_object($result);

            if ( isset( $currencyNotations[$value->iso_4217] ) ){

              $currency = $value->iso_4217;

            } else {

              $currency = 'CHF';

            }

            $_SESSION['currency_code'] = $currency;

          } else {

If we find the currency, then we set in session.

            include("include/geoiploc.php");

            $ip = $_SERVER["REMOTE_ADDR"];

            if ( getCountryFromIP($ip) == 'CH' ){

              $_SESSION['currency_code'] = 'CHF';

            } else {

              $_SESSION['currency_code'] = 'EUR';

            }

          }

 

          mysql_close($connection2);

 

          $_SESSION['phone_number'] = $number;

 

          if ( $_SESSION['currency_code'] != '' ){

            $currency = $_SESSION['currency_code'];

          }

 

          ?>

Else, it means no account have been found, we try to find it with the IP address of the customer.

The library used for locating the country of the IP can be found here http://chir.ag/projects/geoiploc

 

          <h1 style="text-align:center;"><?= H1_PAYMENT ?></h1>

          <form data-parsley-validate class="pure-form" method="post" action="paypalProcess.php" id="payForm"><br>

            <table>

              <tr>

                <td class="label" width="40%">

                  <label><?= TEXT_SIP_ACCOUNT ?></label>

                </td>

                <td>

                  <?= $number ?>

                </td>

              </tr>

              <tr class="parsleyError">

                <td></td>

              </tr>

              <tr>

                <td class="label">

                  <label for="amountInput"><?= TEXT_AMOUNT ?> <span style="color: #777;font-size:12px;white-space:nowrap;">(min. 5 <?= $currency ?>)</span></label>

                </td>

                <td class="td_input">

                  <?php if ( $accountFound ){ ?>

                    <?php if ( $layoutType != 'classic' ) { ?>

                      <input  class="input_text" data-parsley-errors-container="#amountError" name="itemprice" style="width:80px;text-align:left;" min="5" size="10" placeholder="XXX.XX" required value="<?= $_SESSION['postdata']['amount'] ?>" />

                    <?php } else { ?>

                      <input id="amountInput" class="input_text" data-parsley-errors-container="#amountError" data-parsley-type="number" name="itemprice" style="text-align:left;" min="5" type="text" size="10" placeholder="XXX.XX" required value="<?= $_SESSION['postdata']['amount'] ?>" />

                    <?php } ?>

                    <span style="color: #777;font-size:14px;white-space:nowrap;">&nbsp;&nbsp;<?= $currency ?></span>

                  <?php } else { ?>

                    <?php if ( $layoutType != 'classic' ) { ?>

                      <input  class="input_text" data-parsley-errors-container="#amountError" name="itemprice" style="width:50px;text-align:left;" min="5" size="10" placeholder="XXX.XX" required value="<?= $_SESSION['postdata']['amount'] ?>" />

                    <?php } else { ?>

                      <input id="amountInput" class="input_text" data-parsley-errors-container="#amountError" data-parsley-type="number" name="itemprice" style="text-align:left;" min="5" type="text" size="10" placeholder="XXX.XX" required value="<?= $_SESSION['postdata']['amount'] ?>" />

                    <?php } ?>&nbsp;

                        <select data-parsley-errors-container="#amountError" name="currency" onchange="changeCurrency(this)" changeCurrency>

                          <?php

                          foreach ($currencyNotations as $key => $value) {

                            $selected = "";

                            if ( $_SESSION['currency_code'] == $key ){ $selected = ' selected="selected" ';}

                            echo "<option value='".$key."' ".$selected.">".$key."</option>";

                          }

                          ?>

                        </select>

                  <?php } ?>

                </td>

              </tr>

              <tr class="parsleyError">

                <td id="amountError" colspan="2"></td>

              </tr>

              <tr>

                <?php if ( $currency == 'CHF' ){ ?>

                <td class="label">

                  <label for="paymentType"><?= TEXT_PAIEMENT_METHOD ?></label>

                </td>

                <td>

                  <select id="paymentType" onchange="updateFormAction(this)" name="paiementType">

                    <option value="creditcard" selected="selected"><?= TEXT_CREDIT_CARD ?></option>

                    <option value="paypal" ><?= TEXT_PAYPAL ?></option>

                  <select>

                </td>

                <?php } else { ?>

                <td>

                  <input type="hidden" name="paiementType" value="paypal" />

                </td>

                <?php } ?>

              </tr>

              <tr>

                <td colspan="3" style="text-align:center;"><br>

                  <button type='button' class="pure-button" onclick="window.location.href='<?= $WEBURL ?>?action=number'"><?= BUTTON_BACK ?></button>

                  <input type='submit' name="submitbutt" class="pure-button pure-button-primary" value="<?= BUTTON_PAY ?>"/>

                </td>

              </tr>

            </table>

            <input type="hidden" name="number" value="<?= $number ?>" />

          </form>

          <?php

      }

 

Here we display the final payment page before the processor. It permits to select the

 

 

The final form for selecting the payment processor and amount.

 

 

 

      } else {

      ?>

        <h1 style="text-align:center;"><?= H1_PAYMENT ?></h1>

        <form data-parsley-validate class="pure-form" method="post" action="#"><br>

        <table>

          <tr>

            <td class="label">

              <label for="num_part_1"><?= TEXT_SIP_ACCOUNT ?></label>

            </td>

            <td class="td_input" >

 

             

If action parameter is not defined or is not in the list of action triggered before, we display the input fields for selecting the account to credit.

 

          <select data-parsley-errors-container="#numberError1" name="num_part_1" id="num_part_1" required>

            <option value="" >---</option>

  <?php

  foreach ($pref1_pref2 as $id_pref => $prefixes){

    if ( $prefixes[0]==$part1 && $prefixes[1]==$part2 && $found=="" ){

      $found=$id_pref;

    }

  }

  if ($found==""){

    foreach ($pref1_pref2 as $id_pref => $prefixes){

      if ($prefixes[0]==$part1){

        $found=$id_pref;

      }

    }

  }

  foreach ($pref1_pref2 as $id_pref => $prefixes){

    echo '<option value="'.$prefixes[0].'-'.$prefixes[1].'" ';

    if ( $id_pref==$found ) {

      echo "selected = \"selected\"";  

    }

    echo '>'.$prefixes[0].'-'.$prefixes[1].'</option>'."\n";

  }

  ?>

          </select>

 

Selection of the prefixes.

 

            </td>

            <td class="td_input" >

              <?php if ( $layoutType != 'classic' ) { ?>

                <input class="input_text" data-parsley-errors-container="#numberError2" style="width:55px;" name="num_part_2" type="number" data-parsley-length="[4, 4]" size="4" placeholder="XXXX" value="<?= $part3 ?>" required/>

              <?php } else { ?>

                <input class="input_text" data-parsley-errors-container="#numberError2" data-parsley-type="number" data-parsley-length="[4, 4]" name="num_part_2" type="text" maxlength="4" size="5" placeholder="XXXX" value="<?= $part3 ?>" required/>

              <?php } ?>

            </td>

          </tr>

 

Selection of the last 4 digits.

 

          <tr class="parsleyError">

            <td></td>

            <td id="numberError1"></td>

            <td id="numberError2"></td>

          </tr>

 

This is some hidden cells for displaying error in input cells.

 

          <tr>

            <td colspan="3" style="text-align:center;"><br>

              <input type="submit" name="submitbutt" class="pure-button pure-button-primary" value="<?= BUTTON_CONTINUE ?>"/>

            </td>

          </tr>

        </table>

        <input type="hidden" name="action" value="payment" />

        <input type="hidden" name="itemname" value="Account crediting" />

        <input type="hidden" name="itemQty" value="1" />

        <input type="hidden" name="itemdesc" value="Credit your Switzernet account with credit card or paypal." />

      </form>

<?php } ?>

    </div>

 

Button for validating the form and continuing to last page.

 

    <?php if ( $layoutType != 'classic' ){ ?>

    <footer>

    <?php } else { ?>

    <div id="footer_div">

    <?php } ?>

      <center>

        <?php

        if ( $layoutType != 'classic' ){

          echo '<hr style="color: #eee;border: 0;width: 90%;height: 3px;background-color: #eee;">';

        } else { ?>

        <br>

        <br>

        <br>

        <?php } ?>

        <?php if ( $_SESSION['currency_code'] == 'CHF' || $_SESSION['action'] != 'payment' ){ ?>

          <a href="https://www.postfinance.ch/pf/content/fr.html" target="_blank"><img height="30" src="/public/060801-web/images/logoPoste.gif" border="0"></a>&nbsp;&nbsp;

          <a href="http://www.mastercard.com/" target="_blank"><img height="30" src='/public/060801-web/images/mastercard.gif' border="0"></a>&nbsp;&nbsp;

          <a href="http://www.visa.com/" target="_blank"><img height="30" src='/public/060801-web/images/visa.gif' border="0"></a>&nbsp;&nbsp;

          <a href="https://www.paypal.com/fr/webapps/mpp/paypal-popup" title="PayPal Comment Ca Marche" onclick="javascript:window.open('https://www.paypal.com/fr/webapps/mpp/paypal-popup','WIPaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700'); return false;"><img height="30" src="https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg" border="0" alt="PayPal Logo" /></a>

        <?php } else { ?>

          <a href="https://www.paypal.com/fr/webapps/mpp/paypal-popup" title="PayPal Comment Ca Marche" onclick="javascript:window.open('https://www.paypal.com/fr/webapps/mpp/paypal-popup','WIPaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700'); return false;"><img style="width:290px;" src="https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_moyens_paiement_fr.jpg" border="0" alt="PayPal Acceptance Mark" /></a>

        <?php } ?>

      </center>

    <?php if ( $layoutType != 'classic' ){ ?>

    </footer>

    <?php } else { ?>

    </div>

    <?php } ?>

  </div>

Footer with logos of the available payment methods.

</body>

</html>

 

End of the html

 

<?php

 

function pref1_pref2(){

  $connection = mysql_connect(DB1_SERVER,DB1_SERVER_USERNAME,DB1_SERVER_PASSWORD, TRUE);

  mysql_select_db(DB1_DATABASE, $connection);

  $prefs=array();

  $sql = "SELECT id_prefix, prefix1, prefix2 FROM prefixes";

  $req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());

  while($prefix = mysql_fetch_assoc($req)){

    $prefs[$prefix["id_prefix"]] = array(ereg_replace("^41","0",$prefix["prefix1"]),$prefix["prefix2"]);

  }

  mysql_close($connection);

  return $prefs;

}

 

Function for getting the prefixes from

 

function layoutTypes(){

  return array('classic', 'mobile', 'tablet');

}

 

function initLayoutType(){

  // Safety check.

  if (!class_exists('Mobile_Detect')) { return 'classic'; }

  $detect = new Mobile_Detect;

  $isMobile = $detect->isMobile();

  $isTablet = $detect->isTablet();

  $layoutTypes = layoutTypes();

 

  // Set the layout type.

  if ( isset($_GET['layoutType']) ) {

    $layoutType = $_GET['layoutType'];

  } else {

    if (empty($_SESSION['layoutType'])) {

      $layoutType = ($isMobile ? ($isTablet ? 'tablet' : 'mobile') : 'classic');

    } else {

      $layoutType$_SESSION['layoutType'];

    }

  }

 

  // Fallback. If everything fails choose classic layout.

  if ( !in_array($layoutType, $layoutTypes) ) { $layoutType = 'classic'; }

 

  // Store the layout type for future use.

  $_SESSION['layoutType'] = $layoutType;

 

  return $layoutType;

}

?>

 

Function for detecting mobile devices. This is required for all displaying differences added to the html and CSS.

 

 

 

PayPal

Process PayPal payments

[paypalProcess.php]

CODE

COMMENT

<?php

 

if(!isset($_SESSION)){session_start();}

 

include_once("include/pay.config.php");

include_once("include/paypal.config.php");

include_once("include/paypal.class.php");

 

Starting session and including configuration files and a PayPal class for processing the payment easier.

 

$paypalmode = ($PayPalMode=='sandbox') ? '.sandbox' : '';

Defining the string for the PayPal URL to reach in case of we are using the sandbox account or the live account.

 

$PaypalLocalCode = 'CH';

if ( isset( $defaultLocale[$PayPalCurrencyCode] ) ){

  $PaypalLocalCode = $defaultLocale[$PayPalCurrencyCode];

}

 

The PayPal variable to define the localization to display.

The available localization codes are in the paypal.config.php file.

 

if($_POST) //Post Data received from product list page.

{

 

I data has been submitted to this page with POST.

 

$number = $_POST['number'];

 

if ( ! preg_match('/^41[0-9]{9}$/', $number) ){

  die ("wrong number format $number");

}

 

We get the VOIP number to credit and verify the format.

 

$credit = "";

if ( isset($_POST['itemprice']) ){

  $credit = str_replace(',', '.', $_POST['itemprice']);

  if ( ! preg_match('/^[0-9]+(\.[0-9]{0,2})?$/', $credit ) ){

    die ("wrong amount format $credit");

  }

}

 

We get the amount the customer wants to credit on his account.

 

$ItemName     = "Credit compte"; //Item Name

$ItemPrice     = $credit; //Item Price

$ItemNumber   = $number; //Item Number

$ItemDesc     = "Switzernet account crediting with credit card or paypal."; //Item Number

$ItemCustomDesc = "SIP_account:".$number;

$ItemQty       = 1; // Item Quantity

 

Main parameters we have to set for account crediting.

 

$ItemTotalPrice = ($ItemPrice*$ItemQty); //(Item Price x Quantity = Total) Get total amount of product;

 

//Grand total including all tax, insurance, shipping cost and discount

$GrandTotal = ($ItemTotalPrice + $TotalTaxAmount + $HandalingCost + $InsuranceCost + $ShippinCost + $ShippinDiscount);

 

//Parameters for SetExpressCheckout, which will be sent to PayPal

$padata =   '&METHOD=SetExpressCheckout'.

      '&RETURNURL='.urlencode($PayPalReturnURL).

      '&CANCELURL='.urlencode($PayPalCancelURL).

      '&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("SALE").

     

      '&L_PAYMENTREQUEST_0_NAME0='.urlencode($ItemName).

      '&L_PAYMENTREQUEST_0_NUMBER0='.urlencode($ItemNumber).

      '&L_PAYMENTREQUEST_0_DESC0='.urlencode($ItemDesc).

      '&L_PAYMENTREQUEST_0_AMT0='.urlencode($ItemPrice).

     

      '&NOSHIPPING=1'. //set 1 to hide buyer's shipping address, in-case products that does not require shipping

     

      '&PAYMENTREQUEST_0_ITEMAMT='.urlencode($ItemTotalPrice).

      '&PAYMENTREQUEST_0_TAXAMT='.urlencode($TotalTaxAmount).

      '&PAYMENTREQUEST_0_SHIPPINGAMT='.urlencode($ShippinCost).

      '&PAYMENTREQUEST_0_HANDLINGAMT='.urlencode($HandalingCost).

      '&PAYMENTREQUEST_0_SHIPDISCAMT='.urlencode($ShippinDiscount).

      '&PAYMENTREQUEST_0_INSURANCEAMT='.urlencode($InsuranceCost).

      '&PAYMENTREQUEST_0_CUSTOM='.urlencode($ItemCustomDesc).

      '&PAYMENTREQUEST_0_AMT='.urlencode($GrandTotal).

      '&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($PayPalCurrencyCode).

      '&LOCALECODE='.$PaypalLocalCode . //PayPal pages to match the language on your website.

      '&LOGOIMG=https://slave.switzernet.com:8444/brandpane/logo-switzernet-com-2.png'. //site logo

      '&LANDINGPAGE=Billing'.    //Show crdit card

      '&SOLUTIONTYPE=Sole'.    //Show crdit card

      '&USERSELECTEDFUNDINGSOURCE=CreditCard'.

      '&CARTBORDERCOLOR=6699FF'. //border color of cart

      '&ALLOWNOTE=0';

     

This is the part for preparing the SetExpressCheckout method.

A full documentation of the parameters can be found on PayPal developer website [link].

 

      ############# set session variable we need later for "DoExpressCheckoutPayment" #######

      $_SESSION['ItemName']     =  $ItemName; //Item Name

      $_SESSION['ItemPrice']     =  $ItemPrice; //Item Price

      $_SESSION['ItemNumber']   =  $ItemNumber; //Item Number

      $_SESSION['ItemDesc']     =  $ItemDesc; //Item Description

      $_SESSION['ItemCustomDesc']   =  $ItemCustomDesc; // Item Customer Description

      $_SESSION['ItemQty']       =  $ItemQty; // Item Quantity

      $_SESSION['ItemTotalPrice']   =  $ItemTotalPrice;

      $_SESSION['TotalTaxAmount']   =  $TotalTaxAmount;

      $_SESSION['HandalingCost']   =  $HandalingCost;

      $_SESSION['InsuranceCost']   =  $InsuranceCost;

      $_SESSION['ShippinDiscount']   =  $ShippinDiscount;

      $_SESSION['ShippinCost']   =   $ShippinCost;

      $_SESSION['GrandTotal']   =  $GrandTotal;

 

In the same time, we save the data in the session.

 

  $paypal= new MyPayPal();

  $httpParsedResponseAr = $paypal->PPHttpPost('SetExpressCheckout', $padata, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);

 

Executing the SetExpressCheckOut method to obtain the PayPal token.

 

  if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {

    $paypalurl ='https://www'.$paypalmode.'.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].'';

    header('Location: '.$paypalurl);

 

If the PayPal answer is success, we redirect the user to PayPal with the received token in the URL.

 

  } else {

    echo '<div style="color:red"><b>Error : </b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';

    echo '<pre>';

    //print_r($httpParsedResponseAr);

    echo '</pre>';

  }

}

 

Else we show the error message.

 

if(isset($_GET["token"]) && isset($_GET["PayerID"]))

 

  $token = $_GET["token"];

  $payer_id = $_GET["PayerID"];

 

  //get session variables

  $ItemName          = $_SESSION['ItemName'];

  $ItemPrice         = $_SESSION['ItemPrice'] ;

  $ItemNumber        = $_SESSION['ItemNumber'];

  $ItemDesc          = $_SESSION['ItemDesc'];

  $ItemCustomDesc    = $_SESSION['ItemCustomDesc'];

  $ItemQty           = $_SESSION['ItemQty'];

  $ItemTotalPrice    = $_SESSION['ItemTotalPrice'];

  $TotalTaxAmount    = $_SESSION['TotalTaxAmount'];

  $HandalingCost     = $_SESSION['HandalingCost'];

  $InsuranceCost     = $_SESSION['InsuranceCost'];

  $ShippinDiscount   = $_SESSION['ShippinDiscount'];

  $ShippinCost       = $_SESSION['ShippinCost'];  $GrandTotal       = $_SESSION['GrandTotal'];

 

When the user confirmed the payment, it used the ReturnURL we set in the SetExpressCheckout method witch is the same page. We receive a token and a Payer ID of the DoExpressCheckout method.

 

We haven’t received the payment yet.

 

We also get all the session variables.

 

  $padata =   '&TOKEN='.urlencode($token).

    '&PAYERID='.urlencode($payer_id).

    '&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("SALE").

    '&L_PAYMENTREQUEST_0_NAME0='.urlencode($ItemName).

    '&L_PAYMENTREQUEST_0_NUMBER0='.urlencode($ItemNumber).

    '&L_PAYMENTREQUEST_0_DESC0='.urlencode($ItemDesc).

    '&L_PAYMENTREQUEST_0_AMT0='.urlencode($ItemPrice).

    '&PAYMENTREQUEST_0_CUSTOM='.urlencode($ItemCustomDesc).

    '&PAYMENTREQUEST_0_ITEMAMT='.urlencode($ItemTotalPrice).

    '&PAYMENTREQUEST_0_TAXAMT='.urlencode($TotalTaxAmount).

    '&PAYMENTREQUEST_0_SHIPPINGAMT='.urlencode($ShippinCost).

    '&PAYMENTREQUEST_0_HANDLINGAMT='.urlencode($HandalingCost).

    '&PAYMENTREQUEST_0_SHIPDISCAMT='.urlencode($ShippinDiscount).

    '&PAYMENTREQUEST_0_INSURANCEAMT='.urlencode($InsuranceCost).

    '&PAYMENTREQUEST_0_AMT='.urlencode($GrandTotal).

    '&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($PayPalCurrencyCode);

 

Preparing the data for DoExpressCheckout method.

 

 

  //We need to execute the "DoExpressCheckoutPayment" at this point to Receive payment from user.

  $paypal= new MyPayPal();

  $httpParsedResponseAr = $paypal->PPHttpPost('DoExpressCheckoutPayment', $padata, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);

 

Executing the DoExpressCheckout method with the same parameters.

 

  //Check if everything went ok..

  if ( "SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {

 

If the DoExpressCheckout method succeed …

 

   if('Completed' == $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]) {

     header('Location: '. $ReturnURL ."?action=paymentok&tid=". $httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);

 

And the status of payment is Completed we redirect the customer to the corresponding page.

 

   } elseif('Pending' == $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]) {

     header('Location: '. $ReturnURL ."?action=paymentpending&tid=". $httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);

   }

 

And the status of payment is Pending we redirect the customer to the corresponding page.

 

   $padata =   '&TOKEN='.urlencode($token);

   $paypal= new MyPayPal();

   $httpParsedResponseAr = $paypal->PPHttpPost('GetExpressCheckoutDetails', $padata, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);

 

   if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {

     header('Location: ' . $ReturnURL . "?action=paymentok &tid=".$httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);

   } else {

     header('Location: ' . $ReturnURL . "?action=paymentfailed&tid=".$httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);

   }

  } else {

   header('Location: '.$ReturnURL."?action=paymenterror&tid=" . $httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);

  }

}

 

 

We can also get some more information with the GetExpressCheckoutDetails method.

 

?>

 

 

PayPal payment notifications and update payment on billing

[live.php]

CODE

COMMENT

<?php

 

  $SOAP_user = 'xxxxxx';

  $SOAP_password = 'xxxxxx';

  $sandbox = FALSE;

 

SOAP login and password.

 

 

 

  include "PortaBillingSoapClient.php";

 

A PHP library for the SOAP connection to porta-billing.

 

  // Send an empty HTTP 200 OK response to acknowledge receipt of the notification

  header('HTTP/1.1 200 OK');

 

When the page is called, we send a 200 OK header to PayPal to inform we got the payment notification. This way, PayPal will not resend the message.

 

  $item_name        = $_POST['item_name1'];

  $item_number      = $_POST['item_number1'];

  $payment_status   = $_POST['payment_status'];

  $payment_amount   = $_POST['mc_gross'];

  $payment_currency = $_POST['mc_currency'];

  $receiver_email   = $_POST['receiver_email'];

  $payer_email      = $_POST['payer_email'];

  $transaction_id   = $_POST['txn_id'];

  $custom           = $_POST['custom'];

 

We get the required data from PayPal to process the payment on Portabilling.

 

 

  $mail_To      = "cash@switzernet.com";

  $mail_From    = "PayPal_IPN@switzernet.com";

  $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";

 

Some variables for all the emails that will be sent to cash [at] switzernet.com.

 

  if ( $sandbox == TRUE ){

    $payment_currency = 'CHF';

    $PayPalURL = "www.sandbox.paypal.com";

    $mail_To   = "developer@domain.com";

 

    $mail_Header = "";

    $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

    $mail_Header .= 'Reply-To: '.$mail_To                                                           . "\r\n";

    $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                       . "\r\n";

    $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                                 . "\r\n";

    $mail_Subject = "PayPal new payment notification arrived";

 

    $mail_Body    = "Notification details.\n\n";

 

    foreach ($_POST as $key => $value) {

      $mailreq .= "$key = $value\n";

      $mail_Body  .= "$key:$value\n";

    }

    $mail_Body   .= $mail_Footer;

    mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

  } else {

    $PayPalURL = "www.paypal.com";

  }

 

This part set up variables when testing in sandbox mode.

 

We also send an email with all the data send by PayPal for verification.

 

  $message_id_prefix = $transaction_id . '.' . $item_number;

 

A unique message id is generated. We need to save it for keeping a thread in our mailboxes.

 

  // Build the required acknowledgement message out of the notification just received

  $req = 'cmd=_notify-validate';

  $mailreq = "";

 

  foreach ($_POST as $key => $value) {         // Loop through the notification NV pairs

    $mailreq .= "$key = $value\n";

    $value = urlencode(stripslashes($value));

    $req  .= "&$key=$value";

  }

 

We build the acknowledgement message with all parameters sent by PayPal.

 

  // Set up the acknowledgement request headers

  $header  = "POST /cgi-bin/webscr HTTP/1.1\r\n";

  $header .= "Host: ".$PayPalURL."\r\n";

  $header .= "Content-Type: application/x-www-form-urlencoded\r\n";

  $header .= "Connection: close\r\n";

  $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

 

The header for to send to PayPal.

 

  // Open a socket for the acknowledgement request

  $fp = fsockopen('ssl://'.$PayPalURL, 443, $errno, $errstr, 30);

 

  // Send the HTTP POST request back to PayPal for validation

  fputs($fp, $header . $req);

 

The answer message is posted to PayPal server through secured connection with all the parameters we have received.

 

  while (!feof($fp)) {                     // While not EOF

 

When posting, we read the content of the message send by PayPal until the end of file of the socket.

 

    if (strcmp (chomp($res), "VERIFIED") == 0) {  // Response contains VERIFIED - process notification

 

      // Authentication protocol is complete - OK to process notification contents

      $mail_Header = "";

      $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

      $mail_Header .= 'Reply-To: '.$mail_To                                                           . "\r\n";

      $mail_Header .= 'Message-Id: <'$message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

      $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                       . "\r\n";

      $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                                 . "\r\n";

 

      $mail_Subject = "PayPal new payment notification / account:".$item_number." / transaction id:".$transaction_id." / status:".$payment_status."";

 

      $mail_Body    = "A new transaction as been processed by paypal.\n";

      $mail_Body   .= "\n";

      $mail_Body   .= "**********************************************\n";

      $mail_Body   .= "*          Transaction details               *\n";

      $mail_Body   .= "**********************************************\n";

      $mail_Body   .= "\n";

      $mail_Body   .= "item_name        : " . $item_name          . "\n";

      $mail_Body   .= "item_number      : " . $item_number        . "\n";

      $mail_Body   .= "payment_status   : " . $payment_status     . "\n";

      $mail_Body   .= "payment_amount   : " . $payment_amount     . "\n";

      $mail_Body   .= "payment_currency : " . $payment_currency   . "\n";

      $mail_Body   .= "receiver_email   : " . $receiver_email     . "\n";

      $mail_Body   .= "payer_email      : " . $payer_email        . "\n";

      $mail_Body   .= "transaction_id   : " . $transaction_id     . "\n";

      $mail_Body   .= "custom trx name  : " . $custom             . "\n";

      $mail_Body   .= $mail_Footer;

 

      mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

      file_put_contents("log/".$message_id_prefix.".log","step:transaction_auth ok\n",FILE_APPEND);

 

      // Possible processing steps for a payment include the following:

      // Check that the payment_status is Completed

 

If PayPal answers VERIFIED, it means the received parameters match with a PayPal payment for which we received a notification.

 

We send an email to @cash with the transaction details.

 

      if ( $payment_status == 'Completed' ){

 

          $ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account');

          $session_id = $ServiceAccount->_login($SOAP_user, $SOAP_password);

          $ServiceAccount->_setSessionId($session_id);

 

          // Getting i_customer

          $GetAccountInfoRequest = array( 'id' => $item_number );

          $GetAccountInfoResponse = $ServiceAccount->get_account_info($GetAccountInfoRequest);

 

          $i_customer = '';

 

 

          file_put_contents("log/" . $message_id_prefix . ".log","step:payment_completed ok\n",FILE_APPEND);

 

 

If the payment is Completed, according to the initial submit from PayPal, we connect to portabilling to the SOAP account API to search the customer account to update with the payment.

 

          if ( !isset($GetAccountInfoResponse->account_info) ){ // Account does not exist

 

            $mail_Subject = "[account_not_found] PayPal new payment notification / account:".$item_number." / transaction id:".$transaction_id." / status:".$payment_status."";

 

            $mail_Body = "";

            $mail_Body .= "The tansaction could not be done because the account '".$item_number."' could not be found.\n\n";

            $mail_Body .= "Please open or check the account '".$item_number."' and manually add the payment.\n\n";

            $mail_Body .= "Once the payment has been manually entered, please answer this email with '[done] PayPal new ...'.\n\n";

            $mail_Body .= $mail_Footer;

 

            $mail_Header = "";

            $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

      $mail_Header .= 'Reply-To: '.$mail_To                                                           . "\r\n";

            $mail_Header .= 'Message-Id: <'$message_id_prefix . '.account_not_found@ipn.switzernet.com>' . "\r\n";

            $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

            $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                   . "\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, $mail_Subject, $mail_Body, $mail_Header);

 

            file_put_contents("log/".$message_id_prefix.".log","step:account_exist no\n",FILE_APPEND);

 

 

If the account is not found, we send an email replying the precedent email, informing the account could not be found.

 

 

          } else {

           

            $i_customer = $GetAccountInfoResponse->account_info->i_customer;

            $account_currency = $GetAccountInfoResponse->account_info->iso_4217;

 

            file_put_contents("log/".$message_id_prefix.".log","step:account_exist ok\n",FILE_APPEND);

 

Else, if the account is found, we get the ID of the customer and the currency.

 

            if ( $payment_currency != $account_currency ){

 

              file_put_contents("log/".$message_id_prefix.".log","step:currency_match no\n",FILE_APPEND);

 

 

              $mail_Subject = "[wrong_currency] PayPal new payment notification / account:".$item_number." / transaction id:".$transaction_id." / status:".$payment_status."";

 

              $mail_Body = "";

              $mail_Body .= "The tansaction could not be processed because the payment currency '".$payment_currency."' is not the same as the '".$item_number."' account's currency '".$account_currency."'.\n\n";

              $mail_Body .= "Please convert and manually process the payment to the customer account of voip account '".$item_number."'.\n\n";

              $mail_Body .= "Once the payment has been manually made, please answer this email with '[done] PayPal new ...'.\n\n";

              $mail_Body .= $mail_Footer;

 

              $mail_Header = "";

              $mail_Header .= 'From: ' . $mail_From                                                         . "\r\n";

      $mail_Header .= 'Reply-To: '.$mail_To                                                           . "\r\n";

              $mail_Header .= 'Message-Id: <'$message_id_prefix . '.wrong_currency@ipn.switzernet.com>'  . "\r\n";

              $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

              $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

              $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                     . "\r\n";

              $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                               . "\r\n";

 

              mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

If the customer currency does not match the currency of the payment, we send an email informing of this and do not process the payment.

 

            } else {

 

              file_put_contents("log/".$message_id_prefix.".log","step:currency_match ok\n",FILE_APPEND);

 

              $ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer');

              $session_id = $ServiceCustomer->_login($SOAP_user, $SOAP_password);

              $ServiceCustomer->_setSessionId($session_id);

 

              $MakeCustomerTransactionRequest = array(

                'i_customer'            => $i_customer,

                'visible_comment'       => 'paiement paypal',

                'internal_comment'      => 'paiement paypal',

                'action'                => 'Manual payment',

                'amount'                => $payment_amount,

                'suppress_notification' => 0,

                'transaction_id'        => $transaction_id,

                'h323_conf_id'          => ''

              );

 

If currencies match, we prepare a payment request on portabilling on the SOAP customer API.

 

              try{ // do the transaction

 

                $MakeCustomerTransactionResponse = $ServiceCustomer->make_transaction($MakeCustomerTransactionRequest);

 

                file_put_contents("log/".$message_id_prefix.".log","step:make_transaction ok\n",FILE_APPEND);

 

                $mail_Subject = "[done] PayPal new payment notification / account:".$item_number." / transaction id:".$transaction_id." / status:".$payment_status."";

 

                $mail_Body = "";

                $mail_Body .= "A payment of ".$payment_amount." ".$payment_currency." has been processed on account '".$item_number."'\n\n";

                $mail_Body .= "YOU HAVE NOTHING TO DO\n\n";

                $mail_Body .= "Transaction result :\n";

                $mail_Body .= "amount     :".$payment_amount."\n";

                $mail_Body .= "new balace :".$MakeCustomerTransactionResponse->balance."\n";

                $mail_Body .= "id of cdr  :".$MakeCustomerTransactionResponse->i_xdr . "\n";

                $mail_Body .= $mail_Footer;

 

                $mail_Header = "";

                $mail_Header .= 'From: ' . $mail_From                                                         . "\r\n";

      $mail_Header .= 'Reply-To: '.$mail_To                                                           . "\r\n";

                $mail_Header .= 'Message-Id: <'$message_id_prefix . '.done@ipn.switzernet.com>'            . "\r\n";

                $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

                $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

                $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                     . "\r\n";

                $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                               . "\r\n";

 

                mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

To process the payment, we use the “try { . . . } catch { . . . }” method to avoid the PHP script to exit on an error.

 

 

 

              } catch (SoapFault $fault) {

 

                file_put_contents("log/".$message_id_prefix.".log", "step:make_transaction failed\n",FILE_APPEND);

 

                $mail_Subject = "[payment_error] PayPal new payment notification / account:".$item_number." / transaction id:".$transaction_id." / status:".$payment_status."";

 

                $mail_Body = "";

                $mail_Body .= "An error occured during the payment on customer account on porta-billing\n\n";

                $mail_Body .= "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})";

                $mail_Body .= $mail_Footer;

 

                $mail_Header = "";

                $mail_Header .= 'From: ' . $mail_From                                                         . "\r\n";

      $mail_Header .= 'Reply-To: '.$mail_To                                                           . "\r\n";

                $mail_Header .= 'Message-Id: <'$message_id_prefix . '.payment_error@ipn.switzernet.com>'   . "\r\n";

                $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

                $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                 . "\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, $mail_Subject, $mail_Body, $mail_Header);

              }

 

If an error happen, we send an email to cash for informing.

 

              $ServiceCustomer->_logout();

            }

 

Logout from the SOAP customer API.

 

          }

          $ServiceAccount->_logout();

 

Logout from the SOAP account API.

 

      }

 

 

 

    } else if (strcmp ($res, "INVALID") == 0) {

 

      $mail_From    = "IPN@switzernet.com";

      $mail_Subject = "INVALID IPN";

      $mail_Header = 'From: ' . $mail_From . "\r\n" .

      'Reply-To: ' . $mail_To. "\r\n" .

      'X-Mailer: PHP/' . phpversion();

      $mail_Body    = $req;

      mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

    }

  }

 

 

If PayPal return INVALID to our script, we send an email with the information to @cash.

 

  function chomp($string){

    return trim(preg_replace('/\s+/', ' ', $string));

  }

 

Function for deleting bad end of line.

 

?>

 

 

 

PostFinance

Process Postfinance payments

[postfinanceProcess.php]

CODE

COMMENT

<?php

 

if(!isset($_SESSION)){session_start();}

 

$locales = array('FR' => 'fr_FR',

                 'EN' => 'en_EN',

                 'DE' => 'de_DE'

);

 

if ( ! isset( $_SESSION['language']['code'] ) ){

  $_SESSION['language']['code'] = 'FR';

}

 

if ( isset( $_GET['language'] ) && isset( $locales[ $_GET['language'] ] ) ){

  $_SESSION['language']['code'] = $_GET['language'];

}

 

Setting language and locales correspondences for PostFinance payment page.

 

$number = $_POST['number'];

 

if ( ! preg_match('/^41[0-9]{9}$/', $number) ){

  die ("wrong number format $number");

}

 

Verifying the number format.

 

$credit = "";

if ( isset($_POST['itemprice']) ){

  $credit = str_replace(',', '.', $_POST['itemprice']);

  if ( ! preg_match('/^[0-9]+(\.[0-9]{0,2})?$/', $credit ) ){

    die ("wrong amount format $credit");

  }

}

 

Getting the amount the customer want to credit on his account.

 

if ( isset( $_POST['paiementType'] ) && $_POST['paiementType'] == "creditcard" ){

  $orderTotal = $credit;

 

  $params = array('orderID', 'amount', 'currency', 'PSPID', 'Operation', 'logo', 'language', 'paramplus', 'SHASIGN');

 

  usort($params, "cmp");

 

 

  $hashSeed = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

 

  // post account informations

  $data['PSPID'] = "xxxxxxxxxxxxxxxxxxxx";

 

  // payment informations

  $data['orderID'] = htmlentities("VOIP-" . convert_to_0XX_XXX_XXXX($number) );

 

  $data['amount'] = (int)($orderTotal*100. ); // Format the number in integer after being mutliplied by 100 to fit to e-pay requirements

  $data['currency'] = "CHF";

  $data['Operation'] = "SAL";

 

  // view informations

 

  $data['language'] = $locales[ $_SESSION['language']['code'] ];

  $data['logo'] = "https://www.intarnetinc.com/images/switzernet.gif";

  $data['paramplus'] = "numeroSIP=".convert_to_0XX_XXX_XXXX($number);

  $data['TP'] = "http://switzernet.com/public/140819-epay/postfinanceTemplate.php";

 

  $request = "";

 

  // Create the signature

  foreach ($params as $i => $p){

    if (isset($data[$p]))

      $request .= strtoupper($p)."=".$data[$p] . $hashSeed;

  }

  $data['SHASIGN'] = strtoupper(sha1($request));

}

 

 

 

We prepare the parameters to post to PostFinance.

 

To permit to PostFinance to verify the data, we create a string with all defined parameters under the format defined in PostFinance documentation.

 

It is a string of key=value pairs separated with the SHA-IN defined in the PostFinance account. Keys must always be in uppercase.

 

The string must then be hashed. It is the field to post called SHASIGN.

 

 

?>

<html>

<head>

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

  <title></title>

  <script type="text/javascript">

    function postFinancePost(){

      var form=document.getElementById("postfinanceForm");

      form.submit();    

    }

    window.onload = function() {

      postFinancePost();

    };

  </script>

</head>

<body>

<FORM id="postfinanceForm" METHOD=post ACTION="https://e-payment.postfinance.ch/ncol/prod/orderstandard.asp">

<?php

foreach ($params as $i => $p){

  if (isset($data[$p])){

    echo "<INPUT TYPE=hidden name=$p value=\"$data[$p]\">\n";

  }

}

?>

<br/>

<center>

<INPUT TYPE=hidden value="ACCEPT">

</center>

</FORM>

</body>

</html>

 

We create a form with our data and tell the browser to submit it to PostFinance.

 

<?php

 

function convert_to_0XX_XXX_XXXX($number){

  $number = ereg_replace("[^0-9]", "", $number);

  if (ereg('^41[0-9]{9}$',$number)){

    $number=substr_replace(substr_replace(ereg_replace("^41","0",$number),"-",3,0),"-",7,0);

    return $number;

  } elseif ( ereg('^0[0-9]{9}$',$number) ) {

    $number=substr_replace(substr_replace($number,"-",3,0),"-",7,0);

    return $number;

  } else {

    return FALSE;

  }

}

 

 

 

?>

 

Function to convert a phone number to 0XX-XXX-XXXX.

 

Postfinance payment notifications and update payment in portabilling

[index.php]

CODE

COMMENT

<?php

 

$SOAP_user = 'xxxxxxx';

$SOAP_password = 'xxxxxxxxxxxxxxxxxxxxxx';

 

SOAP user and password.

 

$postFinanceSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

 

Postfinance SHA-OUT defined in PostFinance interface.

 

include "PortaBillingSoapClient.php";

 

A PHP library for the SOAP connection to portabilling.

 

$test = FALSE;

 

Test mode is disabled.

 

$mail_To      = "cash@switzernet.com";

$mail_From    = "PostFinance_IPN@switzernet.com";

 

$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";

 

Some variables for all the emails that will be sent to cash [at] switzernet.com.

 

if ( $test == TRUE ){

  $mail_To      = "developer@domain.com";

  $postFinanceSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

  $mail_From    = "TEST_PostFinance_IPN@switzernet.com";

}

 

This part set up variables in testing mode.

 

Secret may not be the same as we use the test account of PostFinance.

 

$message_id_prefix = time() . '-' . md5('postfinance-notification' . $mail_To);

 

A unique message id is generated. We need to save it for keeping a thread in our mailboxes.

 

if ( isset($_POST['SHASIGN']) && $_POST['SHASIGN'] == ogone_hash_parameters_in( $_POST, $postFinanceSecret ) ){

  $mail_Header  = "";

  $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

  $mail_Header .= 'Reply-To: cash@switzernet.com'                                                 . "\r\n";

  $mail_Header .= 'Message-Id: <'$message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

  $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                       . "\r\n";

  $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                                 . "\r\n";

  $mail_Subject = "Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

  $mail_Body    = "";

  $mail_Body   .= "RECEIVED PARAMETER :\n".print_r($_REQUEST,TRUE)."\n";

  $mail_Body   .= $mail_Footer;

 

  mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

If the SHASIGN received by PostFinance is the same as the one we calculated in the ogone_hash_parameters_in function, it means the payment notification is valid.

 

We send an email to @cash with the received request.

 

 

  if ( $_POST['STATUS'] == '9' ){

    $ServiceAccount = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Account');

    $session_id = $ServiceAccount->_login($SOAP_user, $SOAP_password);

    $ServiceAccount->_setSessionId($session_id);

 

    // Getting i_customer

    $GetAccountInfoRequest = array( 'id' => format_account($_POST['numeroSIP']) );

    $GetAccountInfoResponse = $ServiceAccount->get_account_info($GetAccountInfoRequest);

 

In the PostFinance submitted data, the status 9 means the payment is accepted.

 

In the case we connect to portabilling in order to find the account of the customer who paid.

 

    if ( !isset($GetAccountInfoResponse->account_info) ){ // Account does not exist

      $mail_Subject = "[account_not_found] Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

      $mail_Body = "";

      $mail_Body .= "The tansaction could not be done because the account '".$_POST['numeroSIP']."' could not be found.\n\n";

      $mail_Body .= "Please open or check the account '".$_POST['numeroSIP']."' and manually add the payment.\n\n";

      $mail_Body .= "Once the payment has been manually entered, please answer this email with '[done] PostFinance new ...'.\n\n";

      $mail_Body .= $mail_Footer;

 

      $mail_Header = "";

      $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

      $mail_Header .= 'Reply-To: cash@switzernet.com'                                                 . "\r\n";

      $mail_Header .= 'Message-Id: <'$message_id_prefix . '.account_not_found@ipn.switzernet.com>' . "\r\n";

      $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

      $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                   . "\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, $mail_Subject, $mail_Body, $mail_Header);

 

If we cannot find the account, an email is send to @cash informing the account could not be found.

 

    } else {

 

      $i_customer = $GetAccountInfoResponse->account_info->i_customer;

      $account_currency = $GetAccountInfoResponse->account_info->iso_4217;

      if ( $_POST['currency'] != $account_currency ){

        $mail_Subject = "[account_not_found] Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

        $mail_Body = "";

        $mail_Body .= "The tansaction could not be processed because the payment currency '".$_POST['numeroSIP']."' is not the same as the '".$_POST['numeroSIP']."' account's currency '".$account_currency."'.\n\n";

        $mail_Body .= "Please convert and manually process the payment to the customer account of voip account '".$_POST['numeroSIP']."'.\n\n";

        $mail_Body .= "Once the payment has been manually made, please answer this email with '[done] PostFinance new ...'.\n\n";

        $mail_Body .= $mail_Footer;

        $mail_Header = "";

        $mail_Header .= 'From: ' . $mail_From                                                         . "\r\n";

        $mail_Header .= 'Reply-To: cash@switzernet.com'                                               . "\r\n";

        $mail_Header .= 'Message-Id: <'$message_id_prefix . '.wrong_currency@ipn.switzernet.com>'  . "\r\n";

        $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

        $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

        $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                     . "\r\n";

        $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                               . "\r\n";

        mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

Else, we search for the ID of customer and currency of the account before entering the payment.

 

If the currencies do not match, we inform by sending an email to @cash.

 

      } else {

        $ServiceCustomer = new PortaBillingSoapClient('https://slave.switzernet.com:8444', 'Admin', 'Customer');

        $session_id = $ServiceCustomer->_login($SOAP_user, $SOAP_password);

        $ServiceCustomer->_setSessionId($session_id);

        $MakeCustomerTransactionRequest = array(

          'i_customer'            => $i_customer,

          'visible_comment'       => 'e-paiement',

          'internal_comment'      => 'e-paiement postfinance',

          'action'                => 'Manual payment',

          'amount'                => $_POST['amount'],

          'suppress_notification' => 0,

          'transaction_id'        => $_POST['PAYID'],

          'h323_conf_id'          => ''

        );

 

If the currencies match, we connect to the customer service of the SOAP API and prepare the payment request.

 

        try{ // do the transaction

 

          $MakeCustomerTransactionResponse = $ServiceCustomer->make_transaction($MakeCustomerTransactionRequest);

 

          $mail_Subject = "[done] Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

 

          $mail_Body = "";

          $mail_Body .= "A payment of ".$_POST['amount']." ".$_POST['currency']." has been processed on account '".$_POST['numeroSIP']."'\n\n";

          $mail_Body .= "YOU HAVE NOTHING TO DO\n\n";

          $mail_Body .= "Transaction result :\n";

          $mail_Body .= "amount     :".$$_POST['amount']."\n";

          $mail_Body .= "new balace :".$MakeCustomerTransactionResponse->balance."\n";

          $mail_Body .= "id of cdr  :".$MakeCustomerTransactionResponse->i_xdr."\n";

          $mail_Body .= $mail_Footer;

 

          $mail_Header = "";

          $mail_Header .= 'From: ' . $mail_From                                                         . "\r\n";

          $mail_Header .= 'Reply-To: cash@switzernet.com'                                               . "\r\n";

          $mail_Header .= 'Message-Id: <'$message_id_prefix . '.done@ipn.switzernet.com>'            . "\r\n";

          $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

          $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

          $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                     . "\r\n";

          $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                               . "\r\n";

 

          mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

If the transaction executes without exception, we reply to the first email with [done] to confirm the payment has been correctly entered.

 

        } catch (SoapFault $fault) {

 

 

          $mail_Subject = "[payment_error] Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

 

          $mail_Body = "";

          $mail_Body .= "An error occured during the payment on customer account on porta-billing\n\n";

          $mail_Body .= "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})";

          $mail_Body .= $mail_Footer;

 

          $mail_Header = "";

          $mail_Header .= 'From: ' . $mail_From                                                         . "\r\n";

          $mail_Header .= 'Reply-To: cash@switzernet.com'                                               . "\r\n";

          $mail_Header .= 'Message-Id: <'$message_id_prefix . '.payment_error@ipn.switzernet.com>'   . "\r\n";

          $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                 . "\r\n";

          $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                 . "\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, $mail_Subject, $mail_Body, $mail_Header);

        }

        $ServiceCustomer->_logout();

      }

    }

    $ServiceAccount->_logout();

 

Else the error message is sent to @cash.

 

  } elseif ( $_POST['STATUS'] == '1' ) {

    $mail_Header = "";

    $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

    $mail_Header .= 'Reply-To: cash@switzernet.com'                                                 . "\r\n";

    $mail_Header .= 'Message-Id: <'$message_id_prefix . '.unknown_status@ipn.switzernet.com>'    . "\r\n";

    $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

    $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

    $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                       . "\r\n";

    $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                                 . "\r\n";

    $mail_Subject = "[payment cancelled] Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

    $mail_Body    = "The payment has been cancelled by customer\n\n";

    $mail_Body   .= "YOU HAVE NOTHING TO DO\n\n";

    $mail_Body   .= "RECEIVED PARAMETER :\n".print_r($_REQUEST,TRUE)."\n";

    $mail_Body   .= $mail_Footer;

    mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

Payment cancellation notice when the status is 1: the payment has been cancelled by the payer.

 

 

  } else {

    $mail_Header = "";

    $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

    $mail_Header .= 'Reply-To: cash@switzernet.com'                                                 . "\r\n";

    $mail_Header .= 'Message-Id: <'$message_id_prefix . '.unknown_status@ipn.switzernet.com>'    . "\r\n";

    $mail_Header .= 'References: <' . $message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

    $mail_Header .= 'In-Reply-To: <'. $message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

    $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                       . "\r\n";

    $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                                 . "\r\n";

    $mail_Subject = "[unknown status] Postfinance new payment notification / PAYID:".$_POST['PAYID']." / orderID:".$_POST['orderID']." / STATUS:".$_POST['STATUS']."";

    $mail_Body    = "";

    $mail_Body   .= "RECEIVED PARAMETER :\n".print_r($_REQUEST,TRUE)."\n";

    $mail_Body   .= $mail_Footer;

    mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

  }

 

For other statuses, we send an [unknown status] notification in reply to @cash.

 

 

} else {

 

  $mail_Header = "";

  $mail_Header .= 'From: ' . $mail_From                                                           . "\r\n";

  $mail_Header .= 'Reply-To: cash@switzernet.com'                                                 . "\r\n";

  $mail_Header .= 'Message-Id: <'$message_id_prefix . '@ipn.switzernet.com>'                   . "\r\n";

  $mail_Header .= 'Content-type: text/plain; charset=utf-8'                                       . "\r\n";

  $mail_Header .= 'X-Mailer: PHP/' . phpversion()                                                 . "\r\n";

  $mail_Subject = "Postfinance INVALID payment notification";

  $mail_Body    = "";

  $mail_Body   .= "RECEIVED PARAMETER :\n".print_r($_REQUEST,TRUE)."\n Calculated hash : ".ogone_hash_parameters_in( $_POST, $postFinanceSecret );

  $mail_Body   .= $mail_Footer;

  mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);

 

}

 

If the calculated hash does not correspond to the one sent by PostFinance, we send an email will all the data to @cash.

 

function ogone_hash_parameters_in($parameters = array(), $secretkey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') {  

  $str = '';

  $param = array();

  /* On s'assure que toutes les clés sont en majuscules et rangées par ordre alphabétique*/

  $txt = '';

  if ( !empty($parameters) ) {

    foreach ($parameters as $i => $j) {

      $param[strtoupper($i)] = $j;

    }

  }

  /* Trier par ordre alphabetique */

  ksort($param);

  if ( !empty($param) ) {

    foreach($param as $i=> $j) {

      if ( $j != "" && valid_param(strtoupper($i)) ){

        $str .= $i. '=' . $j. $secretkey;

        $txt .= $i. '=' . $j."\n";

      }

    }

  }

  $str = utf8_encode ($str);

  return strtoupper(sha1($str));

}

 

 

The function for calculating the hash from received parameters from PostFinance.

 

The key is a hashed string of value/pair separated by the SHA-OUT secret key defined in e-payment PostFinance account.

 

Each keys must be in uppercase and all value/pair key must be in the alphabetical order.

 

 

function format_account( $id ){

  $id = preg_replace('/[^0-9,]|,[0-9]*$/','',$id);

  $id = preg_replace('/^0([0-9]{9})$/', "41$1", $id);

  return $id;

}

 

A simple function of formatting account id.

 

function valid_param ($key = ""){

  $sha_out_param = array(

    'AAVADDRESS'           => 1,

    'AAVCHECK'             => 1,

    'AAVMAIL'              => 1,

    'AAVNAME'              => 1,

    'AAVPHONE'             => 1,

    'AAVZIP'               => 1,

    'ACCEPTANCE'           => 1,

    'ALIAS'                => 1,

    'AMOUNT'               => 1,

    'BIC'                  => 1,

    'BIN'                  => 1,

    'BRAND'                => 1,

    'CARDNO'               => 1,

    'CCCTY'                => 1,

    'CN'                   => 1,

    'COMPLUS'              => 1,

    'CREATION_STATUS'      => 1,

    'CURRENCY'             => 1,

    'CVCCHECK'             => 1,

    'DCC_COMMPERCENTAGE'   => 1,

    'DCC_CONVAMOUNT'       => 1,

    'DCC_CONVCCY'          => 1,

    'DCC_EXCHRATE'         => 1,

    'DCC_EXCHRATESOURCE'   => 1,

    'DCC_EXCHRATETS'       => 1,

    'DCC_INDICATOR'        => 1,

    'DCC_MARGINPERCENTAGE' => 1,

    'DCC_VALIDHOURS'       => 1,

    'DIGESTCARDNO'         => 1,

    'ECI'                  => 1,

    'ED'                   => 1,

    'ENCCARDNO'            => 1,

    'FXAMOUNT'             => 1,

    'FXCURRENCY'           => 1,

    'IBAN'                 => 1,

    'IP'                   => 1,

    'IPCTY'                => 1,

    'NBREMAILUSAGE'        => 1,

    'NBRIPUSAGE'           => 1,

    'NBRIPUSAGE_ALLTX'     => 1,

    'NBRUSAGE'             => 1,

    'NCERROR'              => 1,

    'NCERRORCARDNO'        => 1,

    'NCERRORCN'            => 1,

    'NCERRORCVC'           => 1,

    'NCERRORED'            => 1,

    'ORDERID'              => 1,

    'PAYID'                => 1,

    'PM'                   => 1,

    'SCO_CATEGORY'         => 1,

    'SCORING'              => 1,

    'STATUS'               => 1,

    'SUBBRAND'             => 1,

    'SUBSCRIPTION_ID'      => 1,

    'TRXDATE'              => 1,

    'VC'                   => 1,

  );

  if ( $sha_out_param[$key] ){

    return true;

  }

  return false;

}

 

?>

 

The list of valid parameters to include in the hash. The list comes from the following document [pdf].

 


Links

Ce document : http://switzernet.com/3/public/140923-payments/

Online payment page : http://pay.switzernet.com

Switzernet customer interface : https://account.switzernet.com/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*                  *                  *

Copyright © 2014 by Switzernet