function uc_cybersource_calculate_tax in Ubercart 5
Same name and namespace in other branches
- 6.2 payment/uc_cybersource/uc_cybersource.module \uc_cybersource_calculate_tax()
Calculates taxes for an order using CyberSource's tax service.
Parameters
$order: An order object with address and product information.
Return value
An array of associative arrays representing tax information with the keys 'id', 'name', and 'amount'.
1 call to uc_cybersource_calculate_tax()
- uc_cybersource_tax_test in payment/
uc_cybersource/ uc_cybersource.module
File
- payment/
uc_cybersource/ uc_cybersource.module, line 716 - A module used for CyberSource's Silent Order POST method of payment.
Code
function uc_cybersource_calculate_tax($order) {
// Kick out if the tax service is not enabled.
if (!variable_set('uc_cybersource_soap_tax_calculate', FALSE)) {
return array();
}
// Check for compatibility.
if (!class_exists('SoapClient') || !class_exists('DOMDocument')) {
drupal_set_message(t('CyberSource needs PHP to have the SOAP and DOM extensions enabled. Please talk to your system administrator to get this configured.'));
return array();
}
if (!is_object($order)) {
return array();
}
// Include the SOAP helper file.
require_once drupal_get_path('module', 'uc_cybersource') . '/uc_cybersource.soap.inc';
global $user;
// Set the URL for the CyberSource SOAP Toolkit API WSDL.
if (variable_get('uc_cybersource_server', 'test') == 'test') {
$url = 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.38.wsdl';
}
else {
$url = 'https://ics2ws.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.38.wsdl';
}
// Variable currency... not used atm.
$currency = variable_get('uc_cybersource_currency', 'usd');
$billing_country = uc_get_country_data(array(
'country_id' => $order->billing_country,
));
$delivery_country = uc_get_country_data(array(
'country_id' => $order->delivery_country,
));
try {
$soapClient = new CyberSourceSoapClient($url, array());
$login = _uc_cybersource_soap_login_data();
// Create the request with some meta data.
$request = new stdClass();
$request->merchantID = $login['merchant_id'];
$request->merchantReferenceCode = $order->order_id;
$request->clientLibrary = 'PHP';
$request->clientLibraryVersion = phpversion();
$request->clientEnvironment = php_uname();
// Add the billing information.
$billTo = new stdClass();
$billTo->firstName = $order->billing_first_name;
$billTo->lastName = $order->billing_last_name;
$billTo->street1 = $order->billing_street1;
if ($order->billing_street2) {
$billTo->street2 = $order->billing_street2;
}
$billTo->city = $order->billing_city;
$billTo->state = uc_get_zone_code($order->billing_zone);
$billTo->postalCode = $order->billing_postal_code;
$billTo->country = $billing_country[0]['country_iso_code_2'];
if ($order->billing_phone) {
$billTo->phoneNumber = $order->billing_phone;
}
$billTo->email = $order->primary_email;
$billTo->customerID = $order->uid;
$request->billTo = $billTo;
// Add the shipping information.
$shipTo = new stdClass();
$shipTo->firstName = $order->delivery_first_name;
$shipTo->lastName = $order->delivery_last_name;
$shipTo->street1 = $order->delivery_street1;
if ($order->billing_street2) {
$shipTo->street2 = $order->delivery_street2;
}
$shipTo->city = $order->delivery_city;
$shipTo->state = uc_get_zone_code($order->delivery_zone);
$shipTo->postalCode = $order->delivery_postal_code;
$shipTo->country = $delivery_country[0]['country_iso_code_2'];
$shipTo->email = $order->primary_email;
$request->shipTo = $shipTo;
// Add the company's ship from information.
$shipFrom = new stdClass();
$shipFrom->firstName = variable_get('cs_ship_from_first_name', '');
$shipFrom->lastName = variable_get('cs_ship_from_last_name', '');
$shipFrom->street1 = variable_get('cs_ship_from_street1', '');
$shipFrom->city = variable_get('cs_ship_from_city', '');
$shipFrom->state = variable_get('cs_ship_from_zone', '');
$shipFrom->postalCode = variable_get('cs_ship_from_postal_code', '');
$shipFrom->country = variable_get('cs_ship_from_country', '');
$shipFrom->email = variable_get('cs_ship_from_email', '');
$request->shipFrom = $shipFrom;
// TaxService
// US product codes:
// 70.280: Software Training Services
// 81112201.121: Business Use Services and Upgrades via Elect Dnld
// TODO: product code, international product code
// TODO: invoiceHeader->invoiceDate: to get correct refund amounts
// TODO: VAT
$taxService = new stdClass();
$taxService->nexus = 'MA CA';
$taxService->orderOriginCity = $taxService->orderAcceptanceCity = $shipFrom->city;
$taxService->orderOriginCountry = $taxService->orderAcceptanceCountry = $shipFrom->country;
$taxService->orderOriginState = $taxService->orderAcceptanceState = $shipFrom->state;
$taxService->orderOriginPostalCode = $taxService->orderAcceptancePostalCode = $shipFrom->postalCode;
$taxService->sellerRegistration = 'XXX TODO';
$taxService->run = 'true';
$request->taxService = $taxService;
// Add the order total information.
$purchaseTotals = new stdClass();
$purchaseTotals->currency = $currency;
// Add the products to the request.
$request->item = array();
$counter = 0;
// Add the products to the item array.
foreach ($order->products as $product) {
$obj = $request->item[] = new stdClass();
$obj->productName = $product->title;
$obj->unitPrice = $product->price;
$obj->quantity = $product->qty;
$obj->productSKU = $product->model;
$obj->productCode = 'default';
$obj->id = $counter;
$counter++;
}
// drupal_set_message('<pre>Request: '. print_r($request, TRUE) .'</pre>');
// Send the request to CyberSource and get the reply.
$reply = $soapClient
->runTransaction($request);
// drupal_set_message('<pre>Reply: '. print_r($reply, TRUE) .'</pre>');
} catch (SoapFault $exception) {
// Log and display errors if Ubercart is unable to connect via SOAP.
watchdog('uc_cybersource', t('Unable to connect to CyberSource via SOAP.'), WATCHDOG_ERROR);
drupal_set_message(t('We apologize for the delay, but we are unable to process your credit card at this time. Please <a href="!url">contact sales</a> to complete your order.', array(
'!url' => url('contact'),
)), 'error');
}
// Process a reply from CyberSource.
if (isset($reply)) {
$result = array();
if ($reply->reasonCode == '100') {
// Add a city tax if applicable.
if (floatval($reply->taxReply->totalCityTaxAmount) > 0) {
$result[] = array(
'id' => 'city',
'name' => t('@city city tax', array(
'@city' => floatval($reply->taxReply->city),
)),
'amount' => floatval($reply->taxReply->totalCityTaxAmount),
);
}
// Add a county tax if applicable.
if (floatval($reply->taxReply->totalCountyTaxAmount) > 0) {
$result[] = array(
'id' => 'county',
'name' => t('County tax'),
'amount' => floatval($reply->taxReply->totalCountryTaxAmount),
);
}
// Add a district tax if applicable.
if (floatval($reply->taxReply->totalDistrictTaxAmount) > 0) {
$result[] = array(
'id' => 'district',
'name' => t('District tax'),
'amount' => floatval($reply->taxReply->totalDistrictTaxAmount),
);
}
// Add a state tax if applicable.
if (floatval($reply->taxReply->totalStateTaxAmount) > 0) {
$result[] = array(
'id' => 'state',
'name' => t('@state state tax', array(
'@state' => $reply->taxReply->state,
)),
'amount' => floatval($reply->taxReply->totalStateTaxAmount),
);
}
// Verify that the component taxes equal the total.
$total = 0;
foreach ($result as $tax) {
$total += $tax['amount'];
}
// If it doesn't, log an error message and simply return the total.
if ($total != floatval($reply->taxReply->totalTaxAmount)) {
watchdog('uc_cybersource', t('Tax calculation produced uneven results. Expected a total of @total, received the following: @dump', array(
'@total' => uc_currency_format($reply->taxReply->totalTaxAmount),
'@dump' => '<pre>' . print_r($result, TRUE) . '</pre>',
)), WATCHDOG_ERROR);
$result = array(
array(
'id' => 'total',
'name' => t('Tax'),
'amount' => floatval($reply->taxReply->totalTaxAmount),
),
);
}
}
else {
watchdog('uc_cybersource', t('Attempted to calculate taxes failed for order @order_id - reason @code', array(
'@order_id' => $order->order_id,
'@code' => $reply->reasonCode,
)), WATCHDOG_ERROR);
}
}
else {
watchdog('uc_cybersource', t('Attempted to calculate taxes failed for order @order_id. No response returned from CyberSource.', array(
'@order_id' => $order->order_id,
)), WATCHDOG_ERROR);
$result = array();
}
return $result;
}