Postfinance e-payment configuration

advertisement
[1'e9e'1 card payments]
CREDIT CARD PAYMENTS
Document created on 2013-06-24
Nicolas Bondier
[pdf][doc][htm]
Page 1 of 61
[1'e9e'1 card payments]
*
*
*
Copyright © 2016 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
Page 2 of 61
[1'e9e'1 card payments]
Add PostFinance to the Porta-Billing payments systems. ..................................................................................9
Payments on website .............................................................................................................................................10
Payment page .....................................................................................................................................................10
PayPal ..................................................................................................................................................................29
Process PayPal payments..................................................................................................................................29
PayPal payment notifications and update payment on billing .........................................................................34
PostFinance .........................................................................................................................................................45
Process Postfinance payments .........................................................................................................................45
Postfinance payment notifications and update payment in portabilling .........................................................49
Liens .......................................................................................................................................................................61
Page 3 of 61
[1'e9e'1 card payments]
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.
Page 4 of 61
[1'e9e'1 card payments]
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.
Page 5 of 61
[1'e9e'1 card payments]
Page 6 of 61
[1'e9e'1 card payments]
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.
Page 7 of 61
[1'e9e'1 card payments]
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 ‘epayment.postfinance.ch’ as bellow.
sub set_defaults{
my $self = shift;
$self->server('e-payment.postfinance.ch');
Page 8 of 61
[1'e9e'1 card payments]
$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.
Page 9 of 61
[1'e9e'1 card payments]
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
Page 10 of 61
[1'e9e'1 card payments]
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
├──
├──
│
│
│
│
│
│
│
├──
├──
├──
├──
└──
│
├── 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
Page 11 of 61
[1'e9e'1 card payments]
├──
├──
├──
├──
└──
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();}
Session start
include_once "include/pay.config.php";
Including general configuration
file.
Getting information posted to
this page.
if ( isset($_GET['amount']) ){
if ( preg_match('/^[0-9]+(\.[0-9]{0,2})?$/', $_GET['amount']) ){
Page 12 of 61
[1'e9e'1 card payments]
$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'];
}
$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,maximumscale=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">
Page 13 of 61
HTML begins here.
The head content contains
information for better
displaying on mobile
applications and old browser.
[1'e9e'1 card payments]
<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/jquery1.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">
<?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
}
?>
<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+'';
}
function getParentElementByTagName( element , tag ){
while( element.tagName.toLowerCase() != tag.toLowerCase() ){
element = element.parentNode;
if (!element.tagName) {
Page 14 of 61
Getting the localization files
(language) for error handling
for the customer.
Some JavaScript functions for
submitting language and
currency changes.
A function to simplify the
selection of a parent element.
[1'e9e'1 card payments]
return;
}
}
return element;
}
</script>
<!--[if lte IE 8]>
<link rel="stylesheet" href="style/ie.css" type="text/css"
media="screen,projection" />
<![endif]-->
<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>
Special CSS style sheet for
internet explorer.
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 for getting
statistics.
<!-- Piwik -->
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(["trackPageView"]);
_paq.push(["enableLinkTracking"]);
Page 15 of 61
[1'e9e'1 card payments]
(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>
<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="../060801web/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">
<form id="formLanguage" action="#" method="get">
<fieldset>
<select name="language" id="language_select"
onchange="changeLanguage(this)">
<?php
foreach ($LANGUAGES as $ISO => $text) {
Page 16 of 61
Starting of the body and the
page header.
Language selection
[1'e9e'1 card payments]
if ( $_SESSION['language']['code'] == $ISO ){
echo "<option value='".$ISO."'
selected='selected'>".$text."</option>";
} else {
echo "<option value='".$ISO."'>".$text."</option>";
}
}
?>
</select>
</fieldset>
</form>
End of page header
</div>
</td>
</tr>
</tbody>
</table>
</div>
Starting of the man content div.
<div id="pay_div" style="">
<?php
if ( $_SERVER['REMOTE_ADDR'] == '46.14.170.24' && FALSE ){
echo time();
}
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>
Page 17 of 61
When the action received is
cancel (from PayPal or
PostFinance), we display the
corresponding content.
[1'e9e'1 card payments]
</tr>
</table>
<?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>
When the action received is
paymentok (from PayPal or
PostFinance), we display the
corresponding content.
</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
} 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
Page 18 of 61
When the action received is
paymentpending (from PayPal),
we display the corresponding
content.
[1'e9e'1 card payments]
} 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>
When the action received is
paymentfailed (from PayPal or
Postfinance), we display the
corresponding content.
<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
} 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
} 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"]);
Page 19 of 61
Error during the payment (from
PayPal), we display the
corresponding content.
Text when received an action
called payment. It refers to the
last page before submitting the
payment to PostFinance or
PayPal.
[1'e9e'1 card payments]
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 {
$accountFound = FALSE;
$currency = 'CHF';
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.
If the format is correct, we get
the account currency to display
$connection2=mysql_connect(DB2_SERVER.':'.DB2_SERVER_PORT,DB2_SERVER_USERNAME, it on the web page.
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);
Page 20 of 61
[1'e9e'1 card payments]
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 {
include("include/geoiploc.php");
$ip = $_SERVER["REMOTE_ADDR"];
if ( getCountryFromIP($ip) == 'CH' ){
$_SESSION['currency_code'] = 'CHF';
} else {
$_SESSION['currency_code'] = 'EUR';
}
}
mysql_close($connection2);
If we find the currency, then we
set in session.
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
$_SESSION['phone_number'] = $number;
if ( $_SESSION['currency_code'] != '' ){
$currency = $_SESSION['currency_code'];
}
?>
<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>
Page 21 of 61
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.
[1'e9e'1 card payments]
<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-errorscontainer="#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-parsleyerrors-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;whitespace:nowrap;">  <?= $currency ?></span>
<?php } else { ?>
<?php if ( $layoutType != 'classic' ) { ?>
<input class="input_text" data-parsley-errorscontainer="#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-parsleyerrors-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 } ?> 
<select data-parsley-errors-container="#amountError"
name="currency" onchange="changeCurrency(this)" changeCurrency>
<?php
foreach ($currencyNotations as $key => $value) {
Page 22 of 61
[1'e9e'1 card payments]
$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 ?>"/>
Page 23 of 61
[1'e9e'1 card payments]
</td>
</tr>
</table>
<input type="hidden" name="number" value="<?= $number ?>" />
</form>
<?php
}
} 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" >
<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){
Page 24 of 61
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.
Selection of the prefixes.
[1'e9e'1 card payments]
echo '<option value="'.$prefixes[0].'-'.$prefixes[1].'" ';
if ( $id_pref==$found ) {
echo "selected = \"selected\"";
}
echo '>'.$prefixes[0].'-'.$prefixes[1].'</option>'."\n";
}
?>
</select>
</td>
<td class="td_input" >
<?php if ( $layoutType != 'classic' ) { ?>
<input class="input_text" data-parsley-errorscontainer="#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-errorscontainer="#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.
This is some hidden cells for
displaying error in input cells.
<tr class="parsleyError">
<td></td>
<td id="numberError1"></td>
<td id="numberError2"></td>
</tr>
<tr>
<td colspan="3" style="text-align:center;"><br>
<input type="submit" name="submitbutt" class="pure-button purebutton-primary" value="<?= BUTTON_CONTINUE ?>"/>
</td>
</tr>
Page 25 of 61
Button for validating the form
and continuing to last page.
[1'e9e'1 card payments]
</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>
<?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>  
<a href="http://www.mastercard.com/" target="_blank"><img
height="30" src='/public/060801-web/images/mastercard.gif'
border="0"></a>  
<a href="http://www.visa.com/" target="_blank"><img height="30"
src='/public/060801-web/images/visa.gif' border="0"></a>  
<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/paypalpopup','WIPaypal','toolbar=no, location=no, directories=no, status=no,
Page 26 of 61
Footer with logos of the
available payment methods.
[1'e9e'1 card payments]
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/paypalpopup','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/logocenter/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>
</body>
</html>
End of the html
Function for getting the
prefixes from
<?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"]);
}
Page 27 of 61
[1'e9e'1 card payments]
mysql_close($connection);
return $prefs;
}
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;
}
?>
Page 28 of 61
Function for detecting mobile
devices. This is required for all
displaying differences added to
the html and CSS.
[1'e9e'1 card payments]
PayPal
Process PayPal payments
[paypalProcess.php]
CODE
COMMENT
<?php
Starting session and
including configuration
files and a PayPal class for
processing the payment
easier.
if(!isset($_SESSION)){session_start();}
include_once("include/pay.config.php");
include_once("include/paypal.config.php");
include_once("include/paypal.class.php");
$paypalmode = ($PayPalMode=='sandbox') ? '.sandbox' : '';
$PaypalLocalCode = 'CH';
if ( isset( $defaultLocale[$PayPalCurrencyCode] ) ){
$PaypalLocalCode = $defaultLocale[$PayPalCurrencyCode];
}
if($_POST) //Post Data received from product list page.
{
Page 29 of 61
Defining the string for the
PayPal URL to reach in case
of we are using the
sandbox account or the
live account.
The PayPal variable to
define the localization to
display.
The available localization
codes are in the
paypal.config.php file.
I data has been submitted
to this page with POST.
[1'e9e'1 card payments]
We get the VOIP number
to credit and verify the
format.
$number = $_POST['number'];
if ( ! preg_match('/^41[0-9]{9}$/', $number) ){
die ("wrong number format $number");
}
$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");
}
}
$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
$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).
Page 30 of 61
We get the amount the
customer wants to credit
on his account.
Main parameters we have
to set for account
crediting.
This is the part for
preparing the
SetExpressCheckout
method.
A full documentation of
the parameters can be
found on PayPal developer
website [link].
[1'e9e'1 card payments]
'&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-com2.png'. //site logo
'&LANDINGPAGE=Billing'.
//Show crdit card
'&SOLUTIONTYPE=Sole'.
//Show crdit card
'&USERSELECTEDFUNDINGSOURCE=CreditCard'.
'&CARTBORDERCOLOR=6699FF'. //border color of cart
'&ALLOWNOTE=0';
############# 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;
Page 31 of 61
In the same time, we save
the data in the session.
[1'e9e'1 card payments]
$_SESSION['ShippinDiscount']
= $ShippinDiscount;
$_SESSION['ShippinCost']
=
$ShippinCost;
$_SESSION['GrandTotal']
= $GrandTotal;
Executing the
SetExpressCheckOut
method to obtain the
PayPal token.
If the PayPal answer is
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING"
success, we redirect the
== strtoupper($httpParsedResponseAr["ACK"])) {
$paypalurl ='https://www'.$paypalmode.'.paypal.com/cgi-bin/webscr?cmd=_express- user to PayPal with the
checkout&token='.$httpParsedResponseAr["TOKEN"].'';
received token in the URL.
$paypal= new MyPayPal();
$httpParsedResponseAr = $paypal->PPHttpPost('SetExpressCheckout', $padata,
$PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);
header('Location: '.$paypalurl);
} else {
echo '<div style="color:red"><b>Error :
</b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';
echo '<pre>';
//print_r($httpParsedResponseAr);
echo '</pre>';
}
}
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'];
Page 32 of 61
Else we show the error
message.
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.
[1'e9e'1 card payments]
$ItemTotalPrice
= $_SESSION['ItemTotalPrice'];
$TotalTaxAmount
= $_SESSION['TotalTaxAmount'];
$HandalingCost
= $_SESSION['HandalingCost'];
$InsuranceCost
= $_SESSION['InsuranceCost'];
$ShippinDiscount
= $_SESSION['ShippinDiscount'];
$ShippinCost
= $_SESSION['ShippinCost']; $GrandTotal
$_SESSION['GrandTotal'];
We haven’t received the
payment yet.
=
$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);
//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);
//Check if everything went ok..
if ( "SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) ||
"SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
if('Completed' == $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]) {
Page 33 of 61
We also get all the session
variables.
Preparing the data for
DoExpressCheckout
method.
Executing the
DoExpressCheckout
method with the same
parameters.
If the DoExpressCheckout
method succeed …
And the status of payment
is Completed we redirect
[1'e9e'1 card payments]
header('Location: '. $ReturnURL ."?action=paymentok&tid=".
$httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);
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
Page 34 of 61
[1'e9e'1 card payments]
<?php
SOAP login and
password.
$SOAP_user = 'xxxxxx';
$SOAP_password = 'xxxxxx';
$sandbox = FALSE;
include "PortaBillingSoapClient.php";
// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
header('HTTP/1.1 200 OK');
$item_name
$item_number
$payment_status
$payment_amount
$payment_currency
$receiver_email
$payer_email
$transaction_id
$custom
=
=
=
=
=
=
=
=
=
$_POST['item_name1'];
$_POST['item_number1'];
$_POST['payment_status'];
$_POST['mc_gross'];
$_POST['mc_currency'];
$_POST['receiver_email'];
$_POST['payer_email'];
$_POST['txn_id'];
$_POST['custom'];
$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";
Page 35 of 61
A PHP library for
the SOAP
connection to
porta-billing.
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.
We get the
required data
from PayPal to
process the
payment on
Portabilling.
Some variables
for all the emails
that will be sent
[1'e9e'1 card payments]
to cash [at]
switzernet.com.
This part set up
variables when
testing in sandbox
mode.
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
We also send an
email with all the
data send by
PayPal for
verification.
= "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";
}
$message_id_prefix = $transaction_id . '.' . $item_number;
Page 36 of 61
A unique message
id is generated.
We need to save
it for keeping a
thread in our
mailboxes.
[1'e9e'1 card payments]
// Build the required acknowledgement message out of the notification just received
$req = 'cmd=_notify-validate';
$mailreq = "";
foreach ($_POST as $key => $value) {
pairs
$mailreq .= "$key = $value\n";
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// Loop through the notification NV
// 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";
// 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);
while (!feof($fp)) {
// While not EOF
if (strcmp (chomp($res), "VERIFIED") == 0) {
process notification
// Response contains VERIFIED -
Page 37 of 61
We build the
acknowledgement
message with all
parameters sent
by PayPal.
The header for to
send to PayPal.
The answer
message is posted
to PayPal server
through secured
connection with
all the parameters
we have received.
When posting, we
read the content
of the message
send by PayPal
until the end of
file of the socket.
If PayPal answers
VERIFIED, it
[1'e9e'1 card payments]
.
.
.
.
.
// 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
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
$mail_Body
=
.=
.=
.=
.=
.=
.=
.=
.=
.=
.=
.=
.=
.=
.=
.=
"A new transaction as been processed by paypal.\n";
"\n";
"**********************************************\n";
"*
Transaction details
*\n";
"**********************************************\n";
"\n";
"item_name
: " . $item_name
. "\n";
"item_number
: " . $item_number
. "\n";
"payment_status
: " . $payment_status
. "\n";
"payment_amount
: " . $payment_amount
. "\n";
"payment_currency : " . $payment_currency
. "\n";
"receiver_email
: " . $receiver_email
. "\n";
"payer_email
: " . $payer_email
. "\n";
"transaction_id
: " . $transaction_id
. "\n";
"custom trx name : " . $custom
. "\n";
$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:
Page 38 of 61
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.
[1'e9e'1 card payments]
// Check that the payment_status is Completed
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 = '';
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.
file_put_contents("log/" . $message_id_prefix .
".log","step:payment_completed ok\n",FILE_APPEND);
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 = "";
Page 39 of 61
If the account is
not found, we
send an email
replying the
precedent email,
informing the
account could not
be found.
[1'e9e'1 card payments]
$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);
} 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);
if ( $payment_currency != $account_currency ){
Page 40 of 61
Else, if the
account is found,
we get the ID of
the customer and
the currency.
If the customer
currency does not
[1'e9e'1 card payments]
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;
match the
currency of the
payment, we send
an email
informing of this
and do not
process the
payment.
$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 currencies
match, we
prepare a
} else {
Page 41 of 61
[1'e9e'1 card payments]
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);
payment request
on portabilling on
the SOAP
customer API.
$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'
=> ''
);
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";
Page 42 of 61
To process the
payment, we use
the “try { . . . }
catch { . . . }”
method to avoid
the PHP script to
exit on an error.
[1'e9e'1 card payments]
$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);
} 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;
Page 43 of 61
If an error
happen, we send
an email to cash
for informing.
[1'e9e'1 card payments]
$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);
}
Logout from the
SOAP customer
API.
Logout from the
SOAP account
API.
$ServiceCustomer->_logout();
}
}
$ServiceAccount->_logout();
}
} else if (strcmp ($res, "INVALID") == 0) {
Page 44 of 61
[1'e9e'1 card payments]
$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
Setting language
and locales
correspondences
for PostFinance
payment page.
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';
Page 45 of 61
[1'e9e'1 card payments]
}
if ( isset( $_GET['language'] ) && isset( $locales[ $_GET['language'] ] ) ){
$_SESSION['language']['code'] = $_GET['language'];
}
Verifying the
number format.
$number = $_POST['number'];
if ( ! preg_match('/^41[0-9]{9}$/', $number) ){
die ("wrong number format $number");
}
$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");
}
}
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) );
Page 46 of 61
Getting the
amount the
customer want to
credit on his
account.
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
[1'e9e'1 card payments]
$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));
}
?>
<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>
Page 47 of 61
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.
We create a form
with our data and
tell the browser
to submit it to
PostFinance.
[1'e9e'1 card payments]
</head>
<body>
<FORM id="postfinanceForm" METHOD=post ACTION="https://epayment.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>
<?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;
}
}
?>
Page 48 of 61
Function to
convert a phone
number to 0XXXXX-XXXX.
[1'e9e'1 card payments]
Postfinance payment notifications and update payment in portabilling
[index.php]
CODE
COMMENT
<?php
SOAP user and password.
$SOAP_user = 'xxxxxxx';
$SOAP_password = 'xxxxxxxxxxxxxxxxxxxxxx';
$postFinanceSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
include "PortaBillingSoapClient.php";
Test mode is disabled.
$test = FALSE;
$mail_To
$mail_From
Postfinance SHA-OUT
defined in PostFinance
interface.
A PHP library for the SOAP
connection to portabilling.
Some variables for all the
emails that will be sent to
cash [at] switzernet.com.
= "cash@switzernet.com";
= "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";
if ( $test == TRUE ){
$mail_To
= "developer@domain.com";
$postFinanceSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$mail_From
= "TEST_PostFinance_IPN@switzernet.com";
}
Page 49 of 61
This part set up variables
in testing mode.
Secret may not be the
same as we use the test
account of PostFinance.
[1'e9e'1 card payments]
$message_id_prefix = time() . '-' . md5('postfinance-notification' . $mail_To);
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;
A unique message id is
generated. We need to save
it for keeping a thread in our
mailboxes.
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.
mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);
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'])
);
Page 50 of 61
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.
[1'e9e'1 card payments]
$GetAccountInfoResponse = $ServiceAccount>get_account_info($GetAccountInfoRequest);
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";
Page 51 of 61
If we cannot find the
account, an email is send
to @cash informing the
account could not be
found.
[1'e9e'1 card payments]
mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);
} 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.
If the currencies match,
we connect to the
} else {
Page 52 of 61
[1'e9e'1 card payments]
$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'
=> ''
);
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 = "";
Page 53 of 61
customer service of the
SOAP API and prepare the
payment request.
If the transaction executes
without exception, we
reply to the first email
with [done] to confirm
the payment has been
correctly entered.
[1'e9e'1 card payments]
$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);
Else the error message is
sent to @cash.
} 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";
Page 54 of 61
[1'e9e'1 card payments]
$mail_Header
'@ipn.switzernet.com>'
$mail_Header
'@ipn.switzernet.com>'
$mail_Header
. "\r\n";
$mail_Header
. "\r\n";
$mail_Header
. "\r\n";
$mail_Header
. "\r\n";
$mail_Header
. "\r\n";
.= 'References: <' . $message_id_prefix .
. "\r\n";
.= 'In-Reply-To: <'. $message_id_prefix .
. "\r\n";
.= 'X-Priority: 1'
.= 'X-MSMail-Priority: High'
.= 'Importance: High'
.= 'Content-type: text/plain; charset=utf-8'
.= 'X-Mailer: PHP/' . phpversion()
mail($mail_To, $mail_Subject, $mail_Body, $mail_Header);
}
$ServiceCustomer->_logout();
}
}
$ServiceAccount->_logout();
} 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";
Page 55 of 61
Payment cancellation
notice when the status is
1: the payment has been
cancelled by the payer.
[1'e9e'1 card payments]
$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);
} 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.
If the calculated hash does
not correspond to the one
sent by PostFinance, we
} else {
$mail_Header = "";
Page 56 of 61
[1'e9e'1 card payments]
$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);
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";
}
Page 57 of 61
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.
[1'e9e'1 card payments]
}
}
$str = utf8_encode ($str);
return strtoupper(sha1($str));
}
function format_account( $id ){
$id = preg_replace('/[^0-9,]|,[0-9]*$/','',$id);
$id = preg_replace('/^0([0-9]{9})$/', "41$1", $id);
return $id;
}
function valid_param ($key
$sha_out_param = array(
'AAVADDRESS'
'AAVCHECK'
'AAVMAIL'
'AAVNAME'
'AAVPHONE'
'AAVZIP'
'ACCEPTANCE'
'ALIAS'
'AMOUNT'
'BIC'
'BIN'
'BRAND'
'CARDNO'
'CCCTY'
'CN'
'COMPLUS'
'CREATION_STATUS'
'CURRENCY'
'CVCCHECK'
'DCC_COMMPERCENTAGE'
'DCC_CONVAMOUNT'
'DCC_CONVCCY'
'DCC_EXCHRATE'
The list of valid
parameters to include in
the hash. The list comes
from the following
document [pdf].
= ""){
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
A simple function of
formatting account id.
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
Page 58 of 61
[1'e9e'1 card payments]
'DCC_EXCHRATESOURCE'
'DCC_EXCHRATETS'
'DCC_INDICATOR'
'DCC_MARGINPERCENTAGE'
'DCC_VALIDHOURS'
'DIGESTCARDNO'
'ECI'
'ED'
'ENCCARDNO'
'FXAMOUNT'
'FXCURRENCY'
'IBAN'
'IP'
'IPCTY'
'NBREMAILUSAGE'
'NBRIPUSAGE'
'NBRIPUSAGE_ALLTX'
'NBRUSAGE'
'NCERROR'
'NCERRORCARDNO'
'NCERRORCN'
'NCERRORCVC'
'NCERRORED'
'ORDERID'
'PAYID'
'PM'
'SCO_CATEGORY'
'SCORING'
'STATUS'
'SUBBRAND'
'SUBSCRIPTION_ID'
'TRXDATE'
'VC'
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
);
if ( $sha_out_param[$key] ){
return true;
}
return false;
}
Page 59 of 61
[1'e9e'1 card payments]
?>
Page 60 of 61
[1'e9e'1 card payments]
Liens
Ce document :
http://switzernet.com/3/public/folder/
*
*
*
Copyright © 2016 by Switzernet
Page 61 of 61
Download