我正在使用magento api,我在创建订单时遇到了一些问题。我已经能够完成创建订单以正常工作的一切。我看到的问题是,当我调用方法创建订单时,我总是得到异常:Credit card number mismatch with credit card type.
我正在运行Magento ver。 1.6.2.0
我已经确认我正在测试的卡是通过magento前端工作的。
非常感谢任何帮助。
这是我正在使用的测试代码:
<?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);
?>
答案 0 :(得分:8)
根据您的帖子,您对cart_payment.method的调用正在成功,因此CC号码正在按预期验证为MC卡。
问题在于,由于PCI问题,Magento不会在数据库中保存CC号(在大多数情况下)。
因此,当您在一个请求中发送付款详细信息以及CC编号和CID,然后在另一个请求中创建订单时,状态将丢失,CC编号和CID将被消隐。
创建订单后,第二次验证付款数据,当发生这种情况时,它的CC编号为空,其类型为MC,导致您看到错误。
不幸的是,我没有办法让cart.order接受付款数据作为解决方法。
您可以编写一个模块,使用一种新方法扩展结帐API,该方法可以在一次调用中执行这两个步骤,这可能会解决问题。
答案 1 :(得分:2)
我也遇到了这个问题。我的解决方案是创建一个自定义SOAP端点,它可以立即处理所有订单创建和提交逻辑,而无需多次API调用。
即使这样,我也会遇到卡片类型不匹配的例外情况。
诀窍是,一旦我使用getPayment-&gt; importData方法设置付款信息,收集总计和保存报价,它似乎忘记了卡信息。可能是(不是最好的处理方式)PCI-DSS合规性。
为了解决这个问题,在提交订单之前,我在保存报价后添加了另一个getPayment-&gt; importData行。
这是在不更改任何核心文件的情况下实现的。
参见示例:
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);
}
答案 2 :(得分:1)
我从未对付款方式代码authorizenet
成功完成API交易。这只是总是通过前端成功,不知道为什么..也没有时间调查原因。虽然我一直做的是改为使用authorizenet_direct
帖子。我背后的理由/我如何偶然发现这同样适用于Paypal支付方式。 API似乎仅适用于paypal_direct
或paypaluk_direct
。试试吧!它应该工作。至少,这对我有用。
$paymentMethod = array(
"method" => "authorizenet_directpost",
"cc_type" => 'MC',
"cc_number" =>'5555555555554444' ,
"cc_exp_month" => 9,
"cc_exp_year" => 2014,
"cc_cid" => 123
);
答案 3 :(得分:1)
实际上我刚刚发现了一种通过API获取authorize.net付款的方法。
首先在/app/code/core/Mage/Payment/Model/Method/Cc.php中取消注释保存cid的行,所以函数在第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;
}
然后在付款方式的主模型文件中,确保将变量设置为:
protected $_canSaveCc = true;
我已经使用此方法测试了两种付款方式,现在都可以通过API运行。
答案 4 :(得分:1)
这是我的解决方案: goto /app/code/core/Mage/Payment/Model/Method/Cc.php 并看到功能:
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;
}
仅评论专栏:
$info->setCcNumber(null)
->setCcCid(null);