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

With API

Use this guide if you want to build directly against the ePay API.

The API gives you full backend control over your payment flow. You can create payments, handle results, update your own order system and build the checkout experience that fits your product.

What you will do

In this guide, you will:

Authenticate with your API key

Create an order in your own system

Create a payment session with ePay

Inspect the response

Test the payment

Handle the result server-side

Before you start

You need:

  • An API key
  • A Point of Sale ID
  • A backend environment
  • A tool for making API requests
  • A notification URL or webhook

You can use cURL, Postman, Insomnia or your own backend code.

Your API key must only be used server-side. Never expose your API key in frontend code.

Step 1: Understand authentication

Authenticate API requests with your API key.

Authorization: Bearer <TEST_API_KEY>

Use your test API key while building and testing.

Switch to your live API key only when your account is ready for live payments.

Step 2: Use idempotency

When creating payments, include an idempotency key.

This helps prevent duplicate payments if your system retries a request.

Idempotency-Key: <UUID>

Use a unique value for each payment creation attempt.

Step 3: Create an order in your own system

Before creating the payment in ePay, create an order in your own system.

Set the order status to pending.

const order = await createOrder({  reference: "ORDER-1001",  amount: 10000,  currency: "DKK",  status: "pending",});

The order should not be marked as paid until your backend receives and verifies the payment result.

Step 4: Create the payment

Send a request to create a payment session.

API referencePOSTInitialize Payment Session/public/api/v1/citInitializes a new payment session with the ePay Payments API.
const body = JSON.stringify({  "pointOfSaleId": "<POINT_OF_SALE_ID>",  "amount": 10000,  "currency": "DKK",  "reference": "ORDER-1001",  "notificationUrl": "https://example.com/api/epay/notification",  "successUrl": "https://example.com/payment/success",  "failureUrl": "https://example.com/payment/failure"})fetch("https://payments.epay.eu/public/api/v1/cit", {  method: "POST",  headers: {    "Content-Type": "application/json",    "Authorization": "Bearer <TEST_API_KEY>",    "Idempotency-Key": "<UUID>"  },  body})

Use your actual ePay endpoint and the required fields for your payment type.

Step 5: Understand the request

FieldDescription
pointOfSaleIdIdentifies which webshop, sales channel or system the payment belongs to
amountThe amount in minor units
currencyThe payment currency
referenceYour own order reference
notificationUrlWhere ePay sends the payment result
successUrlWhere the customer is redirected after success
failureUrlWhere the customer is redirected after failure

The reference should connect the ePay payment to your internal order.

Step 6: Inspect the response

The response contains the payment information your system needs.

Depending on your integration, this may include:

  • Payment ID
  • Session ID
  • Session key
  • Payment window URL
  • Status
  • Expiration time

For embedded flows such as Blocks, the most important response fields are session.id, key, and javascript.

Example:

{  "paymentWindowUrl": "https://payments.epay.eu/payment-window?sessionId=0192473a-e382-79a9-bfc2-65da88fe812f&sessionKey=4651656e-f29e-4dfa-a1cd-a65647862011",  "session": {    "id": "0192473a-e382-79a9-bfc2-65da88fe812f",    "state": "PENDING"  },  "key": "4651656e-f29e-4dfa-a1cd-a65647862011",  "javascript": "https://payments.epay.eu/sessions/0192473a-e382-79a9-bfc2-65da88fe812f/client.js"}

Store the identifiers you need to match future payment results to your order.

Do not store sensitive payment data.

Step 7: Send the customer to payment

What you do next depends on your frontend integration.

If you use Checkout, redirect the customer to the payment window URL.

return redirect(payment.paymentWindowUrl);

If you use Blocks, return the session values needed by ePay.js.

return {  sessionId: payment.session.id,  sessionKey: payment.key,  javascript: payment.javascript,};

The sessionKey and javascript URL are scoped to this exact payment session.

Only return values that are safe to expose to the frontend.

Never return your API key.

Step 8: Complete a test payment

Complete the payment using a test card.

Test at least:

  • A successful payment
  • A failed payment
  • A cancelled or abandoned payment
  • A duplicate notification
  • A retry from your own backend

Step 9: Handle the payment result

Use your notification URL or webhook to update your order.

Recommended backend flow:

Receive payment result from ePay

Verify that the result is valid

Find the order using the payment ID or reference

Check whether the order has already been processed

Update the order status

Return a successful response

Your notification handler should be safe to run more than once.

Example notification handler

export async function handlePaymentNotification(payload) {  const payment = await verifyPaymentResult(payload);  const order = await findOrderByReference(payment.reference);  if (!order) {    throw new Error("Order not found");  }  if (order.status === "paid") {    return { ok: true };  }  if (payment.status === "accepted") {    await markOrderAsPaid(order.id);  }  if (payment.status === "declined") {    await markOrderAsFailed(order.id);  }  return { ok: true };}

This is only an example. Your implementation should match your own order system and the actual ePay payment result format.

Common API errors

400 Bad Request

The request is invalid.

Check that:

  • Required fields are included
  • Field names are correct
  • Amount is in the correct format
  • Currency is supported
  • URLs are valid

401 Unauthorized

The API key is missing or invalid.

Check that:

  • The authorization header is included
  • The API key is correct
  • The API key belongs to the correct environment

422 Validation Error

The request is understood, but one or more values are not valid.

Check that:

  • The Point of Sale ID exists
  • The payment method is available
  • The amount is allowed
  • The currency is available for the Point of Sale

429 Rate Limited

Too many requests were sent in a short period.

Add retry handling with backoff.

Do not retry payment creation without idempotency.

What you built

You have now created your first payment with the ePay API.

You authenticated with your API key, created a payment session, inspected the response and prepared your backend to handle the payment result.

Next steps

How is this guide?

On this page