openapi: 3.0.3
info:
  title: ePay Payments API
  description: >
    This API describes the endpoints for the ePay payments API.
    Communication is made using REST and standard web technologies.
  version: "1.0.0"
servers:
  - url: https://payments.epay.eu

tags:
  - name: Sessions
    description: Endpoints for payment session initialization.
  - name: Transactions
    description: Endpoints for payment transactions (authorization, capture, refund, void, etc.).
  - name: Payouts
    description: Endpoints for initiating payouts.
  - name: Settlements
    description: Endpoints for settlement transfers and transactions.
  - name: Subscriptions
    description: Endpoints for managing subscriptions.
  - name: Subscription Billing
    description: Endpoints for managing automatic subscription billing.
  - name: Payment Links
    description: Endpoints for creating payment links
  - name: Payment Methods
    description: Endpoints for accessing payment method data
  - name: Webhooks
    description: Endpoints for handling webhooks
  - name: Management
    description: Endpoints for managing non-transaction resources
  - name: Partner
    description: Endpoints for partner integrations

paths:
  /public/api/v1/mit:
    post:
      tags:
        - Transactions
      summary: MIT Authorization
      description: >
        :::warning Batching and Rate limits
          ePay strongly recommends merchants to implement the **<a href="/api/mit-batch-authorization">MIT Batch Authorization</a>** endpoint over the single MIT authorization endpoint.

          Please review our <a href="/guides/rate-limits">rate limits</a> before you begin your implementation.
        :::

        A MIT (Merchant-Initiated Transaction) is a payment initiated by the merchant, typically based on a previously established agreement, such as a subscription.

        <br/><br/>
        Use a MIT authorization when the customer has agreed to let the merchant charge them automatically.
        For example, monthly subscription payments must be handled using MIT.
        MIT is not suitable when the customer starts the payment themselves, like clicking a “Pay Now” button.

        <br/><br/>
        For more information about the differences between CIT (Customer-Initiated Transaction) and MIT, see our <a href="/get-started/core-concepts">Core Concepts</a> page.

        <br/><br/>
        All MIT transactions are processed <b>asynchronously</b> and cannot run in real time.
        Most are completed within a few seconds, but ePay does not guarantee processing times.
        Some payment methods, such as Vipps MobilePay, may take several days to complete, depending on the method’s processing rules.

        <br/><br/>
        If you want to offer your customers the ability to store their cards for faster checkout in the future, you must use CIT transactions.
        In such cases, you are required to provide a <code>customerId</code> when creating the payment.
        This ID links the stored card to the customer and enables quick-checkout functionality in future sessions.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        description: MIT authorization request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MitAuthorizationRequest"
            example:
              subscriptionId: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
              amount: 500
              currency: "DKK"
              reference: "reference-2"
              instantCapture: "OFF"
              textOnStatement: "The text"
              notificationUrl: "https://yape.dev"
              attributes:
                key1: "value1"
                key2: "value2"
      responses:
        "200":
          description: MIT authorization requested successfully created. Processing will begin shortly.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionResponse"
              example:
                transaction:
                  id: "LDG7M4WW44G"
                  amount: 500
                  currency: "DKK"
                  clientIp: ""
                  customerId: "User159"
                  exemptions: []
                  instantCapture: "OFF"
                  paymentMethodId: "01924756-d1f6-738d-8040-90d76cedf01f"
                  paymentMethodType: "CARD"
                  paymentMethodSubType: "Visa"
                  paymentMethodExpiry: "2050-01-01"
                  paymentMethodDisplayText: "40000000XXXX0003"
                  pointOfSaleId: "01924737-9c18-71c0-ab1a-88698eaceabf"
                  reference: "reference-2"
                  scaMode: "SKIP"
                  sessionId: null
                  state: "PENDING"
                  errorCode: null
                  subscriptionId: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
                  textOnStatement: "The text"
                  createdAt: "2024-10-17T15:07:03.290909169+02:00"
                  attributes:
                    key1: "value1"
                    key2: "value2"
                  type: "PAYMENT"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/mit/batch:
    post:
      tags:
        - Transactions
      summary: MIT Batch Authorization
      description: >
        :::warning Rate limits
          Please review our <a href="/guides/rate-limits">rate limits</a> before you begin your implementation.
        :::

        Create multiple MIT (Merchant-Initiated Transaction) authorizations in a single request. 
        Each entry mirrors the single MIT endpoint and is processed asynchronously, supporting partial success across the batch. 
        Each transaction is processed individually, if the transaction passes initial validation then a transaction is created for background processing and a `transaction` is returned. 
        If the initial validation fails, instead an `error` is returned. You will receive one callback for each individual transaction.
        
        <br/><br/>
        Use a MIT authorization when the customer has agreed to let the merchant charge them automatically.
        For example, monthly subscription payments must be handled using MIT.
        MIT is not suitable when the customer starts the payment themselves, like clicking a “Pay Now” button.

        <br/><br/>
        For more information about the differences between CIT (Customer-Initiated Transaction) and MIT, see our <a href="/get-started/core-concepts">Core Concepts</a> page.

        <br/><br/>
        All MIT transactions are processed <b>asynchronously</b> and cannot run in real time.
        Most are completed within a few seconds, but ePay does not guarantee processing times.
        Some payment methods, such as Vipps MobilePay, may take several days to complete, depending on the method’s processing rules.

        <br/><br/>
        If you want to offer your customers the ability to store their cards for faster checkout in the future, you must use CIT transactions.
        In such cases, you are required to provide a <code>customerId</code> when creating the payment.
        This ID links the stored card to the customer and enables quick-checkout functionality in future sessions.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        description: MIT batch authorization request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateMitBatchTransactionRequest"
      responses:
        "200":
          description: MIT batch accepted; returns per-entry creation results while processing continues asynchronously. Each transaction is processed individually, if the transaction passes initial validation then a transaction is created for background processing and a `transaction` is returned. If the initial validation fails, instead an `error` is returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateMitBatchTransactionResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/moto:
    post:
      tags:
        - Transactions
      summary: MOTO Authorization
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      description: |
        :::warning PCI-DSS Compliance
          As this endpoint receives raw payment data, the integrator is required to provide documentation for PCI-DSS compliance before access can be granted.
        :::
        
        This endpoints creates and processes an online MOTO transaction and returns the authorization result in the response. 
        This is typically used within the travel industry, where it is more common for customers to provide their card info over the phone when booking a vacation.
        
        This can be used by merchants to automate authorizations when receiving card info from brokers such as hotels.com and booking.com.
      security:
        - BearerAuth: []
      requestBody:
        description: Transaction processing result
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateMotoTransactionRequest"
      responses:
        "200":
          description: Successful payment session initialization response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationWebhook"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/transactions/{transactionId}/capture:
    post:
      tags:
        - Transactions
      summary: Capture Payment
      description: Capture a payment by transferring funds from the cardholder's bank.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: transactionId
          in: path
          description: The id of the transaction to capture.
          required: true
          schema:
            type: string
      requestBody:
        description: Capture request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CaptureRequest"
            example:
              amount: 1095
      responses:
        "200":
          description: Capture operation response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OperationResponse"
              example:
                operationId: "019248e0-0ff4-7c1e-9438-f7648c9ff0fe"
                success: false
                errorCode:
                  code: "DECLINED_BY_ISSUER_OR_SCHEME"
                  message: "The operation was rejected by either the issuer or schemes."
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/transactions/{transactionId}/refund:
    post:
      tags:
        - Transactions
      summary: Refund Payment
      description: >
        Refund a captured payment. Partial refunds are allowed.
        <br/><br/>
        The endpoint typically only returns a single refund operation. But if multiple partial captures has been requested, the endpoint might return multiple refund operations as each capture is refunded in isolation.
        If you do not use partial captures, then you will only ever receive a single refund operation.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: transactionId
          in: path
          description: The id of the transaction to refund.
          required: true
          schema:
            type: string
      requestBody:
        description: Refund request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RefundRequest"
            example:
              amount: 1095
      responses:
        "200":
          description: Refund operation response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RefundResponse"
              example:
                success: false
                operations:
                  - operationId: "019248e0-0ff4-7c1e-9438-f7648c9ff0fe"
                    success: false
                    errorCode:
                      code: "DECLINED_BY_ISSUER_OR_SCHEME"
                      message: "The operation was rejected by either the issuer or schemes."
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/transactions/{transactionId}/void:
    post:
      tags:
        - Transactions
      summary: Void Payment
      description: Void an authorized payment that has not been captured.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: transactionId
          in: path
          description: The id of the transaction to void.
          required: true
          schema:
            type: string
      requestBody:
        description: Void request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VoidRequest"
            example:
              amount: 1095
      responses:
        "200":
          description: Void operation response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OperationResponse"
              example:
                operationId: "019248e0-0ff4-7c1e-9438-f7648c9ff0fe"
                success: false
                errorCode:
                  code: "DECLINED_BY_ISSUER_OR_SCHEME"
                  message: "The operation was rejected by either the issuer or schemes."
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/payout:
    post:
      tags:
        - Payouts
      summary: Payout (Asynchronous)
      description: >
        Initiate an asynchronous payout to send funds to a cardholder.
        A webhook will be sent to the specified notificationUrl once processed.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        description: Payout request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PayoutRequest"
            example:
              pointOfSaleId: "0192473a-e381-705c-b61c-fc2ac9624afc"
              amount: 1000
              currency: "DKK"
              paymentMethodId: "01924756-d1f6-738d-8040-90d76cedf01f"
              notificationUrl: "https://example.com/notification"
              reference: "payout-1"
              textOnStatement: "Prize money"
              processor:
                - "shift4"
                - "clearhaus"
              attributes:
                key1: "value1"
                key2: "value2"
              customer:
                firstName: "Morten"
                lastName: "Thomassen"
                ip: "118.249.219.99"
                birthdate: "1970-01-01"
      responses:
        "200":
          description: Payout response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionResponse"
              example:
                transaction:
                  id: "LDG7M4WW44G"
                  subscriptionId: null
                  state: "PENDING"
                  errorCode: null
                  createdAt: "2024-10-01T09:08:45.174774Z"
                  sessionId: null
                  paymentMethodId: "01924756-d1f6-738d-8040-90d76cedf01f"
                  paymentMethodType: "CARD"
                  paymentMethodSubType: "Visa"
                  paymentMethodExpiry: "2050-01-01"
                  paymentMethodDisplayText: "40000000XXXX0003"
                  scaMode: "SKIP"
                  customerId: "User159"
                  amount: 1000
                  currency: "DKK"
                  instantCapture: "OFF"
                  notificationUrl: "https://example.com/notification"
                  pointOfSaleId: "0192473a-e381-705c-b61c-fc2ac9624afc"
                  reference: "payout-1"
                  textOnStatement: "Prize money"
                  exemptions: []
                  attributes:
                    key1: "value1"
                    key2: "value2"
                  clientIp: "118.249.219.99"
                  type: "PAYOUT"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/payout-sync:
    post:
      tags:
        - Payouts
      summary: Payout (Synchronous)
      description: >
        Initiate a synchronous payout to send funds to a cardholder.
        Synchronous payouts require explicit approval from ePay.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        description: Synchronous payout request payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PayoutRequestSync"
            example:
              pointOfSaleId: "0192473a-e381-705c-b61c-fc2ac9624afc"
              amount: 1000
              currency: "DKK"
              paymentMethodId: "01924756-d1f6-738d-8040-90d76cedf01f"
              reference: "payout-1"
              textOnStatement: "Prize money"
              processor:
                - "shift4"
                - "clearhaus"
              attributes:
                key1: "value1"
                key2: "value2"
              customer:
                firstName: "Morten"
                lastName: "Thomassen"
                ip: "118.249.219.99"
                birthdate: "1970-01-01"
      responses:
        "200":
          description: Synchronous payout response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationWebhook"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/transactions/{transactionId}:
    get:
      tags:
        - Transactions
      summary: Get Transaction
      description: Retrieve details about an existing payment.
      security:
        - BearerAuth: []
      parameters:
        - name: transactionId
          in: path
          description: The id of the transaction to fetch.
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Transaction details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetTransactionResponse"
              example:
                transaction:
                  id: "LDG7M4WW44G"
                  state: "SUCCESS"
                  errorCode: null
                  createdAt: "2024-10-01T09:08:45.174774Z"
                  sessionId: "01924756-badd-71d4-be55-da367f434da4"
                  paymentMethodId: "01924756-d1f6-738d-8040-90d76cedf01f"
                  paymentMethodType: "CARD"
                  paymentMethodSubType: "Visa"
                  paymentMethodExpiry: "2050-01-01"
                  paymentMethodDisplayText: "40000000XXXX0003"
                  scaMode: "SKIP"
                  amount: 1000
                  currency: "DKK"
                  instantCapture: "OFF"
                  notificationUrl: "https://example.com/notification"
                  pointOfSaleId: "0192473a-e381-705c-b61c-fc2ac9624afc"
                  reference: "reference-1"
                  textOnStatement: "The text"
                  exemptions:
                    - "TRA"
                  attributes:
                    key1: "value1"
                    key2: "value2"
                  clientIp: "1.2.3.4"
                  type: "PAYMENT"
                operations:
                  - id: "01924cbf-d51c-71a7-b517-e42edb8e0dc2"
                    amount: 1000
                    state: "SUCCESS"
                    transactionId: "LDG7M4WW44G"
                    type: "AUTHORIZATION"
                    errorCode: null
                    createdAt: "2024-10-01T09:08:46.189214Z"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/transactions:
    get:
      tags:
        - Transactions
      summary: List Transactions
      description: >
        Retrieve transactions for the authenticated merchant using cursor-based pagination.
        Use `offset` to continue from the previous page and combine it with `sessionId` and `reference`
        filters to narrow the results.
      security:
        - BearerAuth: []
      parameters:
        - name: perPage
          in: query
          description: Maximum number of results to return in the response.
          schema:
            type: integer
            default: 25
            maximum: 500
            minimum: 1
        - name: offset
          in: query
          description: Cursor returned by `nextOffset`. Omit or pass an empty string to fetch the first page.
          schema:
            type: string
            example: ZAT48V8GW43M
        - name: sessionId
          in: query
          description: Only include transactions that belong to the provided session id.
          schema:
            type: string
            format: uuid
            example: 019ad8a2-18c6-7a72-bf20-2768be84eb42
        - name: reference
          in: query
          description: Only include transactions that match the provided reference / order id string exactly.
          schema:
            type: string
            example: reference-1
      responses:
        "200":
          description: Cursor paginated transactions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionsListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/transactions/operations:
    get:
      tags:
        - Transactions
      summary: List Operations
      description: |
        Retrieve a paginated list of transaction operations.
        Query parameters `page` and `perPage` can be used to control pagination. `finalizedBefore` and `finalizedAfter` can be sent to only get operations finalized between certain timeframes. `pointOfSaleId` can be used to limit the operations to a list of points of sale.
        <br/><br/>
        The endpoint only returns operations in a finalized state of `FAILED` or `SUCCESS`.
      security:
        - BearerAuth: []
      parameters:
        - name: page
          in: query
          description: Page number.
          schema:
            type: integer
            default: 1
        - name: perPage
          in: query
          description: Number of items per page.
          schema:
            type: integer
            default: 25
            maximum: 500
        - name: finalizedBefore
          in: query
          description: A filter to limit operations created finalized before a certain time. RFC 3339 format.
          schema:
            type: string
            format: date-time
        - name: finalizedAfter
          in: query
          description: A filter to limit operations created finalized after a certain time. RFC 3339 format.
          schema:
            type: string
            format: date-time
        - name: pointOfSaleId
          in: query
          description: An optional filter to limit operations from the given points of sale.
          explode: true
          schema:
            type: array
            items:
              type: string
              format: uuid
      responses:
        "200":
          description: A paginated list of transaction operations.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionOperationListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/{subscriptionId}:
    get:
      tags:
        - Subscriptions
      summary: Get Subscription
      description: Retrieve details about a specific subscription.
      security:
        - BearerAuth: []
      parameters:
        - name: subscriptionId
          in: path
          description: The id of the subscription to fetch.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Subscription details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetSubscriptionResponse"
              example:
                subscription:
                  id: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
                  paymentMethodId: "01924756-d1f6-738d-8040-90d76cedf01f"
                  currency: "DKK"
                  customerId: "User159"
                  pointOfSaleId: "0192473a-e381-705c-b61c-fc2ac9624afc"
                  reference: "subscription-1"
                  state: "ACTIVE"
                  type: "SCHEDULED"
                  expiryDate: null
                  interval:
                    period: "MONTH"
                    frequency: 1
                  createdAt: "2024-10-01T10:38:14.658688472+02:00"
                paymentMethod:
                  id: "01924756-d1f6-738d-8040-90d76cedf01f"
                  type: "CARD"
                  customerId: "User159"
                  createdAt: "2024-10-01T09:08:45.174235Z"
                  displayText: "40000000XXXX0003"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"
    delete:
      tags:
        - Subscriptions
      summary: Disable Subscription
      description: >
        Disables an active subscription, preventing the creation of new transactions.
        However, payments for existing transactions can still be captured, voided and refunded.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: subscriptionId
          in: path
          description: The id of the subscription to disable.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Subscription disabled successfully. No content returned.
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"
    patch:
      tags:
        - Subscriptions
      summary: Update Subscription
      description: >
        Updates the meta data of an ACTIVE subscription. This can be used to update the price or interval of in-app payment methods such as Vipps MobilePay.
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: subscriptionId
          in: path
          required: true
          description: The id of the subscription to update.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateSubscriptionRequest"
      responses:
        "200":
          description: Subscription updated successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetSubscriptionResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions:
    get:
      tags:
        - Subscriptions
      summary: List Subscriptions
      description: >
        Retrieve a paginated list of subscriptions.
        Query parameters `page` and `perPage` can be used to control pagination. `createdBefore` can be sent to only get subscriptions created before a certain time, and `customerId` can be used to limit subscriptions to a single customer.
        <br/><br/>
        When running import scripts against this endpoint, we strongly recommend setting a fixed `createdBefore` filter to avoid missing data caused by new subscriptions created on the account during the import.
      security:
        - BearerAuth: []
      parameters:
        - name: page
          in: query
          description: Page number.
          schema:
            type: integer
            default: 1
        - name: perPage
          in: query
          description: Number of items per page.
          schema:
            type: integer
            default: 25
            maximum: 500
        - name: createdBefore
          in: query
          description: A filter to limit subscriptions created before a certain time. RFC 3339 format.
          schema:
            type: string
            format: date-time
        - name: customerId
          in: query
          description: An optional filter to limit subscriptions to a specific customer id.
          schema:
            type: string
      responses:
        "200":
          description: A paginated list of subscriptions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionsListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/agreements:
    post:
      tags:
        - Subscription Billing
      summary: Create Billing Agreement
      description: >
        Creates a new <b>Billing Agreement</b> based on an existing <b>Subscription</b> and a <b>Billing Plan</b>.
        <br/><br/>

        A billing agreement represents a scheduled payment relationship between the merchant and the cardholder, managed automatically by ePay.
        It links a subscription and a plan together, allowing ePay to handle recurring charges according to the plan’s configuration - for example, charging the customer monthly based on the defined price and interval.
        <br/><br/>

        <b>Important:</b> Billing agreements is an <b>optional</b> extension of the base subscription and is only necessary if you want ePay to automatically manage recurring or interval-based billing on your behalf.
        <br/><br/>

        If you only need to perform unscheduled MIT (Merchant-Initiated Transaction) payments - meaning you trigger the charge manually via the API whenever needed - you do not need to create a billing agreement or billing plan.
        In that case, use the existing Subscription created through the [Initialize Payment Session <code>/cit</code>](/api/initialize-payment-session) endpoint, and perform MIT transactions directly.
        <br/><br/>

        :::info Relationship to other components
          - <b>Subscription:</b> The underlying link between a merchant and a stored payment method. Created via the [Initialize Payment Session <code>/cit</code>](/api/initialize-payment-session) endpoint by sending the Subscription object.  
          - <b>Billing Plan:</b> Defines recurring details like price, interval, and retry policy. Used only when ePay manages the billing schedule automatically.  
          - <b>Billing Agreement:</b> Connects a Subscription to a Billing Plan. Tracks scheduled processing and charge lifecycle.  
          - <b>Billing Agreement Charge:</b> Represents a scheduled billing event created from an agreement. Each charge can have multiple transaction attempts and a completion deadline.  
          - <b>Transaction:</b> The base payment model used for all processing. Charges and transactions are linked to maintain attempt history.
        :::
      security:
        - BearerAuth: [ ]
      requestBody:
        description: Create billing agreement data
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateBillingAgreementRequest"
      responses:
        "200":
          description: Billing agreement details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

    get:
      tags:
        - Subscription Billing
      summary: List Billing Agreements
      description: Returns a paginated list of all billing agreements associated to your account.
      security:
        - BearerAuth: [ ]
      responses:
        "200":
          description: Billing agreement details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementsListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/agreements/{agreementId}:
    get:
      tags:
        - Subscription Billing
      summary: Get Billing Agreement
      description: Returns the specific billing agreement from its id
      security:
        - BearerAuth: [ ]
      parameters:
        - name: agreementId
          in: path
          description: The id of the agreement to fetch.
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Billing agreement details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/agreements/{agreementId}/stop:
    post:
      tags:
        - Subscription Billing
      summary: Stop Billing Agreement
      description: Stop automatic billing charges for the given billing agreement. No more automatic charges will be made for the agreement, until `/resume` is called.
      security:
        - BearerAuth: [ ]
      parameters:
        - name: agreementId
          in: path
          description: The id of the agreement to stop.
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Billing agreement details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/agreements/{agreementId}/resume:
    post:
      tags:
        - Subscription Billing
      summary: Resume Billing Agreement
      description: Resume automatic billing charges for the given billing agreement. Charges will begin again, with the first charge made on the given `nextChargeAt` date.
      security:
        - BearerAuth: [ ]
      parameters:
        - name: agreementId
          in: path
          description: The id of the agreement to stop.
          required: true
          schema:
            type: string
      requestBody:
        description: Create billing agreement data
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ResumeBillingAgreementRequest"
      responses:
        "200":
          description: Billing agreement details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/plans:
    post:
      tags:
        - Subscription Billing
      summary: Create Billing Plan
      description: >
        Creates a new billing plan. Billing plans are the basis of all billing agreements with automatic charges.
        
        :::info Relationship to other components
          - <b>Subscription:</b> The underlying link between a merchant and a stored payment method. Created via the [Initialize Payment Session <code>/cit</code>](/api/initialize-payment-session) endpoint by sending the Subscription object.  
          - <b>Billing Plan:</b> Defines recurring details like price, interval, and retry policy. Used only when ePay manages the billing schedule automatically.  
          - <b>Billing Agreement:</b> Connects a Subscription to a Billing Plan. Tracks scheduled processing and charge lifecycle.  
          - <b>Billing Agreement Charge:</b> Represents a scheduled billing event created from an agreement. Each charge can have multiple transaction attempts and a completion deadline.  
          - <b>Transaction:</b> The base payment model used for all processing. Charges and transactions are linked to maintain attempt history.
        :::
      security:
        - BearerAuth: [ ]
      requestBody:
        description: Create billing plan data
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateBillingPlanRequest"
      responses:
        "200":
          description: Billing plan details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingPlanResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

    get:
      tags:
        - Subscription Billing
      summary: List Billing Plans
      description: Returns a paginated list of all the billing plans associated your account. Billing plans are the basis for all billing agreement and automatic charges. They define the price and interval between charges.
      security:
        - BearerAuth: [ ]
      responses:
        "200":
          description: Billing plan details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingPlansListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/plans/{planId}:
    get:
      tags:
        - Subscription Billing
      summary: Get Billing Plan
      description: Returns the specific billing plan from its id
      security:
        - BearerAuth: [ ]
      parameters:
        - name: planId
          in: path
          description: The id of the plan to fetch.
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Billing plan details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingPlanResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/charges:
    get:
      tags:
        - Subscription Billing
      summary: List Billing Charges
      description: >
        Returns a paginated list of billing agreement charges created for your merchant account.
        Use this endpoint to audit scheduled billing events, see their states, and review current or historic attempts.
        You can optionally filter the list by `billingAgreementId` to focus on a single agreement.
      security:
        - BearerAuth: [ ]
      parameters:
        - name: billingAgreementId
          in: query
          description: Optional UUID of a billing agreement to filter the charges list.
          schema:
            type: string
            format: uuid
        - name: page
          in: query
          description: Page number.
          schema:
            type: integer
            default: 1
        - name: perPage
          in: query
          description: Number of items per page.
          schema:
            type: integer
            default: 25
            maximum: 500
      responses:
        "200":
          description: Billing agreement charge details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementChargesListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/subscriptions/billing/charges/{billingAgreementChargeId}:
    get:
      tags:
        - Subscription Billing
      summary: Get Billing Charge
      description: Returns the specific billing agreement charge by id.
      security:
        - BearerAuth: [ ]
      parameters:
        - name: billingAgreementChargeId
          in: path
          description: The id of the billing agreement charge to fetch.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Billing agreement charge details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAgreementChargeResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/webhooks:
    get:
      tags:
        - Webhooks
      summary: List Webhooks
      description: >
        Returns a paginated list of active webhooks configured for the authenticated merchant.
        Use this endpoint to audit webhook destinations, verify subscribed events, and ensure each webhook aligns with your point-of-sale domains.
      security:
        - BearerAuth: [ ]
      parameters:
        - name: page
          in: query
          description: Page number.
          schema:
            type: integer
            default: 1
        - name: perPage
          in: query
          description: Number of items per page.
          schema:
            type: integer
            default: 25
            maximum: 500
      responses:
        "200":
          description: Paginated webhook collection.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhooksListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

    post:
      tags:
        - Webhooks
      summary: Create Webhook
      description: >
        Registers a new webhook endpoint limited to domains already approved on your point of sale configuration.
        A maximum of 10 active webhooks is allowed per merchant. Each webhook must subscribe to one or more supported events and include a shared secret used as the value of the `Authorization` header when sending webhook.
      security:
        - BearerAuth: [ ]
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        description: Webhook configuration payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/StoreWebhookRequest"
      responses:
        "200":
          description: Newly created webhook.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookResource"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/webhooks/{webhookId}:
    delete:
      tags:
        - Webhooks
      summary: Delete Webhook
      description: Deletes a webhook configuration, stopping ePay from delivering further notifications to the URL.
      security:
        - BearerAuth: [ ]
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: webhookId
          in: path
          description: ID of the webhook to delete.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Webhook deleted successfully. No content returned.
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/cit:
    post:
      tags:
        - Sessions
      summary: Initialize Payment Session
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      description: |
        Initializes a new payment session with the ePay Payments API.
        This endpoint requires a valid ApiKey and must be called from the server side
        to ensure the ApiKey is never exposed client-side.

        :::info Required or configurable fields
        In the ePay backoffice, under Advanced Point of Sale Settings, you can set default values for many session initialization parameters. This allows you to manage your setup without updating your code.
        
        Each property must be defined either in the backoffice or in the API request. If a value is provided in the API request, it overrides the backoffice default.

        The following fields can be configured:
          - `scaMode`
          - `timeout`
          - `instantCapture`
          - `processor`
          - `maxAttempts`
          - `notificationUrl`
          - `successUrl`
          - `failureUrl`
          - `exemptions`
        Note: Only a subset of these fields are strictly required for the API request. The table below indicates which fields are mandatory or optional.
        :::

      security:
        - BearerAuth: []
      requestBody:
        description: Payment session initialization payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentSessionInitializationRequest"
            example:
              pointOfSaleId: "01924737-9c18-71c0-ab1a-88698eaceabf"
              reference: "reference-1"
              amount: 1000
              currency: "DKK"
              scaMode: "SKIP"
              timeout: 60
              instantCapture: "OFF"
              processor: ["shift4", "clearhaus", "nets"]
              exemptions: ["TRA"]
              textOnStatement: "The text"
              attributes:
                key1: "value1"
                key2: "value2"
              customerId: "User159"
              maxAttempts: 10
              reportFailure: false
              dynamicAmount: false
              notificationUrl: "https://example.com/notification"
              preAuthUrl: "https://example.com/pre-auth"
              successUrl: "https://example.com/success"
              failureUrl: "https://example.com/failure"
              subscription:
                type: "SCHEDULED"
                reference: "subscription-1"
                expiryDate: "2050-01-01"
                interval:
                  period: "MONTH"
                  frequency: 1
      responses:
        "200":
          description: Successful payment session initialization response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentSessionInitializationResponse"
              example:
                paymentWindowUrl: "https://payments.epay.eu/payment-window?sessionId=0192473a-e382-79a9-bfc2-65da88fe812f&sessionKey=4651656e-f29e-4dfa-a1cd-a65647862011"
                javascript: "https://payments.epay.eu/sessions/0192473a-e382-79a9-bfc2-65da88fe812f/client.js"
                key: "4651656e-f29e-4dfa-a1cd-a65647862011"
                session:
                  id: "0192473a-e382-79a9-bfc2-65da88fe812f"
                  subscriptionId: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
                  amount: 1000
                  attributes:
                    key1: "value1"
                    key2: "value2"
                  exemptions: ["TRA"]
                  currency: "DKK"
                  expiresAt: "2024-10-01T12:41:14.658688472+02:00"
                  instantCapture: "OFF"
                  maxAttempts: 10
                  reportFailure: false
                  dynamicAmount: false
                  notificationUrl: "https://example.com/notification"
                  preAuthUrl: "https://example.com/pre-auth"
                  successUrl: "https://example.com/success"
                  failureUrl: "https://example.com/failure"
                  pointOfSaleId: "0192473a-e381-705c-b61c-fc2ac9624afc"
                  reference: "reference-1"
                  state: "PENDING"
                  textOnStatement: "The text"
                  scaMode: "SKIP"
                  timeout: 60
                  createdAt: "2024-10-01T10:38:14.658688472+02:00"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/payment-links:
    post:
      tags:
        - Payment Links
      summary: Create Payment Link
      description: |
        Creates a new payment link with the ePay Payments API.
        This endpoint requires a valid ApiKey and must be called from the server side
        to ensure the ApiKey is never exposed client-side.

        :::info Required fields 
        In the ePay backoffice in the advanced Point of Sale settings you can set the default for many of the session initialization parameters, allowing you to change your setup from the interface without updating your code. 

        Properties must be defined in either the point of sale settings or the API request. The API request takes precedence and overwrites any point of sale settings if present.

        These fields are:
          - `scaMode`
          - `timeout`
          - `instantCapture`
          - `processor`
          - `maxAttempts`
          - `notificationUrl`
          - `successUrl`
          - `failureUrl`
        :::

      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        description: Create payment link initialization payload.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePaymentLinkRequest"
      responses:
        "200":
          description: Successful payment link creation response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreatePaymentLinkResponse"
              example:
                id: "KSNMWEWZPPA"
                sessionId: "01975f11-329f-7c14-a03a-3739d8b48ef3"
                url: "https://payments.epay.eu/link/KSNMWEWZPPA"
                qrCode: "/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4n...."
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/payment-links/{id}:
    delete:
      tags:
        - Payment Links
      summary: Cancel Payment Link
      description: |
        Cancels a payment link that has not yet been completed. 
        
        A payment link can only be cancelled if no transactions are currently being processed for it. If the payment link cannot be cancelled, an `UNEXPECTED_SESSION_STATE` error is returned.
      security:
        - BearerAuth: [ ]
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
        - name: id
          in: path
          description: ID of the payment-link to cancel.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Payment link cancelled successfully. No content returned.
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/payment-methods/imported:
    get:
      tags:
        - Payment Methods
      summary: List Imported Payment Methods
      description: >
        Retrieve imported payment methods for the authenticated merchant using cursor-based pagination ordered by newest `id`.
        
        Each entry includes the imported payment method, its underlying payment method, and associated card details (if any).
      security:
        - BearerAuth: []
      parameters:
        - name: perPage
          in: query
          description: Maximum number of results to return in the response.
          schema:
            type: integer
            default: 25
            maximum: 500
            minimum: 1
        - name: offset
          in: query
          description: Cursor returned by `nextOffset`. Provide the id of the last item from the previous page to fetch entries with a lower `id`. Use an empty string to fetch the first page.
          schema:
            type: string
            example: ""
      responses:
        "200":
          description: Cursor paginated imported payment methods.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ImportedPaymentMethodsListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/settlements/transfers:
    get:
      tags:
        - Settlements
      summary: List settlement transfers
      description: >
        List settlement transfers. Settlement transfers models the actual bank payouts from the acquirer to your bank.
        
        :::info Relationship to other components
          - <b>Settlement Transfer:</b> A bank transfer / payout / settlement from the acquirer to your bank.
          - <b>Settlement Transaction:</b> Settlement data for a specific transaction, can be related to an ePay transaction if the transaction was made through ePay. 
          - <b>Adjustments:</b> Any modifications the acquirer makes to the transaction amount, before arriving at the net amount being paid out. This includes both transaction, settlement and service fees, but also any reimbursements or currency exchange fees.
          - <b>Transactions:</b> An ePay transaction. If an acquirer transaction within the settlement data was processed through ePay, it will be linked to the Settlement Transaction.
        :::
      security:
        - BearerAuth: []
      parameters:
        - name: perPage
          in: query
          description: Maximum number of results to return in the response.
          schema:
            type: integer
            default: 25
            maximum: 500
            minimum: 1
        - name: offset
          in: query
          description: Cursor returned by `nextOffset`. Omit or pass an empty string to fetch the first page.
          schema:
            type: string
            example: 019b3168-9334-770c-b34f-829d3c9c65d1
      responses:
        "200":
          description: Cursor-paginated settlement transfers
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettlementTransferCursor"
        "401":
          description: Missing/invalid API key
        "500":
          description: Server error

  /public/api/v1/settlements/transfers/{transferId}:
    get:
      tags:
        - Settlements
      summary: Show settlement transfer
      description: >
        Show settlement transfers. Settlement transfers models the actual bank payouts from the acquirer to your bank.
        
        :::info Relationship to other components
          - <b>Settlement Transfer:</b> A bank transfer / payout / settlement from the acquirer to your bank.
          - <b>Settlement Transaction:</b> Settlement data for a specific transaction, can be related to an ePay transaction if the transaction was made through ePay. 
          - <b>Adjustments:</b> Any modifications the acquirer makes to the transaction amount, before arriving at the net amount being paid out. This includes both transaction, settlement and service fees, but also any reimbursements or currency exchange fees.
          - <b>Transactions:</b> An ePay transaction. If an acquirer transaction within the settlement data was processed through ePay, it will be linked to the Settlement Transaction.
        :::
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: transferId
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Settlement transfer
          content:
            application/json:
              schema:
                type: object
                properties:
                  settlementTransfer:
                    $ref: "#/components/schemas/SettlementTransfer"
        "401":
          description: Missing/invalid API key
        "404":
          description: Transfer not found or not owned by merchant
        "500":
          description: Server error

  /public/api/v1/settlements/transfers/{transferId}/transactions:
    get:
      tags:
        - Settlements
      summary: List settlement transactions
      description: >
        List settlement transactions. Settlement transactions gives pr. transaction insight into the fees paid to the acquirer, scheme and network.
        
        Normal acquirer agreements often only contain a single `acquirer` fee, which represent your blended pricing at the acquirer.
        Larger merchants working with IC++ pricing will typically see a breakdown of the transaction cost into `interchange` fees (Set by the issuer bank), `scheme` fee (Set by Visa/Mastercard) and `acquirer` fee (Set by the acquirer).
        
        Do note, one ePay transaction can be linked to multiple settlement transactions if multiple partial captures or refunds are used.
        
        :::info Relationship to other components
          - <b>Settlement Transfer:</b> A bank transfer / payout / settlement from the acquirer to your bank.
          - <b>Settlement Transaction:</b> Settlement data for a specific transaction, can be related to an ePay transaction if the transaction was made through ePay. 
          - <b>Adjustments:</b> Any modifications the acquirer makes to the transaction amount, before arriving at the net amount being paid out. This includes both transaction, settlement and service fees, but also any reimbursements or currency exchange fees.
          - <b>Transactions:</b> An ePay transaction. If a settlement transaction was processed through ePay, it will be linked to the ePay Transaction.
        :::
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: transferId
          required: true
          schema:
            type: string
            format: uuid
        - name: perPage
          in: query
          description: Maximum number of results to return in the response.
          schema:
            type: integer
            default: 25
            maximum: 500
            minimum: 1
        - name: offset
          in: query
          description: Cursor returned by `nextOffset`. Omit or pass an empty string to fetch the first page.
          schema:
            type: string
            example: 019b3168-9334-770c-b34f-829d3c9c65d1
      responses:
        "200":
          description: Cursor-paginated settlement transactions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettlementTransactionCursor"
        "401":
          description: Missing/invalid API key
        "404":
          description: Transfer not found or not owned by merchant
        "500":
          description: Server error

  /public/api/v1/management/point-of-sales:
    post:
      tags:
        - Management
      summary: Create Point of Sale
      description: >
        Create a new Point of Sale and its associated hosted configuration.
        Note: The `webhookAuthentication` value is the entire `Authorization` header value send for any webhook. So you must include the auth scheme such as `Bearer` or `Basic`.
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/StorePointOfSaleRequest"
      responses:
        "200":
          description: Created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedPointOfSale"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

    get:
      tags:
        - Management
      summary: List Points of Sales
      description: >
        Retrieve a paginated list of points of sale.
        Query parameters `page` and `perPage` can be used to control pagination.
      security:
        - BearerAuth: []
      parameters:
        - name: page
          in: query
          description: Page number.
          schema:
            type: integer
            default: 1
        - name: perPage
          in: query
          description: Number of items per page.
          schema:
            type: integer
            default: 25
            maximum: 500
      responses:
        "200":
          description: A paginated list of points of sale.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PointOfSaleListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/management/point-of-sales/{pointOfSaleId}:
    get:
      tags:
        - Management
      summary: Get Point of Sale
      description: Retrieve a single Point of Sale with its hosted configuration.
      security:
        - BearerAuth: []
      parameters:
        - name: pointOfSaleId
          in: path
          required: true
          description: UUID of the Point of Sale
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: The requested Point of Sale.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedPointOfSale"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/management/api-keys:
    post:
      summary: "Create API key"
      description: |
        Creates a new merchant API key. This is the key merchants and external systems must use to communicate with the ePay API. 

        *Partner Specific:* Partners should instead use partner keys to generate an access token, when accessing ePay apis on behalf our merchants.
      tags:
        - Management
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateApiKeyRequest"
      responses:
        "200":
          description: API key created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateApiKeyResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/partner/accounts:
    post:
      summary: "Create merchant Account"
      description: Use this endpoint to create a new merchant account associated with your partner profile.
      tags:
        - Partner
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerAccountRequest"
      responses:
        "200":
          description: Account created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreatePartnerAccountResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"
    get:
      summary: "List merchant Accounts"
      tags:
        - Partner
      parameters:
        - name: page
          in: query
          description: Page number.
          schema:
            type: integer
            default: 1
        - name: perPage
          in: query
          description: Number of items per page.
          schema:
            type: integer
            default: 25
            maximum: 500
      responses:
        "200":
          description: This endpoint can be used to fetch all merchant accounts associated with your partner profile.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountsListResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/partner/accounts/{accountId}:
    get:
      summary: "Show merchant Account"
      description: Fetches merchant account details for the request id.
      tags:
        - Partner
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Account details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShowPartnerAccountResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

    delete:
      summary: "Close merchant Account"
      description: Marks a merchant account for closing. The account is not instantly closed, but will be closed during the next billing period by ePay.
      tags:
        - Partner
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Account closed successfully
          content: {}
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/partner/accounts/{accountId}/activate:
    patch:
      summary: "Activate merchant Live Account"
      description: To enable a merchant to go live, and begin billing, use this endpoint. To receive real production payments, a merchant account must be marked as live.
      tags:
        - Partner
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Account activated successfully
          content: {}
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

  /public/api/v1/partner/accounts/{accountId}/access-token:
    post:
      summary: "Request Merchant Access Token"
      description: |
        To access the ePay API on behalf of a merchant under your partner profile, partners must create a access token for the merchant before sending requests. An access token expires after 8 hours. 
        
        Access token requests are cached in one hour, so any subsequent access token requests for the same merchant and environment may return the same token as previously requested, within the cache period.
        
        The returned access token is used in-place of the merchant API key in the `Authorization` header.
      tags:
        - Partner
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerAccessTokenRequest"
      responses:
        "200":
          description: Access token created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreatePartnerAccessTokenResponse"
        "400":
          $ref: "#/components/responses/ErrorResponse"
        "422":
          $ref: "#/components/responses/ValidationErrorResponse"
        "500":
          $ref: "#/components/responses/ErrorResponse"

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer

  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      description: |
        Ensures that a request can be safely retried without causing duplicate operations. 
        Typically used for actions like payment creation and operations such as refund and void to prevent accidental double processing.  

        - If a response is replayed due to using the same key, the response will include the header `Idempotent-Replayed: true`.  
        - Idempotency keys are scoped by **[Key, Endpoint, HTTP Verb]**; the same key on a different endpoint or method will not replay the original response.  
        - Responses are cached for **24 hours**. After that, the cache is cleared, so idempotency is only guaranteed within 24 hours of the initial request.
      required: false
      schema:
        type: string
      example: "c4f5e8d2-1234-5678-90ab-cdef12345678"

  responses:
    ErrorResponse:
      description: |
        Standard error response returned when a request fails.
        Contains a machine-readable error code, a human-readable message.
      content:
        application/json:
          schema:
            type: object
            properties:
              errorCode:
                type: string
                example: "SERVER_ERROR"
                description: A system error code to identify the issue. Can be used by your system to detect what went wrong.
              message:
                type: string
                example: "An unexpected system error"
                description: Contains a human readable explanation of the error code. Any situational detail is appended to the end of the description.

    ValidationErrorResponse:
      description: |
        Standard error response returned when a request fails.
        Contains a machine-readable error code, a human-readable message,
        and an `errors` object with field-specific validation issues.
      content:
        application/json:
          schema:
            type: object
            properties:
              errorCode:
                type: string
                description: Machine-readable error code indicating the type of error.
                example: VALIDATION_ERROR
              message:
                type: string
                description: Human-readable description of the error.
                example: Input validation errors
              errors:
                type: object
                description: |
                  Object where each key corresponds to the name of an invalid field.
                  Each value is an array of strings, where each string describes
                  a specific validation issue for that field.
                additionalProperties:
                  type: array
                  items:
                    type: string
                example:
                  amount:
                    - "[required]: Is a required non-nullable field"
                    - "[int]: Must be an integer"
                    - "[min:0]: Must be greater than 0"
                    - "[max:999999999]: Must be less than 999999999"
            required:
              - errorCode
              - message

  schemas:
    Account:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 019a0abe-f093-72c7-9f89-be4e48b9e01e
          description: The primary id of the merchant account
        name:
          type: string
          description: The name of the account
        addressLineOne:
          type: string
          nullable: true
          description: The address line of the merchant
        addressLineTwo:
          type: string
          nullable: true
          description: The address line of the merchant
        city:
          type: string
          nullable: true
          description: The city of the merchant
        postalCode:
          type: string
          nullable: true
          description: The postal code of the merchant
        countryCode:
          type: string
          nullable: true
          description: The country code of the merchant
        phone:
          type: string
          nullable: true
          description: The primary contact number of the merchant
        email:
          type: string
          nullable: true
          description: The primary contact email of the merchant
        timezone:
          type: string
          nullable: true
          description: The primary timezone of the merchant
        invoiceEmail:
          type: string
          nullable: true
          description: The email used when sending invoices.
        invoiceAttention:
          type: string
          nullable: true
          description: The receiver name of the invoice email.
        vat:
          type: string
          nullable: true
          description: The VAT number of the merchant
        currencyCode:
          type: string
          nullable: true
          description: The primary currency code of the merchant
        status:
          type: string
          description: The current status of the merchant account
        createdAt:
          type: string
          format: date-time
          description: The merchant account creation time

    AccountsListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                type: object
                properties:
                  account:
                    $ref: "#/components/schemas/Account"

    CreateApiKeyRequest:
      type: object
      required: [name]
      properties:
        name:
          description: A display name for the API key visible in the ePay backoffice. This can be used to indicate the reason or usage of the API key.
          type: string
          example: My Name

    CreateApiKeyResponse:
      type: object
      properties:
        name:
          type: string
          example: My Name
          description: A display name for the API key visible in the ePay backoffice. This can be used to indicate the reason or usage of the API key.
        key:
          type: string
          example: test_13cfbcbf-fd20-4dc5-9b16-209f6c708119
          description: The API key. Keys starting with `test_` is for the test environment and keys starting with `live_` is for the live environment.

    CreatePartnerAccountRequest:
      type: object
      required: [name, email, currencyCode, timezone, domain]
      properties:
        name:
          type: string
          example: Merchant Name
          description: The name of the merchant. This is typically the company name or the name of the merchant domain or app.
        email:
          type: string
          format: email
          example: owner@merchant.dk
          description: The email address of the merchant account owner. This email will automatically be invited to join the created merchant account and granted ownership privileges.
        currencyCode:
          type: string
          example: DKK
          description: The primary currency of the merchant. Alpha-3.
        language:
          type: string
          example: da
          description: The primary language of the merchant. ISO 639.
        timezone:
          type: string
          example: Europe/Copenhagen
          description: The primary timezone of the merchant.
        domain:
          type: string
          example: merchant.dk
          description: The primary domain used by the merchant. This should be the URL that purchases are expected to take place from.

    CreatePartnerAccountResponse:
      type: object
      properties:
        account:
          $ref: "#/components/schemas/Account"

    ShowPartnerAccountResponse:
      type: object
      properties:
        account:
          $ref: "#/components/schemas/Account"

    CreatePartnerAccessTokenRequest:
      type: object
      required: [environment]
      properties:
        environment:
          description: The environment for which to create an access token. This can be either `test` or `live`. The created access token will only have access to the respective environment for the merchant account.
          type: string
          enum: [test, live]
          example: live

    CreatePartnerAccessTokenResponse:
      type: object
      properties:
        expiresAt:
          description: The time at which the access token expires. It is recommended to create a new access token before the current one expires to avoid inflight clock skew issues.
          type: string
          format: date-time
          example: 2030-07-29T15:51:28.071Z
        accessToken:
          description: A JWT access token granting access to the merchant account for either the live or test environment. As a partner you can send this access token instead of a merchant API key, when accessing the ePay API on behalf of the merchant.
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0N...

    Processor:
      type: string
      description: |
        Identifier of a payment processor.
        This value determines which payment gateway(s) are used to process a payment.
      enum:
        - shift4
        - clearhaus
        - nets
        - worldline

    PaymentMethodType:
      type: string
      example: "CARD"
      description: The type of the payment method.
      enum:
        - CARD
        - VIPPS_MOBILEPAY
        - MOBILEPAY_ONLINE
        - APPLE_PAY
        - GOOGLE_PAY
        - SWISH
        - VIABILL
        - ANYDAY

    MitAuthorizationRequest:
      type: object
      properties:
        subscriptionId:
          type: string
          format: uuid
          description: The ID of the subscription to charge
          example: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
        amount:
          type: integer
          description: Amount in minor units (e.g., 1095 = 10.95 DKK)
          example: 100
        currency:
          pattern: ^[A-Z]{3}$
          type: string
          description: The currency of the transaction. If set to null, then the same currency as the subscription was created for will be used.
          nullable: true
          example: "DKK"
        reference:
          type: string
          example: "subscription-charge-1"
          description: The merchant reference for the payment. This is typically used for the order id.
        instantCapture:
          type: string
          example: "OFF"
          description: "If the payment should be captured instantly or not.<ul><li> `OFF` indicates that the payment should not be captured instantly.</li><li> `VOID` indicates that the payment should be captured instantly and if somehow the instant capture fails the payment is voided.</li><li> `NO_VOID` indicates that the payment should be captured instantly and if the capture fails the authorization is kept (no void is made)</li></ul>"
          enum:
            - OFF
            - VOID
            - NO_VOID
        textOnStatement:
          type: string
          minLength: 1
          maxLength: 39
          example: "WineBox subscription"
          description: The text to show on the cardholder bank statement. Many providers do not support long texts. Epay will cut the text to match the acquirer limitations.
        notificationUrl:
          description: The URL to receive the webhook with the transaction result
          example: "https://example.com/epay/notification"
          type: string
          format: uri
        attributes:
          description: A list of pass-through parameters that will be sent back on the notification URL
          type: object
          additionalProperties: {}
      required:
        - subscriptionId
        - amount
        - notificationUrl

    CreateMitBatchTransactionRequest:
      type: object
      description: Batch payload for creating multiple MIT transactions in one request.
      properties:
        transactions:
          type: array
          description: Ordered list of MIT transaction requests that will be processed asynchronously.
          minItems: 1
          maxItems: 500
          items:
            $ref: "#/components/schemas/MitAuthorizationRequest"
      required:
        - transactions

    CreateMitBatchTransactionResponse:
      type: object
      description: Per-entry creation results for a MIT batch request.
      properties:
        transactions:
          type: array
          description: Results for each submitted transaction in the batch, in the same order as received. Each transaction is processed individually, if the transaction passes initial validation then a transaction is created for background processing and a `transaction` is returned. If the initial validation fails, instead an `error` is returned.
          items:
            $ref: "#/components/schemas/MitBatchResultRow"
          example:
            - transaction:
                id: "LDG7M4WW44G"
                amount: 500
                currency: "DKK"
                subscriptionId: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
                state: "PENDING"
                paymentMethodType: "CARD"
              error: null
            - transaction: null
              error:
                success: false
                errorCode: "MODEL_NOT_FOUND"
                message: "The requested model was not found."
      required:
        - transactions

    MitBatchResultRow:
      type: object
      description: Outcome for a single entry in a MIT batch request. Only one of `transaction` or `error` is populated.
      properties:
        transaction:
          nullable: true
          description: Created MIT transaction when the entry is accepted. Null when validation or ownership checks fail.
          allOf:
            - $ref: "#/components/schemas/Transaction"
        error:
          nullable: true
          description: Error payload explaining why the batch entry could not be created.
          type: object
          properties:
            success:
              type: boolean
              description: Indicates that the batch entry failed; always false when present.
              example: false
            errorCode:
              type: string
              description: Machine-readable error code for the failure reason.
              example: "MODEL_NOT_FOUND"
            message:
              type: string
              description: Human-readable description of the failure reason.
              example: "The requested model was not found."
          required:
            - success
            - errorCode
            - message

    CaptureRequest:
      type: object
      properties:
        amount:
          type: integer
          description: The amount to capture in minor units (e.g., 1095 = 10.95 DKK). You cannot capture more than authorized.
          minimum: 1
        voidRemaining:
          type: boolean
          description: If true, any remaining authorization balance will be voided after a successful capture. If the capture fails, nothing will be voided.
          default: false
      required:
        - amount

    VoidRequest:
      type: object
      properties:
        amount:
          type: integer
          description: |
            Amount in minor units to void (e.g., 1095 = 10.95 DKK).  
            ePay supports both full and partial voids. It is not possible to void more than was authorized.  
            To void any remaining amount, send `-1`. Sending `0` is not allowed.
          anyOf:
            - type: integer
              enum: [-1]
            - type: integer
              minimum: 1
      required:
        - amount

    RefundRequest:
      type: object
      properties:
        amount:
          type: integer
          description: Amount in minor units to refund (e.g., 1095 = 10.95 DKK)
          minimum: 1
      required:
        - amount

    PayoutRequestSync:
      type: object
      properties:
        pointOfSaleId:
          type: string
          format: uuid
          description: UUID of the Point of Sale to debit from; must belong to your account.
          example: "0192473a-e381-705c-b61c-fc2ac9624afc"
        amount:
          type: integer
          example: 1000
          description: Amount in minor units (e.g., 1095 = 10.95 DKK). Must be >= 1.
          minimum: 1
        currency:
          type: string
          example: "DKK"
          pattern: ^[A-Z]{3}$
          description: ISO 4217 alpha-3 currency, e.g., “DKK”.
        paymentMethodId:
          type: string
          format: uuid
          example: "01924756-d1f6-738d-8040-90d76cedf01f"
          description: UUID of a stored payment method eligible for payouts.
        reference:
          type: string
          example: "payout-1"
          description: Merchant reference for reconciliation; should be unique per payout when possible. Defaults to the ePay transaction id.
        textOnStatement:
          type: string
          example: "Prize money"
          minLength: 1
          maxLength: 39
          description: Descriptor shown on recipient’s statement; acquirer limits may apply (e.g., 22 chars).
        processor:
          type: array
          deprecated: true
          description: |
            **DEPRECATED:** *This parameter will soon be removed and will no longer have any effect. The functionality has been replaced by routing rules in the ePay back office.*
            
            List of permitted processors; order is priority fallback. Values: shift4, clearhaus, nets.
          items:
            $ref: "#/components/schemas/Processor"
          example:
            - "shift4"
            - "clearhaus"
        attributes:
          type: object
          description: Pass-through key-value pairs returned in webhooks; recommend max combined size (e.g., 1 KB) and ASCII/UTF-8 guidance.
          additionalProperties: {}
          example:
            key1: "value1"
            key2: "value2"
        customer:
          type: object
          properties:
            firstName:
              type: string
              example: "Morten"
              description: Recipient name; used for compliance and risk.
            lastName:
              type: string
              example: "Thomassen"
              description: Recipient name; used for compliance and risk.
            ip:
              type: string
              example: "118.249.219.99"
              description: IPv4/IPv6 address of the client initiating the payout request; used for fraud/risk.
            birthdate:
              type: string
              nullable: true
              example: 1970-01-01
              pattern: "^\\d{4}-\\d{2}-\\d{2}$"
              description: The birthdate of the recipient. YYYY-MM-DD; required by some payout methods;
          required:
            - firstName
            - lastName
            - ip
      required:
        - pointOfSaleId
        - amount
        - currency
        - paymentMethodId

    PayoutRequest:
      allOf:
        - $ref: "#/components/schemas/PayoutRequestSync"
        - type: object
          properties:
            notificationUrl:
              type: string
              format: uri
              description: Webhook target for payout result. This endpoint will be called once the transaction is fully processed.
          required:
            - notificationUrl

    TransactionResponse:
      type: object
      properties:
        transaction:
          $ref: "#/components/schemas/Transaction"

    NotificationWebhook:
      type: object
      description: |
        The notification webhook is sent to the merchant’s configured endpoint when a transaction attempt has been completed, regardless of whether the transaction succeeded or failed.

        **Delivery and Retry Policy**  
        - The receiving system must respond with standard HTTP `200 OK`.  
        - If no `200 OK` is received, the webhook will be retried with exponential backoff.  
        - Retry strategy:  
          - Attempt 1: immediate (0 seconds).  
          - Attempt 2: immediate (0 seconds).  
          - Attempt 3+: delayed by `2^attempt` seconds.  
          - Maximum delay capped at 3 hours.  
          - Retries stop after 25 attempts.  
        - Each webhook request has a strict timeout of 5 seconds.  
        - Merchants should always acknowledge quickly and process business logic asynchronously. Failure to comply may result in the endpoint being moved to a low-priority queue.

        **Headers and Authentication**  
        - Every webhook includes an `Authorization` header that must be validated to ensure the request originated from ePay.  
        - By default, ePay issues a random Bearer token at account creation. This token, and the authorization scheme (`Bearer` vs `Basic`), can be managed in the ePay Backoffice.  
        - No additional signatures or payload signing is applied. Verification relies exclusively on the `Authorization` header.
      properties:
        acquirerAgreement:
          $ref: "#/components/schemas/AcquirerAgreement"
        transaction:
          $ref: "#/components/schemas/Transaction"
        operations:
          type: array
          items:
            $ref: "#/components/schemas/Operation"
        session:
          nullable: true
          allOf:
            - $ref: "#/components/schemas/Session"
        subscription:
          nullable: true
          allOf:
            - $ref: "#/components/schemas/Subscription"
        sca:
          nullable: true
          allOf:
            - $ref: "#/components/schemas/ScaStatus"
        card:
          nullable: true
          description: Info about the card used during the transaction. Is only available for card based payments.
          allOf:
            - $ref: "#/components/schemas/Card"

    ScaStatus:
      type: object
      properties:
        rejected:
          type: boolean
          example: false
          description: Boolean indicator which is true when the transaction is rejected due to failing SCA such as a 3DS challenge with MitID.
        type:
          type: string
          example: "3DS"
          description: The type of SCA performed during the transaction.
          enum:
            - 3DS
            - DELEGATED
            - UNKNOWN
        verification:
          type: string
          example: "FRICTIONLESS"
          description: The level of verification performed during the transaction. The value will be `CHALLENGED` if the customer was prompted with challenges such as MitID login.
          enum:
            - NONE
            - FRICTIONLESS
            - CHALLENGED
            - UNKNOWN

    Card:
      type: object
      properties:
        pan:
          type: string
          example: 12345678XXXX1234
          description: The masked account number of the paying card. If the transaction is token based, like ApplePay, this will instead contain the TAN (Token PAN).
        expireMonth:
          type: string
          example: "07"
          description: The month the card expires in. A card expires at the end of the month.
        expireYear:
          type: string
          example: "35"
          description: The year the card expires in.
        par:
          type: string
          nullable: true
          example: "8F1B7C2QX4Z9N3V6M2R0K8YD5LJTPH"
          description: The "Primary Account Reference" is a unique non-sensitive reference to the specific card. This will have the same value for any payment made with the same card even across wallets such as ApplePay. This can be used for loyalty systems or fraud prevention systems which needs to uniquely identify cards. The value is not always available. Availability depends on the used acquirer.
        Issuer:
          type: string
          nullable: true
          example: "Danske Bank"
          description: The name of the card issuer (Bank)
        Scheme:
          type: string
          nullable: true
          example: "Visa"
          description: The network scheme such as `Visa` and `Mastercard` of the card
        Country:
          type: string
          nullable: true
          example: "DK"
          description: The alpha-2 code of the country the card was issued in
        Segment:
          type: string
          nullable: true
          example: "consumer"
          description: The customer segment the card is issued to. This can be used to identify consumer vs business cards.
          enum:
            - consumer
            - business
            - payouts
        Funding:
          type: string
          nullable: true
          example: "debit"
          description: The type of funding behind payments made from the card. This can be used identify debit vs credit cards.
          enum:
            - debit
            - credit
            - prepaid

    AcquirerAgreement:
      type: object
      properties:
        acquirer:
          type: string
          example: "shift4"
          description: The name of the used acquirer / processor of the transaction
        mcc:
          type: string
          example: "4514"
          description: The merchant category code registered on the agreement. Note `4514` is the default code when none is registered or when not relevant.

    Transaction:
      type: object
      properties:
        id:
          type: string
          example: "LDG7M4WW44G"
          description: The ID of the transaction
        subscriptionId:
          type: string
          format: uuid
          nullable: true
          example: 0197c07b-3f6d-7be2-b848-702b08958128
          description: The ID of the associated subscription
        billingAgreementChargeId:
          type: string
          format: uuid
          nullable: true
          example: 019a727b-987f-7768-a59e-71af920ef81f
          description: The ID of any associated subscription billing charge. Will be null if the transaction was not an automatic charge made on a billing agreement.
        state:
          type: string
          description: The current state of the transaction. See our <a href="/get-started/core-concepts">Core Concepts</a> page.
          enum:
            - PENDING
            - PROCESSING
            - SUCCESS
            - FAILED
        errorCode:
          type: string
          nullable: true
          description: If the transaction has failed, this contains the associated error code explaining what went wrong.
        externalStatusCodes:
          type: object
          nullable: true
          description: A nullable object containing any known external status codes, such as the status code from the acquirer or the network. This can be useful for merchants who want to be able to react to very specific rejection reasons.
          properties:
            acquirer:
              type: string
              nullable: false
              description: The status code from the acquirer. The possible values depend on processing acquirer. The key is only present if the value is known to ePay.
            network:
              type: string
              nullable: false
              description: The status code from the scheme network. The field is only used for card based payments but stays consistent between acquirers. The key is only present if the value is known to ePay.
            sca:
              type: string
              nullable: false
              description: |
                A unified status code representing the result of the Strong Customer Authentication (SCA) flow, such as 3DS. 
                The code is built by concatenating the challenge status (`transStatus`) and reason code (`transStatusReason`) from the two steps of the 3DS protocol.

                | Code | Meaning                                          |
                |------|--------------------------------------------------|
                | C    | Transaction was challenged                       |
                | N    | Transaction was rejected                         |
                | Y    | Transaction was approved                         |
                | U    | Technical issues                                 |
                | I    | Informational Only (No authentication performed) |

                The reason code (`transStatusReason`) is appended if present, e.g., `07`.

                Examples:  
                - `Y` - Frictionless approval
                - `CY` - Challenged then approved
                - `CN07` - Challenged then rejected due to reason `07`
                - `N07` - Rejected without a challenge due to reason `07`
        createdAt:
          type: string
          format: date-time
          description: The time of creation
        sessionId:
          type: string
          nullable: true
          description: The ID of the associated session. This will be null for any MIT transactions.
        paymentMethodId:
          type: string
          format: uuid
          description: The ID of the associated payment method
        paymentMethodType:
          $ref: "#/components/schemas/PaymentMethodType"
        paymentMethodSubType:
          type: string
          description: The sub type of the associated payment method. For card based payments, this will contain the name of the scheme, such as `Visa` or `Mastercard`. The card scheme name formatted with a uppercase starting character. For non-card based payments the field vary depending on the requirements of the payment method.
        paymentMethodExpiry:
          type: string
          format: date
          description: |
            The expiration date of the associated payment method.  
            Although payment cards are specified by a month and year (MM/YY), this value is returned as a full date (YYYY-MM-DD) representing the **last day of the expiration month**.
            Example: `"2030-05-31"` for a card expiring in May 2030.
        paymentMethodDisplayText:
          type: string
          description: A cardholder friendly text to help them identify the payment method. For cards this will be a masked version of the card number.
        paymentMethodHolderName:
          type: string
          nullable: true
          description: Contains the entered cardholder name of the optional "name" field. Will be null if the field is not rendered.
        scaMode:
          type: string
          enum:
            - SKIP
            - NORMAL
            - FORCE
          description: The SCA mode of the transaction.
        customerId:
          type: string
          description: The merchant customer id of the transaction. This field is required to enable advanced features such as storing a card for later reuse. Do not use any "guest" customer ids. Customer ids must be unique for each customer and must be protected by authentication.
        amount:
          type: integer
          description: The transaction amount in minor units (e.g., 1095 = 10.95 DKK)
        fee:
          type: integer
          description: >
            The applied transaction fee in minor units. The fee is included in the `amount` field. To get the original amount you must subtract `fee` from `amount`. 
            Fees are only applied if surcharge is configured in the ePay backoffice.
            <br/><br/>
            Fees are calculated during transaction processing and as such is always 0 when initially created during MIT transactions.
        currency:
          type: string
          description: The currency of the transaction in ISO 4217 alpha-3. DKK for danish kroner.
        instantCapture:
          type: string
          description: The instant capture mode.
          enum:
            - OFF
            - VOID
            - NO_VOID
        notificationUrl:
          type: string
          description: The URL to receive webhook notifications of any transaction attempts. May contain templating variables.
          maxLength: 1024
          format: uri
        pointOfSaleId:
          type: string
          format: uuid
          description: The ID of the associated point of sale
        reference:
          type: string
          description: The merchant reference of the transaction, this is often used for the order id.
        textOnStatement:
          type: string
          minLength: 1
          maxLength: 39
          description: The text to show on the cardholder bank statement
        exemptions:
          type: array
          example: ["LVT", "TRA"]
          description: The list of exemptions to apply when possible. Note that exemptions may shift liability from the issuer to the merchant.
          items:
            type: string
        attributes:
          type: object
          description: A list of pass-through parameters that will be sent back to the merchant for following any webhooks
          additionalProperties: {}
        clientIp:
          example: "52.212.176.122"
          description: The ip (ipv4/ipv6) of the cardholder making the transaction. The IP is captured by ePay at the initialization of the transaction client-side. Can be empty.
          type: string
        clientCountry:
          example: "DK"
          description: |
            The detected origin country (Alpha-2) based on the `clientIp` property. Can be empty. 

            - Data derived from GeoLite2 by [MaxMind](https://www.maxmind.com).
          type: string
        type:
          description: The type of transaction.
          type: string
          enum:
            - PAYMENT
            - PAYOUT
            - MOTO

    ErrorCode:
      type: object
      properties:
        code:
          description: A textual error code explaining the error reason
          type: string
        message:
          description: A longer textual description of the error code and any contextual reasons for the failure. Only use the code to systematically detect reasons, as the message can be updated at any time.
          type: string

    OperationResponse:
      type: object
      properties:
        operationId:
          type: string
          format: uuid
          description: The ID of the associated operation
        success:
          type: boolean
          description: A boolean indicator for operation processing success.
        errorCode:
          $ref: "#/components/schemas/ErrorCode"
          nullable: true

    RefundResponse:
      type: object
      properties:
        success:
          type: boolean
          description: A boolean indicator for full refund success. If this is true, then the full amount was refunded. If it is false, it might have failed entirely or only partially.
        operations:
          type: array
          items:
            $ref: "#/components/schemas/OperationResponse"

    GetTransactionResponse:
      type: object
      properties:
        transaction:
          $ref: "#/components/schemas/Transaction"
        acquirerAgreement:
          $ref: "#/components/schemas/AcquirerAgreement"
        operations:
          type: array
          items:
            $ref: "#/components/schemas/Operation"

    Operation:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the operation
        referenceTransactionOperationId:
          type: string
          nullable: true
          format: uuid
          description: |
            The ID of another operation that this operation depends on.  
            For example, a `REFUND` must reference the `CAPTURE` it is refunding.  
            Other operation types may also reference a prior operation if required.
        amount:
          type: integer
          description: The operation amount in minor units (e.g., 1095 = 10.95 DKK)
        state:
          type: string
          description: |
            The state of the operation.  
            - `PROCESSING`: The operation has been received and is being handled.
            - `SUCCESS`: The operation completed successfully.
            - `FAILED`: The operation could not be completed. See `errorCode` for rejection reason.
          enum:
            - PROCESSING
            - SUCCESS
            - FAILED
        transactionId:
          type: string
          example: "LDG7M4WW44G"
          description: The ID of the associated transaction
        type:
          type: string
          description: |
            The type of operation.
            - `AUTHORIZATION`: Reserve funds on the payment method.
            - `CAPTURE`: Transfer previously authorized funds.
            - `SALE`: A combined operation that performs both `AUTHORIZATION` and `CAPTURE` in a single step.
            - `REFUND`: Return funds to the customer.
            - `VOID`: Releases previously authorized funds.
            - `PAYOUT`: Transfer funds to a recipient.

            `SALE` operations are only available for certain acquirers and will be used when available and instant capture is enabled.
          enum:
            - AUTHORIZATION
            - SALE
            - CAPTURE
            - REFUND
            - VOID
            - PAYOUT
        errorCode:
          type: string
          nullable: true
          description: When state is equal to `FAILED`, this will contain the explaining error code.
        createdAt:
          type: string
          format: date-time
          description: The time of creation
        finalizedAt:
          type: string
          nullable: true
          format: date-time
          description: |
            The timestamp when the operation reached a terminal state.  
            An operation is terminal once it transitions from `PROCESSING` to either `SUCCESS` or `FAILED`.

    TransactionsListResponse:
      type: object
      description: Cursor paginated transactions ordered from newest to oldest.
      required:
        - currentOffset
        - nextOffset
        - perPage
        - hasMore
        - items
      properties:
        currentOffset:
          type: string
          description: Cursor used to generate the current page. Empty when the first page is requested.
          example: ""
        nextOffset:
          type: string
          nullable: true
          description: Cursor to pass as `offset` when requesting the next page. Null when no more items exist.
          example: LDG7M4WW44G
        perPage:
          type: integer
          description: The maximum number of entries returned in each page.
          example: 25
        hasMore:
          type: boolean
          description: Indicates whether another page can be requested.
          example: false
        items:
          type: array
          description: The transactions returned for the current cursor window.
          items:
            type: object
            required:
              - transaction
            properties:
              transaction:
                $ref: "#/components/schemas/Transaction"

    SettlementAdjustment:
      type: object
      properties:
        type:
          type: string
          description: |
            The type of adjustment, this tells you reason for the adjust and who the money is paid to. 
            
            The types [`RESERVE`, `ADJUSTMENT`, `FEE`] is used for transfer adjustments.

            <ul>
              <li><b>RESERVE</b>: The amounts deducted and released from the merchant’s collateral</li>
              <li><b>FEE</b>: Fees charged for different services provided by the acquirer (e.g., wire transfer fee).</li>
              <li><b>ADJUSTMENT</b>: Amounts debited or credited to the merchant to adjust the merchant balance.</li>
            </ul>
            
            The types [`ACQUIRER_FEE`, `INTERCHANGE_FEE`, `SCHEME_FEE`] is used for transaction adjustments.
            
            <ul>
              <li><b>ACQUIRER_FEE</b>: Fees that is charged by and goes to the acquirer.</li>
              <li><b>INTERCHANGE_FEE</b>: Fees that goes to the issuing bank of the paying card.</li>
              <li><b>SCHEME_FEE</b>: Fees that goes to the scheme network such as Visa and Mastercard.</li>
            </ul>
          example: FEE
          enum:
            - RESERVE
            - ADJUSTMENT
            - FEE
            - ACQUIRER_FEE
            - INTERCHANGE_FEE
            - SCHEME_FEE
        amount:
          type: string
          description: Numeric string, negative for fees
          example: "-1.00"
        description:
          type: string
          description: Human-readable description
          example: "discount_rate"

    SettlementTransfer:
      description: Settlement transfers models the actual bank payouts from the acquirer to your bank.
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "019b3130-5d58-716d-8881-9a3ec506017f"
          description: The ePay ID of the settlement transfer
        acquirer:
          type: string
          description: Acquirer identifier
          example: shift4
        settlementName:
          type: string
          description: Name or filename of the settlement report as received by ePay. This is mainly used for logging and debugging purposes.
          example: "settlement.csv"
        settlementIds:
          type: array
          description: List of MIDs included in the settlement report.
          items:
            type: string
            example: ["R01234"]
        postingDate:
          type: string
          format: date
          example: "2025-01-01"
          description: The posting date of the transfer as registered by the acquirer
        netAmount:
          type: string
          description: Net amount (After adjustments and fees) as numeric string
          example: "99.01"
        currency:
          type: string
          description: ISO 4217 currency
          example: "DKK"
        acquirerReference:
          type: string
          description: Reference from acquirer
          example: "acq-123"
        adjustments:
          type: array
          items:
            $ref: "#/components/schemas/SettlementAdjustment"
        createdAt:
          type: string
          format: date-time
          example: "2025-12-18T11:20:11Z"

    SettlementTransaction:
      description: Settlement transactions gives pr. transaction insight into the fees paid to the acquirer, scheme and network.
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "019b3130-5d58-716d-8881-9a3ec506017f"
          description: The ID of the settlement transaction
        settlementTransferId:
          type: string
          format: uuid
          example: "019b3130-5d58-716d-8881-9a3ec506017f"
          description: The ID of the settlement transfer
        transactionId:
          type: string
          nullable: true
          description: The ID of the ePay transaction. Can be null if the data cannot be linked to an ePay transaction.
          example: "50947727185442134"
        agreementId:
          type: string
          example: "R01234"
          description: The acquirer MID this transaction was executed on
        merchantReference:
          type: string
          example: "ref-settlement-6"
          description: The merchant provided reference value
        acquirerReference:
          type: string
          example: "acq-tx-settlement-6"
          description: The acquirer provided reference value
        postingDate:
          type: string
          format: date
          example: "2025-01-01"
          description: The posting date of the transaction as registered by the acquirer
        settlementNetAmount:
          type: string
          example: "100.01"
          description: The net settlement amount after adjustments and fees.
        settlementCurrency:
          type: string
          description: The currency the transaction was settle in. This can be different than the original transaction amount, if your payments are settled in a single currency.
          example: "DKK"
        adjustments:
          type: array
          description: List of adjustments/fees applied to the transaction before the amount is paid out. This contains all the fees the acquirer, network and issuer has taken for processing your transaction. These fees are not related to nor charged by ePay.
          items:
            $ref: "#/components/schemas/SettlementAdjustment"
        createdAt:
          type: string
          format: date-time
          example: "2025-12-18T11:20:11Z"
          description: The creation time of the data at ePay.

    SettlementTransferCursor:
      type: object
      properties:
        currentOffset:
          type: string
          description: Cursor used to generate the current page. Empty when the first page is requested.
          example: ""
        nextOffset:
          type: string
          nullable: true
          description: Cursor to pass as `offset` when requesting the next page. Null when no more items exist.
          example: 019b3168-9334-770c-b34f-829d3c9c65d1
        perPage:
          type: integer
          description: The maximum number of entries returned in each page.
          example: 25
        hasMore:
          type: boolean
          description: Indicates whether another page can be requested.
          example: false
        items:
          type: array
          items:
            type: object
            properties:
              settlementTransfer:
                $ref: "#/components/schemas/SettlementTransfer"

    SettlementTransactionCursor:
      type: object
      properties:
        currentOffset:
          type: string
          description: Cursor used to generate the current page. Empty when the first page is requested.
          example: ""
        nextOffset:
          type: string
          nullable: true
          description: Cursor to pass as `offset` when requesting the next page. Null when no more items exist.
          example: 019b3168-9334-770c-b34f-829d3c9c65d1
        perPage:
          type: integer
          description: The maximum number of entries returned in each page.
          example: 25
        hasMore:
          type: boolean
          description: Indicates whether another page can be requested.
          example: false
        items:
          type: array
          items:
            type: object
            properties:
              settlementTransaction:
                $ref: "#/components/schemas/SettlementTransaction"
              transaction:
                oneOf:
                  - $ref: "#/components/schemas/Transaction"
                  - type: "null"

    TransactionOperationListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                $ref: "#/components/schemas/Operation"

    PaginatedResponse:
      type: object
      description: Generic paginated response
      properties:
        page:
          type: integer
          description: The current pagination page
        perPage:
          type: integer
          description: The requested number of entries per page
        lastPage:
          type: integer
          description: The last page with entries
        total:
          type: integer
          description: The total number of entries
        firstPageUrl:
          type: string
          description: URL for the first page
        lastPageUrl:
          type: string
          description: URL for the last page
        nextPageUrl:
          type: string
          nullable: true
          description: URL for the next page
        previousPageUrl:
          type: string
          nullable: true
          description: URL for the previous page
        nextPage:
          type: integer
          nullable: true
          description: The page number for the next page. Null if no next page.
        previousPage:
          type: integer
          nullable: true
          description: The page number for the previous page. Null if no previous page.
        from:
          type: integer
          description: The entry offset for the first entry in the page
        to:
          type: integer
          description: The entry offset for the last entry in the page
        path:
          type: string
          description: The path for the pagination endpoint
        items:
          type: array
          description: The page contents
          items: {} # Placeholder; will be overridden

    CreateBillingPlanRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 256
          description: Human-readable name of the billing plan.
        amount:
          type: integer
          minimum: 1
          description: Charge amount (in the smallest currency unit, e.g. cents).
        currency:
          type: string
          minLength: 3
          maxLength: 3
          pattern: '^[A-Z]{3}$'
          description: ISO 4217 alpha-3 currency code (e.g., USD, EUR).
        instantCapture:
          example: OFF
          default: OFF
          type: string
          nullable: true
          enum:
            - OFF
            - VOID
            - NO_VOID
          description: "The `InstantCapture` mode to use for all charges related to the plan.<ul><li> `OFF` indicates that the payment should not be captured instantly (Default).</li><li> `VOID` indicates that the payment should be captured instantly and if somehow the instant capture fails the payment is voided.</li><li> `NO_VOID` indicates that the payment should be captured instantly and if the capture fails the authorization is kept (no void is made)</li></ul>"
        maxAttempts:
          type: integer
          minimum: 1
          maximum: 31
          description: Maximum number of billing attempts before giving up.
        interval:
          $ref: "#/components/schemas/BillingInterval"
      required:
        - name
        - amount
        - currency
        - maxAttempts
        - interval

    BillingInterval:
      type: object
      description: The frequency between automatic charges. A `frequency=2` and `period=WEEK` means one charge every two weeks.
      properties:
        period:
          type: string
          example: "MONTH"
          enum:
            - DAY
            - WEEK
            - MONTH
            - YEAR
          description: The time unit of the frequency field
        frequency:
          type: integer
          example: 1
          minimum: 1
          maximum: 31
          description: The number of `period`'s between each charge.
      required:
        - period
        - frequency
    
    BillingPlan:
      type: object
      description: >
        Defines the configuration for recurring billing, including price, interval, and retry behavior.
        Used by Billing Agreements to determine how and when ePay processes scheduled charges.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the billing plan.
        name:
          type: string
          description: Human-readable name of the billing plan.
        amount:
          type: integer
          description: Charge amount for the plan (in the smallest currency unit, e.g. cents).
        currency:
          type: string
          minLength: 3
          maxLength: 3
          pattern: '^[A-Z]{3}$'
          description: ISO 4217 three-letter currency code (e.g., USD, EUR).
        maxAttempts:
          type: integer
          description: Maximum number of billing attempts allowed per billing period.
        interval:
          $ref: "#/components/schemas/BillingInterval"
          description: Defines the recurring billing interval.
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the billing plan was created.
      required:
        - id
        - name
        - amount
        - currency
        - maxAttempts
        - interval
        - createdAt

    BillingPlanResource:
      type: object
      description: Object containing the billing plan resource.
      properties:
        billingPlan:
          $ref: '#/components/schemas/BillingPlan'

    CreateBillingAgreementRequest:
      type: object
      properties:
        billingPlanId:
          type: string
          format: uuid
          description: Identifier for the associated billing plan.
        subscriptionId:
          type: string
          format: uuid
          example:
          description: Identifier for the related subscription. Subscription must be in `ACTIVE` state.
        reference:
          type: string
          nullable: true
          description: Optional reference string.
          example: agreement-1
        nextChargeAt:
          type: string
          format: date
          nullable: true
          example: 2030-07-29
          description: Date of the next scheduled charge. If none is given, the current date and interval from the plan is used to calculate the next charge date.
      required:
        - billingPlanId
        - subscriptionId

    BillingAgreement:
      type: object
      description: >
        Represents an automated, recurring payment agreement between a merchant and a cardholder.
        Links a Subscription to a Billing Plan so ePay can manage scheduled charges and track billing status.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the billing agreement.
          example: 019a729e-2d93-7612-9329-8f783f66f834
        billingPlanId:
          type: string
          format: uuid
          description: ID of the associated billing plan.
          example: 019a729e-41c2-7d16-a1e2-fdb15a8146bb
        subscriptionId:
          type: string
          format: uuid
          description: ID of the linked subscription.
          example: 019a729e-51ed-7426-b7c9-0e212b2d77d4
        sessionId:
          type: string
          format: uuid
          nullable: true
          description: Optional session identifier. Is only present when the billing agreement was made using a session.
          example: 019a729e-660a-7a05-90ad-5160ad0decc5
        customerId:
          type: string
          nullable: true
          description: Optional customer identifier.
          example: user-1
        nextChargeAt:
          type: string
          format: date-time
          nullable: true
          description: Date and time of the next charge, if scheduled. Will be null if the agreement is not in the `ACTIVE` state.
          example: 2030-08-29T15:51:28.071Z
        lastChargeAt:
          type: string
          format: date-time
          nullable: true
          description: Date and time of the last charge, if available.
          example: 2030-07-29T15:51:28.071Z
        desiredDate:
          type: integer
          nullable: true
          example: 30
          description: Preferred day of the month for charging. This is the day of the month ePay will attempt to target for monthly payments. This ensures a consistent billing date across months, which might otherwise vary depending on number of days in the month or leap years. Only available for monthly intervals.
        state:
          type: string
          description: Current state of the billing agreement.
          enum:
            - PENDING
            - ACTIVE
            - STOPPED
        stateChangedAt:
          type: string
          format: date-time
          description: Timestamp when the billing agreement last changed state.
          example: 2030-07-29T15:51:28.071Z
        reference:
          type: string
          nullable: true
          description: Optional reference string.
          example: agreement-1
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the billing agreement was created.
          example: 2030-07-29T15:51:28.071Z
      required:
        - id
        - billingPlanId
        - subscriptionId
        - state
        - stateChangedAt
        - createdAt

    BillingAgreementCharge:
      type: object
      description: >
        Represents a scheduled billing event created from a billing agreement. Tracks processing state, retry schedule, and any linked transactions.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the billing agreement charge.
          example: 019a72a0-4247-71c4-a4da-62b534d87af6
        state:
          type: string
          description: Current processing state of the charge.
          enum:
            - PROCESSING
            - FAILED
            - SUCCESS
          example: PROCESSING
        transactionId:
          type: string
          nullable: true
          description: Identifier of the successful transaction created for this charge, when available.
          example: LDG7M4WW44G
        billingPlanId:
          type: string
          format: uuid
          description: Identifier for the associated billing plan.
          example: 019a729e-41c2-7d16-a1e2-fdb15a8146bb
        billingAgreementId:
          type: string
          format: uuid
          description: Identifier for the billing agreement that produced this charge.
          example: 019a729e-2d93-7612-9329-8f783f66f834
        deadlineAt:
          type: string
          format: date-time
          nullable: true
          description: Deadline for completing the charge before it is marked as failed.
          example: 2030-09-05T12:00:00Z
        nextAttemptAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp of the next scheduled retry attempt, when additional retries are pending.
          example: 2030-08-01T12:00:00Z
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the billing agreement charge was created.
          example: 2030-07-29T15:51:28.071Z
      required:
        - id
        - state
        - billingPlanId
        - billingAgreementId
        - createdAt

    BillingAgreementResource:
      type: object
      description: Object containing the billing agreement details
      properties:
        billingAgreement:
          $ref: '#/components/schemas/BillingAgreement'

    ResumeBillingAgreementRequest:
      type: object
      description: Resumes the automatic charges for the billing agreement. It requires the associated subscription is still active.
      properties:
        nextChargeAt:
          type: string
          format: date
          example: 2030-07-29
          description: Date of the next scheduled charge.
      required:
        - nextChargeAt

    GetSubscriptionResponse:
      type: object
      properties:
        subscription:
          $ref: "#/components/schemas/Subscription"
        paymentMethod:
          $ref: "#/components/schemas/PaymentMethod"

    UpdateSubscriptionRequest:
      type: object
      required:
        - type
        - amount
        - expiryDate
      properties:
        amount:
          type: integer
          minimum: 1
          example: 9900
          description: The subscription charge amount in minor units (e.g., 1095 = 10.95 DKK). This is displayed in-app for payment methods such as Vipps MobilePay.
        type:
          type: string
          enum: [SCHEDULED, UNSCHEDULED]
          example: "SCHEDULED"
          description: The type of the subscription
        expiryDate:
          type: string
          format: date
          nullable: true
          example: "2035-07-23"
          description: The expiry date of the subscription. Do note that ePay does not enforce this expiration date, but it is used during processing of transactions.
        interval:
          type: object
          nullable: true
          description: "An optional subscription schedule for `SCHEDULED` type subscriptions. Must be omitted for `UNSCHEDULED` type subscriptions. Is required by some payment methods such as Vipps Mobilepay."
          properties:
            period:
              type: string
              example: MONTH
              enum: [DAY, WEEK, MONTH, YEAR]
            frequency:
              type: integer
              example: 1
              minimum: 1
              maximum: 31
          required:
            - period
            - frequency

    Subscription:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
          description: The ID of the subscription
        paymentMethodId:
          type: string
          format: uuid
          example: "01924756-d1f6-738d-8040-90d76cedf01f"
          description: The ID of the associated payment method
        currency:
          type: string
          pattern: ^[A-Z]{3}$
          example: "DKK"
          description: The currency of the original transaction which created the subscription. This is used as the default currency for new MIT transactions, if no currency is given.
        customerId:
          type: string
          example: "User159"
          description: The id of the merchant customer
        pointOfSaleId:
          type: string
          format: uuid
          example: "0192473a-e381-705c-b61c-fc2ac9624afc"
          description: The ID of the associated point of sale used during the creation of the subscription
        reference:
          type: string
          example: "reference-1"
          description: The merchant reference for the subscription.
        state:
          type: string
          example: "ACTIVE"
          description: The current state of the subscription. See our <a href="/get-started/core-concepts">Core Concepts</a> page.
          enum:
            - PENDING
            - ACTIVE
            - INVALID
            - DISABLED
        type:
          type: string
          example: "SCHEDULED"
          description: The type of subscription. `SCHEDULED` is used for fixed interval charges such as a monthly subscription fee. `UNSCHEDULED` is used for varying transaction intervals such as pay-as-you-go solutions such as parking or bike renting.
          enum:
            - SCHEDULED
            - UNSCHEDULED
        expiryDate:
          type: string
          format: date
          nullable: true
          example: "2050-01-01"
          description: The expiration date of the subscription. ePay does not enforce this expiration, but uses it in the processing of transactions which may improve approval rates.
        interval:
          type: object
          description: Interval configuration. It can only be present when type equal `SCHEDULED`. A `frequency=2` and `period=WEEK` means one charge for every two weeks.
          properties:
            period:
              type: string
              example: "MONTH"
              enum:
                - DAY
                - WEEK
                - MONTH
                - YEAR
              description: The time unit of the frequency field
            frequency:
              type: integer
              example: 1
              minimum: 1
              maximum: 31
              description: The number of `period`'s between each charge.
          required:
            - period
            - frequency
        createdAt:
          type: string
          format: date-time
          description: The time of creation

    PaymentMethod:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          description: The ID of the payment method
        type:
          $ref: "#/components/schemas/PaymentMethodType"
        subType:
          type: string
          example: "Visa"
          nullable: true
          description: The subtype of the payment method. For card based payments, this will contain the scheme of the card. Such as `Visa` or `Mastercard`
        customerId:
          type: string
          example: "User159"
          nullable: true
          description: The merchant customer id that created the payment method.
        expiry:
          type: string
          format: date
          nullable: true
          example: "2024-07-29"
          description: |
            The expiration date of the associated payment method.  
            Although payment cards are specified by a month and year (MM/YY), this value is returned as a full date (YYYY-MM-DD) representing the **last day of the expiration month**.
            Example: `"2030-05-31"` for a card expiring in May 2030.
        createdAt:
          type: string
          format: date-time
          description: The time of creation
          example: "2024-07-29T15:51:28.071Z"
        displayText:
          type: string
          description: A cardholder friendly text to help the customer identify the card. For card based payments, this will contain a masked version of the card number.
          example: "40000000XXXX0003"

    ImportedPaymentMethod:
      type: object
      description: Details about an imported payment method.
      required:
        - id
        - paymentMethodId
        - reference
        - createdAt
      properties:
        id:
          type: string
          description: Unique identifier of the imported payment method.
          example: "01929a94-5fce-7ccc-a7e4-7e9249133b38"
        paymentMethodId:
          type: string
          description: ID of the associated payment method.
          example: "01924756-d1f6-738d-8040-90d76cedf01f"
        reference:
          type: string
          description: External reference used when importing the payment method.
          example: "reference-1"
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the imported payment method was created.
          example: "2024-10-17T15:07:03.290909169+02:00"

    ImportedPaymentMethodResource:
      type: object
      required:
        - importedPaymentMethod
        - paymentMethod
      properties:
        card:
          nullable: true
          $ref: "#/components/schemas/Card"
        importedPaymentMethod:
          $ref: "#/components/schemas/ImportedPaymentMethod"
        paymentMethod:
          $ref: "#/components/schemas/PaymentMethod"

    ImportedPaymentMethodsListResponse:
      type: object
      description: Cursor paginated imported payment methods ordered from newest to oldest.
      required:
        - currentOffset
        - nextOffset
        - perPage
        - hasMore
        - items
      properties:
        currentOffset:
          type: string
          description: Cursor used to generate the current page. Empty when the first page is requested.
          example: "019afe0a-3987-75e5-9704-c3a1dc2b092b"
        nextOffset:
          type: string
          nullable: true
          description: Cursor to pass as `offset` when requesting the next page. Null when no more items exist.
          example: "01929a94-5fce-7ccc-a7e4-7e9249133b39"
        perPage:
          type: integer
          description: The maximum number of entries returned in each page.
          example: 25
        hasMore:
          type: boolean
          description: Indicates whether another page can be requested.
          example: true
        items:
          type: array
          description: Imported payment methods returned for the current cursor window.
          items:
            $ref: "#/components/schemas/ImportedPaymentMethodResource"

    SubscriptionsListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                type: object
                properties:
                  subscription:
                    $ref: "#/components/schemas/Subscription"
                  paymentMethod:
                    $ref: "#/components/schemas/PaymentMethod"

    BillingAgreementsListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                $ref: "#/components/schemas/BillingAgreementResource"

    BillingAgreementChargeResource:
      type: object
      description: Object containing the billing agreement charge resource.
      properties:
        billingAgreementCharge:
          $ref: '#/components/schemas/BillingAgreementCharge'

    BillingAgreementChargesListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                $ref: "#/components/schemas/BillingAgreementChargeResource"

    StoreWebhookRequest:
      type: object
      description: Payload for registering a webhook endpoint.
      properties:
        url:
          type: string
          format: uri
          description: HTTPS URL that will receive webhook notifications. Must match one of your approved point-of-sale domains.
        events:
          type: array
          minItems: 1
          description: List of webhook events to subscribe to. Duplicate values are rejected.
          items:
            type: string
            enum:
              - transaction.success.v1
              - transaction.failed.v1
              - subscription-billing.charge-created.v1
              - subscription-billing.charge-success.v1
              - subscription-billing.charge-failed.v1
              - subscription-billing.agreement-active.v1
              - subscription-billing.agreement-stopped.v1
              - settlement.transfer-ready.v1
        secret:
          type: string
          minLength: 1
          maxLength: 2048
          description: Shared secret used as the value of the `Authorization` header during webhook callback.
      required:
        - url
        - events
        - secret

    Webhook:
      type: object
      description: Webhook configuration returned by the API.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the webhook.
        url:
          type: string
          format: uri
          description: Destination URL configured for webhook delivery.
        events:
          type: array
          description: Events the webhook is subscribed to.
          items:
            type: string
            enum:
              - subscription-billing.charge-created.v1
              - subscription-billing.charge-failed.v1
              - subscription-billing.charge-success.v1
              - subscription-billing.agreement-active.v1
              - subscription-billing.agreement-stopped.v1
              - settlement.transfer-ready.v1
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the webhook was created.
      required:
        - id
        - url
        - events
        - createdAt

    WebhookResource:
      type: object
      description: Object containing the webhook resource.
      properties:
        webhook:
          $ref: '#/components/schemas/Webhook'

    WebhooksListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                $ref: "#/components/schemas/Webhook"

    EventWebhook:
      type: object
      description: |
        Envelope posted to your webhook URL when supported events fire. Used for `transaction.success.v1`, `transaction.failed.v1`, `subscription-billing.charge-created.v1`, `subscription-billing.charge-success.v1`, `subscription-billing.charge-failed.v1`, `subscription-billing.agreement-active.v1`, `subscription-billing.agreement-stopped.v1`, and `settlement.transfer-ready.v1`.
      properties:
        event:
          type: string
          description: Identifier of the event that triggered the webhook.
          enum:
            - transaction.success.v1
            - transaction.failed.v1
            - subscription-billing.charge-created.v1
            - subscription-billing.charge-success.v1
            - subscription-billing.charge-failed.v1
            - subscription-billing.agreement-active.v1
            - subscription-billing.agreement-stopped.v1
            - settlement.transfer-ready.v1
        data:
          description: Event-specific payload.
          oneOf:
            - $ref: "#/components/schemas/TransactionEventData"
            - $ref: "#/components/schemas/BillingAgreementChargeEventData"
            - $ref: "#/components/schemas/BillingAgreementEventData"
            - $ref: "#/components/schemas/SettlementTransferEventData"
      required:
        - event
        - data

    TransactionEventData:
      type: object
      description: Payload delivered for `transaction.success.v1` and `transaction.failed.v1` webhooks.
      properties:
        transaction:
          $ref: "#/components/schemas/Transaction"
      required:
        - transaction

    BillingAgreementChargeEventData:
      type: object
      description: Payload delivered for `subscription-billing.charge-created.v1`, `subscription-billing.charge-success.v1`, and `subscription-billing.charge-failed.v1` webhooks.
      properties:
        billingAgreementCharge:
          $ref: "#/components/schemas/BillingAgreementCharge"
      required:
        - billingAgreementCharge

    BillingAgreementEventData:
      type: object
      description: Payload delivered for `subscription-billing.agreement-active.v1` and `subscription-billing.agreement-stopped.v1` webhooks.
      properties:
        billingAgreement:
          $ref: "#/components/schemas/BillingAgreement"
      required:
        - billingAgreement

    SettlementTransferEventData:
      type: object
      description: Payload delivered for `settlement.transfer-ready.v1` webhooks.
      properties:
        settlementTransfer:
          $ref: "#/components/schemas/SettlementTransfer"
      required:
        - settlementTransfer

    BillingPlansListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                $ref: "#/components/schemas/BillingPlanResource"

    PaymentSessionInitializationRequest:
      type: object
      allOf:
        - $ref: "#/components/schemas/MotoTransactionData"
        - type: object
          properties:
            transactionType:
              description: |
                The type of transaction to process. Most merchants should use `PAYMENT` unless they have specific use cases.
    
                - `PAYMENT` is for ordinary purchases and the standard type to use for most merchants.
                - `MOTO` is short for Mail Order & Telephone Order and is typically used by travel agencies who receive payment info over the phone or email. MOTO is exempt from SCA but requires a special acquirer agreement to use.
              type: string
              nullable: true
              default: "PAYMENT"
              enum:
                - PAYMENT
                - MOTO
            scaMode:
              example: "NORMAL"
              nullable: true
              type: string
              enum:
                - SKIP
                - NORMAL
                - FORCE
              description: "How 3D secure is handled:<br/><ul><li>`SKIP` 3DS is not tried and full liability is put at merchant.</li><li>`NORMAL` 3DS flow is attempted as normal guidelines suggests - Both challenge and frictionless can occur.</li><li>`FORCE` A challenge flow is forced. Note: Third parties in the 3DS flow might ignore this instruction.</li></ul>"
            timeout:
              example: 120
              nullable: true
              type: integer
              minimum: 1
              maximum: 120
              description: "The session is valid for the specified number of minutes. If a timeout occurs, the session expires and no more payment attempts are possible."
            exemptions:
              example: []
              type: array
              nullable: true
              items:
                type: string
                enum:
                  - TRA
                  - LVT
              description: "List of exemptions to apply when applicable. Supports [`TRA`, `LVT`]. Note: Using exemptions may shift liability for fraud from the issuer to the merchant."
            maxAttempts:
              example: 25
              type: integer
              nullable: true
              minimum: 1
              maximum: 25
              description: "The maximum allowed number of payment attempts for the session."
            reportFailure:
              example: false
              nullable: true
              type: boolean
              description: "If true: Enables webhooks to the `notificationUrl` for failed transactions. Otherwise only successful transactions are reported."
            reportExpired:
              type: boolean
              default: false
              description: "If true: Enables webhooks to the `notificationUrl` for sessions that reach the expired state."
            dynamicAmount:
              example: false
              nullable: true
              type: boolean
              description: "If true: Enables the cardholder to define the transaction amount. Otherwise, the amount from the session is used for transactions. Can be used in conjunction with pre-auth webhooks to reject transactions with unacceptable amounts. **NOTE: This gives client side control over the payment amount. Only use if necessary.**. Must be enabled by ePay support."
            notificationUrl:
              example: "https://example.com/notification"
              nullable: true
              maxLength: 1024
              minLength: 1
              type: string
              format: uri
              description: |
                The URL to where ePay notifies about payment statuses. Max length is `1024`. 
                
                <div class="theme-admonition theme-admonition-info alert alert--info">
                  <p style="margin-bottom:8px;">All URL properties support dynamic templating with session and transaction data, allowing merchants to define URLs that include ePay-generated resource ID's.</p>
                
                  <p style="margin-bottom:8px;">This feature can be particularly helpful for some merchants, especially with success and failure URLs, as it simplifies fetching order information upon transaction completion.</p>
                
                  <p style="margin-bottom:8px;">Unknown template keys will be rejected during request validation.</p>
                
                  - `${transaction.id}`: The primary id of the associated transaction.
                  - `${transaction.reference}`: The merchant supplied reference from session init.
                  - `${session.id}`: The primary id of the associated session.
                  - `${subscription.id}`: The primary id of the associated subscription.
                </div>
            preAuthUrl:
              example: "https://example.com/preAuth"
              maxLength: 1024
              minLength: 1
              nullable: true
              type: string
              format: uri
              description: "If not null then pre-authorization webhook are enabled for all transaction attempts for the session. Max length is `1024`."
            returnUrl:
              example: "https://example.com/success"
              nullable: true
              maxLength: 1024
              minLength: 1
              type: string
              format: uri
              description: |
                The URL to where the browser is returned, when clicking the `back` button in the Payment Window. This overrides the default defined in the payment window configuration and supports url templating. Max length is `1024`.
                
                <div class="theme-admonition theme-admonition-info alert alert--info">
                  Only used in Payment Window integrations.
                </div>
            successUrl:
              example: "https://example.com/success"
              nullable: true
              maxLength: 1024
              minLength: 1
              type: string
              format: uri
              description: "The URL the client is redirected to on a successful payment. Max length is `1024`."
            failureUrl:
              example: "https://example.com/failure"
              nullable: true
              maxLength: 1024
              minLength: 1
              type: string
              format: uri
              description: "The URL the client is redirected to when no more payment attempts are allowed. Max length is `1024`."
            retryUrl:
              example: "https://example.com/retry"
              nullable: true
              maxLength: 1024
              minLength: 1
              type: string
              format: uri
              description: "An optional URL the client is redirected to when a payment attempt fails but more attempts are still allowed. If the retryUrl is not provided then the client will be redirected to the failureUrl. Max length is `1024`."
            ageVerification:
              type: object
              description: "Specifies age verification requirements for the purchase.\n - If not provided or set to null, no age verification will be performed.\n - If provided, the customer must verify their age to be at least the value specified in the `minimumAge` property.\nFor danish customers this id verified using MitID. Session.minimumAge will be set; transactions may be rejected if age not verified."
              properties:
                minimumAge:
                  type: integer
                  minimum: 0
                  maximum: 99
                country:
                  type: string
                  enum:
                    - DK
                  description: "Country code for the delivery country (ISO 3166 alpha-2 country codes). This code determines which electronic ID (eID) is presented to the user (e.g., MitID in Denmark)."
              required:
                - minimumAge

    CreateMotoTransactionRequest:
      type: object
      properties:
        transaction:
          type: object
          $ref: "#/components/schemas/MotoTransactionData"
        paymentMethod:
          type: object
          properties:
            card:
              type: object
              properties:
                cardNumber:
                  type: string
                  example: 1234567812345678
                  maxLength: 19
                  minLength: 15
                  description: The primary account number (PAN) of the card to charge. Must be Luhn compliant.
                expiryMonth:
                  type: string
                  maxLength: 2
                  minLength: 2
                  example: "07"
                  description: The month part of the expiry of the card to charge.
                expiryYear:
                  type: string
                  example: "35"
                  maxLength: 2
                  minLength: 2
                  description: The year part of the expiry of the card to charge.
                securityCode:
                  type: string
                  example: "123"
                  minLength: 2
                  maxLength: 3
                  description: The CVV / CVC of the card to charge
                brand:
                  type: string
                  nullable: true
                  example: "Visa"
                  description: An optional parameter that can be used to choose which brand of a cobranded card to charge. Such as when payment with a VisaDankort card. Otherwise leave blank.
              required:
                - cardNumber
                - expiryMonth
                - expiryYear
                - securityCode

    MotoTransactionData:
      type: object
      properties:
        pointOfSaleId:
          example: "01924737-9c18-71c0-ab1a-88698eaceabf"
          type: string
          format: uuid
          description: "Id of the point of sale to associate the payment with."
        reference:
          type: string
          example: "reference-1"
          nullable: true
          minLength: 1
          maxLength: 36
          pattern: "^[A-Za-z0-9-]{1,36}$"
          description: |
            This is the transaction reference, similar to an order ID.  
            The reference **SHOULD** be unique for each payment, as some acquirers enforce per-payment uniqueness.  
            Using a duplicate reference may result in failed payments or make reconciliation difficult.  
            Only ASCII alphanumeric characters and dashes are allowed.

            **Worldline specific**: `-` is removed if present and if the value is longer than 12 position, the left most part is used.
        amount:
          example: 100
          type: integer
          description: "The amount must be defined in minor units. E.g. 2,50 DKK must be set as 250. If amount is set to 0 a token will be created only and returned to the integrator."
        currency:
          pattern: ^[A-Z]{3}$
          example: "DKK"
          type: string
          description: "The currency code of the payment. For Danish Kroner defined as DKK. ISO 4217 alpha-3 (e.g., DKK)"
        instantCapture:
          example: OFF
          type: string
          nullable: true
          enum:
            - OFF
            - VOID
            - NO_VOID
          description: "If the payment should be captured instantly or not.<ul><li> `OFF` indicates that the payment should not be captured instantly.</li><li> `VOID` indicates that the payment should be captured instantly and if somehow the instant capture fails the payment is voided.</li><li> `NO_VOID` indicates that the payment should be captured instantly and if the capture fails the authorization is kept (no void is made)</li></ul>"
        processor:
          type: array
          deprecated: true
          example: ["shift4"]
          nullable: true
          items:
            $ref: "#/components/schemas/Processor"
          description: |
            **DEPRECATED:** *This parameter will soon be removed and will no longer have any effect. The functionality has been replaced by routing rules in the ePay back office.*
            
            List of processors to use. This is the routing of the payment. 
            The value can be `shift4`, `clearhaus` and `nets`.<br/><br/>Processor priority follows the order in the list. 
            If the first processor fails or declines, the next processor in the list will be attempted, and so on until all processors have been tried. 
            Note that the actual processing order is not guaranteed and may depend on external factors, such as the specific payment card used by the cardholder.
        textOnStatement:
          example: "order 123"
          nullable: true
          type: string
          minLength: 1
          maxLength: 39
          description: 'This is the text set on the transaction in the bank viewed by the card holder. That can be e.g. "order 123". Defaults to the ePay transaction id. Some providers does not support long texts, ePay will automatically cut the text to fit the providers requirements.'
        attributes:
          type: object
          nullable: true
          additionalProperties: {}
          description: "A list of pass through attributes that is sent back to the merchant on webhooks. Max size is 1kb."
        customerId:
          example: "User159"
          nullable: true
          type: string
          description: "An optional merchant defined customer id used to uniquely identify a user in the merchant system. This field is required to enable stored payment methods and enhanced age verification."
        customer:
          type: object
          description: "Customer info. These data points are used during SCA/3DS and is required for some schemes. These data may also be sent to the specific payment provider, if required to complete the payment such as Klarna. It is recommended to send all the info that is available to improve the approval rate."
          properties:
            firstName:
              type: string
              description: The first name of the paying customer.
              minLength: 1
              nullable: true
              example: Peter
            lastName:
              type: string
              description: The last name of the paying customer.
              minLength: 1
              nullable: true
              example: Nielsen
            birthdate:
              type: string
              format: date
              description: The date of birth of the cardholder in YYYY-MM-DD format.
              nullable: true
              example: 2000-07-25
            email:
              type: string
              nullable: true
              example: email@example.com
              minLength: 1
              description: The email of the paying customer.
            phoneNumber:
              type: string
              nullable: true
              example: +45 12345678
              description: >
                E.164 phone number format with a single space between country code and local number. No additional spaces allowed.
                <br><br>
                Format: "+[countryCode] [number]".
              pattern: "^\\+\\d{1,3} \\d+$"
            shippingAddress:
              type: object
              nullable: true
              description: "The shipping address of the purchase. If no wares are shipped, leave this empty. If billing and shipping address is the same, then fill both properties with identical information."
              allOf:
                - $ref: "#/components/schemas/AddressInfo"
            billingAddress:
              type: object
              nullable: true
              description: "The billing address of the customer. Often the personal address of the customer or the business address of paying company. If billing and shipping address is the same, then fill both properties with identical information."
              allOf:
                - $ref: "#/components/schemas/AddressInfo"
        preAuthUrl:
          example: "https://example.com/preAuth"
          maxLength: 1024
          minLength: 1
          nullable: true
          type: string
          format: uri
          description: "If not null then pre-authorization webhook are enabled for all transaction attempts for the session. Max length is `1024`."
        orderLines:
          type: array
          nullable: true
          description: The array containing list of line items that are part of this order. Maximum of 1000 line items could be processed in a single order. This is used by some payment methods, such as Klarna.
          maxItems: 1000
          items:
            type: object
            properties:
              description:
                type: string
                description: Descriptive name of the order line item.
                example: Running shoe
                maxLength: 255
                minLength: 1
              imageUrl:
                type: string
                format: url
                nullable: true
                maxLength: 1024
                minLength: 1
                description: URL to an image that can be later embedded in communications between Klarna and the customer. (max 1024 characters). A minimum of 250x250 px resolution is recommended for the image to look good. We recommend using a good sized image (650x650 px or more), however the file size must not exceed 12MB.
              quantity:
                type: integer
                example: 2
                minimum: 0
                description: Quantity of the order line item. Must be a non-negative number.
              totalAmount:
                type: integer
                example: 20000
                maximum: 200000000
                minimum: 0
                description: Total amount of the order line. Must be defined as minor units. Includes tax and discount.
              unitPrice:
                type: integer
                description: Price for a single unit of the order line. Must be defined as minor units and exclude any discount. Typically including taxes, however some countries may include specific requirements.
                maximum: 200000000
                example: 10000
              type:
                type: string
                description: Type of the order line item.
                enum:
                  - PHYSICAL
                  - DISCOUNT
                  - SHIPPING_FEE
                  - SALES_TAX
                  - DIGITAL
                  - GIFT_CARD
                  - STORE_CREDIT
                  - SURCHARGE
                  - OTHER
            required:
              - description
              - quantity
              - totalAmount
              - unitPrice
              - type
        subscription:
          type: object
          description: |
            **Note `scaMode` is always set to `FORCE` when initializing a subscription due to EU PSD2 regulations.**
            <br><br>
            To create a subscription, allowing you to process MIT transactions in the future, you must send the subscription object. To process MIT transactions you must ensure your acquirer agreement has recurring payments enabled.
          properties:
            id:
              type: string
              format: uuid
              description: "An optional subscription ID can be used to update an existing active subscription with new payment details, such as a new card or a completely different payment method."
            amount:
              type: integer
              description: "An optional amount in minor units (e.g., 1095 = 10.95 DKK) that can be used to differentiate the recurring subscription amount from the current transaction amount. This is useful if customers are not expected to pay today, but must pay a monthly fee going forward - In this case set amount=0 and subscription.amount=XXX. Defaults to the transaction amount if not given."
            type:
              example: "SCHEDULED"
              type: string
              enum:
                - UNSCHEDULED
                - SCHEDULED
              description: "The type of subscription. <br/><br/><ul><li>`UNSCHEDULED` Pay-as-you-go type subscriptions with no fixed interval for charges.</li><li>`SCHEDULED` Fixed interval charges like a subscription paid monthly.</li></ul>"
            reference:
              example: "subscription-1"
              type: string
              description: "An optional merchant defined reference for the subscription. If none is given, then the session reference will be used as a fallback."
            expiryDate:
              type: string
              format: date
              description: "An optional field indicating the expiry of the subscription. This date is used during 3DS, and may improve conversion rates. ePay does not reject payments after this date."
            interval:
              type: object
              description: "An optional subscription schedule for `SCHEDULED` type subscriptions. Must be omitted for `UNSCHEDULED` type subscriptions. Is required by some payment methods such as Vipps Mobilepay. Is used during 3DS - May improve conversion rates."
              properties:
                period:
                  type: string
                  enum:
                    - DAY
                    - WEEK
                    - MONTH
                    - YEAR
                  description: "The period unit between charges"
                frequency:
                  type: integer
                  description: "The number of period units between each charge. `1-31`. Example: `Frequency: 3, Period: DAY` One charge every 3 days."
              required:
                - period
                - frequency
            billingAgreement:
              type: object
              description: "An optional property. When given a automatic scheduled billing agreement will be created. This can be used to sign up customers to automatic subscription billing, such as monthly payments. This field is mutually exclusive with subscription.id and subscription.interval"
              nullable: true
              properties:
                billingPlanId:
                  type: string
                  format: uuid
                  description: The id of the billing plan to use for the agreement. The billing plan contains the price and interval used during automatic charging.
                  example: 019a7266-2f3a-7b26-9c93-b950aea9e13c
                reference:
                  type: string
                  nullable: true
                  description: An optional reference to be added to the created billing agreement. If not set, the one from the subscription will be used.
                  example: agreement-1
                nextChargeAt:
                  type: string
                  format: date
                  nullable: true
                  example: 2030-07-22
                  description: Which date to create the first automatic charge. If left blank the current date plus the plan interval will be used to calculate the next charge. This can be used for introductory campaigns where the first period is free followed by monthly charges.
              required:
                - billingPlanId
          required:
            - type
      required:
        - pointOfSaleId
        - amount
        - currency

    AddressInfo:
      type: object
      description: |
        Standardized representation of a postal address.  
        The object supports international formats while enforcing consistent field lengths and validation rules.  

        - `countryCode` must follow the ISO 3166-1 alpha-2 standard (e.g., `"DK"`).  
        - `postalCode` and `city` capture the locality information.  
        - `line1` is required for meaningful addresses; `line2` and `line3` are optional extensions and should only be used if the address naturally contains multiple lines, always in order (line1 → line2 → line3).  
        - All fields are nullable, allowing partial addresses where only some information is known.
      properties:
        countryCode:
          type: string
          description: ISO 3166-1 alpha-2 country code
          minLength: 2
          maxLength: 2
          nullable: true
          example: "DK"
        postalCode:
          type: string
          description: The local postal code of the address
          example: "1400"
          minLength: 1
          maxLength: 16
          nullable: true
        city:
          type: string
          description: The city
          example: "København"
          minLength: 1
          maxLength: 50
          nullable: true
        line1:
          type: string
          description: "The first address line. Most address only has a singular line."
          example: Torvegade 45
          minLength: 1
          maxLength: 50
          nullable: true
        line2:
          type: string
          description: Second address line. Only use if address contains multiple lines. Always start with line1.
          example: "2. th."
          minLength: 1
          maxLength: 50
          nullable: true
        line3:
          type: string
          description: Third address line. Only use if address contains multiple lines. Always start with line1 and line2.
          example: "Christianshavn"
          minLength: 1
          maxLength: 50
          nullable: true

    PaymentSessionInitializationResponse:
      type: object
      properties:
        paymentWindowUrl:
          type: string
          format: uri
          description: URL for ePay Checkout. If you are using Checkout and not Blocks, then you must redirect the customer to this URL.
        javascript:
          type: string
          format: uri
          description: For merchants implementing Blocks, load this script to use the ePay.js client
        key:
          type: string
          description: For merchants implementing Blocks, this is the client secret used to allow the ePay.js client to interact with the payment session
        session:
          $ref: "#/components/schemas/Session"

    Session:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the payment session
        subscriptionId:
          type: string
          format: uuid
          nullable: true
          description: The subscription id related to the session, this can either be a new ID for new subscriptions or the given ID of a previous subscription which needs to be updated.
        amount:
          type: integer
          description: The transaction amount in minor units (e.g., 1095 = 10.95 DKK)
        attributes:
          type: object
          nullable: true
          description: Pass-through data which will be returned back to the merchant in any webhook.
          additionalProperties: {}
        exemptions:
          type: array
          description: List of exemptions to apply when available. Note exemptions may cause liability shift from the issuer to the merchant.
          items:
            type: string
        currency:
          pattern: ^[A-Z]{3}$
          type: string
          description: The currency of the payment. For Danish Kroner defined as DKK.
        expiresAt:
          type: string
          format: date-time
          description: The expiration time of the payment session. After this time the session can no longer be used and a new session must be created.
        instantCapture:
          type: string
          description: The instant capture mode.
          enum:
            - OFF
            - VOID
            - NO_VOID
        maxAttempts:
          type: integer
          description: The maximum number of transaction attempts allowed for the session
        attempts:
          type: integer
          description: The current number of transaction attempts so far.
        minimumAge:
          type: integer
          description: The minimum age required. If not null and ePay Verify is enabled on your account, the cardholder will be prompted to verify their age using local online IDs such as MitID in Denmark.
        ageVerified:
          type: boolean
          description: Is true once the customers age has been verified to be at least equal to `minimumAge` parameter.
        reportFailure:
          type: boolean
          description: Boolean flag to enable / disable receiving webhook notifications for failed transactions.
        reportExpired:
          type: boolean
          description: Boolean flag to enable / disable receiving webhook notifications for sessions that reach the expired state.
        dynamicAmount:
          type: boolean
          description: Boolean flag to enable / disable dynamic amounts, allowing the client to determine the transaction amount. This is generally not recommended for most merchants.
        notificationUrl:
          type: string
          format: uri
          description: The URL to receive webhooks related to transaction attempts
        preAuthUrl:
          type: string
          nullable: true
          format: uri
          description: Optional URL to receive a webhook just before authorization is attempted. Can be used to update or reject the transaction. This is often used by merchants integrating external risk tooling to trigger 3DS challenges depending on the payment.
        successUrl:
          type: string
          format: uri
          description: The URL to redirect the client on successful payment attempts
        returnUrl:
          nullable: true
          maxLength: 1024
          minLength: 1
          type: string
          format: uri
          description: |
            The URL to where the browser is returned, when clicking the `back` button in the Payment Window. This overrides the default defined in the payment window configuration and supports url templating. Max length is `1024`.
            
            <div class="theme-admonition theme-admonition-info alert alert--info">
              Only used in Payment Window integrations.
            </div>
        failureUrl:
          type: string
          format: uri
          description: The URL to redirect the client on failed payment attempts when no more attempts are possible.
        retryUrl:
          type: string
          nullable: true
          format: uri
          description: The URL to redirect the client on failed payment attempts when more attempts are possible. If null, then failureUrl is used instead.
        customerId:
          type: string
          nullable: true
          description: The ID of the cardholder. This field is required to enable stored cards. Do not use any "guest" customer ids. Customer ids must be unique for each customer and secured behind authentication.
        pointOfSaleId:
          type: string
          format: uuid
          description: The ID of the associated point of sale
        reference:
          type: string
          nullable: true
          description: The transaction reference - Typically the order id.
        state:
          type: string
          description: The state of the transaction
          enum:
            - PENDING
            - PROCESSING
            - COMPLETED
            - EXPIRED
        textOnStatement:
          type: string
          minLength: 1
          maxLength: 39
          description: The text to display on the cardholders bank statement
        scaMode:
          type: string
          enum:
            - SKIP
            - NORMAL
            - FORCE
          description: The chosen SCA mode. This can be used to control the level of cardholder authentication performed before the transaction is authorized.
        timeout:
          type: integer
          description: The number of minutes the session is available.
        createdAt:
          type: string
          format: date-time
          description: The time of creation

    StorePointOfSaleRequest:
      type: object
      required:
        - name
        - domain
        - webhookAuthentication
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: >
            The name to display in the ePay backoffice. 
            If you are creating a point of sale as a partner it is recommended to name the point of sale after yourself.

            As an example if your company name is "Wordpress IT Solutions" then use the same name for the point of sale. This helps both the merchant and the ePay staff when providing support.
        domain:
          type: string
          maxLength: 1024
          description: >
            Must be a valid URL or domain. Use the top level domain and not a sub-domain, even if the payment occurs on a subdomain.
            If you are providing an iframe payment solution, then you must provide the domain of the iframe and not the browser visiting domain.
            <br/>
            If you need more than one domain whitelisted, then contact ePay support.
        webhookAuthentication:
          type: string
          minLength: 1
          maxLength: 255
          description: >
            The full `Authorization` header value sent for any notifications / webhooks. Remember to include the Authorization scheme such as `Bearer` or `Basic`. 
            The authorization cannot later be updated using the API, it can only be changed and fetched from the ePay backoffice.
            Example: `Bearer super-secret-token`.
            <br/><br/>
            If you are a partner <strong>DO NOT</strong> use the same authentication for multiple merchants as this poses a security risk.
      example:
        name: "Store #42"
        domain: "example.com"
        webhookAuthentication: "Bearer super-secret-token"

    DetailedPointOfSale:
      type: object
      properties:
        pointOfSale:
          $ref: "#/components/schemas/PointOfSale"
        hostedConfiguration:
          $ref: "#/components/schemas/HostedConfiguration"

    PointOfSale:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the point of sale. This is used when creating new payment session.
        name:
          type: string
          description: A visual name displayed in the ePay backoffice to help the merchant and ePay staff identify the point of sale
        descriptor:
          type: string
          description: The merchant name displayed to the cardholder in both their bank statement and any 3DS challenge such as MitID.
        createdAt:
          type: string
          format: date-time
          description: The time of creation in UTC.
        updatedAt:
          type: string
          format: date-time
          description: The last time the point of sale was modified in UTC
      required:
        - id
        - name
        - descriptor
        - createdAt
        - updatedAt
      example:
        id: "0192473a-e381-705c-b61c-fc2ac9624afc"
        name: "Store #42"
        descriptor: "POS Copenhagen"
        createdAt: "2024-10-01T10:38:14.658688472+02:00"
        updatedAt: "2024-10-01T12:38:14.658688472+02:00"

    HostedConfiguration:
      type: object
      description: The hosted configuration acts as the default values for most of the session initialization parameters. If fields such as `maxAttempts` is not defined within the `/cit` call, the value will be fetched from the hosted configuration instead.
      properties:
        instantCapture:
          type: string
          description: "If the payment should be captured instantly or not.<ul><li> `OFF` indicates that the payment should not be captured instantly.</li><li> `VOID` indicates that the payment should be captured instantly and if somehow the instant capture fails the payment is voided.</li><li> `NO_VOID` indicates that the payment should be captured instantly and if the capture fails the authorization is kept (no void is made)</li></ul>"
        scaMode:
          enum:
            - SKIP
            - NORMAL
            - FORCE
          type: string
          description: "How 3D secure is handled:<br/><ul><li>`SKIP` 3DS is not tried and full liability is put at merchant.</li><li>`NORMAL` 3DS flow is attempted as normal guidelines suggests - Both challenge and frictionless can occur.</li><li>`FORCE` A challenge flow is forced. Note: Third parties in the 3DS flow might ignore this instruction.</li></ul>"
        timeout:
          type: integer
          description: How many minutes sessions stays active.
        notificationUrl:
          type: string
          format: uri
          description: The URL to receive webhook notifications for any attempted transactions
        successUrl:
          type: string
          format: uri
          description: The URL the client is redirected to on successful payments
        failureUrl:
          type: string
          format: uri
          description: The URL the client is redirected to when no more payment attempts is possible for the current session.
        retryUrl:
          type: string
          format: uri
          nullable: true
          description: The URL the client is redirected to on failed payments while there is still more attempts available. If null, then failureUrl is used as a fallback.
        maxAttempts:
          type: integer
          description: The maximum number of transaction attempts allowed for the payment session
        processor:
          type: array
          deprecated: true
          items:
            $ref: "#/components/schemas/Processor"
          description: |
            **DEPRECATED:** *This parameter will soon be removed and will no longer have any effect. The functionality has been replaced by routing rules in the ePay back office.*
            
            List of processors to use. This is the routing of the payment. The value can be `shift4`, `clearhaus` and `nets`.<br/><br/>The priority of the processors is made on the order. That means that if the first processor fails / declines then the next in the list will be used and so on until all processors in the list have been tried. The order is not guaranteed as it depends on external factors such as the specific payment card used by the cardholder.
        exemptions:
          type: array
          items:
            type: string
            enum:
              - TRA
              - LVT
          description: List of exemptions to apply when possible. Note exemptions shifts liability from the issuer to the merchant.
        reportFailure:
          type: boolean
          description: If true, the notificationUrl will also receive webhooks for failed transactions. Otherwise, only successful transactions is notified.
        reportExpired:
          type: boolean
          description: Boolean flag to enable / disable receiving webhook notifications for sessions that reach the expired state.
      required:
        - instantCapture
        - scaMode
        - timeout
        - notificationUrl
        - successUrl
        - failureUrl
        - maxAttempts
        - processor
        - exemptions
        - reportFailure
      example:
        instantCapture: "OFF"
        scaMode: "SKIP"
        timeout: 60
        notificationUrl: "https://example.com/notification"
        successUrl: "https://example.com/success"
        failureUrl: "https://example.com/failure"
        retryUrl: null
        maxAttempts: 10
        processor: ["shift4", "nets"]
        exemptions: ["TRA", "LVT"]
        reportFailure: false

    PointOfSaleListResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - type: object
          properties:
            items:
              type: array
              description: The page contents
              items:
                $ref: "#/components/schemas/DetailedPointOfSale"

    CreatePaymentLinkRequest:
      allOf:
        - $ref: "#/components/schemas/PaymentSessionInitializationRequest"

    CreatePaymentLinkResponse:
      type: object
      properties:
        id:
          type: string
          description: The ID of the payment link resource
        sessionId:
          type: string
          format: uuid
          description: The ID of the underlying payment session
        url:
          type: string
          format: uri
          description: The URL to redirect the customer to complete the payment
        qrCode:
          type: string
          description: QR code version of the `url` in base64, which can be displayed for quick device-to-device link sharing such as from a POS device where the customer can scan the code and complete the payment on their own phone.
