CheckoutFinland / psp-api

5 stars 5 forks source link

How to handle situation when payment status update comes in too late #73

Open niklasmannila opened 4 years ago

niklasmannila commented 4 years ago

We are using CheckoutFinland to handle payments for bookings as well, and we have a set time limit for how long we can keep that booking locked for a customer until we free up that time for someone else. We now have a problem where the customer can possibly finish the payment but then closes the browser before it gets redirected back through CheckoutFinland and to our redirect url. For example if the customer doesn't wait until the browser automatically redirects, doesn't press the "Back to the seller" button and simply closes the browser.

We did some tests in production, with actual OP payment and that payment took a really long time to be polled and registered by CheckoutFinland. In our case it took until next morning, several hours later.

In our use case, we cannot allow the booking to stay "locked" that long and we need a faster reliable reply that it has been paid. By the time the payment status has been changed to 'ok', we have already released the lock and cancelled the booking since it took to long to get an answer about the payment status. So the problem we are having at this point is that the customers transaction has finished and the customer has been charged for the payment but the booking that the customer paid for is already cancelled.

What do you suggest we do in this case or is there a recommended way of handling this scenario? Also, would it be possible to have Checkout poll the bank a little earlier?

Ahtoranta commented 4 years ago

Hi. That is true, closing the browser before success/cancel redirections or connectivity issues etc. breaks the "real time" payment flow. As we cannot tell is the payment just a shopping cart left behind (there are naturally lots of these) or paid but broken payment flow, we must poll all payments that are in state new (in other words not exclusively succeeded/cancelled). There are faster ways to poll the individual payments states from providers but those would be way more expensive to use.

Also the window to complete the payment at provider side is quite long and we need to accept that the customer may complete the payment days after it's initiation.

In those cases some integrators have done implementations which automatically fires a refund to payment that is already been released by shopping system before (delayed) succeeded payment.

snekbaev commented 4 years ago

Hi,

this week we enabled OPCheckout for certain bank payments and also ran into that issue for which I contacted the support. The main problem is that customer is under assumption that payment did go through and technically it did, but it's too late for the order and yes, auto-refund kicked in (12 hours later in that specific case), but because sums might be large we can't do anything if customer contacts us and asks for a refund so he can try again within a meaningful time frame as by that moment the product might be sold out and customer didn't have enough extra funds to retry. That's quite bad UX.

@Ahtoranta how about this proposal: the Create payment request can have an extra property such as payment window duration. Say, it is set to 20 mins, then if your back-end receives some transaction details from a bank and that window has expired - you issue an auto-refund without contacting the merchant's webhooks. This gives an option whether merchant wants to handle the "expired" transactions or simply leave it to your back-end as less moving parts are better.

Thank you!

niklasmannila commented 4 years ago

Thanks for the tips! We decided, for now, to handle this a little differently. Since the customer might notice that the he/she has been charged for the transaction before checkout has handled the payment, they might contact the company and ask for a refund immediately. And if the company decides to do this, then it would mean that another refund would happen automatically once checkout notices that the transaction went through. Might be able to do some logic that would check for this case and only auto refund if the customer hasn't already been refunded but we will take a closer look at this at a later stage. We haven't had any real issues with this yet since it seems like most people do complete all the steps and return to the sellers page after a transaction so it is not such a big deal at the moment.

snekbaev commented 4 years ago

@niklasmannila we already had at least 3 known cases within about a week (since we added bank payments). Today one customer probably (as I don't know for sure, transaction is "New" for now) ran into the same issue - didn't return properly for unknown reasons to me. It takes time from the support and me to look into each case.

As for your implementation suggestion: do you mean I would be able to refund a transaction that has "New" status? If so, such refunds will probably become "email provider" refunds regardless of the bank, as you can't really refund something you don't have enough info about yet. Also, isn't it so that underlying problem still remains - funds are frozen for the time being anyway until you will receive the payment info from the bank and actual refund is initiated. In this case, with my suggestion I don't have to call you again, I provided a value - a duration (and user's email and other possible info which might be needed for auto-refund) within which I'm ready to accept the payment notification, later on - not interested, please auto-refund. This approach makes caller's life much easier. You can even implement both: for those merchants who may decide to refund the new transaction for some reason (given that you don't have that feature yet, probably not many requests for it) and for others who have expiring shopping carts and definitely not interested in payment notification coming late as there's no order anymore. My suggestion will require you to implement #72 first.

Thank you!

niklasmannila commented 4 years ago

@snekbaev it was not really an implementation suggestion, as I am not part of the Checkout Finland dev team. We are simply integrating Checkout into our own system and trying to figure out how to handle these cases. How we will actually overcome issue this is still a little bit of a work in progress. I should have clarified this in the beginning, I was thanking @Ahtoranta for his reply to my initial question :)

snekbaev commented 4 years ago

@niklasmannila oh lol, was surprised a bit :)

but yeah, they are really slow to reply to support emails, basically asking here and via their support - it's quite painful to dev when you need certain questions to be answered now, but 2 weeks later.

One matter that I have open now is that refunds can be done either directly (if bank supports refund API) and via email provider as fallback (when a regular email is dispatched to the user). In one of the late charge notification cases a refund provider for bank that does support direct refund was email provider, whereas expectation was to be a direct refund. Asked why...

And the follow up question was about "email provider" which doesn't seem to be (at least when I was testing back then) anything else than an intention to do the refund, i.e. for a charge of 10 EUR you can dispatch several 10 EUR email refunds, but that doesn't guarantee an actual refund. During the development I asked whether I will receive a notification when the actual refund has completed and got a confirmation for that. And that makes sense, yes, I can dispatch several refund emails, but what I'm really interested is when the actual refund happens. So my refund logic ignores "email provider" webhook callbacks for refunds as it expects a real bank provider to be provided for the real refund... but this doesn't seem to be the case: we refunded via email and my own refund logic is still "waiting" for the callback to finalize the refunding in the system... though in Extranet that order is indicated as refunded. And that's a problem... I can't treat "email provider" refund callback as the actual refund just because an email was dispatched to the user. Trying to figure out is it a PEBKAC or what is going on.

Also heads up, email refunds can be active up to 60 days (afair) and you will not get a notification if they just expire or cancelled via Extranet :)