You are here

function commerce_payflow_link_redirect_form_submit in Commerce PayPal 7.2

Payment method callback: redirect form return submission.

File

modules/payflow/commerce_payflow.module, line 728
Implements PayPal Payments Advanced (U.S. only) and Payflow Link Hosted Checkout pages and Transparent Redirect.

Code

function commerce_payflow_link_redirect_form_submit($order, $payment_method) {
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
  $order_total = $order_wrapper->commerce_order_total
    ->value();

  // Determine the currency code used to actually process the transaction,
  // which will either be the default currency code or the currency code of the
  // charge if it's supported by PayPal if that option is enabled.
  if (!empty($_POST['CURRENCY'])) {
    $currency_code = $_POST['CURRENCY'];
  }
  else {
    $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($payment_method['method_id'])))) {
      $currency_code = $order_total['currency_code'];
    }
  }

  // Convert the order total to the currency specified by the settings.
  $amount = commerce_currency_convert($order_total['amount'], $order_total['currency_code'], $currency_code);

  // Prepare a transaction object to log the API response.
  $transaction = commerce_payment_transaction_new($payment_method['method_id'], $order->order_id);
  $transaction->instance_id = $payment_method['instance_id'];
  $transaction->amount = commerce_currency_decimal_to_amount($_POST['AMT'], $currency_code);
  $transaction->currency_code = $currency_code;
  $transaction->payload[REQUEST_TIME] = $_POST;
  $transaction->remote_id = $_POST['PNREF'];
  $transaction->data['commerce_payflow']['pnref'] = $_POST['PNREF'];

  // Determine the type of transaction.
  if (!empty($_POST['TRXTYPE'])) {
    $trxtype = $_POST['TRXTYPE'];
  }
  elseif (!empty($_POST['TYPE'])) {
    $trxtype = $_POST['TYPE'];
  }
  else {
    $trxtype = $payment_method['settings']['trxtype'];
  }

  // Store the type of transaction in the remote status.
  $transaction->remote_status = $trxtype;
  $trxtype_name = commerce_payflow_trxtype_name($trxtype);

  // Build a meaningful response message.
  $message = array();

  // Set the transaction status based on the type of transaction this was.
  if (intval($_POST['RESULT']) == 0) {
    switch ($trxtype) {
      case 'S':
        $transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
        break;
      case 'A':
      default:
        $transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
        break;
    }
    $message[] = '<b>' . t('@action - Success', array(
      '@action' => $trxtype_name,
    )) . '</b>';
  }
  elseif (intval($_POST['RESULT']) == 126) {
    $transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
    $message[] = '<b>' . t('@action - Pending fraud review', array(
      '@action' => $trxtype_name,
    )) . '</b>';
  }

  // Store the tender type in the transaction's data array.
  $transaction->data['commerce_payflow']['tender'] = $_POST['TENDER'];

  // Add the CC info if present.
  if (!empty($_POST['ACCT']) && !empty($_POST['EXPDATE'])) {

    // Convert the MMYY expiration date to a MM/YY format.
    $exp = str_pad($_POST['EXPDATE'], 4, '0', STR_PAD_LEFT);
    $exp = substr($exp, 0, 2) . '/' . substr($exp, -2);
    if (isset($_POST['CARDTYPE'])) {
      $message[] = t('@cardtype ending in @last4, exp. @exp', array(
        '@cardtype' => commerce_payflow_cardtype_name($_POST['CARDTYPE']),
        '@last4' => $_POST['ACCT'],
        '@exp' => $exp,
      ));
    }
    else {
      $message[] = t('Credit card ending in @last4, exp. @exp', array(
        '@last4' => $_POST['ACCT'],
        '@exp' => $exp,
      ));
    }
  }

  // Add the AVS response if present.
  if (!empty($_POST['AVSADDR']) || !empty($_POST['AVSZIP']) || !empty($_POST['AVSDATA'])) {
    if (!empty($_POST['AVSDATA'])) {
      $avsdata = $_POST['AVSDATA'];
    }
    else {
      $avsdata = '';
      if (!empty($_POST['AVSADDR'])) {
        $avsdata .= $_POST['AVSADDR'];
      }
      if (!empty($_POST['AVSZIP'])) {
        $avsdata .= $_POST['AVSZIP'];
      }
    }
    $message[] = t('AVS response: @avs', array(
      '@avs' => $avsdata,
    ));
  }

  // Add the CVV response if present.
  if (!empty($_POST['PROCCVV2'])) {
    $message[] = t('CVV2 match: @cvv', array(
      '@cvv' => commerce_paypal_cvv_match_message($_POST['PROCCVV2']),
    ));
  }

  // Add the pending reason if present.
  if (!empty($_POST['PENDINGREASON']) && $_POST['PENDINGREASON'] != 'completed') {
    $message[] = commerce_paypal_short_pending_reason($_POST['PENDINGREASON']);

    // And ensure the local and remote status are pending.
    $transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
  }

  // If this was a PayPal payment, store whether or not it came with a billing
  // agreement for use in reference transactions.
  if ($_POST['TENDER'] == 'P') {
    $message[] = t('Payment initiated from a PayPal account.');

    // Add the PayPal fees if given.
    if (!empty($_POST['FEEAMT'])) {
      $message[] = t('PayPal fees: @feeamt', array(
        '@feeamt' => $_POST['FEEAMT'],
      ));
    }

    // Store the payment type so we know if the payment is via echeck.
    if (!empty($_POST['PAYMENTTYPE'])) {
      $transaction->data['commerce_paypal_ec']['paymenttype'] = $_POST['PAYMENTTYPE'];
    }
    else {
      $transaction->data['commerce_paypal_ec']['paymenttype'] = '';
    }

    // Store the billing agreement ID if applicable.
    if (!empty($_POST['BAID'])) {
      $transaction->data['commerce_payflow']['baid'] = $_POST['BAID'];
      $message[] = t('Billing agreement ID: @baid', array(
        '@baid' => $_POST['BAID'],
      ));
    }
    else {
      $transaction->data['commerce_payflow']['baid'] = '';
    }

    // Because follow-up API requests for this transaction must be submitted
    // directly to PayPal, check to see if there's a corresponding Express
    // Checkout payment method configured and update the remote ID to the PayPal
    // transaction ID.
    if (module_exists('commerce_paypal_ec') && !empty($payment_method['settings']['paypal_ec_instance'])) {
      $transaction->remote_id = $_POST['PPREF'];

      // Also update the remote status to match one expected by PayPal.
      if (!is_null(commerce_payflow_paypal_remote_status($trxtype))) {
        $transaction->remote_status = commerce_payflow_paypal_remote_status($trxtype);
      }

      // Finally set the method_id and instance_id to point to the Express
      // Checkout instance.
      $transaction->data['commerce_payflow']['original_instance'] = $payment_method['instance_id'];
      $transaction->payment_method = 'paypal_ec';
      $transaction->instance_id = 'paypal_ec|' . $payment_method['settings']['paypal_ec_instance'];
    }
  }

  // Set the final message.
  $transaction->message = implode('<br />', $message);

  // Save the transaction information.
  commerce_payment_transaction_save($transaction);
}