Skip to main content
POST
/
v1
/
payments
Create a Direct API payment
curl --request POST \
  --url https://api.flowlix.dev/v1/payments \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "amount": 4999,
  "currency": "eur",
  "card": {
    "number": "4111111111111111",
    "exp_month": 12,
    "exp_year": 2027,
    "cvc": "314",
    "holder_name": "Jenny Rosen"
  },
  "customer": {
    "email": "jenny@example.com",
    "first_name": "Jenny",
    "last_name": "Rosen",
    "country": "DE",
    "phone": "+491701234567",
    "address": "Kurfuerstendamm 21",
    "city": "Berlin",
    "zip": "10719"
  },
  "description": "Order #1234",
  "metadata": {
    "order_id": "ord_1234",
    "sku": "WIDGET-XL"
  }
}
'
{
  "id": "pay_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "object": "payment",
  "amount": 4999,
  "currency": "eur",
  "status": "pending",
  "description": "Order #1234",
  "card": {
    "brand": null,
    "last4": "1111",
    "exp_month": null,
    "exp_year": null,
    "country": null
  },
  "customer": {
    "email": "jenny@example.com",
    "name": "Jenny Rosen"
  },
  "metadata": {
    "order_id": "ord_1234",
    "sku": "WIDGET-XL"
  },
  "decline_code": null,
  "decline_message": null,
  "redirect_url": null,
  "refunded_at": null,
  "succeeded_at": null,
  "failed_at": null,
  "created": 1719792000,
  "livemode": false,
  "refunded_amount": 0,
  "refunds": [],
  "next_action": null
}

Authorizations

Authorization
string
header
required

Use your secret API key as the Bearer token. Test (sandbox) mode keys start with fl_test_sk_ and live mode keys start with fl_live_sk_. Both modes use the same API host; the mode is determined by the key.

Authorization: Bearer fl_test_sk_abc123def456

Headers

Idempotency-Key
string

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 (HTTP 2xx), the cached response is returned. Non-2xx responses are not cached, so you may freely retry on errors. Keys expire after 24 hours.

For one-shot requests (e.g. creating a payment from a checkout button) a random UUIDv4 is fine. For requests tied to a specific business operation (e.g. refunding order #1234) a deterministic key like refund-order-1234 is preferred so retries collapse correctly across processes.

Maximum string length: 255

Body

application/json
amount
integer<int64>
required

The payment amount in minor units (smallest currency unit). For EUR, 4999 means EUR 49.99. Must be a positive integer.

Required range: x >= 1
Example:

4999

currency
enum<string>
required

Three-letter ISO 4217 currency code in lowercase.

Available options:
eur,
usd,
gbp
Example:

"eur"

card
object
required
customer
object
description
string

An arbitrary string to attach to the payment for your records.

Maximum string length: 500
Example:

"Order #1234"

metadata
object

A set of key-value pairs for storing additional information about the payment. Maximum 50 keys; each value up to 500 characters. Key length is recommended to stay within 40 characters.

Example:
{
"order_id": "ord_1234",
"sku": "WIDGET-XL"
}
return_url
string<uri>

URL the customer is redirected to after completing or abandoning 3D Secure authentication. Must use https (or http://localhost for local development). Required when 3DS is triggered for the payment.

Response

Payment created successfully.

A Payment object represents a single attempt to move money. It is created when you submit a payment request and is updated as the payment progresses through its lifecycle.

id
string
required

Unique identifier for the payment (pay_ prefix + UUID).

Pattern: ^pay_[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$
Example:

"pay_a1b2c3d4-e5f6-7890-abcd-ef1234567890"

object
enum<string>
required

Object type; always payment.

Available options:
payment
Example:

"payment"

amount
integer<int64>
required

The payment amount in minor units.

Example:

4999

currency
string
required

Three-letter ISO 4217 currency code.

Example:

"eur"

status
enum<string>
required

The current status of the payment.

  • pending -- The payment has been created and is being processed asynchronously.
  • succeeded -- The payment was successful. A succeeded payment may have refunds; check refunds array and refunded_amount.
  • failed -- The payment was declined or failed.
  • requires_action -- The payment requires customer action (e.g. 3D Secure authentication). Redirect the customer to next_action.redirect_url.
  • expired -- The required customer action (e.g. 3D Secure challenge) was not completed in time.
  • canceled -- The payment was canceled before completion.
Available options:
pending,
succeeded,
failed,
requires_action,
expired,
canceled
Example:

"succeeded"

created
integer<int64>
required

Unix timestamp when the payment was created.

Example:

1719792000

livemode
boolean
required

Whether this payment was created using a live API key (true) or a test API key (false).

Example:

false

description
string | null

The description attached to the payment.

Example:

"Order #1234"

card
object

The masked card details. null for HPP payments that have not yet been completed.

customer
object

The customer associated with the payment.

metadata
object

Arbitrary key-value metadata attached to the payment.

Example:
{ "order_id": "ord_1234" }
decline_code
string | null

If the payment was declined, the decline code indicating the reason. Common codes include insufficient_funds, expired_card, lost_card, stolen_card, and do_not_honor. For 3D Secure failures the code is one of three_d_secure_failed, three_d_secure_timeout, three_d_secure_not_supported, or three_d_secure_error. See the decline codes reference for the full list, and 3D Secure Declines for 3DS-specific codes.

Example:

null

decline_message
string | null

If the payment was declined, a human-readable message explaining why.

Example:

null

redirect_url
string<uri> | null

For HPP payments, the URL of the hosted payment page to redirect the customer to. null for direct API payments.

Example:

null

refunded_at
integer<int64> | null

Unix timestamp when the payment was fully refunded (refunded_amount equals the original amount), or null if not fully refunded.

Example:

null

succeeded_at
integer<int64> | null

Unix timestamp when the payment succeeded, or null if not yet succeeded.

Example:

1719792000

failed_at
integer<int64> | null

Unix timestamp when the payment failed, or null if not failed.

Example:

null

next_action
object

Present (non-null) when status is requires_action. Contains information needed to complete the payment. Otherwise null.

refunded_amount
integer<int64>

Total amount refunded so far, in minor units. This accumulates across partial refunds (only succeeded refunds contribute to the total).

Example:

0

provider_transaction_id
string | null

The payment service provider's reference for this transaction. Useful for dispute resolution and reconciliation with your PSP. null while the payment is still being submitted to the provider.

Example:

"1402758057"

refunds
object[]

All refunds on this payment, oldest first. Each entry is created by a call to POST /v1/payments/{id}/refund. A refund starts as pending and transitions to succeeded or failed.