Callback mechanism: Difference between revisions

From Barion Documentation
Jump to navigation Jump to search
m (replaced reference to v2 GetPaymentState with v4 PaymentState)
(replaced old content with rewritten and approved content. to-do: links)
Line 3: Line 3:




Whenever a given payment's state changes, it is expected that the caller system and the Barion database are synchronized. This is accomplished by implementing the '''callback mechanism''' (referred to as ''"Instant Payment Notification"'' or ''"IPN"'' in some terminology) between the two systems.
Learn how to subscribe to the Barion callback mechanism, a webhook service that helps you track the state changes of payments in real time.


== The callback process ==
The basic idea is that to help automate your payment processing, the Barion server sends notifications about updates to the payments in your Barion shop, which should make your Barion shop query the Barion API’s payment state endpoint for the specifics of the status change.


The event flow of the implemented callback mechanism is simple:
Here’s an overview of the steps involved:


# The payment gets completed, cancelled, expired, refunded, taken under investigation, or released from investigation
# Set up a webhook listener endpoint (that implements the processing logic detailed on this page).
# The Barion system sends an '''HTTP POST''' request to the merchant's system to the URL defined by the merchant (in the <code>CallbackUrl</code> parameter of the [[Payment-Start-v2|/v2/Payment/Start]] API call) with the payment's unique identifier, indicating that something has just happened, so the merchant's system should check the payment now
# Provide your listener’s URL when setting up a payment ([[05-api-reference/01-payment-resource/01-payment-start#callbackurl|as a required parameter to the payment start endpoint call]]).
# The merchant's system sends a request to the [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] API endpoint with its POSKey and the received payment identifier
# The Barion server sends real-time state change notifications to the listener about the payment.
# Based on the response received, the merchant's system can determine what processing tasks should take place
# The notification triggers your listener endpoint logic.


{{NotificationBox|title=IMPORTANT|text=Always process the entire response with all included transaction data, because different actions make different changes to the payment state object.|color=#FF7A3D}}
This page offers an overview of the Barion callback mechanism (an implementation of the [https://en.wikipedia.org/wiki/Instant_payment_notification Instant Payment Notification (IPN)] concept), best practices, and troubleshooting tips.


== Structure and processing of the callback request ==
<span id="the-callback-process"></span>
== The callback process ==


The callback request contains one parameter, the payment identifier. This is sent in the <code>paymentId</code> field of the POST request body. The merchant's system must send an <code>HTTP 200 OK</code> response (with any content) in order for the callback to be considered successful. The timeout period for answering a callback request is '''15 seconds'''.
Whenever there’s a change in the status of a payment transaction, the Barion server sends a HTTP POST request to the <code>CallbackUrl</code> parameter you passed to [[05-api-reference/01-payment-resource/01-payment-start|the Payment/Start call]] when you created the payment.


If the Barion system does not get an HTTP 200 response, it retries sending the callback for a maximum of 5 times, with exponential back-off timing delay between tries:
This improves scalability, and avoids potential delays in your payment processing caused by polling intervals.
* 2 seconds
* 6 seconds
* 18 seconds
* 54 seconds
* 2 minutes 42 seconds
So the total time window allocated for successful callback is roughly '''4 minutes'''. If the Barion system fails to get an HTTP 200 response after that, the callback is not sent and the merchant's system automatically gets an e-mail notification about the error.


Every time, when your system receives a callback request from the Barion you have to call the [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] API endpoint to find out the change. First, your system should check the payment's status and after the list of the payment's transactions. For example, if you requested a payment refund or when the reserved payment's time limit has expired the list of payment’s transactions will contain new e-money transactions. It's your system's responsibility to handle changes.
<ol style="list-style-type: decimal;">
<li><p>The Barion server sends a POST request to the <code>CallbackUrl</code> you specified, with the <code>PaymentId</code> identifying the updated payment.</p>
<p>This is merely an indication that there’s an update to query.</p></li>
<li><p>Your listener should acknowledge receipt of the POST request with a <code>HTTP 200 OK</code> response within 15 seconds.</p>
<blockquote>The Barion server only accepts HTTPS-protocol requests that are using TLS v1.2 and above.</blockquote>
<p>The Barion server re-sends the webhook up to 5 more times after the initial 15-second window, with increasing delays between calls (2 seconds, 6 seconds, 18 seconds, 54 seconds, and 102 seconds).</p>
<p>If the server doesn’t get a <code>HTTP 200 OK</code> after the fifth call (and 4 minutes’ total waiting time), it sends an error message email to your Barion shop’s registered email address.</p></li>
<li><p>After acknowledging the request, your listener should make a call to [[05-api-reference/01-payment-resource/01-payment-state|the Payment/<PaymentId>/PaymentState]] API endpoint to query the payment transaction’s new status.</p></li>
<li><p>Your listener logic should check the [[05-api-reference/01-payment-resource/04-payment-resource-enums/04-payment-status|<code>PaymentStatus</code>]] to see if the payment is still active:</p>
<ul>
<li><p><code>Canceled</code> indicates that the customer has closed the checkout page without starting a payment process, or before the payment process could finish.</p></li>
<li><p><code>Expired</code> indicates that the customer let the payment window elapse without completing the payment – they most likely abandoned the checkout page.</p>
<p>An <code>Expired</code> reservation payment automatically gets refunded, which generates a new refund-type transaction in the endpoint response’s [[05-api-reference/01-payment-resource/01-payment-state#transactions|<code>Transactions</code>]] array.</p></li></ul>


== Actions initiating a callback, and how to detect them ==
<blockquote><p>It’s recommended to reach out to your customer in these cases, and attempt to change their minds about the payment.</p></blockquote></li>
<li><p>After determining that the customer attempted to pay, the listener logic should check both [[05-api-reference/01-payment-resource/04-payment-resource-enums/04-payment-status|<code>PaymentStatus</code>]] and the [[05-api-reference/01-payment-resource/01-payment-state#transactions|<code>Transactions</code>]] array in the endpoint response.</p></li>
<li><p>Based on the payment state endpoint response, and considering [[#payment-scenarios|the payment scenario]], your listener should process the payment according to your business logic.</p></li></ol>


Different actions result in different changes in the payment state object that you query on the [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] API endpoint. Depending on what happened in the payment's life cycle, there are different things to look for. This section should help you choose what checks to perform based on your integration scenario. Please read these thoroughly and perform all applying checks in your business logic when processing a callback.
<span id="payment-scenarios"></span>
=== Payment scenarios ===


'''Successful payment'''
<span id="immediate-payment"></span>
==== Immediate payment ====


When the customer successfully completes the payment, the payment status will be set to different values depending on the type of the payment.
A “Succeeded” payment status indicates that all transactions in the payment went through.
* <code>Successful</code> when using Immediate payments
* <code>Reserved</code> when using Reservation payments


'''Pending payment'''
<span id="reservation-payment"></span>
==== Reservation payment ====


In delayed capture type payments, when the payment amount is blocked on the payer's payment source, the transaction's payment status is set to <code>Authorized</code>.
<span id="reservation-payment-setup"></span>
{{NotificationBox|title=Note|text=An <code>Authorized</code>-status payment is very likely to succeed, but isn't in fact considered successful [[Payment-Capture-v2|until the payee shop captures it]].|color=#FF7A3D}}
===== reservation payment setup =====


'''Payment rejection'''
A “Reserved” payment status indicates that the reservation is successfully set up.


When the customer decides to reject payment, and return to the shop, the payment status will be set to <code>Canceled</code>. The payment can no longer be completed.
<span id="reservation-payment-finishing"></span>
===== Reservation payment finishing =====


'''Finishing a Reservation payment'''
“Succeeded” payment status: all transactions in the payment have been finished with the initially reserved amount


When the shop finishes a Reservation payment, the payment status will be set depending on the finish being partial or full.
“PartiallySucceeded” payment status<!-- a doksiban az áll, hogy marad reserved, de a payment status oldal szerint ilyenkor PartiallySucceeded a helyzet -->: some, but not all transactions have been finished with the initially reserved amount
* if there are multiple payment transactions, but only certain one of them are being finished, the payment status will NOT change (it will stay in <code>Reserved</code>)
* when every transaction in the payment has been finished, the payment status will be set to <code>Succeeded</code>
* transactions finished with a lower amount than the initial reserve will result in a partial refund to the user, which shows up as a new refund transaction in the Transactions[] array of the payment state object


'''Capturing a Delayed Capture payment'''
A new refund-type transaction in the endpoint response’s [[05-api-reference/01-payment-resource/01-payment-state#transactions|<code>Transactions</code>]] array: a transaction in a reserved payment was finished with a lower amount than the initially reserved amount, and the difference is automatically refunded to the user in a new transaction


When the shop captures a Delayed Capture payment, the payment status will be set to <code>Succeeded</code>, regardless of whether the authorization and capture amounts match. No refund transaction is being created in this case, because the partial capture happens directly on the bank card.
<span id="delayed-capture"></span>
==== Delayed capture ====


'''Payment expiring'''
<span id="delayed-capture-payment-setup"></span>
===== Delayed capture payment setup =====


When a payment expires without being completed, the payment status will be set to <code>Expired</code>.
An “Authorized” payment status indicates that the customer completed the payment, and the payment funds are blocked on their payment instrument.
* If the payment was an ongoing Reservation payment that hasn't been finished in time, a refund will also be created, which shows up as a new refund transaction in the payment state object


'''Refund'''
<span id="delayed-capture-payment-capturing"></span>
===== Delayed capture payment capturing =====


When a refund is executed (via the website, or the [[Payment-Refund-v2|/v2/Payment/Refund]] API), a new refund transaction will be added to the Transactions[] array in the payment state object. Only <code>Succeeded</code> payments can be refunded, and the payment status will not change during a refund, it will stay <code>Succeeded</code>. Barion sends a callback for successful and unsuccessful refunds as well. You have to check the refund transaction in the Transactions[] array for the result.
“Succeeded” payment status indicates that the payment was successfully captured.


{{NotificationBox|title=IMPORTANT|text=Different actions make different changes to the overall payment state. Never rely only on payment status changes! Always process the entire payment state object and execute your business logic accordingly.|color=#FF7A3D}}
<blockquote>Even if the captured amount is lower that the previously-authorized amount, no refund transaction is generated, because the difference is simply released directly on the payer’s payment instrument.
</blockquote>
<span id="refund"></span>
==== Refund ====


== Security ==
A new refund-type transaction is added to the [[05-api-reference/01-payment-resource/01-payment-state#transactions|<code>Transactions</code>]] array in the endpoint response.
Never rely on the callback function alone. When the callback URL is requested, your application must call the [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] Barion API to get the proper payment state.


Please refer to the [[Security Measures]] page for more information and a list of IP addresses.
<blockquote>Note that only previously “Succeeded” payment transactions can be refunded, and that the status of these payments won’t change regardless of whether the refund was successful or not.
</blockquote>
<span id="best-practices"></span>
== Best practices ==


{{NotificationBox|title=IMPORTANT|text=The IP address of the callback request may change any time for security reasons.|color=#FF7A3D}}
<span id="rate-limiting"></span>
=== Rate limiting ===


== Why you should use it ==
Throttling is in place to prevent service disruption caused by excessive requests to the payment state endpoint: if you call the endpoint with the same `PaymentID` more than once within a 5-second interval, for the following 5 seconds, further calls to the endpoint the request return the `HTTP 429 Too many requests` error.


When a Barion Smart Gateway payment process takes place between the two systems, neither of them can rely purely on explicit user interaction to process things. In such situations, the Barion system must inform the merchant's system that the payment has changed in some way, without involving the user.
<blockquote>If the number of requests with the same `PaymentID` exceeds a certain threshold within a certain time window, all further requests will return `HTTP 429 Too many requests`.</blockquote>


Here are some examples:
<span id="ip-allowlisting"></span>
=== IP allowlisting ===


* the payment is completed, but the user closed their browser or lose network connection, preventing them from returning to the webshop or application that redirected them to the Barion Smart Gateway
To protect your webhook listener endpoint from unauthorized requests, it’s strongly recommended to allowlist the Barion API IP addresses, and blocklist all other IPs.
* the user explicitly cancels the payment, but closes their browser instead of navigating back to the merchant
* the payment is never completed and expires because of the time window limit
* the payment is refunded


Implementing callback handling will save you time and pain tracking such "lost" payments. It also eases the troubleshooting with your customers, since you will always have valid data on your side.
<!-- > Although Barion strives to notify all its merchant clients about any changes in the IP addresses well in advance, it's recommended that you use a Domain Name Service (DNS) to determine the IP address of the Barion API server. -->
<span id="production-environment-barion-api-ip-address"></span>
==== Production environment Barion API IP address ====


== Rate limiting ==
40.113.73.229
To prevent potential disruptions in our service caused by the abuse of the [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] API endpoint, we have introduced a rate-limiting feature to throttle excessive requests. '''Generally, you should rely on the callback mechanism whenever possible unless you have a specific reason not to''', but if you want to manually get the details of a payment, here are a couple of things to bear in mind:
* Make sure you do not send continuous requests for the same payment even if you need to get its current state manually without waiting for the callback to happen
* Do not keep requesting for an indefinite time, even if your requests are throttled (e.g. if a problem occurs during the payment process, and the callback never happens, you shouldn't keep polling the API indefinitely) In this case the frequency is not the problem, but as time passes these orphan requests can cause a great load together


To avoid these situations, the following throttling logic is implemented on our API:
<span id="sandbox-barion-api-ip-address"></span>
* During a 5 seconds window we only accept the first 2 [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] requests with the same payment ID. This means that if you submit two requests less than 5 seconds apart, subsequent requests will be denied until 5 seconds pass after the initial successful request. These requests will return with an HTTP 429 "Too many requests" error.
==== Sandbox Barion API IP address ====
* We keep track of requests, and if requests with the same payment ID reach a certain limit during a specific timeframe, all further requests will return HTTP 429. The exact timeframe and limits are not disclosed to the public.


To reinforce the points above, we recommend using the callback mechanism described above, and calling the [[Payment-PaymentState-v4|/v4/Payment/<PaymentId>/PaymentState]] API endpoint only when there's a reason to do so.
20.223.214.216

Revision as of 09:31, 5 August 2024

Payment callback mechanism (aka. IPN)


Learn how to subscribe to the Barion callback mechanism, a webhook service that helps you track the state changes of payments in real time.

The basic idea is that to help automate your payment processing, the Barion server sends notifications about updates to the payments in your Barion shop, which should make your Barion shop query the Barion API’s payment state endpoint for the specifics of the status change.

Here’s an overview of the steps involved:

  1. Set up a webhook listener endpoint (that implements the processing logic detailed on this page).
  2. Provide your listener’s URL when setting up a payment (as a required parameter to the payment start endpoint call).
  3. The Barion server sends real-time state change notifications to the listener about the payment.
  4. The notification triggers your listener endpoint logic.

This page offers an overview of the Barion callback mechanism (an implementation of the Instant Payment Notification (IPN) concept), best practices, and troubleshooting tips.

The callback process

Whenever there’s a change in the status of a payment transaction, the Barion server sends a HTTP POST request to the CallbackUrl parameter you passed to the Payment/Start call when you created the payment.

This improves scalability, and avoids potential delays in your payment processing caused by polling intervals.

  1. The Barion server sends a POST request to the CallbackUrl you specified, with the PaymentId identifying the updated payment.

    This is merely an indication that there’s an update to query.

  2. Your listener should acknowledge receipt of the POST request with a HTTP 200 OK response within 15 seconds.

    The Barion server only accepts HTTPS-protocol requests that are using TLS v1.2 and above.

    The Barion server re-sends the webhook up to 5 more times after the initial 15-second window, with increasing delays between calls (2 seconds, 6 seconds, 18 seconds, 54 seconds, and 102 seconds).

    If the server doesn’t get a HTTP 200 OK after the fifth call (and 4 minutes’ total waiting time), it sends an error message email to your Barion shop’s registered email address.

  3. After acknowledging the request, your listener should make a call to the Payment/<PaymentId>/PaymentState API endpoint to query the payment transaction’s new status.

  4. Your listener logic should check the PaymentStatus to see if the payment is still active:

    • Canceled indicates that the customer has closed the checkout page without starting a payment process, or before the payment process could finish.

    • Expired indicates that the customer let the payment window elapse without completing the payment – they most likely abandoned the checkout page.

      An Expired reservation payment automatically gets refunded, which generates a new refund-type transaction in the endpoint response’s Transactions array.

    It’s recommended to reach out to your customer in these cases, and attempt to change their minds about the payment.

  5. After determining that the customer attempted to pay, the listener logic should check both PaymentStatus and the Transactions array in the endpoint response.

  6. Based on the payment state endpoint response, and considering the payment scenario, your listener should process the payment according to your business logic.

Payment scenarios

Immediate payment

A “Succeeded” payment status indicates that all transactions in the payment went through.

Reservation payment

reservation payment setup

A “Reserved” payment status indicates that the reservation is successfully set up.

Reservation payment finishing

“Succeeded” payment status: all transactions in the payment have been finished with the initially reserved amount

“PartiallySucceeded” payment status: some, but not all transactions have been finished with the initially reserved amount

A new refund-type transaction in the endpoint response’s Transactions array: a transaction in a reserved payment was finished with a lower amount than the initially reserved amount, and the difference is automatically refunded to the user in a new transaction

Delayed capture

Delayed capture payment setup

An “Authorized” payment status indicates that the customer completed the payment, and the payment funds are blocked on their payment instrument.

Delayed capture payment capturing

“Succeeded” payment status indicates that the payment was successfully captured.

Even if the captured amount is lower that the previously-authorized amount, no refund transaction is generated, because the difference is simply released directly on the payer’s payment instrument.

Refund

A new refund-type transaction is added to the Transactions array in the endpoint response.

Note that only previously “Succeeded” payment transactions can be refunded, and that the status of these payments won’t change regardless of whether the refund was successful or not.

Best practices

Rate limiting

Throttling is in place to prevent service disruption caused by excessive requests to the payment state endpoint: if you call the endpoint with the same `PaymentID` more than once within a 5-second interval, for the following 5 seconds, further calls to the endpoint the request return the `HTTP 429 Too many requests` error.

If the number of requests with the same `PaymentID` exceeds a certain threshold within a certain time window, all further requests will return `HTTP 429 Too many requests`.

IP allowlisting

To protect your webhook listener endpoint from unauthorized requests, it’s strongly recommended to allowlist the Barion API IP addresses, and blocklist all other IPs.

Production environment Barion API IP address

40.113.73.229

Sandbox Barion API IP address

20.223.214.216