User Tools

Site Tools


how_to_create_a_payment_module

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
how_to_create_a_payment_module [2020/07/06 21:23]
admin [verify()]
how_to_create_a_payment_module [2020/08/08 21:15] (current)
A User Not Logged in old revision restored (2019/01/10 16:33)
Line 6: Line 6:
  
 <code php /includes/modules/payment/pm_mymodule.inc.php> <code php /includes/modules/payment/pm_mymodule.inc.php>
-class pm_module {+class pm_mymodule {
   public $id = __CLASS__;   public $id = __CLASS__;
-  public $name = 'My Vendor Module';+  public $name = 'My Module';
   public $description = 'Lorem ipsum dolor';   public $description = 'Lorem ipsum dolor';
   public $author = 'ACME Corp.';   public $author = 'ACME Corp.';
Line 21: Line 21:
         array(         array(
           'id' => 'method1',           'id' => 'method1',
-          'icon' => $this->settings['icon'],+          'icon' => 'images/payment/mymodule-method1.png',
           'name' => 'Method 1',           'name' => 'Method 1',
           'description' => 'Select this option for method 1.',           'description' => 'Select this option for method 1.',
Line 59: Line 59:
       array(       array(
         'key' => 'icon',         'key' => 'icon',
-        'default_value' => 'images/payment/vendor.png',+        'default_value' => 'images/payment/'.__CLASS__.'.png',
         'title' => 'Icon',         'title' => 'Icon',
         'description' => 'Web path of the icon to be displayed.',         'description' => 'Web path of the icon to be displayed.',
Line 172: Line 172:
       'action' => 'http://www.paymentgateway.com/form_process.ext',       'action' => 'http://www.paymentgateway.com/form_process.ext',
       'fields' => array(       'fields' => array(
-        'foo' => 'bar', +                    'foo' => 'bar', 
-        'this' => 'that', +                    'this' => 'that', 
-      ),+                  ),
     );     );
   }   }
Line 222: Line 222:
 </code> </code>
  
-==== Using Machine-to-Machine Transactions ==== +==== Using Your Own M2M Transaction ====
- +
-This is an example when we send a JSON request to another machine and return a gateway window.+
  
 <code php> <code php>
   public function transfer($order) {   public function transfer($order) {
- +     
-    $request = array( +    ... 
-      ... +     
-    ); +  // Do whatever 
- +    $client = new someclientyoucreated(); 
-    $headers = array( +    $result = $client->methodyoucreated($mydata); 
-      'Content-Type' => 'application/json; charset=utf-8', +     
-    ); +    if (empty($result) || !empty($result['error'])) { 
- +      return array('error' => 'There was an error: '$result['error']);
-    try { +
- +
-      $client = new wrap_http(); +
-      $response = $client->call('POST', 'https://...', json_encode($request, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), $headers); +
-       +
-      // See the ~/logs/ folder for request logs +
- +
-      if (!$result = json_decode($response, true)) { +
-        throw new Exception('Invalid JSON response'); +
-      } +
-       +
-      ... +
-       +
-      return array( +
-        'method' => 'get'+
-        'action' => $result['someGatewayUrl']+
-      ); +
- +
-    } catch (Exception $e) { +
-      return array('error' => $e->getMessage();+
     }     }
 +    
 +  // Since we don't need to send the user anywhere we simply don't return anything
   }   }
 </code> </code>
Line 274: Line 254:
  
 <code php> <code php>
 +  $item_no = 0;
   foreach ($order->data['items'] as $item) {   foreach ($order->data['items'] as $item) {
-    $fields['items'][] = array( +    $fields['item_name_'.$item_no= $item['name']; 
-      'name' =$item['name']+    $fields['item_number_'.$item_no] = $item['product_id'. (!empty($item['option_id']) ? ':'.$item['product_id': ''); 
-      'sku=> $item['sku'], +    $fields['quantity_'.$item_no] = $item['quantity']; 
-      'quantity' =$item['quantity'], +    $fields['amount_'.$item_no] = currency::format_raw($item['price'], $order->data['currency_code'], $order->data['currency_value']); 
-      'amount' =currency::format_raw($item['price'], $order->data['currency_code'], $order->data['currency_value']), +    $fields['tax_'.$item_no] = currency::format_raw($item['tax'], $order->data['currency_code'], $order->data['currency_value']); 
-      'tax' =currency::format_raw($item['tax'], $order->data['currency_code'], $order->data['currency_value']), +    $item_no++;
-    );+
   }   }
      
 +  $item_no = 0;
   foreach ($order->data['order_total'] as $row) {   foreach ($order->data['order_total'] as $row) {
     if (empty($row['calculate'])) continue;     if (empty($row['calculate'])) continue;
-    $fields['items'][] = array( +    $fields['item_name_'.$item_no] = $row['title']; 
-      'name' => $row['title'], +    $fields['item_number_'.$item_no] = $row['module_id']; 
-      'sku' =$row['module_id'], +    $fields['quantity_'.$item_no] = '1'; 
-      'quantity' ='1', +    $fields['amount_'.$item_no] = currency::format_raw($row['value'], $order->data['currency_code'], $order->data['currency_value']); 
-      'amount' =currency::format_raw($row['value'], $order->data['currency_code'], $order->data['currency_value']), +    $fields['tax_'.$item_no] = currency::format_raw($row['tax'], $order->data['currency_code'], $order->data['currency_value']); 
-      'tax' =currency::format_raw($row['tax'], $order->data['currency_code'], $order->data['currency_value']), +    $item_no++;
-    );+
   }   }
 </code> </code>
Line 298: Line 278:
 Different behaviors depending on different choice of option: Different behaviors depending on different choice of option:
  
-<code php>+</code php>
     list($module_id, $option_id) = explode(':', $order->data['payment_option']['id']);     list($module_id, $option_id) = explode(':', $order->data['payment_option']['id']);
          
Line 321: Line 301:
     try {     try {
          
-      $order->save(); // Save order to database before the transaction. Creates $order->data['id']+      //$order->save(); // Save session order to database before transaction creates an $order->data['id']. Not recommended
          
       $fields = array(       $fields = array(
         ...         ...
-        'cancel_url' => (string)document::ilink('checkout'), +        'cancel_url' => document::ilink('checkout'), 
-        'success_url' => (string)document::ilink('order_process'), +        'success_url' => document::ilink('order_process'), 
-        'callback_url' => (string)document::link(WS_DIR_APP . 'ext/vendorname/callbackfile.php', array('order_id' => $order->data['id'])),+        'callback_url' => document::link(WS_DIR_EXT . 'payment_service_provider/my_external_callback_file.php', array('order_uid' => $order->data['uid'])), // An order always have a uid even though it is not saved
       );       );
              
Line 337: Line 317:
              
       return array(       return array(
-        'action' => 'https://www.paymentgateway.com/form_process.ext',+        'action' => 'http://www.paymentgateway.com/form_process.ext',
         'method' => 'post',         'method' => 'post',
         'fields' => $fields,         'fields' => $fields,
Line 365: Line 345:
     ...     ...
          
-    if ($error) {+    if (isset($error) && $error == true) {
       return array('error' => 'There was an error verifying your transaction');       return array('error' => 'There was an error verifying your transaction');
     }     }
Line 387: Line 367:
 ===== settings() ===== ===== settings() =====
  
-This method sets up the payment module with a settings structure. The return is an array of the structure.  The functions supported are listed in func_form.inc.php form_draw_function().+This method sets up the payment module with a settings structure. The return is an array of the structure.
  
 <code php> <code php>
Line 455: Line 435:
 ===== Callbacks ===== ===== Callbacks =====
  
-Some payment service providers offers machine-to-machine data exchange during the transaction. In such cases you might need a listener for callbacks. Here is an example of an external script that will call a method inside the module called callback().+Some payment service providers offers machine-to-machine data exchange during the transaction takes part. In such cases you will need a callback function. Here is an example of an external script that will call a method inside the module called callback().
  
 <code php /ext/provider/callback.php> <code php /ext/provider/callback.php>
 <?php <?php
 +  define('REQUIRE_POST_TOKEN', false); // Allow unsigned external incoming POST data
 +  require_once('../../includes/app_header.inc.php');
 +  
 +// Make sure callback comes from a trusted IP address
 +  if (!in_array($_SERVER['REMOTE_ADDR'], array('123.456.789.0', '123.456.789.1', '123.456.789.2'))) {
 +    error_log('Unauthorized access by '. $_SERVER['REMOTE_ADDR'] .' to file '. __FILE__);
 +    http_response_code(403);
 +    die('Access Denied');
 +  }
 +  
 +// Make sure we have a UID
 +  if (empty($_GET['order_uid'])) {
 +    http_response_code(400);
 +    die('Bad Request');
 +  }
  
-  try { +// Get Order From Database (In this example using UID) 
-    define('REQUIRE_POST_TOKEN', false)// Allow unsigned external incoming POST data +// To be able to find the order in the database, the order must previously have been saved. 
-    require_once('../../includes/app_header.inc.php'); +  $orders_query = database::query( 
-     +    "select id from "DB_TABLE_ORDERS .
-  // Make sure callback comes from a trusted IP address +    where uid = '"database::input($_GET['order_uid']."' 
-    if (!in_array($_SERVER['REMOTE_ADDR'], array('123.456.789.0', '123.456.789.1', '123.456.789.2'))) { +    limit 1;" 
-      error_log('Unauthorized access by '$_SERVER['REMOTE_ADDR'.' to file '. __FILE__); +  ); 
-      throw new Exception('Access Denied', 403); +   
-    } +  if (!$order = database::fetch($orders_query)) { 
-     +    http_response_code(404); 
-  // Make sure we have a ID +    die('File Not Found'); 
-    if (empty($_GET['order_id'])) { +  } 
-      throw new Exception('Bad Request', 400); +   
-    }+// Initiate $order as the order object 
 +  //$order = new ctrl_order('load'$order['id']); // LiteCart 1.0 
 +  $order = new ctrl_order($order['id']); // LiteCart 2.0 
 +   
 +// Get the order's payment option 
 +  list($module_id, $option_id) = explode(':', $order->data['payment_option']['id']);
  
-  // Get Order From Database (In this example using ID) +// Pass the call to the payment module's method callback() 
-  // To be able to find the order in the database, the order must previously have been saved. +  $payment = new mod_payment(); 
-    $orders_query = database::query( +  $result = $payment->run('callback', $module_id, $order);
-      "select id from ". DB_TABLE_ORDERS ." +
-      where id = '". database::input($_GET['order_id']."' +
-      limit 1;" +
-    ); +
-     +
-    if (!$order database::fetch($orders_query)) { +
-      throw new Exception('File Not Found', 404); +
-    } +
-     +
-  // Initiate $order as the order object +
-    //$order = new ctrl_order('load', $order['id']); // LiteCart 1.0 +
-    //$order = new ctrl_order($order['id']); // LiteCart 2.0 +
-    $order = new ent_order($order['id']); // LiteCart 2.2+
  
-  // Get the order's payment option +  // The rest is handled inside the payment module 
-    list($module_id, $option_id) = explode(':', $order->data['payment_option']['id']); +  // Define the funtion by: public function callback($order) {}
- +
-  // Pass the call to the payment module's method callback() +
-    $payment = new mod_payment(); +
-    $result = $payment->run('callback', $module_id, $order); +
- +
-    // The rest is handled inside the payment module +
-    // Define the funtion by: public function callback($order) {+
- +
-  } catch (Exception $e) { +
-    http_response_code($e->getCode()); +
-    die($e->getMessage()); +
-  }+
  
 </code> </code>
  
 We suggest storing the transaction details in the callback and verify them later in the method verify(). We suggest storing the transaction details in the callback and verify them later in the method verify().
how_to_create_a_payment_module.1594063408.txt.gz · Last modified: 2020/07/06 21:23 by admin