> ## 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 provider-hosted card checkout session (internal)



## OpenAPI

````yaml /openapi/fluide-pay.json post /api/v1/payments/internal/checkout-sessions/card-hosted-checkout
openapi: 3.0.0
info:
  title: Fluide Pay API
  description: >-
    Digital wallets, transactions, checkout sessions, payouts, and collections.
    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: Sandbox
  - url: https://api.fluideglobal.com
    description: Production
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: Internal banking
  - name: MobileMoney
  - name: Checkout sessions
  - name: Payments capabilities
  - name: Payments capabilities (internal admin)
  - name: billing-public
  - name: billing
  - name: billing-platform
  - name: billing-internal
  - name: billing-payments
  - name: checkout-sessions-platform
  - name: checkout-sessions-public
  - name: checkout-sessions-internal
  - name: checkout-sessions
  - name: campaigns
  - name: campaigns-public
  - name: invoices
  - name: subscriptions
  - name: channels
  - name: qr-codes
  - name: Internal Payouts
  - name: AR Collection Internal
  - name: stats
  - name: Payouts
  - name: Collections
paths:
  /api/v1/payments/internal/checkout-sessions/card-hosted-checkout:
    post:
      tags:
        - Checkout sessions
      summary: Create provider-hosted card checkout session (internal)
      operationId: CardInternalController_createCardHostedCheckout
      parameters:
        - 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
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCheckoutSessionDto'
      responses:
        '201':
          description: Card hosted checkout session created
          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 POST
            "$FLUIDE_BASE_URL/api/v1/payments/internal/checkout-sessions/card-hosted-checkout"
            \ -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" \ -H "Content-Type:
            application/json" \ -d '{}'
        - lang: node
          label: Node.js
          source: >-
            const baseUrl = process.env.FLUIDE_BASE_URL; const response = await
            fetch(`${baseUrl}/api/v1/payments/internal/checkout-sessions/card-hosted-checkout`,
            { method: 'POST', 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, 'Content-Type': 'application/json',
            }, body: JSON.stringify({}),

            }); 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.post(
            f"{base_url}/api/v1/payments/internal/checkout-sessions/card-hosted-checkout",
            headers=headers, json={}, 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/internal/checkout-sessions/card-hosted-checkout"))
            .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")) .header("Content-Type",
            "application/json") .POST(HttpRequest.BodyPublishers.ofString("{}"))
            .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/internal/checkout-sessions/card-hosted-checkout");

            curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => 'POST', 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'), 'Content-Type: application/json', ],
            CURLOPT_POSTFIELDS => "{}",

            ]);

            $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:
    CreateCheckoutSessionDto:
      type: object
      properties:
        amountMinor:
          type: number
          minimum: 1
          description: Amount in minor units (cents)
        currency:
          type: string
          maxLength: 3
          example: USD
        lineItems:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/CheckoutLineItemDto'
        successUrl:
          type: string
          format: uri
        cancelUrl:
          type: string
          format: uri
        customerEmail:
          type: string
          format: email
        customerName:
          type: string
        metadata:
          type: object
        branding:
          $ref: '#/components/schemas/CheckoutBrandingDto'
        presentation:
          $ref: '#/components/schemas/CheckoutPresentationDto'
        allowedMethods:
          type: array
          items:
            type: string
            enum:
              - card
              - mobile_money
        mode:
          enum:
            - payment
            - setup
            - subscription
          type: string
        accountingIntent:
          $ref: '#/components/schemas/CheckoutAccountingIntentDto'
        idempotencyKey:
          type: string
          maxLength: 128
        expiresInSeconds:
          type: number
          minimum: 0
          description: >-
            TTL in seconds. Use 0 for no expiration (link stays valid until paid
            or cancelled). Minimum otherwise is 300.
          default: 86400
        frameAncestors:
          type: string
          description: Space-separated frame-ancestors for embed mode
        vertical:
          type: string
          maxLength: 64
          description: Industry vertical for checkout UX (e.g. school, healthcare)
          example: school
        collectFields:
          maxItems: 40
          description: >-
            Custom fields to collect during checkout (from org checkout
            workflow)
          type: array
          items:
            $ref: '#/components/schemas/CheckoutCollectFieldDto'
      required:
        - amountMinor
        - currency
        - lineItems
        - successUrl
        - cancelUrl
    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
    CheckoutLineItemDto:
      type: object
      properties:
        description:
          type: string
          maxLength: 500
        quantity:
          type: number
          minimum: 1
          default: 1
        unitAmountMinor:
          type: number
          minimum: 0
          description: Unit amount in minor units
      required:
        - description
        - quantity
        - unitAmountMinor
    CheckoutBrandingDto:
      type: object
      properties:
        displayName:
          type: string
        logoUrl:
          type: string
          format: uri
        primaryColor:
          type: string
          example: '#2563eb'
        darkMode:
          type: boolean
        fontFamily:
          type: string
        locale:
          type: string
          example: en
    CheckoutPresentationDto:
      type: object
      properties:
        title:
          type: string
          maxLength: 120
          description: Hero headline on checkout
        description:
          type: string
          maxLength: 2000
          description: Long description shown under the cover image
        coverImageUrl:
          type: string
          format: uri
          description: Public HTTPS URL for cover image (e.g. /api/v1/app/public/files/:id)
        coverImageFileId:
          type: string
          maxLength: 64
          description: fluide-utils file_uploads id for audit
    CheckoutAccountingIntentDto:
      type: object
      properties:
        kind:
          type: object
        invoiceId:
          type: string
        companyId:
          type: string
        autoReconcile:
          type: boolean
          default: true
    CheckoutCollectFieldDto:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 64
        label:
          type: string
          minLength: 1
          maxLength: 120
        type:
          type: string
          enum:
            - text
            - select
            - number
            - date
            - email
            - phone
        required:
          type: boolean
        options:
          maxItems: 50
          type: array
          items:
            type: string
        placeholder:
          type: string
          maxLength: 200
      required:
        - id
        - label
        - type
  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

````