Automatic Order Status Change After Creditcard/escrow Payment Is Complete

Hi there,

We're currently trying to make the status change from paid to complete fully automatic, we have a logic that basically checks if the payment is done, since our escrow payment has multiple milestones that need to be completed, payments takes some time to process.

I’m wondering if it's possible to make the status change automatically after exactly 14 days from paid to complete.

// Check if the order is not empty
if (!empty($order_id)) {
        if ($response['event_type'] == 'transaction') {
// checks if there is a transaction
// We initialise the order status 
            $status = '';
// Case were payment is complete
            if ($response['event'] == 'payment_approved') {
// Change the order status to paid
                $status = 'P';
            } 
// Case were payment is accepted
elseif ($response['event'] == 'accept') {
// Get the order infos
                $order_info = fn_get_order_info($order_id);
//check if the infos are not empty
                if (!empty($order_info)) {
// Get the transaction data from the escrow API
                    $transaction_data = fn_ecl_escrow_get_transaction_data($order_info['payment_id'], $response['transaction_id']);
// Initialise a boolean to approve all conditions (This variable represents the decision) 
                    $all_accepted = true;
                    if (!empty($transaction_data)) {
// Map into all the transaction data
                        foreach ($transaction_data['items'] as $i) {
//Check for the milestone with an empty status (Not accepted)
                            if ($i['type'] == 'milestone' && empty($i['status']['accepted'])) {
// Assign the decision variable to false
                                $all_accepted = false;
                            }
                        }
                    }
// If all conditions are fulfilled
// Keep the decision variable to true
                    if ($all_accepted == true) {
// Change status to complete
                        $status = 'C';
                    }
                }
            }
// Keep status empty if none of the transaction conditions are fulfilled
            if (!empty($status)) {
                fn_change_order_status($order_id, $status, '');
            }
        }
    } 

Need some recommendations here on how I can improve this logic to do so ?

Thanks,

You can create special controller and run in via cron task each day. The controller should check status in Escrow system for paid order after 14 days.

You can create special controller and run in via cron task each day. The controller should check status in Escrow system for paid order after 14 days.

Hello, thanks for suggestion, I never really worked with cron tasks before … It would be great if you can recommend a starting point for me. Documentations are very limited when it comes to cron tasks.

Thanks.

Just create simple controller which can be run via browser. Then you can run it in cron tasks

Just create simple controller which can be run via browser. Then you can run it in cron tasks

I created a controller that checks the order's status, if it's complete it will generate a PDF file from all the attached threads.

I'm using a link to run this function, as shown below in the screenshot.

/ Generate file without opening the popup

if ($mode == ‘generate_file_automatic’) {
$order_data = db_get_row(“SELECT * FROM ?:orders WHERE order_id = ?i”, $_REQUEST[‘order_id’]);
if($order_data[‘status’] == ‘C’){
$request_data = $REQUEST;
$request_data[‘name’] = “Complete Negotiation”.'
‘.“Order #”.$REQUEST[‘order_id’].'’.date(‘ymd’);
fn_ss_order_threads_generate_file_auto_select($request_data);
fn_set_notification(‘N’, __(‘notice’), __(‘ss_order_threads_file_generated_complete_order_update’));
return array(CONTROLLER_STATUS_OK, ‘orders.details&order_id=’ . $_REQUEST[‘order_id’] .“&selected_section=ss_order_threads_files_tab”);
} else {
fn_set_notification(‘W’, __(‘warning’), __(‘ss_order_threads_file_generated_not_completed’));
return array(CONTROLLER_STATUS_OK, ‘orders.details&order_id=’ . $_REQUEST[‘order_id’] .“&selected_section=ss_order_threads_files_tab”);
}
} // end if

Link in smarty :

Update  

Can you please suggest a way to make this a cron job every time the status changes, for instance?

Is it possible to make this controller runs when I click on the Documents tab ?

(This is another use case, but it also requires a cron job)

Thanks

cron job.png

In this case cron is not required. Just put all your code to new function and call it on order status change (use hooks in the fn_change_order_status function) and when you click on the Documents tab

In this case cron is not required. Just put all your code to new function and call it on order status change (use hooks in the fn_change_order_status function) and when you click on the Documents tab

Hello,

thanks for the answer, I tried doing that, as you can see below :

So in the add-on, I created this file : app/addons/ss_order_threads/hooks.php

if (!defined('BOOTSTRAP')) { die('Access denied'); }
// error_reporting(0);
/**
 * Hook delete_order::fn_delete_order::/app/functions/fn.cart.php
 * 
 * When an order is deleted, also delete the records associated with it
 *
 * @param unknown $order_id
 */
function fn_ss_order_threads_delete_order($order_id)
{
    print_r('********************** Delete order hook test ********************************************');
    $thread_files = db_get_array("SELECT * FROM ?:ss_order_threads_files WHERE threads != ?i AND deprecated = ?s", 0, "T");
    foreach ($thread_files as $key => $thread_file) {
        $structure = array(
            "name" => $thread_file['name'],
            "filename" => $thread_file['filename'],
            "thread_id" => $thread_file['threads'],
            "timestamp"=> $thread_file['timestamp'],
            "path" => $thread_file['path']
        );
        db_query("INSERT INTO ?:ss_order_threads_thread_loaded_files ?e", $structure);
    } // end foreach
    db_query("DELETE FROM ?:ss_order_threads_links WHERE order_id = ?i", $order_id);
    db_query("DELETE FROM ?:ss_order_threads_files WHERE order_id = ?i", $order_id);
} // end function fn_ss_order_threads_delete_order

/**

  • Hook change_order_status::fn_change_order_status::/app/functions/fn.cart.php
  • After changing the order status, generate the file
  • @param unknown $status_to
  • @param unknown $status_from
  • @param unknown $order_info
  • @param unknown $force_notification
  • @param unknown $order_statuses
  • @param unknown $place_order
    */

function fn_ss_order_threads_change_order_status_post($status_to, $status_from, $order_info, $force_notification, $order_statuses, $place_order) {
print_r(‘********************** Status change hook test ********************************************’);
$addon_params = Registry::get(‘addons.ss_order_threads’);
if($status_to == $addon_params[‘ss_order_threads_generate_chat_file’]) {
$threads = db_get_array(“SELECT * FROM ?:ss_order_threads_links WHERE order_id = ?i”, $order_info[‘order_id’]);
foreach ($threads as $key => $thread) {
$request_data = array();
$request_data[‘order_id’] = $order_info[‘order_id’];
$request_data[‘threads’][‘selected_threads’][$thread[‘thread_id’]][‘enable’] = “Y”;
$request_data[‘name’] = “Messaging thread #”.$thread[‘thread_id’];
fn_ss_order_threads_generate_file($request_data);
} // end foreach
} // end if
} // end function fn_ss_order_threads_change_order_status

The first function will delete the files when the order is deleted and the second one should generate the files on the order status is changed …

I also added the hooks in : app/addons/ss_order_threads/init.php

if (!defined('BOOTSTRAP')) { die('Access denied'); }

fn_register_hooks(
“change_order_status_post”,
“delete_order”
);

When testing :

- when deleting an order, the first function is executed, it does the job, but I also see that the second one is also executed.
- when changing the status, nothing happened ...

I was testing for three days now, and I can't find a solution for this … Even if I only use the change_order_status_post hook only, it executes the function when I delete the order …

Can you help please ?

Hello,

thanks for the answer, I tried doing that, as you can see below :

So in the add-on, I created this file : app/addons/ss_order_threads/hooks.php

if (!defined('BOOTSTRAP')) { die('Access denied'); }
// error_reporting(0);
/**
 * Hook delete_order::fn_delete_order::/app/functions/fn.cart.php
 * 
 * When an order is deleted, also delete the records associated with it
 *
 * @param unknown $order_id
 */
function fn_ss_order_threads_delete_order($order_id)
{
    print_r('********************** Delete order hook test ********************************************');
    $thread_files = db_get_array("SELECT * FROM ?:ss_order_threads_files WHERE threads != ?i AND deprecated = ?s", 0, "T");
    foreach ($thread_files as $key => $thread_file) {
        $structure = array(
            "name" => $thread_file['name'],
            "filename" => $thread_file['filename'],
            "thread_id" => $thread_file['threads'],
            "timestamp"=> $thread_file['timestamp'],
            "path" => $thread_file['path']
        );
        db_query("INSERT INTO ?:ss_order_threads_thread_loaded_files ?e", $structure);
    } // end foreach
    db_query("DELETE FROM ?:ss_order_threads_links WHERE order_id = ?i", $order_id);
    db_query("DELETE FROM ?:ss_order_threads_files WHERE order_id = ?i", $order_id);
} // end function fn_ss_order_threads_delete_order

/**

  • Hook change_order_status::fn_change_order_status::/app/functions/fn.cart.php
  • After changing the order status, generate the file
  • @param unknown $status_to
  • @param unknown $status_from
  • @param unknown $order_info
  • @param unknown $force_notification
  • @param unknown $order_statuses
  • @param unknown $place_order
    */

function fn_ss_order_threads_change_order_status_post($status_to, $status_from, $order_info, $force_notification, $order_statuses, $place_order) {
print_r(‘********************** Status change hook test ********************************************’);
$addon_params = Registry::get(‘addons.ss_order_threads’);
if($status_to == $addon_params[‘ss_order_threads_generate_chat_file’]) {
$threads = db_get_array(“SELECT * FROM ?:ss_order_threads_links WHERE order_id = ?i”, $order_info[‘order_id’]);
foreach ($threads as $key => $thread) {
$request_data = array();
$request_data[‘order_id’] = $order_info[‘order_id’];
$request_data[‘threads’][‘selected_threads’][$thread[‘thread_id’]][‘enable’] = “Y”;
$request_data[‘name’] = “Messaging thread #”.$thread[‘thread_id’];
fn_ss_order_threads_generate_file($request_data);
} // end foreach
} // end if
} // end function fn_ss_order_threads_change_order_status

The first function will delete the files when the order is deleted and the second one should generate the files on the order status is changed …

I also added the hooks in : app/addons/ss_order_threads/init.php

if (!defined('BOOTSTRAP')) { die('Access denied'); }

fn_register_hooks(
“change_order_status_post”,
“delete_order”
);

When testing :

- when deleting an order, the first function is executed, it does the job, but I also see that the second one is also executed.
- when changing the status, nothing happened ...

I was testing for three days now, and I can't find a solution for this … Even if I only use the change_order_status_post hook only, it executes the function when I delete the order …

Can you help please ?

Deleting an order also calls the fn_change_order_status function, to change the order's status to Incomplete before deleting it, in order to reset the amount of products bought in that order.

Deleting an order also calls the fn_change_order_status function, to change the order's status to Incomplete before deleting it, in order to reset the amount of products bought in that order.

Now I see the issue, do you have a proposal on how to fix it ? What's the best approach here ?

Now I see the issue, do you have a proposal on how to fix it ? What's the best approach here ?

In case you wish not to execute the fn_ss_order_threads_change_order_status_post function when it is called from fn_delete_order, you can try similar construction:

$backtrace = debug_backtrace();
if ($backtrace[3]['function'] === 'fn_delete_order') {
    return;
}

in that function.

Hope it will help you.