Getting 404 Error After The Payment Is Processed

Hi

I really need a help from community.

I've been trying to solve this issue from quite some time but no success.

I am using Ozow payment module.

The module is installed 100%, I can get the payment from customers.

The problem is when after the successful Ozow transaction, I do get payment from customers

then it going back to my website, it throws 404 error page and order statues is changed to Incomplete.

Below is the link address when it go back from Ozow to my website

https://mynespot.com/index.php?dispatch=payment_notification.return&payment=ipay&order_id=424&SiteCode=LIN-MYN-001&TransactionId=be175014-050d-4050-a6c2-58ad99bf2c9b&TransactionReference=424&Amount=0.01&Status=Complete&Optional1=&Optional2=&Optional3=&Optional4=&Optional5=CS-Cart+4.x&CurrencyCode=ZAR&IsTest=False&StatusMessage=&Hash=7099e2f7857820f12e2dce26535f5654b2bc16f330302800fb6cc7acd98cfc45f614336e2546accd074737a65bbee3d669d54616064859e285ae4e16b0bab18b

I've asked Ozow support team to check the issue and they told me it's something to do with CS-CART and I need someone to fix the issue.

Can anyone help me to fix the issue, please.

Below is response from Ozow support team

We ran two test transactions on your website and found the below:

I am trying to attached a text file of the notification response error, but I am failing to upload all the time, tried basic and advanced mode. Any ideas?

It is required to examine 3rd party code. At first, please make sure that their script which is used to process payments is called "ipay.php"

Thank you for your reply.

I can confirm ipay.php is correct and it's in place

use Tygh\Http;
use Tygh\Registry;
if (!defined('BOOTSTRAP')) { die('Access denied'); }
require_once(Registry::get('config.dir.payments') . 'ipay/ipay_func.php');
if( defined('PAYMENT_NOTIFICATION') )
{
$payment_id = db_get_field("SELECT payment_id FROM ?:orders WHERE order_id = ?i", $_REQUEST['order_id']);
$processor_data = fn_get_payment_method_data($payment_id);
$order_info = fn_get_order_info( $_REQUEST['order_id'] );
$debug = (bool)$processor_data['processor_params']['debug'];
if (fn_check_payment_script('ipay.php', $_REQUEST['order_id'], $processor_data))
{
ipay_logging('Payment Notification Mode:: ' . $mode, false, $debug);
$pp_response = array();
$data = ipay_get_itn_notification_data();
ipay_logging('ITN Notication Data::' . print_r( $data, true ), false, $debug);
$itn_result = ipay_process_payment_itn( $data, $processor_data, $order_info);
$transaction_id = $data['TransactionId'];
$order_status = '';
switch( $data['Status'] )
{
case IPAY_ORDER_STATUS_COMPLETE:
ipay_logging(sprintf( 'Payment complete::%s', $itn_result ), false, $debug);
$order_status = 'O';
break;
case IPAY_ORDER_STATUS_PENDING_INVESTIGATION:
case IPAY_ORDER_STATUS_PENDING:
ipay_logging(sprintf( 'Payment pending::%s', $itn_result ), false, $debug);
$order_status = 'F';
break;
default:
ipay_logging(sprintf( 'Payment error::%s', $itn_result ), false, $debug);
$order_status = 'F';
break;
break;
}
$pp_response['order_status'] = $order_status;
$pp_response['reason_text'] = $itn_result;
$pp_response['transaction_id'] = $transaction_id;
fn_change_order_status($_REQUEST['order_id'], $order_status, '', false);
fn_finish_payment($_REQUEST['order_id'], $pp_response);
fn_order_placement_routines('route', $_REQUEST['order_id']);
}
}
else
{
$debug = (bool)$processor_data['processor_params']['debug'];
ipay_logging('Payment Notification Mode:: ' . $mode, false, $debug);
$ipay_url = ipay_get_payment_url();
$site_code = $processor_data['processor_params']['site_code'];
$country_code = $processor_data['processor_params']['country_code'];
$currency_code = $processor_data['processor_params']['currency_code'];
$private_key = $processor_data['processor_params']['private_key'];
$test_mode = $processor_data['processor_params']['mode'] == 'test' ? 'true' : 'false';
$amount = fn_format_price( $order_info['total'] , $currency_code );
$order_id = $order_info['order_id'];
$return_url = fn_url("payment_notification.return?payment=ipay&order_id=$order_id", AREA, 'current');
$cancel_url = fn_url("payment_notification.cancel?payment=ipay&order_id=$order_id", AREA, 'current');
$notify_url = fn_url("payment_notification.notify?payment=ipay&order_id=$order_id", AREA, 'current');
$post_data = array(
'SiteCode' => $site_code,
'CountryCode' => $country_code,
'CurrencyCode' => $currency_code,
'Amount' => $amount,
'TransactionReference' => $order_id,
'BankReference' => $order_id,
'Optional1' => '',
'Optional5' => 'CS-Cart 4.x',
'Customer' => $order_info['firstname'] . ' ' . $order_info['lastname'],
'CancelUrl' => $cancel_url,
'SuccessUrl' => $return_url,
'NotifyUrl' => $notify_url,
'IsTest' => $test_mode
);
$hash_check = ipay_get_hash($post_data, $private_key);
$post_data['HashCheck'] = $hash_check;
ipay_logging('Payment Post Data::' . print_r( $post_data, true ), false, $debug);
fn_create_payment_form($ipay_url, $post_data, 'i-Pay Server');
}
exit;

Try to replace

        fn_change_order_status($_REQUEST['order_id'], $order_status, '', false);
        fn_finish_payment($_REQUEST['order_id'], $pp_response);
        fn_order_placement_routines('route', $_REQUEST['order_id']); 
with
        if ($mode != 'notify') {
            fn_change_order_status($_REQUEST['order_id'], $order_status, '', false);
            fn_finish_payment($_REQUEST['order_id'], $pp_response);
        } else {
            fn_order_placement_routines('route', $_REQUEST['order_id']); 
        }

Hi.

It didn't worked.

Below it's the link back to my website after the payment.

https://mynespot.com/index.php?dispatch=payment_notification.return&payment=ipay&order_id=431&SiteCode=LIN-MYN-001&TransactionId=79a87e48-8bb1-45db-9a99-f809fb5fdefb&TransactionReference=431&Amount=0.01&Status=Complete&Optional1=&Optional2=&Optional3=&Optional4=&Optional5=CS-Cart+4.x&CurrencyCode=ZAR&IsTest=False&StatusMessage=&Hash=8aa75448358d1ad9b7f16ba1c0ac54877b5ba2a6e29b03f86a2d721df4c1f2e27cba914f4096cda0c70704f5bac8f33df7669a632f6568e1950ebd74d73003bd

I edited as below in bold.

else
{
$pp_response['order_status'] = $order_status;
$pp_response['reason_text'] = $itn_result;
}
$pp_response['transaction_id'] = $transaction_id;

if ($mode != 'notify') {
fn_change_order_status($_REQUEST['order_id'], $order_status, '', false);
fn_finish_payment($_REQUEST['order_id'], $pp_response);
} else {
fn_order_placement_routines('route', $_REQUEST['order_id']);

}
}
}
else
{

It is required to examine the code to find a reason of such behaviour

Sure, I like you to check further.

Let me know how can we proceed.