mindbody-php-api for stored credit card payment? - php

I am using mindbody api for payment, when I add my credit card detail then payment is successful but when I am using stored(existing) card for payment then it's given error :
Card Authorization Failed mb.Core.BLL.Transaction failed validation Could not determine the type of credit card.
my code is:
$shoppingCart = array(
'ClientID' => $client_id,
'Test' => false,
'InStore' => true, //add by NIK
'CartItems' => array(
'CartItem' => array(
'Quantity' => $product_qty,
'Item' => new SoapVar(
array('ID' => $product_id), SOAP_ENC_ARRAY, 'Service', 'http://clients.mindbodyonline.com/api/0_5'
),
'DiscountAmount' => 0
)
),
'Payments' => array(
'PaymentInfo' => new SoapVar(
array(
'LastFour'=>$clientCreditCard->LastFour,
'Amount'=>round($OnlinePrice, 2),
),
SOAP_ENC_ARRAY,
'StoredCardInfo',
'http://clients.mindbodyonline.com/api/0_5'
),
)
);
please give any solution for it, what should I do or send extra parameter.
thanks!

Shouldn't it look more like this?
'Payments' => array(
'PaymentInfo' => new SoapVar(
array(
'CreditCardNumber'=>'4111111111111111',
'ExpYear'=>'2015',
'ExpMonth'=>'06',
'Amount'=>'130',
'BillingAddress'=>'123 Happy Ln',
'BillingPostalCode'=>'93405'
),
SOAP_ENC_ARRAY,
'CreditCardInfo',
'http://clients.mindbodyonline.com/api/0_5'
)
Taken from this README.md https://github.com/devincrossman/mindbody-php-api

Your shopping cart array with saved card is correctly constructed.
I've been struggling with exactly the same problem for the last few days, and I found that the error in my case was that the front end account page was passing the credit card number with spaces in the string - the front end form was automatically adding the spaces for the usual format/usability reasons in the admin part of the application where the saved card details are entered.
I solved it by stripping out the spaces in PHP : str_replace(" ", "", $_POST['cardnumber']) in the card save function.
Once I did that the saved card payment process worked fine.

Related

Double customer entry in braintree vault issue

After completing transaction, there are two customer entry under vault.
Step I have followed:
1. Created customer.
//first customer vault entry is created at this point
$customerParams = Braintree_Customer::create(array(
'firstName' => $firstName,
'lastName' => $lastName,
));
2.Then generated clientToken
Braintree_ClientToken::generate(array(
"customerId" => $customerParams->customer->id
));
3.Then with help of api generated nonce in js successfully:
var client = new braintree.api.Client({clientToken: ctoken});
client.tokenizeCard({
...
...
});
4.Again at this point new customer is created
Braintree_Transaction::sale(array(
'amount' => $mapCidInvoiceID['amount'],
'orderId' => $redirectParams['invoiceID'],
'paymentMethodNonce' => $nonce,
'options' => array(
'storeInVaultOnSuccess' => true,
),
));
is there something wrong in my code? why for one transaction two customer record are created? For first record first and last name are recorded. But second case no such detail are stored.
First creation of customer is required for second and third step.
Full disclosure: I work at Braintree.
Your code is creating two separate customers because when you call Transaction::sale it does not have the customer from your Customer::create call tied to it, and you have the option set to store the payment method in the vault upon success. This creates a customer when saving the payment method from the transaction, because a payment method must be tied to a customer. To resolve your problem, pass the customer id returned from Customer::create as a customerId param when you call Transaction::sale.
Braintree_Transaction::sale(array(
'amount' => $mapCidInvoiceID['amount'],
'orderId' => $redirectParams['invoiceID'],
'customerId' => $customerParams->customer->id
'paymentMethodNonce' => $nonce,
'options' => array(
'storeInVaultOnSuccess' => true,
),
));

Paypal PHP API integration

Recently I'm playing with paypal API PHP.
I have downloaded a code from this url.
https://github.com/paypal/rest-api-curlsamples/blob/master/execute_all_calls.php
The code really works good with test creditcard(type:mastercard). The code looks like this
$url = $host.'/v1/payments/payment';
$payment = array(
'intent' => 'sale',
'payer' => array(
'payment_method' => 'credit_card',
'funding_instruments' => array ( array(
'credit_card' => array (
'number' => '540xxxxxxxxxxxx6',
'type' => 'mastercard',
'expire_month' => 12,
'expire_year' => 2018,
'cvv2' => 111,
'first_name' => 'First Name',
'last_name' => 'Last Name'
)
))
),
'transactions' => array (array(
'amount' => array(
'total' => '2',
'currency' => 'USD'
),
'description' => 'payment by a credit card using a test script'
))
);
Now if i try to use the same code to make the payment using my VISA(American Express) with test card number 37xxxxxxxxxx005, how shall i obtain this? What are the parameters to be altered?
In other words I would like to make the payment using Diner's Club,Discover and JCB. How shall I achieve this?
Edit: I have got two comments from Stack Overflow users, and you can check it at the bottom of my question. I'm not clear with the comments. Do they tell that I don't need to think about the parameters and paypal will take care of the card details and make the transaction?
Got reply from Paypal Tech Team for my above question
{snip}
You need to alter the code for 'type'. Below shows the code for the credit card type :l
- Visa
- MasterCard
- Discover
- Amex
And also make sure you need to input correct credit card number based on the type if you not you will receive an error message.
{/snip}
In other words, it is more than enough if I change the 'type' => 'mastercard' to 'type' => 'visa' (or) 'type' => 'amex' (or) 'type' => 'discover'
And also please make sure you give the correct test card numbers. You can view the dummy credit card numbers here.
http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
Hope this will help someone if they are struck with the paypal PHP API integration.
Thanks for all the tech support & SOF-Users.
Thanks again,
Haan

PayPal Order Summary Using REST API - - cURL or PHP

I am working with the PayPal RESTful API.
https://developer.paypal.com/webapps/developer/docs/api/
How can I pass my consumers order items and purchase description to PayPal, so when my user is redirected to PayPal to approve the order by logging in, their order summary will show up on the left.
.
.
ORDER SUMMARY ON THE LEFT
I have tried to passing in the transactions.item_list.items but that information isn't showing up in the order summary still.
Any help how to get an order summary to appear on the paypal approval page using the PayPal RESTful API?
I haven't been to pleased with their documentation as it is lacking some information and also has a few mistakes which wasted decent amount of my time to debug.
//
// prepare paypal data
$payment = array(
'intent' => 'sale',
'redirect_urls' => array(
'return_url' => $url_success,
'cancel_url' => $url_cancel,
),
'payer' => array(
'payment_method' => 'paypal'
)
);
//
// prepare basic payment details
$payment['transactions'][0] = array(
'amount' => array(
'total' => '0.03',
'currency' => 'USD',
'details' => array(
'subtotal' => '0.02',
'tax' => '0.00',
'shipping' => '0.01'
)
),
'description' => 'This is the payment transaction description 1.'
);
//
// prepare individual items
$payment['transactions'][0]['item_list']['items'][] = array(
'quantity' => '1',
'name' => 'Womens Large',
'price' => '0.01',
'currency' => 'USD',
'sku' => '31Wf'
);
$payment['transactions'][0]['item_list']['items'][] = array(
'quantity' => '1',
'name' => 'Womens Medium',
'price' => '0.01',
'currency' => 'USD',
'sku' => '31WfW'
);
//
//format payment array to pass to cURL
$CURL_POST = json_encode($payment);
your code is good. This is actually a bug that will be fixed very soon. Regarding documentation, can you share how we can make it better? I want to make sure your feedback gets passed to our documentation team.
I experienced the same issue while trying it out today. What I did was add the Items like below.
$item = new Item();
$item->setQuantity($item_quantity);
$item->setName($item_name);
$item->setPrice($item_price);
$item->setCurrency($item_currency);
$item_list = new ItemList();
$item_list->setItems(array($item));
The $item_list is a property of transaction so you should add it after.
$transaction = new Transaction();
$transaction->setItemList($item_list);
....
That should show on the Order summary pane on PayPal page.
You can also check the answer here.
Try using the sample shown here : http://htmlpreview.github.io/?https://raw.githubusercontent.com/paypal/PayPal-PHP-SDK/master/sample/doc/payments/CreatePaymentUsingPayPal.html
It is a sample that comes along with the PayPal REST API SDK. You can try those samples out yourselves, by following instructions on readme.
This is how it would look like, when you run that sample:

How do I pass the cardCode value to createCustomerProfileTransactionRequest for hosted CIM popup form

So I am using the Hosted CIM at Authorize.net to store customer information, they do not store the CCV cardCode.
How do I get the cardCode (entered via the CIM hosted popup form) so that I can process the createCustomerProfileTransactionRequest?
I have not required the CCV code, but transactions fail with the banks that require the code.
I am using the hosted CIM, I query the Customer ID and get the payment profile info using the below code:
$xml->createCustomerProfileTransactionRequest(array(
'transaction' => array(
'profileTransAuthCapture' => array(
'amount' => $amount_,
'customerProfileId' => $profile_id,
'customerPaymentProfileId' => $paymentProfileID,
'customerShippingAddressId' => $customerShippingAddressId,
'order' => array(
'invoiceNumber' => $invNo,
'description' => 'Subscription'/*,
'purchaseOrderNumber' => 'PO1'*/
),
'taxExempt' => 'false',
'recurringBilling' => 'false',
'cardCode' => '000'
)
),
));
This was solved by removing the cardCode field:
'cardCode' => '000'
It was passing the incorrect value: '000' causing the transaction to fail with cardCode mismatch error.

Magento Credit card number mismatch with credit card type exception

I am working with the magento api and I have run into a bit of an issue with creating an order. I have been able to get everything up to creating the order to work correctly. The issue that I am seeing is when I call the method to create the order I always get the exception: Credit card number mismatch with credit card type.
I am running Magento ver. 1.6.2.0
I have verified that the card I am testing with works via the magento frontend.
Any help with this is greatly appreciated.
This is the test code that I am using:
<?php
$proxy = new SoapClient('http://localhost/index.php/api/soap/?wsdl');
$sessionId = $proxy->login('shopapi', 'test123');
// Create a quote, get quote identifier
$shoppingCartId = $proxy->call( $sessionId, 'cart.create');
// Set customer, for example guest
$customerAsGuest = array(
"firstname" => "testFirstname",
"lastname" => "testLastName",
"email" => "test#test.com",
//"website_id" => "0",
//"store_id" => "0",
"mode" => "guest"
);
$resultCustomerSet = $proxy->call($sessionId, 'cart_customer.set', array( $shoppingCartId, $customerAsGuest) );
// Set customer addresses, for example guest's addresses
$arrAddresses = array(
array(
"mode" => "shipping",
"firstname" => "testFirstname",
"lastname" => "testLastname",
"company" => "testCompany",
"street" => "testStreet",
"city" => "testCity",
"region" => "CA",
"postcode" => "90049",
"country_id" => "US",
"telephone" => "0123456789",
"fax" => "0123456789",
"is_default_shipping" => 0,
"is_default_billing" => 0
),
array(
"mode" => "billing",
"firstname" => "testFirstname",
"lastname" => "testLastname",
"company" => "testCompany",
"street" => "testStreet",
"city" => "testCity",
"region" => "CA",
"postcode" => "90049",
"country_id" => "US",
"telephone" => "0123456789",
"fax" => "0123456789",
"is_default_shipping" => 0,
"is_default_billing" => 0
)
);
$resultCustomerAddresses = $proxy->call($sessionId, "cart_customer.addresses", array($shoppingCartId, $arrAddresses));
// add products into shopping cart
$arrProducts = array(
array(
"product_id" => "1",
"qty" => 1
)
);
$resultCartProductAdd = $proxy->call($sessionId, "cart_product.add", array($shoppingCartId, $arrProducts));
// get list of products
$shoppingCartProducts = $proxy->call($sessionId, "cart_product.list", array($shoppingCartId));
// set payment method
$paymentMethod = array(
"method" => "authorizenet",
"cc_type" => 'MC',
"cc_number" =>'5555555555554444' ,
"cc_exp_month" => 9,
"cc_exp_year" => 2014,
"cc_cid" => 123
);
$resultPaymentMethod = $proxy->call($sessionId, "cart_payment.method", array($shoppingCartId, $paymentMethod));
// create order
$resultOrderCreation = $proxy->call($sessionId,"cart.order",array($shoppingCartId));
var_dump($resultOrderCreation);
?>
Your call to cart_payment.method is succeeding, according to your post, so the CC number is validating to be a MC card, as expected.
The problem is that Magento, due to PCI concerns, does NOT save the CC number in the database (in most cases).
So, as you are sending payment details, along with CC number and CID, in one request and then creating the order in another, the state is lost and the CC number and CID are blanked out.
When the order is created, the payment data is validated a second time and when that happens, it has an empty CC number with a type of MC, causing the fault you see.
Unfortunately, I do not see a way to make cart.order accept payment data as a work around.
You could write a module to extend the checkout APIs with a new method that does both steps in a single call and that would likely solve the problem.
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.
This is achieved without changing any of the core files.
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#email.cc';
// 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);
}
I have never done successful API transactions to the payment method code authorizenet. This only always succeeds via frontend, not sure why.. nor have I had time to investigate why. Although what I have always done instead is to use authorizenet_direct post instead. My reasoning behind this / how I stumbled upon this is that the same also applies to the Paypal payment methods. API seems to only work with paypal_direct or paypaluk_direct. Try it! it should work. At the very least, this works for me.
$paymentMethod = array(
"method" => "authorizenet_directpost",
"cc_type" => 'MC',
"cc_number" =>'5555555555554444' ,
"cc_exp_month" => 9,
"cc_exp_year" => 2014,
"cc_cid" => 123
);
Actually I just discovered a way to take authorize.net payments via the API.
First in /app/code/core/Mage/Payment/Model/Method/Cc.php, uncomment the line about saving the cid, so the function look like this on line 65
public function prepareSave()
{
$info = $this->getInfoInstance();
if ($this->_canSaveCc) {
$info->setCcNumberEnc($info->encrypt($info->getCcNumber()));
}
$info->setCcCidEnc($info->encrypt($info->getCcCid()));
$info->setCcNumber(null)
->setCcCid(null);
return $this;
}
And then in the main model file of your payment method, make sure the variable is set to:
protected $_canSaveCc = true;
I've tested 2 payment methods using this and both work fine via API now.
this is my solution:
goto /app/code/core/Mage/Payment/Model/Method/Cc.php
and see function :
public function prepareSave()
{
$info = $this->getInfoInstance();
if ($this->_canSaveCc) {
$info->setCcNumberEnc($info->encrypt($info->getCcNumber()));
}
//$info->setCcCidEnc($info->encrypt($info->getCcCid()));
$info->setCcNumber(null)
->setCcCid(null);
return $this;
}
only comment line :
$info->setCcNumber(null)
->setCcCid(null);

Categories