Drupal - Commerce partial payment : pay deposit at checkout and full settlement later

I got it working the following way.

  • First install Commerce Partial Payment.
  • Write a custom function to calculate deposit, MODULENAME_deposit_calculation

In order to get Commerce Deposit work with the deposit calculation you like to instead of a customer deposit input, patch it as following :

function commerce_partial_payment_form_commerce_checkout_form_alter(&$form, &$form_state, $form_id) {
  //... line 93
  $acompte = MODULENAME_deposit_calculation($form_state['order']) /100;
    if (!is_null($acompte) && $acompte > 0) {
      $default = $acompte;
    }
  //... line 109 Add the amount to the payment details form,in a hidden field.
  $form['commerce_payment']['payment_details']['amount'] = array(
    '#type' => 'hidden',
  //...
}

function commerce_partial_payment_checkout_validate($form, &$form_state, $checkout_pane, $order) {
  //... line 261
  $amount['amount'] = MODULENAME_deposit_calculation($order)  /100;
  //...
}

function commerce_partial_payment_checkout_submit($form, &$form_state, $checkout_pane, $order) {
  //...line 317
  if ($pane_values['payment_methods']) {
    $amount = MODULENAME_deposit_calculation($order) /100;
    $order->data['atos']['request']['amount'] = $amount;
    if (!empty( $amount)){
      $amount['amount'] = $amount;
  //...
}

As the sandbox doesn't properly send the deposit amount to off site payment, we need to hook the payment method :

In a METHOD_PAYMENT.api.php file

function hook_METHOD_PAYMENT_request_alter(&$settings) {
  //no example
}

Now send to off site payment the deposit amount instead of order total :

function commerce_partial_payment_PAYMENT_METHOD_request_alter(&$settings) {
  $order = commerce_order_load($settings['order_id']);
  $deposit = MODULENAME_deposit_calculation($order);
  $settings['amount'] = $deposit;
}

Last, add a price component deposit below Total to inform the customer what he's going to pay.

function commerce_partial_payment_commerce_price_formatted_components_alter(&$components, $price, $entity) {
  //Add a deposit line to price components
  $deposit= MODULENAME_deposit_calculation($entity);

  $components['deposit'] = array(
      'title' => t('Deposit'),
      'price' => array(
        'amount' => $deposit,
        'currency_code' => $components['commerce_price_formatted_amount']['price']['currency_code'],
        'data' => '',
      ),      
    'weight' => '200',
  );
}