function _uc_cybersource_soap_charge in Ubercart 7.3
Same name and namespace in other branches
- 5 payment/uc_cybersource/uc_cybersource.module \_uc_cybersource_soap_charge()
- 6.2 payment/uc_cybersource/uc_cybersource.module \_uc_cybersource_soap_charge()
Handles the SOAP charge request and Ubercart order save.
1 call to _uc_cybersource_soap_charge()
- uc_cybersource_charge in payment/
uc_cybersource/ uc_cybersource.module - Charges card.
File
- payment/
uc_cybersource/ uc_cybersource.module, line 727 - A module used for CyberSource's Silent Order POST and Hosted Order Page methods of payment.
Code
function _uc_cybersource_soap_charge($order, $amount, $data, $cc_type, $country) {
// Include the SOAP helper file.
module_load_include('inc', 'uc_cybersource', 'uc_cybersource.soap');
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 at the moment.
$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;
$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 (round($amount, 2) == round($order->order_total, 2)) {
$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.
$discount_amount = 0;
foreach ((array) $order->line_items as $line_item) {
// Handle negative line items.
if ($line_item['amount'] < 0) {
$discount_amount += -$line_item['amount'];
}
elseif (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 the total order discount into the request.
if ($discount_amount != 0) {
$request->purchaseTotals->discountAmount = $discount_amount;
}
// 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', 'Unable to connect to CyberSource via SOAP.', array(), 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' => _uc_cybersource_parse_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' => _uc_cybersource_parse_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' => _uc_cybersource_parse_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,
'data' => array(
'module' => 'uc_cybersource',
'txn_type' => $data['txn_type'],
'request_id' => $reply->requestID,
),
);
// 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_update('uc_orders')
->fields(array(
'data' => serialize($order->data),
))
->condition('order_id', $order->order_id)
->execute();
}
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;
}