customer notification not send after status update

  • Posts: 339
  • Thank you received: 26
1 month 1 week ago #372154

-- url of the page with the problem -- : www.cultuuroudenbosch.nl/
-- HikaShop version -- : 6.5.0
-- Joomla version -- : 6.1.1
-- PHP version -- : 8.4

Hi,
We are using RO Payments for handling the payments and the return to HikaShop.

In here we set the status of the order to "Shipped" because it's about digital tickets.
I have updated the setting to always notify the customer when updating an order.

The problem is that this e-mail is not send when the status is updated via RO Payments but is when done manually.
Checked with Roland and he tells me that when the test are done and the statuses meet the requirements he execute this code :
$history->notified = 1;

Now can you help us figure out if anything is wrong with this approach?

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
1 month 1 week ago #372156

Hi,

Setting notified = 1 is the right idea, the customer status email is gated on that flag, but it only goes out if the call to modifyOrder is done in a way that actually saves the order. Two things need to be true, and the second one is the most likely reason it works manually but not through RO Payments.

1. The history object (with notified = 1) has to be passed as the third argument of modifyOrder, for example $this->modifyOrder($order_id, 'Shipped', $history). HikaShop rebuilds the history record from that argument, so anything set directly on $order->history is ignored. The simplest equivalent is to pass true as the third argument:

$this->modifyOrder($order_id, 'Shipped', true)

true maps straight to notified = 1.

2. modifyOrder has to be called with the integer order id, not the order object. This is the important one. modifyOrder only saves the order (and therefore only sends the customer email) when the first argument is an id and not an object. Passing the order object is meant for the order creation flow, where the order is saved later by the controller. For a status change on an existing order, passing the object means no save happens, so the customer notification is never sent. That matches what you see: the manual backend update sends the mail, the RO Payments update does not.

So could you ask Roland to check that he calls modifyOrder with the integer order id (not the order object), and passes the notification as the third argument (true, or the history object with notified = 1). With that, the Shipped status email will be sent like it is for a manual update.

One side note so there is no confusion: the email parameter and the "payment notification email" setting control a separate notification that goes to the shop owner, not to the customer. The customer status email is the notified flag on the history, which is what you already identified.

Please Log in or Create an account to join the conversation.

  • Posts: 273
  • Thank you received: 40
  • Hikamarket Multivendor Hikashop Business
1 month 1 week ago #372162

useless response from me after Nicolas' message, that's why I deleted it, sorry :whistle:

Last edit: 1 month 1 week ago by oxido. Reason: useless response from me after Nicolas' message

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
1 month 6 days ago #372188

Hi Nicolas,

Roland added some extra logging to check what is done. This comes from the logging when doing a successful payment:

[2026-06-08 13:45:20] Send customer to URL: www.mollie.com/checkout/select-method/LfVv44peTFeP4ZWM29LSJ
[2026-06-08 13:45:27] == Start Payment provider processing
[2026-06-08 13:45:27] Found log ID: 104
[2026-06-08 13:45:27] Query string: pid=nkpy8QKMI9TL7JFC0ecrJEDGXoFblPEipwXhC6G9f7QpRwnu7L
[2026-06-08 13:45:27] Get transaction status
[2026-06-08 13:45:27] Customer processing
[2026-06-08 13:45:27] [Customer] Query string: pid=nkpy8QKMI9TL7JFC0ecrJEDGXoFblPEipwXhC6G9f7QpRwnu7L
[2026-06-08 13:45:27] [Customer] Is transaction processed: No
[2026-06-08 13:45:27] [Customer] Going to sleep
[2026-06-08 13:45:27] Received payment status: paid
[2026-06-08 13:45:27] Has chargebacks: No
[2026-06-08 13:45:27] Received card: ideal
[2026-06-08 13:45:28] Payment sequence: oneoff
[2026-06-08 13:45:28] Processing OK status
[2026-06-08 13:45:28] Payment has SUCCESS status
[2026-06-08 13:45:28] Current order status P
[2026-06-08 13:45:28] Send customer change status email
[2026-06-08 13:45:28] {"order_number":"B-00111","order_id":111,"order_total":"37.50000","order_status":"shipped","user_email":"xxxx@xxxx.nl","order_comment":"Transactie nummer: tr_LfVv44peTFeP4ZWM29LSJ"}
[2026-06-08 13:45:28] Send admin order payment email
[2026-06-08 13:45:28] Setting payment as processed
[2026-06-08 13:45:28] Start Notify extension
[2026-06-08 13:45:28] Result status is valid
[2026-06-08 13:45:28] Starting payment notification
[2026-06-08 13:45:28] Order status is created
[2026-06-08 13:45:28] Get status code for result SUCCESS and profile mollie
[2026-06-08 13:45:28] Status code RO Payments: C
[2026-06-08 13:45:28] Status code RO Hikashop: shipped
[2026-06-08 13:45:28] Work with status: shipped
[2026-06-08 13:45:28] Set History notified to 1
[2026-06-08 13:45:28] History notified is 1
[2026-06-08 13:45:28] History details
[2026-06-08 13:45:28] {"notified":1,"amount":37.5,"type":"payment","data":"Transactie nummer: mollie_6a26c76e4cd25"}
[2026-06-08 13:45:28] Modifying order 111 to status shipped
[2026-06-08 13:45:28] [Customer] Waking up
[2026-06-08 13:45:28] [Customer] Result: SUCCESS
[2026-06-08 13:45:28] [Customer] Is transaction processed: Yes
[2026-06-08 13:45:28] [Customer] Payment already processed
[2026-06-08 13:45:28] [Customer] Payment result is SUCCESS
[2026-06-08 13:45:28] [Customer] Payment status is valid
[2026-06-08 13:45:28] Redirect to: xxx.xxxxxx.nl/index.php?option=com_hikas...EipwXhC6G9f7QpRwnu7L
[2026-06-08 13:46:27] == Start Payment provider processing
[2026-06-08 13:46:27] Found log ID: 104
[2026-06-08 13:46:27] Query string: pid=nkpy8QKMI9TL7JFC0ecrJEDGXoFblPEipwXhC6G9f7QpRwnu7L
[2026-06-08 13:46:27] == End Payment provider processing
[2026-06-08 13:48:26] == Start Payment provider processing
[2026-06-08 13:48:26] Found log ID: 104
[2026-06-08 13:48:26] Query string: pid=nkpy8QKMI9TL7JFC0ecrJEDGXoFblPEipwXhC6G9f7QpRwnu7L
[2026-06-08 13:48:26] == End Payment provider processing
J! Info
Request
Session
Profile
Queries19
5.109MB
305ms

Hope this is giving some inspiration on the matter :-)

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
1 month 5 days ago #372191

Hi,

There are actually two modifyOrder methods and they do not take the arguments in the same order, which is almost certainly what is happening here.

- The payment plugin one (called as $this->modifyOrder(...) from a plugin that extends hikashopPaymentPlugin) takes the history as its 3rd argument:
$this->modifyOrder($order_id, 'shipped', $history, $email);
That is the form you see in the example plugin and in our documentation and what I was referring to in my previous message here.

- The order class one (hikashop_get('class.order')->modifyOrder(...)) takes the payment method name as its 3rd argument and the history as its 4th:
hikashop_get('class.order')->modifyOrder($order_id, 'shipped', 'ro_payments', $history);

So if RO Payments calls the order class directly with the history as the 3rd argument (the usual payment-plugin form), the history object lands in the payment-name slot and the real history stays empty, so the notified flag is lost. The order is still saved and the status still changes to shipped, but no customer email goes out, which matches your logs exactly (your own history object is correctly set to notified = 1, but it never reaches the notification code).

If you are calling the order class, move the flag to the 4th argument:

hikashop_get('class.order')->modifyOrder($order_id, 'shipped', 'ro_payments', true);
// or, with your history object (history->notified = 1):
hikashop_get('class.order')->modifyOrder($order_id, 'shipped', 'ro_payments', $history);

If RO Payments is itself a HikaShop payment plugin and uses $this->modifyOrder, then the 3rd-argument form is correct and the flag is fine; in that case the email would be empty for another reason.

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
1 month 5 days ago #372196

Hi,

Roland is using this:
$this->modifyOrder as payment plugin.

This code has not been changed for a long time.

He would also like to know what the conditions are for sending this e-mail with the (in this case) serial tickets. Is this just that "notified" ?

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
1 month 5 days ago #372197

Hi,

To answer your direct question first: for a status change, the customer email is sent when three things are true, not just "notified":
1. the history "notified" flag is set (which you confirmed),
2. no plugin clears the send flag during the onAfterOrderUpdate event,
3. the order has a customer email address to send to.

HikaSerial hooks onAfterOrderUpdate too, but it only assigns the serials there; it does not clear the send flag. At send time it adds the serials into the status email rather than blocking it. So a serial-ticket order has no extra email condition compared to a normal order, it should send like any other.

Since "notified" is confirmed and HikaSerial is not blocking it, the cleanest next step is to log the email decision so we see exactly where it is lost. In administrator/components/com_hikashop/classes/order.php, find the order update branch (search for "history_notified" near "onAfterOrderUpdate") and add the four hikashop_writeToLog lines marked NEW:

			$send_email = @$order->history->history_notified;
			hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': update branch reached, notified='.var_export($send_email,true).', status='.@$order->order_status);   // NEW
			$app->triggerEvent('onAfterOrderUpdate', array( &$order, &$send_email) );
			hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': after onAfterOrderUpdate, send_email='.var_export($send_email,true));   // NEW

			$historyClass->addRecord($order);

			if(!$send_email) {
				hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': SUPPRESSED, send_email empty after the plugins');   // NEW
				return $order->order_id;
			}

a bit further down, where the mail is sent:
			if(!empty($order->mail)) {
				$mailClass = hikashop_get('class.mail');
				hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': dst_email='.var_export(@$order->mail->dst_email,true).', mail_name='.@$order->mail->mail_name);   // NEW
				if(!empty($order->mail->dst_email)) {
					$mailClass->sendMail($order->mail);
					hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': sendMail done, success='.var_export(@$mailClass->mail_success,true));   // NEW
				}

Then place one order paid through RO Payments (the failing case) and change one order's status by hand in the backend (the working case with the user notification activated), and send me the EMAILDEBUG lines from the HikaShop log for both. They will tell us exactly where it diverges:

- if the "update branch reached" line is missing for the RO Payments order, then the order modification did not save through this path at all (for example the order object, not its id, was passed), and the issue is on the call side, not the email,
- if "send_email" becomes empty after onAfterOrderUpdate, a plugin is clearing it,
- if send_email stays set but dst_email is empty, the order has no recipient in that context,
- if sendMail runs with success=false, it is a mailer problem.


If that second line shows send_email becoming empty after onAfterOrderUpdate (the most likely case), a plugin is clearing it. To find exactly which one, replace that single dispatch line:
			$app->triggerEvent('onAfterOrderUpdate', array( &$order, &$send_email) );

with this block, which runs the same plugins one by one (each exactly once, so the order is still processed normally) and logs the culprit:
			$diagDispatcher = new \Joomla\Event\Dispatcher();
			foreach(JPluginHelper::getPlugin('hikashop') as $diagP) {
				$diagClass = 'plgHikashop'.ucfirst($diagP->name);
				if(!class_exists($diagClass))
					continue;
				try {
					$diagInst = new $diagClass($diagDispatcher, (array)$diagP);
					if(!method_exists($diagInst, 'onAfterOrderUpdate'))
						continue;
					$diagBefore = $send_email;
					$diagInst->onAfterOrderUpdate($order, $send_email);
					hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': plugin "'.$diagP->name.'" -> send_email='.var_export($send_email,true).($send_email != $diagBefore ? '   <<< CLEARED BY THIS PLUGIN' : ''));
				} catch(\Throwable $diagE) {
					hikashop_writeToLog('EMAILDEBUG order '.@$order->order_id.': plugin "'.$diagP->name.'" could not be run on its own: '.$diagE->getMessage());
				}
			}

The line marked "<<< CLEARED BY THIS PLUGIN" names the culprit. A throwaway dispatcher is used so the plugins are not re-registered on the live one, and each plugin still runs exactly once, so the order processes as usual. Put the original triggerEvent line back once you have the name.

Remove the NEW lines once we have the answer.

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
1 month 5 days ago #372202

Hi Nicolas,

We added the log lines and found out that it stops at step 3:

if send_email stays set but dst_email is empty, the order has no recipient in that context,

Here is the log from the test:

<h3>06.09.26 14:45:22</h3>
EMAILDEBUG order 123: update branch reached, notified=1, status=shipped

<h3>06.09.26 14:45:22</h3>
EMAILDEBUG order 123: after onAfterOrderUpdate, send_email=1

What does this mean for the next step(s)? Anything else we should check and/or test?

Regards,

Roland

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
1 month 4 days ago #372205

Hi Roland,

Good, that narrows it down nicely. You are right that it stops at the recipient: the status email is gated on dst_email, and an empty dst_email means no send even though send_email is 1.

Where dst_email comes from: it is only ever filled inside loadOrderNotification(), which loads the customer from the order's order_user_id and sets dst_email to customer->user_email. The important part for your case is when that function is NOT called. In the update branch of the order save, loadOrderNotification only runs when $order->mail is still empty. If $order->mail is already set on the order object at that point, HikaShop takes the other path and never builds dst_email, so it stays empty. The same applies if $order->customer is already set with a user_id matching order_user_id but without a user_email: the customer is then not reloaded and dst_email ends up empty.

That is the difference with the manual update. The backend save carries a fully loaded order with the customer (and email) already attached, so it sends. A gateway callback that passes a pre-built order object carrying its own ->mail (or a ->customer without the email) makes HikaShop reuse that object and skip the lookup that fills the recipient.

Two things to try:

1. Call modifyOrder with the integer order id only, and do not attach $order->mail or a partial $order->customer to it beforehand. With a plain id, HikaShop builds a fresh order, reloads it from the database, loads the customer from order_user_id, and fills dst_email itself. That is the cleanest fix and matches the id-not-object point from earlier in the thread.

2. To confirm which of the two cases it is, add these two lines in the same update branch where you already log (right around the loadOrderNotification call):

hikashop_writeToLog('EMAILDEBUG order '.$order->order_id.': mail_preset='.(empty($order->mail)?'no':'yes').', order_user_id='.(int)@$order->order_user_id);
// and just before the dst_email check / sendMail:
hikashop_writeToLog('EMAILDEBUG order '.$order->order_id.': dst_email= customer_email=');

If mail_preset is "yes", RO Payments is setting $order->mail before the save, which is the cause. If mail_preset is "no" but customer_email is empty, then order_user_id points to a user record with no user_email, in which case check that the order's order_user_id is the real customer record and that it has an email on file (relevant for guest or admin-created orders).

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
3 weeks 6 days ago #372248

a reply from Roland :

Hi Nicholas,

> Call modifyOrder with the integer order id only

The method requires 2 arguments where the second argument is the $order_status. What should I put there?

At least I assume I am calling the modifyOrder from the payment plugin, is that correct?

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
3 weeks 6 days ago #372249

The second argument should be the new order status.
For example: "confirmed"
Yes, you normally what you use $this->modifyOrder() inside the main class of the payment plugin which extends from hikashopPaymentPlugin.

It's basically what I said a week ago:
- The payment plugin one (called as $this->modifyOrder(...) from a plugin that extends hikashopPaymentPlugin) takes the history as its 3rd argument:
$this->modifyOrder($order_id, 'shipped', $history, $email);
www.hikashop.com/forum/orders-management...s-update.html#372191

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
2 weeks 4 days ago #372390

Hi Nicolas,
An update from what Roland is doing. These 2 lines are after each other :

$this->modifyOrder($orderId, $status);
$this->modifyOrder($orderId, $status, $history, $email);

And we see this in the log:

<h3>06.24.26 06:33:16</h3>
EMAILDEBUG order 124: update branch reached, notified=0, status=shipped
<h3>06.24.26 06:33:16</h3>
EMAILDEBUG order 124: after onAfterOrderUpdate, send_email=0
<h3>06.24.26 06:33:16</h3>
EMAILDEBUG order 124: SUPPRESSED, send_email empty after the plugins
<h3>06.24.26 06:33:16</h3>
EMAILDEBUG order 124: update branch reached, notified=1, status=shipped
<h3>06.24.26 06:33:16</h3>
EMAILDEBUG order 124: after onAfterOrderUpdate, send_email=1
<h3>06.24.26 06:33:16</h3>
EMAILDEBUG order Before loadOrder 124: mail_preset=no, order_user_id=1

Does this make sense or give any insight?

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
2 weeks 4 days ago #372392

Hi,

Two things stand out in that log.

1. You are calling modifyOrder twice in a row:

$this->modifyOrder($orderId, $status);
$this->modifyOrder($orderId, $status, $history, $email);

The first (bare) call is the one that actually moves the order created -> shipped, and it runs with notified=0. That is exactly the first block in your log: update branch reached notified=0 -> send_email=0 -> SUPPRESSED. The second call then only re-saves shipped -> shipped with notified=1. Drop the first call and keep a single one that carries the notification:
$this->modifyOrder($orderId, $status, $history, $email);

That single call is the exact equivalent of changing the status by hand in the backend with the user notification ticked, which is the case that already sends for you.

2. For the recipient: mail_preset=no is good news, it means RO Payments is not pre-setting $order->mail, so HikaShop builds the recipient itself and the earlier preset-mail theory is ruled out. That leaves order_user_id=1. dst_email is filled from the customer loaded behind order_user_id, so if user 1 is not the real buyer (or has no email on file), dst_email stays empty and the mail is skipped. A test order paid while logged in as the admin can easily land on user 1.

So please:
- check that order 124's order_user_id is the buyer's HikaShop user (Customers listing) and that this user has an email,
- add one more log line that shows the recipient after it is loaded.

It goes in the same update branch of administrator/components/com_hikashop/classes/order.php where you already added the other EMAILDEBUG lines, right after the loadOrderNotification block and just before the if(!empty($order->mail)) that sends. That way it still logs when dst_email came back empty:
if(empty($order->mail) && isset($order->order_status)) {
			$this->loadOrderNotification($order,'order_status_notification');
		} elseif(!empty($order->mail)) {
			$order->mail->data = &$order;
			$order->mail->mail_name = 'order_status_notification';
		}
		// NEW:
		hikashop_writeToLog('EMAILDEBUG order '.$order->order_id.': dst_email='.var_export(@$order->mail->dst_email,true).', user_email='.var_export(@$order->customer->user_email,true));
		if(!empty($order->mail)) {
			$mailClass = hikashop_get('class.mail');
			if(!empty($order->mail->dst_email)) {
				$mailClass->sendMail($order->mail);
			}
			$this->mail_success =& $mailClass->mail_success;
		}

It is the companion to your "Before loadOrder ... mail_preset=no, order_user_id=1" line, which sits a few lines up: that one shows the inputs, this one shows the result of loadOrderNotification (the actual recipient).

Then, place one more RO Payments order with the single modifyOrder call and send me that line.

If dst_email does come back empty, it is one of these, all about the customer behind order_user_id (since mail_preset=no, loadOrderNotification did run and read that user record):

1. order_user_id is not the buyer. Here it is 1, which is usually the admin or the first user, so the lookup loads the wrong person. A test order paid while logged in as the admin lands on this case. It is also possible that the email server of the hosting refuses sending an email if the recipient and the sender email addresses are the same. That could be a possibility here.

2. order_user_id is the right customer but that user has no email address on file. This should normally never happen. It could indicate that $order->customer has been modified by something at some point.

3. RO Payments attaches a partial $order->customer to the order before the save (same user_id as order_user_id but without user_email). Because the user_id matches, HikaShop does not reload the customer from the database, so the empty email is kept. The fix there is the same as for the call: pass only the integer order id and let HikaShop build the order and the customer itself.

The fourth case, $order->mail preset so the recipient lookup is skipped entirely, is already ruled out by your mail_preset=no.

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
1 week 2 hours ago #372524

Hi Nicholas,

The double modifyOrder call has been removed, I just added it because I wasn't sure what you were asking last time. The user ID 1 is the order user and has an email linked. Another test with a guest user also did not send the email with PDF attachment.

The log now shows the following:
<h3>07.07.26 12:14:37</h3>
EMAILDEBUG order 125: update branch reached, notified=0, status=shipped
<h3>07.07.26 12:14:37</h3>
EMAILDEBUG order 125: after onAfterOrderUpdate, send_email=0
<h3>07.07.26 12:14:37</h3>
EMAILDEBUG order 125: SUPPRESSED, send_email empty after the plugins
<h3>07.07.26 12:14:37</h3>
EMAILDEBUG order 125: update branch reached, notified=1, status=shipped
<h3>07.07.26 12:14:37</h3>
EMAILDEBUG order 125: after onAfterOrderUpdate, send_email=1
<h3>07.07.26 12:14:37</h3>
EMAILDEBUG order Before loadOrder 125: mail_preset=no, order_user_id=9

Notice that it ends with the "Before loadOrder" while the code should show another line with "After loadOrder". Here is how the code looks like in the order.php:
hikashop_writeToLog('EMAILDEBUG order Before loadOrder '.$order->order_id.': mail_preset='.(empty($order->mail)?'no':'yes').', order_user_id='.(int)@$order->order_user_id);
$this->loadOrderNotification($order,'order_status_notification');
hikashop_writeToLog('EMAILDEBUG order After loadOrder '.$order->order_id.': mail_preset='.(empty($order->mail)?'no':'yes').', order_user_id='.(int)@$order->order_user_id);

Does it stop/die in the loadOrderNotification()?

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
6 days 22 hours ago #372525

Hi,

Yes. The missing "After loadOrder" line is the proof: execution enters loadOrderNotification() and never comes back, so it dies inside that call and not in the status logic. And now that the log shows mail_preset=no with order_user_id=9, the recipient part is correct, so what fails is the email build itself.

Inside loadOrderNotification() the heavy step is where it builds the message:

$order->mail = $mailClass->get('order_status_notification', $order);

That call loads the mail template, which reloads the full order and generates its attachments (your PDF). A PHP fatal in there, or in a plugin hooked on the mail, kills the whole request with no "After loadOrder" and no send. It works from the backend because that runs in the admin context, while the RO Payments return/webhook runs as a front, guest request where the same attachment build can fail (a class that is not autoloaded there, or the memory or execution time limit hit while making the PDF).

Two steps to pin it down:

1. Capture the error. The webhook is headless, so the fatal is not printed on screen, only logged. Wrap the call:
try {
    $this->loadOrderNotification($order, 'order_status_notification');
} catch (\Throwable $e) {
    hikashop_writeToLog('EMAILDEBUG order '.$order->order_id.' loadOrder THREW: '.$e->getMessage().' in '.$e->getFile().':'.$e->getLine());
    throw $e;
}

Also look at the site PHP error log around that timestamp. One of the two should name the exact file and line. Note that a real out of memory or max execution time fatal is not catchable, so if the try/catch logs nothing, step 2 is what will show it.

2. Confirm the attachment is the trigger. In System > Emails > Order status notification, temporarily remove the PDF attachment, then place one more RO Payments order. If the mail goes out without the attachment, the PDF generation in the callback context is the cause, and the fix is usually raising memory_limit and max_execution_time for that return URL, or loading the class the attachment needs.

Send me the THREW line (or the error log entry) and the result of the no-attachment test.

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
1 day 3 hours ago #372595

Hey Nicolas,

So we tested this further and I also generated a trace as to see what is going on. The trace you will find at the end. What I see happening is that HikaSerial is trying to load the HTML template by going into the code below in the file ***/www/administrator/components/com_hikaserial/helpers/helper.php on line 1031.

$active = $config->get('display_view_files', 0);
if(!$active)
return parent::loadTemplate($tpl);
This call goes to the core HtmlView class for loading the template. The core view, libraries/src/MVC/View/HtmlView.php, on line 373 executes this code:

if (Factory::getApplication()->getDocument()->getType() !== 'html') {
At this point there is no document instantiated/created/initialised so the getDocument() returns null and as such the getType() cannot be executed either, this throws the fatal error.

That stops everything. That is as far as my knowledge goes of this flow.

EMAILDEBUG order #0 ***/public_html/administrator/components/com_hikaserial/helpers/helper.php(1033): Joomla\CMS\MVC\View\HtmlView->loadTemplate()
#1 ***/public_html/libraries/src/MVC/View/HtmlView.php(204): hikaserialView->loadTemplate()
#2 ***/public_html/administrator/components/com_hikaserial/helpers/helper.php(882): Joomla\CMS\MVC\View\HtmlView->display()
#3 ***/public_html/components/com_hikaserial/views/orderserial/view.html.php(18): hikaserialView->display()
#4 ***/public_html/administrator/components/com_hikaserial/helpers/helper.php(293): orderserialViewOrderserial->display()
#5 ***/public_html/plugins/hikashop/serials/serials.php(358): hikaserial::getLayout()
#6 ***/public_html/libraries/src/Plugin/CMSPlugin.php(386): plgHikashopSerials->onAfterOrderProductsListingDisplay()
#7 ***/public_html/libraries/vendor/joomla/event/src/Dispatcher.php(454): Joomla\CMS\Plugin\CMSPlugin->{closure:Joomla\CMS\Plugin\CMSPlugin::registerLegacyListener():370}()
#8 ***/public_html/libraries/src/Application/EventAware.php(111): Joomla\Event\Dispatcher->dispatch()
#9 ***/public_html/media/com_hikashop/mail/order_status_notification.preload.php(493): Joomla\CMS\Application\WebApplication->triggerEvent()
#10 ***/public_html/administrator/components/com_hikashop/classes/mail.php(369): include('***/publi...')
#11 ***/public_html/administrator/components/com_hikashop/classes/mail.php(32): hikashopMailClass->loadEmail()
#12 ***/public_html/administrator/components/com_hikashop/classes/order.php(2363): hikashopMailClass->get()
#13 ***/public_html/administrator/components/com_hikashop/classes/order.php(633): hikashopOrderClass->loadOrderNotification()
#14 ***/public_html/administrator/components/com_hikashop/classes/order.php(2699): hikashopOrderClass->save()
#15 ***/public_html/administrator/components/com_hikashop/helpers/paymentplugin.php(354): hikashopOrderClass->modifyOrder()
#16 ***/public_html/plugins/hikashoppayment/ropayments/ropayments.php(296): hikashopPaymentPlugin->modifyOrder()
#17 ***/public_html/components/com_hikashop/controllers/checkout.php(583): PlgHikashoppaymentRopayments->onPaymentNotification()
#18 ***/public_html/libraries/src/MVC/Controller/BaseController.php(730): checkoutController->notify()
#19 ***/public_html/administrator/components/com_hikashop/helpers/helper.php(2932): Joomla\CMS\MVC\Controller\BaseController->execute()
#20 ***/public_html/components/com_hikashop/hikashop.php(89): hikashopController->execute()
#21 ***/public_html/plugins/hikashoppayment/ropayments/addons/Hikashop.php(366): require_once('***/publi...')
#22 ***/public_html/components/com_ropayments/src/Service/Notify.php(740): Rolandd\Component\Ropayments\Site\Addons\Hikashop->notifyExtension()
#23 ***/public_html/components/com_ropayments/src/Service/Notify.php(432): Rolandd\Component\Ropayments\Site\Service\Notify->notifyExtension()
#24 ***/public_html/components/com_ropayments/src/Service/Notify.php(104): Rolandd\Component\Ropayments\Site\Service\Notify->processPayment()
#25 ***/public_html/plugins/system/ropayments/src/Extension/Ropayments.php(89): Rolandd\Component\Ropayments\Site\Service\Notify->process()
#26 ***/public_html/libraries/vendor/joomla/event/src/Dispatcher.php(454): Rolandd\Plugin\System\Ropayments\Extension\Ropayments->onAfterInitialise()
#27 ***/public_html/libraries/vendor/joomla/application/src/AbstractApplication.php(99): Joomla\Event\Dispatcher->dispatch()
#28 ***/public_html/libraries/src/Application/CMSApplication.php(829): Joomla\Application\AbstractApplication->dispatchEvent()
#29 ***/public_html/libraries/src/Application/SiteApplication.php(431): Joomla\CMS\Application\CMSApplication->initialiseApp()
#30 ***/public_html/libraries/src/Application/SiteApplication.php(238): Joomla\CMS\Application\SiteApplication->initialiseApp()
#31 ***/public_html/libraries/src/Application/CMSApplication.php(320): Joomla\CMS\Application\SiteApplication->doExecute()
#32 ***/public_html/includes/app.php(58): Joomla\CMS\Application\CMSApplication->execute()
#33 ***/public_html/index.php(51): require_once('***/publi...')
#34 {main}

Please Log in or Create an account to join the conversation.

  • Posts: 85879
  • Thank you received: 14117
  • MODERATOR
13 hours 37 minutes ago #372607

Hi,

Your analysis is exactly right, thank you for the trace, it made it clear. On Joomla 6.1, the core HtmlView::loadTemplate() calls getDocument()->getType() without checking that a document exists. When the status email is built from the RO Payments server notification, Joomla has not created a page document yet, so when HikaSerial renders its serials block for the email that call fails fatally and the notification email is never sent. Updating the status manually works because a normal backend page does have a document.

We have fixed this for the next HikaSerial release. In the meantime, you can apply the fix manually on your site. Edit the file administrator/components/com_hikaserial/helpers/helper.php and look for these two lines:

public static function getLayout($controller, $layout, $params, &$js, $backend = false) {
	$app = JFactory::getApplication();

Right after them, add this block, which provides a fallback document in that context so the email can be built and sent normally:
if(method_exists($app, 'getDocument') && $app->getDocument() === null) {
			try {
				$doc = JFactory::getContainer()->get(\Joomla\CMS\Document\FactoryInterface::class)->createDocument('html');
				if(method_exists($app, 'loadDocument'))
					$app->loadDocument($doc);
			} catch(Throwable $e) {
			}
		}

We reproduced your exact error on a Joomla 6.1.1 test site and confirmed that with this change the notification email is built normally, with no change needed on the RO Payments side. The modification will be included in the next version of HikaSerial, so it will not be lost when you update later on.

Please Log in or Create an account to join the conversation.

  • Posts: 339
  • Thank you received: 26
3 hours 30 minutes ago #372623

Hi, this seems to do the trick.
Thank you.

The following user(s) said Thank You: nicolas

Please Log in or Create an account to join the conversation.

Time to create page: 0.101 seconds
Powered by Kunena Forum