You are here

function commerce_paypal_ec_set_express_checkout in Commerce PayPal 7.2

Submits a SetExpressCheckout request to PayPal for the given order.

This function does not make any changes to the given order, so storage of the token in the order's data array must happen separately. Additionally, the $order must already have a payment_redirect_key in its data array for the proper creation of return and cancel URLs in the API request.

Parameters

$payment_method: The payment method instance array containing the Express Checkout settings.

$order: The order to set Express Checkout for.

$flow: Either 'ec' or 'mark' indicating which Express Checkout flow the token is being requested for.

Return value

The Express Checkout token if successful or FALSE if not.

2 calls to commerce_paypal_ec_set_express_checkout()
commerce_paypal_ec_order_form_submit in modules/ec/commerce_paypal_ec.module
Submit handler: redirect to PayPal Express Checkout.
commerce_paypal_ec_submit_form_submit in modules/ec/commerce_paypal_ec.module
Payment method callback: submit form submission.

File

modules/ec/commerce_paypal_ec.module, line 1015
Implements PayPal Express Checkout in Drupal Commerce checkout.

Code

function commerce_paypal_ec_set_express_checkout($payment_method, $order, $flow) {

  // Extract the order total value array.
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
  $order_total = $order_wrapper->commerce_order_total
    ->value();

  // Determine the currency code to use to actually process the transaction,
  // which will either be the default currency code or the currency code of the
  // order if it's supported by PayPal if that option is enabled.
  $currency_code = $payment_method['settings']['currency_code'];
  if (!empty($payment_method['settings']['allow_supported_currencies']) && in_array($order_total['currency_code'], array_keys(commerce_paypal_currencies('paypal_ec')))) {
    $currency_code = $order_total['currency_code'];
  }

  // Build a name-value pair array for this transaction.
  $nvp = array(
    'METHOD' => 'SetExpressCheckout',
    // Default the Express Checkout landing page to the Mark solution.
    'SOLUTIONTYPE' => 'Mark',
    'LANDINGPAGE' => 'Login',
    // Disable entering notes in PayPal, as we don't have any way to accommodate
    // them right now.
    'ALLOWNOTE' => '0',
    'PAYMENTREQUEST_0_PAYMENTACTION' => commerce_paypal_payment_action($payment_method['settings']['txn_type']),
    'PAYMENTREQUEST_0_AMT' => commerce_paypal_price_amount($order_total['amount'], $order_total['currency_code']),
    'PAYMENTREQUEST_0_CURRENCYCODE' => $currency_code,
    'PAYMENTREQUEST_0_INVNUM' => commerce_paypal_ipn_invoice($order),
    // Set the return and cancel URLs.
    'RETURNURL' => url('checkout/' . $order->order_id . '/payment/return/' . $order->data['payment_redirect_key'], array(
      'absolute' => TRUE,
    )),
    'CANCELURL' => url('checkout/' . $order->order_id . '/payment/back/' . $order->data['payment_redirect_key'], array(
      'absolute' => TRUE,
    )),
  );

  // If reference transactions are enabled and a billing agreement is supplied...
  if (!empty($payment_method['settings']['reference_transactions']) && !empty($payment_method['settings']['ba_desc'])) {
    $nvp['BILLINGTYPE'] = 'MerchantInitiatedBillingSingleAgreement';
    $nvp['L_BILLINGTYPE0'] = 'MerchantInitiatedBillingSingleAgreement';
    $nvp['L_BILLINGAGREEMENTDESCRIPTION0'] = $payment_method['settings']['ba_desc'];
  }

  // Add itemized information to the API request.
  $nvp += commerce_paypal_ec_itemize_order($order, $currency_code);

  // If Express Checkout Account Optional is enabled...
  if ($payment_method['settings']['ec_mode'] != 'Mark') {

    // Update the solution type and landing page parameters accordingly.
    $nvp['SOLUTIONTYPE'] = 'Sole';
    if ($payment_method['settings']['ec_mode'] == 'SoleBilling') {
      $nvp['LANDINGPAGE'] = 'Billing';
    }
  }

  // Overrides specific values for the Credit payment method.
  if ($flow == 'bml') {
    $nvp['USERSELECTEDFUNDINGSOURCE'] = 'BML';
    $nvp['SOLUTIONTYPE'] = 'SOLE';
    $nvp['LANDINGPAGE'] = 'BILLING';
  }

  // If the shipping module is enabled...
  if (module_exists('commerce_shipping')) {

    // If we have a shipping address, pass it to PayPal and do not allow the
    // customer to set a new one at PayPal.
    if (isset($order_wrapper->commerce_customer_shipping) && !empty($order_wrapper->commerce_customer_shipping->commerce_customer_address)) {
      $shipping_address = $order_wrapper->commerce_customer_shipping->commerce_customer_address
        ->value();

      // Ensure there's a name_line.
      if (empty($shipping_address['name_line'])) {
        $shipping_address['name_line'] = $shipping_address['first_name'] . ' ' . $shipping_address['last_name'];
      }

      // Add the shipping address fields to the request.
      $nvp += array(
        'PAYMENTREQUEST_0_SHIPTONAME' => substr($shipping_address['name_line'], 0, 32),
        'PAYMENTREQUEST_0_SHIPTOSTREET' => substr($shipping_address['thoroughfare'], 0, 100),
        'PAYMENTREQUEST_0_SHIPTOSTREET2' => substr($shipping_address['premise'], 0, 100),
        'PAYMENTREQUEST_0_SHIPTOCITY' => substr($shipping_address['locality'], 0, 40),
        'PAYMENTREQUEST_0_SHIPTOSTATE' => substr($shipping_address['administrative_area'], 0, 40),
        'PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE' => substr($shipping_address['country'], 0, 2),
        'PAYMENTREQUEST_0_SHIPTOZIP' => substr($shipping_address['postal_code'], 0, 20),
      );

      // For the Mark flow, do not prompt for an address at PayPal unless the
      // payment method explicitly asks to.
      if ($payment_method['settings']['shipping_prompt'] != '2' && $flow == 'mark') {
        $nvp += array(
          'NOSHIPPING' => '1',
          'ADDROVERRIDE' => '1',
        );
      }
      else {
        $nvp += array(
          'NOSHIPPING' => '0',
          'ADDROVERRIDE' => '0',
        );
      }
    }
    else {

      // Allow the customer to specify a shipping address at PayPal if enabled.
      if ($payment_method['settings']['shipping_prompt'] != '0') {
        $nvp['NOSHIPPING'] = '0';
      }
      else {
        $nvp['NOSHIPPING'] = '1';
      }
    }
  }
  else {

    // Otherwise disable shipping options entirely.
    $nvp['NOSHIPPING'] = '1';
  }

  // Submit the SetExpressCheckout API request to PayPal.
  $response = commerce_paypal_api_request($payment_method, $nvp, $order);

  // If the request is successful, return the token.
  if (in_array($response['ACK'], array(
    'SuccessWithWarning',
    'Success',
  ))) {
    return $response['TOKEN'];
  }

  // Otherwise indicate failure by returning FALSE.
  return FALSE;
}