LCOV - code coverage report
Current view: top level - util - taler_error_codes.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 11 29 37.9 %
Date: 2021-08-30 06:43:37 Functions: 1 3 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :      This file is part of GNU Taler
       3             :      Copyright (C) 2012-2020 Taler Systems SA
       4             : 
       5             :      GNU Taler is free software: you can redistribute it and/or modify it
       6             :      under the terms of the GNU Lesser General Public License as published
       7             :      by the Free Software Foundation, either version 3 of the License,
       8             :      or (at your option) any later version.
       9             : 
      10             :      GNU Taler is distributed in the hope that it will be useful, but
      11             :      WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :      Lesser General Public License for more details.
      14             : 
      15             :      You should have received a copy of the GNU Lesser General Public License
      16             :      along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             : 
      18             :      SPDX-License-Identifier: LGPL3.0-or-later
      19             : 
      20             :      Note: the LGPL does not apply to all components of GNU Taler,
      21             :      but it does apply to this file.
      22             :  */
      23             : #include "taler_error_codes.h"
      24             : #include <stddef.h>
      25             : #include <microhttpd.h>
      26             : #include <gettext.h>
      27             : 
      28             : /**
      29             :  * MHD does not define our value for 0 (client-side generated code).
      30             :  */
      31             : #define MHD_HTTP_UNINITIALIZED 0
      32             : 
      33             : /**
      34             :  * A pair containing an error code and its hint.
      35             :  */
      36             : struct ErrorCodeAndHint
      37             : {
      38             :   /**
      39             :    * The error code.
      40             :    */
      41             :   enum TALER_ErrorCode ec;
      42             : 
      43             :   /**
      44             :    * The hint.
      45             :    */
      46             :   const char *hint;
      47             : 
      48             :   /**
      49             :    * The HTTP status code.
      50             :    */
      51             :   unsigned int http_code;
      52             : };
      53             : 
      54             : 
      55             : /**
      56             :  * The list of all error codes with their hints.
      57             :  */
      58             : static const struct ErrorCodeAndHint code_hint_pairs[] = {
      59             : 
      60             :   {
      61             :     .ec = TALER_EC_NONE,
      62             :     .hint = gettext_noop ("Special code to indicate success (no error)."),
      63             :     .http_code = MHD_HTTP_UNINITIALIZED
      64             :   },
      65             :   {
      66             :     .ec = TALER_EC_INVALID,
      67             :     .hint = gettext_noop ("A non-integer error code was returned in the JSON response."),
      68             :     .http_code = MHD_HTTP_UNINITIALIZED
      69             :   },
      70             :   {
      71             :     .ec = TALER_EC_GENERIC_INVALID_RESPONSE,
      72             :     .hint = gettext_noop ("The response we got from the server was not even in JSON format."),
      73             :     .http_code = MHD_HTTP_UNINITIALIZED
      74             :   },
      75             :   {
      76             :     .ec = TALER_EC_GENERIC_TIMEOUT,
      77             :     .hint = gettext_noop ("An operation timed out."),
      78             :     .http_code = MHD_HTTP_UNINITIALIZED
      79             :   },
      80             :   {
      81             :     .ec = TALER_EC_GENERIC_VERSION_MALFORMED,
      82             :     .hint = gettext_noop ("The version string given does not follow the expected CURRENT:REVISION:AGE Format."),
      83             :     .http_code = MHD_HTTP_UNINITIALIZED
      84             :   },
      85             :   {
      86             :     .ec = TALER_EC_GENERIC_REPLY_MALFORMED,
      87             :     .hint = gettext_noop ("The service responded with a reply that was in JSON but did not satsify the protocol. Note that invalid cryptographic signatures should have signature-specific error codes."),
      88             :     .http_code = MHD_HTTP_UNINITIALIZED
      89             :   },
      90             :   {
      91             :     .ec = TALER_EC_GENERIC_CONFIGURATION_INVALID,
      92             :     .hint = gettext_noop ("There is an error in the client-side configuration, for example the base URL specified is malformed."),
      93             :     .http_code = MHD_HTTP_UNINITIALIZED
      94             :   },
      95             :   {
      96             :     .ec = TALER_EC_GENERIC_METHOD_INVALID,
      97             :     .hint = gettext_noop ("The HTTP method used is invalid for this endpoint."),
      98             :     .http_code = MHD_HTTP_METHOD_NOT_ALLOWED
      99             :   },
     100             :   {
     101             :     .ec = TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
     102             :     .hint = gettext_noop ("There is no endpoint defined for the URL provided by the client."),
     103             :     .http_code = MHD_HTTP_NOT_FOUND
     104             :   },
     105             :   {
     106             :     .ec = TALER_EC_GENERIC_JSON_INVALID,
     107             :     .hint = gettext_noop ("The JSON in the client's request was malformed (generic parse error)."),
     108             :     .http_code = MHD_HTTP_BAD_REQUEST
     109             :   },
     110             :   {
     111             :     .ec = TALER_EC_GENERIC_HTTP_HEADERS_MALFORMED,
     112             :     .hint = gettext_noop ("Some of the HTTP headers provided by the client caused the server to not be able to handle the request."),
     113             :     .http_code = MHD_HTTP_BAD_REQUEST
     114             :   },
     115             :   {
     116             :     .ec = TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
     117             :     .hint = gettext_noop ("The payto:// URI provided by the client is malformed."),
     118             :     .http_code = MHD_HTTP_BAD_REQUEST
     119             :   },
     120             :   {
     121             :     .ec = TALER_EC_GENERIC_PARAMETER_MISSING,
     122             :     .hint = gettext_noop ("A required parameter in the request was missing."),
     123             :     .http_code = MHD_HTTP_BAD_REQUEST
     124             :   },
     125             :   {
     126             :     .ec = TALER_EC_GENERIC_PARAMETER_MALFORMED,
     127             :     .hint = gettext_noop ("A parameter in the request was malformed."),
     128             :     .http_code = MHD_HTTP_BAD_REQUEST
     129             :   },
     130             :   {
     131             :     .ec = TALER_EC_GENERIC_CURRENCY_MISMATCH,
     132             :     .hint = gettext_noop ("The currencies involved in the operation do not match."),
     133             :     .http_code = MHD_HTTP_BAD_REQUEST
     134             :   },
     135             :   {
     136             :     .ec = TALER_EC_GENERIC_URI_TOO_LONG,
     137             :     .hint = gettext_noop ("The URI is longer than the longest URI the HTTP server is willing to parse."),
     138             :     .http_code = MHD_HTTP_URI_TOO_LONG
     139             :   },
     140             :   {
     141             :     .ec = TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT,
     142             :     .hint = gettext_noop ("The body is too large to be permissible for the endpoint."),
     143             :     .http_code = MHD_HTTP_PAYLOAD_TOO_LARGE
     144             :   },
     145             :   {
     146             :     .ec = TALER_EC_GENERIC_DB_SETUP_FAILED,
     147             :     .hint = gettext_noop ("The service failed initialize its connection to the database."),
     148             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     149             :   },
     150             :   {
     151             :     .ec = TALER_EC_GENERIC_DB_START_FAILED,
     152             :     .hint = gettext_noop ("The service encountered an error event to just start the database transaction."),
     153             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     154             :   },
     155             :   {
     156             :     .ec = TALER_EC_GENERIC_DB_STORE_FAILED,
     157             :     .hint = gettext_noop ("The service failed to store information in its database."),
     158             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     159             :   },
     160             :   {
     161             :     .ec = TALER_EC_GENERIC_DB_FETCH_FAILED,
     162             :     .hint = gettext_noop ("The service failed to fetch information from its database."),
     163             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     164             :   },
     165             :   {
     166             :     .ec = TALER_EC_GENERIC_DB_COMMIT_FAILED,
     167             :     .hint = gettext_noop ("The service encountered an error event to commit the database transaction (hard, unrecoverable error)."),
     168             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     169             :   },
     170             :   {
     171             :     .ec = TALER_EC_GENERIC_DB_SOFT_FAILURE,
     172             :     .hint = gettext_noop ("The service encountered an error event to commit the database transaction, even after repeatedly retrying it there was always a conflicting transaction. (This indicates a repeated serialization error; should only happen if some client maliciously tries to create conflicting concurrent transactions.)"),
     173             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     174             :   },
     175             :   {
     176             :     .ec = TALER_EC_GENERIC_DB_INVARIANT_FAILURE,
     177             :     .hint = gettext_noop ("The service's database is inconsistent and violates service-internal invariants."),
     178             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     179             :   },
     180             :   {
     181             :     .ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
     182             :     .hint = gettext_noop ("The HTTP server experienced an internal invariant failure (bug)."),
     183             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     184             :   },
     185             :   {
     186             :     .ec = TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH,
     187             :     .hint = gettext_noop ("The service could not compute a cryptographic hash over some JSON value."),
     188             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     189             :   },
     190             :   {
     191             :     .ec = TALER_EC_GENERIC_PARSER_OUT_OF_MEMORY,
     192             :     .hint = gettext_noop ("The HTTP server had insufficient memory to parse the request."),
     193             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     194             :   },
     195             :   {
     196             :     .ec = TALER_EC_GENERIC_ALLOCATION_FAILURE,
     197             :     .hint = gettext_noop ("The HTTP server failed to allocate memory."),
     198             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     199             :   },
     200             :   {
     201             :     .ec = TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE,
     202             :     .hint = gettext_noop ("The HTTP server failed to allocate memory for building JSON reply."),
     203             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     204             :   },
     205             :   {
     206             :     .ec = TALER_EC_GENERIC_CURL_ALLOCATION_FAILURE,
     207             :     .hint = gettext_noop ("The HTTP server failed to allocate memory for making a CURL request."),
     208             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     209             :   },
     210             :   {
     211             :     .ec = TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
     212             :     .hint = gettext_noop ("Exchange is badly configured and thus cannot operate."),
     213             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     214             :   },
     215             :   {
     216             :     .ec = TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
     217             :     .hint = gettext_noop ("Operation specified unknown for this endpoint."),
     218             :     .http_code = MHD_HTTP_NOT_FOUND
     219             :   },
     220             :   {
     221             :     .ec = TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,
     222             :     .hint = gettext_noop ("The number of segments included in the URI does not match the number of segments expected by the endpoint."),
     223             :     .http_code = MHD_HTTP_NOT_FOUND
     224             :   },
     225             :   {
     226             :     .ec = TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY,
     227             :     .hint = gettext_noop ("The same coin was already used with a different denomination previously."),
     228             :     .http_code = MHD_HTTP_CONFLICT
     229             :   },
     230             :   {
     231             :     .ec = TALER_EC_EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB,
     232             :     .hint = gettext_noop ("The public key of given to a \"/coins/\" endpoint of the exchange was malformed."),
     233             :     .http_code = MHD_HTTP_BAD_REQUEST
     234             :   },
     235             :   {
     236             :     .ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN,
     237             :     .hint = gettext_noop ("The exchange is not aware of the denomination key the wallet requested for the operation."),
     238             :     .http_code = MHD_HTTP_NOT_FOUND
     239             :   },
     240             :   {
     241             :     .ec = TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID,
     242             :     .hint = gettext_noop ("The signature of the denomination key over the coin is not valid."),
     243             :     .http_code = MHD_HTTP_FORBIDDEN
     244             :   },
     245             :   {
     246             :     .ec = TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
     247             :     .hint = gettext_noop ("The exchange failed to perform the operation as it could not find the private keys. This is a problem with the exchange setup, not with the client's request."),
     248             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     249             :   },
     250             :   {
     251             :     .ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
     252             :     .hint = gettext_noop ("Validity period of the denomination lies in the future."),
     253             :     .http_code = MHD_HTTP_PRECONDITION_FAILED
     254             :   },
     255             :   {
     256             :     .ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
     257             :     .hint = gettext_noop ("Denomination key of the coin is past its expiration time for the requested operation."),
     258             :     .http_code = MHD_HTTP_GONE
     259             :   },
     260             :   {
     261             :     .ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED,
     262             :     .hint = gettext_noop ("Denomination key of the coin has been revoked."),
     263             :     .http_code = MHD_HTTP_GONE
     264             :   },
     265             :   {
     266             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_NOT_FOUND,
     267             :     .hint = gettext_noop ("The exchange did not find information about the specified transaction in the database."),
     268             :     .http_code = MHD_HTTP_NOT_FOUND
     269             :   },
     270             :   {
     271             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_H_WIRE,
     272             :     .hint = gettext_noop ("The wire hash of given to a \"/deposits/\" handler was malformed."),
     273             :     .http_code = MHD_HTTP_BAD_REQUEST
     274             :   },
     275             :   {
     276             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_MERCHANT_PUB,
     277             :     .hint = gettext_noop ("The merchant key of given to a \"/deposits/\" handler was malformed."),
     278             :     .http_code = MHD_HTTP_BAD_REQUEST
     279             :   },
     280             :   {
     281             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_H_CONTRACT_TERMS,
     282             :     .hint = gettext_noop ("The hash of the contract terms given to a \"/deposits/\" handler was malformed."),
     283             :     .http_code = MHD_HTTP_BAD_REQUEST
     284             :   },
     285             :   {
     286             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_COIN_PUB,
     287             :     .hint = gettext_noop ("The coin public key of given to a \"/deposits/\" handler was malformed."),
     288             :     .http_code = MHD_HTTP_BAD_REQUEST
     289             :   },
     290             :   {
     291             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE,
     292             :     .hint = gettext_noop ("The signature returned by the exchange in a /deposits/ request was malformed."),
     293             :     .http_code = MHD_HTTP_UNINITIALIZED
     294             :   },
     295             :   {
     296             :     .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID,
     297             :     .hint = gettext_noop ("The signature of the merchant is invalid."),
     298             :     .http_code = MHD_HTTP_FORBIDDEN
     299             :   },
     300             :   {
     301             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS,
     302             :     .hint = gettext_noop ("The given reserve does not have sufficient funds to admit the requested withdraw operation at this time.  The response includes the current \"balance\" of the reserve as well as the transaction \"history\" that lead to this balance."),
     303             :     .http_code = MHD_HTTP_CONFLICT
     304             :   },
     305             :   {
     306             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN,
     307             :     .hint = gettext_noop ("The exchange has no information about the \"reserve_pub\" that was given."),
     308             :     .http_code = MHD_HTTP_NOT_FOUND
     309             :   },
     310             :   {
     311             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
     312             :     .hint = gettext_noop ("The amount to withdraw together with the fee exceeds the numeric range for Taler amounts.  This is not a client failure, as the coin value and fees come from the exchange's configuration."),
     313             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     314             :   },
     315             :   {
     316             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_SIGNATURE_FAILED,
     317             :     .hint = gettext_noop ("The exchange failed to create the signature using the denomination key."),
     318             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     319             :   },
     320             :   {
     321             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID,
     322             :     .hint = gettext_noop ("The signature of the reserve is not valid."),
     323             :     .http_code = MHD_HTTP_FORBIDDEN
     324             :   },
     325             :   {
     326             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
     327             :     .hint = gettext_noop ("When computing the reserve history, we ended up with a negative overall balance, which should be impossible."),
     328             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     329             :   },
     330             :   {
     331             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_DENOMINATION_KEY_LOST,
     332             :     .hint = gettext_noop ("Withdraw period of the coin to be withdrawn is in the past."),
     333             :     .http_code = MHD_HTTP_GONE
     334             :   },
     335             :   {
     336             :     .ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE,
     337             :     .hint = gettext_noop ("The client failed to unblind the blind signature."),
     338             :     .http_code = MHD_HTTP_UNINITIALIZED
     339             :   },
     340             :   {
     341             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_INSUFFICIENT_FUNDS,
     342             :     .hint = gettext_noop ("The respective coin did not have sufficient residual value for the /deposit operation (i.e. due to double spending). The \"history\" in the response provides the transaction history of the coin proving this fact."),
     343             :     .http_code = MHD_HTTP_CONFLICT
     344             :   },
     345             :   {
     346             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID,
     347             :     .hint = gettext_noop ("The signature made by the coin over the deposit permission is not valid."),
     348             :     .http_code = MHD_HTTP_FORBIDDEN
     349             :   },
     350             :   {
     351             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
     352             :     .hint = gettext_noop ("The stated value of the coin after the deposit fee is subtracted would be negative."),
     353             :     .http_code = MHD_HTTP_BAD_REQUEST
     354             :   },
     355             :   {
     356             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
     357             :     .hint = gettext_noop ("The stated refund deadline is after the wire deadline."),
     358             :     .http_code = MHD_HTTP_BAD_REQUEST
     359             :   },
     360             :   {
     361             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
     362             :     .hint = gettext_noop ("The exchange failed to canonicalize and hash the given wire format. For example, the merchant failed to provide the \"salt\" or a valid payto:// URI in the wire details.  Note that while the exchange will do some basic sanity checking on the wire details, it cannot warrant that the banking system will ultimately be able to route to the specified address, even if this check passed."),
     363             :     .http_code = MHD_HTTP_BAD_REQUEST
     364             :   },
     365             :   {
     366             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
     367             :     .hint = gettext_noop ("The hash of the given wire address does not match the wire hash specified in the proposal data."),
     368             :     .http_code = MHD_HTTP_BAD_REQUEST
     369             :   },
     370             :   {
     371             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE,
     372             :     .hint = gettext_noop ("The signature provided by the exchange is not valid."),
     373             :     .http_code = MHD_HTTP_UNINITIALIZED
     374             :   },
     375             :   {
     376             :     .ec = TALER_EC_EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT,
     377             :     .hint = gettext_noop ("The deposited amount is smaller than the deposit fee, which would result in a negative contribution."),
     378             :     .http_code = MHD_HTTP_BAD_REQUEST
     379             :   },
     380             :   {
     381             :     .ec = TALER_EC_EXCHANGE_RESERVES_GET_STATUS_UNKNOWN,
     382             :     .hint = gettext_noop ("The reserve status was requested using a unknown key."),
     383             :     .http_code = MHD_HTTP_NOT_FOUND
     384             :   },
     385             :   {
     386             :     .ec = TALER_EC_EXCHANGE_MELT_INSUFFICIENT_FUNDS,
     387             :     .hint = gettext_noop ("The respective coin did not have sufficient residual value for the /refresh/melt operation.  The \"history\" in this response provdes the \"residual_value\" of the coin, which may be less than its \"original_value\"."),
     388             :     .http_code = MHD_HTTP_CONFLICT
     389             :   },
     390             :   {
     391             :     .ec = TALER_EC_EXCHANGE_MELT_COIN_HISTORY_COMPUTATION_FAILED,
     392             :     .hint = gettext_noop ("The exchange had an internal error reconstructing the transaction history of the coin that was being melted."),
     393             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     394             :   },
     395             :   {
     396             :     .ec = TALER_EC_EXCHANGE_MELT_FEES_EXCEED_CONTRIBUTION,
     397             :     .hint = gettext_noop ("The exchange encountered melt fees exceeding the melted coin's contribution."),
     398             :     .http_code = MHD_HTTP_BAD_REQUEST
     399             :   },
     400             :   {
     401             :     .ec = TALER_EC_EXCHANGE_MELT_COIN_SIGNATURE_INVALID,
     402             :     .hint = gettext_noop ("The signature made with the coin to be melted is invalid."),
     403             :     .http_code = MHD_HTTP_FORBIDDEN
     404             :   },
     405             :   {
     406             :     .ec = TALER_EC_EXCHANGE_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
     407             :     .hint = gettext_noop ("The exchange failed to obtain the transaction history of the given coin from the database while generating an insufficient funds errors."),
     408             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     409             :   },
     410             :   {
     411             :     .ec = TALER_EC_EXCHANGE_MELT_COIN_EXPIRED_NO_ZOMBIE,
     412             :     .hint = gettext_noop ("The denomination of the given coin has past its expiration date and it is also not a valid zombie (that is, was not refreshed with the fresh coin being subjected to recoup)."),
     413             :     .http_code = MHD_HTTP_BAD_REQUEST
     414             :   },
     415             :   {
     416             :     .ec = TALER_EC_EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE,
     417             :     .hint = gettext_noop ("The signature returned by the exchange in a melt request was malformed."),
     418             :     .http_code = MHD_HTTP_UNINITIALIZED
     419             :   },
     420             :   {
     421             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_COMMITMENT_VIOLATION,
     422             :     .hint = gettext_noop ("The provided transfer keys do not match up with the original commitment.  Information about the original commitment is included in the response."),
     423             :     .http_code = MHD_HTTP_CONFLICT
     424             :   },
     425             :   {
     426             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_SIGNING_ERROR,
     427             :     .hint = gettext_noop ("Failed to produce the blinded signatures over the coins to be returned."),
     428             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     429             :   },
     430             :   {
     431             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_SESSION_UNKNOWN,
     432             :     .hint = gettext_noop ("The exchange is unaware of the refresh session specified in the request."),
     433             :     .http_code = MHD_HTTP_NOT_FOUND
     434             :   },
     435             :   {
     436             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
     437             :     .hint = gettext_noop ("The size of the cut-and-choose dimension of the private transfer keys request does not match #TALER_CNC_KAPPA - 1."),
     438             :     .http_code = MHD_HTTP_BAD_REQUEST
     439             :   },
     440             :   {
     441             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
     442             :     .hint = gettext_noop ("The number of coins to be created in refresh exceeds the limits of the exchange. private transfer keys request does not match #TALER_CNC_KAPPA - 1."),
     443             :     .http_code = MHD_HTTP_BAD_REQUEST
     444             :   },
     445             :   {
     446             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISMATCH,
     447             :     .hint = gettext_noop ("The number of envelopes given does not match the number of denomination keys given."),
     448             :     .http_code = MHD_HTTP_BAD_REQUEST
     449             :   },
     450             :   {
     451             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_COST_CALCULATION_OVERFLOW,
     452             :     .hint = gettext_noop ("The exchange encountered a numeric overflow totaling up the cost for the refresh operation."),
     453             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     454             :   },
     455             :   {
     456             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_AMOUNT_INSUFFICIENT,
     457             :     .hint = gettext_noop ("The exchange's cost calculation shows that the melt amount is below the costs of the transaction."),
     458             :     .http_code = MHD_HTTP_BAD_REQUEST
     459             :   },
     460             :   {
     461             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID,
     462             :     .hint = gettext_noop ("The signature made with the coin over the link data is invalid."),
     463             :     .http_code = MHD_HTTP_FORBIDDEN
     464             :   },
     465             :   {
     466             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_INVALID_RCH,
     467             :     .hint = gettext_noop ("The refresh session hash given to a /refreshes/ handler was malformed."),
     468             :     .http_code = MHD_HTTP_BAD_REQUEST
     469             :   },
     470             :   {
     471             :     .ec = TALER_EC_EXCHANGE_REFRESHES_REVEAL_OPERATION_INVALID,
     472             :     .hint = gettext_noop ("Operation specified invalid for this endpoint."),
     473             :     .http_code = MHD_HTTP_BAD_REQUEST
     474             :   },
     475             :   {
     476             :     .ec = TALER_EC_EXCHANGE_LINK_COIN_UNKNOWN,
     477             :     .hint = gettext_noop ("The coin specified in the link request is unknown to the exchange."),
     478             :     .http_code = MHD_HTTP_NOT_FOUND
     479             :   },
     480             :   {
     481             :     .ec = TALER_EC_EXCHANGE_TRANSFERS_GET_WTID_MALFORMED,
     482             :     .hint = gettext_noop ("The public key of given to a /transfers/ handler was malformed."),
     483             :     .http_code = MHD_HTTP_BAD_REQUEST
     484             :   },
     485             :   {
     486             :     .ec = TALER_EC_EXCHANGE_TRANSFERS_GET_WTID_NOT_FOUND,
     487             :     .hint = gettext_noop ("The exchange did not find information about the specified wire transfer identifier in the database."),
     488             :     .http_code = MHD_HTTP_NOT_FOUND
     489             :   },
     490             :   {
     491             :     .ec = TALER_EC_EXCHANGE_TRANSFERS_GET_WIRE_FEE_NOT_FOUND,
     492             :     .hint = gettext_noop ("The exchange did not find information about the wire transfer fees it charged."),
     493             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     494             :   },
     495             :   {
     496             :     .ec = TALER_EC_EXCHANGE_TRANSFERS_GET_WIRE_FEE_INCONSISTENT,
     497             :     .hint = gettext_noop ("The exchange found a wire fee that was above the total transfer value (and thus could not have been charged)."),
     498             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     499             :   },
     500             :   {
     501             :     .ec = TALER_EC_EXCHANGE_REFUND_COIN_NOT_FOUND,
     502             :     .hint = gettext_noop ("The exchange knows literally nothing about the coin we were asked to refund. But without a transaction history, we cannot issue a refund. This is kind-of OK, the owner should just refresh it directly without executing the refund."),
     503             :     .http_code = MHD_HTTP_NOT_FOUND
     504             :   },
     505             :   {
     506             :     .ec = TALER_EC_EXCHANGE_REFUND_CONFLICT_DEPOSIT_INSUFFICIENT,
     507             :     .hint = gettext_noop ("We could not process the refund request as the coin's transaction history does not permit the requested refund because then refunds would exceed the deposit amount.  The \"history\" in the response proves this."),
     508             :     .http_code = MHD_HTTP_CONFLICT
     509             :   },
     510             :   {
     511             :     .ec = TALER_EC_EXCHANGE_REFUND_DEPOSIT_NOT_FOUND,
     512             :     .hint = gettext_noop ("The exchange knows about the coin we were asked to refund, but not about the specific /deposit operation.  Hence, we cannot issue a refund (as we do not know if this merchant public key is authorized to do a refund)."),
     513             :     .http_code = MHD_HTTP_NOT_FOUND
     514             :   },
     515             :   {
     516             :     .ec = TALER_EC_EXCHANGE_REFUND_MERCHANT_ALREADY_PAID,
     517             :     .hint = gettext_noop ("The exchange can no longer refund the customer/coin as the money was already transferred (paid out) to the merchant. (It should be past the refund deadline.)"),
     518             :     .http_code = MHD_HTTP_GONE
     519             :   },
     520             :   {
     521             :     .ec = TALER_EC_EXCHANGE_REFUND_FEE_TOO_LOW,
     522             :     .hint = gettext_noop ("The refund fee specified for the request is lower than the refund fee charged by the exchange for the given denomination key of the refunded coin."),
     523             :     .http_code = MHD_HTTP_BAD_REQUEST
     524             :   },
     525             :   {
     526             :     .ec = TALER_EC_EXCHANGE_REFUND_FEE_ABOVE_AMOUNT,
     527             :     .hint = gettext_noop ("The refunded amount is smaller than the refund fee, which would result in a negative refund."),
     528             :     .http_code = MHD_HTTP_BAD_REQUEST
     529             :   },
     530             :   {
     531             :     .ec = TALER_EC_EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID,
     532             :     .hint = gettext_noop ("The signature of the merchant is invalid."),
     533             :     .http_code = MHD_HTTP_FORBIDDEN
     534             :   },
     535             :   {
     536             :     .ec = TALER_EC_EXCHANGE_REFUND_MERCHANT_SIGNING_FAILED,
     537             :     .hint = gettext_noop ("Merchant backend failed to create the refund confirmation signature."),
     538             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     539             :   },
     540             :   {
     541             :     .ec = TALER_EC_EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE,
     542             :     .hint = gettext_noop ("The signature returned by the exchange in a refund request was malformed."),
     543             :     .http_code = MHD_HTTP_UNINITIALIZED
     544             :   },
     545             :   {
     546             :     .ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE,
     547             :     .hint = gettext_noop ("The failure proof returned by the exchange is incorrect."),
     548             :     .http_code = MHD_HTTP_UNINITIALIZED
     549             :   },
     550             :   {
     551             :     .ec = TALER_EC_EXCHANGE_REFUND_INCONSISTENT_AMOUNT,
     552             :     .hint = gettext_noop ("Conflicting refund granted before with different amount but same refund transaction ID."),
     553             :     .http_code = MHD_HTTP_FAILED_DEPENDENCY
     554             :   },
     555             :   {
     556             :     .ec = TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
     557             :     .hint = gettext_noop ("The given coin signature is invalid for the request."),
     558             :     .http_code = MHD_HTTP_FORBIDDEN
     559             :   },
     560             :   {
     561             :     .ec = TALER_EC_EXCHANGE_RECOUP_WITHDRAW_NOT_FOUND,
     562             :     .hint = gettext_noop ("The exchange could not find the corresponding withdraw operation. The request is denied."),
     563             :     .http_code = MHD_HTTP_NOT_FOUND
     564             :   },
     565             :   {
     566             :     .ec = TALER_EC_EXCHANGE_RECOUP_COIN_BALANCE_ZERO,
     567             :     .hint = gettext_noop ("The coin's remaining balance is zero.  The request is denied."),
     568             :     .http_code = MHD_HTTP_FORBIDDEN
     569             :   },
     570             :   {
     571             :     .ec = TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED,
     572             :     .hint = gettext_noop ("The exchange failed to reproduce the coin's blinding."),
     573             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     574             :   },
     575             :   {
     576             :     .ec = TALER_EC_EXCHANGE_RECOUP_COIN_BALANCE_NEGATIVE,
     577             :     .hint = gettext_noop ("The coin's remaining balance is zero.  The request is denied."),
     578             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     579             :   },
     580             :   {
     581             :     .ec = TALER_EC_EXCHANGE_RECOUP_NOT_ELIGIBLE,
     582             :     .hint = gettext_noop ("The coin's denomination has not been revoked yet."),
     583             :     .http_code = MHD_HTTP_NOT_FOUND
     584             :   },
     585             :   {
     586             :     .ec = TALER_EC_EXCHANGE_KEYS_TIMETRAVEL_FORBIDDEN,
     587             :     .hint = gettext_noop ("This exchange does not allow clients to request /keys for times other than the current (exchange) time."),
     588             :     .http_code = MHD_HTTP_FORBIDDEN
     589             :   },
     590             :   {
     591             :     .ec = TALER_EC_EXCHANGE_WIRE_SIGNATURE_INVALID,
     592             :     .hint = gettext_noop ("A signature in the server's response was malformed."),
     593             :     .http_code = MHD_HTTP_UNINITIALIZED
     594             :   },
     595             :   {
     596             :     .ec = TALER_EC_EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED,
     597             :     .hint = gettext_noop ("No bank accounts are enabled for the exchange. The administrator should enable-account using the taler-exchange-offline tool."),
     598             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     599             :   },
     600             :   {
     601             :     .ec = TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED,
     602             :     .hint = gettext_noop ("The payto:// URI stored in the exchange database for its bank account is malformed."),
     603             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     604             :   },
     605             :   {
     606             :     .ec = TALER_EC_EXCHANGE_WIRE_FEES_NOT_CONFIGURED,
     607             :     .hint = gettext_noop ("No wire fees are configured for an enabled wire method of the exchange. The administrator must set the wire-fee using the taler-exchange-offline tool."),
     608             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     609             :   },
     610             :   {
     611             :     .ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE,
     612             :     .hint = gettext_noop ("The exchange failed to talk to the process responsible for its private denomination keys."),
     613             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     614             :   },
     615             :   {
     616             :     .ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG,
     617             :     .hint = gettext_noop ("The response from the denomination key helper process was malformed."),
     618             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     619             :   },
     620             :   {
     621             :     .ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY,
     622             :     .hint = gettext_noop ("The helper refuses to sign with the key, because it is too early: the validity period has not yet started."),
     623             :     .http_code = MHD_HTTP_BAD_REQUEST
     624             :   },
     625             :   {
     626             :     .ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE,
     627             :     .hint = gettext_noop ("The exchange failed to talk to the process responsible for its private signing keys."),
     628             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     629             :   },
     630             :   {
     631             :     .ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG,
     632             :     .hint = gettext_noop ("The response from the online signing key helper process was malformed."),
     633             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     634             :   },
     635             :   {
     636             :     .ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_TOO_EARLY,
     637             :     .hint = gettext_noop ("The helper refuses to sign with the key, because it is too early: the validity period has not yet started."),
     638             :     .http_code = MHD_HTTP_BAD_REQUEST
     639             :   },
     640             :   {
     641             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_NOT_FOUND,
     642             :     .hint = gettext_noop ("The auditor that was supposed to be disabled is unknown to this exchange."),
     643             :     .http_code = MHD_HTTP_NOT_FOUND
     644             :   },
     645             :   {
     646             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_MORE_RECENT_PRESENT,
     647             :     .hint = gettext_noop ("The exchange has a more recently signed conflicting instruction and is thus refusing the current change (replay detected)."),
     648             :     .http_code = MHD_HTTP_CONFLICT
     649             :   },
     650             :   {
     651             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID,
     652             :     .hint = gettext_noop ("The signature to add or enable the auditor does not validate."),
     653             :     .http_code = MHD_HTTP_FORBIDDEN
     654             :   },
     655             :   {
     656             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID,
     657             :     .hint = gettext_noop ("The signature to disable the auditor does not validate."),
     658             :     .http_code = MHD_HTTP_FORBIDDEN
     659             :   },
     660             :   {
     661             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID,
     662             :     .hint = gettext_noop ("The signature to revoke the denomination does not validate."),
     663             :     .http_code = MHD_HTTP_FORBIDDEN
     664             :   },
     665             :   {
     666             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID,
     667             :     .hint = gettext_noop ("The signature to revoke the online signing key does not validate."),
     668             :     .http_code = MHD_HTTP_FORBIDDEN
     669             :   },
     670             :   {
     671             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_MORE_RECENT_PRESENT,
     672             :     .hint = gettext_noop ("The exchange has a more recently signed conflicting instruction and is thus refusing the current change (replay detected)."),
     673             :     .http_code = MHD_HTTP_CONFLICT
     674             :   },
     675             :   {
     676             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN,
     677             :     .hint = gettext_noop ("The signingkey specified is unknown to the exchange."),
     678             :     .http_code = MHD_HTTP_NOT_FOUND
     679             :   },
     680             :   {
     681             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_DETAILS_SIGNATURE_INVALID,
     682             :     .hint = gettext_noop ("The signature to publish wire account does not validate."),
     683             :     .http_code = MHD_HTTP_FORBIDDEN
     684             :   },
     685             :   {
     686             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID,
     687             :     .hint = gettext_noop ("The signature to add the wire account does not validate."),
     688             :     .http_code = MHD_HTTP_FORBIDDEN
     689             :   },
     690             :   {
     691             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID,
     692             :     .hint = gettext_noop ("The signature to disable the wire account does not validate."),
     693             :     .http_code = MHD_HTTP_FORBIDDEN
     694             :   },
     695             :   {
     696             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_NOT_FOUND,
     697             :     .hint = gettext_noop ("The wire account to be disabled is unknown to the exchange."),
     698             :     .http_code = MHD_HTTP_NOT_FOUND
     699             :   },
     700             :   {
     701             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID,
     702             :     .hint = gettext_noop ("The signature to affirm wire fees does not validate."),
     703             :     .http_code = MHD_HTTP_FORBIDDEN
     704             :   },
     705             :   {
     706             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_WIRE_FEE_MISMATCH,
     707             :     .hint = gettext_noop ("The signature conflicts with a previous signature affirming different fees."),
     708             :     .http_code = MHD_HTTP_CONFLICT
     709             :   },
     710             :   {
     711             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID,
     712             :     .hint = gettext_noop ("The signature affirming the denomination key is invalid."),
     713             :     .http_code = MHD_HTTP_FORBIDDEN
     714             :   },
     715             :   {
     716             :     .ec = TALER_EC_EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID,
     717             :     .hint = gettext_noop ("The signature affirming the signing key is invalid."),
     718             :     .http_code = MHD_HTTP_FORBIDDEN
     719             :   },
     720             :   {
     721             :     .ec = TALER_EC_EXCHANGE_AUDITORS_AUDITOR_SIGNATURE_INVALID,
     722             :     .hint = gettext_noop ("The auditor signature over the denomination meta data is invalid."),
     723             :     .http_code = MHD_HTTP_FORBIDDEN
     724             :   },
     725             :   {
     726             :     .ec = TALER_EC_EXCHANGE_AUDITORS_AUDITOR_UNKNOWN,
     727             :     .hint = gettext_noop ("The auditor that was specified is unknown to this exchange."),
     728             :     .http_code = MHD_HTTP_PRECONDITION_FAILED
     729             :   },
     730             :   {
     731             :     .ec = TALER_EC_EXCHANGE_AUDITORS_AUDITOR_INACTIVE,
     732             :     .hint = gettext_noop ("The auditor that was specified is no longer used by this exchange."),
     733             :     .http_code = MHD_HTTP_GONE
     734             :   },
     735             :   {
     736             :     .ec = TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN,
     737             :     .hint = gettext_noop ("The backend could not find the merchant instance specified in the request."),
     738             :     .http_code = MHD_HTTP_NOT_FOUND
     739             :   },
     740             :   {
     741             :     .ec = TALER_EC_MERCHANT_GENERIC_HOLE_IN_WIRE_FEE_STRUCTURE,
     742             :     .hint = gettext_noop ("The start and end-times in the wire fee structure leave a hole. This is not allowed."),
     743             :     .http_code = MHD_HTTP_UNINITIALIZED
     744             :   },
     745             :   {
     746             :     .ec = TALER_EC_MERCHANT_GENERIC_RESERVE_PUB_MALFORMED,
     747             :     .hint = gettext_noop ("The reserve key of given to a /reserves/ handler was malformed."),
     748             :     .http_code = MHD_HTTP_BAD_REQUEST
     749             :   },
     750             :   {
     751             :     .ec = TALER_EC_MERCHANT_GENERIC_FAILED_TO_LOAD_TEMPLATE,
     752             :     .hint = gettext_noop ("The backend could not locate a required template to generate an HTML reply."),
     753             :     .http_code = MHD_HTTP_NOT_ACCEPTABLE
     754             :   },
     755             :   {
     756             :     .ec = TALER_EC_MERCHANT_GENERIC_FAILED_TO_EXPAND_TEMPLATE,
     757             :     .hint = gettext_noop ("The backend could not expand the template to generate an HTML reply."),
     758             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     759             :   },
     760             :   {
     761             :     .ec = TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN,
     762             :     .hint = gettext_noop ("The proposal is not known to the backend."),
     763             :     .http_code = MHD_HTTP_NOT_FOUND
     764             :   },
     765             :   {
     766             :     .ec = TALER_EC_MERCHANT_GENERIC_PRODUCT_UNKNOWN,
     767             :     .hint = gettext_noop ("The order provided to the backend could not be completed, because a product to be completed via inventory data is not actually in our inventory."),
     768             :     .http_code = MHD_HTTP_NOT_FOUND
     769             :   },
     770             :   {
     771             :     .ec = TALER_EC_MERCHANT_GENERIC_TIP_ID_UNKNOWN,
     772             :     .hint = gettext_noop ("The tip ID is unknown.  This could happen if the tip has expired."),
     773             :     .http_code = MHD_HTTP_NOT_FOUND
     774             :   },
     775             :   {
     776             :     .ec = TALER_EC_MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID,
     777             :     .hint = gettext_noop ("The contract obtained from the merchant backend was malformed."),
     778             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     779             :   },
     780             :   {
     781             :     .ec = TALER_EC_MERCHANT_GENERIC_CONTRACT_HASH_DOES_NOT_MATCH_ORDER,
     782             :     .hint = gettext_noop ("The order we found does not match the provided contract hash."),
     783             :     .http_code = MHD_HTTP_FORBIDDEN
     784             :   },
     785             :   {
     786             :     .ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE,
     787             :     .hint = gettext_noop ("The exchange failed to provide a valid response to the merchant's /keys request."),
     788             :     .http_code = MHD_HTTP_BAD_GATEWAY
     789             :   },
     790             :   {
     791             :     .ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT,
     792             :     .hint = gettext_noop ("The exchange failed to respond to the merchant on time."),
     793             :     .http_code = MHD_HTTP_GATEWAY_TIMEOUT
     794             :   },
     795             :   {
     796             :     .ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE,
     797             :     .hint = gettext_noop ("The merchant failed to talk to the exchange."),
     798             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     799             :   },
     800             :   {
     801             :     .ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED,
     802             :     .hint = gettext_noop ("The exchange returned a maformed response."),
     803             :     .http_code = MHD_HTTP_BAD_GATEWAY
     804             :   },
     805             :   {
     806             :     .ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS,
     807             :     .hint = gettext_noop ("The exchange returned an unexpected response status."),
     808             :     .http_code = MHD_HTTP_BAD_GATEWAY
     809             :   },
     810             :   {
     811             :     .ec = TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED,
     812             :     .hint = gettext_noop ("The merchant refused the request due to lack of authorization."),
     813             :     .http_code = MHD_HTTP_UNAUTHORIZED
     814             :   },
     815             :   {
     816             :     .ec = TALER_EC_MERCHANT_GENERIC_INSTANCE_DELETED,
     817             :     .hint = gettext_noop ("The merchant instance specified in the request was deleted."),
     818             :     .http_code = MHD_HTTP_NOT_FOUND
     819             :   },
     820             :   {
     821             :     .ec = TALER_EC_MERCHANT_GENERIC_TRANSFER_UNKNOWN,
     822             :     .hint = gettext_noop ("The backend could not find the inbound wire transfer specified in the request."),
     823             :     .http_code = MHD_HTTP_NOT_FOUND
     824             :   },
     825             :   {
     826             :     .ec = TALER_EC_MERCHANT_GET_ORDERS_EXCHANGE_TRACKING_FAILURE,
     827             :     .hint = gettext_noop ("The exchange failed to provide a valid answer to the tracking request, thus those details are not in the response."),
     828             :     .http_code = MHD_HTTP_OK
     829             :   },
     830             :   {
     831             :     .ec = TALER_EC_MERCHANT_GET_ORDERS_ID_EXCHANGE_REQUEST_FAILURE,
     832             :     .hint = gettext_noop ("The merchant backend failed to construct the request for tracking to the exchange, thus tracking details are not in the response."),
     833             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     834             :   },
     835             :   {
     836             :     .ec = TALER_EC_MERCHANT_GET_ORDERS_ID_EXCHANGE_LOOKUP_START_FAILURE,
     837             :     .hint = gettext_noop ("The merchant backend failed trying to contact the exchange for tracking details, thus those details are not in the response."),
     838             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     839             :   },
     840             :   {
     841             :     .ec = TALER_EC_MERCHANT_GET_ORDERS_ID_INVALID_TOKEN,
     842             :     .hint = gettext_noop ("The claim token used to authenticate the client is invalid for this order."),
     843             :     .http_code = MHD_HTTP_FORBIDDEN
     844             :   },
     845             :   {
     846             :     .ec = TALER_EC_MERCHANT_GET_ORDERS_ID_INVALID_CONTRACT_HASH,
     847             :     .hint = gettext_noop ("The contract terms hash used to authenticate the client is invalid for this order."),
     848             :     .http_code = MHD_HTTP_FORBIDDEN
     849             :   },
     850             :   {
     851             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS,
     852             :     .hint = gettext_noop ("The exchange responded saying that funds were insufficient (for example, due to double-spending)."),
     853             :     .http_code = MHD_HTTP_CONFLICT
     854             :   },
     855             :   {
     856             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND,
     857             :     .hint = gettext_noop ("The denomination key used for payment is not listed among the denomination keys of the exchange."),
     858             :     .http_code = MHD_HTTP_BAD_REQUEST
     859             :   },
     860             :   {
     861             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_AUDITOR_FAILURE,
     862             :     .hint = gettext_noop ("The denomination key used for payment is not audited by an auditor approved by the merchant."),
     863             :     .http_code = MHD_HTTP_BAD_REQUEST
     864             :   },
     865             :   {
     866             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
     867             :     .hint = gettext_noop ("There was an integer overflow totaling up the amounts or deposit fees in the payment."),
     868             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     869             :   },
     870             :   {
     871             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT,
     872             :     .hint = gettext_noop ("The deposit fees exceed the total value of the payment."),
     873             :     .http_code = MHD_HTTP_BAD_REQUEST
     874             :   },
     875             :   {
     876             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES,
     877             :     .hint = gettext_noop ("After considering deposit and wire fees, the payment is insufficient to satisfy the required amount for the contract.  The client should revisit the logic used to calculate fees it must cover."),
     878             :     .http_code = MHD_HTTP_NOT_ACCEPTABLE
     879             :   },
     880             :   {
     881             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT,
     882             :     .hint = gettext_noop ("Even if we do not consider deposit and wire fees, the payment is insufficient to satisfy the required amount for the contract."),
     883             :     .http_code = MHD_HTTP_NOT_ACCEPTABLE
     884             :   },
     885             :   {
     886             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_COIN_SIGNATURE_INVALID,
     887             :     .hint = gettext_noop ("The signature over the contract of one of the coins was invalid."),
     888             :     .http_code = MHD_HTTP_FORBIDDEN
     889             :   },
     890             :   {
     891             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
     892             :     .hint = gettext_noop ("When we tried to find information about the exchange to issue the deposit, we failed.  This usually only happens if the merchant backend is somehow unable to get its own HTTP client logic to work."),
     893             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     894             :   },
     895             :   {
     896             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE,
     897             :     .hint = gettext_noop ("The refund deadline in the contract is after the transfer deadline."),
     898             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     899             :   },
     900             :   {
     901             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED,
     902             :     .hint = gettext_noop ("The payment is too late, the offer has expired."),
     903             :     .http_code = MHD_HTTP_GONE
     904             :   },
     905             :   {
     906             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING,
     907             :     .hint = gettext_noop ("The \"merchant\" field is missing in the proposal data. This is an internal error as the proposal is from the merchant's own database at this point."),
     908             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     909             :   },
     910             :   {
     911             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN,
     912             :     .hint = gettext_noop ("Failed to locate merchant's account information matching the wire hash given in the proposal."),
     913             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     914             :   },
     915             :   {
     916             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED,
     917             :     .hint = gettext_noop ("The deposit time for the denomination has expired."),
     918             :     .http_code = MHD_HTTP_GONE
     919             :   },
     920             :   {
     921             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
     922             :     .hint = gettext_noop ("The exchange of the deposited coin charges a wire fee that could not be added to the total (total amount too high)."),
     923             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     924             :   },
     925             :   {
     926             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUNDED,
     927             :     .hint = gettext_noop ("The contract was not fully paid because of refunds. Note that clients MAY treat this as paid if, for example, contracts must be executed despite of refunds."),
     928             :     .http_code = MHD_HTTP_PAYMENT_REQUIRED
     929             :   },
     930             :   {
     931             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUNDS_EXCEED_PAYMENTS,
     932             :     .hint = gettext_noop ("According to our database, we have refunded more than we were paid (which should not be possible)."),
     933             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     934             :   },
     935             :   {
     936             :     .ec = TALER_EC_DEAD_QQQ_PAY_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE,
     937             :     .hint = gettext_noop ("Legacy stuff. Remove me with protocol v1."),
     938             :     .http_code = MHD_HTTP_UNINITIALIZED
     939             :   },
     940             :   {
     941             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_FAILED,
     942             :     .hint = gettext_noop ("The payment failed at the exchange."),
     943             :     .http_code = MHD_HTTP_BAD_GATEWAY
     944             :   },
     945             :   {
     946             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH,
     947             :     .hint = gettext_noop ("The contract hash does not match the given order ID."),
     948             :     .http_code = MHD_HTTP_BAD_REQUEST
     949             :   },
     950             :   {
     951             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID,
     952             :     .hint = gettext_noop ("The signature of the merchant is not valid for the given contract hash."),
     953             :     .http_code = MHD_HTTP_FORBIDDEN
     954             :   },
     955             :   {
     956             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED,
     957             :     .hint = gettext_noop ("The merchant failed to send the exchange the refund request."),
     958             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     959             :   },
     960             :   {
     961             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED,
     962             :     .hint = gettext_noop ("The merchant failed to find the exchange to process the lookup."),
     963             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
     964             :   },
     965             :   {
     966             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND,
     967             :     .hint = gettext_noop ("The merchant could not find the contract."),
     968             :     .http_code = MHD_HTTP_NOT_FOUND
     969             :   },
     970             :   {
     971             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE,
     972             :     .hint = gettext_noop ("The payment was already completed and thus cannot be aborted anymore."),
     973             :     .http_code = MHD_HTTP_PRECONDITION_FAILED
     974             :   },
     975             :   {
     976             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH,
     977             :     .hint = gettext_noop ("The hash provided by the wallet does not match the order."),
     978             :     .http_code = MHD_HTTP_FORBIDDEN
     979             :   },
     980             :   {
     981             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY,
     982             :     .hint = gettext_noop ("The array of coins cannot be empty."),
     983             :     .http_code = MHD_HTTP_BAD_REQUEST
     984             :   },
     985             :   {
     986             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND,
     987             :     .hint = gettext_noop ("We could not claim the order because the backend is unaware of it."),
     988             :     .http_code = MHD_HTTP_NOT_FOUND
     989             :   },
     990             :   {
     991             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED,
     992             :     .hint = gettext_noop ("We could not claim the order because someone else claimed it first."),
     993             :     .http_code = MHD_HTTP_CONFLICT
     994             :   },
     995             :   {
     996             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE,
     997             :     .hint = gettext_noop ("The client-side experienced an internal failure."),
     998             :     .http_code = MHD_HTTP_UNINITIALIZED
     999             :   },
    1000             :   {
    1001             :     .ec = TALER_EC_MERCHANT_POST_ORDERS_ID_REFUND_SIGNATURE_FAILED,
    1002             :     .hint = gettext_noop ("The backend failed to sign the refund request."),
    1003             :     .http_code = MHD_HTTP_UNINITIALIZED
    1004             :   },
    1005             :   {
    1006             :     .ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE,
    1007             :     .hint = gettext_noop ("The client failed to unblind the signature returned by the merchant."),
    1008             :     .http_code = MHD_HTTP_UNINITIALIZED
    1009             :   },
    1010             :   {
    1011             :     .ec = TALER_EC_MERCHANT_TIP_PICKUP_EXCHANGE_ERROR,
    1012             :     .hint = gettext_noop ("The exchange returned a failure code for the withdraw operation."),
    1013             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1014             :   },
    1015             :   {
    1016             :     .ec = TALER_EC_MERCHANT_TIP_PICKUP_SUMMATION_FAILED,
    1017             :     .hint = gettext_noop ("The merchant failed to add up the amounts to compute the pick up value."),
    1018             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1019             :   },
    1020             :   {
    1021             :     .ec = TALER_EC_MERCHANT_TIP_PICKUP_HAS_EXPIRED,
    1022             :     .hint = gettext_noop ("The tip expired."),
    1023             :     .http_code = MHD_HTTP_GONE
    1024             :   },
    1025             :   {
    1026             :     .ec = TALER_EC_MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING,
    1027             :     .hint = gettext_noop ("The requested withdraw amount exceeds the amount remaining to be picked up."),
    1028             :     .http_code = MHD_HTTP_BAD_REQUEST
    1029             :   },
    1030             :   {
    1031             :     .ec = TALER_EC_MERCHANT_TIP_PICKUP_DENOMINATION_UNKNOWN,
    1032             :     .hint = gettext_noop ("The merchant did not find the specified denomination key in the exchange's key set."),
    1033             :     .http_code = MHD_HTTP_CONFLICT
    1034             :   },
    1035             :   {
    1036             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_INSTANCE_CONFIGURATION_LACKS_WIRE,
    1037             :     .hint = gettext_noop ("The backend lacks a wire transfer method configuration option for the given instance. Thus, this instance is unavailable (not findable for creating new orders)."),
    1038             :     .http_code = MHD_HTTP_NOT_FOUND
    1039             :   },
    1040             :   {
    1041             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_NO_LOCALTIME,
    1042             :     .hint = gettext_noop ("The proposal had no timestamp and the backend failed to obtain the local time. Likely to be an internal error."),
    1043             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1044             :   },
    1045             :   {
    1046             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR,
    1047             :     .hint = gettext_noop ("The order provided to the backend could not be parsed, some required fields were missing or ill-formed."),
    1048             :     .http_code = MHD_HTTP_BAD_REQUEST
    1049             :   },
    1050             :   {
    1051             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS,
    1052             :     .hint = gettext_noop ("The backend encountered an error: the proposal already exists."),
    1053             :     .http_code = MHD_HTTP_CONFLICT
    1054             :   },
    1055             :   {
    1056             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_REFUND_AFTER_WIRE_DEADLINE,
    1057             :     .hint = gettext_noop ("The request is invalid: the wire deadline is before the refund deadline."),
    1058             :     .http_code = MHD_HTTP_BAD_REQUEST
    1059             :   },
    1060             :   {
    1061             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_DELIVERY_DATE_IN_PAST,
    1062             :     .hint = gettext_noop ("The request is invalid: a delivery date was given, but it is in the past."),
    1063             :     .http_code = MHD_HTTP_BAD_REQUEST
    1064             :   },
    1065             :   {
    1066             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_SYNTAX_INCORRECT,
    1067             :     .hint = gettext_noop ("One of the paths to forget is malformed."),
    1068             :     .http_code = MHD_HTTP_BAD_REQUEST
    1069             :   },
    1070             :   {
    1071             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_NOT_FORGETTABLE,
    1072             :     .hint = gettext_noop ("One of the paths to forget was not marked as forgettable."),
    1073             :     .http_code = MHD_HTTP_CONFLICT
    1074             :   },
    1075             :   {
    1076             :     .ec = TALER_EC_MERCHANT_PRIVATE_DELETE_ORDERS_AWAITING_PAYMENT,
    1077             :     .hint = gettext_noop ("The order provided to the backend could not be deleted, our offer is still valid and awaiting payment."),
    1078             :     .http_code = MHD_HTTP_CONFLICT
    1079             :   },
    1080             :   {
    1081             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_INCONSISTENT_AMOUNT,
    1082             :     .hint = gettext_noop ("The amount to be refunded is inconsistent: either is lower than the previous amount being awarded, or it is too big to be paid back. In this second case, the fault stays on the business dept. side."),
    1083             :     .http_code = MHD_HTTP_CONFLICT
    1084             :   },
    1085             :   {
    1086             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_ORDER_UNPAID,
    1087             :     .hint = gettext_noop ("The frontend gave an unpaid order id to issue the refund to."),
    1088             :     .http_code = MHD_HTTP_CONFLICT
    1089             :   },
    1090             :   {
    1091             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_NOT_ALLOWED_BY_CONTRACT,
    1092             :     .hint = gettext_noop ("The refund delay was set to 0 and thus no refunds are allowed for this order."),
    1093             :     .http_code = MHD_HTTP_FORBIDDEN
    1094             :   },
    1095             :   {
    1096             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_EXCHANGE_UNKNOWN,
    1097             :     .hint = gettext_noop ("The exchange says it does not know this transfer."),
    1098             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1099             :   },
    1100             :   {
    1101             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_REQUEST_ERROR,
    1102             :     .hint = gettext_noop ("We internally failed to execute the /track/transfer request."),
    1103             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1104             :   },
    1105             :   {
    1106             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_TRANSFERS,
    1107             :     .hint = gettext_noop ("The amount transferred differs between what was submitted and what the exchange claimed."),
    1108             :     .http_code = MHD_HTTP_CONFLICT
    1109             :   },
    1110             :   {
    1111             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS,
    1112             :     .hint = gettext_noop ("The exchange gave conflicting information about a coin which has been wire transferred."),
    1113             :     .http_code = MHD_HTTP_CONFLICT
    1114             :   },
    1115             :   {
    1116             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE,
    1117             :     .hint = gettext_noop ("The exchange charged a different wire fee than what it originally advertised, and it is higher."),
    1118             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1119             :   },
    1120             :   {
    1121             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND,
    1122             :     .hint = gettext_noop ("We did not find the account that the transfer was made to."),
    1123             :     .http_code = MHD_HTTP_NOT_FOUND
    1124             :   },
    1125             :   {
    1126             :     .ec = TALER_EC_MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED,
    1127             :     .hint = gettext_noop ("The backend could not delete the transfer as the echange already replied to our inquiry about it and we have integrated the result."),
    1128             :     .http_code = MHD_HTTP_CONFLICT
    1129             :   },
    1130             :   {
    1131             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION,
    1132             :     .hint = gettext_noop ("The backend was previously informed about a wire transfer with the same ID but a different amount. Multiple wire transfers with the same ID are not allowed. If the new amount is correct, the old transfer should first be deleted."),
    1133             :     .http_code = MHD_HTTP_CONFLICT
    1134             :   },
    1135             :   {
    1136             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS,
    1137             :     .hint = gettext_noop ("The merchant backend cannot create an instance under the given identifier as one already exists. Use PATCH to modify the existing entry."),
    1138             :     .http_code = MHD_HTTP_CONFLICT
    1139             :   },
    1140             :   {
    1141             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH,
    1142             :     .hint = gettext_noop ("The merchant backend cannot create an instance because the authentication configuration field is malformed."),
    1143             :     .http_code = MHD_HTTP_BAD_REQUEST
    1144             :   },
    1145             :   {
    1146             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH,
    1147             :     .hint = gettext_noop ("The merchant backend cannot update an instance's authentication settings because the provided authentication settings are malformed."),
    1148             :     .http_code = MHD_HTTP_BAD_REQUEST
    1149             :   },
    1150             :   {
    1151             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_PURGE_REQUIRED,
    1152             :     .hint = gettext_noop ("The merchant backend cannot create an instance under the given identifier, the previous one was deleted but must be purged first."),
    1153             :     .http_code = MHD_HTTP_CONFLICT
    1154             :   },
    1155             :   {
    1156             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_INSTANCES_PURGE_REQUIRED,
    1157             :     .hint = gettext_noop ("The merchant backend cannot update an instance under the given identifier, the previous one was deleted but must be purged first."),
    1158             :     .http_code = MHD_HTTP_CONFLICT
    1159             :   },
    1160             :   {
    1161             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS,
    1162             :     .hint = gettext_noop ("The product ID exists."),
    1163             :     .http_code = MHD_HTTP_CONFLICT
    1164             :   },
    1165             :   {
    1166             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_REDUCED,
    1167             :     .hint = gettext_noop ("The update would have reduced the total amount of product lost, which is not allowed."),
    1168             :     .http_code = MHD_HTTP_CONFLICT
    1169             :   },
    1170             :   {
    1171             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS,
    1172             :     .hint = gettext_noop ("The update would have mean that more stocks were lost than what remains from total inventory after sales, which is not allowed."),
    1173             :     .http_code = MHD_HTTP_BAD_REQUEST
    1174             :   },
    1175             :   {
    1176             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_STOCKED_REDUCED,
    1177             :     .hint = gettext_noop ("The update would have reduced the total amount of product in stock, which is not allowed."),
    1178             :     .http_code = MHD_HTTP_CONFLICT
    1179             :   },
    1180             :   {
    1181             :     .ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_SOLD_REDUCED,
    1182             :     .hint = gettext_noop ("The update would have reduced the total amount of product sold, which is not allowed."),
    1183             :     .http_code = MHD_HTTP_CONFLICT
    1184             :   },
    1185             :   {
    1186             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_PRODUCTS_LOCK_INSUFFICIENT_STOCKS,
    1187             :     .hint = gettext_noop ("The lock request is for more products than we have left (unlocked) in stock."),
    1188             :     .http_code = MHD_HTTP_GONE
    1189             :   },
    1190             :   {
    1191             :     .ec = TALER_EC_MERCHANT_PRIVATE_DELETE_PRODUCTS_CONFLICTING_LOCK,
    1192             :     .hint = gettext_noop ("The deletion request is for a product that is locked."),
    1193             :     .http_code = MHD_HTTP_CONFLICT
    1194             :   },
    1195             :   {
    1196             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD,
    1197             :     .hint = gettext_noop ("The requested wire method is not supported by the exchange."),
    1198             :     .http_code = MHD_HTTP_CONFLICT
    1199             :   },
    1200             :   {
    1201             :     .ec = TALER_EC_MERCHANT_PRIVATE_DELETE_RESERVES_NO_SUCH_RESERVE,
    1202             :     .hint = gettext_noop ("The reserve could not be deleted because it is unknown."),
    1203             :     .http_code = MHD_HTTP_NOT_FOUND
    1204             :   },
    1205             :   {
    1206             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_EXPIRED,
    1207             :     .hint = gettext_noop ("The reserve that was used to fund the tips has expired."),
    1208             :     .http_code = MHD_HTTP_GONE
    1209             :   },
    1210             :   {
    1211             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_UNKNOWN,
    1212             :     .hint = gettext_noop ("The reserve that was used to fund the tips was not found in the DB."),
    1213             :     .http_code = MHD_HTTP_SERVICE_UNAVAILABLE
    1214             :   },
    1215             :   {
    1216             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_INSUFFICIENT_FUNDS,
    1217             :     .hint = gettext_noop ("The backend knows the instance that was supposed to support the tip, and it was configured for tipping. However, the funds remaining are insufficient to cover the tip, and the merchant should top up the reserve."),
    1218             :     .http_code = MHD_HTTP_UNINITIALIZED
    1219             :   },
    1220             :   {
    1221             :     .ec = TALER_EC_MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_NOT_FOUND,
    1222             :     .hint = gettext_noop ("The backend failed to find a reserve needed to authorize the tip."),
    1223             :     .http_code = MHD_HTTP_SERVICE_UNAVAILABLE
    1224             :   },
    1225             :   {
    1226             :     .ec = TALER_EC_MERCHANT_PRIVATE_GET_ORDERS_ID_AMOUNT_ARITHMETIC_FAILURE,
    1227             :     .hint = gettext_noop ("The merchant backend encountered a failure in computing the deposit total."),
    1228             :     .http_code = MHD_HTTP_OK
    1229             :   },
    1230             :   {
    1231             :     .ec = TALER_EC_AUDITOR_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
    1232             :     .hint = gettext_noop ("The signature from the exchange on the deposit confirmation is invalid."),
    1233             :     .http_code = MHD_HTTP_FORBIDDEN
    1234             :   },
    1235             :   {
    1236             :     .ec = TALER_EC_AUDITOR_EXCHANGE_SIGNING_KEY_REVOKED,
    1237             :     .hint = gettext_noop ("The exchange key used for the signature on the deposit confirmation was revoked."),
    1238             :     .http_code = MHD_HTTP_GONE
    1239             :   },
    1240             :   {
    1241             :     .ec = TALER_EC_BANK_SAME_ACCOUNT,
    1242             :     .hint = gettext_noop ("Wire transfer attempted with credit and debit party being the same bank account."),
    1243             :     .http_code = MHD_HTTP_UNINITIALIZED
    1244             :   },
    1245             :   {
    1246             :     .ec = TALER_EC_BANK_UNALLOWED_DEBIT,
    1247             :     .hint = gettext_noop ("Wire transfer impossible, due to financial limitation of the party that attempted the payment."),
    1248             :     .http_code = MHD_HTTP_UNINITIALIZED
    1249             :   },
    1250             :   {
    1251             :     .ec = TALER_EC_BANK_NEGATIVE_NUMBER_AMOUNT,
    1252             :     .hint = gettext_noop ("Negative number was used (as value and/or fraction) to initiate a Amount object."),
    1253             :     .http_code = MHD_HTTP_UNINITIALIZED
    1254             :   },
    1255             :   {
    1256             :     .ec = TALER_EC_BANK_NUMBER_TOO_BIG,
    1257             :     .hint = gettext_noop ("A number too big was used (as value and/or fraction) to initiate a amount object."),
    1258             :     .http_code = MHD_HTTP_UNINITIALIZED
    1259             :   },
    1260             :   {
    1261             :     .ec = TALER_EC_BANK_LOGIN_FAILED,
    1262             :     .hint = gettext_noop ("Could not login for the requested operation."),
    1263             :     .http_code = MHD_HTTP_UNINITIALIZED
    1264             :   },
    1265             :   {
    1266             :     .ec = TALER_EC_BANK_UNKNOWN_ACCOUNT,
    1267             :     .hint = gettext_noop ("The bank account referenced in the requested operation was not found. Returned along \"400 Not found\"."),
    1268             :     .http_code = MHD_HTTP_UNINITIALIZED
    1269             :   },
    1270             :   {
    1271             :     .ec = TALER_EC_BANK_TRANSACTION_NOT_FOUND,
    1272             :     .hint = gettext_noop ("The transaction referenced in the requested operation (typically a reject operation), was not found."),
    1273             :     .http_code = MHD_HTTP_UNINITIALIZED
    1274             :   },
    1275             :   {
    1276             :     .ec = TALER_EC_BANK_BAD_FORMAT_AMOUNT,
    1277             :     .hint = gettext_noop ("Bank received a malformed amount string."),
    1278             :     .http_code = MHD_HTTP_UNINITIALIZED
    1279             :   },
    1280             :   {
    1281             :     .ec = TALER_EC_BANK_REJECT_NO_RIGHTS,
    1282             :     .hint = gettext_noop ("The client does not own the account credited by the transaction which is to be rejected, so it has no rights do reject it.  To be returned along HTTP 403 Forbidden."),
    1283             :     .http_code = MHD_HTTP_UNINITIALIZED
    1284             :   },
    1285             :   {
    1286             :     .ec = TALER_EC_BANK_UNMANAGED_EXCEPTION,
    1287             :     .hint = gettext_noop ("This error code is returned when no known exception types captured the exception, and comes along with a 500 Internal Server Error."),
    1288             :     .http_code = MHD_HTTP_UNINITIALIZED
    1289             :   },
    1290             :   {
    1291             :     .ec = TALER_EC_BANK_SOFT_EXCEPTION,
    1292             :     .hint = gettext_noop ("This error code is used for all those exceptions that do not really need a specific error code to return to the client, but need to signal the middleware that the bank is not responding with 500 Internal Server Error.  Used for example when a client is trying to register with a unavailable username."),
    1293             :     .http_code = MHD_HTTP_UNINITIALIZED
    1294             :   },
    1295             :   {
    1296             :     .ec = TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED,
    1297             :     .hint = gettext_noop ("The request UID for a request to transfer funds has already been used, but with different details for the transfer."),
    1298             :     .http_code = MHD_HTTP_CONFLICT
    1299             :   },
    1300             :   {
    1301             :     .ec = TALER_EC_BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT,
    1302             :     .hint = gettext_noop ("The withdrawal operation already has a reserve selected.  The current request conflicts with the existing selection."),
    1303             :     .http_code = MHD_HTTP_CONFLICT
    1304             :   },
    1305             :   {
    1306             :     .ec = TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT,
    1307             :     .hint = gettext_noop ("The wire transfer subject duplicates an existing reserve public key. But wire transfer subjects must be unique."),
    1308             :     .http_code = MHD_HTTP_CONFLICT
    1309             :   },
    1310             :   {
    1311             :     .ec = TALER_EC_SYNC_ACCOUNT_UNKNOWN,
    1312             :     .hint = gettext_noop ("The sync service failed find the account in its database."),
    1313             :     .http_code = MHD_HTTP_NOT_FOUND
    1314             :   },
    1315             :   {
    1316             :     .ec = TALER_EC_SYNC_BAD_IF_NONE_MATCH,
    1317             :     .hint = gettext_noop ("The SHA-512 hash provided in the If-None-Match header is malformed."),
    1318             :     .http_code = MHD_HTTP_BAD_REQUEST
    1319             :   },
    1320             :   {
    1321             :     .ec = TALER_EC_SYNC_BAD_IF_MATCH,
    1322             :     .hint = gettext_noop ("The SHA-512 hash provided in the If-Match header is malformed or missing."),
    1323             :     .http_code = MHD_HTTP_BAD_REQUEST
    1324             :   },
    1325             :   {
    1326             :     .ec = TALER_EC_SYNC_BAD_SYNC_SIGNATURE,
    1327             :     .hint = gettext_noop ("The signature provided in the \"Sync-Signature\" header is malformed or missing."),
    1328             :     .http_code = MHD_HTTP_BAD_REQUEST
    1329             :   },
    1330             :   {
    1331             :     .ec = TALER_EC_SYNC_INVALID_SIGNATURE,
    1332             :     .hint = gettext_noop ("The signature provided in the \"Sync-Signature\" header does not match the account, old or new Etags."),
    1333             :     .http_code = MHD_HTTP_FORBIDDEN
    1334             :   },
    1335             :   {
    1336             :     .ec = TALER_EC_SYNC_MALFORMED_CONTENT_LENGTH,
    1337             :     .hint = gettext_noop ("The \"Content-length\" field for the upload is not a number."),
    1338             :     .http_code = MHD_HTTP_BAD_REQUEST
    1339             :   },
    1340             :   {
    1341             :     .ec = TALER_EC_SYNC_EXCESSIVE_CONTENT_LENGTH,
    1342             :     .hint = gettext_noop ("The \"Content-length\" field for the upload is too big based on the server's terms of service."),
    1343             :     .http_code = MHD_HTTP_PAYLOAD_TOO_LARGE
    1344             :   },
    1345             :   {
    1346             :     .ec = TALER_EC_SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH,
    1347             :     .hint = gettext_noop ("The server is out of memory to handle the upload. Trying again later may succeed."),
    1348             :     .http_code = MHD_HTTP_PAYLOAD_TOO_LARGE
    1349             :   },
    1350             :   {
    1351             :     .ec = TALER_EC_SYNC_INVALID_UPLOAD,
    1352             :     .hint = gettext_noop ("The uploaded data does not match the Etag."),
    1353             :     .http_code = MHD_HTTP_BAD_REQUEST
    1354             :   },
    1355             :   {
    1356             :     .ec = TALER_EC_SYNC_PAYMENT_GENERIC_TIMEOUT,
    1357             :     .hint = gettext_noop ("HTTP server experienced a timeout while awaiting promised payment."),
    1358             :     .http_code = MHD_HTTP_REQUEST_TIMEOUT
    1359             :   },
    1360             :   {
    1361             :     .ec = TALER_EC_SYNC_PAYMENT_CREATE_BACKEND_ERROR,
    1362             :     .hint = gettext_noop ("Sync could not setup the payment request with its own backend."),
    1363             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1364             :   },
    1365             :   {
    1366             :     .ec = TALER_EC_SYNC_PREVIOUS_BACKUP_UNKNOWN,
    1367             :     .hint = gettext_noop ("The sync service failed find the backup to be updated in its database."),
    1368             :     .http_code = MHD_HTTP_NOT_FOUND
    1369             :   },
    1370             :   {
    1371             :     .ec = TALER_EC_SYNC_MISSING_CONTENT_LENGTH,
    1372             :     .hint = gettext_noop ("The \"Content-length\" field for the upload is missing."),
    1373             :     .http_code = MHD_HTTP_BAD_REQUEST
    1374             :   },
    1375             :   {
    1376             :     .ec = TALER_EC_WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE,
    1377             :     .hint = gettext_noop ("The wallet does not implement a version of the exchange protocol that is compatible with the protocol version of the exchange."),
    1378             :     .http_code = MHD_HTTP_NOT_IMPLEMENTED
    1379             :   },
    1380             :   {
    1381             :     .ec = TALER_EC_WALLET_UNEXPECTED_EXCEPTION,
    1382             :     .hint = gettext_noop ("The wallet encountered an unexpected exception.  This is likely a bug in the wallet implementation."),
    1383             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1384             :   },
    1385             :   {
    1386             :     .ec = TALER_EC_WALLET_RECEIVED_MALFORMED_RESPONSE,
    1387             :     .hint = gettext_noop ("The wallet received a response from a server, but the response can't be parsed."),
    1388             :     .http_code = MHD_HTTP_UNINITIALIZED
    1389             :   },
    1390             :   {
    1391             :     .ec = TALER_EC_WALLET_NETWORK_ERROR,
    1392             :     .hint = gettext_noop ("The wallet tried to make a network request, but it received no response."),
    1393             :     .http_code = MHD_HTTP_UNINITIALIZED
    1394             :   },
    1395             :   {
    1396             :     .ec = TALER_EC_WALLET_HTTP_REQUEST_THROTTLED,
    1397             :     .hint = gettext_noop ("The wallet tried to make a network request, but it was throttled."),
    1398             :     .http_code = MHD_HTTP_UNINITIALIZED
    1399             :   },
    1400             :   {
    1401             :     .ec = TALER_EC_WALLET_UNEXPECTED_REQUEST_ERROR,
    1402             :     .hint = gettext_noop ("The wallet made a request to a service, but received an error response it does not know how to handle."),
    1403             :     .http_code = MHD_HTTP_UNINITIALIZED
    1404             :   },
    1405             :   {
    1406             :     .ec = TALER_EC_WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT,
    1407             :     .hint = gettext_noop ("The denominations offered by the exchange are insufficient.  Likely the exchange is badly configured or not maintained."),
    1408             :     .http_code = MHD_HTTP_UNINITIALIZED
    1409             :   },
    1410             :   {
    1411             :     .ec = TALER_EC_WALLET_CORE_API_OPERATION_UNKNOWN,
    1412             :     .hint = gettext_noop ("The wallet does not support the operation requested by a client."),
    1413             :     .http_code = MHD_HTTP_UNINITIALIZED
    1414             :   },
    1415             :   {
    1416             :     .ec = TALER_EC_WALLET_INVALID_TALER_PAY_URI,
    1417             :     .hint = gettext_noop ("The given taler://pay URI is invalid."),
    1418             :     .http_code = MHD_HTTP_UNINITIALIZED
    1419             :   },
    1420             :   {
    1421             :     .ec = TALER_EC_WALLET_EXCHANGE_COIN_SIGNATURE_INVALID,
    1422             :     .hint = gettext_noop ("The signature on a coin by the exchange's denomination key is invalid after unblinding it."),
    1423             :     .http_code = MHD_HTTP_UNINITIALIZED
    1424             :   },
    1425             :   {
    1426             :     .ec = TALER_EC_WALLET_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN_AT_EXCHANGE,
    1427             :     .hint = gettext_noop ("The exchange does not know about the reserve (yet), and thus withdrawal can't progress."),
    1428             :     .http_code = MHD_HTTP_NOT_FOUND
    1429             :   },
    1430             :   {
    1431             :     .ec = TALER_EC_WALLET_CORE_NOT_AVAILABLE,
    1432             :     .hint = gettext_noop ("The wallet core service is not available."),
    1433             :     .http_code = MHD_HTTP_UNINITIALIZED
    1434             :   },
    1435             :   {
    1436             :     .ec = TALER_EC_WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
    1437             :     .hint = gettext_noop ("The bank has aborted a withdrawal operation, and thus a withdrawal can't complete."),
    1438             :     .http_code = MHD_HTTP_UNINITIALIZED
    1439             :   },
    1440             :   {
    1441             :     .ec = TALER_EC_WALLET_HTTP_REQUEST_GENERIC_TIMEOUT,
    1442             :     .hint = gettext_noop ("An HTTP request made by the wallet timed out."),
    1443             :     .http_code = MHD_HTTP_UNINITIALIZED
    1444             :   },
    1445             :   {
    1446             :     .ec = TALER_EC_WALLET_ORDER_ALREADY_CLAIMED,
    1447             :     .hint = gettext_noop ("The order has already been claimed by another wallet."),
    1448             :     .http_code = MHD_HTTP_UNINITIALIZED
    1449             :   },
    1450             :   {
    1451             :     .ec = TALER_EC_WALLET_WITHDRAWAL_GROUP_INCOMPLETE,
    1452             :     .hint = gettext_noop ("A group of withdrawal operations (typically for the same reserve at the same exchange) has errors and will be tried again later."),
    1453             :     .http_code = MHD_HTTP_UNINITIALIZED
    1454             :   },
    1455             :   {
    1456             :     .ec = TALER_EC_WALLET_TIPPING_COIN_SIGNATURE_INVALID,
    1457             :     .hint = gettext_noop ("The signature on a coin by the exchange's denomination key (obtained through the merchant via tipping) is invalid after unblinding it."),
    1458             :     .http_code = MHD_HTTP_UNINITIALIZED
    1459             :   },
    1460             :   {
    1461             :     .ec = TALER_EC_WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE,
    1462             :     .hint = gettext_noop ("The wallet does not implement a version of the bank integration API that is compatible with the version offered by the bank."),
    1463             :     .http_code = MHD_HTTP_UNINITIALIZED
    1464             :   },
    1465             :   {
    1466             :     .ec = TALER_EC_WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH,
    1467             :     .hint = gettext_noop ("The wallet processed a taler://pay URI, but the merchant base URL in the downloaded contract terms does not match the merchant base URL derived from the URI."),
    1468             :     .http_code = MHD_HTTP_UNINITIALIZED
    1469             :   },
    1470             :   {
    1471             :     .ec = TALER_EC_WALLET_CONTRACT_TERMS_SIGNATURE_INVALID,
    1472             :     .hint = gettext_noop ("The merchant's signature on the contract terms is invalid."),
    1473             :     .http_code = MHD_HTTP_UNINITIALIZED
    1474             :   },
    1475             :   {
    1476             :     .ec = TALER_EC_WALLET_CONTRACT_TERMS_MALFORMED,
    1477             :     .hint = gettext_noop ("The contract terms given by the merchant are malformed."),
    1478             :     .http_code = MHD_HTTP_UNINITIALIZED
    1479             :   },
    1480             :   {
    1481             :     .ec = TALER_EC_ANASTASIS_GENERIC_BACKEND_TIMEOUT,
    1482             :     .hint = gettext_noop ("We encountered a timeout with our payment backend."),
    1483             :     .http_code = MHD_HTTP_GATEWAY_TIMEOUT
    1484             :   },
    1485             :   {
    1486             :     .ec = TALER_EC_ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST,
    1487             :     .hint = gettext_noop ("The backend requested payment, but the request is malformed."),
    1488             :     .http_code = MHD_HTTP_UNINITIALIZED
    1489             :   },
    1490             :   {
    1491             :     .ec = TALER_EC_ANASTASIS_GENERIC_BACKEND_ERROR,
    1492             :     .hint = gettext_noop ("The backend got an unexpected reply from the payment processor."),
    1493             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1494             :   },
    1495             :   {
    1496             :     .ec = TALER_EC_ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH,
    1497             :     .hint = gettext_noop ("The \"Content-length\" field for the upload is missing."),
    1498             :     .http_code = MHD_HTTP_BAD_REQUEST
    1499             :   },
    1500             :   {
    1501             :     .ec = TALER_EC_ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH,
    1502             :     .hint = gettext_noop ("The \"Content-length\" field for the upload is malformed."),
    1503             :     .http_code = MHD_HTTP_BAD_REQUEST
    1504             :   },
    1505             :   {
    1506             :     .ec = TALER_EC_ANASTASIS_GENERIC_ORDER_CREATE_BACKEND_ERROR,
    1507             :     .hint = gettext_noop ("The backend failed to setup an order with the payment processor."),
    1508             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1509             :   },
    1510             :   {
    1511             :     .ec = TALER_EC_ANASTASIS_GENERIC_PAYMENT_CHECK_UNAUTHORIZED,
    1512             :     .hint = gettext_noop ("The backend was not authorized to check for payment with the payment processor."),
    1513             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1514             :   },
    1515             :   {
    1516             :     .ec = TALER_EC_ANASTASIS_GENERIC_PAYMENT_CHECK_START_FAILED,
    1517             :     .hint = gettext_noop ("The backend could not check payment status with the payment processor."),
    1518             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1519             :   },
    1520             :   {
    1521             :     .ec = TALER_EC_ANASTASIS_TRUTH_UNKNOWN,
    1522             :     .hint = gettext_noop ("The truth public key is unknown to the provider."),
    1523             :     .http_code = MHD_HTTP_NOT_FOUND
    1524             :   },
    1525             :   {
    1526             :     .ec = TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_METHOD_NO_LONGER_SUPPORTED,
    1527             :     .hint = gettext_noop ("The authorization method used by the truth is no longer supported by the provider."),
    1528             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1529             :   },
    1530             :   {
    1531             :     .ec = TALER_EC_ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED,
    1532             :     .hint = gettext_noop ("The client needs to respond to the challenge."),
    1533             :     .http_code = MHD_HTTP_FORBIDDEN
    1534             :   },
    1535             :   {
    1536             :     .ec = TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED,
    1537             :     .hint = gettext_noop ("The client's response to the challenge was invalid."),
    1538             :     .http_code = MHD_HTTP_FORBIDDEN
    1539             :   },
    1540             :   {
    1541             :     .ec = TALER_EC_ANASTASIS_TRUTH_CHALLENGE_UNKNOWN,
    1542             :     .hint = gettext_noop ("The service is unaware of having issued a challenge."),
    1543             :     .http_code = MHD_HTTP_GONE
    1544             :   },
    1545             :   {
    1546             :     .ec = TALER_EC_ANASTASIS_TRUTH_CHALLENGE_ACTIVE,
    1547             :     .hint = gettext_noop ("A challenge is already active, the service is thus not issuing a new one."),
    1548             :     .http_code = MHD_HTTP_ALREADY_REPORTED
    1549             :   },
    1550             :   {
    1551             :     .ec = TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED,
    1552             :     .hint = gettext_noop ("The backend failed to initiate the authorization process."),
    1553             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1554             :   },
    1555             :   {
    1556             :     .ec = TALER_EC_ANASTASIS_TRUTH_KEY_SHARE_GONE,
    1557             :     .hint = gettext_noop ("The authorization succeeded, but the key share is no longer available."),
    1558             :     .http_code = MHD_HTTP_NOT_FOUND
    1559             :   },
    1560             :   {
    1561             :     .ec = TALER_EC_ANASTASIS_TRUTH_ORDER_DISAPPEARED,
    1562             :     .hint = gettext_noop ("The backend forgot the order we asked the client to pay for"),
    1563             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1564             :   },
    1565             :   {
    1566             :     .ec = TALER_EC_ANASTASIS_TRUTH_BACKEND_EXCHANGE_BAD,
    1567             :     .hint = gettext_noop ("The backend itself reported a bad exchange interaction."),
    1568             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1569             :   },
    1570             :   {
    1571             :     .ec = TALER_EC_ANASTASIS_TRUTH_UNEXPECTED_PAYMENT_STATUS,
    1572             :     .hint = gettext_noop ("The backend reported a payment status we did not expect."),
    1573             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1574             :   },
    1575             :   {
    1576             :     .ec = TALER_EC_ANASTASIS_TRUTH_PAYMENT_CREATE_BACKEND_ERROR,
    1577             :     .hint = gettext_noop ("The backend failed to setup the order for payment."),
    1578             :     .http_code = MHD_HTTP_BAD_GATEWAY
    1579             :   },
    1580             :   {
    1581             :     .ec = TALER_EC_ANASTASIS_TRUTH_DECRYPTION_FAILED,
    1582             :     .hint = gettext_noop ("The decryption of the truth object failed with the provided key."),
    1583             :     .http_code = MHD_HTTP_EXPECTATION_FAILED
    1584             :   },
    1585             :   {
    1586             :     .ec = TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED,
    1587             :     .hint = gettext_noop ("The request rate is too high. The server is refusing requests to guard against brute-force attacks."),
    1588             :     .http_code = MHD_HTTP_TOO_MANY_REQUESTS
    1589             :   },
    1590             :   {
    1591             :     .ec = TALER_EC_ANASTASIS_TRUTH_AUTH_TIMEOUT,
    1592             :     .hint = gettext_noop ("The authentication process did not yet complete. The user should try again later."),
    1593             :     .http_code = MHD_HTTP_REQUEST_TIMEOUT
    1594             :   },
    1595             :   {
    1596             :     .ec = TALER_EC_ANASTASIS_TRUTH_UPLOAD_UUID_EXISTS,
    1597             :     .hint = gettext_noop ("The backend failed to store the truth because the UUID is already in use."),
    1598             :     .http_code = MHD_HTTP_CONFLICT
    1599             :   },
    1600             :   {
    1601             :     .ec = TALER_EC_ANASTASIS_TRUTH_UPLOAD_METHOD_NOT_SUPPORTED,
    1602             :     .hint = gettext_noop ("The backend failed to store the truth because the authorization method is not supported."),
    1603             :     .http_code = MHD_HTTP_BAD_REQUEST
    1604             :   },
    1605             :   {
    1606             :     .ec = TALER_EC_ANASTASIS_SMS_PHONE_INVALID,
    1607             :     .hint = gettext_noop ("The provided phone number is not an acceptable number."),
    1608             :     .http_code = MHD_HTTP_EXPECTATION_FAILED
    1609             :   },
    1610             :   {
    1611             :     .ec = TALER_EC_ANASTASIS_SMS_HELPER_EXEC_FAILED,
    1612             :     .hint = gettext_noop ("Failed to run the SMS transmission helper process."),
    1613             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1614             :   },
    1615             :   {
    1616             :     .ec = TALER_EC_ANASTASIS_SMS_HELPER_COMMAND_FAILED,
    1617             :     .hint = gettext_noop ("Helper terminated with a non-successful result."),
    1618             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1619             :   },
    1620             :   {
    1621             :     .ec = TALER_EC_ANASTASIS_EMAIL_INVALID,
    1622             :     .hint = gettext_noop ("The provided email address is not an acceptable address."),
    1623             :     .http_code = MHD_HTTP_EXPECTATION_FAILED
    1624             :   },
    1625             :   {
    1626             :     .ec = TALER_EC_ANASTASIS_EMAIL_HELPER_EXEC_FAILED,
    1627             :     .hint = gettext_noop ("Failed to run the E-mail transmission helper process."),
    1628             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1629             :   },
    1630             :   {
    1631             :     .ec = TALER_EC_ANASTASIS_EMAIL_HELPER_COMMAND_FAILED,
    1632             :     .hint = gettext_noop ("Helper terminated with a non-successful result."),
    1633             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1634             :   },
    1635             :   {
    1636             :     .ec = TALER_EC_ANASTASIS_POST_INVALID,
    1637             :     .hint = gettext_noop ("The provided postal address is not an acceptable address."),
    1638             :     .http_code = MHD_HTTP_EXPECTATION_FAILED
    1639             :   },
    1640             :   {
    1641             :     .ec = TALER_EC_ANASTASIS_POST_HELPER_EXEC_FAILED,
    1642             :     .hint = gettext_noop ("Failed to run the mail transmission helper process."),
    1643             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1644             :   },
    1645             :   {
    1646             :     .ec = TALER_EC_ANASTASIS_POST_HELPER_COMMAND_FAILED,
    1647             :     .hint = gettext_noop ("Helper terminated with a non-successful result."),
    1648             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1649             :   },
    1650             :   {
    1651             :     .ec = TALER_EC_ANASTASIS_IBAN_INVALID,
    1652             :     .hint = gettext_noop ("The provided IBAN address is not an acceptable IBAN."),
    1653             :     .http_code = MHD_HTTP_EXPECTATION_FAILED
    1654             :   },
    1655             :   {
    1656             :     .ec = TALER_EC_ANASTASIS_POLICY_BAD_IF_NONE_MATCH,
    1657             :     .hint = gettext_noop ("The given if-none-match header is malformed."),
    1658             :     .http_code = MHD_HTTP_BAD_REQUEST
    1659             :   },
    1660             :   {
    1661             :     .ec = TALER_EC_ANASTASIS_POLICY_OUT_OF_MEMORY_ON_CONTENT_LENGTH,
    1662             :     .hint = gettext_noop ("The server is out of memory to handle the upload. Trying again later may succeed."),
    1663             :     .http_code = MHD_HTTP_PAYLOAD_TOO_LARGE
    1664             :   },
    1665             :   {
    1666             :     .ec = TALER_EC_ANASTASIS_POLICY_BAD_SIGNATURE,
    1667             :     .hint = gettext_noop ("The signature provided in the \"Anastasis-Policy-Signature\" header is malformed or missing."),
    1668             :     .http_code = MHD_HTTP_BAD_REQUEST
    1669             :   },
    1670             :   {
    1671             :     .ec = TALER_EC_ANASTASIS_POLICY_BAD_IF_MATCH,
    1672             :     .hint = gettext_noop ("The given if-match header is malformed."),
    1673             :     .http_code = MHD_HTTP_BAD_REQUEST
    1674             :   },
    1675             :   {
    1676             :     .ec = TALER_EC_ANASTASIS_POLICY_INVALID_UPLOAD,
    1677             :     .hint = gettext_noop ("The uploaded data does not match the Etag."),
    1678             :     .http_code = MHD_HTTP_BAD_REQUEST
    1679             :   },
    1680             :   {
    1681             :     .ec = TALER_EC_ANASTASIS_POLICY_NOT_FOUND,
    1682             :     .hint = gettext_noop ("The provider is unaware of the requested policy."),
    1683             :     .http_code = MHD_HTTP_NOT_FOUND
    1684             :   },
    1685             :   {
    1686             :     .ec = TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID,
    1687             :     .hint = gettext_noop ("The given action is invalid for the current state of the reducer."),
    1688             :     .http_code = MHD_HTTP_UNINITIALIZED
    1689             :   },
    1690             :   {
    1691             :     .ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
    1692             :     .hint = gettext_noop ("The given state of the reducer is invalid."),
    1693             :     .http_code = MHD_HTTP_UNINITIALIZED
    1694             :   },
    1695             :   {
    1696             :     .ec = TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
    1697             :     .hint = gettext_noop ("The given input to the reducer is invalid."),
    1698             :     .http_code = MHD_HTTP_UNINITIALIZED
    1699             :   },
    1700             :   {
    1701             :     .ec = TALER_EC_ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED,
    1702             :     .hint = gettext_noop ("The selected authentication method does not work for the Anastasis provider."),
    1703             :     .http_code = MHD_HTTP_UNINITIALIZED
    1704             :   },
    1705             :   {
    1706             :     .ec = TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
    1707             :     .hint = gettext_noop ("The given input and action do not work for the current state."),
    1708             :     .http_code = MHD_HTTP_UNINITIALIZED
    1709             :   },
    1710             :   {
    1711             :     .ec = TALER_EC_ANASTASIS_REDUCER_BACKEND_FAILURE,
    1712             :     .hint = gettext_noop ("We experienced an unexpected failure interacting with the backend."),
    1713             :     .http_code = MHD_HTTP_UNINITIALIZED
    1714             :   },
    1715             :   {
    1716             :     .ec = TALER_EC_ANASTASIS_REDUCER_RESOURCE_MALFORMED,
    1717             :     .hint = gettext_noop ("The contents of a resource file did not match our expectations."),
    1718             :     .http_code = MHD_HTTP_UNINITIALIZED
    1719             :   },
    1720             :   {
    1721             :     .ec = TALER_EC_ANASTASIS_REDUCER_RESOURCE_MISSING,
    1722             :     .hint = gettext_noop ("A required resource file is missing."),
    1723             :     .http_code = MHD_HTTP_UNINITIALIZED
    1724             :   },
    1725             :   {
    1726             :     .ec = TALER_EC_ANASTASIS_REDUCER_INPUT_REGEX_FAILED,
    1727             :     .hint = gettext_noop ("An input did not match the regular expression."),
    1728             :     .http_code = MHD_HTTP_UNINITIALIZED
    1729             :   },
    1730             :   {
    1731             :     .ec = TALER_EC_ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED,
    1732             :     .hint = gettext_noop ("An input did not match the custom validation logic."),
    1733             :     .http_code = MHD_HTTP_UNINITIALIZED
    1734             :   },
    1735             :   {
    1736             :     .ec = TALER_EC_ANASTASIS_REDUCER_POLICY_LOOKUP_FAILED,
    1737             :     .hint = gettext_noop ("Our attempts to download the recovery document failed with all providers."),
    1738             :     .http_code = MHD_HTTP_UNINITIALIZED
    1739             :   },
    1740             :   {
    1741             :     .ec = TALER_EC_ANASTASIS_REDUCER_BACKUP_PROVIDER_FAILED,
    1742             :     .hint = gettext_noop ("Anastasis provider reported a fatal failure."),
    1743             :     .http_code = MHD_HTTP_UNINITIALIZED
    1744             :   },
    1745             :   {
    1746             :     .ec = TALER_EC_ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED,
    1747             :     .hint = gettext_noop ("Anastasis provider failed to respond to the configuration request."),
    1748             :     .http_code = MHD_HTTP_UNINITIALIZED
    1749             :   },
    1750             :   {
    1751             :     .ec = TALER_EC_ANASTASIS_REDUCER_POLICY_MALFORMED,
    1752             :     .hint = gettext_noop ("The policy we downloaded is malformed. Must have been a client error while creating the backup."),
    1753             :     .http_code = MHD_HTTP_UNINITIALIZED
    1754             :   },
    1755             :   {
    1756             :     .ec = TALER_EC_ANASTASIS_REDUCER_NETWORK_FAILED,
    1757             :     .hint = gettext_noop ("We failed to obtain the policy, likely due to a network issue."),
    1758             :     .http_code = MHD_HTTP_UNINITIALIZED
    1759             :   },
    1760             :   {
    1761             :     .ec = TALER_EC_ANASTASIS_REDUCER_SECRET_MALFORMED,
    1762             :     .hint = gettext_noop ("The recovered secret did not match the required syntax."),
    1763             :     .http_code = MHD_HTTP_UNINITIALIZED
    1764             :   },
    1765             :   {
    1766             :     .ec = TALER_EC_ANASTASIS_REDUCER_CHALLENGE_DATA_TOO_BIG,
    1767             :     .hint = gettext_noop ("The challenge data provided is too large for the available providers."),
    1768             :     .http_code = MHD_HTTP_UNINITIALIZED
    1769             :   },
    1770             :   {
    1771             :     .ec = TALER_EC_ANASTASIS_REDUCER_SECRET_TOO_BIG,
    1772             :     .hint = gettext_noop ("The provided core secret is too large for some of the providers."),
    1773             :     .http_code = MHD_HTTP_UNINITIALIZED
    1774             :   },
    1775             :   {
    1776             :     .ec = TALER_EC_ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG,
    1777             :     .hint = gettext_noop ("The provider returned in invalid configuration."),
    1778             :     .http_code = MHD_HTTP_UNINITIALIZED
    1779             :   },
    1780             :   {
    1781             :     .ec = TALER_EC_LIBEUFIN_NEXUS_GENERIC_ERROR,
    1782             :     .hint = gettext_noop ("A generic error happened in the LibEuFin nexus.  See the enclose details JSON for more information."),
    1783             :     .http_code = MHD_HTTP_UNINITIALIZED
    1784             :   },
    1785             :   {
    1786             :     .ec = TALER_EC_LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION,
    1787             :     .hint = gettext_noop ("An uncaught exception happened in the LibEuFin nexus service."),
    1788             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1789             :   },
    1790             :   {
    1791             :     .ec = TALER_EC_LIBEUFIN_SANDBOX_GENERIC_ERROR,
    1792             :     .hint = gettext_noop ("A generic error happened in the LibEuFin sandbox.  See the enclose details JSON for more information."),
    1793             :     .http_code = MHD_HTTP_UNINITIALIZED
    1794             :   },
    1795             :   {
    1796             :     .ec = TALER_EC_LIBEUFIN_SANDBOX_UNCAUGHT_EXCEPTION,
    1797             :     .hint = gettext_noop ("An uncaught exception happened in the LibEuFin sandbox service."),
    1798             :     .http_code = MHD_HTTP_INTERNAL_SERVER_ERROR
    1799             :   },
    1800             :   {
    1801             :     .ec = TALER_EC_END,
    1802             :     .hint = gettext_noop ("End of error code range."),
    1803             :     .http_code = MHD_HTTP_UNINITIALIZED
    1804             :   },
    1805             : 
    1806             : };
    1807             : 
    1808             : 
    1809             : /**
    1810             :  * The length of @e code_hint_pairs.
    1811             :  */
    1812             : static const unsigned int code_hint_pairs_length = 349;
    1813             : 
    1814             : 
    1815             : const char *
    1816          71 : TALER_ErrorCode_get_hint (enum TALER_ErrorCode ec)
    1817             : {
    1818          71 :   unsigned int lower = 0;
    1819          71 :   unsigned int upper = code_hint_pairs_length - 1;
    1820          71 :   unsigned int mid = upper / 2;
    1821         566 :   while (lower <= upper)
    1822             :   {
    1823         566 :     mid = (upper + lower) / 2;
    1824         566 :     if (code_hint_pairs[mid].ec < ec)
    1825             :     {
    1826         221 :       lower = mid + 1;
    1827             :     }
    1828         345 :     else if (code_hint_pairs[mid].ec > ec)
    1829             :     {
    1830         274 :       upper = mid - 1;
    1831             :     }
    1832             :     else
    1833             :     {
    1834          71 :       return code_hint_pairs[mid].hint;
    1835             :     }
    1836             :   }
    1837           0 :   return "<no hint found>";
    1838             : }
    1839             : 
    1840             : 
    1841             : unsigned int
    1842           0 : TALER_ErrorCode_get_http_status (enum TALER_ErrorCode ec)
    1843             : {
    1844           0 :   unsigned int lower = 0;
    1845           0 :   unsigned int upper = code_hint_pairs_length - 1;
    1846           0 :   unsigned int mid = upper / 2;
    1847           0 :   while (lower <= upper)
    1848             :   {
    1849           0 :     mid = (upper + lower) / 2;
    1850           0 :     if (code_hint_pairs[mid].ec < ec)
    1851             :     {
    1852           0 :       lower = mid + 1;
    1853             :     }
    1854           0 :     else if (code_hint_pairs[mid].ec > ec)
    1855             :     {
    1856           0 :       upper = mid - 1;
    1857             :     }
    1858             :     else
    1859             :     {
    1860           0 :       return code_hint_pairs[mid].http_code;
    1861             :     }
    1862             :   }
    1863           0 :   return UINT_MAX;
    1864             : }
    1865             : 
    1866             : 
    1867             : unsigned int
    1868           0 : TALER_ErrorCode_get_http_status_safe (enum TALER_ErrorCode ec)
    1869             : {
    1870             :   unsigned int hc;
    1871             : 
    1872           0 :   hc = TALER_ErrorCode_get_http_status (ec);
    1873           0 :   if ( (0 == hc) ||
    1874             :        (UINT_MAX == hc) )
    1875           0 :     return MHD_HTTP_INTERNAL_SERVER_ERROR;
    1876           0 :   return hc;
    1877             : }

Generated by: LCOV version 1.14