This attempts to re-add the ability to create a card on file without going through checkout. This patch definitely needs review, but hopefully it saves someone a bit of time. I'll update this with the issue number of the related commerce_authnet patch.

Comments

benjf’s picture

found an issue with permissions, updated patch attached.

also, the related issue in commerce_authnet is #2051357: Add card on file outside of the checkout process

balintbrews’s picture

I refactored the current Card on File update functionality and incorporated the support of creating new card data. Thanks @benjf, your patch was a great starting point for this work!

dwkitchen’s picture

Looks like what I was thinking, I will give it a test with Amex and Sagepay

warmnoise’s picture

These patches have been very helpful in getting an admin-centered workflow going in a CIM setup. I've been reviewing / testing with authorize.net and have success. One security issue that I found was that any user is able to view /users/%/cards. I propose that this type of redirect can help. Basically making sure that any user without access cannot see another user's cof profile area.

// Starting on line 440 of commerce_cardonfile_access() (after patch-3)
<?php
  // DENY if we are trying to view another user's cards listing
  if ($op == 'edit' && !user_access("administer card data") || !user_access("$op any card data") ) {
    $profile_owner = explode('/',current_path());
    if (is_numeric($profile_owner[1])) {
      if ($user->uid != $profile_owner[1]) {
        commerce_cardonfile_redirect_to_user($user);
        return FALSE;
      }
    }
  }
?>
jpstrikesback’s picture

+++ b/includes/commerce_cardonfile.pages.incundefined
@@ -25,62 +25,99 @@ function commerce_cardonfile_card_view($card_data, $view_mode) {
+function commerce_cardonfile_card_form_page($op, $card_data) {
...
...
...
+
+  if ($form_callback = commerce_cardonfile_payment_method_callback($payment_method, $op . ' form_callback')) {
+    return drupal_get_form($form_callback, $card_data);
   }
   else {
-    return drupal_get_form('commerce_cardonfile_update_form', $card_data);
+    return drupal_get_form('commerce_cardonfile_card_form', $op, $card_data);
   }

I think it would be nice if the "$op form callback" forms received the $op param just like the default form.

+  if ($form_callback = commerce_cardonfile_payment_method_callback($payment_method, $op . ' form_callback')) {
+    return drupal_get_form($form_callback, $op, $card_data);
   }
balintbrews’s picture

@warmnoise: Thanks for pointing out this problem. It turned out that there was an argument validator handler in place that we can use to solve it. The handler just needed some small fixing. I also noticed that it was possible to add a new card on behalf of another user, this has also been fixed.

@jpstrikesback: Totally agree, thanks for the suggestion!

balintbrews’s picture

A small fix.

dwkitchen’s picture

Status: Needs review » Fixed

Thanks for the patch.

There is a change needed in any payment modules that have implemented a custom update for, but I think this is only Amex so far as you have based PayMill on this patch.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

companyguy’s picture

I'm still not able to add new cards. Going to /user/%user/cards/add/ results in a "page not found" even though I can see the code for this patch in the newest dev release...

stefank’s picture

@companyguy

You need to click the link for add new card, shown on the top in stored cards tab. The page is not found, because the link is always adding an hash after the /user/%user/cards/add/.
Hope that helps to clarify it.

favrik’s picture

Is it expected to not be able to add a card with Authorize.NET & CIM because there is to "create callback" in the commerce_payment_method_info() hook ?

jeremymcminn’s picture

Would anyone be able to provide a small snippet on how to add a class to the "Add new card details" link to make for easier CSS theming?

I've stuck this in, but as you can expect nothing came of it. More a site builder than a developer, any help would be appreciated.

'attributes' => array(
        'class' => array('xxx'),
    ),

Thanks

stefank’s picture

@jeremymcminn

Had the same problem and sort it out by adding hook_form_alter into custom module.

/**
 * Implements hook_form_alter().
 */
function modulename_form_alter(&$form, $form_state, $form_id)
{
    if($form_id == 'commerce_cardonfile_card_form') {
        if($form_state['op'] == 'create'){
            $form['credit_card']['type']['#prefix'] = '<div class="credit-card">';
            $form['submit']['#suffix'] = '</div';

        }
    }
    
    return $form;
}
jeremymcminn’s picture

Ah brilliant, thanks!

I used a hacky version of CSS by theming the operation links on that particular page using a body class, but this would be much better.

Thanks

subu.purohit’s picture

Issue summary: View changes
Issue tags: +Not able to find

@stefank
I am not able to find that link. I am in "user/1/cards" but can see only:
"You do not have any stored credit cards on file for this account."
From where I can find that link? is there any way to create this button manually?

stefank’s picture

@subu.purohit Just to mention this is a bad idea, but you can add the code to views header/footer with php field (http://site-name/admin/structure/views/view/commerce_card_on_file_user_c.... The add to card should work when u enable ur payment gateway. The code below is a hack.
hope it helps.

<?php
global $user;
// create paths for each payment method
  $create_implements = commerce_cardonfile_payment_method_implements('create callback');
  foreach ($create_implements as $method_id => $method_function) {
    $payment_method_instances = _commerce_cardonfile_payment_method_instances($method_id, TRUE);
    if (empty($payment_method_instances)) {
      continue;
    }

    foreach ($payment_method_instances as $instance_id => $payment_method) {
      $new_card_data = commerce_cardonfile_new(array(
        'instance_id' => $instance_id,
        'payment_method' => $payment_method['method_id'],
      ));
      $url='/user/'.$user->uid.'/cards/add/' . drupal_hash_base64($instance_id);
	}
  }
?>
<a class="button button-light" href="<?php print $url; ?>">Add Card</a>
subu.purohit’s picture

@ stefank

Thank you for getting back to me.

This is giving me a blank array:

$create_implements = commerce_cardonfile_payment_method_implements('create callback');

thats why my code inside foreach loop is not executing. I have enabled authorized.net payment method.
Any idea?

stefank’s picture

Have you added the patch from https://drupal.org/node/1850100 ?

subu.purohit’s picture

Thank you Stefank,

It brings me the link "Add a card for payments with Credit card" and it is working fine on my localhost. But when I deployed it in server it is giving me "Access denied" error. But if I use same hash code then it is coming properly. Any idea why I am getting this error with different hash code?

stefank’s picture

Check that the user have permissions to add new card.

subu.purohit’s picture

I dont know why it was coming but when I removed that new button "Add card" from views then it is working properly.
After adding new card it is showing me the message "A new card has been added." but under stored card it is still showing me "You do not have any stored credit cards on file for this account."
I am using example visa card for authorized.net. Is there anything else I need to configure?

stefank’s picture

Any cards in http://[your_site]/admin/commerce/cards ?

subu.purohit’s picture

Yes there are 4 cards stored and those are stored using checkout.
But the new testing card x-1111 is stored in some other user's account. is it an issue?

stefank’s picture

Try to open a new issue.

oystercrackher’s picture

@subu.purohit for your error in #22,

Please try the suggestions here: https://drupal.org/node/2224063 (See #6)

Thanks

Gaurav.Singh’s picture

StatusFileSize
new120.21 KB

Hi,

After creating a link for Add Card (Add a card for payments with Credit card) when i tried to add a demo credit card detail when the card detail should be accepted, I am getting the page for "No Data Recived" attaching the page

stefank’s picture

@gaurav.singh

Any errors in logs?

Gaurav.Singh’s picture

Yes it gives an error of malformed.

stefank’s picture

Could you submit the full error message please?

Gaurav.Singh’s picture

Yes @stefank please see,

Type: commerce_authnet
Date: Monday, September 22, 2014 - 22:41
User: admin
Location: My URL
Referrer: My URL
Message: cURL error: url malformed
Severity: error
Hostname: My IP Address

Please help me out with this if anyone of you can.
Thanks in advance for your help.

sbasi’s picture

Hi, I am looking to store credit card number as a node field. I know it won't be PCI compliant but I still need it. Any suggestions how I can use this module or any of the other payment modules to do so. I won't be integrating a payment gateway.

thermalmusic’s picture

Hi,
I have cardonfile 7.x-2.0-Beta5+2-dev installed. I'm assuming that commerce_cardonfile-create-card-outside-checkout-7.patch is included in this version. But I do not see the 'Add card' link in any users 'Stored cards' tab, with or without added cards from checkout. All the card permissions are checked. Looked in the view for that link as well but do not see any reference to it. We are using authorize.net with CIM enabled.

Can anyone suggest what I am missing?

Thanks

sbasi’s picture

Update on https://www.drupal.org/node/2051331#comment-9405695

I was able to resolve this by adding a custom plugin to the field validation module with LUHN's algorithm.