openapi: 3.2.0 info: version: 1.6.0 title: iBanFirst Payments API description: "iBanFirst API for cross-border payments, FX trades, account management, beneficiaries, and webhooks.\n\n**Try it out in Postman:** [View Postman Collection](https://www.postman.com/productibf/ibanfirst-rest-api-workspace/collection/d24hl8d/ibanfirst-rest-api?action=share&creator=44872188)\n\n---\n\n## Authentication — X-WSSE\n\nEvery request must include an `X-WSSE` header. Plain HTTP calls will fail. The token is **stateless and expires after ~5 minutes**, so it must be computed fresh for each request.\n\n### Header format\n\n```\nX-WSSE: UsernameToken Username=\"\", PasswordDigest=\"\", Nonce=\"\", Created=\"\"\n```\n\n### Fields\n\n| Field | Description |\n|---|---|\n| `Username` | The username assigned during onboarding. |\n| `Nonce` | A Base64-encoded random hex string (≥ 32 hex characters). |\n| `Created` | Current UTC timestamp in ISO 8601: `YYYY-MM-DDTHH:MM:SSZ`. |\n| `PasswordDigest` | `Base64( SHA-1( nonce_bytes ∥ created_bytes ∥ secret_bytes ) )` — SHA-1 **binary** digest, then Base64. |\n\n### Algorithm (step-by-step)\n\n1. Generate a random nonce: at least 32 lowercase hexadecimal characters (e.g. `d36e3162829ed4c89851497a717f0001`).\n2. Get the current UTC timestamp as an ISO-8601 string (e.g. `2026-05-12T10:30:00Z`).\n3. Encode the nonce string as UTF-8 bytes, the timestamp as UTF-8 bytes, and the API secret as UTF-8 bytes.\n4. Compute `SHA-1( nonce_bytes + created_bytes + secret_bytes )`. The hash **must** be the raw binary digest (not hex).\n5. `PasswordDigest` = `Base64( sha1_binary_digest )`\n6. `Nonce` = `Base64( nonce_utf8_bytes )`\n\n### Code samples\n\n**Python**\n```python\nimport base64, hashlib, os, binascii\nfrom datetime import datetime, timezone\n\ndef generate_xwsse(username: str, secret: str) -> str:\n nonce = binascii.b2a_hex(os.urandom(16)) # 32 hex bytes\n created = datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n digest = base64.b64encode(\n hashlib.sha1(nonce + created.encode() + secret.encode()).digest()\n ).decode()\n nonce_b64 = base64.b64encode(nonce).decode()\n return f'UsernameToken Username=\"{username}\", PasswordDigest=\"{digest}\", Nonce=\"{nonce_b64}\", Created=\"{created}\"'\n```\n\n**JavaScript (Node.js)**\n```javascript\nconst crypto = require('crypto');\nfunction generateXWSSE(username, secret) {\n const nonce = crypto.randomBytes(16);\n const created = new Date().toISOString();\n const digest = crypto.createHash('sha1')\n .update(nonce)\n .update(Buffer.from(created))\n .update(Buffer.from(secret))\n .digest('base64');\n return `UsernameToken Username=\"${username}\", PasswordDigest=\"${digest}\", Nonce=\"${nonce.toString('base64')}\", Created=\"${created}\"`;\n}\n```\n\n**PHP**\n```php\nfunction generateXWSSE(string $username, string $secret): string {\n $nonce = bin2hex(random_bytes(16)); // 32 hex chars\n $created = gmdate('Y-m-d\\TH:i:s\\Z');\n $digest = base64_encode(sha1($nonce . $created . $secret, true));\n return sprintf('UsernameToken Username=\"%s\", PasswordDigest=\"%s\", Nonce=\"%s\", Created=\"%s\"',\n $username, $digest, base64_encode($nonce), $created);\n}\n```\n\n### Environments\n\n| Environment | Base URL |\n|---|---|\n| Demo (testing) | `https://api-demo.ibanfirst.com/api` |\n| Live (production) | `https://api.ibanfirst.com/api` |\n\n### Forbidden characters in input fields\n\nThe following characters are rejected in route parameters, query parameters, and JSON bodies: `&` `<` `>` `%` `?` `\\` `/` `|`" servers: - url: https://api-demo.ibanfirst.com/api security: - X-WSSE: [] tags: - name: Payments description: "Sending funds from one of your iBanFirst accounts to your own external bank account or a third-party recipient involves two steps:\n\n1. Generate the payment object with the 'Create payment' method. \nA unique id is assigned to each payment. \n\n2. Use the 'Confirm Payment' method to send the payment for processing. \nWhen you confirm a payment, make sure you have sufficient funds in your account balance. \n\n**Caution:** Payments are automatically rolled to the next closest working days if not confirmed in the scheduled date of operation. If the balance of your account is not sufficient to cover the payment amount, funds may be locked-in by iBanFirst.\n" paths: /payments/options/{walletId}/{externalBankAccountId}: get: summary: Get payment options tags: - Payments description: "Before doing any payments, you may use this request to get priority and fee options available for a given account and beneficiary. \n\nYou will also get fee cost for each `priorityPaymentOption` and `feePaymentOption` combinations, and minimal source and target amount for this combination.\n\n **Note :** you may also use this request to estimate the cost of a payment." parameters: - name: walletId in: path description: 'The source account you want to put your payment debit on. ' required: true schema: type: string - name: externalBankAccountId in: path description: 'The beneficiary you want to put your payment credit on. ' required: true schema: type: string responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/PaymentOption' default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/Error' /payments: post: summary: Create payment tags: - Payments description: 'You can use this request to schedule a new payment. ' requestBody: content: application/json: schema: type: object required: - sourceWalletId - externalBankAccountId - amount - desiredExecutionDate - feeCurrency - feePaymentOption - priorityPaymentOption properties: sourceWalletId: $ref: '#/components/schemas/ID' externalBankAccountId: $ref: '#/components/schemas/ID' amount: $ref: '#/components/schemas/Amount' desiredExecutionDate: $ref: '#/components/schemas/Date' feeCurrency: $ref: '#/components/schemas/Currency' feePaymentOption: description: 'A code representing the charges option to be applied to this payment. ' type: string enum: - BEN - OUR - SHARE - SEPA - DSP - RTGS priorityPaymentOption: $ref: '#/components/schemas/paymentSpeedOption' tag: description: 'A custom reference that you want to link to this payment in the system. This tag is not communicated to the beneficiary. ' type: string maxLength: 50 communication: description: 'A free format string sent to the beneficiary. ' type: string maxLength: 76 verificationOfPayee: type: boolean description: "`true` to verify the beneficiary's IBAN, name and type. If the verification fails, the payment will not be created.\n\n **Note** : the verification of payee process can take up to 8 seconds." description: 'The payment to post ' required: true responses: '200': description: OK content: application/json: schema: type: object properties: payment: $ref: '#/components/schemas/PaymentVOP' default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/ErrorVOP' /payments/{id}/confirm: put: summary: Confirm a payment tags: - Payments description: 'Payments that has been scheduled must be confirmed in order to be released. If the payment is not confirmed before the end of scheduled date of operation, it will be automatically postponed to the next operation date available. ***NOTE**: For an instant SEPA payment confirmation, if the source account does not have sufficient funds, the payment will be automatically rejected..* ' parameters: - name: id in: path description: "The unique id identifying the payment you want to confirm.\n\n \n\n **Note :** you may use the **[Get payments by status](https://docs.ibanfirst.com/api/clientapi/payments/paths/~1payments~1%7Bstatus%7D/get)** service to get the unique id of your payment. \n" required: true schema: type: string responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Payment' default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/Error' /payments/{id}/proofOfTransaction: put: summary: Upload a proof of transaction for a payment tags: - Payments description: 'We may ask you to provide a proof of transaction under specific terms. You can anticipate our request and send us your invoice or the ID of the beneficiary to avoid any request from us and fully automate your payment process. To send a file with this request, you have to extract the content of the file with a binary format, and encode it with a base64 algorithm to put in in the “file” field. ' parameters: - name: id in: path description: 'The unique id of the payment you want to update. ' required: true schema: type: string requestBody: content: application/json: schema: type: object required: - documentType - tag - file properties: documentType: description: "The type of document to submit for a transaction. \n" type: string enum: - invoice - identity tag: description: 'The name of the document to be attached. ' type: string file: description: 'The binary content of the file, encoded with a base64 algorithm. ' type: string description: 'The proof of transaction to upload ' required: true responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Payment' default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/Error' /payments/{status}: get: summary: Get payments by status tags: - Payments description: 'Request a list of payments filtered by status. ' parameters: - name: status in: path description: 'A code representing the status of the payments you want to get. ' required: true schema: type: string enum: - all - planified - rejected - finalized - canceled - refused - blocked - waitingconfirmation - waitingsignature - name: fromDate in: query description: 'The starting date to search for payments. ' required: false schema: type: string format: YYYY-MM-DD - name: toDate in: query description: 'The ending date to search for payments. ' required: false schema: type: string format: YYYY-MM-DD - name: page in: query description: 'Index of the page. ' required: false schema: type: string default: '1' - name: per_page in: query description: 'Number of items returned. ' required: false schema: type: string default: '50' - name: sort in: query description: 'A code representing the order of rendering objects. ' required: false schema: type: string enum: - ASC - DESC responses: '200': description: OK content: application/json: schema: type: object properties: payments: type: array items: $ref: '#/components/schemas/Payment' '204': description: No payments found default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/Error' /payments/{id}: get: summary: Get payment details tags: - Payments description: 'Retrieve the details of a specific payment. ' parameters: - name: id in: path description: "The unique id of the payment.\n\n **Note :** you may use the **Get payments by status** service to get the unique id of your payment .\n" required: true schema: type: string responses: '200': description: OK content: application/json: schema: type: object properties: payment: $ref: '#/components/schemas/Payment' default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/Error' delete: summary: Delete a payment tags: - Payments description: 'Allows you to delete a scheduled payment. ' parameters: - name: id in: path description: 'The code identifying the payment you want to delete. ' required: true schema: type: string responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Payment' default: description: ERROR content: application/json: schema: $ref: '#/components/schemas/Error' components: schemas: ErrorVOP: type: object description: 'Representation of an error. ' properties: errorCode: type: number format: int description: 'The code referring the error. ' errorType: type: string description: 'A short description identifying a general category for the error that occurred. ' errorMessage: type: string description: 'Error description. ' link: type: string description: 'An hyperlink to access the page that describes more accurately the error. ' payeeVerification: type: object description: '' properties: status: type: string enum: - PARTIAL - FAILED description: '' message: type: string description: Verification of payee result details. corrections: type: object description: Proposed modification regarding the beneficiary information. properties: account_holder_name: type: string description: Expected beneficiary name. account_holder_type: type: string enum: - Individual - Corporate description: Expected beneficiary type. Currency: type: string pattern: ^[A-Z]{3}$ format: ^[A-Z]{3}$ example: USD description: 'A String representing the Three-digit ISO 4217 Currency Code of a currency. This String only contains capitalized letters. ' PaymentVOP: type: object description: 'Representation of a payment. ' properties: id: $ref: '#/components/schemas/ID' status: type: string description: 'The code identifying the payment status. ' enum: - planified - rejected - finalized - canceled - refused - blocked - awaitingconfirmation - waitingsignature - processing createdDate: $ref: '#/components/schemas/Datetime' desiredExecutionDate: $ref: '#/components/schemas/Date' executionDate: $ref: '#/components/schemas/Date' amount: $ref: '#/components/schemas/Amount' counterValue: $ref: '#/components/schemas/Amount' rate: $ref: '#/components/schemas/Rate' tag: type: string maxLength: 50 description: 'The custom reference related to the payment. (For internal use only, not communicated to the beneficiary). ' externalBankAccountId: $ref: '#/components/schemas/ID' sourceWalletId: $ref: '#/components/schemas/ID' communication: type: string maxLength: 50 description: 'The wording of the payment. ' priorityPaymentOption: $ref: '#/components/schemas/paymentPriorityOption' feePaymentOption: type: string description: 'The code identifying the charges option for this payment. ' enum: - BEN - OUR - SHARE - SEPA - DSP - RTGS speedOption: $ref: '#/components/schemas/paymentSpeedOption' feePaymentAmount: $ref: '#/components/schemas/Amount' tracker: type: string description: 'Payment tracker link. For SWIFT payment only. Not available for payments pending confirmation or signature. ' payeeVerification: type: object description: "Verification of payee result. \n\n **Note** : check default error response if the verification failed for more details.\n" properties: status: type: string description: '`SUCCESS` if the beneficiary IBAN and name are verified.' message: type: string description: '`Match` if the beneficiary IBAN and name are a perfect match.' PaymentOption: type: object description: 'The representation of a payment option object. This object contains information about priorityPaymentOption and feePaymentOption for a payment. ' properties: paymentOption: type: object properties: externalBankAccountId: $ref: '#/components/schemas/ID' sourceWalletId: $ref: '#/components/schemas/ID' options: description: 'An array containing all priorityPaymentOptions for the payment, and then, all the feePaymentOptions for this priorityPaymentOptions ' type: array items: type: object properties: priorityPaymentOption: $ref: '#/components/schemas/paymentSpeedOption' feePaymentOption: description: The fee option type: string enum: - BEN - OUR - SHARE - SEPA - DSP - RTGS priorityCost: $ref: '#/components/schemas/Amount' feeCost: $ref: '#/components/schemas/Amount' minimumAmountSource: $ref: '#/components/schemas/Amount' minimumAmountTarget: $ref: '#/components/schemas/Amount' QuotedDecimal: type: string pattern: ^((\-)?)[0-9]{12}((\.[0-9]{1,7})?)$ format: ^((\-)?)[0-9]{12}((\.[0-9]{1,7})?)$ example: '2.257' description: 'A String representing a formatted floating number. ' Payment: type: object description: 'Representation of a payment. ' properties: id: $ref: '#/components/schemas/ID' status: type: string description: 'The code identifying the payment status. ' enum: - awaitingconfirmation - planified - rejected - finalized - canceled - refused - blocked - waitingsignature - processing createdDate: $ref: '#/components/schemas/Datetime' desiredExecutionDate: $ref: '#/components/schemas/Date' executionDate: $ref: '#/components/schemas/Date' amount: $ref: '#/components/schemas/Amount' counterValue: $ref: '#/components/schemas/Amount' rate: $ref: '#/components/schemas/Rate' tag: type: - string - 'null' maxLength: 50 description: 'The custom reference related to the payment. (For internal use only, not communicated to the beneficiary). ' externalBankAccountId: $ref: '#/components/schemas/ID' sourceWalletId: $ref: '#/components/schemas/ID' communication: type: - string - 'null' maxLength: 76 description: 'The wording of the payment. ' priorityPaymentOption: $ref: '#/components/schemas/paymentPriorityOption' feePaymentOption: type: string description: 'The code identifying the charges option for this payment. ' enum: - BEN - OUR - SHARE - SEPA - DSP - RTGS speedOption: $ref: '#/components/schemas/paymentSpeedOption' feePaymentAmount: $ref: '#/components/schemas/Amount' tracker: type: string description: Payment tracker link. For SWIFT payment only. Not available for payments pending confirmation or signature. paymentSpeedOption: description: 'A code representing the speed option. ' type: string enum: - 48H - 24H - 1H - instant Rate: type: object description: 'Representation of a Rate. ' properties: currencyPair: $ref: '#/components/schemas/CurrencyPair' midMarket: $ref: '#/components/schemas/QuotedDecimal' date: $ref: '#/components/schemas/Datetime' coreAsk: $ref: '#/components/schemas/QuotedDecimal' coreBid: $ref: '#/components/schemas/QuotedDecimal' appliedAsk: $ref: '#/components/schemas/QuotedDecimal' appliedBid: $ref: '#/components/schemas/QuotedDecimal' paymentPriorityOption: description: 'A code representing whether this payment has a standard priority, or a priority treatment. ' type: string enum: - normal - urgent ID: type: string pattern: ^[A-Za-z0-9]+$ format: ^[A-Za-z0-9]+$ example: Na5Dv6E description: 'A String representing the id of an object. This string contains alpha-numeric characters, including the capital ones. ' Error: type: object description: 'Representation of an error. ' properties: errorCode: type: number format: int description: 'The code referring the error. ' errorType: type: string description: 'A short description identifying a general category for the error that occurred. ' errorMessage: type: string description: Error description. link: type: string description: 'An hyperlink to access the page that describes more accurately the error. ' Date: type: string pattern: ^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$ format: ^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$ example: '2016-01-01' description: "A String representing a date by its year, month and day in month.\n \n" CurrencyPair: type: string pattern: ^[A-Z]{6}$ format: ^[A-Z]{6}$ example: EURUSD description: "A String representing two concatenated Three-digit ISO 4217 Currency Code of a currency. This String only contains capitalized letters.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n" Datetime: type: string pattern: ^((19[0,99]|2[0-9]{3})\-(0[1-9]|1[012])\-([012][0-9]|3[01])\ ([01][0-9]|2[0-3])\:([0-5][0-9])\:([0-5][0-9]))$ format: ^((19[0,99]|2[0-9]{3})\-(0[1-9]|1[012])\-([012][0-9]|3[01])\ ([01][0-9]|2[0-3])\:([0-5][0-9])\:([0-5][0-9]))$ example: '2016-01-01 00:00:00' description: 'A String representing a date by its year, month, day in month, hour, minute and second. ' Amount: type: - object - 'null' description: 'Representation of an amount. ' required: - value - currency properties: value: $ref: '#/components/schemas/QuotedDecimal' currency: $ref: '#/components/schemas/Currency' securitySchemes: X-WSSE: type: apiKey in: header name: X-WSSE description: 'X-WSSE token-based authentication. The header value must be computed fresh for every request (tokens expire in ~5 minutes). Header value format: ``` UsernameToken Username="", PasswordDigest="", Nonce="", Created="" ``` Algorithm: 1. Generate a random nonce: ≥ 32 lowercase hex characters. 2. Get current UTC timestamp in ISO 8601: `YYYY-MM-DDTHH:MM:SSZ`. 3. Compute `PasswordDigest = Base64( SHA-1( nonce_bytes + created_bytes + secret_bytes ) )` — SHA-1 over the raw UTF-8 bytes concatenated in that order, result must be the binary digest before Base64 encoding. 4. Compute `Nonce = Base64( nonce_utf8_bytes )`. See the `info.description` field at the top of this spec for full code samples in Python, JavaScript, PHP, Java, and Go.'