You are here

function commerce_worldpay_bg_order_form in Commerce Worldpay 7

Build the form to be submitted to WorldPay.

See also

commerce_worldpay_bg_redirect_form()

1 call to commerce_worldpay_bg_order_form()
commerce_worldpay_bg_redirect_form in ./commerce_worldpay_bg.module
Implements hook_redirect_form().

File

./commerce_worldpay_bg.module, line 580
Provides a Worldpay Business Gateway payment method for Drupal Commerce.

Code

function commerce_worldpay_bg_order_form($form, &$form_state, $order, $settings) {
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
  $currency_code = $order_wrapper->commerce_order_total->currency_code
    ->value();
  $amount = $order_wrapper->commerce_order_total->amount
    ->value();

  // @todo Find out which should really be used for the ammount or are they the same?
  // $amount = commerce_line_items_total($order_wrapper->commerce_line_items);
  // Ensure a default value for the payment_method setting.
  $settings += array(
    'payment_method' => '',
  );

  // Load customer profile.
  $profile = commerce_customer_profile_load($order->commerce_customer_billing[LANGUAGE_NONE][0]['profile_id']);

  // Get user billing address.
  $address = $profile->commerce_customer_address[LANGUAGE_NONE][0];

  // Necessary for country_get_list() so we can get the country name. Is this
  // how the Drupal include files should be loaded?
  require_once DRUPAL_ROOT . '/includes/locale.inc';
  $countries = country_get_list();
  $country = !empty($countries[$address['country']]) ? $countries[$address['country']] : '';

  // Build the data array that will be translated into hidden form values.
  $data = array();
  if ($settings['payment_parameters']['test_mode']) {
    $worldpay_name = $settings['payment_parameters']['test_result'];
    $data = array(
      'testMode' => '100',
    );
  }
  else {

    // Not sure if this would ever happen but hay
    if (!empty($address['name_line'])) {
      $worldpay_name = drupal_substr($address['name_line'], 0, 128);
    }
    elseif (!empty($address['first_name']) && !empty($address['last_name'])) {
      $worldpay_name = drupal_substr($address['first_name'] . ' ' . $address['last_name'], 0, 128);
    }
    elseif (isset($address['organisation_name'])) {
      $worldpay_name = substr($address['organisation_name'], 0, 128);
    }
  }

  // @todo provide a hook to override address_post in order to give other modules a chance to provide this info from elsewhere.
  // @todo Look into producing a formatter for addressfield.
  $address_post = (!empty($address['thoroughfare']) ? $address['thoroughfare'] . "\n" : '') . (!empty($address['premise']) ? $address['premise'] . "\n" : '') . (!empty($address['sub_premise']) ? $address['sub_premise'] . "\n" : '') . (!empty($address['locality']) ? $address['locality'] . "\n" : '') . (!empty($address['dependent_locality']) ? $address['dependent_locality'] . "\n" : '') . (!empty($address['sub_administrative_area']) ? $address['sub_administrative_area'] . "\n" : '') . (!empty($address['administrative_area']) ? $address['administrative_area'] . "\n" : '');

  // Separate post fields.
  if (!empty($address['thoroughfare'])) {
    $data['address1'] = $address['thoroughfare'];
  }
  if (!empty($address['premise'])) {
    $data['address2'] = $address['premise'];
  }
  if (!empty($address['locality'])) {
    $data['town'] = $address['locality'];
  }
  if (!empty($address['administrative_area'])) {
    $data['region'] = $address['administrative_area'];
  }
  if (!empty($address['country'])) {
    $data['country'] = $address['country'];
  }
  $response_url = commerce_worldpay_bg_response_url($settings['payment_method'], $settings['payment_urls']['use_ssl']);
  $salt = $settings['payment_security']['md5_salt'];

  // Invoke the extra post field hook. We do this first so that we can
  // overwrite fields that should not be set by this hook.
  $extra_data = module_invoke_all('commerce_worldpay_bg_post_data', $order, $profile, $settings);
  if (!is_array($extra_data)) {
    $extra_data = array();
  }
  if (!empty($GLOBALS['language']->prefix) && drupal_multilingual()) {
    $http_host = $_SERVER['HTTP_HOST'] . '/' . !empty($GLOBALS['language']->prefix);
  }
  else {
    $http_host = $_SERVER['HTTP_HOST'];
  }

  // @todo wouldn't it be easier to add those values to $data and then do a drupal_alter?
  $data += array_replace($extra_data, array(
    'instId' => $settings['installation_id'],
    'amount' => round(commerce_currency_amount_to_decimal($amount, $currency_code), 2),
    'cartId' => $order->order_number,
    'currency' => $currency_code,
    'name' => $worldpay_name,
    'address' => $address_post,
    'postcode' => $address['postal_code'],
    'countryString' => $country,
    'email' => $order->mail,
    // @todo make it possible to select a field to be used for the telephone data
    // 'tel' => $profile->field_telephone,
    'MC_orderId' => $order->order_id,
    'lang' => $settings['payment_parameters']['lang'],
    'M_http_host' => $http_host,
    // @see http://www.worldpay.com/support/kb/bg/htmlredirect/rhtml.html
    'signatureFields' => join(':', _commerce_worldpay_bg_md5_signature_fields()),
    'signature' => commerce_worldpay_bg_build_md5(_commerce_worldpay_bg_build_sig_array($order_wrapper, $settings['installation_id'], $response_url), $salt),
    // The path WorldPay should send its Payment Response to
    'MC_callback' => $response_url,
    // Used in WorldPay custom pages
    'C_siteTitle' => variable_get('site_name', 'Drupal Commerce'),
  ));

  // Allows for generating some unique information that can be used
  // for CSS selectors and folder names. Allowing one WorldPay
  // account to serve multiple sites with each altering its
  // presentation.
  if (isset($settings['site_id'])) {
    $data['C_siteId'] = $settings['site_id'];
  }
  if (isset($order->data['commerce_worldpay_bg']) && isset($order->data['commerce_worldpay_bg']['paymentType'])) {
    $data['paymentType'] = $order->data['commerce_worldpay_bg']['paymentType'];
  }

  // @todo
  // Implement support for authValidFrom and authValidTo in order to prevent
  // purchases on limited time offers.
  // Get the product line item count and build cart description.
  $order_post = '';
  $commerce_line_items = field_get_items('commerce_order', $order, 'commerce_line_items');
  $prod_count = 0;
  foreach ($commerce_line_items as $item) {
    $line_item = commerce_line_item_load($item['line_item_id']);
    $description = $line_item->line_item_label;
    $quantity = $line_item->quantity;

    //$item_total = $line_item->commerce_unit_price[LANGUAGE_NONE][0]['amount'] / 100;
    $item_total = commerce_currency_format($line_item->commerce_unit_price[LANGUAGE_NONE][0]['amount'], $line_item->commerce_unit_price[LANGUAGE_NONE][0]['currency_code']);
    $line_total = commerce_currency_format($line_item->commerce_total[LANGUAGE_NONE][0]['amount'], $line_item->commerce_total[LANGUAGE_NONE][0]['currency_code']);
    $order_post .= "{$description} ({$item_total}) x {$quantity}: {$line_total}\n";
    if ($line_item->type == 'product') {
      $prod_count++;
    }
  }

  // Worldpay allows up to 255 characters but appends "FuturePay" to recurring payments.
  $order_post = substr($order_post, 0, 244);

  // Add a summary of content to the description.
  if ($settings['payment_parameters']['cart_in_desc']) {
    $data += array(
      'desc' => t("Cart contents: \n@cart", array(
        '@cart' => $order_post,
      )),
    );
  }

  // Add a custom WorldPay param for product count.
  $data['C_productCount'] = $prod_count;
  $data['C_lineItemCount'] = count($commerce_line_items);
  if (!$settings['payment_parameters']['edit_contact']) {
    $data += array(
      'fixContact' => 'true',
    );
  }
  if (!$settings['payment_parameters']['show_contact']) {
    $data += array(
      'hideContact' => 'true',
    );
  }
  $form['#action'] = $settings['payment_parameters']['test_mode'] ? $settings['payment_urls']['test'] : $settings['payment_urls']['live'];
  foreach ($data as $name => $value) {
    if (!empty($value)) {
      $form[$name] = array(
        '#type' => 'hidden',
        '#value' => $value,
      );
    }
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Proceed to WorldPay to make your payment'),
    '#name' => 'wp-sub',
  );
  if ($settings['debug'] != 'none') {
    if ($settings['debug'] == 'screen' || $settings['debug'] == 'both') {
      debug($data, 'Post data');
    }
    if ($settings['debug'] == 'log' || $settings['debug'] == 'both') {
      watchdog('commerce_worldpay_bg', "Data to be posted for order !order_id:\n <pre>!log</pre>.", array(
        '!order_id' => $order->order_id,
        '!log' => print_r($data, TRUE),
      ), WATCHDOG_NOTICE);
    }
  }
  return $form;
}