1

Please note that this is not a duplicate question - the existing questions do not address the issue with the same level of specificity.

I am receiving the following error when attempting to process credit cards via PayPal PayFlow:

Fatal error: Uncaught SoapFault exception: [1008] Credit card number mismatch with credit card type.

I have fully configured PayFlow within Magento with test mode active using identical PayPal credentials to those used in another (fully functional, non-Magento) application.

I have a shopping cart active with a user and products successfully attached - I have tested this portion by submitting the test payment as a check order and it works fine.

Once the cart is ready, I attach payment details as follows:

$paymentMethod = array(
    'po_number' => null,
    'method' => 'verisign',
    'cc_cid' => '123',
    'cc_owner' => $customer['firstname'].' '.$customer['lastname'],
    'cc_number' => '4111111111111111',
    'cc_type' => 'VI',
    'cc_exp_year' => '2022',
    'cc_exp_month' => '12'
);
$proxy->shoppingCartPaymentMethod($sessionId, $cartId, $paymentMethod);

At this point, no errors have been thrown. The error occurs after the following code:

$proxy->shoppingCartOrder($sessionId, $cartId, null, null);

What could be causing this error? Are there any known starting points for fixing it? Thanks in advance!

5
  • You don't have a single question in your question. Feb 18, 2015 at 21:43
  • I assumed the question of how to fix the error was implied. Feb 18, 2015 at 22:48
  • Have you tried using the checkout method without setting payment method data programmatically and set breakpoints to determine how it should behave and the input it needs? Feb 18, 2015 at 22:57
  • How it should behave and the input it needs are documented. And as I said in the question, I verified functionality of the checkout process using a check payment - yes that check payment was set programmatically, but it covers the bases you are asking me if I have covered. Feb 19, 2015 at 16:20
  • Documentation and how things work are two very different things, especially when it comes to Magento. I fail to see how using an entirely different payment method programmatically automatically verifies your paypal extn as working. Once again - I would just run a regular checkout (not programmatically) with a breakpoint to find out what's going on and why your programmatic method isn't working. Feb 19, 2015 at 16:41

2 Answers 2

1

I think this post on Stack Overflow is most immediately relevant to you.

The issue is PCI Compliance. Magento never saves credit card information in it's system for payment processing, since that would put customers' financial information at risk. Instead, it uses PayPal (or Authorize.net or whatever) as a payment gateway.

The problem is that the API is designed to have two round trips to your server to create your order - the cartPaymentMethod to add the credit card, shoppingCartOrder to process the order. Because of that PCI compliance, and because Magento doesn't ever store CC data by the time the second call is made Magento has already lost the card info. Viola, CC mistmatch.

The solution is to create an extension to the API that would alter shoppingCartOrder to accept the payment info and effectively run both calls at the same time. Unfortunately, I've yet to find one that exists. I'm on the lookout for a solution as well, and if one should arise I'll be sure to post a subsequent note here.

1

I ran into this issue as well. My solution was to create a custom SOAP endpoint which handled all of the order creation and submission logic at once without multiple API calls.

Even this way, I was getting card type mismatch exceptions.

The trick was once I set the payment info, collect totals, and save quote, with the getPayment->importData method, it seems to forget the card info. Probably for (not the best way to handle) PCI-DSS compliance.

To solve it, I added another getPayment->importData line after saving the quote, before submitting the order.

See example:

public function customCheckout($checkoutData=false)
  {
    if(!$checkoutData){
      Mage::throwException("No checkout data received.");
    }
    if(!json_decode($checkoutData)){
      Mage::throwException("Bad checkout data received.");
    }

    $data = json_decode($checkoutData);

    $email = '[email protected]';

    // get the basic store info to associate with order
    $websiteId  = Mage::app()->getWebsite()->getId();
    $store      = Mage::app()->getStore();

    // begin checkout with a quote
    $quote    = Mage::getModel('sales/quote')->setStoreId($store->getId());

    // set customer by email
    $customer = Mage::getModel('customer/customer')
                  ->setWebsiteId($websiteId)
                  ->loadByEmail($email);

    // handle customer not exists by creating a new customer
    if($customer->getId() == ''){
      $customer = Mage::getModel('customer/customer');
      $customer->setWebsiteId($websiteId)
               ->setStore($store)
               ->setFirstName("Bob")
               ->setLastName("Loblaw")
               ->setEmail($email)
               ->setPassword('password');
      $customer->save();
    }

    // assign customer to SO quote
    $quote->assignCustomer($customer);

    // do we want to send a confirmation email to the customer?
    // my guess is we would handle that in a separate service.
    $quote->setSendConfirmation(0);

    // add products to quote
    foreach($data->products as $item){
      $product = Mage::getModel('catalog/product')->load($item->id);
      $quote->addProduct($product,new Varien_Object(array('qty'=>$item->qty)));
    }

    // set SO billing address
    $billingAddress = $quote->getBillingAddress()->addData(array(
      'customer_address_id' => '',
      'prefix' => '',
      'firstname' => $data->customer->firstName,
      'middlename' => '',
      'lastname' => $data->customer->lastName,
      'suffix' => '',
      'company' => '',
      'street' => array(
        '0' => 'street1',
        '1' => 'street2'
      ),
      'city'=>'city',
      'country_id'=>'US',
      'region'=>'WA',
      'postcode'=>'98101',
      'telephone' => '425-425-4254',
      'fax' => '789-789-7897',
      'vat_id' => '',
      'save_in_address_book' => 0
    ));

    // set SO shipping address, this will probably be the location of sale, on-site
    $shippingAddress = $quote->getShippingAddress()->addData(array(
      'customer_address_id' => '',
      'prefix' => '',
      'firstname' => $data->customer->firstName,
      'middlename' => 'middle',
      'lastname' => $data->customer->lastName,
      'suffix' => '',
      'company' => '',
      'street' => array(
        '0' => 'street1',
        '1' => 'street2'
      ),
      'city'=>'city',
      'country_id'=>'US',
      'region'=>'WA',
      'postcode'=>'98201',
      'telephone' => '425-425-4254',
      'fax' => '789-789-7897',
      'vat_id' => '',
      'save_in_address_book' => 0
    ));

    // set shipping method, if it's sold on site we aren't charging for delivery
    $shipMethod='freeshipping_freeshipping';

    $shippingAddress->setCollectShippingRates(true)
                    ->collectShippingRates()
                    ->setShippingMethod($shipMethod)
                    ->setPaymentMethod($data->payment->method);

    // set payment method
    $quote->getPayment()->importData(array(
      'method'      =>$data->payment->method,
      'cc_type'     =>$data->payment->type,
      'cc_number'   =>$data->payment->number,
      'cc_exp_year' =>$data->payment->expYear,
      'cc_exp_month'=>$data->payment->expMonth,
    ));

    // collect totals, save quote
    $quote->collectTotals()->save();

    // turn the quote into an order
    $service = Mage::getModel('sales/service_quote',$quote);

    // set payment method A SECOND TIME!!!!!!!!!!!!!
    $quote->getPayment()->importData(array(
      'method'      =>$data->payment->method,
      'cc_type'     =>$data->payment->type,
      'cc_number'   =>$data->payment->number,
      'cc_exp_year' =>$data->payment->expYear,
      'cc_exp_month'=>$data->payment->expMonth,
    ));

    $service->submitAll();
    $increment_id = $service->getOrder()->getRealOrderId();

    $quote = $customer = $service = null;

    $retval = new stdClass;
    $retval->orderId = $increment_id;

    return json_encode($retval);
  }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.