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

Parameter Type Required Description
service_id String Mandatory Specific service you have created on Fortumo dashboard. Example: e2bbf830a55f565375915a94f3309cc
cuid String Mandatory Specific 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_reference String Optional Matches 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
price Float, 2 decimals Mandatory Overrides 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_vat Float, 2 decimals Mandatory End-user price in local currency without VAT (Value Added Tax) (float, 2 decimals). Example: 0.27
revenue Float, 2 decimals Mandatory Revenue in local currency. Example: 0.13
currency String, ISO 4217 Mandatory Overrides the virtual currency exchange rate specified on Fortumo dashboard. Currency parameter specifies the real currency against which virtual currency is converted to. Example: EUR
amount Integer Mandatory Overrides 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
sender String Mandatory Phone number. Can be in standard format or hash(sometimes operators encode the phone number for security and privacy measures). Example: 37256455115 or #a2001sdf1993fc7
country String, ISO Alpha-2 Mandatory Preselects consumer country. Can be useful in case your consumers are known to use VPNs, but you have knowledge about their real location. Example: MY
operator String Mandatory Operator name. Example: Vodafone
payment_id String Mandatory Unique payment id. Example: 32 or hash dc06a486787906f4b88dc74740f82c99
status Boolean Mandatory Status of the payment. Example: completed / failed
user_share Float, 2 decimals Mandatory Merchant share % from the transaction. Example: 0.75
sig String Mandatory Used to verify the information in this request. Example: 136cc6f53d62afd45ac849674259f703
test Boolean Optional This parameter is present only when the payment is a test payment. Example: ok / fail
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "amount": "1",
  "country": "EE",
  "cuid": "fortumo-test-08a352435",
  "currency": "EUR",
  "operator": "cellcard-kh",
  "payment_id": "3d9587dd0fa69737fe25b61f853456e0",
  "price": "0.64",
  "price_wo_vat": "0.53",
  "product_name": "badass bucket",
  "revenue": "0.27",
  "sender": "37253490312",
  "service_id": "6b708952dc9e991169318f22388f6d34",
  "sig": "ab101d75d6f79f98f5bd06f060a97278",
  "status": "completed",
  "test": "ok",
  "user_share": "0.5"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "amount": "1",
  "country": "EE",
  "cuid": "fortumo-test-08a35293",
  "currency": "EUR",
  "operator": "cellcard-kh",
  "payment_id": "09381682d54b6b87b540708da629d83e",
  "price": "0.64",
  "price_wo_vat": "0.53",
  "product_name": "badass bucket",
  "revenue": "0.27",
  "sender": "37253490312",
  "service_id": "6b708952dc9e991169318f22388f6d34",
  "sig": "ab101d75d6f79f98f5bd06f060a97278",
  "status": "completed",
  "user_share": "0.5"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
      "amount": "1",
      "country": "EE",
      "cuid": "fortumo-test-08a3543123",
      "currency": "EUR",
      "error_code": "ERR_700",
      "error_description": "Charging operation failed",
      "operator": "cellcard-kh",
      "payment_id": "c0384706416321a56b7d170c4c94bdf4",
      "price": "0.64",
      "price_wo_vat": "0.53",
      "product_name": "badass bucket",
      "revenue": "0.27",
      "sender": "37253490312",
      "service_id": "6b708952dc9e991169318f22388f6d34",
      "sig": "ab101d75d6f79f98f5bd06f060a97278",
      "status": "failed",
      "user_share": "0.5"
}

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.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
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

Do not expose your service secret, it allows clients to edit parameters such as tc_amount which can lead to "free" credits.

Help us improve our Merchants Portal. Was this article helpful?