Getting this error on a custom payment gateway when I am creating an order from the admin page admin/commerce/orders/115/payment:

Notice: Undefined index: payment_details in commerce_payment_order_transaction_add_form_validate() (line 206 of /var/www/sites/all/modules/commerce/modules/payment/includes/commerce_payment.forms.inc).

I know this issue has been fixed in the submit function (https://drupal.org/node/1250900) but I am getting the same error in the validation function. I can't seem to track down how payment_details gets set in the form_state

Comments

nvahalik’s picture

Version: 7.x-1.9 » 7.x-1.x-dev
Status: Active » Needs review
StatusFileSize
new870 bytes

Adding check for empty $form_state['values']['payment_details'].

nvahalik’s picture

Issue tags: +Commerce Sprint
joshmiller’s picture

Reviewing this patch

joshmiller’s picture

Issue summary: View changes
Status: Needs review » Needs work
StatusFileSize
new160.29 KB

Ok, to reproduce the "bug" you have to straight up unset the payment details like this:

/**
 * Validation callback for commerce_payment_order_transaction_add_form().
 */
function commerce_payment_order_transaction_add_form_validate($form, &$form_state) {
  // Testing the worst case scenario
  unset($form_state['values']['payment_details']);

And you will then get this error:

Error issue example.

Though, interestingly, using this with Authorize.net terminal OR the example payment terminal, it also ruins the transaction completely and the payment will not continue. With the patch and the "unsetting" of the array in the same function, this patch trades one error:

Notice: Undefined index: payment_details in commerce_payment_order_transaction_add_form_validate() (line 209 of /commerce/modules/payment/includes/commerce_payment.forms.inc).

For another error (with patch and reproduction code):

Notice: Undefined index: credit_card in commerce_payment_example_submit_form_validate() (line 52 of /commerce/modules/payment/modules/commerce_payment_example.module).

or with Authorize.net (with patch and reproduction code):

Notice: Undefined index: credit_card in commerce_authnet_aim_submit_form_validate() (line 324 of /commerce_authnet/commerce_authnet.module)

So ... needs work :/ We need a way to faithfully reproduce the error to confirm this notice is really the fault of core commerce.

EDIT: Adding error from Authorize.net to prove it's not just a weird example payment error.

torgospizza’s picture

Yeah to me this sounds like the custom payment gateway is not implementing the payment method callbacks correctly. If someone could post the code for that it would help us figure this one out :)

nvahalik’s picture

Status: Needs work » Closed (cannot reproduce)

I have to agree with @torgosPizza. This sounds like a funky module and not a problem with payments. Reporter is free to open the issue again if a link to the code which can reproduce this is posted.

nvahalik’s picture

I just had this pop up on me again and I will say that it is a problem with a payment gateway that doesn't present a payment form. This isn't a bug in Commerce but rather a module that doesn't implement the terminal properly.

nvahalik’s picture

Status: Closed (cannot reproduce) » Active

tl;dr: If your module specifies a payment terminal validation function without specifying a payment terminal form, you'll get this message. To fix it, just create a payment terminal form and return a form with a single value in it. It will then populate the values and not give you this error message.

Okay, re-opening.

When a payment terminal doesn't specify a form, it gets set to a blank array:

if ($callback = commerce_payment_method_callback($payment_method, 'submit_form')) {
  $form['payment_terminal']['payment_details'] = $callback($payment_method, $terminal_values, NULL, $order);
}
else {
  $form['payment_terminal']['payment_details'] = array();
}

When this array is blank, there are no values associated with it. Ergo, when it comes time to do form validation, if there is a validation function, it passes in the $form_state['values']['payment_details'] without checking to see if it actually exists.

Since there is nothing to disallow this, I suggest we simply check to see if the value exists and if it doesn't, then just set it to an empty array.

nvahalik’s picture

Status: Active » Needs review
StatusFileSize
new931 bytes

Attaching a different patch that appears to work for me.

mglaman’s picture

Status: Needs review » Needs work

We do this in commerce_payment_pane_checkout_form_validate()

      if ($callback = commerce_payment_method_callback($payment_method, 'submit_form_validate')) {
        // Initialize the payment details array to accommodate payment methods
        // that don't add any additional details to the checkout pane form.
        if (!isset($pane_values['payment_details'])) {
          $pane_values['payment_details'] = array();
        }
        $result = $callback($payment_method, $pane_form['payment_details'], $pane_values['payment_details'], $order, array($checkout_pane['pane_id'], 'payment_details'));

Looks good, except

+++ b/modules/payment/includes/commerce_payment.forms.inc
@@ -202,6 +202,10 @@ function commerce_payment_order_transaction_add_form_validate($form, &$form_stat
+      // In certain cases, payment_details can be empty, so set it just in case.

Update comment based on checkout pane comment.