taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit 408e486c87cc6aab90b4ff3577c354a47eea6836
parent 5de82620d0fa2629bda355cbddcfa9b01ea5b1f8
Author: Antoine A <>
Date:   Fri, 13 Jun 2025 19:07:53 +0200

corebank: add conversion rate classes endpoints, new protocol v9

Diffstat:
Mcore/api-bank-conversion-info.rst | 46++++++++++++++++++++++++++++++++++------------
Mcore/api-corebank.rst | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mdesign-documents/063-libeufin-conversion-rate-group.rst | 18------------------
3 files changed, 276 insertions(+), 56 deletions(-)

diff --git a/core/api-bank-conversion-info.rst b/core/api-bank-conversion-info.rst @@ -1,7 +1,7 @@ .. This file is part of GNU TALER. - Copyright (C) 2014-2024 Taler Systems SA + Copyright (C) 2014-2025 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -30,7 +30,8 @@ is used by wallets for withdrawals that involve a currency conversion. .. http:get:: /config - Get configuration information about the bank. + Return the protocol version and configuration information about the bank. + This specification corresponds to ``current`` protocol being **v2**. **Response:** @@ -68,15 +69,27 @@ is used by wallets for withdrawals that involve a currency conversion. // How the bank SPA should render this currency. fiat_currency_specification: CurrencySpecification; - // Additional information on conversion rates. - // Those informations should never be used to perform conversions, - // use /cashin-rate or /cashout-rate instead. - // Conversion rates can change at any time. Clients must deal with - // any resulting errors and call /cashin-rate or /cashout-rate again - // to use the new rates. + // Global exchange rate between the regional currency and the fiat + // currency of the banking system. Use /rate to get the user specific + // rate. conversion_rate: ConversionRate; } +.. http:get:: /rate + + Since protocol **v2**. + + This public endpoint allows clients to get the currenlty applied change rate between the regional currency and the fiat currency of the banking system for this exchange account. + Those informations should never be used to perform conversions use /cashin-rate and /cashout-rate instead. + Conversion rates can change at any time. Clients must deal with any resulting errors and call /cashin-rate or /cashout-rate again to use the new rates. + If cashin_ratio is zero, this means the account cannot cashin, and if cash_out ratio is zero, this means the account cannot cashout. + + **Response:** + + :http:statuscode:`200 OK`: + Response is a `ConversionRate`. + :http:statuscode:`501 Not implemented`: + This server does not support conversion. .. http:get:: /cashin-rate @@ -107,6 +120,10 @@ is used by wallets for withdrawals that involve a currency conversion. * ``TALER_EC_GENERIC_PARAMETER_MISSING`` : none of the parameters have been provided. * ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` : both of the parameters have been provided or one of them is not a valid Taler amount. * ``TALER_EC_GENERIC_CURRENCY_MISMATCH`` : the parameter is in the wrong currency. + :http:statuscode:`401 Unauthorized`: + Invalid credentials or missing rights. + :http:statuscode:`403 Forbidden`: + Missing rights. :http:statuscode:`409 Conflict`: The amount is too small to be converted because it produces an amount less than zero. :http:statuscode:`501 Not implemented`: @@ -153,6 +170,10 @@ is used by wallets for withdrawals that involve a currency conversion. * ``TALER_EC_GENERIC_PARAMETER_MISSING`` : none of the parameters have been provided. * ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` : both of the parameters have been provided or one of them is not a valid Taler amount. * ``TALER_EC_GENERIC_CURRENCY_MISMATCH`` : the parameter is in the wrong currency. + :http:statuscode:`401 Unauthorized`: + Invalid credentials or missing rights. + :http:statuscode:`403 Forbidden`: + Missing rights. :http:statuscode:`409 Conflict`: The amount is too small to be converted because it produces an amount less than zero. :http:statuscode:`501 Not implemented`: @@ -173,12 +194,11 @@ is used by wallets for withdrawals that involve a currency conversion. .. http:post:: /conversion-rate - This endpoint allows the administrator to update - the exchange rate between the regional currency - and the fiat currency of the banking system. + This endpoint allows the administrator to update the global exchange rate between the regional currency and the fiat currency of the banking system. Individual users can have different rate if they are part of an conversion rate classe. - The conversion is calculated as follows: ``(amount * ratio - fee) / tiny_amount`` + The conversion is calculated as follows: ``(amount * ratio - fee) / tiny_amount``. + Only available to the administrator. **Request:** @@ -222,5 +242,7 @@ is used by wallets for withdrawals that involve a currency conversion. Operation successful. :http:statuscode:`401 Unauthorized`: Invalid credentials or missing rights. + :http:statuscode:`403 Forbidden`: + Missing rights. :http:statuscode:`501 Not implemented`: This server does not support conversion, client should check config response. diff --git a/core/api-corebank.rst b/core/api-corebank.rst @@ -38,7 +38,7 @@ Config .. http:get:: /config Return the protocol version and configuration information about the bank. - This specification corresponds to ``current`` protocol being version **v8**. + This specification corresponds to ``current`` protocol being version **v9**. **Response:** @@ -329,15 +329,17 @@ Account Management // Only admin can set this property. debit_threshold?: Amount; - // If present, set a custom minimum cashout amount for this account. - // Only admin can set this property - // @since **v4** - min_cashout?: Amount; + // If present, set the user conversion rate class + // Only admin can set this property. + conversion_rate_class_id?: Number; // If present, enables 2FA and set the TAN channel used for challenges // Only admin can set this property, other user can reconfig their account // after creation. tan_channel?: TanChannel; + + // @deprecated in **v9**, use conversion_rate_class_id instead + min_cashout?: Amount; } .. ts:def:: ChallengeContactData @@ -368,12 +370,13 @@ Account Management * ``TALER_EC_BANK_UNALLOWED_DEBIT`` : admin account does not have sufficient funds to grant bonus. * ``TALER_EC_BANK_RESERVED_USERNAME_CONFLICT`` : a reserved username was attempted, like ``admin`` or ``bank`` * ``TALER_EC_BANK_NON_ADMIN_PATCH_DEBT_LIMIT`` : a non-admin user has tried to create an account with a customer debt limit. - * ``TALER_EC_BANK_NON_ADMIN_SET_MIN_CASHOUT`` : a non-admin user has tried to create an account with a custom min cashout amount. + * ``TALER_EC_BANK_NON_ADMIN_SET_CONVERSION_RATE_CLASS`` : a non-admin user has tried to create an account with a conversion rate class. * ``TALER_EC_BANK_NON_ADMIN_SET_TAN_CHANNEL`` : a non-admin user has tried to create an account with 2fa. * ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED``: ``tan_channel`` is not supported, check bank config to find supported ones. * ``TALER_EC_BANK_MISSING_TAN_INFO``: the user did not share any contact data where to send the TAN via ``tan_channel``. * ``TALER_EC_BANK_PASSWORD_TOO_SHORT``: password is shorter than 8 characters. * ``TALER_EC_BANK_PASSWORD_TOO_LONG``: password is longer than 64 characters. + * ``TALER_EC_BANK_CONVERSION_RATE_CLASS_UNKNOWN`` : no conversion rate class found for this id. **Details:** @@ -416,13 +419,15 @@ Account Management // Only admin can change this property. debit_threshold?: Amount; - // If present, change the custom minimum cashout amount for this account. - // Only admin can set this property - // @since **v4** - min_cashout?: Amount; + // If present, set the user conversion rate class + // Only admin can set this property. + conversion_rate_class_id?: Number // If present, enables 2FA and set the TAN channel used for challenges tan_channel?: TanChannel; + + // @deprecated in **v9**, user conversion rate classes instead + min_cashout?: Amount; } **Response:** @@ -441,9 +446,10 @@ Account Management * ``TALER_EC_BANK_NON_ADMIN_PATCH_LEGAL_NAME`` : a non-admin user has tried to change their legal name. * ``TALER_EC_BANK_NON_ADMIN_PATCH_CASHOUT`` : a non-admin user has tried to change their cashout account. * ``TALER_EC_BANK_NON_ADMIN_PATCH_DEBT_LIMIT`` : a non-admin user has tried to change their debt limit. - * ``TALER_EC_BANK_NON_ADMIN_SET_MIN_CASHOUT`` : a non-admin user has tried to change their custom min cashout amount. + * ``TALER_EC_BANK_NON_ADMIN_SET_CONVERSION_RATE_CLASS`` : a non-admin user has tried to create an account with a conversion rate class. * ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED`` : ``tan_channel`` is not supported, check bank config to find supported ones. * ``TALER_EC_BANK_MISSING_TAN_INFO`` : the user did not share any contact data where to send the TAN via ``tan_channel``. + * ``TALER_EC_BANK_CONVERSION_RATE_CLASS_UNKNOWN`` : no conversion rate class found for this id. .. _account-password-reconfig: @@ -1288,7 +1294,212 @@ Cashouts username: string; } -.. _cashout-rates: +Conversion rate class +--------------------- + +.. http:post:: /conversion-rate-classes + + Create a new conversion rate classe. + + Only available to the administrator. + + **Request:** + + .. ts:def:: ConversionRateClassInput + + interface ConversionRateClassInput { + // The name of this class + name: string; + + // A description of the class + description?: string; + + // Minimum fiat amount authorised for cashin before conversion + cashin_min_amount?: Amount; + + // Exchange rate to buy regional currency from fiat + cashin_ratio?: DecimalNumber; + + // Regional amount fee to subtract after applying the cashin ratio. + cashin_fee?: Amount; + + // Rounding mode used during cashin conversion + cashin_rounding_mode?: "zero" | "up" | "nearest"; + + // Minimum regional amount authorised for cashout before conversion + cashout_min_amount?: Amount; + + // Exchange rate to sell regional currency for fiat + cashout_ratio?: DecimalNumber; + + // Fiat amount fee to subtract after applying the cashout ratio. + cashout_fee?: Amount; + + // Rounding mode used during cashout conversion + cashout_rounding_mode?: "zero" | "up" | "nearest"; + } + + **Response:** + + :http:statuscode:`200 OK`: + The conversion rate class request was correctly created. + This returns the `ConversionRateClassResponse` response. + :http:statuscode:`401 Unauthorized`: + Invalid or missing credentials. + :http:statuscode:`403 Forbidden`: + Missing rights. + :http:statuscode:`409 Conflict`: + * ``TALER_EC_BANK_NAME_REUSE`` : name already used. + :http:statuscode:`501 Not implemented`: + This server does not support conversion, client should check config response. + + **Details:** + + .. ts:def:: ConversionRateClassResponse + + interface ConversionRateClassResponse { + // ID identifying the conversion rate class being created + conversion_rate_class_id: Integer; + } + +.. http:patch:: /conversion-rate-classes/{CLASS_ID} + + Edit an existing conversion rate class. + + Only available to the administrator. + + **Request:** + + `ConversionRateClassInput` + + **Response:** + + :http:statuscode:`204 No Content`: + The conversion rate class request was correctly edited. + :http:statuscode:`401 Unauthorized`: + Invalid or missing credentials. + :http:statuscode:`403 Forbidden`: + Missing rights. + :http:statuscode:`404 Not Found`: + The conversion rate class was not found. + :http:statuscode:`409 Conflict`: + * ``TALER_EC_BANK_NAME_REUSE`` : name already used. + :http:statuscode:`501 Not implemented`: + This server does not support conversion, client should check config response. + +.. http:delete:: /conversion-rate-classes/{CLASS_ID} + + Delete an existing conversion rate class. + + Only available to the administrator. + + **Response:** + + :http:statuscode:`204 No Content`: + The conversion rate class request was correctly deleted. + :http:statuscode:`401 Unauthorized`: + Invalid or missing credentials. + :http:statuscode:`403 Forbidden`: + Missing rights. + :http:statuscode:`404 Not Found`: + The conversion rate class was not found. + :http:statuscode:`501 Not implemented`: + This server does not support conversion, client should check config response. + +.. http:get:: /conversion-rate-classes/{CLASS_ID} + + Get an existing conversion rate class. + + Only available to the administrator. + + **Response:** + + :http:statuscode:`200 OK`: + Response is a `ConversionRateClass`. + :http:statuscode:`401 Unauthorized`: + Invalid or missing credentials. + :http:statuscode:`403 Forbidden`: + Missing rights. + :http:statuscode:`404 Not Found`: + The conversion rate class was not found. + :http:statuscode:`501 Not implemented`: + This server does not support conversion, client should check config response. + + **Details:** + + interface ConversionRateClass { + // The name of this class + name: string; + + // A description of the class + description?: string; + + // Class unique ID + conversion_rate_class_id: Integer; + + // Number of users affected to this class + num_users: Integer; + + // Applied conversion rate + conversion_rate: ConversionRate; + + // Minimum fiat amount authorised for cashin before conversion + cashin_min_amount?: Amount; + + // Exchange rate to buy regional currency from fiat + cashin_ratio?: DecimalNumber; + + // Regional amount fee to subtract after applying the cashin ratio. + cashin_fee?: Amount; + + // Rounding mode used during cashin conversion + cashin_rounding_mode?: "zero" | "up" | "nearest"; + + // Minimum regional amount authorised for cashout before conversion + cashout_min_amount?: Amount; + + // Exchange rate to sell regional currency for fiat + cashout_ratio?: DecimalNumber; + + // Fiat amount fee to subtract after applying the cashout ratio. + cashout_fee?: Amount; + + // Rounding mode used during cashout conversion + cashout_rounding_mode?: "zero" | "up" | "nearest"; + } + +.. http:get:: /conversion-rate-classes + + Returns the list of all conversion rate classes. + + Only available to the administrator. + + **Request:** + + :query limit: *Optional.* + At most return the given number of results. Negative for descending by ``conversion_rate_class_id``, positive for ascending by ``conversion_rate_class_id``. Defaults to ``-20``. + :query offset: *Optional.* + Starting ``conversion_rate_class_id`` for :ref:`pagination <row-id-pagination>`. + + **Response:** + + :http:statuscode:`200 OK`: + Response is a `ConversionRateClass`. + :http:statuscode:`401 Unauthorized`: + Invalid or missing credentials. + :http:statuscode:`403 Forbidden`: + Missing rights. + :http:statuscode:`404 Not Found`: + The conversion rate class was not found. + :http:statuscode:`501 Not implemented`: + This server does not support conversion, client should check config response. + + **Details:** + + interface ConversionRateClasses { + default: ConversionRate; + classes: ConversionRateClass[]; + } 2FA --- @@ -1522,30 +1733,34 @@ Endpoints for Integrated Sub-APIs .. http:any:: /accounts/$USERNAME/taler-wire-gateway/* - All endpoints under this prefix are specified - by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`. + All endpoints under this prefix are specified + by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`. - The endpoints are only available for accounts configured with ``is_taler_exchange=true``. + The endpoints are only available for accounts configured with ``is_taler_exchange=true``. .. http:any:: /accounts/$USERNAME/taler-revenue/* - All endpoints under this prefix are specified - by the :doc:`GNU Taler Revenue API </core/api-bank-revenue>`. + All endpoints under this prefix are specified + by the :doc:`GNU Taler Revenue API </core/api-bank-revenue>`. +.. http:any:: /accounts/$USERNAME/conversion-info/* -.. http:any:: /conversion-info/* + User custom rates, public for accounts configured with ``is_taler_exchange=true`` else private. Since protocol **v9** - All endpoints under this prefix are specified - by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`. + All endpoints under this prefix are specified + by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`. +.. http:any:: /conversion-rate-classes/$CLASS_ID/conversion-info/* -.. http:post:: /ebicshost + Conversion rate conversion infos, admin only. Since **v9** - EBICS base URL. This URL allows clients to make EBICS requests to one of - the configured EBICS hosts. + All endpoints under this prefix are specified + by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`. + +.. http:any:: /conversion-info/* - The Taler bank can be configured to serve bank account transactions and - allow payment initiations via the EBICS protocol. + Global conversion rate infos. - This is an optional feature, not all implementations of the API support it. + All endpoints under this prefix are specified + by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`. +\ No newline at end of file diff --git a/design-documents/063-libeufin-conversion-rate-group.rst b/design-documents/063-libeufin-conversion-rate-group.rst @@ -23,9 +23,6 @@ The current global conversion rate schema is: // Regional amount fee to subtract after applying the cashin ratio. cashin_fee: Amount; - // Smallest possible regional amount, converted amount is rounded to this amount - cashin_tiny_amount: Amount; - // Rounding mode used during cashin conversion cashin_rounding_mode: "zero" | "up" | "nearest"; @@ -38,9 +35,6 @@ The current global conversion rate schema is: // Fiat amount fee to subtract after applying the cashout ratio. cashout_fee: Amount; - // Smallest possible fiat amount, converted amount is rounded to this amount - cashout_tiny_amount: Amount; - // Rounding mode used during cashout conversion cashout_rounding_mode: "zero" | "up" | "nearest"; } @@ -65,9 +59,6 @@ This would become the ``default`` class, that will be used by all created users. // Regional amount fee to subtract after applying the cashin ratio. cashin_fee?: Amount; - // Smallest possible regional amount, converted amount is rounded to this amount - cashin_tiny_amount?: Amount; - // Rounding mode used during cashin conversion cashin_rounding_mode?: "zero" | "up" | "nearest"; @@ -80,9 +71,6 @@ This would become the ``default`` class, that will be used by all created users. // Fiat amount fee to subtract after applying the cashout ratio. cashout_fee?: Amount; - // Smallest possible fiat amount, converted amount is rounded to this amount - cashout_tiny_amount?: Amount; - // Rounding mode used during cashout conversion cashout_rounding_mode?: "zero" | "up" | "nearest"; } @@ -114,9 +102,6 @@ This would become the ``default`` class, that will be used by all created users. // Regional amount fee to subtract after applying the cashin ratio. cashin_fee?: Amount; - // Smallest possible regional amount, converted amount is rounded to this amount - cashin_tiny_amount?: Amount; - // Rounding mode used during cashin conversion cashin_rounding_mode?: "zero" | "up" | "nearest"; @@ -129,9 +114,6 @@ This would become the ``default`` class, that will be used by all created users. // Fiat amount fee to subtract after applying the cashout ratio. cashout_fee?: Amount; - // Smallest possible fiat amount, converted amount is rounded to this amount - cashout_tiny_amount?: Amount; - // Rounding mode used during cashout conversion cashout_rounding_mode?: "zero" | "up" | "nearest"; }