---
title: "Payment Hub"
description: "Fabrick Payment Hub: documentation in progress."
url: "https://docs.fabrick.com/en/payment-hub-and-orchestra/payment-hub/"
language: "en"
---

# Payment Hub

## Introduction

This document describes the APIs of the PACE (Fabrick) platform payment module, exposed under the base path `/api/fabrick/pace/v4.0/mods/payment/v2.0/back`. These APIs are designed to be called by clients and cover the management of payments (bills), their related transactions and executions, mandates, and saved payment instruments (card tokens, SDD mandates).

For each API, the following details are provided: a functional description, input parameter tables, an example request and response in JSON format, and the main error codes returned. Shared fields/DTOs used across multiple APIs are described once in this introductory section and referenced in subsequent sections.

### Authentication and Common Headers

All APIs described in this document require, in addition to any specific headers indicated per endpoint, the following common headers:

- `Api-Key` (required: Yes): API key provided by the client for S2S authentication.
- `Auth-Schema` (required: Yes): Fixed value: S2S.

*Some endpoints also require the Auth-Token header, which is necessary to resolve the impersonated user session (merchant and tenant) through the platform's "impersonation" mechanism. When present, this requirement is explicitly indicated in the "Authentication" line of each API.*

### Response Structure (ResponseDto)

Unless stated otherwise, all responses are encapsulated in a common ResponseDto wrapper with the following structure:

- `status` (string (enum); required: Yes): Result of the operation: OK, KO, UNAUTHORIZED, PENDING.
- `errors` (array of ErrorDto; required: No): List of encountered errors, populated in case of a non-OK status.
- `payload` (object; required: No): Endpoint-specific response body, described in its respective section.

**ErrorDto**

- `code` (string; required: Yes): Error identifier code (e.g., PAYM-REQUIRED-400).
- `description` (string; required: No): Text description of the error.
- `params` (object; required: No): Any additional parameters accompanying the error.

### Shared Types

The following DTOs recur across multiple APIs and are described here once; in subsequent sections, they are referenced by name.

**MoneyDTO**

- `amount` (number; required: Yes): Amount.
- `currency` (string; required: Yes): Currency, ISO 4217 code (e.g., EUR).

**PaymentAllowedMethodsDTO**

- `customerMethods` (array of string; required: No): Payment methods available for the end customer.
- `businessMethods` (array of string; required: No): Payment methods available in B2B context.
- `orchestraMethodsB2B` (array of string; required: No): ORCHESTRA methods allowed in B2B context.
- `orchestraMethodsB2C` (array of string; required: No): ORCHESTRA methods allowed in B2C context (verified, e.g., during payment execution).

**PaymentGatewayResponse**

- `exitUrl` (string; required: No): Exit/redirect URL to the payment gateway.
- `paymentGatewayStatus` (string; required: No): Status returned by the gateway (e.g., AUTHORIZED, ERROR).
- `error` (string; required: No): Optional gateway error message.
- `transactionId` (string; required: No): Gateway-side transaction identifier.

**PaymentSubjectDTO**

- `id` (string; required: No): Internal subject identifier.
- `xid` (string; required: No): External subject identifier.
- `name` (string; required: No): Company name (legal entity).
- `firstName` (string; required: No): First name (natural person).
- `lastName` (string; required: No): Last name (natural person).
- `email` (string; required: No): Email address.
- `phoneNumber` (string; required: No): Phone number.

**Enum PaymentMethod**

Allowed values: SDD, CASH, CHEQUE, SMARTPOS, INSURANCE_CREDIT, BANCOMATPAY, FBKR2P, EXTERNAL, CREDITCARD, SCT, MYBANK, PAYPAL, SATISPAY, SDD_CBI, KLARNA, ORCHESTRA. In the absence of explicit indication, the default method used by the platform is ORCHESTRA.

**MandateSubject / MandateSubjectResponse**

- `name` (string; required: No): Company name of the mandate holder.
- `firstName` (string; required: No): First name.
- `lastName` (string; required: No): Last name.
- `email` (string; required: No): Email address.
- `phoneNumber` (string; required: No): Phone number.
- `ccu` (string; required: No): Unique Customer Code (CCU) of the subject.
- `legalInformation` (LegalInformation; required: No): Legal data of the subject — see below.
- `registryInformation` (RegistryInformation; required: No): Registry/address data of the subject — see below.

**LegalInformation / LegalInformationResponse**

- `type` (string; required: No): Subject type (e.g., PF = natural person, PG = legal entity).
- `taxCode` (string; required: No): Tax code / Fiscal code.
- `vatNumber` (string; required: No): VAT number.

**RegistryInformation / RegistryInformationResponse**

- `address` (string; required: No): Address (street name and house number).
- `city` (string; required: No): City.
- `region` (string; required: No): Province/Region.
- `zipCode` (string; required: No): Postal / ZIP code.

**PaymentInstrumentData (SDD mandate data)**

- `xId` (string; required: Yes): External identifier of the payment instrument (must be unique per merchant).
- `iban` (string; required: Yes): IBAN of the debited account.
- `signatureDate` (string (date); required: Yes): Signature date of the SDD mandate; also determines the instrument expiration date (year-month).
- `signaturePlace` (string; required: No): Mandate signature place.
- `contractId` (string; required: No): Underlying contract identifier; the last digits are used to generate the instrument alias.
- `contractDescription` (string; required: No): Description of the underlying contract.

## Payments — /back/payments

Endpoints related to the lifecycle of payments (bills): creation, reading, cancellation, updating tags/expiration date, transaction execution (authorization, capture, payment using saved tokens), and refunds.

### Payment Creation (bill)

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments`

**Functional Description**

Creates a new bill. This is the main entry point for payment creation.

**Notes and Business Rules**

- If the merchant is of PSP type "BILLING", the `pagoPa.pspId` field is mandatory and must match (case-insensitive) the `pspId` configured for the merchant; if the merchant is "SPENDING", the field must not be populated.

- If `paymentConfiguration.mandateCreation` is true, the merchant must have the `enableMandate` option enabled; otherwise, the operation is rejected (403).

- With `mandateCreation=true`, amounts (bill and items) can be >= 0 (including zero); with `mandateCreation=false`, they must be strictly > 0.

- If items are present, the sum of their amounts must match the bill amount exactly.

**Request Body Fields (PaymentCoreCreateRequestDTO)**

- `merchantId` (string; required: Yes): Merchant identifier.
- `externalId` (string; required: Yes): External reference assigned by the caller.
- `paymentConfiguration` (object; required: No): Payment configuration — see PaymentConfigurationPaymentCoreDTO in "Shared Types".
- `bill` (object; required: Yes): Bill details — see BillPaymentCoreRequestDTO in "Shared Types".
- `pagoPa` (object; required: No): PagoPA-specific configuration (`pspId` field), required only for BILLING merchants.

***Request Example (JSON):***

```json
{
  "merchantId": "MERCH-00012345",
  "externalId": "ORD-2026-000789",
  "paymentConfiguration": {
    "expirationDate": "2026-09-15T23:59:59.000Z",
    "manualExecution": false,
    "mandateCreation": false
  },
  "bill": {
    "externalId": "BILL-2026-000789",
    "amount": 150,
    "currency": "EUR",
    "description": "Fattura energia elettrica settembre 2026",
    "items": [
      {
        "externalId": "ITEM-000001",
        "amount": 150,
        "currency": "EUR",
        "description": "Consumo energia elettrica"
      }
    ]
  }
}
```

**Response — 200 OK (PaymentCoreResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "externalId": "ORD-2026-000789",
    "tenantId": "TENANT-PACE",
    "paymentId": "PAY-2026-000789",
    "merchantId": "MERCH-00012345",
    "paymentPageUrl": "https://pay.fabrick.com/checkout/PAY-2026-000789",
    "paymentPageAuthUrl": "https://pay.fabrick.com/checkout/PAY-2026-000789/auth",
    "shortPaymentPageUrl": "https://pay.fbk.it/s/ab12cd",
    "qrCodePayment": "https://pay.fabrick.com/qr/PAY-2026-000789.png",
    "qrCodeAuth": "https://pay.fabrick.com/qr/PAY-2026-000789-auth.png",
    "coupon": null,
    "description": "Fattura energia elettrica settembre 2026"
  }
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Missing mandatory field (e.g., `bill.amount`).
- **403 PAYM-FORBIDDEN-403**: Merchant not enabled to operate.
- **422 PAYM-INVALID-PAYLOAD**: Invalid payload (e.g., `bill.amount` differs from the sum of items).
- **500 TECH-500**: Unexpected technical error.

### Payment Reading

**GET** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}`

**Functional Description**

Returns full details of the requested payment (bill data, transactions, creation mandate, amounts).

**Notes and Business Rules**

- The optional header `x-terminalId` is accepted but does not affect response processing.

- If the payment expiration date is missing or already past, the endpoint responds with a 404 status ("not found"), even though conceptually the payment exists but has expired.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Specific Headers**

- `x-terminalId` (required: No): Terminal identifier, optional and not used for response computation.

**Response — 200 OK (PaymentDTO)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "payload": {
    "id": "PAY123456789",
    "creationDate": "2026-09-01T10:15:30.000Z",
    "expirationDate": "2026-09-08T23:59:59.000Z",
    "shortCode": "AB12CD",
    "merchant": {
      "id": "MERCH001",
      "xid": "X-MERCH-001",
      "name": "Acme Store Srl",
      "email": "merchant@acme.it",
      "phoneNumber": "+390212345678"
    },
    "customer": {
      "id": "CUST987",
      "xid": "X-CUST-987",
      "firstName": "Mario",
      "lastName": "Rossi",
      "email": "mario.rossi@example.com",
      "phoneNumber": "+393331234567"
    },
    "allowedPaymentMethods": {
      "customerMethods": [
        "CARD",
        "BANK_TRANSFER"
      ],
      "businessMethods": [
        "CARD"
      ],
      "orchestraMethodsB2B": [],
      "orchestraMethodsB2C": [
        "CARD"
      ]
    },
    "residualAmount": {
      "amount": 0,
      "currency": "EUR"
    },
    "paidAmount": {
      "amount": 150,
      "currency": "EUR"
    },
    "money": {
      "amount": 150,
      "currency": "EUR"
    },
    "bill": {
      "id": "BILL5678",
      "status": "CREATED",
      "description": "Order #5678",
      "money": {
        "amount": 150,
        "currency": "EUR"
      },
      "tag": "order-5678"
    },
    "manualExecution": false
  }
}
```

**Main Error Codes**

- **404 PAYM-NOTFOUND-404**: Payment not found or expired.

### Payment Cancellation

**DELETE** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}`

**Functional Description**

Cancels the specified payment.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Response — 200 OK (BillCancelResult)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "payload": {
    "paymentId": "PAY123456789",
    "billId": "BILL5678",
    "status": "CANCELLED",
    "executed": false
  }
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Missing mandatory field.
- **404 PAYM-NOTFOUND-404**: Payment not found.
- **500 TECH-500**: Unexpected technical error.

### Payment Tags Update

**PUT** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/tag`

**Functional Description**

Updates the `tag`, `tag2`, and `tag3` fields (custom labels) associated with the bill.

**Notes and Business Rules**

- At least one of `tag`, `tag2`, or `tag3` must be populated; otherwise, the request is rejected.

- The merchant of the impersonated session must match the merchant owning the bill.

- The update triggers a domain event and a merchant notification; any notification failure results in a 500 error, even if the tag was updated internally.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Request Body Fields (BillUpdateTagRequestDTO)**

- `tag` (string; required: No): First custom label.
- `tag2` (string; required: No): Second custom label.
- `tag3` (string; required: No): Third custom label.

***Request Example (JSON):***

```json
{
  "tag": "order-5678",
  "tag2": "campaign-summer",
  "tag3": "channel-web"
}
```

**Response — 200 OK (ResponseDto)**

***Response Example (JSON):***

```json
{
  "status": "OK"
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Invalid or unknown payload (no tag populated).
- **404 PAYM-NOTFOUND-404**: Payment not found.
- **401 AUTH-401**: Unauthorized.

### Expiration Date Update

**PUT** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/expirationDate`

**Functional Description**

Modifies the expiration date of a bill/payment.

**Notes and Business Rules**

- Allowed only if the bill is in `READY`, `PAYMENT_STARTED`, or `CANC` status; any other status produces an error.

- The `newExpirationDate` field is parsed using the pattern `"yyyy-MM-dd HH:mm:ss"` in the server default timezone, not in UTC like other platform dates — keep this in mind during integration.

**Request Body Fields (ChangeExpirationDto)**

- `paymentId` (string; required: Yes): Identifier of the payment to update.
- `newExpirationDate` (string; required: Yes): New expiration date.

***Request Example (JSON):***

```json
{
  "paymentId": "PAY-2026-000789",
  "newExpirationDate": "2026-10-15T23:59:59.000Z"
}
```

**Response — 200 OK (ExpirationDateDto)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "id": "PAY-2026-000789",
    "creationDate": "2026-09-01T09:00:00.000Z",
    "expirationDate": "2026-10-15T23:59:59.000Z",
    "xId": "EXT-2026-000789"
  }
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Missing mandatory field (e.g., `newExpirationDate`).
- **500 TECH-500**: Unexpected technical error.

### Payment Execution (Initialization + Authorization)

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/transaction`

**Functional Description**

Initializes and authorizes a payment transaction in a single synchronous call on the Axerve gateway for the specified payment.

**Notes and Business Rules**

- Before execution, system checks verify that the bill exists, is not expired, that the requested amount matches the bill amount, and that the requested `paymentMethod` is among the allowed ORCHESTRA methods on the B2C side for that payment.

- In case of authorization failure on the gateway, a failure event is recorded, and the payment is cancelled (`CANC` status) before the error is returned to the caller.

- Conceptually distinct from "execution" (which only performs capture of an already authorized transaction) and "updateandexecution" (capture of a specific amount on a preauthorized transaction).

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Request Body Fields (ExecutePaymentRequest)**

- `paymentMethod` (string (enum); required: Yes): Payment method — see `PaymentMethod` enum in "Shared Types".
- `money` (MoneyDTO; required: Yes): Amount and currency — see MoneyDTO in "Shared Types".

***Request Example (JSON):***

```json
{
  "paymentMethod": "CREDITCARD",
  "money": {
    "amount": 49.9,
    "currency": "EUR"
  }
}
```

**Response — 200 OK (ExecutePaymentResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "status": "OK",
    "transactionId": "TRX-2026-000456",
    "paymentGatewayResponse": {
      "exitUrl": "https://pay.axerve.com/checkout/TRX-2026-000456",
      "paymentGatewayStatus": "AUTHORIZED",
      "error": null,
      "transactionId": "TRX-2026-000456"
    }
  }
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Missing mandatory field (e.g., `money.amount`).
- **404 PAYM-NOTFOUND-404**: Payment not found.
- **409 PAYM-INVALID-409**: Payment already executed or cannot be executed in the current status.
- **500 PAYM-GATEWAY-000**: Gateway/core payment error.

### Capture (Execution) of a Preauthorized Transaction

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/execution`

**Functional Description**

Captures ("execution") a previously authorized and uncaptured transaction associated with the specified payment.

**Notes and Business Rules**

- Supports only the `CREDITCARD` payment method; any other method is rejected with a 422 status.

- The target transaction must be in `IN_PRGS` status; otherwise, the operation is rejected with 409 ("already executed").

- Before capturing, transaction status is realigned with the gateway: if already settled, the endpoint returns current status without re-attempting capture.

- In case of gateway timeout or internal error during capture, the endpoint does not propagate the error but returns 200 OK with the current transaction status to facilitate handling idempotent retries.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Response — 200 OK (PaymentResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "payload": {
    "transactionId": "TXN445566",
    "transactionDateTime": "2026-09-08T09:45:00.000Z",
    "amount": 150,
    "currency": "EUR",
    "gatewayId": "GW-01",
    "acquirerId": "ACQ-01",
    "status": "AUTHORIZED",
    "paymentMethod": "CARD",
    "scaRequired": false,
    "scaUrl": null
  }
}
```

**Main Error Codes**

- **401 AUTH-401**: Unauthorized.
- **422 PAYM-INVALID-PAYLOAD**: Unsupported payment method for execution (different from CREDITCARD).
- **409 PAYM-INVALID-409**: Payment already executed.
- **500 PAYM-GATEWAY-000**: Blocking error on gateway capture.

### Real Amount Capture on Preauthorized Payment

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/updateandexecution`

**Functional Description**

Used to settle (capture) the actual amount of a preauthorized payment when the final amount differs from the preauthorized amount (e.g., maximum pre-authorization, capture of actual consumed amount).

**Notes and Business Rules**

- Requires the bill to be configured with `manualExecution = true`; otherwise, the operation is rejected.

- The requested amount cannot exceed the total bill amount.

- At least one transaction in `IN_PRGS` status must exist for the specified payment.

- Unlike "execution", this endpoint always requires `manualExecution=true` and accepts an explicit amount in the request body.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Request Body Fields (MoneyDTO)**

- `amount` (number; required: Yes): Amount to capture (cannot exceed bill amount) — see MoneyDTO in "Shared Types".
- `currency` (string; required: Yes): Currency (ISO 4217).

***Request Example (JSON):***

```json
{
  "amount": 99.9,
  "currency": "EUR"
}
```

**Response — 200 OK (PaymentResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "transactionId": "TRX-2026-000456",
    "transactionDateTime": "2026-09-08T10:15:30.000Z",
    "amount": 99.9,
    "currency": "EUR",
    "gatewayId": "AXERVE",
    "acquirerId": "ACQ-001",
    "status": "OK",
    "paymentMethod": "CREDITCARD",
    "scaRequired": false,
    "scaUrl": null
  }
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Missing mandatory field (e.g., `amount`).
- **404 PAYM-NOTFOUND-404**: Payment not found.
- **409 PAYM-INVALID-409**: Payment already executed or cannot be executed in the current status.
- **500 TECH-500**: Unexpected technical error.

### Payment with Saved Payment Instrument (Token)

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/payWithToken`

**Functional Description**

Executes the payment on the specified bill using a previously saved payment instrument (token), identified by its xid.

**Notes and Business Rules**

- The bill must be in `READY` status.

- The payment instrument must belong to the session merchant, be in `ACTIVE` status, and be of type `CREDITCARD`, `SEPA`, or `SDD` (`SEPA` type is internally handled as a historical alias for SDD).

- No other transactions in `INIT` or `IN_PRGS` status must exist for the same payment to prevent concurrent/duplicate payments.

- The paid amount is not the value passed in the request body but always matches the total bill amount.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Request Body Fields (PayWithTokenRequest)**

- `paymentInstrumentXid` (string; required: Yes): Xid of the saved payment instrument to use.

***Request Example (JSON):***

```json
{
  "paymentInstrumentXid": "PI-2026-000123"
}
```

**Response — 200 OK (PayWithTokenResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "id": "PAY-2026-000789",
    "expirationDate": "2026-09-20T23:59:59.000Z",
    "importo": {
      "amount": 99.9,
      "currency": "EUR"
    },
    "creationDate": "2026-09-08T10:15:30.000Z",
    "status": "OK",
    "paymentMethod": "CREDITCARD"
  }
}
```

**Main Error Codes**

- **401 AUTH-401**: Missing or invalid authentication headers.
- **404 INSTR-NOTFOUND-404**: Payment instrument not found.
- **409 PAYM-INVALID-409**: Payment already executed or cannot be executed in current status.
- **500 TECH-500**: Unexpected technical error.

### Authorization with Saved Payment Instrument (Token)

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/authWithToken`

**Functional Description**

Authorizes (without capturing) a payment on the specified bill using a saved card payment instrument identified by its xid. Returns a `PENDING` (202) result when the gateway requires additional processing (e.g., 3DS/SCA).

**Notes and Business Rules**

- The bill must be in `READY` status and configured with `manualExecution = true`: this endpoint is designed for pre-authorization flows with subsequent manual capture (via "execution" or "updateandexecution").

- Supports exclusively `CREDITCARD` payment instruments.

- If strong customer authentication (3DS/SCA) is required, response HTTP status is 202 and logical status is `PENDING`, with `scaRedirectUrl` populated; otherwise, response is 200 OK.

- The authorized amount is always the bill amount, not a body value; non-existence of concurrent transactions in `INIT` or `IN_PRGS` status is also checked.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.

**Request Body Fields (AuthWithTokenRequest)**

- `paymentInstrumentXid` (string; required: Yes): Xid of the saved card payment instrument to use.

***Request Example (JSON):***

```json
{
  "paymentInstrumentXid": "PI-2026-000123"
}
```

**Response — 200 OK / 202 Accepted (SCA required) (AuthWithTokenResponse)**

***Response Example (JSON):***

```json
{
  "status": "PENDING",
  "errors": [],
  "payload": {
    "id": "PAY-2026-000789",
    "expirationDate": "2026-09-20T23:59:59.000Z",
    "money": {
      "amount": 99.9,
      "currency": "EUR"
    },
    "creationDate": "2026-09-08T10:15:30.000Z",
    "status": "PMT_IN_PRGS",
    "paymentMethod": "CREDITCARD",
    "code": "3DS_REQUIRED",
    "scaRedirectUrl": "https://pay.axerve.com/3ds/PAY-2026-000789"
  }
}
```

**Main Error Codes**

- **400 INSTR-REQUIRED-400**: Missing mandatory field (e.g., `paymentInstrumentXid`).
- **404 INSTR-NOTFOUND-404**: Payment instrument not found.
- **401 AUTH-401**: Missing or invalid authentication headers.
- **500 TECH-500**: Unexpected technical error.

### Transaction Refund

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{paymentId}/transactions/{transactionId}/refund`

**Functional Description**

Executes total or partial refund for a specific transaction associated with the specified payment.

**Notes and Business Rules**

- Merchant must have refund enabled in configuration; otherwise, request is rejected.

- Target transaction must be in `OK` status and not fully refunded yet; cumulative refund amount (already done + requested) cannot exceed transaction amount.

- Refund must occur within merchant's configured timeframe starting from transaction creation date.

- Partial refund (lower than total amount) is allowed only if explicitly enabled in merchant configuration.

- Transaction payment method must match merchant refund configuration.

**Path Parameters**

- `paymentId` (string; required: Yes): Payment identifier.
- `transactionId` (string; required: Yes): Transaction identifier to refund.

**Request Body Fields (RefundRequest)**

- `amountToRefund` (MoneyDTO; required: No): Amount to refund — see MoneyDTO in "Shared Types". If omitted or equal to total amount, refund is total.
- `refundReason` (string; required: No): Refund reason.
- `merchantId` (string; required: No): Ignored: always overridden with authenticated session merchant.

***Request Example (JSON):***

```json
{
  "amountToRefund": {
    "amount": 50,
    "currency": "EUR"
  },
  "refundReason": "Customer requested partial refund"
}
```

**Response — 200 OK (RefundResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "payload": {
    "id": "REF001122",
    "creationDate": "2026-09-08T09:30:00.000Z",
    "transactionId": "TXN998877",
    "status": "IN_PROGRESS",
    "reason": "Customer request",
    "amount": 50,
    "currency": "EUR"
  }
}
```

**Main Error Codes**

- **401 AUTH-401**: Missing or invalid authentication headers.
- **400 PAYM-REQUIRED-400**: Refund verification failed (invalid merchant configuration or ineligible transaction).
- **500 TECH-500**: Unexpected technical error.

### Mandate Creation for Payment

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payments/{idPayment}/doMandate`

**Functional Description**

Creates a mandate for the specified payment based on provided transaction data. Presence of authentication header enables B2B mandate flow (without header, flow is B2C).

**Notes and Business Rules**

- `tokenCart` field determines if mandate will use "token cart" (useful for recurring/tokenized payments sharing a token cart across mandates).

- `redirect` / `redirectTo` / `redirectLabel` fields define return URL and label on gateway side after mandate flow completion.

- If mandate is already in `ATTEMPTING` or `IN_PROGRESS` status (and not an "orchestra" mandate), operation is blocked to prevent duplication/concurrency.

- Currently, executor is implemented only for `CREDITCARD` method; other methods might not be supported.

- On error during execution, a mandate failure event is still logged before returning error to caller.

**Path Parameters**

- `idPayment` (string; required: Yes): Payment identifier for mandate creation.

**Specific Headers**

- `Auth-Token` (required: No): If present, enables B2B mandate creation flow (validated against IDP).

**Request Body Fields (Input (TransactionDTO))**

- `expirationDate` (string (date-time); required: No): Mandate expiration date.
- `rate` (number; required: Yes): Mandate installment / reference amount.
- `paymentMethod` (string (enum); required: No): Payment method — see `PaymentMethod` enum in "Shared Types".
- `money` (Money; required: No): Amount and currency — see MoneyDTO in "Shared Types".
- `redirect` (boolean; required: No): Enables redirect to specified URL upon flow completion.
- `redirectTo` (string; required: No): Return URL after mandate signing flow.
- `redirectLabel` (string; required: No): Label displayed for return link.
- `tokenCart` (boolean; required: No): Enables token cart usage for mandate (default: false).

***Request Example (JSON):***

```json
{
  "expirationDate": "2026-09-20T23:59:59.000Z",
  "rate": 1,
  "paymentMethod": "CREDITCARD",
  "money": {
    "amount": 99.9,
    "currency": "EUR"
  },
  "redirect": true,
  "redirectTo": "https://merchant.example.com/thank-you",
  "redirectLabel": "Torna al negozio",
  "tokenCart": false
}
```

**Response — 200 OK (MandateResponseDto)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "exitUrl": "https://pay.fabrick.com/mandate/PAY-2026-000789/exit",
    "gatewayError": null
  }
}
```

**Main Error Codes**

- **400 PAYM-REQUIRED-400**: Missing mandatory field.
- **500 TECH-500**: Unexpected technical error.

## Payment Instrument — /back/payment-instrument

Back-channel endpoints for managing saved payment instruments (card tokens, SDD mandates): creation, reading, updating, deleting, and searching by merchant/subject/token.

### Creation of a Payment Instrument

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument`

**Functional Description**

Creates a new payment instrument with a mandate already tokenized on the gateway. The requesting merchant is resolved from the authenticated session; combination of `xid`, `subject_xid`, and merchant must be unique.

**Notes and Business Rules**

- Expiration date must be in year-month format and in the future.

- Maximum allowed instruments limit per subject/merchant applies based on configuration.

- Combination of `xid` + `subject_xid` + `merchantId` must be unique.

- First instrument created for a subject automatically becomes default (`is_default = true`).

**Request Body Fields (PaymentInstrumentCreateRequest)**

- `alias` (string; required: Yes): Descriptive instrument label.
- `description` (string; required: No): Extended description.
- `type` (string (enum); required: Yes): Instrument type: CREDITCARD, PAYPAL, SATISPAY, SDD, SEPA.
- `xid` (string; required: Yes): Identification token assigned by gateway.
- `subject_xid` (string; required: Yes): External ID of the holder subject.
- `expiration_date` (string; required: Yes): Expiration date (year-month format).
- `card_country` (string; required: No): Card issuing country.
- `card_type` (string; required: No): Card type (e.g., VISA).
- `card_company` (string; required: No): Card network/brand.
- `commercial` (string \[Y/N]; required: No): Indicates if card is commercial.
- `prepaid` (string \[Y/N]; required: No): Indicates if card is prepaid.
- `cardHolderName` (string; required: No): Cardholder name.

***Request Example (JSON):***

```json
{
  "alias": "Carta Visa personale",
  "description": "Carta Visa principale",
  "expiration_date": "12/28",
  "type": "CREDITCARD",
  "xid": "tok-2026-abc123",
  "subject_xid": "X-SUBJ-001",
  "card_country": "IT",
  "card_type": "VISA",
  "card_company": "VISA",
  "commercial": "N",
  "prepaid": "N",
  "cardHolderName": "Mario Rossi"
}
```

**Response — 200 OK (PaymentInstrumentCreateResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "id": "PI-2026-000123",
    "xid": "tok-2026-abc123",
    "type": "CREDITCARD",
    "subject_id": "3f2a9e10-8b1a-4c2e-9d55-1a2b3c4d5e6f",
    "subject_xid": "X-SUBJ-001",
    "alias": "Carta Visa personale",
    "description": "Carta Visa principale",
    "expiration_date": "12/28",
    "card_country": "IT",
    "card_type": "VISA",
    "card_company": "VISA",
    "is_default": true,
    "status": "ACTIVE",
    "prepaid": "N",
    "cardHolderName": "Mario Rossi"
  }
}
```

**Main Error Codes**

- **401 AUTH-401**: Missing or invalid authentication headers.
- **409 INSTR-INVALID-409**: Payment instrument already exists with the same `xid`.
- **400 INSTR-REQUIRED-400 / INSTR-INVALID-PAYLOAD**: Missing mandatory field, non-future expiration date, or max instruments limit reached.
- **500 TECH-500**: Unexpected technical error.

### Creation of External SDD Mandate and Payment Instrument

**POST** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/full`

**Functional Description**

Creates an external SDD mandate on the gateway and simultaneously registers the corresponding payment instrument in a single synchronous transactional call.

**Notes and Business Rules**

- Merchant must have SDD method enabled (B2B or B2C) in configuration.

- Payment instrument `xId` must be unique per merchant.

- Alias is auto-generated from last digits of `contractId`.

- Instrument expiration date is derived from mandate signature date (year-month), not from an explicit value.

**Request Body Fields (SddExternalPaymentInstrumentRequest)**

- `merchantId` (string; required: Yes): Merchant ID (must match authenticated session).
- `subjectXId` (string; required: Yes): External ID of mandate holder subject.
- `mandateSubject` (object; required: Yes): Subject registry data — see `MandateSubject` in "Shared Types".
- `paymentInstrument` (object; required: Yes): SDD mandate data (IBAN, signature, contract) — see `PaymentInstrumentData` in "Shared Types".

***Request Example (JSON):***

```json
{
  "merchantId": "MERCH001",
  "subjectXId": "X-SUBJ-001",
  "mandateSubject": {
    "name": "Mario Rossi Srl",
    "firstName": "Mario",
    "lastName": "Rossi",
    "email": "mario.rossi@example.com",
    "phoneNumber": "+393331234567",
    "ccu": "CCU00123456",
    "legalInformation": {
      "type": "PF",
      "taxCode": "RSSMRA80A01H501U",
      "vatNumber": "IT01234567890"
    },
    "registryInformation": {
      "address": "Via Roma 1",
      "city": "Milano",
      "region": "MI",
      "zipCode": "20100"
    }
  },
  "paymentInstrument": {
    "xId": "SDD-INSTR-2026-001",
    "iban": "IT60X0542811101000000123456",
    "signatureDate": "2026-09-01",
    "signaturePlace": "Milano",
    "contractId": "CTR-9988",
    "contractDescription": "Fornitura energia elettrica"
  }
}
```

**Response — 200 OK (SddExternalPaymentInstrumentResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "id": "MND-2026-000456",
    "xId": "SDD-INSTR-2026-001",
    "type": "SDD",
    "alias": "SDD ****-9988",
    "description": "Fornitura energia elettrica",
    "status": "ACTIVE",
    "subjectId": "3f2a9e10-8b1a-4c2e-9d55-1a2b3c4d5e6f",
    "subjectXId": "X-SUBJ-001",
    "merchantId": "MERCH001",
    "expirationDate": "2026-09",
    "isDefault": true,
    "mandateSubject": {
      "ccu": "CCU00123456",
      "email": "mario.rossi@example.com",
      "firstName": "Mario",
      "lastName": "Rossi",
      "name": "Mario Rossi Srl",
      "phoneNumber": "+393331234567"
    },
    "sddMandate": {
      "iban": "IT60X0542811101000000123456",
      "signatureDate": "2026-09-01",
      "signaturePlace": "Milano",
      "contractId": "CTR-9988",
      "contractDescription": "Fornitura energia elettrica"
    }
  }
}
```

**Main Error Codes**

- **401 AUTH-401**: Missing or invalid authentication headers.
- **403 INSTR-FORBIDDEN-403**: Merchant not enabled to operate.
- **400 INSTR-REQUIRED-400**: Missing mandatory field (e.g., `signatureDate`).
- **409 INSTR-INVALID-409**: Conflict with current resource status (non-unique `xId`).
- **500 TECH-500**: Unexpected technical error.

### Reading a Payment Instrument by Internal ID

**GET** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/{id}`

**Functional Description**

Returns details of a payment instrument identified by its internal ID.

**Path Parameters**

- `id` (string; required: Yes): Internal ID of payment instrument.

**Response — 200 OK (PaymentInstrumentCreateResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "id": "PI-2026-000123",
    "xid": "tok-2026-abc123",
    "type": "CREDITCARD",
    "subject_id": "SUBJ-001",
    "subject_xid": "X-SUBJ-001",
    "alias": "Carta Visa personale",
    "description": "Carta Visa principale",
    "expiration_date": "12/28",
    "card_country": "IT",
    "card_type": "VISA",
    "card_company": "VISA",
    "is_default": true,
    "status": "ACTIVE",
    "prepaid": "N",
    "cardHolderName": "Mario Rossi"
  }
}
```

**Main Error Codes**

- **404 INSTR-NOTFOUND-404**: Payment instrument not found (also returned if merchant does not match).
- **403 INSTR-FORBIDDEN-403**: Merchant not enabled to operate.
- **500 TECH-500**: Unexpected technical error.

### Payment Instrument Update

**PUT** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/{id}`

**Functional Description**

Updates alias, description, status, or default flag of an existing payment instrument.

**Notes and Business Rules**

- Explicitly setting `is_default` to `false` is not allowed: flag can only be set to `true` or omitted.

- Setting `status` to `INACTIVE` and `is_default` flag in the same request simultaneously is not allowed.

**Path Parameters**

- `id` (string; required: Yes): Internal ID of payment instrument.

**Request Body Fields (PaymentInstrumentUpdateRequest)**

- `alias` (string; required: No): New descriptive label.
- `description` (string; required: No): New description.
- `status` (string (enum); required: No): New status: ACTIVE or INACTIVE (cannot be combined with `is_default` in same request).
- `is_default` (boolean; required: No): Setting as default instrument (can only be set to `true`).

***Request Example (JSON):***

```json
{
  "alias": "La mia carta principale",
  "description": "Carta Visa principale",
  "is_default": true,
  "status": "ACTIVE"
}
```

**Response — 200 OK (PaymentInstrumentCreateResponse)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": {
    "id": "PI-2026-000123",
    "xid": "tok-2026-abc123",
    "type": "CREDITCARD",
    "alias": "La mia carta principale",
    "description": "Carta Visa principale",
    "is_default": true,
    "status": "ACTIVE"
  }
}
```

**Main Error Codes**

- **400 INSTR-REQUIRED-400**: Missing mandatory field or invalid field combination (e.g., `alias`, `status`+`is_default`).
- **403 INSTR-FORBIDDEN-403**: Merchant not enabled to operate on this instrument.
- **404**: Payment instrument not found.
- **500 TECH-500**: Unexpected technical error.

### Search Payment Instruments by Merchant and Subject

**GET** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/{merchantId}/subject/{subjectXid}`

**Functional Description**

Returns payment instruments belonging to a subject for a given merchant, with optional status filter.

**Path Parameters**

- `merchantId` (string; required: Yes): Merchant identifier.
- `subjectXid` (string; required: Yes): Subject external identifier.

**Query Parameters**

- `status` (string; required: No): Optional status filter (e.g., ACTIVE, INACTIVE).

**Response — 200 OK (PaymentInstrumentCreateResponse (array))**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": [
    {
      "id": "PI-2026-000123",
      "xid": "tok-2026-abc123",
      "type": "CREDITCARD",
      "subject_id": "SUBJ-001",
      "subject_xid": "X-SUBJ-001",
      "alias": "Carta Visa personale",
      "is_default": true,
      "status": "ACTIVE"
    }
  ]
}
```

**Main Error Codes**

- **500 TECH-500**: Unexpected technical error.

### Search Payment Instruments by Subject

**GET** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/subject/{subjectXid}`

**Functional Description**

Returns payment instruments belonging to a subject, with optional status filter.

**Path Parameters**

- `subjectXid` (string; required: Yes): Subject external identifier.

**Query Parameters**

- `status` (string; required: No): Optional status filter.

**Response — 200 OK (PaymentInstrumentCreateResponse (array))**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": [
    {
      "id": "PI-2026-000123",
      "xid": "tok-2026-abc123",
      "type": "CREDITCARD",
      "subject_id": "SUBJ-001",
      "subject_xid": "X-SUBJ-001",
      "alias": "Carta Visa personale",
      "is_default": true,
      "status": "ACTIVE"
    }
  ]
}
```

**Main Error Codes**

- **401 AUTH-401**: Missing or invalid authentication headers.
- **403 INSTR-FORBIDDEN-403**: Merchant not enabled to operate.
- **500 TECH-500**: Unexpected technical error.

### Search Payment Instruments by Gateway Token

**GET** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/token/{xid}`

**Functional Description**

Returns payment instruments corresponding to the gateway assigned token (`xid`).

**Path Parameters**

- `xid` (string; required: Yes): Gateway assigned token ID.

**Response — 200 OK (PaymentInstrumentCreateResponse (array))**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": [
    {
      "id": "PI-2026-000123",
      "xid": "tok-2026-abc123",
      "type": "CREDITCARD",
      "subject_id": "SUBJ-001",
      "subject_xid": "X-SUBJ-001",
      "alias": "Carta Visa personale",
      "is_default": true,
      "status": "ACTIVE"
    }
  ]
}
```

**Main Error Codes**

- **403**: Merchant not enabled to operate.
- **500 TECH-500**: Unexpected technical error.

### SDD Payment Instrument Deletion

**DELETE** `/api/fabrick/pace/v4.0/mods/payment/v2.0/back/payment-instrument/{paymentInstrumentId}`

**Functional Description**

Deletes an SDD payment instrument along with its corresponding mandate on the external gateway. Only instruments of type SDD can be deleted.

**Notes and Business Rules**

- Any attempt to delete an instrument of a type other than SDD is rejected.

- External gateway mandate deletion occurs before local data modifications: if gateway deletion fails, the entire operation fails.

**Path Parameters**

- `paymentInstrumentId` (string; required: Yes): ID of the SDD payment instrument to delete.

**Response — 200 OK (ResponseDto)**

***Response Example (JSON):***

```json
{
  "status": "OK",
  "errors": [],
  "payload": null
}
```

**Main Error Codes**

- **401**: Missing/invalid authentication headers, or attempt to delete non-SDD instrument.
- **404 INSTR-NOTFOUND-404**: Payment instrument not found.
- **500 INSTR-GATEWAY-000**: Gateway/instrument core error.
