• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

AAC Fortumo payment system

damian00912

Member
Joined
Sep 11, 2009
Messages
90
Reaction score
6
Hei. Can someone help me with this??

I want make Fortumo Payment sms on gesior acc and i have this script for check after payment succesfully, but i don't know how add sql to database. Can someone help me?

PHP:
      ))) {
    header("HTTP/1.0 403 Forbidden");
    die("Error: Unknown IP");
  }

    // read $_GET from Fortumo servers
    $sender = $_GET['sender'];//phone num.
    $amount = $_GET['amount'];//credit
    $payment_id = $_GET['cuid'];//unique id
    $custom = $_GET['custom'];
    $country = $_GET['country'];
    $currency = $_GET['currency'];
    $service_id = $_GET['service_id'];
    $operator = $_GET['operator'];
    $status = $_GET['status'];
    $price = $_GET['price'];
    $points    = $_GET['amount'];
    $created = time();
    $ip = $_SERVER['REMOTE_ADDR'];
  
    $con=mysqli_connect("localhost","root","passwd","database");
    // Check connection
    if (mysqli_connect_errno())
      {
      echo "Failed to connect to MySQL: " . mysqli_connect_error();
      }
    $result = mysqli_query($con, "SELECT * FROM z_fortumo WHERE 'payment_id' != '$payment_id'") or die(mysqli_error($con));
    if ($result && $payment_id != "undefined"){
      //id, account_id, price,service_id,points,operator,payment_id,sender,currency,status,ip,created
    mysqli_query($con,"INSERT INTO z_fortumo VALUES ('', '$payment_id', '$price', '$service_id', '$points', '$operator', '$sender', '$currency', '$status', '$ip', '$created')");
    // update the points in database
    mysqli_query($con,"UPDATE accounts SET premium_points = premium_points + '$points' WHERE id = '$payment_id'");

    $count->close();
    mysqli_close($con);

    }


?>



also they have on official website example:


Processing the receipt verification request​

Receipt verification is a convenient way for integrating in-app purchases with users online profile so that in-app purchases can be kept track of and shared between different devices and platforms. Receipt verification can also be used to gather live statistics about purchases made and integrate data with your live dashboard or accounting systems.

In order to handle and process the values sent to your callback URL you need implement a script hosted at your service backend.

The following example Receipt Verification script is called whenever an user makes a payment. The script first makes security checks (validate IP addresses, check the signature) to validate that the request came from Fortumo. Then the script processes the $_GET['product_name'] and $_GET['status'] parameters and grants virtual items to the user who made the purchase.

PHP:
<?php

  // check that the request comes from Fortumo server
  if(!in_array($_SERVER['REMOTE_ADDR'],
    //add Fortumo hosted ip addresses inside the 'array'.
    array('1.2.3.4', '2.3.4.5'))) {
    header("HTTP/1.0 403 Forbidden");
    die("Error: Unknown IP");
  }

  // check the signature
  $secret = ''; // insert your secret between ''
  if(empty($secret)||!check_signature($_GET, $secret)) {
    header("HTTP/1.0 404 Not Found");
    die("Error: Invalid signature");
  }

  $sender = $_GET['sender'];//phone num.
  $amount = $_GET['amount'];//credit
  $cuid = $_GET['cuid'];//resource i.e. user
  $payment_id = $_GET['payment_id'];//unique id
  $test = $_GET['test']; // this parameter is present only when the payment is a test payment, it's value is either 'ok' or 'fail'

  //hint: find or create payment by payment_id
  //additional parameters: operator, price, user_share, country

  if(preg_match("/completed/i", $_GET['status'])) {
    // mark payment as successful
  }

  // print out the reply
  if($test){
    echo('TEST OK');
  }
  else {
    echo('OK');
  }

  function check_signature($params_array, $secret) {
    ksort($params_array);

    $str = '';
    foreach ($params_array as $k=>$v) {
      if($k != 'sig') {
        $str .= "$k=$v";
      }
    }
    $str .= $secret;
    $signature = md5($str);

    return ($params_array['sig'] == $signature);
  }
?>




Payment result processing​

When someone completes a payment, Fortumo will inform service providers’ servers by making a HTTP GET request to the URL that was specified in the service configuration.
Example URL: https://yourdomain.com/in-app-payment.php
The payment processor does not need to be written in PHP, any other server side technology (.NET, Java, Ruby on Rails) will work as well. This response is considered successful and notification delivered if your server responds with code 200, otherwise the request will be repeated up to 20 times with growing intervals. The body of your response will not be processed or forwarded.

Notification parameters​

ParameterTypeRequiredDescription
service_idStringMandatorySpecific service you have created on Fortumo dashboard. Example: e2bbf830a55f565375915a94f3309cc
cuidStringMandatorySpecific user record internal to your system. Helps you match every payment to a specific user of your service. In order to prevent fraud we can limit how often one cuid can make a payment. To use this feature please contact Fortumo customer support. Example: Username21
operation_referenceStringOptionalMatches every specific Fortumo payment to specific orders internal to your system. Different from cuid in that it should be unique per every transaction. Example: order_12345
priceFloat, 2 decimalsMandatoryOverrides the virtual currency exchange rate specified on Fortumo dashboard. Price parameter defines the real currency base amount and should be used together with parameters currency and amount. Example: 5.00
price_wo_vatFloat, 2 decimalsMandatoryEnd-user price in local currency without VAT (Value Added Tax) (float, 2 decimals). Example: 0.27
revenueFloat, 2 decimalsMandatoryRevenue in local currency. Example: 0.13
currencyString, ISO 4217MandatoryOverrides the virtual currency exchange rate specified on Fortumo dashboard. Currency parameter specifies the real currency against which virtual currency is converted to. Example: EUR
amountIntegerMandatoryOverrides the virtual currency exchange rate specified on Fortumo dashboard. Amount parameter specifies the number of virtual credits that are being sold for the real price and currency also specified in the payment request. Example: 100
senderStringMandatoryPhone number. Can be in standard format or hash(sometimes operators encode the phone number for security and privacy measures). Example: 37256455115 or #a2001sdf1993fc7
countryString, ISO Alpha-2MandatoryPreselects consumer country. Can be useful in case your consumers are known to use VPNs, but you have knowledge about their real location. Example: MY
operatorStringMandatoryOperator name. Example: Vodafone
payment_idStringMandatoryUnique payment id. Example: 32 or hash dc06a486787906f4b88dc74740f82c99
statusBooleanMandatoryStatus of the payment. Example: completed / failed
user_shareFloat, 2 decimalsMandatoryMerchant share % from the transaction. Example: 0.75
sigStringMandatoryUsed to verify the information in this request. Example: 136cc6f53d62afd45ac849674259f703
testBooleanOptionalThis parameter is present only when the payment is a test payment. Example: ok / fail
Notification example - sandbox
Notification examples - live

Processing the receipt verification request​

Receipt verification is a convenient way for integrating in-app purchases with users online profile so that in-app purchases can be kept track of and shared between different devices and platforms. Receipt verification can also be used to gather live statistics about purchases made and integrate data with your live dashboard or accounting systems.
In order to handle and process the values sent to your callback URL you need implement a script hosted at your service backend.
The following example Receipt Verification script is called whenever an user makes a payment. The script first makes security checks (validate IP addresses, check the signature) to validate that the request came from Fortumo. Then the script processes the $_GET['product_name'] and $_GET['status'] parameters and grants virtual items to the user who made the purchase.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php

// check that the request comes from Fortumo server
if(!in_array($_SERVER['REMOTE_ADDR'],
//add Fortumo hosted ip addresses inside the 'array'.
array('1.2.3.4', '2.3.4.5'))) {
header("HTTP/1.0 403 Forbidden");
die("Error: Unknown IP");
}

// check the signature
$secret = ''; // insert your secret between ''
if(empty($secret)||!check_signature($_GET, $secret)) {
header("HTTP/1.0 404 Not Found");
die("Error: Invalid signature");
}

$sender = $_GET['sender'];//phone num.
$amount = $_GET['amount'];//credit
$cuid = $_GET['cuid'];//resource i.e. user
$payment_id = $_GET['payment_id'];//unique id
$test = $_GET['test']; // this parameter is present only when the payment is a test payment, it's value is either 'ok' or 'fail'

//hint: find or create payment by payment_id
//additional parameters: operator, price, user_share, country

if(preg_match("/completed/i", $_GET['status'])) {
// mark payment as successful
}

// print out the reply
if($test){
echo('TEST OK');
}
else {
echo('OK');
}

function check_signature($params_array, $secret) {
ksort($params_array);

$str = '';
foreach ($params_array as $k=>$v) {
if($k != 'sig') {
$str .= "$k=$v";
}
}
$str .= $secret;
$signature = md5($str);

return ($params_array['sig'] == $signature);
}
?>

Verifying Fortumo notification signature​

The signature is added as sig parameter and is calculated as md5 checksum of the request parameters and secret concatenated together. You can find your service secret from the service settings page on Fortumo.com Dashboard. To check whether the sig parameter in the notification matches the one that you calculated you can make the same calculation.
Before calculating the signature:
  • It is important to sort the parameters alphabetically.
  • Parameter values (e.g. callback_url) should be URL decoded (though they have to be encoded prior to composing payment URL).
  • Exclude sig parameter from the signature calculation.

PHP:
PARAMETERS
credit_name = gold
tc_amount = 3333
tc_id = 291
test = ok
secret = bad54c617b3a51230ac7cc3da398855e

CALCULATION STRING
credit_name=goldtc_amount=3333tc_id=291test=okbad54c617b3a51230ac7cc3da398855e

MD5 RESULT AS SIGNATURE
sig = 047f555536f8826825c9079265ad36de
Post automatically merged:

ALSO I HAVE THIS FROM MYACC. SOMEONE CAN CHANGE THIS TO GESIOR ACC?

PHP:
<?php
/**
 * This is shop system taken from Gesior, modified for MyAAC.
 *
 * @name      myaac-gesior-shop-system
 * @author    Gesior <[email protected]>
 * @author    Slawkens <[email protected]>
 * @website   github.com/slawkens/myaac-gesior-shop-system
 */

require_once '../common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
require_once LIBS . 'shop-system.php';
require_once PLUGINS . 'gesior-shop-system/config.php';

if(!isset($config['fortumo']) || !count($config['fortumo']) || empty($config['fortumo']['service_id'])) {
    log_append('fortumo_debug.log', 'Fortumo is disabled. IP: ' . $_SERVER['REMOTE_ADDR']);
    header("HTTP/1.0 404 Not Found");
    die("Error: Fortumo is disabled");
}

 // check that the request comes from Fortumo server
if(!in_array($_SERVER['REMOTE_ADDR'], array('54.72.6.23', '54.72.6.126', '54.72.6.27', '54.72.6.17', '79.125.125.1', '79.125.5.95', '79.125.5.205'))) {
    log_append('fortumo_scammer.log', $_SERVER['REMOTE_ADDR']);
    header("HTTP/1.0 403 Forbidden");
    die("Error: Unknown IP");
}

// check the signature
$secret = $config['fortumo']['secret'];
if(empty($secret) || !check_signature($_GET, $secret)) {
    log_append('fortumo_debug.log', 'Invalid signature: ' . $secret);
    header("HTTP/1.0 404 Not Found");
    die("Error: Invalid signature");
}

if($_GET['status'] != 'completed')
{
    log_append('fortumo_debug.log', 'Transaction status: ' . $_GET['status']);
    return;
}

$account = new OTS_Account();
$account_id = (int)$_GET['cuid'];
$account->load($account_id);
if($account->isLoaded()) {
    $points = (int)$_GET['amount'];
    if(GesiorShop::changePoints($account, $points)) {
        $time = date('d.m.Y, g:i A');
        $account_id = $account->getId();
        $price = $_GET['price'];
        $currency = $_GET['currency'];
        $payment_id = $_GET['payment_id'];
        $service_id = $_GET['service_id'];
        $country = $_GET['country'];
        $operator = $_GET['operator'];
        $sender = $_GET['sender'];
        log_append('fortumo.log', "$time;$account_id;$points;$price:$currency;$payment_id;$service_id;$country;$operator;$sender");
    }
}
else
    log_append('fortumo_debug.log', 'Invalid account used: ' . $account_id . '. Payment id: ' . $_GET['payment_id']);

function check_signature($params_array, $secret)
{
    ksort($params_array);

    $str = '';
    foreach ($params_array as $k=>$v) {
        if($k != 'sig') {
            $str .= "$k=$v";
        }
    }

    $str .= $secret;
    $signature = md5($str);

    return ($params_array['sig'] == $signature);
}
 
Last edited:
Solution
I made this a while ago, never used tho (but i tested it and work at the time)

PHP:
<?php

function log_append($file, $str) {
   $f = fopen($file, 'ab');
   fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $str . PHP_EOL);
   fclose($f);
}

// check that the request comes from Fortumo server
if(!in_array($_SERVER['REMOTE_ADDR'], array('54.72.6.23', '54.72.6.126', '54.72.6.27', '54.72.6.17', '79.125.125.1', '79.125.5.95', '79.125.5.205'))) {
log_append('logs/fortumo_scammer.log', $_SERVER['REMOTE_ADDR']);
  header("HTTP/1.0 403 Forbidden");
  die("Error: Unknown IP");
}

// check the signature
$secret = '';
if(empty($secret) || !check_signature($_GET, $secret)) {
  header("HTTP/1.0 404 Not Found");
  die("Error: Invalid signature");
}...
I made this a while ago, never used tho (but i tested it and work at the time)

PHP:
<?php

function log_append($file, $str) {
   $f = fopen($file, 'ab');
   fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $str . PHP_EOL);
   fclose($f);
}

// check that the request comes from Fortumo server
if(!in_array($_SERVER['REMOTE_ADDR'], array('54.72.6.23', '54.72.6.126', '54.72.6.27', '54.72.6.17', '79.125.125.1', '79.125.5.95', '79.125.5.205'))) {
log_append('logs/fortumo_scammer.log', $_SERVER['REMOTE_ADDR']);
  header("HTTP/1.0 403 Forbidden");
  die("Error: Unknown IP");
}

// check the signature
$secret = '';
if(empty($secret) || !check_signature($_GET, $secret)) {
  header("HTTP/1.0 404 Not Found");
  die("Error: Invalid signature");
}

$time = date('d.m.Y, g:i A');
$sender = $_GET['sender']; //phone num.
$amount = $_GET['amount']; //credit
$price = $_GET['price'];
$currency = $_GET['currency'];
$cuid = $_GET['cuid']; //resource i.e. user
$payment_id = $_GET['payment_id']; //unique id
$country = $_GET['country'];
$operator = $_GET['operator'];

// replace these parameters by your database details
$dbhost     = "localhost"; //Your database domain
$dbuser     = "root"; //Database username
$dbpassword = ""; //Database password
$dbname     = ""; //Database name

if(preg_match("/completed/i", $_GET['status'])) {
    $connect = mysql_connect($dbhost, $dbuser, $dbpassword);
    mysql_select_db($dbname);
    mysql_query("UPDATE accounts SET premium_points = premium_points+'".mysql_real_escape_string($amount)."' WHERE id = '".mysql_real_escape_string($cuid)."';");
    mysql_close($connect);
    log_append('logs/fortumo.log', "$time;$cuid;$amount;$price:$currency;$country;$operator;$sender;$payment_id");
}
function check_signature($params_array, $secret)
{
  ksort($params_array);
  $str = '';
  foreach ($params_array as $k=>$v) {
    if($k != 'sig') {
      $str .= "$k=$v";
    }
  }
  $str .= $secret;
  $signature = md5($str);
  return ($params_array['sig'] == $signature);
}
?>

Also dont forget to set your secret signature
 
Solution
thats, perfect, thanks you, buy where I should put this my secret code? where this change, here? $secret = '';

and whiat is this: if(preg_match("/completed/i"

i should have some extra files?

and how this know abount after payment it give's coints to my account?
 
Last edited:
thats, perfect, thanks you, buy where I should put this my secret code? where this change?
Post automatically merged:

aaa, here? $secret = '';
Post automatically merged:

and whiat is this: if(preg_match("/completed/i"

i should have some extra files?

No you dont need anything extra, just configure your urls on the fortumo website and test it
And yes, your secret signature should be on $secret = '';

Also create a folder called "logs" on your website directory to create fortumo logs in case you want them
 
I made like you told, and after test this on website fortumo I don't get coins, becasue it do't know abount my account it's my account


I have this like that:

asdfghjk.jpg


or It don't get me coins if I use button Test on fortumo website, only I need buy this from my website after login?
 
Last edited:
I mean your fortumo page on your website 😆

You can use this one:
PHP:
<?PHP

if($logged){

$main_content .= '<script src="https://assets.fortumo.com/fmp/fortumopay.js" type="text/javascript"></script>';
$accountShow = strtolower($account_logged->getName());

$main_content .= '
<center>
<img src="./images/fortumo3.png"  border="0" />
<br><b>Fortumo SMS Payments</b><br/>
Your points will be added automatically.<br>
<br> Your account name is: <b>'.$accountShow.'</b><br/>
<a id="fmp-button" href="#" rel="dffc5832ceb5772d35aa6765111596c9/'.$account_logged->getId().' "><img src="https://assets.fortumo.com/fmp/fortumopay_150x50_red.png" width="150" height="50" alt="Mobile Payments by Fortumo" border="0" /></a>
<br><br>
</center>
';
}
else
echo 'You are not logged in. Login first to buy points.'
?>

Just change rel value to your Service Id (in my case it was dffc5832ceb5772d35aa6765111596c9)
It should look like this: rel="your_service_id/'.$account_logged->getId().' "
 
Back
Top