- Issue created by @iamfredrik
- ๐ซ๐ฎFinland tuutti
It seems to fail to this access check: https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/check...
I'm wondering if this has something to do with MobilePay app itself, like if the user used Chrome to create the order, but the MobilePay app returned user to default browser where the cart session does not exist (Safari for example), leading to an access denied error.
Paytrail should call the notify callback even if the return callback fails. The failed order is queued and be processed by Drupal's cron.
You can check if it's stuck in queue with something like (assuming you're using database queue):
drush sqlq "select * from queue;"
. - ๐ซ๐ฎFinland iamfredrik
The queue does not contain anything from the date the order failed.
- ๐ซ๐ฎFinland tuutti
Does the order's
data
field contain anything withcommerce_paytrail_maximum_captures
? - ๐ซ๐ฎFinland iamfredrik
I have no idea, since there is no order registered in the shop. If you have a sql query for retrieving the cart order, I could try that.
- ๐ซ๐ฎFinland tuutti
Maybe something like
drush sqlq "select * from commerce_order where order_id = '1983'"
- ๐ซ๐ฎFinland iamfredrik
Thanks. The data field only contains the following string: "0x613A323A7B733A32313A22706169645F6576656E745F64697370617463686564223B623A303B733A32303A227465726D735F616E645F636F6E646974696F6E73223B693A313B7D"
- ๐ซ๐ฎFinland tuutti
Can you check your web server's access logs if there's any entries matching
/payment/notify/paytrail
andcheckout-reference=1983
, something likecat /your/access.log | grep '/payment/notify/paytrail' | grep '1983'
.I'm trying to figure out if Paytrail actually called the notificiation callback at some point.
- ๐ซ๐ฎFinland iamfredrik
I found lots of checkout-reference entries, but none that matched '1983'.
- ๐ซ๐ฎFinland iamfredrik
Found it:
/payment/notify/paytrail?checkout-account=9XXXXX&checkout-algorithm=sha512&checkout-amount=1500&checkout-stamp=4567debe-0c93-4f20-a1f8-9abe2023e810&checkout-reference=1983&checkout-status=ok&checkout-provider=mobilepay&checkout-transaction-id=e26b303c-da17-11ed-adbd-a7c59d4b19c0&signature=b460d0fdcc1d7928c99a366789d134d1b8e77e78d11f1234ca0edf7650a5f184a4d68292b214babebd92e24df71589cc0e1e09a762aa71541b8c107cf110afee HTTP/1.1" 200 554 "-" "Paytrail Payment Registrationโ
- ๐ซ๐ฎFinland tuutti
Did you check if the order has any payments made (
/admin/commerce/orders/1983/payments
)? - ๐ซ๐ฎFinland tuutti
Weird. The order should be "placed" by payment module's OrderPaidSubscriber when the order is paid in full: https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/payme...
I tested this using test credentials:
1. Created an order
2. Used Nordea as payment method
3. Copied the URL from "Simulate success to merchant" button:
4. Opened the URL in incognito mode and the return page gave an access denied error:
5. The order is now in "draft" status with no payments
6. Paytrail called the notify callback and the order is "placed" after I ran cron:
- ๐ซ๐ฎFinland tuutti
You can find orders that are not placed, but has a payment marked as completed with this SQL query:
select o.order_id from commerce_order o left join commerce_payment p on o.order_id = p.order_id where o.state = 'draft' and p.state = 'completed'
- ๐ซ๐ฎFinland iamfredrik
I checked a couple of those with select * from commerce_order where order_id = 'XXXX'; and one thing they have in common and is different from ones that are actually placed is that the following tables are NULL:
order_number
total_paid__number
total_paid__currency_code
placed
completed - ๐ซ๐ฎFinland iamfredrik
I checked the access log for '2007' and the checkout-provider is Osuuspankki, so the problem apparently is not limited to MobilePay.
- ๐ซ๐ฎFinland iamfredrik
I looked up all from the list in the access log. They were all mobilepay except one from almost a year ago which was aktia_paytrail.
- ๐ซ๐ฎFinland iamfredrik
I have now tested the steps in #13. The order is placed after cron run, but not if cron is run after 3 hours (standard cron setting in Drupal). So the conclusion is that the notify callback expires after some time within 3 hours after the order is placed.
- ๐ซ๐ฎFinland tuutti
Does your queue items get an expiration date even if you don't run cron? (
select * from queue;
). The initial item shouldn't get an expiration date - ๐ซ๐ฎFinland iamfredrik
It is no longer in the queue after cron run, so I have to retest.
- ๐ซ๐ฎFinland tuutti
Does the cron fail or does the queue item just get removed before it's actually processed (after that 3 hour limit you mentioned earlier)? The expire date should only be updated when the item is actually claimed: https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/lib/Drupal/...
- ๐ซ๐ฎFinland iamfredrik
I believe the queue item gets removed only when cron is run, but I'd have to wait 3 hours to verify.
- ๐ซ๐ฎFinland iamfredrik
The queue item gets removed only when cron is run after which the order gets the payment info added, but the order is not moved from draft state to completed order if cron is run 3+ hours later (could be sooner, but haven't tested).
Steps to reproduce:
1. Disable cron
2. Create an order by following the steps outlined in #13
3. Verify that the queue item exists (select * from queue;)
4. Wait 3+ hours
5. Verify that the queue item still exists (select * from queue;)
6. Run cron manually
7. Verify that the queue item is removed (select * from queue;)
8. Check if order is placed or still in draft mode - ๐ซ๐ฎFinland tuutti
I was able to reproduce this on my test site too. I'll look into this a bit more tomorrow.
- ๐ซ๐ฎFinland tuutti
My best guess for now is that this has something to do with core's
automated_cron
module conflicting with some commerce functionality. I vaguely remember seeing some order processing done inTERMINATE
kernel event and the automated cron is triggered onTERMINATE
kernel event too: https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/modules/aut... - ๐ซ๐ฎFinland tuutti
Looks like my guess was right. The commerce payment module seems to rely on core's KernelDestructionSubscriber.php to trigger PaymentOrderUpdater service that eventually triggers the OrderPaidSubscriber that "places" the order when the order is paid in full.
Looks like the KernelDescturctionSubscriber is never triggered when AutomatedCron is run (or they are run in wrong order), leading to PaymentOrderUpdater.php never being run.
I don't think there's much that can be done on our side. Easiest way to fix this is not to rely on
automated_cron
module and trigger the cron some other way: https://www.drupal.org/docs/administering-a-drupal-site/cron-automated-t... โ - ๐ซ๐ฎFinland tuutti
Actually, looks like the original issue ๐ The changes made to the order on the onNotify method are not applied on the onReturn method Fixed (the reason why we even process orders via cron ) seems to be fixed now. The whole queue logic can probably be removed on next Commerce release, which should automatically fix this issue.
- ๐ซ๐ฎFinland iamfredrik
Okay thanks. The issue with the return url being opened in the wrong browser still needs to be addressed, because the 'access denied' message leads to a confusing customer experience. Is it Paytrail's or Mobilepay's responsibility to fix it?
- ๐ซ๐ฎFinland tuutti
I don't have any means to verify if that's even the real culprit, but it's probably something along those lines and it's probably something that should be fixed on Commerce itself. I found this issue ๐ฌ User is sent to 403 page after successful payment (anonymous checkout) Needs work , but it doesn't seem to be very active at the moment.
- ๐ซ๐ฎFinland iamfredrik
Thank you very much for that link. I will give the patch a try.
- Status changed to Closed: works as designed
over 1 year ago 5:30am 27 April 2023 - ๐ซ๐ฎFinland tuutti
I've made a follow up task for this ๐ Deprecate queue processing Fixed .
- ๐ซ๐ฎFinland iamfredrik
Doesn't seem to be working anymore after updating to Commerce Payment Paytrail 3.0.0.
How to reproduce:
Create an order that returns access denied by following the steps in #13
Order is not finalized and running cron does no longer finalize the order.
- ๐ซ๐ฎFinland iamfredrik
Works if I apply patch #40 from:
https://www.drupal.org/project/commerce/issues/3051241 ๐ฌ User is sent to 403 page after successful payment (anonymous checkout) Needs workSo it's seems deprecating queue logic should not have been done until that issue is fixed. Please update the documentation that the patch is required.
- ๐ซ๐ฎFinland tuutti
I added a 120 second delay for notification callback in ๐ Deprecate queue processing Fixed , which should eliminate the original issue too. Does the delay not work for you?