> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowlix.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a hosted payment page payment

> Creates a hosted payment page payment attempt. Redirect the customer to
`next_action.redirect_url` to complete the `next_action.reason`
customer action. The required-action URL is opaque and may later change
from the hosted page to a 3D Secure browser action. Use the latest
`next_action.redirect_url` from `GET /v1/payments/{id}`, and avoid
redirect loops when the URL is unchanged.

`billing_details` is required for HPP and is used to prefill the hosted
page. If the customer edits the billing details on the hosted page, the
customer-entered values become authoritative for the payment.

`return_url` is the merchant URL where the customer is sent after
completing or abandoning the hosted payment page. Return URL query
parameters are UX hints only; merchants must use `GET /v1/payments/{id}`
or webhooks as the source of truth.

Use the `Idempotency-Key` header to safely retry requests.




## OpenAPI

````yaml /api-reference/payments-api.yaml post /v1/payments/hpp
openapi: 3.0.4
info:
  title: Flowlix Payments API
  version: 1.0.0
  description: >
    The Flowlix Payments API is a RESTful API for accepting and managing online
    payments.

    It follows industry-standard conventions: JSON request/response bodies,
    Bearer token authentication,

    standard HTTP verbs, idempotency support, and cursor-based pagination.


    ## Base URL


    All API requests are made to `https://api.flowlix.dev`. Current endpoints

    are versioned under `/v1`, e.g. `https://api.flowlix.dev/v1/payments`.


    ## Amounts


    All monetary amounts are expressed in **minor units** (the smallest currency
    unit).

    For example, `4999` in EUR represents **EUR 49.99**.
  contact:
    name: Flowlix Developer Support
    email: developers@flowlix.eu
    url: https://flowlix.dev/support
  license:
    name: Proprietary
    url: https://flowlix.dev/terms
servers:
  - url: https://api.flowlix.dev
    description: |
      Flowlix API. Test mode and live mode share the same host; the mode is
      selected by the API key prefix (`api_test_sk_*` or `api_live_sk_*`).
security:
  - BearerAuth: []
tags:
  - name: Payments
    description: Create, retrieve, and list payments.
  - name: Refunds
    description: >-
      Create refunds and track their status through the parent payment's
      `refunds` array.
paths:
  /v1/payments/hpp:
    post:
      tags:
        - Payments
      summary: Create a hosted payment page payment
      description: |
        Creates a hosted payment page payment attempt. Redirect the customer to
        `next_action.redirect_url` to complete the `next_action.reason`
        customer action. The required-action URL is opaque and may later change
        from the hosted page to a 3D Secure browser action. Use the latest
        `next_action.redirect_url` from `GET /v1/payments/{id}`, and avoid
        redirect loops when the URL is unchanged.

        `billing_details` is required for HPP and is used to prefill the hosted
        page. If the customer edits the billing details on the hosted page, the
        customer-entered values become authoritative for the payment.

        `return_url` is the merchant URL where the customer is sent after
        completing or abandoning the hosted payment page. Return URL query
        parameters are UX hints only; merchants must use `GET /v1/payments/{id}`
        or webhooks as the source of truth.

        Use the `Idempotency-Key` header to safely retry requests.
      operationId: createHppPayment
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateHPPaymentRequest'
            examples:
              basic:
                summary: Hosted payment page payment
                value:
                  amount: 2500
                  currency: EUR
                  merchant_reference: 2345678901
                  billing_details:
                    email: jenny@example.com
                    first_name: Jenny
                    last_name: Rosen
                    phone: '+491701234567'
                    address:
                      line1: Kurfuerstendamm 21
                      city: Berlin
                      postal_code: '10719'
                      country: DE
                  return_url: https://shop.example.com/checkout/complete
      responses:
        '201':
          description: |
            Hosted payment page payment accepted and a Payment object was
            created. When provider submission succeeds, the payment moves
            directly from `PENDING` to `REQUIRES_ACTION` with
            `next_action.reason` and `next_action.redirect_url`; it does not
            pass through `PROCESSING` before customer redirect. Use the Payment
            object's `status` from `GET /v1/payments/{id}` or webhooks as the
            source of truth for the final outcome.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/IdempotencyConflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: >
        A unique key to ensure the request is processed only once. If a request

        with the same idempotency key and the same body has already been

        processed successfully, the original response is returned. Non-2xx

        responses are not cached, so callers may retry after errors. Keys expire

        after 24 hours.


        For one-shot requests, such as creating a payment from a checkout
        button,

        a random UUIDv4 is fine. For requests tied to a specific business

        operation, such as refunding an order, a deterministic key is preferred

        so retries collapse correctly across processes.
      schema:
        type: string
        maxLength: 255
      example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  schemas:
    CreateHPPaymentRequest:
      type: object
      required:
        - amount
        - currency
        - billing_details
        - return_url
      properties:
        amount:
          type: integer
          format: int64
          minimum: 1
          description: Payment amount in minor units.
          example: 2500
        currency:
          $ref: '#/components/schemas/Currency'
        merchant_reference:
          $ref: '#/components/schemas/MerchantReference'
        billing_details:
          $ref: '#/components/schemas/BillingDetailsInput'
        description:
          type: string
          maxLength: 500
          description: Merchant-provided payment description.
          example: 'Order #5678'
        return_url:
          type: string
          format: uri
          description: >-
            Merchant URL where the customer returns after hosted payment
            completion or abandonment.
          example: https://shop.example.com/checkout/complete
    Payment:
      type: object
      description: |
        A Payment represents one attempt to collect funds from the customer.
        Merchants can use `merchant_reference` to associate multiple
        payment attempts with the same order or checkout in their own systems.
      required:
        - id
        - amount
        - currency
        - status
        - created_at
        - livemode
        - amount_refunded
        - amount_refundable
        - integration_type
      properties:
        id:
          $ref: '#/components/schemas/PaymentId'
        amount:
          type: integer
          format: int64
          minimum: 1
          description: Payment amount in minor units.
          example: 4999
        currency:
          $ref: '#/components/schemas/Currency'
        status:
          $ref: '#/components/schemas/PaymentStatus'
        integration_type:
          $ref: '#/components/schemas/IntegrationType'
        merchant_reference:
          type: integer
          allOf:
            - $ref: '#/components/schemas/MerchantReference'
          nullable: true
          description: Merchant-side reconciliation reference, if provided.
        description:
          type: string
          nullable: true
          description: Merchant-provided payment description.
          example: 'Order #1234'
        card:
          type: object
          allOf:
            - $ref: '#/components/schemas/Card'
          nullable: true
          description: Masked card details, or `null` before card details are available.
        billing_details:
          type: object
          allOf:
            - $ref: '#/components/schemas/BillingDetails'
          nullable: true
          description: Billing details captured for the payment, if available.
        failure_code:
          type: string
          allOf:
            - $ref: '#/components/schemas/OperationFailureCode'
          nullable: true
          description: >-
            Machine-readable reason code when the payment reaches a terminal
            failed status.
          example: insufficient_funds
        failure_message:
          type: string
          nullable: true
          description: >-
            Human-readable explanation when the payment reaches a terminal
            failed status.
          example: The card has insufficient funds.
        amount_refunded:
          type: integer
          format: int64
          minimum: 0
          description: Total amount successfully refunded so far, in minor units.
          example: 0
        amount_refundable:
          type: integer
          format: int64
          minimum: 0
          description: Remaining amount that can be refunded, in minor units.
          example: 4999
        refunds:
          type: array
          description: Refunds created for this payment, oldest first.
          items:
            $ref: '#/components/schemas/Refund'
          default: []
        status_transitions:
          $ref: '#/components/schemas/StatusTransitions'
        created_at:
          type: integer
          format: int64
          description: Unix timestamp when the payment was created.
          example: 1719792000
        livemode:
          type: boolean
          description: Whether this payment was created using a live API key.
          example: false
        next_action:
          type: object
          allOf:
            - $ref: '#/components/schemas/PaymentNextAction'
          nullable: true
          description: Customer action required to continue the payment.
    Currency:
      type: string
      enum:
        - EUR
      description: |
        Three-letter ISO 4217 currency code. Currently supported for card
        acquiring: `EUR`.
      example: EUR
    MerchantReference:
      type: integer
      format: int64
      minimum: 1000000000
      maximum: 9999999999
      description: |
        Optional merchant-side reconciliation reference. The value must contain
        exactly 10 decimal digits and does not provide idempotency by itself.
      example: 1234567890
    BillingDetailsInput:
      type: object
      required:
        - email
        - address
      properties:
        email:
          type: string
          format: email
          minLength: 1
          maxLength: 255
          description: Billing email address.
          example: jenny@example.com
        first_name:
          type: string
          nullable: true
          maxLength: 255
          description: Payer first name.
          example: Jenny
        last_name:
          type: string
          nullable: true
          maxLength: 255
          description: Payer last name.
          example: Rosen
        phone:
          type: string
          nullable: true
          pattern: ^\+[1-9]\d{1,14}$
          maxLength: 16
          description: Billing phone number in E.164 format, for example `+491701234567`.
          example: '+491701234567'
        address:
          allOf:
            - $ref: '#/components/schemas/BillingAddressInput'
    PaymentId:
      type: string
      pattern: ^pay_[A-Za-z0-9]{24}$
      description: >-
        Unique opaque identifier for a payment (`pay_` prefix + random
        alphanumeric suffix).
      example: pay_q7Mk2Np8Vr4Xt6Yz9Ab3Cd5E
    PaymentStatus:
      type: string
      enum:
        - PENDING
        - REQUIRES_ACTION
        - PROCESSING
        - SUCCEEDED
        - FAILED
        - CANCELED
        - EXPIRED
      description: >
        Current status of a payment attempt.


        - `PENDING` -- The payment was accepted by Flowlix and is awaiting
        provider submission or the next lifecycle decision.

        - `REQUIRES_ACTION` -- Customer action is required, such as completing
        3D Secure authentication or a hosted payment page.

        - `PROCESSING` -- The payment is being processed by downstream payment
        systems.

        - `SUCCEEDED` -- The payment completed successfully.

        - `FAILED` -- The payment was declined or failed permanently.

        - `CANCELED` -- The payment was canceled before completion.

        - `EXPIRED` -- The customer did not complete a required action before
        its expiry time.
      example: SUCCEEDED
    IntegrationType:
      type: string
      enum:
        - DIRECT
        - HOSTED_PAYMENT_PAGE
      description: |
        How the payment was collected. This is separate from the payment method
        instrument, such as `card` or a future wallet.
      example: DIRECT
    Card:
      type: object
      description: >-
        Masked card details. If card details are not available, the entire
        `card` field is `null`.
      required:
        - brand
        - last4
        - exp_month
        - exp_year
      properties:
        brand:
          type: string
          description: Card brand, for example `visa`, `mastercard`, or `amex`.
          example: visa
        last4:
          type: string
          pattern: ^[0-9]{4}$
          description: Last four digits of the card number.
          example: '1111'
        exp_month:
          type: integer
          format: int32
          minimum: 1
          maximum: 12
          description: Card expiration month.
          example: 12
        exp_year:
          type: integer
          format: int32
          description: Card expiration year.
          example: 2027
        country:
          type: string
          nullable: true
          pattern: ^[A-Z]{2}$
          description: Two-letter ISO country code of the issuing bank, if available.
          example: DE
    BillingDetails:
      type: object
      description: Billing details associated with the payer.
      properties:
        email:
          type: string
          nullable: true
          format: email
          description: Billing email address.
          example: jenny@example.com
        first_name:
          type: string
          nullable: true
          description: Payer first name.
          example: Jenny
        last_name:
          type: string
          nullable: true
          description: Payer last name.
          example: Rosen
        phone:
          type: string
          nullable: true
          pattern: ^\+[1-9]\d{1,14}$
          description: Billing phone number in E.164 format, for example `+491701234567`.
          example: '+491701234567'
        address:
          type: object
          allOf:
            - $ref: '#/components/schemas/BillingAddress'
          nullable: true
    OperationFailureCode:
      type: string
      description: |
        Stable Flowlix failure reason for a terminal payment operation.
        Use this value to decide whether the customer should retry, use a new
        payment method, or contact support.
      enum:
        - invalid_request
        - not_found
        - processor_error
        - processor_unavailable
        - generic_decline
        - do_not_honor
        - issuer_declined
        - insufficient_funds
        - invalid_number
        - invalid_expiry
        - expired_card
        - invalid_amount
        - invalid_currency
        - not_permitted
        - cardholder_limit
        - card_velocity_exceeded
        - lost_card
        - stolen_card
        - suspect_fraud
        - fraud_filter
        - payment_canceled
        - three_d_secure_failed
        - three_d_secure_timeout
        - three_d_secure_not_supported
        - three_d_secure_error
      example: insufficient_funds
    Refund:
      type: object
      description: A refund against a payment.
      required:
        - id
        - payment_id
        - amount
        - currency
        - reason
        - refund_type
        - status
        - created_at
        - updated_at
        - livemode
      properties:
        id:
          $ref: '#/components/schemas/RefundId'
        payment_id:
          $ref: '#/components/schemas/PaymentId'
        amount:
          type: integer
          format: int64
          minimum: 1
          description: Refund amount in minor units.
          example: 1500
        currency:
          $ref: '#/components/schemas/Currency'
        merchant_reference:
          type: integer
          allOf:
            - $ref: '#/components/schemas/MerchantReference'
          nullable: true
          description: Merchant-side reconciliation reference for this refund, if provided.
        reason:
          type: string
          maxLength: 50
          description: Merchant-provided refund reason stored with the refund.
          example: Full refund verification
        refund_type:
          $ref: '#/components/schemas/RefundType'
        status:
          $ref: '#/components/schemas/RefundStatus'
        failure:
          $ref: '#/components/schemas/RefundFailure'
        created_at:
          type: integer
          format: int64
          description: Unix timestamp when the refund was created.
          example: 1719795600
        updated_at:
          type: integer
          format: int64
          description: Unix timestamp when the refund was last updated.
          example: 1719795660
        completed_at:
          type: integer
          nullable: true
          format: int64
          description: Unix timestamp when the refund reached a terminal status.
          example: 1719799200
        livemode:
          type: boolean
          description: Whether this refund was created using a live API key.
          example: false
    StatusTransitions:
      type: object
      description: Timestamps for important payment status transitions.
      properties:
        requires_action_at:
          type: integer
          nullable: true
          format: int64
          description: Unix timestamp when the payment first required customer action.
          example: null
        processing_at:
          type: integer
          nullable: true
          format: int64
          description: Unix timestamp when downstream processing started.
          example: 1719792002
        succeeded_at:
          type: integer
          nullable: true
          format: int64
          description: Unix timestamp when the payment succeeded.
          example: 1719792042
        failed_at:
          type: integer
          nullable: true
          format: int64
          description: Unix timestamp when the payment failed.
          example: null
        expired_at:
          type: integer
          nullable: true
          format: int64
          description: Unix timestamp when the payment expired.
          example: null
    PaymentNextAction:
      type: object
      required:
        - type
        - reason
        - redirect_url
      properties:
        type:
          type: string
          enum:
            - redirect
          description: The action type. Currently only `redirect` is supported.
          example: redirect
        reason:
          type: string
          enum:
            - hosted_payment_page
            - three_d_secure
          description: Why the customer redirect is required.
          example: three_d_secure
        redirect_url:
          type: string
          format: uri
          description: |
            Opaque provider URL for the current customer browser action. The
            URL can point to a hosted payment page, 3D Secure fingerprint
            collection, or a later authentication/challenge step. Redirect the
            customer to the latest URL returned for the payment, follow a new
            URL if it changes while the payment is still `REQUIRES_ACTION`, and
            avoid repeatedly redirecting the same browser to the same URL.
          example: https://return.wlpg.io/fingerprint/abc
    ApiError:
      type: object
      description: Error response wrapper.
      properties:
        error:
          $ref: '#/components/schemas/ApiErrorBody'
    BillingAddressInput:
      type: object
      required:
        - line1
        - city
        - postal_code
        - country
      properties:
        line1:
          type: string
          minLength: 1
          maxLength: 500
          description: First line of the billing street address.
          example: Kurfuerstendamm 21
        line2:
          type: string
          nullable: true
          maxLength: 500
          description: Second line of the billing street address, if present.
          example: Apartment 4B
        city:
          type: string
          minLength: 1
          maxLength: 255
          description: Billing city.
          example: Berlin
        state:
          type: string
          nullable: true
          maxLength: 255
          description: Billing state, region, or province, if applicable.
          example: Berlin
        postal_code:
          type: string
          minLength: 1
          maxLength: 20
          description: Billing postal code.
          example: '10719'
        country:
          type: string
          pattern: ^[A-Z]{2}$
          description: Billing country as an ISO 3166-1 alpha-2 code.
          example: DE
    BillingAddress:
      type: object
      description: Billing address associated with the payer.
      properties:
        line1:
          type: string
          nullable: true
          description: First line of the billing street address.
          example: Kurfuerstendamm 21
        line2:
          type: string
          nullable: true
          description: Second line of the billing street address, if present.
          example: Apartment 4B
        city:
          type: string
          nullable: true
          description: Billing city.
          example: Berlin
        state:
          type: string
          nullable: true
          description: Billing state, region, or province, if applicable.
          example: Berlin
        postal_code:
          type: string
          nullable: true
          description: Billing postal code.
          example: '10719'
        country:
          type: string
          nullable: true
          pattern: ^[A-Z]{2}$
          description: Billing country as an ISO 3166-1 alpha-2 code.
          example: DE
    RefundId:
      type: string
      pattern: ^ref_[A-Za-z0-9]{24}$
      description: >-
        Unique opaque identifier for a refund (`ref_` prefix + random
        alphanumeric suffix).
      example: ref_L9xQ4wE2rT8yU6iO3pA7sD1f
    RefundType:
      type: string
      enum:
        - FULL
        - PARTIAL
      description: |
        Whether the refund covers the full original payment amount or only part
        of it.
      example: FULL
    RefundStatus:
      type: string
      enum:
        - PENDING
        - PROCESSING
        - SUCCEEDED
        - FAILED
      description: |
        Current refund lifecycle status. Refunds normally move from `PENDING`
        to `PROCESSING`, then to `SUCCEEDED` or `FAILED`.
      example: PENDING
    RefundFailure:
      type: object
      nullable: true
      description: Refund failure details when the refund reaches `FAILED`.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable Flowlix error code.
          example: fraud_filter
        message:
          type: string
          description: Human-readable Flowlix error explanation.
          example: The payment was declined by fraud controls.
    ApiErrorBody:
      type: object
      description: Detailed error information.
      required:
        - message
      properties:
        code:
          type: string
          nullable: true
          description: Short machine-readable error code.
          example: parameter_invalid
        message:
          type: string
          description: Human-readable message explaining the error.
          example: One or more request parameters failed validation.
        param:
          type: string
          nullable: true
          description: Request parameter that caused the error, if applicable.
          example: payment_method_data[card][number]
        doc_url:
          type: string
          nullable: true
          format: uri
          description: URL to documentation for this error.
          example: https://docs.flowlix.dev
        request_id:
          type: string
          nullable: true
          description: Request ID matching the `Request-Id` response header.
          example: req_abc123def456
  headers:
    RequestId:
      description: >-
        A unique identifier for this API request. Include it when contacting
        support.
      schema:
        type: string
        maxLength: 255
      example: req_abc123def456
    RetryAfter:
      description: Number of seconds to wait before retrying.
      schema:
        type: integer
      example: 5
  responses:
    BadRequest:
      description: |
        The request could not be parsed or failed request validation. Check the
        JSON body, required headers, required fields, field formats, and
        `error.param` when it is present.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    Unauthorized:
      description: |
        The API key is missing, invalid, expired, or revoked. Send your secret
        key in the `Authorization: Bearer <key>` header and verify that the key
        has the expected `api_test_sk_` or `api_live_sk_` prefix.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    Forbidden:
      description: |
        The API key is valid, but it is not allowed to perform this operation.
        Check that the key belongs to the correct merchant account, has access
        to this endpoint, and matches the resource's test or live mode.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    IdempotencyConflict:
      description: |
        The `Idempotency-Key` is still being processed, or it was reused for a
        different request. Retry the original request unchanged, or use a new
        idempotency key for a new payment or refund operation.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    UnprocessableEntity:
      description: |
        The request passed basic validation, but the operation cannot be
        completed in the resource's current state — for example, a refund
        amount that exceeds the payment's remaining refundable amount. Check
        `error.code`, `error.message`, and `error.param` when present to decide
        how to fix the request. Note that card declines are not reported through
        this status: a declined payment returns `201` with `status: "FAILED"`
        and a `failure_code` on the Payment object.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    InternalError:
      description: >
        Flowlix encountered an unexpected server error before the operation
        could

        be completed. Retry safely with the same idempotency key when retrying a

        POST request, and include the `Request-Id` if you contact support.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ServiceUnavailable:
      description: |
        Flowlix is temporarily unable to process the request. Wait for
        `Retry-After` when present, then retry with exponential backoff. Reuse
        the same idempotency key when retrying a POST request.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        Use your secret API key as the Bearer token. Test mode keys start with
        `api_test_sk_` and live mode keys start with `api_live_sk_`. Both modes
        use the same API host; the mode is determined by the key.

        ```
        Authorization: Bearer api_test_sk_abc123def456
        ```

````