Looking for ePay classic docs? Go to docs.epay.dk
ePay documentationDocsePay documentation

SoftPay

This guide walks through how to integrate Softpay using the ePay API for physical terminals, with a focus on getting app switching to behave reliably and predictably.

How the Flow Works

A Softpay payment follows a simple sequence:

  1. Your backend creates a transaction using the /sale endpoint
  2. The transaction becomes available in the Softpay app
  3. Your frontend switches to the Softpay app
  4. The customer completes the payment
  5. Softpay returns to your app
  6. The final result is sent to your backend via the notification URL

Softpay processes transactions based on what is already created and available, so the key is to ensure each step completes before moving to the next.


Creating the Payment

The flow starts with a backend request:

POST https://payments.epay.eu/public/api/v1/sale

This creates the transaction and sends it to the Softpay terminal.

A successful response means the transaction is ready for the Softpay app.

For same-device SoftPOS setups, you may want to include:

  • suppressAppNotifications: true to avoid extra popups
  • switchBackTimeout: 0 to return to your app as quickly as allowed

Example request:

{  "terminal": {    "id": "...",    "suppressAppNotifications": true,    "switchBackTimeout": 0  },  "transaction": {    "pointOfSaleId": "...",    "amount": 1000,    "currency": "DKK",    "notificationUrl": "https://your-backend.com/callback"  }}

Waiting for the Response

After calling /sale, your frontend should wait for the response before continuing.

  • If the transaction state is FAILED, stop the flow
  • Otherwise, the transaction is ready in Softpay

Only once the transaction has been successfully created should you proceed to the next step. This ensures the payment is immediately available when the Softpay app opens.


Switching to the Softpay App

After receiving a successful response, trigger the app switch.

For PWAs, this can be done using the Softpay JavaScript client or an intent URL. The switch must be initiated by user interaction due to Android platform requirements.

Example intents:

Initiate pending payment with redirect back to previous app:

intent://softpay.io/pending#Intent;scheme=softpay;action=io.softpay.action.PENDING;launchFlags=0x10000000;end

Initiate pending payment with redirect to specific app or web page:

intent://softpay.io/pending?callback=yourapp://payment-result#Intent;scheme=softpay;action=io.softpay.action.PENDING;launchFlags=0x10000000;end

Used like this:

window.location.assign(`{intent_url}`);

Softpay will open and begin processing the pending transaction.

Payment in Softpay

In the Softpay app, the customer taps their card and completes the payment.

A confirmation screen is shown after processing. This is required by card schemes, though its duration can be minimized through configuration.

Returning to Your App

Once the confirmation screen is complete, Softpay automatically switches back to your app.

Successful payments return quickly, while failed transactions may take slightly longer. Setting switchBackTimeout to zero ensures the fastest allowed return.

Receiving the Final Result

The final payment result is sent to your backend via the notificationUrl.

While the app switch provides immediate user feedback, your backend notification should always be treated as the source of truth for the transaction outcome.


Best Practices

  • Always create the transaction before switching to Softpay
  • Wait for a successful /sale response before triggering the app switch
  • Treat the frontend as a user interface layer only
  • Use backend notifications to determine the final payment result
  • Avoid having both the SoftPay live and test app installed on the same device

Following this sequence ensures that the transaction is ready and visible when the Softpay app opens, resulting in a smooth and predictable user experience.

Closing Notes

For PWA integrations, use either the Softpay JavaScript client or intent-based switching. Native apps can use intents directly or the AppSwitch SDK for deeper integration.

When the flow is implemented in the correct order, the Softpay experience is consistent and easy to work with.

How is this guide?