3. Put the order on hold and confirm it

Once the shopper provides enough information and we're ready to proceed, two things can happen:

  • The order is approved and ready for fulfillment. Your shop must confirm the order is being placed. This is the most common scenario.
  • The order needs review and is put on hold. Your shop must acknowledge the order but mark it as not ready for shipment. Once approved, confirm the order to proceed with fulfillment.

This step serves two purposes:

  • Ensure the cart hasn't changed during checkout. If it has, restart the process.
  • Help your logistics: confirmed orders can ship immediately, while on hold orders wait for approval.

We work to keep the on hold period as short as possible.

For the shop to know about on hold orders that get rejected, see the Webhooks API.

Overview

seQura notifies your shop about order approval or review status via an IPN (Instant Payment Notification) callback to the URL you provided in the first API call.

To implement IPN:

  1. Expose an endpoint where seQura can POST notifications.
  2. When you receive a request, update the order via seQura's API (place on hold or confirm) before responding with a success status code.

Here's the interaction when an order is approved directly:


%%{init: {
    "theme": "base",
    "themeVariables": {
        "background": "#F0F0F0"
    }
}}%%
sequenceDiagram
  participant Shop
  participant seQura

  seQura->>+Shop: IPN request (approved)
  activate seQura
  
  Shop->>+seQura: Confirm order
  seQura-->>-Shop: Order update response
  
  Shop-->>-seQura: IPN response
  deactivate seQura

Or like this when the order goes first through review:

sequenceDiagram
    participant Shop
    participant seQura

    seQura->>+Shop: IPN request (needs review)\
    activate seQura

    Shop->>+seQura: Place order on hold\
    seQura-->>-Shop: Order update response

    Shop-->>-seQura: IPN response\
    deactivate seQura

    seQura->>+Shop: IPN request (approved)\
    activate seQura

    Shop->>+seQura: Confirm order\
    seQura-->>-Shop: Order update response

    Shop-->>-seQura: IPN response\
    deactivate seQura

Authorize & Capture (optional)

Merchants who have Authorize & Capture enabled in their contract can split the “approved” step into two distinct decisions:

  1. Authorize — acknowledge the approved order and close the checkout form for the shopper, without yet committing to capture the payment. The shopper is redirected to return_url immediately, just as on confirmed.
  2. Capture (later) — confirm the order, dispatch it for fulfilment, and run the down-payment-on-confirmation charge as usual. Or, alternatively, void the authorization and release the reservation without producing a refund.

This matches the Authorize & Capture model commonly offered by PSPs for credit-card payments and is intended for flows in which the merchant cannot decide synchronously (travel, high-ticket, marketplace). It is a per-merchant opt-in and is off by default.

Eligibility

  • The merchant’s account must have Authorize & Capture enabled. Without the flag, the API returns 409 Conflict to any state=authorized request.
  • The order’s product_code must not be i1. The i1 product is captured immediately on confirmation and has no authorization step to delay; i1 orders return 409 Conflict if the shop tries to authorize them and must keep using approved → confirmed.

Authorize

When the IPN includes sq_state=approved and the merchant wants to close the form without committing to capture yet, the shop sends a PUT to the order URL with state="authorized" instead of state="confirmed".

  • The checkout form closes and redirects to return_url, exactly as on confirmed.
  • No IPN is emitted when the order enters authorized — the shop drove the transition itself.
  • The order is not dispatched for fulfilment yet. The down-payment-on-confirmation charge is not run yet.
  • SeQura starts a per-merchant authorization window timer (default 24 hours, configurable up to 6 days / 144 hours). If the shop has not captured or voided by the time the window expires, SeQura automatically voids the authorization (see below).

Capture

To capture (i.e. confirm) an authorized order, send a PUT with state="confirmed" from the authorized state. This runs the standard confirmation flow:

  • The order is dispatched for fulfilment.
  • The down-payment-on-confirmation charge is run, if applicable to the product.
  • Subsequent IPNs and webhooks behave exactly as for any other confirmation.

Void

To void an authorized order — releasing the shopper’s reservation without ever placing a charge on their statement — send a PUT with state="cancelled" from the authorized state.

  • No refund is produced. Voiding moves the order directly to the terminal cancelled state, not through the refund pipeline. This avoids the shopper-visible “charge then refund” pair that a regular cancellation would generate.
  • The reservation on the shopper’s account is released.
  • No further capture is possible after void; the order is terminal.

state="cancelled" is only accepted from authorized. From other states the regular cancellation/refund endpoints continue to apply.

Auto-void after window expiry

If the shop neither captures nor voids before the configured authorization window elapses, SeQura voids the authorization automatically with the same semantics as a merchant-driven void (no refund, terminal cancelled). The default window is 24 hours; the per-merchant maximum is 6 days (144 hours).

Configuration

To use the IPN workflow, include at least the notify_url field in the merchant section of your initial API call. We recommend also including a return_url for redirecting shoppers after checkout.

The Notify URL: Include notify_url in the merchant section. seQura sends a POST request to this URL to trigger confirmation or on hold processes.

When you receive a request, find the order in your database. seQura includes your order reference (if known), seQura's order reference, and the order state (see IPN Request Example below). If these aren't enough to identify the order, include additional parameters in the URL or the optional notification_parameters structure.

For shared shop platforms, we recommend including a digital signature in notification_parameters to prevent fake requests. See Securing the IPN call.

The Return URL: Include return_url in the merchant section. seQura redirects the shopper here (via GET) after confirmation or on hold. This is typically your order confirmation page.

If the URL contains SQ_PRODUCT_CODE, seQura replaces it with the product code. For example, if the shopper uses invoicing and return_url is http://shop.example.com/checkout/confirmed?payment_method=sq-SQ_PRODUCT_CODE, they'll be redirected to http://shop.example.com/checkout/confirmed?payment_method=sq-i1. This lets you show different messages based on the payment product used.

Processing the IPN

When seQura sends the IPN, it means seQura is ready to guarantee payment for the order. You can proceed with placing the order.

If the order can proceed to fulfillment, the IPN includes sq_state=approved. Finalize the order with seQura as the payment method.

If the order needs manual review, the IPN includes sq_state=needs_review. Place the order on hold—the order is finalized with seQura but not ready for fulfillment yet. Once approved, you'll receive another IPN with sq_state=approved.

There are several variations to this workflow, depending on whether your shop can fully process the IPN. The sections below describe each case:

Handling an IPN completely

To fully handle an IPN:

  1. Send order data to seQura for verification.
  2. Mark the order as completed or waiting for review in your database.
  3. Send the order reference to seQura (if not already sent).
  4. Respond to the IPN with a 200 OK status.

In step 1, make a PUT request to the URL from the initial solicitation's Location header. Include all order data plus state="confirmed" or state="on_hold".

If the IPN includes sq_state="needs_review": place the order on hold in your system and send state="on_hold" to seQura.

If the IPN includes sq_state="approved": confirm the order in your system and send state="confirmed" to seQura.

seQura usually responds with 200 OK, so proceed with steps 2-4. However, if the cart, delivery address, or other details changed unacceptably, seQura responds with 409 Conflict and a JSON body explaining the issues. In this case, don't complete the order or send the order reference, but still respond to the IPN with 200 OK.

After handling the first IPN (when seQura receives 200 OK), the shopper is redirected to return_url regardless of whether the order update succeeded. Your return_url handler must check the order status before deciding what to display, since the order might be on hold or ready for fulfillment.

Problem: Order reference missing

seQura can't process an order or pay you until you provide order_ref_1. We follow up weekly on confirmed orders missing this reference. Recurring issues may lead to service disconnection.

Problem: Order reference not unique

seQura requires (merchant.id, merchant_reference.order_ref_1) to be unique for confirmed orders. Duplicate references won't be processed. This error can occur in two places:

  • During step 1, when confirming the order. If you provided order_ref_1 at checkout start, seQura checks uniqueness and responds with 409 Conflict if it's not unique.
  • During step 3, when updating the confirmed order with the reference. Again, seQura responds with 409 Conflict if not unique. This case is more complex: the order is confirmed with seQura as payment method, but seQura can't process it further.

Order should not be paid with seQura (410)

Between checkout start and the IPN, the cart might change in ways that prevent order completion:

  • The shopper completed the order via another payment method in a different tab.
  • An item is no longer available (or not at the expected price).

In these cases, don't confirm the order with seQura. Respond to the IPN with 410 Gone. This tells seQura the approved credit won't be used and any down payment should be refunded.

After receiving 410 Gone, seQura redirects the shopper to return_url.

Order cannot be found (404)

If you can't find the order using the notify_url data or request parameters, respond with 404 Not Found. seQura assumes either:

  1. There's a sync delay between your storefront and backend.
  2. The shopper stayed too long in checkout and the unconfirmed order was deleted.

seQura retries the IPN a few times for sync issues. If the 404 persists, seQura treats it as a 410.

Order already confirmed with seQura (409)

Due to communication or sync errors, your shop might consider the order confirmed while seQura's IPN service sees it as needing confirmation. Respond with 409 Conflict to signal seQura to investigate.

After receiving 409 Conflict, seQura redirects the shopper to an error page.

Temporary server problem (5xx)

If you encounter temporary server issues during IPN processing (like database unavailability), respond with a 5xx status. seQura retries for up to 24 hours and won't cancel the order or refund the first installment while you respond with 5xx.

Multi-request notification (30x)

If you respond with 307 Temporary Redirect and a Location: header, seQura makes another POST to the returned URL. This works around technical limitations in platforms like PrestaShop. The sequence becomes:

  1. seQura POSTs to notify_url.
    • You PUT confirmation to seQura (without order number).
    • seQura responds with 200.
    • You create the order from the cart.
  2. You respond with 307 and a URL.
  3. seQura POSTs to that URL.
    • You PUT confirmation to seQura with the order number.
    • seQura responds with 200.
  4. You respond with 200.

Notes:

  • The IPN accepts up to 2 redirects (max 3 POST requests).
  • The Location: URL can be the same as a previous URL, including notify_url.
  • 302 Found currently works but is deprecated for new integrations. 302 typically signals "GET this URL", which can cause hard-to-track bugs.
  • Other 30x codes aren't accepted and cause IPN failure.

IPN request examples

seQura includes order references in the IPN request. Assuming your original API request contained:

{
  "order": {
    "merchant": {
      "id": "...",
      "notify_url": "http://shop.example.com/ipn-me",
      "return_url": "http://shop.example.com/checkout/confirmed?payment_method=sq-SQ_PRODUCT_CODE",
    },
    "merchant_reference": {"order_ref_1": "MHPULMKOE"},
    ...

And seQura returned a URL ending in /9201b602-94b3-4804-8ef2-080c518378ee in the Location header, the IPN request looks like this:

POST /ipn-me HTTP/1.1
User-Agent: seQura-IPN/1.0
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 164
Host: shop.example.com

order_ref=9201b602-94b3-4804-8ef2-080c518378ee&order_ref_1=MHPULMKOE&product_code=pp3&sq_state=approved&approved_since=0

If the order needs to be put on hold:

POST /ipn-me HTTP?1.1
User-Agent: seQura-IPN/1.0
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 172
Host: shop.example.com

order_ref=9201b602-94b3-4804-8ef2-080c518378ee&order_ref_1=MHPULMKOE&product_code=pp3&sq_state=needs_review&needs_review_since=0

approved_since: Seconds since seQura approved the order. Useful for debugging when you return 5xx errors. We recommend logging this value. Only present for approved orders.

needs_review_since: Seconds since seQura requested the order be put on hold. Useful for debugging 5xx cases. We recommend logging this value. Only present for orders needing review.

product_code: Used by our Magento and PrestaShop plugins. Other integrators can ignore it.

Securing the IPN call

Include a secure token—a short string that's hard to guess, easy to verify, and used only once.

Creating a secure token: Use a cryptographic hash function with a secret salt (a string only your application knows). In this example, the token is the SHA1 digest of 1234:sUpErSeCrEtSaLt (cart ID + colon + salt).

{
  "order": {
    "merchant": {
      "notify_url": "https://my.shop.tld/checkout/sequra-ipn",
      "notification_parameters": {
        "cart": "1234",
        "token": "4207e9302d31d4fa2dbcaf9dfb45249d2581b9f8"
      },

IPs used in the IPN request

seQura uses 3 static IPs for both sandbox and production:

  • 34.253.159.179
  • 34.252.147.155
  • 52.211.243.177
Remember: you won't have access to the session when receiving the IPN. If you need session data, include it in `notification_parameters`.

Tips for development environments

Using tunnels

If you're behind a firewall, our servers can't reach your notify_url unless you expose it. We recommend ngrok to expose a specific port.

For example, expose port 3000 with:

$ ngrok http 3000

Ngrok generates a unique URL for your port. For example, if ngrok gives you http://12345678.ngrok.io, your notify_url would be http://12345678.ngrok.io/checkout/sequra-ipn.

Missing SSL certificate

The IPN requires HTTPS. If your server doesn't have a valid SSL certificate, the IPN won't work.

In sandbox, you can bypass this by prefixing the URL with unverified-https://. For example: unverified-https://my.shop.tld/checkout/sequra-ipn/8765432

Note: This doesn't work in production.

Testing the on hold flow

See the FAQ for options to test what happens when an order is put on hold.


Did this page help you?