Skip to content

Flute Checkout

Flute Checkout is a hosted payment page that handles the entire checkout experience on your behalf. You redirect your customer to it at payment time, and once the payment is complete, Flute sends them back to your application.

Flute Checkout gives you:

  • PCI-DSS compliance. Card data is captured and processed through Flute's secure infrastructure, never touching your servers.
  • No frontend work. A single API call creates the payment session. Flute hosts and manages the entire payment UI.
  • Branded experience. Customize the hosted page with your logo, colors, and font to match your application.
Flute Checkout screen
Example of Flute Checkout screen.

Integration Overview

Flute APIMerchant BackendMerchant FrontendCustomerFlute APIMerchant BackendMerchant FrontendCustomerCustomer completes payment on Flute-hosted pagePOST /pay-int-api/payment-sessions1{ "id": "SESSION_ID", "checkoutUrl": "..." }2checkoutUrl3Redirect to Flute Checkout4Redirected to returnUrl5Fetch session result6GET /pay-int-api/payment-sessions/{id}7Session object8Session result9Show result10
Flute APIMerchant BackendMerchant FrontendCustomerFlute APIMerchant BackendMerchant FrontendCustomerCustomer completes payment on Flute-hosted pagePOST /pay-int-api/payment-sessions1{ "id": "SESSION_ID", "checkoutUrl": "..." }2checkoutUrl3Redirect to Flute Checkout4Redirected to returnUrl5Fetch session result6GET /pay-int-api/payment-sessions/{id}7Session object8Session result9Show result10

Building with Flute Checkout

Flute Checkout supports both card and ACH transactions. The integration follows three steps:

  • Step 1: Creating a Payment Session from the backend to get the checkout URL.
  • Step 2: Redirecting the Customer to the Flute-hosted checkout page.
  • Step 3: Verifying Payment once the customer returns to your application.

Step 1: Creating a Payment Session

Sandbox Environment:

https://sandbox.api.flute.com

Production Environment:

https://api.flute.com

To create a payment session, call POST /pay-int-api/payment-sessions from the backend. The following is an example request body showing the fields relevant to Flute Checkout.

POST /pay-int-api/payment-sessions

{
    "amount": 500.00,
    "returnUrl": "https://isv.example.com/payments/returnUrl/{{paymentSessionId}}",
    "paymentMethodTypes": [ "card", "ach" ],
    "metadata":
    {
        "orderId": "ORD/456",
        "invoiceNumber": "INV-2026-001"
    },
    ...
}

The following is a payment session response body relevant to Flute Checkout.

FieldTypeRequiredNotes
amountnumber
float
NoThe transaction amount. If provided, Flute Checkout displays it as the payment total. If omitted, the customer is prompted to enter an amount.
returnUrlstringNoThe URL your customer is redirected to after the checkout flow ends. Include {{paymentSessionId}} as a placeholder in the URL. Flute substitutes the real payment session identifier before returning the URL in the response. See the example response body for details.
metadataobjectNoOptional key-value pairs for additional context, such as an internal order ID or invoice reference. Values are sanitized for security.

Maximum of 50 key-value pairs. Maximum 40 characters per key, 500 characters per value, 8 KB for the full set.
paymentMethodTypesstring[]NoThe allowed payment types. Accepted values: "card", "ach". Defaults to ["card"] if omitted.
expiresAtstring/date-timeNoOptional expiry timestamp in an ISO 8601 UTC date-time format, such as 2026-03-12T19:00:00.000Z. The hosted page renders an expired error after this time, preventing further interaction. If omitted, the payment session expires in 30 minutes.

The default payment session expiry is 30 minutes. If you are using Flute Checkout for emailed payment links or other flows where the customer may not act immediately, set expiresAt explicitly to a longer window.

Example response body:

{
    "id": "dce6a259-0a1b-4c2d-3e4f-5a6b7c8d9e25",
    "amount": 500.00,
    "currency": "USD",
    "status": "Created",
    "checkoutUrl": "https://public.flute.com/checkout/dce6a259-0a1b-4c2d-3e4f-5a6b7c8d9e25",
    "returnUrl": "https://isv.example.com/payments/returnUrl/dce6a259-0a1b-4c2d-3e4f-5a6b7c8d9e25",
    "paymentMethodTypes": [ "card", "ach" ],
    "metadata": { "orderId": "ORD/456", "invoiceNumber": "INV-2026-001" },
    "createdAt": "2026-03-12T19:00:00.000Z"
}

The following is a payment session response body relevant to Flute Checkout.

FieldTypeNotes
idstringThe payment session identifier. Use this value when redirecting to Flute Checkout.
checkoutUrlstringThe fully-formed checkout URL. Redirect your customer to this URL to start the checkout flow.
returnUrlstringThe URL the customer is redirected to after the checkout flow ends, with {{paymentSessionId}} substituted with the real payment session identifier.
metadataobjectThe key-value pairs provided in the request, echoed back in the response.

Step 2: Redirecting the Customer

Use the checkoutUrl from the session creation response to send the customer to Flute Checkout. Use one of the following methods:

Server-side or direct redirect

The checkoutUrl is a fully-formed URL unique to the customer's payment session. Redirect to it directly from your server or pass it to any of the client-side methods below.

Using the Flute.js library

Load the Flute.js library and call flute.checkoutPage() with the payment session identifier.

<head>
  <script src="https://public.flute.com/lib/v1.0/flute.mjs" type="module"></script>
</head>
const flute = new window.Flute();
flute.checkoutPage('dce6a259-0a1b-4c2d-3e4f-5a6b7c8d9e25')

Client-side browser redirect

window.location.href = "https://public.flute.com/checkout/dce6a259-0a1b-4c2d-3e4f-5a6b7c8d9e25";

Step 3: Verifying Payment

When the payment session is completed, cancelled, or expired, the customer is redirected to the returnUrl you provided at payment session creation. The {{paymentSessionId}} placeholder in the URL is substituted with the actual payment session identifier, which you can use to look up the result from the backend.

If no returnUrl was set, the customer remains on the Flute-hosted page and sees a generic confirmation message.

Always verify the payment result from the backend. Never rely on the frontend or the redirect URL alone.

Call the following endpoint after receiving the payment_session.completed webhook or after the customer is redirected to your returnUrl:

GET /pay-int-api/payment-sessions/{paymentSessionId}

Subscribe to the payment_session.completed webhook to be notified when a payment session reaches a terminal state. This is the recommended approach. As a fallback, you can poll the endpoint above and check for the Completed status.

As the customer interacts with Flute Checkout, the payment session moves through these states:

StatusDescription
CreatedPayment session was initialized but not yet processed.
CompletedPayment session was completed. Check transaction details to verify if the payment was approved or not.
CancelledPayment session was canceled before completion.
ExpiredPayment session expired before being completed.
FailedPayment was attempted but did not succeed. A new payment session must be created for a new payment attempt.

Step 3.1: Check the payment session status

The payment session-level status field must be Completed. This confirms the customer went through the checkout flow, but does not by itself confirm the payment was approved.

Step 3.2: Check the transaction status

Check transactionDetails.status against the expected success statuses for your payment type:

Card payments

transactionDetails.statusMeaning
AuthorizedPayment authorized, pending capture.
CapturedPayment captured.
PartiallyAuthorizedPartial amount authorized.

ACH payments

transactionDetails.statusMeaning
ScheduledPayment scheduled for processing.
InProgressSubmission accepted and being processed.

Additional statuses may appear on subsequent lookups as the payment progresses through its lifecycle. For example, Settled for card payments and Cleared for ACH payments. These do not require any action on your end.

Any other status (including Declined, Failed, Voided, Cancelled, ChargedBack, Held, or HeldByProcessor) indicates the payment did not succeed.

Other useful fields

FieldDescription
transactionDetails.transactionReceipt.amountCharged amount (in USD).
transactionDetails.transactionReceipt.transactionIdTransaction identifier.
metadataMetadata provided at payment session creation.
customerIdCustomer record associated with the payment, if a payment method was saved.

Faster Checkout for Returning Customers

When a payment session is created with a customerId that has saved payment methods on file, Flute Checkout automatically surfaces those methods on the payment page. The customer can select a saved card or bank account and complete the payment without re-entering their details, providing a faster checkout experience for returning users.

Flute Checkout with saved payment methods
Flute Checkout showing saved payment methods for a returning customer.

Pass customerId when creating the payment session:

{
  "amount": 144.00,
  "returnUrl": "https://isv.example.com/payments/returnUrl/{{paymentSessionId}}",
  "customerId": "CUSTOMER_ID"
}

The checkoutUrl grants access to any saved payment methods linked to the payment session's customerId. Keep it private. Treat it like a one-time payment token. Generate it at checkout time, send it directly to the authenticated customer, and never share or publicly expose it. Anyone with access to the URL can use those saved methods to complete the payment.

Error Handling

This section describes possible errors, following the Flute error format.

HTTP StatusError TypeNotes
400validation_errorInvalid input.

This means the request was rejected before reaching the processor. No transaction was created and the session status remains Created.
401authentication_errorMissing or invalid OAuth token.

Check for missing, expired, or invalid credentials.
403authorization_errorThe request is forbidden.

The caller is authenticated but not authorized to perform the action. Check API key permission levels.
404not_foundPayment session not found.
409conflictPayment session not in valid state for operation.

The request is valid and well formed. Fulfilling the request would conflict with an existing resource state. Common examples include registering the same webhook endpoint twice or attempting to void a transaction that has already settled.
422payment_errorPayment declined or processing error.

The submission was rejected after reaching the processor. The payment session is now Failed. A new payment session must be created for another payment attempt.
429rate_limit_errorRate limit exceeded on public endpoints.

Reduce the request rate or wait before retrying.
500internal_errorServer error.

The following is an example returned error.

{
    "error":
    {
        "type": "validation_error",
        "message": "Invalid payment method type",
        "details": [{ "field": "paymentMethodTypes", "message": "Allowed values: 'card', 'ach'" }]
    }
}

Branding Flute Checkout

The hosted checkout page can be customized so it feels like part of your own website. Configurable components include the merchant logo, font, accent color, and page background color.

To configure these branding options:

  1. Navigate to the partner's Flute dashboard page.
  2. Select Merchant from the left menu panel. This displays the list of merchants for the partner.
  3. Select the individual merchant.
  4. Select Impersonate merchant. This allows the partner to act on behalf of the merchant.
  5. Select Settings from the left menu panel.
  6. Select Profile in the right navigation panel. This displays the branding options page.
  7. Select options under the Branding and customization section.