If you have any questions or need help with the APIs, you can open a ticket on our support portal. Click on the button below to open a ticket.
As a Payment Service Provider (PSP), FlowPay is regulated by the Bank of Italy and we are authorised to provide payment services to our customers.
We believe that the best API a payment institution can provide is one that is tailored to the payment use case, allowing customers to focus on their business and not the payment process.
On the end user side, FlowPay ensures that users own their data, can access it at any time and fully manage it. They can choose which data to share with third parties in the most transparent way possible.
FlowPay welcomes contributions from partners. The OpenAPI file is publicly available on GitHub: FlowPay/client-openapi.
Partners can propose changes by forking the repository and submitting a pull request.
The APIs are REST over HTTPS. Some endpoints are restricted; partners must register their application and obtain an API key from the developer portal to access them. API keys can be rotated, scoped, and revoked at any time from the backoffice.
FlowPay is authorised to provide AIS. In the Simplified Flow model, consents are collected directly by FlowPay via a hosted flow to minimise partner burden.
Endpoints:
POST /ais/consents: create a consent session; returns a link to complete SCA with the bank.GET /ais/consents/{consentId}: retrieve consent status (pending, active, expired, ...).GET /ais/accounts: list available bank accounts under active consents.GET /ais/accounts/{accountId}/balances: current and available balances.GET /ais/accounts/{accountId}/transactions: list transactions, filterable by date.For field-level semantics, see the AIS schema descriptions in the OpenAPI file. In short: bookingDate is the booking/posting date, valueDate is the bank's effective/value date when provided, and category is best-effort transaction enrichment rather than a normalized taxonomy. On the consent side, canceled means the flow stopped before authorization, while revoked means an already-authorized consent was withdrawn.
If no active consent exists, AIS endpoints return 403 and partners can create a new consent using the consent endpoint.
When a consent session has expired, the consent-session PATCH operation can be used to re-arm it with a minimal body. Any field omitted in the request is inherited from the existing session, so callers only need to send the values they want to change.
FlowPay is an authorised PIS Provider (PISP). In the Simplified Flow, partners create Request To Pay objects and direct users to a hosted checkout to perform Strong Customer Authentication with their bank and authorise the payment.
APIs allow users to initiate traditional payment types:
In addition, FlowPay extends traditional payment methods by providing value-added services such as
docs/payment_chain.md.Each of these services may route funds via a FlowPay technical account when required by business rules, while preserving original payer/payee information in remittance data.
Partners register their application in the developer portal (https://developer.flowpay.it) and obtain one or more API keys with configurable scopes. Keys can be rotated or revoked at any time. Access to the portal requires a company account enabled for FlowPay services.
FlowPay provides a sandbox environment to allow partners to test the APIs before going into production. The sandbox is a safe space where you can experiment with the APIs without affecting real accounts or transactions.
FlowPay APIs implement offset-based pagination on all list endpoints, following a standard response structure.
When requesting a paginated resource, the following query parameters are supported:
limit (integer): the maximum number of items to return. Default is 50, maximum is 100.offset (integer): the number of items to skip before starting to return results.Each paginated response follows the PaginatedResult format:
total: total number of available items.limit: maximum number of items returned in this page (as requested).offset: number of items skipped from the beginning of the collection.count: number of items actually returned in this response.items: array of objects representing the current page results.### Request
GET /payment-requests?limit=20&offset=0
X-API-Key: {api_key}
{
"total": 147,
"limit": 20,
"offset": 0,
"count": 20,
"items": [
{
"id": "req_12345",
"amount": 1000,
"currency": "EUR",
"created_at": "2024-06-01T10:00:00Z",
"status": "created"
}
]
}
This structure allows clients to calculate pagination UI and control navigation across multiple pages using offset and limit.
Requests are limited to 100 requests per minute per source IP; exceeding this limit results in 429 responses. A burst limit of 10 requests per second also applies. Production limits can be customised per partner on request.
Retrieve the list of banks supported by FlowPay
| country | string Example: country=IT Country code (ISO 3166-1 alpha-2) to filter banks by country |
| recurring | boolean Filter banks that support at least one recurring payment type |
| recurringFrequency | Array of strings Items Enum: "monthly" "everyTwoMonths" "quarterly" "semiAnnual" "daily" "everyFourMonths" "weekly" "everyTwoWeeks" "annual" Filter banks that support the specified recurring payment frequency |
| sctType | Array of strings Items Enum: "standard" "instant" Filter banks that support the specified SCT type |
[- {
- "name": "Intesa Sanpaolo",
- "nationalID": "03999",
- "id": "intesa_sanpaolo",
- "countries": [
- "IT"
], - "features": {
- "futurePayments": true,
- "sct": [
- "standard"
], - "recurringPayments": [
- "monthly"
]
}
}
]Retrieve details of a specific bank
| id required | string Example: cassa_di_risparmio_di_orvieto Bank identifier |
{- "name": "Intesa Sanpaolo",
- "nationalID": "03999",
- "id": "intesa_sanpaolo",
- "countries": [
- "IT"
], - "features": {
- "futurePayments": true,
- "sct": [
- "standard"
], - "recurringPayments": [
- "monthly"
]
}
}Returns a paginated list of all created payment requests.
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "chargeId": "aec0aceb-a4db-49fb-b366-75e90229c640",
- "createdAt": "2019-08-24T14:15:22Z",
- "amount": 0.01,
- "currency": "string",
- "payerId": "f612112b-802d-496d-9650-880c09cb2f34",
- "debtorId": "0e24973d-821c-4f49-b6cd-c5f93b86e51d",
- "privateAttachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "remittanceInformation": "string",
- "paymentMethodId": "b6df8625-cd25-4123-b345-638aa7b5d011",
- "customerId": "87d8e330-2878-4742-a86f-dbbb3bf522ac",
- "refundId": "3324897f-393a-4bf6-b3af-0b999cbc2521"
}
]
}Creates a charge using a tokenized payment method. This endpoint is also used to release funds from a locked payment by charging the dedicated technical payment method of type locked. In that case the amount is implicit in the locked token and equals the original locked amount.
Object containing charge details or, for locked flows, the release details for a dedicated technical payment method.
| paymentRequestId required | string <uuid> UUID of the existing payment request to charge. |
| tokenId required | string <uuid> ID of the tokenized payment method to use for the charge. For locked flows, this is the dedicated technical payment method exposed once the initial collection has been reconciled. |
PhoneNumber (string) or string or object Information about the payment payee. For locked-payment release, use this field only when the final payout destination was not already available at creation time. |
{- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "tokenId": "07dfef4c-e677-4ce6-87a3-cd348338445f",
- "payee": "string"
}{- "lockedUntil": "2019-08-24T14:15:22Z",
- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "bulkIntentId": "12e10d33-d79f-4277-8482-e5518032a560",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "createdAt": "2019-08-24T14:15:22Z",
- "amount": 0.01,
- "currency": "string",
- "payerId": "f612112b-802d-496d-9650-880c09cb2f34",
- "debtorId": "0e24973d-821c-4f49-b6cd-c5f93b86e51d",
- "payeeId": "79417842-2e1e-4110-a361-89b9f39b36ed",
- "additionalPayees": [
- {
- "name": "string",
- "iban": "string",
- "amount": 0.01,
- "remittance": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lockedUntil": "2019-08-24T14:15:22Z",
- "status": "created",
- "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked"
}
}
], - "privateAttachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "title": "string",
- "description": "string",
- "remittanceInformation": "string",
- "allowRemittanceChange": false,
- "savePaymentMethod": false,
- "paymentMethod": {
- "technology": "openbanking",
- "iban": "string",
- "instant": true,
- "bank": "string"
}, - "dueDate": "2019-08-24T14:15:22Z",
- "lockedDetails": {
- "fundsOwner": "payer",
- "reconciliationStatus": "pending",
- "automaticRelease": {
- "scheduledFor": "2019-08-24T14:15:22Z",
- "status": "scheduled"
}, - "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked",
- "enabled": true,
- "amount": 0.01,
- "currency": "string",
- "beneficiaryId": "410e5c37-9603-4e5b-81b1-7cb895f362e8"
}
}, - "refundId": "3324897f-393a-4bf6-b3af-0b999cbc2521",
- "newCustomer": false,
- "allowedMethods": [
- "bankAccount"
], - "mode": "string",
- "paymentSessions": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "amount": 0.01,
- "intentId": "9b966aba-7d18-4a93-b6a8-43845b096776",
- "createdAt": "2019-08-24T14:15:22Z",
- "statuses": [
- {
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "message": "string"
}
], - "status": "created",
- "method": { }
}
]
}Webhook sent to the partner when a customer requests the deletion of their data from FlowPay under GDPR or other regulations.
| customerId required | string <uuid> UUID of the customer who requested deletion of their data. |
| requestedAt required | string <date-time> ISO 8601 timestamp when the customer requested deletion. |
{- "customerId": "87d8e330-2878-4742-a86f-dbbb3bf522ac",
- "requestedAt": "2019-08-24T14:15:22Z"
}{- "code": 0,
- "message": "string"
}Registra un customer. Restituisce 201 in caso di creazione o 409 in caso di duplicato.
| phoneNumber required | string Numero mobile del cliente (E.164) |
| services | Array of strings Items Value: "srtp" Servizi da attivare sul cliente |
| name | string Nome |
| surname | string Cognome |
| tin | string Codice fiscale (persona fisica) Optional when the customer entity already exists. |
string <email> Email del cliente | |
| webhookUrl | string <uri> Callback URL used when a service is created or updated. |
{- "phoneNumber": "+390000000001",
- "name": "Test",
- "surname": "Customer",
- "tin": "TSTCST00A00A000A",
- "email": "test.customer@example.com",
- "services": [
- "srtp"
]
}{- "id": "1a111111-2222-3333-4444-555555555555",
- "createdAt": "2025-10-06T12:00:00Z",
- "updatedAt": "2025-10-06T12:30:00Z",
- "type": "consumer",
- "client": "2b222222-3333-4444-5555-666666666666",
- "entity": "3c333333-4444-5555-6666-777777777777",
- "phoneNumber": "+390000000001",
- "name": "Test",
- "surname": "Customer",
- "tin": "TSTCST00A00A000A",
- "email": "test.customer@example.com",
- "address": "Example Street 1, Milano",
- "services": [
- {
- "service": "srtp"
}
]
}Returns the paginated list of customers, automatically populated when creating a payment request for a consumer or business payer.
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "type": "consumer",
- "client": "95b7f642-4812-4c19-ba03-689f2fdf42f8",
- "entity": "01deb6b6-4a1d-47db-89a2-ffb77f46ad2a",
- "phoneNumber": "string",
- "name": "string",
- "surname": "string",
- "businessName": "string",
- "tin": "string",
- "email": "user@example.com",
- "address": "string",
- "services": [
- {
- "service": "string"
}
]
}
]
}Returns the details of a specific customer by UUID.
| customerId required | string <uuid> UUID of the customer to retrieve. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "type": "consumer",
- "client": "95b7f642-4812-4c19-ba03-689f2fdf42f8",
- "entity": "01deb6b6-4a1d-47db-89a2-ffb77f46ad2a",
- "phoneNumber": "string",
- "name": "string",
- "surname": "string",
- "businessName": "string",
- "tin": "string",
- "email": "user@example.com",
- "address": "string",
- "services": [
- {
- "service": "string"
}
]
}Uploads a file and returns the ID of the uploaded file.
| file required | string <binary> The file to upload. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "createdAt": "2019-08-24T14:15:22Z",
- "fileName": "string",
- "fileSize": 0,
- "fileType": "string",
- "urlExpiresAt": "2019-08-24T14:15:22Z"
}Returns a paginated list of uploaded files.
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "createdAt": "2019-08-24T14:15:22Z",
- "fileName": "string",
- "fileSize": 0,
- "fileType": "string",
- "urlExpiresAt": "2019-08-24T14:15:22Z"
}
]
}Retrieves the details of an uploaded file specified by ID.
| fileId required | string <uuid> ID of the file to retrieve. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "createdAt": "2019-08-24T14:15:22Z",
- "fileName": "string",
- "fileSize": 0,
- "fileType": "string",
- "urlExpiresAt": "2019-08-24T14:15:22Z"
}Deletes an uploaded file specified by ID. Deletion is permanent only if the file is not associated with any payment request; otherwise the file is removed from public view but remains available for compliance checks.
| fileId required | string <uuid> ID of the file to delete. |
{- "code": 0,
- "message": "string"
}Returns a paginated list of tokenised payment methods.
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "card",
- "tokenizationDate": "2019-08-24T14:15:22Z",
- "enabled": true,
- "paymentSessionId": "75099bcf-22d5-43f9-8976-b7c5692eaa85",
- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "methodIdentifier": "string",
- "issuer": "string",
}
]
}
Creates a new tokenised payment method for future use.
| type required | string Enum: "card" "bankAccount" |
| callbackUrl | string <uri> Callback URL for notifications about the payment method status. |
| customerId | string <uuid> ID of the customer associated with the payment method. If not specified, the method is associated with the current customer. |
{- "type": "card",
- "customerId": "87d8e330-2878-4742-a86f-dbbb3bf522ac"
}{
}Returns the details of a tokenised payment method.
| paymentMethodId required | string <uuid> UUID of the payment method. |
{- "type": "card",
- "methodIdentifier": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "tokenizationDate": "2019-08-24T14:15:22Z",
- "enabled": true,
- "paymentSessionId": "75099bcf-22d5-43f9-8976-b7c5692eaa85",
- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "issuer": "string",
}Returns a paginated list of refunds created (one per payment session).
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "amount": 0.01,
- "createdAt": "2019-08-24T14:15:22Z",
- "status": "pending",
- "reason": "customerRequest",
- "additionalInfo": "string",
- "paymentMethodId": "b6df8625-cd25-4123-b345-638aa7b5d011",
- "customerId": "87d8e330-2878-4742-a86f-dbbb3bf522ac",
- "emailStatus": "notSent"
}
]
}Performs a refund for a specified payment session. The refund can be partial or total depending on the specified amount. In any case, the refund amount cannot exceed the amount of the payment session.
The refund is credited to the payment method used in the original payment session.
| sessionId required | string <uuid> ID of the payment session for which to create the refund. |
| amount required | number <decimal> >= 0.01 Refund amount as a decimal (e.g. 10.50). Must be less than or equal to the amount of the payment session. |
| reason required | string (RefundReason) Enum: "customerRequest" "fraudulentTransaction" "technicalError" "other" Reason for the refund. |
{- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "amount": 0.01,
- "reason": "customerRequest"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "amount": 0.01,
- "createdAt": "2019-08-24T14:15:22Z",
- "status": "pending",
- "reason": "customerRequest",
- "additionalInfo": "string",
- "paymentMethodId": "b6df8625-cd25-4123-b345-638aa7b5d011",
- "customerId": "87d8e330-2878-4742-a86f-dbbb3bf522ac",
- "emailStatus": "notSent"
}Returns the details of a refund. You can request the response in PDF format; in this case, a document including the refund details is produced and can be used as proof of refund.
| refundId required | string <uuid> UUID of the refund. |
| Accept | string Default: application/json Enum: "application/json" "application/pdf" Specifies the response format; use application/pdf to obtain a PDF document with a QR code and refund details. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "amount": 0.01,
- "createdAt": "2019-08-24T14:15:22Z",
- "status": "pending",
- "reason": "customerRequest",
- "additionalInfo": "string",
- "paymentMethodId": "b6df8625-cd25-4123-b345-638aa7b5d011",
- "customerId": "87d8e330-2878-4742-a86f-dbbb3bf522ac",
- "emailStatus": "notSent"
}This chapter explains how each Request To Pay (RTP) product works functionally: actors, lifecycle, routing, and constraints. Use it to understand behavior before jumping into payloads.
Simple RTP is the shortest path from a payment request to a successful bank transfer. Your backend creates a request that describes what the user is paying (title, description, remittance), who receives the funds (payee), and optional URLs for redirect and server‑to‑server callbacks. You receive a hosted checkout link where the user completes Strong Customer Authentication (SCA) with their bank. From the user’s perspective it’s a clean, guided flow; from your side you track status via callbacks and finalise your order by reading the request status from the API.
State evolution: a Simple RTP typically flows created → inProgress when the user starts checkout, then authorized on a successful SCA with the provider. Settlement goes straight to the payee (fast transition to forwarded); it passes through the Technical Account (onHold) only when the ultimateDebtor differs from the debtor (payer). User cancellations, OTP expirations, or bank denials keep the request non-terminal until a successful attempt occurs or the request expires. Refunds, when issued, move the request to refunded for the affected amount.
What it enables: one‑off payments, invoice settlement, donations, deposits, and any flow where a user authorises a bank transfer to a known beneficiary.
How to enable specific flavors (copy‑paste ready):
Set amount to the exact value you want to charge.
State evolution: most flows are linear. From created the first user attempt moves to inProgress; on a positive outcome the session is authorized and the request proceeds to forwarded. Settlement goes straight to the payee; the Technical Account (onHold) path applies only when ultimateDebtor ≠ debtor. Errors or cancellations do not change the aggregate state to terminal; a later successful attempt completes the flow. Post-settlement reversals are reflected as refunded.
BASE_URL="https://api.sandbox.flowpay.it/v2/"; API_KEY="sk_test_xxx"
curl -sS -X POST "$BASE_URL/payment-requests" -H "Content-Type: application/json" -H "X-API-Key: $API_KEY" -d '{
"payer": "+39 333 1234567",
"title": "Invoice #1001",
"description": "Settlement for invoice 1001",
"remittanceInformation": "INV-1001",
"amount": 49.90,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback"
}'
Omit amount entirely to let the payer enter the amount at checkout. Keep allowPartialPayments at its default (false). Enforce your business rules (min/max) when processing callbacks or before fulfilling the order.
State evolution: identical to fixed-amount, with the value chosen during checkout. Expect multiple inProgress attempts as the payer can re-enter and adjust the amount; only attempts that reach authorized affect the financial outcome. Settlement behaves like Simple RTP (direct to payee; Technical Account hop only if ultimateDebtor ≠ debtor); any reversal is reflected as refunded.
BASE_URL="https://api.sandbox.flowpay.it/v2/"; API_KEY="sk_test_xxx"
curl -sS -X POST "$BASE_URL/payment-requests" -H "Content-Type: application/json" -H "X-API-Key: $API_KEY" -d '{
"payer": "+39 333 1234567",
"title": "Donate to ACME Foundation",
"description": "Thank you for your support",
"remittanceInformation": "DON-2024-09",
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/thank-you",
"callbackUrl": "https://merchant.example.com/api/payment/callback"
}'
Optional: allow the payer to edit the remittance at checkout by setting allowRemittanceChange: true.
Set allowPartialPayments: true and provide the target amount to be fully settled across one or more sessions.
State evolution: each successful session independently reaches authorized and then forwarded for its portion. The request remains non-terminal until the cumulative authorized amount meets the target; it can cycle back to inProgress for additional attempts. Temporary onHold/locked can appear per session when funds pause on the Technical Account. Once the target is covered, the request is effectively complete in forwarded. Refunds operate per session without reopening the request.
BASE_URL="https://api.sandbox.flowpay.it/v2/"; API_KEY="sk_test_xxx"
curl -sS -X POST "$BASE_URL/payment-requests" -H "Content-Type: application/json" -H "X-API-Key: $API_KEY" -d '{
"payer": "+39 333 1234567",
"title": "Installments for Order #A2001",
"description": "Pay in multiple steps",
"remittanceInformation": "A2001",
"amount": 300.00,
"currency": "EUR",
"allowPartialPayments": true,
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback"
}'
To compute the outstanding: list sessions with /payment-requests/{requestId}/sessions, sum succeeded amounts, and subtract from the target amount.
Set executionDate (ISO 8601). The user authenticates now; execution occurs at/after the scheduled time (bank support dependent).
State evolution: after inProgress and authorized, the request remains pending execution until the scheduled time. You will not see forwarded until the bank executes. If execution fails or is revoked, the provider emits a negative outcome and the request converges to rejected. Refunds are available only after execution.
BASE_URL="https://api.sandbox.flowpay.it/v2/"; API_KEY="sk_test_xxx"
EXEC_AT="2025-01-10T10:00:00Z" # choose your date/time (UTC)
curl -sS -X POST "$BASE_URL/payment-requests" -H "Content-Type: application/json" -H "X-API-Key: $API_KEY" -d '{
"payer": "+39 333 1234567",
"title": "Scheduled payment",
"description": "Executes later",
"remittanceInformation": "SCH-10JAN",
"amount": 120.00,
"currency": "EUR",
"executionDate": "'"$EXEC_AT"'",
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback"
}'
Bulk turns many payouts into a single user authorisation. You compute a total amount and provide the allocation list with additional payees. The user performs SCA once; FlowPay collects the total and then splits it to the designated beneficiaries.
What it enables: mass invoice runs, bill aggregation, marketplace or platform settlements with a single frictionless checkout. Repeated beneficiaries in your allocation are grouped automatically. Keep allowPartialPayments disabled; if the sum of additional payees is less than the total, the remainder goes to the primary payee.
Mixed bulk can combine ordinary and locked movements. Set lockedUntil on an individual additionalPayees item to hold only that movement. A top-level lockedUntil applies only to the positive residual amount assigned to the main payee; it is not propagated to the additional payees, and the aggregate root remains a bulk request. Locked movements are not supported for split requests (ultimateDebtor: payee).
State evolution: authorization is single from the user’s perspective and the aggregate funding first lands on the Technical Account. After that collection is reconciled, ordinary movements follow the normal bulk dispatch flow. Each locked movement is instead funded into its own dedicated locked wallet and remains independent until early release, refund, or automatic release at its own lockedUntil. The aggregate can remain onHold while the collection is being reconciled and does not introduce a separate aggregate locked state for mixed or all-locked bulks.
When outcomes depend on a later verification (delivery, inspection, return window, milestone approval), use Locked payments. You specify a lockedUntil date; after a successful checkout the funds are held on FlowPay’s technical perimeter and attributed to a dedicated technical wallet for that operation. Before the date, the partner may release the funds to the beneficiary or refund the payer. If no earlier decision is taken, FlowPay automatically releases the funds to the beneficiary at lockedUntil.
What it enables: escrow‑like experiences, milestone‑based projects, dispute/return windows, and any flow where the partner needs immediate authorization but delayed availability to the beneficiary.
State evolution: after a successful checkout the session is authorized, may pass briefly through onHold while funds are reconciled, and then enters locked. From that state the partner may release early to the beneficiary or refund the payer. If no explicit action is taken, expiry leads to forwarded through automatic release. Additional user attempts do not alter funds that are already locked.
Split payment directs portions of a single checkout to different parties — for example, retaining a platform fee while paying a vendor. You define a primary payee and one or more additional payees with explicit amounts. The platform collects once and allocates the proceeds accordingly, preserving the original payer identity for beneficiaries.
What it enables: marketplaces, app stores, franchise models, partner revenue sharing with full transparency in remittances.
State evolution: similar to Bulk, the user authorizes once and funds always pass via the Technical Account, are processed immediately, and re-forwarded according to the split. The request may show a short onHold during dispatch, then advances to forwarded. Errors on outbound legs are handled by the dispatch engine and do not return the request to inProgress. Refunds mirror the original allocation proportions.
Payment Chain lets a partner create an RTP whose execution depends on funds expected later. The chain subject is the RTP payer and, when specified, the RTP debtor; the payout destination is defined by payee and, for split or bulk scenarios, additionalPayees.
What it enables: chained settlement, supplier or platform payouts funded by expected incoming FlowPay payments, convergence of multiple funding operations into one controlled technical position, and automatic execution of the RTP after the request amount is funded.
State evolution: the chain is created with the standard Request To Pay API and paymentMethod set to chain. After authorization it moves to authorized; once admitted funds arrive it uses onHold while FlowPay reconciles balance, amount, deadline, excesses, and operational conditions. When the reconciled balance reaches the RTP amount, FlowPay forwards the RTP payout to payee and additionalPayees. If the amount is not reached within the operational window, available funds are liquidated to the payer/debtor or the request is rejected if no valid liquidation path exists.
Detailed examples, lifecycle diagrams, and callback handling are documented in Payment Chain.
For public‑service payments in the Italian PagoPA ecosystem, RTP integrates a dedicated branch. You provide the entity tax code and payment notice number, and an email to receive the receipt. The hosted checkout guides the user through the PagoPA‑specific steps, while your integration pattern (redirects, callbacks, receipt download) remains the same.
What it enables: PagoPA notice payments with consistent checkout and server‑side integration semantics. Bulk isn’t natively supported with PagoPA; contact FlowPay for options.
State evolution: follows PagoPA’s own flow as defined in the Simplified Flow document. The request goes created → inProgress during the PagoPA journey, then to authorized on a positive PagoPA outcome, and to forwarded once remittance to the Creditor Entity completes. Invalid notices or cancellations converge to rejected. No Technical Account hop is used unless explicitly mandated by PagoPA reconciliation policies.
Provide the PagoPA‑specific fields (pagopaEcFiscalCode, pagopaPaymentNotice, email) alongside your standard request data.
BASE_URL="https://api.sandbox.flowpay.it/v2/"; API_KEY="sk_test_xxx"
curl -sS -X POST "$BASE_URL/payment-requests" -H "Content-Type: application/json" -H "X-API-Key: $API_KEY" -d '{
"payer": "+39 333 1234567",
"title": "PagoPA payment",
"description": "PagoPA notice 1234567890",
"remittanceInformation": "PPA-123",
"amount": 49.90,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback",
"pagopaEcFiscalCode": "01234567890",
"pagopaPaymentNotice": "123456789012345678",
"email": "payer@example.com"
}'
This section explains the lifecycle of a payment request as defined in the Simplified Flow document. The payment goes through well-defined states from creation to completion or termination.
lockedUntil.lockedUntil for locked payments.Final states are: deleted, forwarded, rejected, refunded.
This chapter collects hands‑on Request To Pay (RTP) examples and the technical explanation of how each use case works end‑to‑end. It covers actors, data fields, settlement paths, and status lifecycles so you can reason about behavior beyond the JSON payloads.
link. The user completes SCA with their bank at checkout. FlowPay sends callbackUrl events and redirects the user to redirectUrl with ?status.X-API-Key.created → inProgress → authorized → onHold/locked → forwarded or terminal rejected/refunded/deleted). Inspect attempts with /payment-requests/{requestId}/sessions (session statuses: succeeded, pending, expired, failed, cancelled).Inline example (Sandbox):
requestId + link.BASE_URL="https://api.sandbox.flowpay.it/v2/"
API_KEY="sk_test_xxx" # replace with yours
curl -sS -X POST "$BASE_URL/payment-requests" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"payer": "+39 333 1234567",
"title": "Order #A1001",
"description": "Payment for order A1001",
"remittanceInformation": "A1001",
"amount": 49.90,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/checkout/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback"
}'
link to complete payment.Verify and download receipt:
REQUEST_ID="..."
curl -sS -X GET "$BASE_URL/payment-requests/$REQUEST_ID" -H "X-API-Key: $API_KEY"
curl -sS -X GET \
-H "X-API-Key: $API_KEY" \
-H "Accept: application/pdf" \
"$BASE_URL/payment-requests/$REQUEST_ID" \
-o receipt.pdf
callbackUrl as the primary source of truth; use the APIs for on‑demand confirmation.amount, primary payee, and an array of additionalPayees with their individual amounts. The remainder flows to the primary payee.amount. Do not combine additionalPayees with allowPartialPayments=true.Set the total amount, define a primary payee, and list additionalPayees with their explicit amounts. Keep allowPartialPayments set to false. Ensure the sum of all additionalPayees.amount is less than or equal to the total; the remainder goes to the primary payee.
BASE_URL="https://api.sandbox.flowpay.it/v2/"
API_KEY="sk_test_xxx"
curl -sS -X POST "$BASE_URL/payment-requests" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"payer": "+39 333 1234567",
"title": "Order #SP-1001",
"description": "Split payment",
"remittanceInformation": "SP-1001",
"amount": 100.00,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback",
"payee": { "name": "ACME Vendor", "iban": "IT60X0542811101000000123456" },
"additionalPayees": [
{ "amount": 5.00, "name": "Platform Fee", "iban": "IT60X0542811101000000654321" }
],
"allowPartialPayments": false
}'
Notes:
remittanceInformation to correlate the whole order across all beneficiaries.lockedUntil (ISO 8601) at creation time. The beneficiary must be identified before authorization; final payout coordinates may already be known at creation time or completed later before release.locked. Before expiry you may retrieve the dedicated locked payment method and release the funds through POST /charges, or refund the payer through POST /refunds. If no explicit action is taken, FlowPay automatically releases the funds to the beneficiary at lockedUntil.Add lockedUntil (ISO 8601). After reconciliation, use GET /payment-requests/{requestId} to retrieve lockedDetails.lockedPaymentMethod.id. The webhook payload exposes the same technical method as payload.paymentMethod.id. Before expiry, either release the funds with POST /charges or refund the payer with POST /refunds.
BASE_URL="https://api.sandbox.flowpay.it/v2/"
API_KEY="sk_test_xxx"
LOCK_UNTIL=$(date -u -v+3d +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -u -d "+3 days" +"%Y-%m-%dT%H:%M:%SZ")
curl -sS -X POST "$BASE_URL/payment-requests" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"payer": "+39 333 1234567",
"title": "Escrow order #L-2001",
"description": "Locked until verification",
"remittanceInformation": "L-2001",
"amount": 59.00,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback",
"payee": { "name": "ACME Vendor", "iban": "IT60X0542811101000000123456" },
"lockedUntil": "'"$LOCK_UNTIL"'"
}'
Early release example:
REQUEST_ID="..." # from create response or callback
LOCKED_TOKEN_ID=$(curl -sS -X GET "$BASE_URL/payment-requests/$REQUEST_ID" \
-H "X-API-Key: $API_KEY" | jq -r '.lockedDetails.lockedPaymentMethod.id')
curl -sS -X POST "$BASE_URL/charges" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"tokenId": "'"$LOCKED_TOKEN_ID"'",
"payee": {
"name": "ACME Vendor",
"iban": "IT60X0542811101000000123456"
},
"remittanceInformation": "L-2001 RELEASE"
}'
Refund example (alternative final outcome):
SESSION_ID="..." # locked collection session id from sessions or callback
curl -sS -X POST "$BASE_URL/refunds" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"sessionId": "'"$SESSION_ID"'",
"amount": 59.00,
"reason": "other"
}'
Notes:
payee field of the locked release payload before expiry.callbackUrl as the primary orchestration signal and use GET /payment-requests/{requestId} as the recovery path if a webhook is missed.additionalPayees) but used for larger lists; total amount equals the sum of all components intended for beneficiaries.Compute the total amount as the sum of all components, set the primary payee, and provide the allocation list in additionalPayees. Keep allowPartialPayments set to false. Repeated beneficiaries are allowed; FlowPay groups them by IBAN+name during settlement.
BASE_URL="https://api.sandbox.flowpay.it/v2/"
API_KEY="sk_test_xxx"
curl -sS -X POST "$BASE_URL/payment-requests" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"payer": "+39 333 1234567",
"title": "Bulk order #B-9001",
"description": "Bulk payout to A,B,C",
"remittanceInformation": "B-9001",
"amount": 250.00,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback",
"payee": { "name": "Beneficiary A", "iban": "IT79Q0300203280941591243326" },
"additionalPayees": [
{ "amount": 50, "name": "Beneficiary B", "iban": "IT79Q0300203280941591243327" },
{ "amount": 25, "name": "Beneficiary C", "iban": "IT79Q0300203280941591243328" },
{ "amount": 75, "name": "Beneficiary A", "iban": "IT79Q0300203280941591243326" }
],
"allowPartialPayments": false
}'
Notes:
callbackUrl + GET /payment-requests/{id} for authoritative status.attachments (visible to payer at checkout) and privateAttachments (compliance‑only, not shown to payer).GET /payment-requests/{requestId} with Accept: application/pdf returns a PDF with details and a QR for device handoff; if paid, it acts as a receipt.BASE_URL="https://api.sandbox.flowpay.it/v2/"
API_KEY="sk_test_xxx"
# Upload (multipart)
FILE_ID=$(curl -sS -X POST "$BASE_URL/files" -H "X-API-Key: $API_KEY" -F "file=@./invoice.pdf;type=application/pdf" | jq -r .id)
# Create RTP with attachments
curl -sS -X POST "$BASE_URL/payment-requests" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"payer": "+39 333 1234567",
"title": "Order #A1002",
"description": "Payment with attachment",
"remittanceInformation": "A1002",
"amount": 129.00,
"currency": "EUR",
"redirectUrl": "https://merchant.example.com/checkout/return",
"callbackUrl": "https://merchant.example.com/api/payment/callback",
"attachments": ["'"$FILE_ID"'"]
}'
# Download receipt (PDF)
REQUEST_ID="..."
curl -sS -X GET -H "X-API-Key: $API_KEY" -H "Accept: application/pdf" "$BASE_URL/payment-requests/$REQUEST_ID" -o receipt.pdf
FlowPay delivers real-time, server-to-server notifications whenever a payment request changes state. Notifications are sent as HTTP POST requests to your configured callbackUrl and include the authoritative status you should use to advance your business flow. When in doubt, you can always query the latest state via GET /payment-requests/{requestId}.
There is a single, stable event for Request-to-Pay: payment.status_change. The current state is provided in the status field and reuses the API enum PaymentRequestStatus (created, inProgress, authorized, rejected, onHold, locked, forwarded, refunded, deleted). If the change originates from a specific checkout attempt, the event includes a sessionId. Multiple attempts may occur during a request’s lifecycle, and events may be delivered more than once; your handler must therefore be idempotent and tolerant of out-of-order delivery within the same requestId.
For locked payments, deliveries may also include an optional paymentMethod object inside the payload. When present, it identifies the dedicated technical payment method created for the locked flow; its id is the value to use as tokenId for an early release through POST /charges.
Deliveries use HTTPS POST with a JSON payload encoded in UTF‑8. The request carries headers that establish identity, integrity and replay protection. In particular, X-FlowPay-Event-Id uniquely identifies the delivery, X-FlowPay-Event-Type is always payment.status_change, X-FlowPay-Timestamp contains Unix epoch seconds, X-FlowPay-Signature holds a detached Ed25519 signature, X-FlowPay-Key-Id identifies the public key to use for verification, and X-FlowPay-Retry-Count indicates the attempt number starting at zero. Any HTTP 2xx response acknowledges the event.
In locked flows, treat the webhook paymentMethod as optional enrichment: use it when available, but always be prepared to recover the authoritative state with GET /payment-requests/{requestId}, which exposes lockedDetails.lockedPaymentMethod.id.
Every delivery is signed by FlowPay with a platform private key. The signature covers the exact bytes of the HTTP body prefixed by the timestamp. Specifically, construct payload = "{timestamp}.{rawBody}" and verify the Base64URL‑encoded Ed25519 signature from X-FlowPay-Signature using the public key indicated by X-FlowPay-Key-Id.
To validate a notification, read X-FlowPay-Timestamp, X-FlowPay-Signature and X-FlowPay-Key-Id; fetch the matching key from our well‑known JWKS; rebuild the payload from the raw HTTP body; and verify the signature using a constant‑time comparison. Reject messages older than five minutes to mitigate replay attacks.
Well‑known JWKS is published at /.well-known/jwks.json:
Implementation notes: we use Ed25519 (EdDSA on Curve25519). The X-FlowPay-Signature header is Base64URL without padding. In Ed25519 JWKs, the public key is carried in the x parameter (also Base64URL without padding).
Below are compact examples of signature verification using JWKS and Ed25519. Always use the raw HTTP request body, not a re‑serialized JSON string.
// Maven deps:
// <dependency>
// <groupId>com.nimbusds</groupId>
// <artifactId>nimbus-jose-jwt</artifactId>
// <version>9.37.3</version>
// </dependency>
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.util.Base64URL;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.security.Signature;
public class FlowPayWebhookVerifier {
public static boolean verify(
String jwksUrl,
String kid,
String timestamp,
String signatureB64Url,
byte[] rawBody
) throws Exception {
JWKSet jwkSet = JWKSet.load(new URL(jwksUrl));
JWK jwk = jwkSet.getKeyByKeyId(kid);
if (!(jwk instanceof OctetKeyPair) || !"Ed25519".equals(((OctetKeyPair) jwk).getCurve().getName())) {
throw new IllegalArgumentException("Unsupported JWK or curve");
}
PublicKey publicKey = ((OctetKeyPair) jwk).toPublicKey();
byte[] message = (timestamp + ".").getBytes(StandardCharsets.UTF_8);
byte[] payload = new byte[message.length + rawBody.length];
System.arraycopy(message, 0, payload, 0, message.length);
System.arraycopy(rawBody, 0, payload, message.length, rawBody.length);
byte[] signature = Base64URL.from(signatureB64Url).decode();
Signature verifier = Signature.getInstance("Ed25519");
verifier.initVerify(publicKey);
verifier.update(payload);
return verifier.verify(signature);
}
}
// npm i tweetnacl
import nacl from "tweetnacl";
function b64urlToUint8(b64url) {
const b64 =
b64url.replace(/-/g, "+").replace(/_/g, "/") +
"=".repeat((4 - (b64url.length % 4)) % 4);
return new Uint8Array(Buffer.from(b64, "base64"));
}
export async function verifyFlowPay({
jwksUrl,
kid,
timestamp,
signatureB64Url,
rawBodyBytes,
}) {
const res = await fetch(jwksUrl);
const { keys } = await res.json();
const jwk = keys.find(
(k) => k.kid === kid && k.kty === "OKP" && k.crv === "Ed25519"
);
if (!jwk) throw new Error("Key not found");
const publicKey = b64urlToUint8(jwk.x);
const signature = b64urlToUint8(signatureB64Url);
const prefix = new TextEncoder().encode(`${timestamp}.`);
const msg = new Uint8Array(prefix.length + rawBodyBytes.length);
msg.set(prefix);
msg.set(rawBodyBytes, prefix.length);
return nacl.sign.detached.verify(msg, signature, publicKey);
}
import Foundation
import CryptoKit
func base64URLDecode(_ s: String) -> Data? {
var str = s.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
let padLen = 4 - (str.count % 4)
if padLen < 4 { str += String(repeating: "=", count: padLen) }
return Data(base64Encoded: str)
}
func verifyFlowPay(jwksJson: Data, kid: String, timestamp: String, signatureB64Url: String, rawBody: Data) throws -> Bool {
let jwks = try JSONSerialization.jsonObject(with: jwksJson) as! [String: Any]
guard let keys = jwks["keys"] as? [[String: Any]],
let key = keys.first(where: { ($0["kid"] as? String) == kid && ($0["kty"] as? String) == "OKP" && ($0["crv"] as? String) == "Ed25519" }),
let xStr = key["x"] as? String,
let x = base64URLDecode(xStr),
let sig = base64URLDecode(signatureB64Url) else {
return false
}
let publicKey = try Curve25519.Signing.PublicKey(rawRepresentation: x)
var message = Data((timestamp + ".").utf8)
message.append(rawBody)
return publicKey.isValidSignature(sig, for: message)
}
FlowPay uses at‑least‑once delivery with exponential backoff and jitter over a multi‑hour window. Retries occur on network errors, timeouts and non‑2xx responses; the current attempt is provided in X-FlowPay-Retry-Count starting from zero. Ordering within the same requestId is best‑effort and not strictly guaranteed. As soon as you persist the event safely, reply with any HTTP 2xx; redirects are not followed.
Use X-FlowPay-Event-Id as the natural idempotency key. Keep a record of processed IDs for at least seven days and return 2xx for already‑applied deliveries. Respond as soon as the event is durably stored; keep the response body empty or return a small acknowledgment such as { "ok": true }.
Prefer a dedicated, unguessable callbackUrl and, where possible, additional controls such as IP allow‑listing or mutual TLS. Keep your handler lean—enqueue downstream work and acknowledge quickly. Log the event headers and id to correlate deliveries with your internal processing during troubleshooting.
| X-FlowPay-Event-Id required | string <uuid> Unique identifier of this webhook delivery. Use for idempotency/deduplication. |
| X-FlowPay-Event-Type required | string Value: "payment.status_change" Event type. Always |
| X-FlowPay-Timestamp required | string UNIX epoch seconds used to compute the signature. |
| X-FlowPay-Signature required | string Detached signature over |
| X-FlowPay-Key-Id required | string Key identifier of the signing key. Fetch the public key from the well-known JWKS at |
| X-FlowPay-Retry-Count | integer >= 0 0 for first delivery, incremented on each retry. |
Payment event payload.
| id required | string <uuid> Unique identifier of this event (matches X-FlowPay-Event-Id). |
| createdAt required | string <date-time> Event creation time (ISO 8601). |
| requestId | string <uuid> Payment request identifier. |
| type required | string Value: "payment.status_change" Event type. |
object |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "createdAt": "2019-08-24T14:15:22Z",
- "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
- "type": "payment.status_change",
- "payload": {
- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "status": "created",
- "previousStatus": "created",
- "paymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked"
}
}
}{- "code": 0,
- "message": "string"
}Returns a paginated list of created payment requests. dateFrom and dateTo can be combined and apply to the request creation timestamp using inclusive bounds. Lifecycle status filtering belongs to payment-session lists and is not supported here.
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
| dateFrom | string <date-time> Example: dateFrom=2026-07-01T00:00:00Z Inclusive lower bound for the payment request |
| dateTo | string <date-time> Example: dateTo=2026-07-31T23:59:59Z Inclusive upper bound for the payment request |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "lockedUntil": "2019-08-24T14:15:22Z",
- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "bulkIntentId": "12e10d33-d79f-4277-8482-e5518032a560",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "createdAt": "2019-08-24T14:15:22Z",
- "amount": 0.01,
- "currency": "string",
- "payerId": "f612112b-802d-496d-9650-880c09cb2f34",
- "debtorId": "0e24973d-821c-4f49-b6cd-c5f93b86e51d",
- "payeeId": "79417842-2e1e-4110-a361-89b9f39b36ed",
- "additionalPayees": [
- {
- "name": "string",
- "iban": "string",
- "amount": 0.01,
- "remittance": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lockedUntil": "2019-08-24T14:15:22Z",
- "status": "created",
- "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked"
}
}
], - "privateAttachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "title": "string",
- "description": "string",
- "remittanceInformation": "string",
- "allowRemittanceChange": false,
- "savePaymentMethod": false,
- "paymentMethod": {
- "technology": "openbanking",
- "iban": "string",
- "instant": true,
- "bank": "string"
}, - "dueDate": "2019-08-24T14:15:22Z",
- "lockedDetails": {
- "fundsOwner": "payer",
- "reconciliationStatus": "pending",
- "automaticRelease": {
- "scheduledFor": "2019-08-24T14:15:22Z",
- "status": "scheduled"
}, - "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked",
- "enabled": true,
- "amount": 0.01,
- "currency": "string",
- "beneficiaryId": "410e5c37-9603-4e5b-81b1-7cb895f362e8"
}
}, - "refundId": "3324897f-393a-4bf6-b3af-0b999cbc2521",
- "newCustomer": false,
- "allowedMethods": [
- "bankAccount"
], - "mode": "string",
- "paymentSessions": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "amount": 0.01,
- "intentId": "9b966aba-7d18-4a93-b6a8-43845b096776",
- "createdAt": "2019-08-24T14:15:22Z",
- "statuses": [
- {
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "message": "string"
}
], - "status": "created",
- "method": { }
}
]
}
]
}Endpoint to create a payment request between two parties, specifying payer and payee details.
Object containing debtor, payee and payment details.
| amount | number <decimal> >= 0.01 Payment amount as a decimal (e.g. 10.50). |
PhoneNumber (string) or string or object Information about the payment payee. If not specified, the partner associated with the client and the IBAN configured for the client are used by default. | |
| allowPartialPayments | boolean Indicates whether to accept partial payments. If true, |
PhoneNumber (string) or Consumer (object) or UUID of the paying customer. (string) Information about the payer of the payment. It can be a phone number or a Consumer object. | |
ConsumerTIN (string) or BusinessTIN (string) or UUID of the debtor customer. (string) Information about the actual debtor of the payment. If not provided, the value of | |
| ultimateDebtor | string Default: "debtor" Enum: "debtor" "payee" "payer" "app" "anonymous" Determines who appears as the originator on the account statement or on the receipt. In the case of a PagoPA payment, this value is used to generate the receipt. ⚠️Warning
If different from
debtor, the payment is routed to a technical account and re-issued after the funds are received. |
| attachments | Array of strings <uuid> [ items <uuid > ] List of UUIDs of files attached to the payment that will be shown at checkout. These files must have been previously uploaded using the |
| privateAttachments | Array of strings <uuid> [ items <uuid > ] List of UUIDs of files attached to the payment that are visible only to FlowPay for compliance checks. These files are not shown to the payer during the payment process. |
| title | string [ 3 .. 50 ] characters Short title for the payment. Displayed to the payer during the payment process. |
| description | string [ 5 .. 255 ] characters Payment description, visible to the payer. |
| remittanceInformation | string [ 5 .. 100 ] characters Remittance information for the payment, visible to the payer and to the payee upon credit to the account. |
| allowRemittanceChange | boolean Default: false Indicates whether the payer can change remittance information during the payment. |
| allowedMethods | Array of strings (AllowedMethod) Items Enum: "bankAccount" "card" "bancomat" "charge" "chain" List of allowed payment technologies for this payment request. If not specified, all available technologies are allowed. |
Bank wire transfer (object) or Card (object) or BANCOMAT Pay (object) or Payment Chain (object) or Use saved payment method (object) (Technology) | |
string <email> Email address to which the payment receipt will be sent. Mandatory for PagoPA. | |
| redirectUrl | string <uri> Redirect URL to which the user is redirected with query parameter |
| callbackUrl | string <uri> Single callback URL for the payment. |
Array of Payment to mobile number (object) or Payment to IBAN (object) or Payment to customer (object) List of additional beneficiaries to whom part of the payment amount can be allocated. The sum of the amounts specified in additionalPayees cannot exceed amount; the difference between amount and the sum of additionalPayees will be sent to the payee. Each item may optionally include remittanceInformation to specify a dedicated reason for the individual payment; if absent, the remittanceInformation from the main request will be used. | |
| lockedUntil | string <date-time> Lock deadline for the main movement. Without additionalPayees, the request is a locked payment. In a bulk request, this field applies only to the positive residual amount assigned to the main payee; it is not propagated to additional payees and the aggregate root remains a bulk request. A bulk with top-level lockedUntil therefore requires amount to exceed the sum of additionalPayees amounts. Split requests (ultimateDebtor: payee) cannot contain locked movements. |
| savePaymentMethod | boolean Default: false Indicates whether to save the payment method for future use. |
{- "amount": 0.01,
- "payee": "string",
- "allowPartialPayments": false,
- "additionalPayees": [
- {
- "amount": 0.01,
- "phoneNumber": "string",
- "remittanceInformation": "string",
- "lockedUntil": "2019-08-24T14:15:22Z"
}
], - "lockedUntil": "2019-08-24T14:15:22Z",
- "savePaymentMethod": false,
- "payer": "string",
- "debtor": "string",
- "ultimateDebtor": "debtor",
- "attachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "privateAttachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "title": "string",
- "description": "string",
- "remittanceInformation": "string",
- "allowRemittanceChange": false,
- "allowedMethods": [
- "bankAccount"
], - "paymentMethod": {
- "technology": "openbanking",
- "iban": "string",
- "instant": true,
- "bank": "string"
}, - "email": "user@example.com",
}{- "lockedUntil": "2019-08-24T14:15:22Z",
- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "bulkIntentId": "12e10d33-d79f-4277-8482-e5518032a560",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "createdAt": "2019-08-24T14:15:22Z",
- "amount": 0.01,
- "currency": "string",
- "payerId": "f612112b-802d-496d-9650-880c09cb2f34",
- "debtorId": "0e24973d-821c-4f49-b6cd-c5f93b86e51d",
- "payeeId": "79417842-2e1e-4110-a361-89b9f39b36ed",
- "additionalPayees": [
- {
- "name": "string",
- "iban": "string",
- "amount": 0.01,
- "remittance": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lockedUntil": "2019-08-24T14:15:22Z",
- "status": "created",
- "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked"
}
}
], - "privateAttachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "title": "string",
- "description": "string",
- "remittanceInformation": "string",
- "allowRemittanceChange": false,
- "savePaymentMethod": false,
- "paymentMethod": {
- "technology": "openbanking",
- "iban": "string",
- "instant": true,
- "bank": "string"
}, - "dueDate": "2019-08-24T14:15:22Z",
- "lockedDetails": {
- "fundsOwner": "payer",
- "reconciliationStatus": "pending",
- "automaticRelease": {
- "scheduledFor": "2019-08-24T14:15:22Z",
- "status": "scheduled"
}, - "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked",
- "enabled": true,
- "amount": 0.01,
- "currency": "string",
- "beneficiaryId": "410e5c37-9603-4e5b-81b1-7cb895f362e8"
}
}, - "refundId": "3324897f-393a-4bf6-b3af-0b999cbc2521",
- "newCustomer": false,
- "allowedMethods": [
- "bankAccount"
], - "mode": "string",
- "paymentSessions": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "amount": 0.01,
- "intentId": "9b966aba-7d18-4a93-b6a8-43845b096776",
- "createdAt": "2019-08-24T14:15:22Z",
- "statuses": [
- {
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "message": "string"
}
], - "status": "created",
- "method": { }
}
]
}Returns details and status of the specified payment request.
The PDF document includes the payment request details and a QR code for mobile opening. If the request has been paid, it also contains the payment information and serves as a receipt.
| requestId required | string Identifier of the payment request for which to retrieve the status. |
| Accept | string Default: application/json Enum: "application/json" "application/pdf" Specifies the desired response format; use application/pdf to obtain a PDF document. |
{- "lockedUntil": "2019-08-24T14:15:22Z",
- "paymentRequestId": "e1d5fdf3-f4c6-4ab6-a2c0-11174dd3f66b",
- "bulkIntentId": "12e10d33-d79f-4277-8482-e5518032a560",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "createdAt": "2019-08-24T14:15:22Z",
- "amount": 0.01,
- "currency": "string",
- "payerId": "f612112b-802d-496d-9650-880c09cb2f34",
- "debtorId": "0e24973d-821c-4f49-b6cd-c5f93b86e51d",
- "payeeId": "79417842-2e1e-4110-a361-89b9f39b36ed",
- "additionalPayees": [
- {
- "name": "string",
- "iban": "string",
- "amount": 0.01,
- "remittance": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lockedUntil": "2019-08-24T14:15:22Z",
- "status": "created",
- "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked"
}
}
], - "privateAttachments": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "title": "string",
- "description": "string",
- "remittanceInformation": "string",
- "allowRemittanceChange": false,
- "savePaymentMethod": false,
- "paymentMethod": {
- "technology": "openbanking",
- "iban": "string",
- "instant": true,
- "bank": "string"
}, - "dueDate": "2019-08-24T14:15:22Z",
- "lockedDetails": {
- "fundsOwner": "payer",
- "reconciliationStatus": "pending",
- "automaticRelease": {
- "scheduledFor": "2019-08-24T14:15:22Z",
- "status": "scheduled"
}, - "lockedPaymentMethod": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "type": "locked",
- "enabled": true,
- "amount": 0.01,
- "currency": "string",
- "beneficiaryId": "410e5c37-9603-4e5b-81b1-7cb895f362e8"
}
}, - "refundId": "3324897f-393a-4bf6-b3af-0b999cbc2521",
- "newCustomer": false,
- "allowedMethods": [
- "bankAccount"
], - "mode": "string",
- "paymentSessions": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "amount": 0.01,
- "intentId": "9b966aba-7d18-4a93-b6a8-43845b096776",
- "createdAt": "2019-08-24T14:15:22Z",
- "statuses": [
- {
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "message": "string"
}
], - "status": "created",
- "method": { }
}
]
}Deletes the specified payment request. It can be done only if no payment has been initiated.
| requestId required | string <uuid> UUID of the payment request to delete. |
{- "code": 0,
- "message": "string"
}Convenience endpoint: returns the list of payment sessions (attempts) for the specified request. Ideal for hierarchical navigation.
| requestId required | string <uuid> UUID of the payment request. |
[- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "amount": 0.01,
- "intentId": "9b966aba-7d18-4a93-b6a8-43845b096776",
- "createdAt": "2019-08-24T14:15:22Z",
- "statuses": [
- {
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "message": "string"
}
], - "status": "created",
- "method": { }
}
]Primary resource for global queries on payment sessions. Supports filters, including requestId to select sessions for a specific request.
| limit | integer Default: 20 Maximum number of items per page. |
| offset | integer Default: 0 Number of items to skip. |
| requestId required | string <uuid> ID of the payment request to filter associated sessions. |
| status | string Enum: "created" "inProgress" "authorized" "rejected" "onHold" "locked" "forwarded" "refunded" "deleted" Payment session status to filter by. |
{- "total": 0,
- "limit": 0,
- "offset": 0,
- "count": 0,
- "items": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "amount": 0.01,
- "intentId": "9b966aba-7d18-4a93-b6a8-43845b096776",
- "createdAt": "2019-08-24T14:15:22Z",
- "statuses": [
- {
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "message": "string"
}
], - "status": "created",
- "method": { }
}
]
}FlowPay sends AIS consent webhooks to the callbackUrl configured on the consent session. A webhook is queued only after FlowPay persists a local consent status transition with a matching event type.
Events:
consent.authorized: the consent was finalized successfully.consent.denied: the consent flow failed or was denied.consent.canceled: a pending or initiated consent was canceled.consent.revoked: an authorized consent was explicitly revoked.consent.expired: an authorized consent is no longer valid according to the banking connector.No webhook is emitted for pending or initiated.
The consent.authorized event is normally queued when the user returns from the SCA flow and FlowPay receives the redirect result. If that redirect is missed, FlowPay can still discover an already-authorized consent during a later consent detail or AIS data-read call, then persist authorized and queue the same event.
Delivery is retried when the partner endpoint returns a non-2xx status or the HTTP request fails. Return any 2xx response to acknowledge the webhook. Retries use exponential backoff with jitter and preserve the same eventId across attempts; use X-FlowPay-Event-Id for idempotency.
Each request is signed with Ed25519. Verify X-FlowPay-Signature against the exact raw request body using:
X-FlowPay-Timestamp + "." + rawBody
Fetch the public key identified by X-FlowPay-Key-Id from /.well-known/jwks.json.
| X-FlowPay-Event-Id required | string <uuid> Unique identifier of this AIS consent event. Reused across retries; use for idempotency and deduplication. |
| X-FlowPay-Event-Type required | string (AisConsentWebhookEventType) Enum: "consent.authorized" "consent.denied" "consent.canceled" "consent.revoked" "consent.expired" AIS consent event type. |
| X-FlowPay-Timestamp required | string UNIX epoch seconds used to compute the signature. |
| X-FlowPay-Signature required | string Detached Ed25519 signature over |
| X-FlowPay-Key-Id required | string Key identifier of the signing key. Fetch the public key from |
| X-FlowPay-Retry-Count | integer >= 0 Zero-based delivery attempt index. |
AIS consent event payload.
| eventId required | string <uuid> Stable event identifier. Matches |
| eventType required | string (AisConsentWebhookEventType) Enum: "consent.authorized" "consent.denied" "consent.canceled" "consent.revoked" "consent.expired" AIS consent webhook event type emitted after a persisted local consent status transition. |
| timestamp required | string <date-time> Event creation timestamp. |
required | object (AisConsentWebhookPayload) |
{- "eventId": "6f43a2a7-94e1-423d-a0b1-9b21e955e3df",
- "eventType": "consent.authorized",
- "timestamp": "2026-03-12T14:15:22Z",
- "payload": {
- "sessionId": "00000000-0000-0000-0000-000000000000",
- "appId": "11111111-1111-1111-1111-111111111111",
- "status": "authorized",
- "previousStatus": "initiated",
- "authorizedAt": "2026-03-12T14:15:20Z",
- "validUntil": "2026-09-08T14:15:20Z",
- "version": 3
}
}{- "message": "string",
- "details": { }
}Checks whether an IBAN is associated with the supplied VAT code for the authenticated client application.
| iban required | string (IBAN) ^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$ IBAN to check. |
| vatCode required | string VAT code or tax identifier to match against the IBAN owner. |
{- "result": "valid"
}Creates a new AIS consent session and returns the identifiers required to drive the SCA journey. Use idempotencyKey to safely retry while the session stays pending.
| idempotencyKey | string Optional key to make creation idempotent while the session is pending. |
| fullName | string <= 200 characters End-user full name to display in the consent journey. |
| bankId | string FlowPay bank identifier to preselect the ASPSP. |
| consentKind | string (AisConsentKind) Enum: "one_off" "recurring" Defines whether the consent is one-off or recurring. |
| services | Array of strings (AisService) Items Enum: "accounts" "balances" "transactions" Subset of AIS services requested. Defaults to all when omitted. |
| callbackUrl | string <uri> URL that will receive webhook notifications. |
| redirectUrl | string <uri> URL where the user should be redirected after completing SCA. |
{- "idempotencyKey": "string",
- "fullName": "string",
- "bankId": "string",
- "consentKind": "one_off",
- "services": [
- "accounts"
],
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "idempotent": true
}Returns consent sessions owned by the authenticated application. Filters can be combined and results are paginated.
| status | Array of strings (AisConsentStatus) Items Enum: "pending" "initiated" "authorized" "denied" "canceled" "expired" "revoked" Filter by consent status. |
| bankId | string Filter by FlowPay bank identifier. |
| consentKind | string (AisConsentKind) Enum: "one_off" "recurring" Filter by consent kind. |
| createdFrom | string <date-time> Example: createdFrom=2026-07-01T00:00:00Z Lower bound (inclusive) for |
| createdTo | string <date-time> Example: createdTo=2026-07-31T23:59:59Z Upper bound (inclusive) for |
| page | integer >= 1 Default: 1 Page number (1-based). |
| per | integer [ 1 .. 200 ] Default: 50 Page size. |
{- "items": [
- {
- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "status": "pending",
- "consentKind": "one_off",
- "services": [
- "accounts"
], - "bankId": "string",
- "fullName": "string",
- "idempotencyKey": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "firstOpenedAt": "2019-08-24T14:15:22Z",
- "authorizedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z",
- "lastError": "string"
}
], - "page": 0,
- "per": 0,
- "hasNext": true
}| consentSessionId required | string <uuid> UUID of the AIS consent session. |
{- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "status": "pending",
- "consentKind": "one_off",
- "services": [
- "accounts"
], - "bankId": "string",
- "fullName": "string",
- "idempotencyKey": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "firstOpenedAt": "2019-08-24T14:15:22Z",
- "authorizedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z",
- "lastError": "string"
}Allows updating mutable fields while the session is still pending. If the session has expired, the same request re-arms it as a fresh pending attempt while reusing the stored values for omitted fields. Other terminal states remain rejected.
| consentSessionId required | string <uuid> UUID of the AIS consent session. |
| idempotencyKey required | string Overrides the idempotency key if it is not used elsewhere. |
| fullName required | string <= 200 characters End-user full name to display in the consent journey. |
| bankId required | string FlowPay bank identifier to preselect the ASPSP. |
| consentKind required | string (AisConsentKind) Enum: "one_off" "recurring" Defines whether the consent is one-off or recurring. |
| services required | Array of strings (AisService) Items Enum: "accounts" "balances" "transactions" AIS services requested from the bank. |
| callbackUrl required | string <uri> URL that will receive webhook notifications. |
| redirectUrl required | string <uri> URL where the user should be redirected after completing SCA. |
{- "idempotencyKey": "string",
- "fullName": "string",
- "bankId": "string",
- "consentKind": "one_off",
- "services": [
- "accounts"
],
}{- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "status": "pending",
- "consentKind": "one_off",
- "services": [
- "accounts"
], - "bankId": "string",
- "fullName": "string",
- "idempotencyKey": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "firstOpenedAt": "2019-08-24T14:15:22Z",
- "authorizedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z",
- "lastError": "string"
}Cancels pending or initiated sessions and revokes authorized ones, which emits the consent.revoked webhook from the engine. Sandbox/provider-driven revoke callbacks may not be available, so exercise the path through the engine delete flow when validating webhooks.
| consentSessionId required | string <uuid> UUID of the AIS consent session. |
{- "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "status": "pending",
- "consentKind": "one_off",
- "services": [
- "accounts"
], - "bankId": "string",
- "fullName": "string",
- "idempotencyKey": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "firstOpenedAt": "2019-08-24T14:15:22Z",
- "authorizedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z",
- "lastError": "string"
}Retrieves the bank authorization URL to redirect the end-user. The first call transitions the session to initiated.
| consentSessionId required | string <uuid> UUID of the AIS consent session. |
{
}| consentSessionId required | string <uuid> UUID of the AIS consent session. |
| page | integer >= 1 Default: 1 Page number (1-based). |
| per | integer [ 1 .. 200 ] Default: 50 Page size. |
{- "items": [
- {
- "accountId": "IT60X0542811101000000123456",
- "iban": "IT60X0542811101000000123456",
- "name": "Main account",
- "currency": "EUR",
- "closingBooked": 5174.72,
- "interimAvailable": 5200
}
], - "page": 0,
- "per": 0,
- "hasNext": true
}Returns the latest balances for the accounts granted by the consent. Each item contains fixed metadata plus dynamic numeric fields keyed by normalized bank balance type.
FlowPay returns all and only the balance types received from the bank. Not every bank provides every balance type, so the set of balance keys may vary across providers and even across accounts of the same provider.
Balance keys and meaning:
closingBooked: booked balance at the end of the last completed booking cycle.interimBooked: booked balance calculated during the current booking cycle.openingBooked: booked balance at the beginning of the reported period or booking cycle.interimAvailable: available balance calculated during the current booking cycle.forwardAvailable: projected available balance at a future point in time, when provided by the bank.creditLimit: credit line or overdraft limit available on the account.expected: expected balance including forecast or pending movements, when provided by the bank.available: funds currently available for use according to the bank.booked: booked balance reported by the bank when no more specific booked subtype is provided.For one-off consents balances are reported as of authorization time; for recurring consents they reflect the retrieval time.
If useful for your integration, FlowPay is available to work with partners on an algorithm to select or prioritise the most relevant balance for each use case.
| consentSessionId required | string <uuid> UUID of the AIS consent session. |
| page | integer >= 1 Default: 1 Page number (1-based). |
| per | integer [ 1 .. 200 ] Default: 50 Page size. |
{- "items": [
- {
- "accountId": "IT60X0542811101000000123456",
- "iban": "IT60X0542811101000000123456",
- "date": "2026-03-12T14:15:22Z",
- "currency": "EUR",
- "closingBooked": 5174.72,
- "interimAvailable": 5200,
- "expected": -262.01
}
], - "page": 0,
- "per": 0,
- "hasNext": true
}Returns transactions constrained to the AIS domain window. Requested dates are clamped automatically and the applied window is returned in the payload. For one-off consents the window ends at authorizedAt; for recurring consents it ends at request time. In both cases the earliest allowed date is authorizedAt minus 90 days.
| consentSessionId required | string <uuid> UUID of the AIS consent session. |
| accountId | string Optional account filter. Pass the |
| fromDate | string <date> Start date (inclusive) in ISO 8601 format. |
| toDate | string <date> End date (inclusive) in ISO 8601 format. |
| page | integer >= 1 Default: 1 Page number (1-based). |
| per | integer [ 1 .. 200 ] Default: 50 Page size. |
{- "items": [
- {
- "transactionId": "bank-tx-123",
- "accountId": "IT60X0542811101000000123456",
- "iban": "IT60X0542811101000000123456",
- "bookingDate": "2026-03-12",
- "valueDate": "2026-03-12",
- "amount": -42.5,
- "currency": "EUR",
- "description": "Card payment",
- "counterparty": "Example Merchant",
- "category": "card"
}
], - "page": 0,
- "per": 0,
- "hasNext": true,
- "appliedDateWindow": {
- "from": "2019-08-24",
- "to": "2019-08-24T14:15:22Z",
- "mode": "one_off"
}
}