function commerce_sagepay_process_response in Drupal Commerce SagePay Integration 7
Helper function to process the response from SagePay of any transaction type.
Return TRUE for a successful transaction.
Parameters
array $payment_method: The payment method being used.
commerce_order $order: The Commerce Order to match against the response.
array $tokens: Tokens available to the response.
Return value
bool Return TRUE is the payment was successful. Return FALSE if payment is rejected or fails for any reason.
5 calls to commerce_sagepay_process_response()
- commerce_sagepay_direct_submit_form_submit in includes/
commerce_sagepay_direct.inc - Payment method callback: checkout form submission.
- commerce_sagepay_paypal_handle_callback in modules/
commerce_sagepay_paypal/ includes/ commerce_sagepay_paypal.inc - Handle a POST callback from Pay Pal to confirm the transaction.
- commerce_sagepay_paypal_submit_form_validate in modules/
commerce_sagepay_paypal/ includes/ commerce_sagepay_paypal.inc - Payment method callback: checkout form submission.
- sagepay_3d_secure_callback in modules/
sagepay_3d_secure/ sagepay_3d_secure.module - Process callback response from merchant server.
- sagepay_token_cardonfile_charge in modules/
sagepay_token/ sagepay_token.module - Implements Card on File Charge Callback.
File
- includes/
commerce_sagepay_common.inc, line 203 - Common utility functions shared by all SagePay modules.
Code
function commerce_sagepay_process_response($payment_method, $order, $tokens, $transaction = NULL) {
// Default no charge for failed transactions.
// (these values will not be in the callback for a failed or cancelled).
$def_charge = array(
'amount' => 0,
'currency_code' => '',
);
$order_id = $order->order_id;
// Check for a valid status callback.
switch ($tokens['Status']) {
case 'ABORT':
watchdog('commerce_sagepay', 'ABORT error from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ALERT);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Your SagePay transaction was aborted.'), 'error');
return FALSE;
case 'NOTAUTHED':
watchdog('commerce_sagepay', 'NOTAUTHED error from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ALERT);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Your transaction was not authorised.'), 'error');
return FALSE;
case 'REJECTED':
watchdog('commerce_sagepay', 'REJECTED error from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ALERT);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Your transaction was rejected. Reason: 3D-Authentication failed.'), 'warning');
$target_step = 'checkout_review';
drupal_alter('commerce_sagepay_3dsecure_fail_destination', $target_step);
commerce_order_status_update($order, $target_step);
return FALSE;
case 'MALFORMED':
watchdog('commerce_sagepay', 'MALFORMED error from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ALERT);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Sorry the transaction has failed.'), 'error');
return FALSE;
case 'INVALID':
watchdog('commerce_sagepay', 'INVALID error from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ERROR);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Sorry an error occurred while processing your transaction. %message', array(
'%message' => $tokens['StatusDetail'],
)), 'error');
$target_step = 'checkout_review';
// Allow custom modules to change which page you end up at when the order
// is invalid.
drupal_alter('commerce_sagepay_invalid_destination', $target_step);
commerce_order_status_update($order, $target_step);
return FALSE;
case 'ERROR':
watchdog('commerce_sagepay', 'System ERROR from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ERROR);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Sorry an error occurred while processing your transaction. %message', array(
'%message' => $tokens['StatusDetail'],
)), 'error');
return FALSE;
case 'FAIL':
watchdog('commerce_sagepay', 'System FAIL from SagePay for order %order_id with message %msg', array(
'%order_id' => $order_id,
'%msg' => $tokens['StatusDetail'],
), WATCHDOG_ERROR);
commerce_sagepay_transaction($payment_method, $order, $def_charge, $tokens, COMMERCE_PAYMENT_STATUS_FAILURE, SAGEPAY_REMOTE_STATUS_FAIL, $transaction);
drupal_set_message(t('Sorry an error occurred while processing your transaction. %message', array(
'%message' => $tokens['StatusDetail'],
)), 'error');
return FALSE;
case 'OK':
$arr_charge = array();
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
if (array_key_exists('Amount', $tokens)) {
$arr_charge['amount'] = $tokens['Amount'];
$arr_charge['currency_code'] = $order_wrapper->commerce_order_total->currency_code
->value();
}
/* As we have already created a transaction, we no longer need to reset this and reload
$transaction = NULL; */
// If 3D secure is in use, we may have to load a partial transaction.
if (module_exists('sagepay_3d_secure')) {
$transaction_3d = sagepay_3d_secure_load_transaction($tokens, $order);
if ($transaction_3d) {
$transaction = $transaction_3d;
}
}
$remote_status = SAGEPAY_REMOTE_STATUS_PAYMENT;
if (isset($transaction->remote_status)) {
if ($transaction->remote_status == 'DEFERRED') {
$remote_status = SAGEPAY_REMOTE_STATUS_DEFERRED;
}
}
// Check for the scenario where we stored the original requested remote
// status prior to 3d Secure.
if (isset($transaction->payload['original_remote_status'])) {
$remote_status = $transaction->payload['original_remote_status'];
unset($transaction->payload['original_remote_status']);
}
commerce_sagepay_transaction($payment_method, $order, $arr_charge, $tokens, COMMERCE_PAYMENT_STATUS_SUCCESS, $remote_status, $transaction);
break;
case 'AUTHENTICATED':
$arr_charge = array();
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$arr_charge['amount'] = $tokens['Amount'];
$arr_charge['currency_code'] = $order_wrapper->commerce_order_total->currency_code
->value();
watchdog('commerce_sagepay', 'AUTHENTICATED Payment callback received from SagePay for order %order_id with status code %status', array(
'%order_id' => $order_id,
'%status' => $tokens['Status'],
));
commerce_sagepay_transaction($payment_method, $order, $arr_charge, $tokens, COMMERCE_PAYMENT_STATUS_PENDING, SAGEPAY_REMOTE_STATUS_AUTHENTICATE, $transaction);
break;
case 'REGISTERED':
$arr_charge = array();
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$arr_charge['amount'] = $tokens['Amount'];
$arr_charge['currency_code'] = $order_wrapper->commerce_order_total->currency_code
->value();
watchdog('commerce_sagepay', 'REGISTERED Payment callback received from SagePay for order %order_id with status code %status', array(
'%order_id' => $order_id,
'%status' => $tokens['Status'],
));
commerce_sagepay_transaction($payment_method, $order, $arr_charge, $tokens, COMMERCE_PAYMENT_STATUS_PENDING, SAGEPAY_REMOTE_STATUS_REGISTERED, $transaction);
break;
case 'PPREDIRECT':
// Card type was PayPal and the server has responded with a PayPal
// redirect URL.
$arr_charge = array();
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$arr_charge['amount'] = $tokens['Amount'];
$arr_charge['currency_code'] = $order_wrapper->commerce_order_total->currency_code
->value();
watchdog('commerce_sagepay', 'REGISTERED PAYPAL Payment callback
received
from SagePay for order %order_id with status code %status', array(
'%order_id' => $order_id,
'%status' => $tokens['Status'],
));
commerce_sagepay_transaction($payment_method, $order, $arr_charge, $tokens, COMMERCE_PAYMENT_STATUS_PENDING, SAGEPAY_REMOTE_STATUS_PAYPAL_REDIRECT);
break;
case '3DAUTH':
// Server has replied with a 3D Secure authentication request.
// Store the returned variables in the order object for processing
// by the 3D Secure module.
// The returned variables should be:
// 1) PAReq.
// 2) ACSURL.
// 3) MD.
$tds_data = array();
$tds_data['PAReq'] = $tokens['PAReq'];
$tds_data['ACSURL'] = $tokens['ACSURL'];
$tds_data['MD'] = $tokens['MD'];
$tds_data['TermUrl'] = url('commerce-sagepay/3d_secure_callback/' . $order->order_id, array(
'absolute' => TRUE,
));
$order->data['extra_authorisation'] = $tds_data;
$arr_charge = array();
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$arr_charge['amount'] = $tokens['Amount'];
$arr_charge['currency_code'] = $order_wrapper->commerce_order_total->currency_code
->value();
// Store the original remote status in the payload otherwise we lose it
// when we change the remote status to 3D Secure.
$tokens['original_remote_status'] = $transaction->remote_status;
commerce_sagepay_transaction($payment_method, $order, $arr_charge, $tokens, COMMERCE_PAYMENT_STATUS_PENDING, SAGEPAY_REMOTE_STATUS_3D_SECURE, $transaction);
break;
default:
// Something has gone wrong so log an error and fail.
watchdog('commerce_sagepay', 'Unrecognised Status response from SagePay for order %order_id (%response_code)', array(
'%order_id' => $order_id,
'%response_code' => $tokens['Status'],
), WATCHDOG_ERROR);
drupal_set_message(t('Sorry an error occurred while processing your transaction. %message', array(
'%message' => $tokens['StatusDetail'],
)), 'error');
return FALSE;
}
return TRUE;
}