Recommended PrestShop Version

Thanks for choosing Agile.
For customers using our Agile Multiple Seller module and its accessry modules, we highly recommend to use PrestaShop 1.6x or 1.7.5 or lower. PrestaShop has made some changes in versions higher than 1.7.6 that makes it possible or very difficult to implement some of features via hooks, or override, since required hooks or override is not available.

Sept. 05, 2019

Payment module integration guide

Payment collection mode and integration

Before we introduce the payment module integration, we need to understand what is Payment Collection mode in Agile Multiple Seller modul. When you are using Agile Multiple Seller and its accessory modules as your online market solution, you need to integrate/customize your payment module into agile multiple seller environment. It depends on the payment collection mode of your Agile Multiple Seller you are using, the requirements of payment module is a little bit different.

Store Collects payment

You do not need to integrate or customize your payment module, you can use any 3rd party payment modules for this Payment Collection mode. But the payment module must be follow following steps to process payment and create orders
             => Proess payment first (the whole shopping cart)
             => Then create Orders by calling valiateOrder() of PaymentModule class or its override

Seller Collects Payment
 

You will need to integrate your payment module.

Both Seller and Store collect Payment 

You need integrate/customize the payment module.


Conditions of 3rd party payment module to be able to integrate with Agile Multiple Seller module.

A. Process payment within store
The payment module must finish payment process within the PrestaShop without redirecting users to payment gateway website to authorize payment. This kind of payment module usually use payment gateway API or web service to send buyer payment info to payment gateway and return the payment result at server side, buyer does not have to be redirected to payment company website to authorize payment. Most credit card payment modules use this way.

B. Process payment first before creating orders
The payment module must process payment first before creating orders. That's only when payment processed successfully, then call PaymentModule->validateOrder() to create order. The validateOrder() could be the payment module override method.

STEPS to integrate your 3rd party module with multiple seller - Agile Multiple Seller 3.2.0.1 or above 
Please focus the code lines in blue - code for integration.

1. Define payment collection mode to support
Add following line to your payment module class to define what payment collection mode you module will support

class AgilePaypalParallel extends PaymentModule
{
   public static $PaymentCollectionMode = array(
      1 => true ///seller collects payment - buyer payments will be split into sellers account
       ,2 => true ///both store and seller collect payment - buyer payment will be split into store(commission) and sellers account
       ,3 => true ///store collects payment from buyers
   );
   ................
}

2. Payment module availability control.
Add following lines of code at beginning of hookDisplayPayment() method to control the module availabilities

///If this payment module does not support current multiple seller payment collection mode, then return false - do not show up
$paymode = (int)Configuration::get('AGILE_MS_PAYMENT_MODE');
if(Module::isInstalled('agilemultipleseller') && !self::$PaymentCollectionMode[$paymode])return false;


3. Register a hook to inform multiple seller module to integrate 
Inside your module install method, adding a line to register HOOK actionAgilePaymentModuleIntegrate to inform agile multiple seller module to integrate this payment module. 


public function uninstall()
{
   if(!parent::uninstall())return false;
   if (!parent::install()
      OR !$this->registerHook('actionAgilePaymentModuleIntegrate') 
      OR !Configuration::updateValue('AGILE_PAYPALPL_BUSINESS', '[email protected]')
      OR !Configuration::updateValue('AGILE_PAYPALPL_SANDBOX', 1)
      OR !$this->registerHook('displayPayment')
      OR !$this->registerHook('displayPaymentReturn')
    )return false;
    .............

}

4. Prepare hook method to return the required integration information
Create following method in your payment module core class, so it will be called by multiple seller module to retrieve integration related information.

public function hookActionAgilePaymentModuleIntegrate($params)
{
   return array(
      'name' => $this->name,
      'desc' => $this->displayName,
      'mode' => self::$PaymentCollectionMode,
       'elinks' => array(
             array(
                  'label' =>$this->l('Authorize Stripe Connection')
                  ,'url'=>'https://connect.stripe.com/oauth/authorize'
                  ,'tooltip' =>$this->l('Click here to authorize or re-authorize your Stripe Account to connect with this marketplace platform')
             ),
      ),

      'info1' => array('label' => $this->l('API Login ID'), 'is_unique'=>1, 'is_readonly' => 0,'tooltip' => $this->l('Explanation of the fiels')),
      'info2' => array('label' => $this->l('Transaction Key'),'is_unique'=>1, 'is_readonly' =>1,'tooltip' => $this->l('Explanation of the fiels')),
      'info3' => array('label' => 'N/A','is_unique'=>0,'is_readonly' => 0,'tooltip' => ''),

      'info4' => array('label' => 'N/A','is_unique'=>0,'is_readonly' => 0,'tooltip' => ''),
      'info5' => array('label' => 'N/A','is_unique'=>0,'is_readonly' => 0,'tooltip' => ''),
      'info6' => array('label' => 'N/A','is_unique'=>0,'is_readonly' => 0,'tooltip' => ''),
      'info7' => array('label' => 'N/A','is_unique'=>0,'is_readonly' => 0,'tooltip' => ''),
      'info8' => array('label' => 'N/A','is_unique'=>0,'is_readonly' => 0,'tooltip' => ''),
    );
}

seller payment setting screen - integrated module

In above hook method, you will provide following information to agile multiple seller module.
- name of the module (internal name)
- description of the module (display name of the module)
- available payment collection mode your module will support
- payment information that seller has to provide to collect payment from buyers through this module. This usually the configuration fields of your modules. There are maximium 8 fields available for use.  The number of fields required depend on your payment module. 

Most cases the information fields requited for main store is different from sellers, but sometime they are the same. For example, Agile Authorize.NET module will have following 2 fields as defined in above sample code.
 - API Log ID
 - Transaction Key

You have to define the label of the field and also specify if the field is part of the unique fields to be validated when a seller adding new payment info. The module will use the fields with is_unique value 1 to check if the payment information is the same with other sellers to avoid duplication.  

Note
Please keep the code the way it is, only change the value so that the label will be able to support multiple languages and you will be able to translate the field name into different languages at back office - Localizations - Transactions tab

5. Prepare payment info field validator (Optional)
Each seller will need to enter payment information for receiving payment from buyers (or from store). You may need validate each field that seller enters is valid data. For example, if it is a Paypal module, you will want to validate the first field "info1" that seller entered is a valid email address.

Here is an example of validator in your payment module

public function validatePaymentInfoFields($paymentinfo)
{
    $errors = array();
   
    if(empty($paymentinfo))$errors[] = $this->l('Invalid payment information');

    $info1 = (is_array($paymentinfo) ? $paymentinfo['info1'] : $paymentinfo->info1);
    if(!Validate::isEmail($info1))$errors[] = $this->name . ":" . $this->l('Paypl Email Address') . $this->l(' is invalid.');

    return $errors;
}


6. Process payment and validateOrder() - create order
In order to integrate your payment module, your payment module must follow the standard steps of PrestaShop checkout and order processing procedure related to the payment. Here is the process that is related to order payment.

 ==> A. Retrieve Payment  info ==> B. Perform Payment ==>  C. ValidateOrder(Create Order data)

Retrieve payment data 

You will need to call following method of Agiile Mulltiple Seller module to receive the payment data.

$payments = AgileMultipleSeller::get_payment_info_from_cart();

The module will return an array with payment data information based on the Payment Collection mode. Each element of the array will contain following information.

- $id_seller as key of array
- 'email": recipient (seller) email address(seller or store), for example, [email protected]
- 'amount': the amount of the recipient should receive, for example, $230.00
- 'commission': the commission of the seller to pay or the store to receive

Note
: the amount is in shopping cart currency, you will need to convert to your payment module specificed currency before send to payment getway.

Below is the sample code to show the payment data for your payment module. 

$payments = AgileMultipleSeller::get_payment_info_from_cart();
foreach($payments $id_seller => $payment)
{
    ... payment processing code 
}

$this->validateOrder(.....)
 

The code for processing payment will be different for different payment modules.  We will leave for you to determine how to implement the payment. We will also leave the payment error handling for you to handle. For example, if there are  multiple seller in one shopping cart, you will need handle if some seller payment failed. Some credit cart payment supports 2 steps - Authorize the payment first then capture the amount to finish one payments, we suggest you authorize all sellers payment first then validateOrder() and then call "capture" to finalize the payments.

Note:

Depending on the payment gateway, you may need to seller's payment information such as API credentials instead of your store's if the payment recipient is seller.   You can use following code to get seller payment information (such as API credentials) for your payment module.

        include_once(_PS_ROOT_DIR_ . "/modules/agilemultipleseller/AgileSellerPaymentInfo.php");
        $paymentinfo = AgileSellerPaymentInfo::getForSellerByModuleName($this->name, $id_seller);




Have fun with the integration.