For the double charge(start_transaction() executed twice) I am still not sure why that happens but Temporarily I come up with a solution:
in protx_prcess.php look for '$response = $GLOBALS['protx_direct']->start_transaction();' added just before:
$last_order_id_query = tep_db_query("SHOW TABLE STATUS from `" . DB_DATABASE . "` like '" . TABLE_ORDERS . "'");
$last_order_id = tep_db_fetch_array($last_order_id_query);
$new_order_id = $last_order_id['Auto_increment'];
$sagepay_local_query = tep_db_query("select * from " . TABLE_PROTX_DIRECT . " where customer_id='". (int)$customer_id . "' order by txtime desc");
if (tep_db_num_rows($sagepay_local_query)>0) {
$sagepay_local = tep_db_fetch_array($sagepay_local_query);
if ($sagepay_local['customer_id']==$customer_id && $sagepay_local['order_id']==$new_order_id_1 && $sagepay_local['status']=='OK') {
echo '<script type="text/javascript">window.location.href="'.tep_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL').'";</script>';
tep_exit();
}
}
Also, during testing I think the following change of code works better in protx_direct.php. look for code for sending payment request (from SagePay addon Direct
http://addons.oscommerce.com/info/6985)
function do_curl($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 90);
if (MODULE_PAYMENT_PROTX_DIRECT_CURL_SSL == 'True')
{
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
$response = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close ($ch);
change to :
function do_curl($data, $url){
$server = parse_url($url);
if (isset($server['port']) === false) {
$server['port'] = ($server['scheme'] == 'https') ? 443 : 80;
}
if (isset($server['path']) === false) {
$server['path'] = '/';
}
if (isset($server['user']) && isset($server['pass'])) {
$header[] = 'Authorization: Basic ' . base64_encode($server['user'] . ':' . $server['pass']);
}
if (function_exists('curl_init')) {
$ch = curl_init($server['scheme'] . '://' . $server['host'] . $server['path'] . (isset($server['query']) ? '?' . $server['query'] : ''));
curl_setopt($ch, CURLOPT_PORT, $server['port']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
if (MODULE_PAYMENT_PROTX_DIRECT_CURL_SSL == 'True')
{
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
$response = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);
} else {
exec(escapeshellarg(MODULE_PAYMENT_PROTX_DIRECT_CURL_SSL) . ' -d ' . escapeshellarg($data) . ' "' . $server['scheme'] . '://' . $server['host'] . $server['path'] . (isset($server['query']) ? '?' . $server['query'] : '') . '" -P ' . $server['port'] . ' -k', $result);
$response = implode("\n", $result);
}
So far I am still not sure what cause the empty responses for request (returned MODULE_PAYMENT_PROTX_DIRECT_TEXT_PROTX_ERROR from protx_direct.php interpreteResponse()) where customer need to re hit the confirm button.
Really appreciated if someone can spot any pitfalls of the changes above or any other suggestion.