function _uc_cybersource_soap_charge in Ubercart 5
Same name and namespace in other branches
- 6.2 payment/uc_cybersource/uc_cybersource.module \_uc_cybersource_soap_charge()
- 7.3 payment/uc_cybersource/uc_cybersource.module \_uc_cybersource_soap_charge()
1 call to _uc_cybersource_soap_charge()
- uc_cybersource_charge in payment/
uc_cybersource/ uc_cybersource.module
File
- payment/
uc_cybersource/ uc_cybersource.module, line 418 - A module used for CyberSource's Silent Order POST method of payment.
Code
function _uc_cybersource_soap_charge($order, $amount, $data, $cc_type, $country) {
// 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(
'success' => FALSE,
);
}
// 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());
// To see the functions and types that the SOAP extension can automatically
// generate from the WSDL file, uncomment this section and check the logs.
// $functions = $soapClient->__getFunctions();
// watchdog('uc_cybersource', '<pre>'. print_r($functions, TRUE) .'</pre>');
// $types = $soapClient->__getTypes();
// watchdog('uc_cybersource', '<pre>'. print_r($types, TRUE) .'</pre>');
$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 credit card authorization service.
if (in_array($data['txn_type'], array(
UC_CREDIT_AUTH_ONLY,
UC_CREDIT_AUTH_CAPTURE,
UC_CREDIT_REFERENCE_TXN,
))) {
$ccAuthService = new stdClass();
$ccAuthService->run = 'true';
$request->ccAuthService = $ccAuthService;
}
// Add the credit card capture service.
if (in_array($data['txn_type'], array(
UC_CREDIT_PRIOR_AUTH_CAPTURE,
UC_CREDIT_AUTH_CAPTURE,
UC_CREDIT_REFERENCE_TXN,
))) {
$ccCaptureService = new stdClass();
$ccCaptureService->run = 'true';
// Add the values for prior authorization capture.
if ($data['txn_type'] == UC_CREDIT_PRIOR_AUTH_CAPTURE) {
$ccCaptureService->authRequestID = $data['auth_id'];
$ccCaptureService->authRequestToken = $order->data['cybersource'][$data['auth_id']];
}
$request->ccCaptureService = $ccCaptureService;
// Add the subscription ID for a reference transaction.
if ($data['txn_type'] == UC_CREDIT_REFERENCE_TXN) {
$recurringSubscriptionInfo = new stdClass();
$recurringSubscriptionInfo->subscriptionID = $data['ref_id'];
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
$request->merchantReferenceCode .= ' (COF)';
}
}
// If enabled, create a subscription profile for this transaction.
if (variable_get('uc_cybersource_soap_create_profile', FALSE) && in_array($data['txn_type'], array(
UC_CREDIT_AUTH_ONLY,
UC_CREDIT_AUTH_CAPTURE,
))) {
// Skip if a profile already exists for this order.
if (!isset($order->data['uc_cybersource']['soap']['subscription_id'])) {
$recurringSubscriptionInfo = new stdClass();
$recurringSubscriptionInfo->amount = 0;
$recurringSubscriptionInfo->frequency = 'on-demand';
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
$paySubscriptionCreateService = new stdClass();
$paySubscriptionCreateService->run = 'true';
$request->paySubscriptionCreateService = $paySubscriptionCreateService;
}
}
// 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 credit card details if needed
if (in_array($data['txn_type'], array(
UC_CREDIT_AUTH_ONLY,
UC_CREDIT_AUTH_CAPTURE,
))) {
$card = new stdClass();
$card->accountNumber = $order->payment_details['cc_number'];
$card->expirationMonth = $order->payment_details['cc_exp_month'];
$card->expirationYear = $order->payment_details['cc_exp_year'];
$card->cardType = $cc_type;
if (variable_get('uc_credit_cvv_enabled', TRUE)) {
$card->cvNumber = $order->payment_details['cc_cvv'];
}
$request->card = $card;
}
// Add the order total information.
$purchaseTotals = new stdClass();
$purchaseTotals->currency = $currency;
// Specify the total to charge if it's less than the order total.
if ($amount < $order->order_total) {
$purchaseTotals->grandTotalAmount = $amount;
}
$request->purchaseTotals = $purchaseTotals;
// Separately add products and line item into the request items object if
// we're charging the full order total.
if ($amount == $order->order_total) {
$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++;
}
// Add the line items to the item array.
foreach ((array) $order->line_items as $line_item) {
// Skip subtotal line items.
if (strpos($line_item['type'], 'subtotal') === FALSE) {
$obj = $request->item[] = new stdClass();
$obj->productName = $line_item['title'];
$obj->unitPrice = $line_item['amount'];
$obj->quantity = 1;
$obj->productSKU = $line_item['type'] . '_' . $line_item['line_item_id'];
$obj->id = $counter;
$counter++;
}
}
}
// Add business rules.
$business = new stdClass();
$business->ignoreAVSResult = variable_get('uc_cybersource_avs', 'true') == 'true' ? 'false' : 'true';
$request->businessRules = $business;
// Send the request to CyberSource and get the reply.
$reply = $soapClient
->runTransaction($request);
} 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)) {
$types = uc_credit_transaction_types();
// Create the order and payment ledger comments.
$o_comment = t('<b>@type:</b> @amount<br /><b>Decision: @decision</b><br /><b>Reason:</b> !reason', array(
'@type' => $types[$data['txn_type']],
'@amount' => uc_currency_format($amount),
'@decision' => $reply->decision,
'!reason' => _parse_cs_reason_code($reply->reasonCode),
));
$p_comment = t('<b>@type:</b><br />@id<br />@decision, Reason: !reason', array(
'@type' => $types[$data['txn_type']],
'@id' => $reply->requestID,
'@decision' => $reply->decision,
'!reason' => $reply->reasonCode,
));
if (!empty($reply->ccAuthReply->avsCode)) {
$o_comment .= '<br />' . t('<b>AVS:</b> @avs', array(
'@avs' => _parse_cs_avs_code($reply->ccAuthReply->avsCode),
));
$p_comment .= t(', AVS: @avs', array(
'@avs' => $reply->ccAuthReply->avsCode,
));
}
if (!empty($reply->ccAuthReply->cvCode)) {
$o_comment .= '<br />' . t('<b>CVV:</b> @cvv', array(
'!cvv' => _parse_cs_cvv_code($reply->ccAuthReply->cvCode),
));
$p_comment .= t(', CVV: @cvv', array(
'@cvv' => $reply->ccAuthReply->cvCode,
));
}
uc_order_comment_save($order->order_id, $user->uid, $o_comment, 'admin');
// Store the subscription ID if one was created.
if (isset($reply->paySubscriptionCreateReply)) {
// If the create request was successful...
if ($reply->paySubscriptionCreateReply->reasonCode == '100') {
$id = $reply->paySubscriptionCreateReply->subscriptionID;
// Save the subscription ID to the order's data array.
$order->data = uc_credit_log_reference($order->order_id, $id, $order->payment_details['cc_number']);
uc_order_comment_save($order->order_id, 0, t('<b>CyberSource profile created.</b><br /><b>Subscription ID:</b> @id', array(
'@id' => $id,
)), 'admin');
}
else {
uc_order_comment_save($order->order_id, 0, t('<b>Attempt to create CyberSource profile failed.</b><br /><b>Reason:</b> @code', array(
'@code' => $reply->paySubscriptionCreateReply->reasonCode,
)), 'admin');
}
}
if ($reply->decision == 'ACCEPT') {
$result = array(
'success' => TRUE,
'comment' => $p_comment,
'message' => $o_comment,
'uid' => $user->uid,
);
// If this was an authorization only transaction...
if ($data['txn_type'] == UC_CREDIT_AUTH_ONLY) {
// Log the authorization to the order.
$order->data = uc_credit_log_authorization($order->order_id, $reply->requestID, $amount);
// Add the request token associated with the request ID.
$order->data['cybersource'][$reply->requestID] = $reply->requestToken;
// Save the updated data array to the database.
db_query("UPDATE {uc_orders} SET data = '%s' WHERE order_id = %d", serialize($order->data), $order->order_id);
}
elseif ($data['txn_type'] == UC_CREDIT_PRIOR_AUTH_CAPTURE) {
uc_credit_log_prior_auth_capture($order->order_id, $data['auth_id']);
}
}
else {
$result = array(
'success' => FALSE,
'comment' => $p_comment,
'message' => $o_comment,
'uid' => $user->uid,
);
}
}
else {
$result = array(
'success' => FALSE,
'message' => t('No response returned from CyberSource.'),
);
}
// Don't log this as a payment if money wasn't actually captured.
if (in_array($data['txn_type'], array(
UC_CREDIT_AUTH_ONLY,
))) {
$result['log_payment'] = FALSE;
}
return $result;
}