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

# Create hosted checkout for the current billing period (system computed)

> Creates/updates the current-period invoice for manual payment via hosted checkout. The system computes the amount from plan pricing and current billable seats (including any seat overage). VAT is not applied in this version. Requires a logged-in user context; frontend must NOT send amount.



## OpenAPI

````yaml /openapi/fluide-pay.json get /api/v1/payments/billing/checkout
openapi: 3.0.0
info:
  title: Fluide Pay API
  description: >-
    Digital wallets, transactions, and payment provider integrations (Ecobank,
    mobile money). Supports async settlement via Kafka. In the API playground,
    click Authorize and provide Bearer JWT, X-Fluide-Api-Key, and
    X-Fluide-Client-Id (fluide-developer). For partner / ISV integrations acting
    on a merchant, also set optional X-Workspace-Id and X-Acting-Company-Id on
    each request (see Multi-tenancy).
  version: '1.0'
  contact: {}
servers:
  - url: https://test.api.fluidehr.com
    description: API
security:
  - bearer: []
    fluideApiKey: []
    fluideClientId: []
tags:
  - name: App
    description: Service root and build metadata. Use for quick connectivity checks.
    x-group: Operations
  - name: Prometheus
    description: >-
      Prometheus scrape endpoint in text exposition format. Configure your
      metrics collector to poll this path on each service.
    x-group: Operations
  - name: wallets
  - name: internal wallets
  - name: transactions
  - name: transactions-reports-internal
  - name: Flutterwave
  - name: Flutterwave Webhooks
  - name: Ecobank Services
  - name: MobileMoney
  - name: Stripe Payments
  - name: Stripe Internal
  - name: Stripe Webhooks
  - name: Payments capabilities
  - name: Payments capabilities (internal admin)
  - name: billing-public
  - name: billing
  - name: billing-internal
  - name: billing-payments
  - name: billing-webhooks
  - name: checkout-sessions
  - name: checkout-sessions-public
  - name: checkout-sessions-internal
  - name: checkout-sessions-platform
  - name: Internal Payouts
  - name: AR Collection Internal
  - name: invoices
  - name: subscriptions
  - name: channels
  - name: qr-codes
  - name: Authorize
    description: >-
      Exchange API key and secret for a machine JWT, read developer metadata,
      rotate secrets, and manage API billing.
paths:
  /api/v1/payments/billing/checkout:
    get:
      tags:
        - billing-payments
      summary: Create hosted checkout for the current billing period (system computed)
      description: >-
        Creates/updates the current-period invoice for manual payment via hosted
        checkout. The system computes the amount from plan pricing and current
        billable seats (including any seat overage). VAT is not applied in this
        version. Requires a logged-in user context; frontend must NOT send
        amount.
      operationId: createBillingCheckout
      parameters:
        - name: plan
          required: true
          in: query
          schema:
            type: string
        - name: discountCode
          required: true
          in: query
          schema:
            type: string
        - name: X-Workspace-Id
          in: header
          required: false
          description: >-
            Partner / ISV only: UUID of the workspace that owns the client
            company. Required together with X-Acting-Company-Id when scoping
            product APIs to a merchant. See /getting-started/multi-tenancy.
          schema:
            type: string
            format: uuid
          example: b03fa178-67bd-4378-a5aa-d169c01ccb6f
        - name: X-Acting-Company-Id
          in: header
          required: false
          description: >-
            Partner / ISV only: UUID of the client company to act on. Must
            belong to the workspace in X-Workspace-Id.
          schema:
            type: string
            format: uuid
          example: ab2df10a-c66c-4bef-b7d6-efda26cca494
      responses:
        '200':
          description: Hosted checkout session
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiResponseDto'
                  - properties:
                      data:
                        description: Endpoint-specific payload
        '400':
          description: Validation failed or invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
        '401':
          description: Missing or invalid JWT / API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
        '403':
          description: Token valid but insufficient permission for this operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
        '404':
          description: Resource not found or outside caller scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
      security:
        - bearer: []
          fluideApiKey: []
          fluideClientId: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            curl -sS -X GET
            "$FLUIDE_BASE_URL/api/v1/payments/billing/checkout?plan=string&discountCode=string"
            \
              -H "Authorization: Bearer $FLUIDE_ACCESS_TOKEN" \
              -H "X-Fluide-Api-Key: $FLUIDE_API_KEY" \
              -H "X-Fluide-Client-Id: fluide-developer" \
              -H "X-Workspace-Id: $FLUIDE_WORKSPACE_ID" \
              -H "X-Acting-Company-Id: $FLUIDE_COMPANY_ID"
        - lang: node
          label: Node.js
          source: >-
            const baseUrl = process.env.FLUIDE_BASE_URL;


            const response = await
            fetch(`${baseUrl}/api/v1/payments/billing/checkout?plan=string&discountCode=string`,
            {
              method: 'GET',
              headers: {
                Authorization: `Bearer ${process.env.FLUIDE_ACCESS_TOKEN}`,
                'X-Fluide-Api-Key': process.env.FLUIDE_API_KEY,
                'X-Fluide-Client-Id': 'fluide-developer',
                'X-Workspace-Id': process.env.FLUIDE_WORKSPACE_ID,
                'X-Acting-Company-Id': process.env.FLUIDE_COMPANY_ID,
              },
            });


            if (!response.ok) throw new Error(`HTTP ${response.status}: ${await
            response.text()}`);

            console.log(await response.json());
        - lang: python
          label: Python
          source: |-
            import os
            import requests

            base_url = os.environ["FLUIDE_BASE_URL"]
            headers = {
                    "Authorization": f"Bearer {os.environ['FLUIDE_ACCESS_TOKEN']}",
                    "X-Fluide-Api-Key": os.environ["FLUIDE_API_KEY"],
                    "X-Fluide-Client-Id": "fluide-developer",
                    "X-Workspace-Id": os.environ["FLUIDE_WORKSPACE_ID"],
                    "X-Acting-Company-Id": os.environ["FLUIDE_COMPANY_ID"],
            }

            response = requests.get(
                f"{base_url}/api/v1/payments/billing/checkout?plan=string&discountCode=string",
                headers=headers,
                timeout=30,
            )
            response.raise_for_status()
            print(response.json())
        - lang: java
          label: Java
          source: >-
            import java.net.URI;

            import java.net.http.HttpClient;

            import java.net.http.HttpRequest;

            import java.net.http.HttpResponse;


            String baseUrl = System.getenv("FLUIDE_BASE_URL");

            HttpClient client = HttpClient.newHttpClient();

            HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/api/v1/payments/billing/checkout?plan=string&discountCode=string"))
                .header("Authorization", "Bearer " + System.getenv("FLUIDE_ACCESS_TOKEN"))
                .header("X-Fluide-Api-Key", System.getenv("FLUIDE_API_KEY"))
                .header("X-Fluide-Client-Id", "fluide-developer")
                .header("X-Workspace-Id", System.getenv("FLUIDE_WORKSPACE_ID"))
                .header("X-Acting-Company-Id", System.getenv("FLUIDE_COMPANY_ID"))
                .GET(HttpRequest.BodyPublishers.noBody())
                .build();
            HttpResponse<String> response = client.send(builder.build(),
            HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() >= 400) throw new RuntimeException("HTTP "
            + response.statusCode() + ": " + response.body());

            System.out.println(response.body());
        - lang: php
          label: PHP
          source: >-
            <?php

            $baseUrl = getenv("FLUIDE_BASE_URL");

            $ch = curl_init($baseUrl .
            "/api/v1/payments/billing/checkout?plan=string&discountCode=string");

            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_CUSTOMREQUEST => 'GET',
                CURLOPT_HTTPHEADER => [
                    'Authorization: Bearer ' . getenv('FLUIDE_ACCESS_TOKEN'),
                    'X-Fluide-Api-Key: ' . getenv('FLUIDE_API_KEY'),
                    'X-Fluide-Client-Id: fluide-developer',
                    'X-Workspace-Id: ' . getenv('FLUIDE_WORKSPACE_ID'),
                    'X-Acting-Company-Id: ' . getenv('FLUIDE_COMPANY_ID'),
                ],
            ]);

            $response = curl_exec($ch);

            if ($response === false) throw new
            RuntimeException(curl_error($ch));

            $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

            if ($status >= 400) throw new RuntimeException("HTTP $status:
            $response");

            echo $response;
components:
  schemas:
    ApiResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
          description: Whether the request succeeded
        message:
          type: string
          example: Operation completed successfully
          description: Human-readable outcome message (localized when i18n is configured)
        data:
          type: object
          description: Response payload when success is true
      required:
        - success
        - message
    ApiErrorResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: Validation failed
          description: Human-readable error message (localized when i18n is configured)
        code:
          type: string
          example: VALIDATION_FAILED
          description: Stable machine-readable error code for client handling and support
        errors:
          type: object
          description: Field-level validation errors keyed by property name
          example:
            from:
              - from must be a valid date
        statusCode:
          type: number
          example: 400
        timestamp:
          type: string
          example: '2026-06-03T12:00:00.000Z'
      required:
        - success
        - message
        - code
        - statusCode
        - timestamp
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Access token JWT. Use as Authorization: Bearer <token>. In the API
        playground, paste the JWT only.
    fluideApiKey:
      type: apiKey
      in: header
      name: X-Fluide-Api-Key
      description: >-
        Developer API key (fl_dev_...). Required on every API call with a
        machine access token.
      x-default: fl_dev_your_key
    fluideClientId:
      type: apiKey
      in: header
      name: X-Fluide-Client-Id
      description: >-
        First-party client audience. Must match the fluide_client_id claim on
        the JWT. Use fluide-developer for Connect.
      x-default: fluide-developer

````