gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: fix #6432


From: gnunet
Subject: [taler-merchant] branch master updated: fix #6432
Date: Tue, 25 Aug 2020 20:32:38 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new d354d11  fix #6432
d354d11 is described below

commit d354d119db7ca0195cb93140bf3160b11449fa92
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Aug 25 20:32:36 2020 +0200

    fix #6432
---
 src/backend/taler-merchant-httpd.c                 | 27 ++++++--------
 src/backend/taler-merchant-httpd_get-orders-ID.c   | 32 ++++++++---------
 src/backend/taler-merchant-httpd_get-tips-ID.c     |  6 ++--
 .../taler-merchant-httpd_post-orders-ID-abort.c    |  2 +-
 .../taler-merchant-httpd_post-orders-ID-claim.c    | 24 ++++++-------
 .../taler-merchant-httpd_post-orders-ID-paid.c     | 36 ++++++++-----------
 .../taler-merchant-httpd_post-orders-ID-pay.c      | 38 ++++++++++++--------
 .../taler-merchant-httpd_post-orders-ID-refund.c   | 15 ++++----
 .../taler-merchant-httpd_post-tips-ID-pickup.c     | 24 ++++++-------
 ...er-merchant-httpd_private-delete-instances-ID.c |  4 +--
 ...taler-merchant-httpd_private-delete-orders-ID.c |  8 ++---
 ...ler-merchant-httpd_private-delete-products-ID.c |  8 ++---
 ...ler-merchant-httpd_private-delete-reserves-ID.c |  6 ++--
 .../taler-merchant-httpd_private-get-orders-ID.c   | 41 +++++++++-------------
 .../taler-merchant-httpd_private-get-orders.c      | 12 +++----
 .../taler-merchant-httpd_private-get-products-ID.c |  3 +-
 .../taler-merchant-httpd_private-get-products.c    |  2 +-
 .../taler-merchant-httpd_private-get-reserves-ID.c |  4 +--
 .../taler-merchant-httpd_private-get-reserves.c    |  2 +-
 .../taler-merchant-httpd_private-get-tips-ID.c     |  4 +--
 .../taler-merchant-httpd_private-get-tips.c        |  2 +-
 .../taler-merchant-httpd_private-get-transfers.c   |  2 +-
 ...ler-merchant-httpd_private-patch-instances-ID.c | 15 ++++----
 ...merchant-httpd_private-patch-orders-ID-forget.c | 25 +++++++------
 ...aler-merchant-httpd_private-patch-products-ID.c | 24 ++++---------
 .../taler-merchant-httpd_private-post-instances.c  | 10 +++---
 ...-merchant-httpd_private-post-orders-ID-refund.c | 14 ++++----
 .../taler-merchant-httpd_private-post-orders.c     | 37 +++++++++----------
 ...-merchant-httpd_private-post-products-ID-lock.c |  7 ++--
 .../taler-merchant-httpd_private-post-products.c   | 19 +++++-----
 ...-httpd_private-post-reserves-ID-authorize-tip.c | 24 +++++--------
 .../taler-merchant-httpd_private-post-reserves.c   |  4 +--
 .../taler-merchant-httpd_private-post-transfers.c  | 17 +++++----
 src/lib/merchant_api_merchant_get_order.c          |  2 +-
 34 files changed, 235 insertions(+), 265 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index 120475d..4a726ec 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -1159,13 +1159,6 @@ url_handler (void *cls,
       NULL
     }
   };
-  static struct TMH_RequestHandler h404 = {
-    .mime_type = "application/json",
-    .data = "{\"code\":10}",
-    .data_size = strlen ("{\"code\":10}"),
-    .handler = &TMH_MHD_handler_static_response,
-    .response_code = MHD_HTTP_NOT_FOUND
-  };
   struct TMH_HandlerContext *hc = *con_cls;
   struct TMH_RequestHandler *handlers;
   bool use_private = false;
@@ -1408,15 +1401,15 @@ url_handler (void *cls,
       }
       if ( (NULL == hc->rh) &&
            (url_found) )
-        return TALER_MHD_reply_json_pack (connection,
-                                          MHD_HTTP_METHOD_NOT_ALLOWED,
-                                          "{s:s}",
-                                          "error",
-                                          "method not allowed");
+        return TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_METHOD_NOT_ALLOWED,
+                                           TALER_EC_METHOD_INVALID,
+                                           method);
       if (NULL == hc->rh)
-        return TMH_MHD_handler_static_response (&h404,
-                                                connection,
-                                                hc);
+        return TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_NOT_FOUND,
+                                           TALER_EC_ENDPOINT_UNKNOWN,
+                                           hc->url);
     }
   }
   /* At this point, we must have found a handler */
@@ -1426,7 +1419,7 @@ url_handler (void *cls,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        TALER_EC_INSTANCE_UNKNOWN,
-                                       "merchant instance unknown");
+                                       url);
   hc->has_body = ( (0 == strcasecmp (method,
                                      MHD_HTTP_METHOD_POST)) ||
                    (0 == strcasecmp (method,
@@ -1461,7 +1454,7 @@ url_handler (void *cls,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_PAYLOAD_TOO_LARGE,
                                            TALER_EC_UPLOAD_EXCEEDS_LIMIT,
-                                           "upload exceeds limit");
+                                           cl);
       }
     }
     GNUNET_break (NULL == hc->request_body); /* can't have it already */
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c 
b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 43e37d3..92c86c1 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -685,7 +685,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_BAD_REQUEST,
                                            TALER_EC_PARAMETER_MALFORMED,
-                                           "token malformed");
+                                           "token");
       }
     }
 
@@ -705,7 +705,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_BAD_REQUEST,
                                            TALER_EC_PARAMETER_MALFORMED,
-                                           "h_contract malformed");
+                                           "h_contract");
       }
     }
 
@@ -729,7 +729,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
           return TALER_MHD_reply_with_error (connection,
                                              MHD_HTTP_BAD_REQUEST,
                                              TALER_EC_PARAMETER_MALFORMED,
-                                             "timeout must be non-negative 
number");
+                                             "timeout_ms (must be non-negative 
number)");
         }
         god->sc.long_poll_timeout
           = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (
@@ -774,7 +774,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
           return TALER_MHD_reply_with_error (connection,
                                              MHD_HTTP_BAD_REQUEST,
                                              TALER_EC_PARAMETER_MALFORMED,
-                                             "invalid amount given for refund 
argument");
+                                             "refund");
         }
         god->sc.awaiting_refund = true;
       }
@@ -806,7 +806,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                         "database error looking up contract");
+                                         NULL);
     }
   }
 
@@ -825,7 +825,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_INTERNAL_LOGIC_ERROR,
-                                         "Could not hash contract terms");
+                                         "could not hash contract terms");
     }
     contract_match = (0 ==
                       GNUNET_memcmp (&h,
@@ -838,7 +838,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_FORBIDDEN,
                                          TALER_EC_GET_ORDER_WRONG_CONTRACT,
-                                         "Contract hash does not match order");
+                                         NULL);
     }
   }
 
@@ -863,7 +863,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                         "database error looking up order");
+                                         NULL);
     }
     god->unclaimed = (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
                      ! contract_available;
@@ -876,7 +876,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          TALER_EC_GET_ORDERS_ID_UNKNOWN,
-                                         "order_id not found in database");
+                                         order_id);
     }
     token_match = (0 == GNUNET_memcmp (&db_claim_token,
                                        &god->claim_token));
@@ -899,7 +899,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_FORBIDDEN,
                                        
TALER_EC_MERCHANT_GET_ORDER_INVALID_TOKEN,
-                                       "Claim token invalid");
+                                       NULL);
   }
   if ( ( (! token_match) ||
          (GNUNET_YES == GNUNET_is_zero (&god->claim_token)) ) &&
@@ -912,11 +912,11 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_FORBIDDEN,
                                            TALER_EC_GET_ORDER_WRONG_CONTRACT,
-                                           "Contract hash does not match 
order");
+                                           NULL);
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_FORBIDDEN,
                                          
TALER_EC_MERCHANT_GET_ORDER_INVALID_TOKEN,
-                                         "Claim token invalid");
+                                         NULL);
     }
     if (god->generate_html)
     {
@@ -982,7 +982,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                         "db error fetching pay session info");
+                                         NULL);
     }
     if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) ||
          (0 != strcmp (order_id,
@@ -1016,7 +1016,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                         "Merchant database error");
+                                         NULL);
     }
     GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
     GNUNET_break (0 ==
@@ -1045,7 +1045,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                       "Failed to lookup refunds for 
contract");
+                                       NULL);
   }
 
   if ( ((god->sc.awaiting_refund) &&
@@ -1097,7 +1097,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
           return TALER_MHD_reply_with_error (god->sc.con,
                                              MHD_HTTP_INTERNAL_SERVER_ERROR,
                                              TALER_EC_ALLOCATION_FAILURE,
-                                             "during QR code generation");
+                                             "qr code");
         }
         {
           json_t *context;
diff --git a/src/backend/taler-merchant-httpd_get-tips-ID.c 
b/src/backend/taler-merchant-httpd_get-tips-ID.c
index 0d853d7..0c79dc3 100644
--- a/src/backend/taler-merchant-httpd_get-tips-ID.c
+++ b/src/backend/taler-merchant-httpd_get-tips-ID.c
@@ -198,7 +198,7 @@ TMH_get_tips_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_PARAMETER_MALFORMED,
-                                       "tip_id malformed");
+                                       hc->infix);
   }
 
   TMH_db->preflight (TMH_db->cls);
@@ -220,7 +220,7 @@ TMH_get_tips_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GET_TIPS_DB_LOOKUP_ERROR,
-                                       "database error looking up contract");
+                                       NULL);
   }
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
   {
@@ -230,7 +230,7 @@ TMH_get_tips_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        TALER_EC_GET_TIPS_ID_UNKNOWN,
-                                       "tip_id not found in database");
+                                       hc->infix);
   }
 
   /* Build response */
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
index 6b1e5d6..7ac1665 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
@@ -499,7 +499,7 @@ process_abort_with_exchange (void *cls,
         ? "{s:s, s:I, s:I, s:I, s:O}"
         : "{s:s, s:I, s:I, s:I}",
         "hint",
-        "failed to obtain meta-data from exchange",
+        TALER_ErrorCode_get_hint (TALER_EC_ABORT_EXCHANGE_KEYS_FAILURE),
         "code",
         (json_int_t) TALER_EC_ABORT_EXCHANGE_KEYS_FAILURE,
         "exchange_http_status",
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-claim.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-claim.c
index 1fee659..d63766c 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-claim.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-claim.c
@@ -230,24 +230,24 @@ TMH_post_orders_ID_claim (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR,
-                                       "Failed to run DB transaction to claim 
order");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_CLAIM_SOFT_DB_ERROR,
-                                       "Failed to serialize DB transaction to 
claim order");
+                                       NULL);
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     if (NULL == contract_terms)
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          TALER_EC_ORDERS_CLAIM_NOT_FOUND,
-                                         "unknown order id (or invalid claim 
token)");
+                                         order_id);
     /* already claimed! */
     json_decref (contract_terms);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_CONFLICT,
                                        TALER_EC_ORDERS_ALREADY_CLAIMED,
-                                       "order already claimed");
+                                       order_id);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     GNUNET_assert (NULL != contract_terms);
     break; /* Good! return signature (below) */
@@ -269,20 +269,18 @@ TMH_post_orders_ID_claim (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_INTERNAL_LOGIC_ERROR,
-                                         "Could not hash order");
+                                         NULL);
     }
 
     GNUNET_CRYPTO_eddsa_sign (&hc->instance->merchant_priv.eddsa_priv,
                               &pdps,
                               &merchant_sig);
-    return TALER_MHD_reply_json_pack (connection,
-                                      MHD_HTTP_OK,
-                                      "{ s:o, s:o }",
-                                      "contract_terms",
-                                      contract_terms,
-                                      "sig",
-                                      GNUNET_JSON_from_data_auto (
-                                        &merchant_sig));
+    return TALER_MHD_reply_json_pack (
+      connection,
+      MHD_HTTP_OK,
+      "{ s:o, s:o }",
+      "contract_terms", contract_terms,
+      "sig", GNUNET_JSON_from_data_auto (&merchant_sig));
   }
 }
 
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-paid.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
index 623b276..f48e69f 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
@@ -84,12 +84,10 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler 
*rh,
                                   &hc->instance->merchant_pub.eddsa_pub))
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_json_pack (
-      connection,
-      MHD_HTTP_FORBIDDEN,
-      "{s:s, s:I}",
-      "hint", "deposit signature invalid",
-      "code", (json_int_t) TALER_EC_PAID_COIN_SIGNATURE_INVALID);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_FORBIDDEN,
+                                       TALER_EC_PAID_COIN_SIGNATURE_INVALID,
+                                       NULL);
   }
 
   TMH_db->preflight (TMH_db->cls);
@@ -111,19 +109,17 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_PAID_DB_ERROR,
-                                       "database error looking up contract");
+                                       NULL);
   }
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Unknown order id given: `%s'\n",
                 order_id);
-    return TALER_MHD_reply_json_pack (
-      connection,
-      MHD_HTTP_NOT_FOUND,
-      "{s:s, s:I}",
-      "hint", "order unknown",
-      "code", (json_int_t) TALER_EC_PAID_ORDER_UNKNOWN);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_PAID_ORDER_UNKNOWN,
+                                       order_id);
   }
 
   {
@@ -144,12 +140,10 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler 
*rh,
                             &h_contract_terms))
     {
       json_decref (contract_terms);
-      return TALER_MHD_reply_json_pack (
-        connection,
-        MHD_HTTP_CONFLICT,
-        "{s:s, s:I}",
-        "hint", "contract hash does not match this order",
-        "code", (json_int_t) TALER_EC_PAID_CONTRACT_HASH_MISMATCH);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_CONFLICT,
+                                         TALER_EC_PAID_CONTRACT_HASH_MISMATCH,
+                                         NULL);
     }
   }
   if (NULL != session_id)
@@ -162,7 +156,7 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_PAID_DB_ERROR,
-                                         "failed to start database 
transaction");
+                                         NULL);
     }
     qs = TMH_db->mark_contract_paid (TMH_db->cls,
                                      hc->instance->settings.id,
@@ -182,7 +176,7 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_PAID_DB_ERROR,
-                                         "failed to update contract's session 
id");
+                                         NULL);
     }
   }
   json_decref (contract_terms);
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index a709b3e..4626e3d 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -576,7 +576,8 @@ deposit_cb (void *cls,
                                 TALER_MHD_make_json_pack (
                                   "{s:s, s:I, s:I, s:I}",
                                   "hint",
-                                  "exchange had an internal server error",
+                                  TALER_ErrorCode_get_hint (
+                                    TALER_EC_PAY_EXCHANGE_FAILED),
                                   "code",
                                   (json_int_t) TALER_EC_PAY_EXCHANGE_FAILED,
                                   "exchange_code",
@@ -593,7 +594,8 @@ deposit_cb (void *cls,
         TALER_MHD_make_json_pack (
           "{s:s, s:I, s:I, s:I}",
           "hint",
-          "exchange failed, response body not even in JSON",
+          TALER_ErrorCode_get_hint (
+            TALER_EC_PAY_EXCHANGE_REPLY_MALFORMED),
           "code",
           (json_int_t) TALER_EC_PAY_EXCHANGE_REPLY_MALFORMED,
           "exchange_code",
@@ -611,7 +613,8 @@ deposit_cb (void *cls,
           MHD_HTTP_CONFLICT,
           TALER_MHD_make_json_pack ("{s:s, s:I, s:I, s:I, s:o, s:O}",
                                     "hint",
-                                    "exchange failed on deposit of a coin",
+                                    TALER_ErrorCode_get_hint (
+                                      TALER_EC_PAY_INSUFFICIENT_FUNDS),
                                     "code",
                                     (json_int_t) 
TALER_EC_PAY_INSUFFICIENT_FUNDS,
                                     "exchange_code",
@@ -628,7 +631,8 @@ deposit_cb (void *cls,
           MHD_HTTP_FAILED_DEPENDENCY,
           TALER_MHD_make_json_pack ("{s:s, s:I, s:I, s:I, s:o, s:O}",
                                     "hint",
-                                    "exchange failed on deposit of a coin",
+                                    TALER_ErrorCode_get_hint (
+                                      TALER_EC_PAY_EXCHANGE_FAILED),
                                     "code",
                                     (json_int_t) TALER_EC_PAY_EXCHANGE_FAILED,
                                     "exchange_code",
@@ -729,7 +733,8 @@ process_pay_with_exchange (void *cls,
         ? "{s:s, s:I, s:I, s:I, s:O}"
         : "{s:s, s:I, s:I, s:I}",
         "hint",
-        "failed to obtain meta-data from exchange",
+        TALER_ErrorCode_get_hint (
+          TALER_EC_PAY_EXCHANGE_KEYS_FAILURE),
         "code",
         (json_int_t) TALER_EC_PAY_EXCHANGE_KEYS_FAILURE,
         "exchange_http_status",
@@ -793,7 +798,9 @@ process_pay_with_exchange (void *cls,
         MHD_HTTP_FAILED_DEPENDENCY,
         TALER_MHD_make_json_pack (
           "{s:s, s:I, s:o, s:o}",
-          "hint", "coin's denomination not found",
+          "hint",
+          TALER_ErrorCode_get_hint (
+            TALER_EC_PAY_DENOMINATION_KEY_NOT_FOUND),
           "code", TALER_EC_PAY_DENOMINATION_KEY_NOT_FOUND,
           "h_denom_pub", GNUNET_JSON_from_data_auto (&dc->h_denom),
           "exchange_keys", TALER_EXCHANGE_get_keys_raw (exchange_handle)));
@@ -812,7 +819,7 @@ process_pay_with_exchange (void *cls,
         TALER_MHD_make_json_pack (
           "{s:s, s:I, s:o}",
           "hint",
-          "denomination not accepted",
+          TALER_ErrorCode_get_hint (ec),
           "code",
           (json_int_t) ec,
           "h_denom_pub",
@@ -851,7 +858,8 @@ process_pay_with_exchange (void *cls,
         MHD_HTTP_FORBIDDEN,
         TALER_MHD_make_json_pack (
           "{s:s, s:I, s:i}",
-          "hint", "deposit signature invalid",
+          "hint",
+          TALER_ErrorCode_get_hint (TALER_EC_PAY_COIN_SIGNATURE_INVALID),
           "code", (json_int_t) TALER_EC_PAY_COIN_SIGNATURE_INVALID,
           "coin_idx", i));
       return;
@@ -1631,7 +1639,7 @@ parse_pay (struct MHD_Connection *connection,
               TALER_MHD_reply_with_error (connection,
                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
                                           TALER_EC_PAY_DB_FETCH_PAY_ERROR,
-                                          "Failed to obtain contract terms 
from DB"))
+                                          NULL))
              ? GNUNET_NO
              : GNUNET_SYSERR;
     }
@@ -1641,7 +1649,7 @@ parse_pay (struct MHD_Connection *connection,
               TALER_MHD_reply_with_error (connection,
                                           MHD_HTTP_NOT_FOUND,
                                           TALER_EC_PAY_PROPOSAL_NOT_FOUND,
-                                          "Proposal not found"))
+                                          pc->order_id))
              ? GNUNET_NO
              : GNUNET_SYSERR;
     }
@@ -1657,7 +1665,7 @@ parse_pay (struct MHD_Connection *connection,
               TALER_MHD_reply_with_error (connection,
                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
                                           
TALER_EC_PAY_FAILED_COMPUTE_PROPOSAL_HASH,
-                                          "Failed to hash contract terms"))
+                                          NULL))
              ? GNUNET_NO
              : GNUNET_SYSERR;
     }
@@ -1677,7 +1685,7 @@ parse_pay (struct MHD_Connection *connection,
               TALER_MHD_reply_with_error (connection,
                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
                                           TALER_EC_PAY_MERCHANT_FIELD_MISSING,
-                                          "No merchant field in proposal"))
+                                          NULL))
              ? GNUNET_NO
              : GNUNET_SYSERR;
     }
@@ -1726,7 +1734,7 @@ parse_pay (struct MHD_Connection *connection,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE,
-                                         "refund deadline after wire transfer 
deadline");
+                                         NULL);
     }
 
     if (pc->pay_deadline.abs_value_us <
@@ -1737,7 +1745,7 @@ parse_pay (struct MHD_Connection *connection,
               TALER_MHD_reply_with_error (connection,
                                           MHD_HTTP_GONE,
                                           TALER_EC_PAY_OFFER_EXPIRED,
-                                          "We are past the payment deadline"))
+                                          NULL))
              ? GNUNET_NO
              : GNUNET_SYSERR;
     }
@@ -1757,7 +1765,7 @@ parse_pay (struct MHD_Connection *connection,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_PAY_WIRE_HASH_UNKNOWN,
-                                         "Did not find matching wire details");
+                                         NULL);
     }
     pc->wm = wm;
   }
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
index 7fafdd5..18fca9a 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
@@ -508,6 +508,7 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
     {
       json_t *contract_terms;
       uint64_t order_serial;
+
       qs = TMH_db->lookup_contract_terms (TMH_db->cls,
                                           hc->instance->settings.id,
                                           hc->infix,
@@ -523,7 +524,7 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR,
-                                           "db error fetching contract terms");
+                                           NULL);
       }
       if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
       {
@@ -531,7 +532,7 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_NOT_FOUND,
                                            TALER_EC_GET_ORDERS_ORDER_NOT_FOUND,
-                                           "Did not find contract terms for 
order in DB");
+                                           NULL);
       }
       {
         struct GNUNET_HashCode h_contract_terms;
@@ -544,7 +545,7 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
           return TALER_MHD_reply_with_error (connection,
                                              MHD_HTTP_INTERNAL_SERVER_ERROR,
                                              
TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH,
-                                             "Failed to hash contract terms");
+                                             NULL);
         }
         json_decref (contract_terms);
         if (0 != GNUNET_memcmp (&h_contract_terms,
@@ -552,8 +553,8 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
         {
           return TALER_MHD_reply_with_error (connection,
                                              MHD_HTTP_FORBIDDEN,
-                                             
TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH,
-                                             "");
+                                             TALER_EC_GET_ORDER_WRONG_CONTRACT,
+                                             NULL);
         }
       }
     }
@@ -572,7 +573,7 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                         "Failed to lookup refunds for 
contract");
+                                         NULL);
     }
   }
 
@@ -595,7 +596,7 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
-                                         "Merchant database error");
+                                         NULL);
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       /* We need to talk to the exchange */
       /* Notify clients waiting for the refund to be obtained. */
diff --git a/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c 
b/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c
index bba73d4..729a07f 100644
--- a/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c
+++ b/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c
@@ -557,7 +557,7 @@ reply_lookup_tip_failed (struct MHD_Connection *connection,
   return TALER_MHD_reply_with_error (connection,
                                      response_code,
                                      ec,
-                                     "Could not process pickup");
+                                     NULL);
 }
 
 
@@ -604,7 +604,7 @@ TMH_post_tips_ID_pickup (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_BAD_REQUEST,
                                          TALER_EC_PARAMETER_MALFORMED,
-                                         "tip_id malformed");
+                                         hc->infix);
     }
 
     {
@@ -631,8 +631,8 @@ TMH_post_tips_ID_pickup (const struct TMH_RequestHandler 
*rh,
       json_decref (planchets);
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_BAD_REQUEST,
-                                         
TALER_EC_PATCH_INSTANCES_BAD_PAYTO_URIS,
-                                         "Invalid bank account information");
+                                         TALER_EC_PARAMETER_MALFORMED,
+                                         "planchets");
     }
 
     GNUNET_array_grow (pc->planchets,
@@ -735,7 +735,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_TIP_PICKUP_DB_ERROR_SOFT,
-                                       "Too many DB serialization failures");
+                                       NULL);
   }
   if (GNUNET_OK !=
       TMH_db->start (TMH_db->cls,
@@ -745,7 +745,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_TIP_PICKUP_DB_ERROR_HARD,
-                                       "Could not begin transaction");
+                                       NULL);
   }
   {
     struct GNUNET_CRYPTO_RsaSignature *sigs[GNUNET_NZL (pc->planchets_length)];
@@ -836,7 +836,7 @@ RETRY:
       return TALER_MHD_reply_with_error (connection,
                                          response_code,
                                          ec,
-                                         "Could not process pickup");
+                                         NULL);
     }
   }
 
@@ -859,7 +859,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_GONE,
                                        TALER_EC_TIP_PICKUP_HAS_EXPIRED,
-                                       "Could not process pickup: it is too 
late");
+                                       hc->infix);
   }
   if (0 >
       TALER_amount_subtract (&total_remaining,
@@ -871,7 +871,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_INTERNAL_LOGIC_ERROR,
-                                       "tip already overdrawn");
+                                       hc->infix);
   }
 
   if (0 >
@@ -883,7 +883,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        
TALER_EC_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING,
-                                       "requested amount exceeds amount left 
in tip");
+                                       hc->infix);
   }
 
   GNUNET_assert (0 <
@@ -904,7 +904,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_TIP_PICKUP_DB_STORE_HARD_ERROR,
-                                       "Could not store pickup ID in 
database");
+                                       NULL);
   }
   qs = TMH_db->commit (TMH_db->cls);
   if (qs < 0)
@@ -915,7 +915,7 @@ RETRY:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_TIP_PICKUP_DB_STORE_HARD_ERROR,
-                                       "Could not commit transaction to 
database");
+                                       NULL);
   }
   MHD_suspend_connection (connection);
   pc->tt = GNUNET_SCHEDULER_add_delayed (EXCHANGE_TIMEOUT,
diff --git a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c 
b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
index 965de32..9c201cd 100644
--- a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
+++ b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
@@ -58,13 +58,13 @@ TMH_private_delete_instances_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_DELETE_INSTANCES_ID_DB_HARD_FAILURE,
-                                       "Transaction failed");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
     GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_INTERNAL_INVARIANT_FAILURE,
-                                       "Serialization error for single SQL 
statement");
+                                       NULL);
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
diff --git a/src/backend/taler-merchant-httpd_private-delete-orders-ID.c 
b/src/backend/taler-merchant-httpd_private-delete-orders-ID.c
index f044425..ef272a6 100644
--- a/src/backend/taler-merchant-httpd_private-delete-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-delete-orders-ID.c
@@ -54,13 +54,13 @@ TMH_private_delete_orders_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_DELETE_DB_HARD_FAILURE,
-                                       "Transaction failed");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
     GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_INTERNAL_INVARIANT_FAILURE,
-                                       "Serialization error for single SQL 
statement");
+                                       NULL);
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     qs = TMH_db->lookup_order (TMH_db->cls,
                                mi->settings.id,
@@ -81,11 +81,11 @@ TMH_private_delete_orders_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          TALER_EC_ORDERS_DELETE_NO_SUCH_ORDER,
-                                         "Order unknown");
+                                         hc->infix);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_CONFLICT,
                                        TALER_EC_ORDERS_DELETE_AWAITING_PAYMENT,
-                                       "Order deletion impossible, order is 
locked");
+                                       hc->infix);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     return TALER_MHD_reply_static (connection,
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/backend/taler-merchant-httpd_private-delete-products-ID.c 
b/src/backend/taler-merchant-httpd_private-delete-products-ID.c
index fe04d76..2102a92 100644
--- a/src/backend/taler-merchant-httpd_private-delete-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-delete-products-ID.c
@@ -49,13 +49,13 @@ TMH_private_delete_products_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_PRODUCTS_DELETE_DB_HARD_FAILURE,
-                                       "Transaction failed");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
     GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_INTERNAL_INVARIANT_FAILURE,
-                                       "Serialization error for single SQL 
statement");
+                                       NULL);
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     qs = TMH_db->lookup_product (TMH_db->cls,
                                  mi->settings.id,
@@ -65,11 +65,11 @@ TMH_private_delete_products_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          
TALER_EC_PRODUCTS_DELETE_NO_SUCH_PRODUCT,
-                                         "Product unknown");
+                                         hc->infix);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_CONFLICT,
                                        
TALER_EC_PRODUCTS_DELETE_CONFLICTING_LOCK,
-                                       "Product deletion impossible, product 
is locked");
+                                       hc->infix);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     return TALER_MHD_reply_static (connection,
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c 
b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c
index ba2c08b..c2060a8 100644
--- a/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c
+++ b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c
@@ -51,7 +51,7 @@ TMH_private_delete_reserves_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_RESERVES_INVALID_RESERVE_PUB,
-                                       "reserve public key malformed");
+                                       hc->infix);
   }
   purge = MHD_lookup_connection_value (connection,
                                        MHD_GET_ARGUMENT_KIND,
@@ -73,7 +73,7 @@ TMH_private_delete_reserves_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_RESERVES_DELETE_DB_HARD_FAILURE,
-                                       "Transaction failed");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
     GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
@@ -84,7 +84,7 @@ TMH_private_delete_reserves_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        
TALER_EC_RESERVES_DELETE_NO_SUCH_RESERVE,
-                                       "Reserve unknown");
+                                       hc->infix);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     return TALER_MHD_reply_static (connection,
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c 
b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index e7c4a2b..09f9dc5 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -318,14 +318,12 @@ gorc_resume (struct GetOrderRequestContext *gorc,
  *
  * @param gorc request to add wire report to
  * @param ec error code to add
- * @param hint human-readable hint
  * @param coin_pub public key of the affected coin
  * @param exchange_hr details from exchange, NULL if exchange is blameless
  */
 static void
 gorc_report (struct GetOrderRequestContext *gorc,
              enum TALER_ErrorCode ec,
-             const char *hint,
              struct TALER_CoinSpendPublicKeyP *coin_pub,
              const struct TALER_EXCHANGE_HttpResponse *exchange_hr)
 {
@@ -333,11 +331,11 @@ gorc_report (struct GetOrderRequestContext *gorc,
     GNUNET_assert (0 ==
                    json_array_append_new (
                      gorc->wire_reports,
-                     json_pack ("{s:I, s:s, s:I, s:I,  s:o}",
+                     json_pack ("{s:I, s:s, s:I, s:I, s:o }",
                                 "code",
                                 (json_int_t) ec,
                                 "hint",
-                                hint,
+                                TALER_ErrorCode_get_hint (ec),
                                 "exchange_ec",
                                 (json_int_t) exchange_hr->ec,
                                 "exchange_hc",
@@ -348,11 +346,11 @@ gorc_report (struct GetOrderRequestContext *gorc,
     GNUNET_assert (0 ==
                    json_array_append_new (
                      gorc->wire_reports,
-                     json_pack ("{s:I, s:s, s:o}",
+                     json_pack ("{s:I, s:s, s:o }",
                                 "code",
                                 (json_int_t) ec,
                                 "hint",
-                                hint,
+                                TALER_ErrorCode_get_hint (ec),
                                 "coin_pub",
                                 GNUNET_JSON_from_data_auto (coin_pub))));
 }
@@ -398,7 +396,6 @@ deposit_get_cb (void *cls,
   {
     gorc_report (gorc,
                  TALER_EC_GET_ORDERS_EXCHANGE_TRACKING_FAILURE,
-                 "Exchange failed to return tracking data",
                  &tq->coin_pub,
                  hr);
     GNUNET_free (tq);
@@ -419,7 +416,6 @@ deposit_get_cb (void *cls,
     {
       gorc_report (gorc,
                    TALER_EC_GET_ORDERS_DB_STORE_TRACKING_FAILURE,
-                   "Merchant backend failed to store transfer details in DB",
                    &tq->coin_pub,
                    NULL);
       GNUNET_free (tq);
@@ -437,7 +433,6 @@ deposit_get_cb (void *cls,
     {
       gorc_report (gorc,
                    TALER_EC_GET_ORDERS_AMOUNT_ARITHMETIC_FAILURE,
-                   "Merchant backend could not sum up deposit total",
                    &tq->coin_pub,
                    NULL);
       GNUNET_free (tq);
@@ -454,7 +449,6 @@ deposit_get_cb (void *cls,
     {
       gorc_report (gorc,
                    TALER_EC_GET_ORDERS_AMOUNT_ARITHMETIC_FAILURE,
-                   "Merchant backend could not sum up deposit fees",
                    &tq->coin_pub,
                    NULL);
       GNUNET_free (tq);
@@ -470,7 +464,6 @@ deposit_get_cb (void *cls,
     /* got a 'preliminary' reply from the exchange, simply skip */
     gorc_report (gorc,
                  TALER_EC_NONE,
-                 "Exchange returned preliminary response",
                  &tq->coin_pub,
                  hr);
   }
@@ -794,7 +787,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
           return TALER_MHD_reply_with_error (connection,
                                              MHD_HTTP_BAD_REQUEST,
                                              TALER_EC_PARAMETER_MALFORMED,
-                                             "timeout must be non-negative 
number");
+                                             "timeout_ms must be non-negative 
number");
         }
         gorc->sc.long_poll_timeout
           = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (
@@ -850,14 +843,14 @@ TMH_private_get_orders_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR,
-                                         "db error fetching contract terms");
+                                         NULL);
     }
     if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     {
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          TALER_EC_GET_ORDERS_ORDER_NOT_FOUND,
-                                         "Did not find contract terms for 
order in DB");
+                                         hc->infix);
     }
 
     /* extract the fulfillment URL and total amount from the contract terms! */
@@ -878,7 +871,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
           connection,
           MHD_HTTP_INTERNAL_SERVER_ERROR,
           TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR,
-          "Merchant database error (contract terms corrupted)");
+          hc->infix);
       }
       if (0 !=
           strcasecmp (TMH_currency,
@@ -889,7 +882,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
           connection,
           MHD_HTTP_INTERNAL_SERVER_ERROR,
           TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR,
-          "Merchant database error (contract terms in wrong currency)");
+          gorc->contract_amount.currency);
       }
     }
     gorc->fulfillment_url
@@ -906,7 +899,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH,
-                                           "Failed to hash contract terms");
+                                           NULL);
       }
     }
   }
@@ -915,7 +908,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        gorc->wire_hc,
                                        gorc->wire_ec,
-                                       "Failed to obtain wire details");
+                                       NULL);
   }
 
   GNUNET_assert (NULL != gorc->contract_terms);
@@ -941,7 +934,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_GET_ORDERS_DB_FETCH_PAYMENT_STATUS,
-                                         "DB error fetching payment status");
+                                         NULL);
     }
   }
   if ( (! paid) &&
@@ -963,7 +956,7 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_GET_ORDERS_DB_FETCH_PAYMENT_STATUS,
-                                         "DB error fetching payment status");
+                                         NULL);
     }
     if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
     {
@@ -1093,7 +1086,7 @@ TMH_private_get_orders_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_GET_ORDERS_DB_FETCH_TRANSACTION_ERROR,
-                                       "Merchant database error");
+                                       NULL);
   }
 
   /* Generate final reply, including wire details if we have them */
@@ -1117,7 +1110,7 @@ TMH_private_get_orders_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR,
-                                         "Merchant database error");
+                                         NULL);
     }
 
     if (! wired)
@@ -1135,7 +1128,7 @@ TMH_private_get_orders_ID (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_GET_ORDERS_CONTRACT_CONTENT_INVALID,
-                                           "Inconsistent contract terms in 
DB");
+                                           "refund exceeds contract value");
       }
       if (0 >
           TALER_amount_subtract (&expect_total,
@@ -1146,7 +1139,7 @@ TMH_private_get_orders_ID (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_GET_ORDERS_CONTRACT_CONTENT_INVALID,
-                                           "Inconsistent contract terms in 
DB");
+                                           "deposit fees exceed total minus 
refunds");
       }
       if (0 >=
           TALER_amount_cmp (&expect_total,
diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c 
b/src/backend/taler-merchant-httpd_private-get-orders.c
index b98b3b7..c8a1338 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders.c
@@ -473,11 +473,10 @@ TMH_private_get_orders (const struct TMH_RequestHandler 
*rh,
     if (TALER_EC_NONE != aos->result)
     {
       GNUNET_break (0);
-      return TALER_MHD_reply_with_error (
-        connection,
-        MHD_HTTP_INTERNAL_SERVER_ERROR,
-        aos->result,
-        TALER_ErrorCode_get_hint (aos->result));
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         aos->result,
+                                         NULL);
     }
     return TALER_MHD_reply_json_pack (connection,
                                       MHD_HTTP_OK,
@@ -643,8 +642,7 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          aos_result,
-                                         TALER_ErrorCode_get_hint (
-                                           aos_result));
+                                         NULL);
     }
   }
   if ( (0 == qs) &&
diff --git a/src/backend/taler-merchant-httpd_private-get-products-ID.c 
b/src/backend/taler-merchant-httpd_private-get-products-ID.c
index 611de7e..41ef612 100644
--- a/src/backend/taler-merchant-httpd_private-get-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-products-ID.c
@@ -51,8 +51,9 @@ TMH_private_get_products_ID (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GET_PRODUCTS_DB_LOOKUP_ERROR,
-                                       "failed to lookup products in 
database");
+                                       NULL);
   }
+  // FIXME: MUST return 404 if qs == 0, not this!
   {
     json_t *reply;
 
diff --git a/src/backend/taler-merchant-httpd_private-get-products.c 
b/src/backend/taler-merchant-httpd_private-get-products.c
index 00b0463..538dec2 100644
--- a/src/backend/taler-merchant-httpd_private-get-products.c
+++ b/src/backend/taler-merchant-httpd_private-get-products.c
@@ -73,7 +73,7 @@ TMH_private_get_products (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GET_PRODUCTS_DB_LOOKUP_ERROR,
-                                       "failed to lookup products in 
database");
+                                       NULL);
   }
   return TALER_MHD_reply_json_pack (connection,
                                     MHD_HTTP_OK,
diff --git a/src/backend/taler-merchant-httpd_private-get-reserves-ID.c 
b/src/backend/taler-merchant-httpd_private-get-reserves-ID.c
index 1945524..9d45fc1 100644
--- a/src/backend/taler-merchant-httpd_private-get-reserves-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-reserves-ID.c
@@ -153,7 +153,7 @@ TMH_private_get_reserves_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_PARAMETER_MALFORMED,
-                                       "reserve_pub malformed");
+                                       hc->infix);
   }
   {
     const char *tstr;
@@ -207,7 +207,7 @@ TMH_private_get_reserves_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          response_code,
                                          ec,
-                                         "Could not determine exchange URL for 
the given tip id");
+                                         hc->infix);
     }
     return ctx.res;
   }
diff --git a/src/backend/taler-merchant-httpd_private-get-reserves.c 
b/src/backend/taler-merchant-httpd_private-get-reserves.c
index 976d71c..97a27f3 100644
--- a/src/backend/taler-merchant-httpd_private-get-reserves.c
+++ b/src/backend/taler-merchant-httpd_private-get-reserves.c
@@ -138,7 +138,7 @@ TMH_private_get_reserves (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GET_RESERVES_DB_LOOKUP_ERROR,
-                                       "failed to lookup reserves in 
database");
+                                       NULL);
   }
   return TALER_MHD_reply_json_pack (connection,
                                     MHD_HTTP_OK,
diff --git a/src/backend/taler-merchant-httpd_private-get-tips-ID.c 
b/src/backend/taler-merchant-httpd_private-get-tips-ID.c
index 7c70a68..ba4e2f6 100644
--- a/src/backend/taler-merchant-httpd_private-get-tips-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-tips-ID.c
@@ -63,7 +63,7 @@ TMH_private_get_tips_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_PARAMETER_MALFORMED,
-                                       "tip_id malformed");
+                                       hc->infix);
   }
   {
     const char *pstr;
@@ -115,7 +115,7 @@ TMH_private_get_tips_ID (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        response_code,
                                        ec,
-                                       "Could not determine exchange URL for 
the given tip id");
+                                       NULL);
   }
   if (fpu)
   {
diff --git a/src/backend/taler-merchant-httpd_private-get-tips.c 
b/src/backend/taler-merchant-httpd_private-get-tips.c
index 47fe305..fa694b3 100644
--- a/src/backend/taler-merchant-httpd_private-get-tips.c
+++ b/src/backend/taler-merchant-httpd_private-get-tips.c
@@ -154,7 +154,7 @@ TMH_private_get_tips (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_GET_DB_LOOKUP_ERROR,
-                                       "failed to lookup tips in database");
+                                       NULL);
   }
 
   return TALER_MHD_reply_json_pack (connection,
diff --git a/src/backend/taler-merchant-httpd_private-get-transfers.c 
b/src/backend/taler-merchant-httpd_private-get-transfers.c
index 8020fbe..534866b 100644
--- a/src/backend/taler-merchant-httpd_private-get-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-get-transfers.c
@@ -226,7 +226,7 @@ TMH_private_get_transfers (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GET_TRANSFERS_DB_FETCH_ERROR,
-                                         "Fail to query database about 
transfers");
+                                         NULL);
     }
     return TALER_MHD_reply_json_pack (connection,
                                       MHD_HTTP_OK,
diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c 
b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
index 8634815..94c02ea 100644
--- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
+++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
@@ -105,7 +105,7 @@ TMH_private_patch_instances_ID (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_PATCH_INSTANCES_BAD_PAYTO_URIS,
-                                       "Invalid bank account information");
+                                       NULL);
   for (unsigned int i = 0; i<MAX_RETRIES; i++)
   {
     /* Cleanup after earlier loops */
@@ -130,8 +130,7 @@ TMH_private_patch_instances_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_BAD_REQUEST,
                                          TALER_EC_POST_INSTANCES_BAD_CURRENCY,
-                                         "Max deposit fee or max wire fee 
currency incompatible with config");
-      break;
+                                         NULL);
     }
     if (GNUNET_OK !=
         TMH_db->start (TMH_db->cls,
@@ -141,7 +140,7 @@ TMH_private_patch_instances_ID (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_PATCH_INSTANCES_DB_START_ERROR,
-                                         "failed to start database 
transaction");
+                                         NULL);
     }
     /* Check for equality of settings */
     if (! ( (0 == strcmp (mi->settings.name,
@@ -209,7 +208,7 @@ TMH_private_patch_instances_ID (const struct 
TMH_RequestHandler *rh,
             return TALER_MHD_reply_with_error (connection,
                                                MHD_HTTP_BAD_REQUEST,
                                                
TALER_EC_POST_INSTANCES_BAD_PAYTO_URIS,
-                                               "Invalid bank account 
information");
+                                               NULL);
           }
           if ((0 == strcasecmp (uri,
                                 str)) )
@@ -223,7 +222,7 @@ TMH_private_patch_instances_ID (const struct 
TMH_RequestHandler *rh,
               return TALER_MHD_reply_with_error (connection,
                                                  MHD_HTTP_BAD_REQUEST,
                                                  
TALER_EC_POST_INSTANCES_BAD_PAYTO_URIS,
-                                                 "Invalid bank account 
information");
+                                                 str);
             }
             matches[i] = true;
             matched = true;
@@ -294,7 +293,7 @@ TMH_private_patch_instances_ID (const struct 
TMH_RequestHandler *rh,
           return TALER_MHD_reply_with_error (connection,
                                              MHD_HTTP_BAD_REQUEST,
                                              
TALER_EC_POST_INSTANCES_BAD_PAYTO_URIS,
-                                             "Invalid bank account 
information");
+                                             ad.payto_uri);
         }
         wm->active = true;
         GNUNET_CONTAINER_DLL_insert (wm_head,
@@ -338,7 +337,7 @@ giveup:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_PATCH_INSTANCES_DB_COMMIT_ERROR,
-                                       "failed to add instance to database");
+                                       NULL);
   }
   /* Deactivate existing wire methods that were removed above */
   for (struct TMH_WireMethod *wm = mi->wm_head;
diff --git a/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c 
b/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c
index 1c33d84..ce79037 100644
--- a/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c
+++ b/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c
@@ -66,6 +66,7 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
   json_t *contract_terms;
   uint64_t order_serial;
 
+  // FIXME: should be a transaction with the update!
   qs = TMH_db->lookup_contract_terms (TMH_db->cls,
                                       hc->instance->settings.id,
                                       order_id,
@@ -77,17 +78,17 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR,
-                                       "Failed to run DB transaction to lookup 
order");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_CLAIM_SOFT_DB_ERROR,
-                                       "Failed to serialize DB transaction to 
lookup order");
+                                       NULL);
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        TALER_EC_FORGET_ORDER_NOT_FOUND,
-                                       "unknown order id");
+                                       order_id);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     GNUNET_assert (NULL != contract_terms);
     break;
@@ -116,7 +117,7 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_PARAMETER_MALFORMED,
-                                       "paths");
+                                       "fields");
   }
 
   {
@@ -125,6 +126,7 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
     json_array_foreach (fields, index, value) {
       int forget_status = GNUNET_OK;
       int expand_status;
+
       if (! (json_is_string (value)))
       {
         json_decref (contract_terms);
@@ -132,7 +134,7 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_BAD_REQUEST,
                                            
TALER_EC_FORGET_PATH_SYNTAX_INCORRECT,
-                                           "field isn't a string");
+                                           "field is not a string");
       }
       expand_status = TALER_JSON_expand_path (contract_terms,
                                               json_string_value (value),
@@ -146,7 +148,7 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_CONFLICT,
                                            
TALER_EC_FORGET_PATH_NOT_FORGETTABLE,
-                                           "field isn't forgettable");
+                                           json_string_value (value));
       }
       if (GNUNET_SYSERR == expand_status)
       {
@@ -156,7 +158,7 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_BAD_REQUEST,
                                            
TALER_EC_FORGET_PATH_SYNTAX_INCORRECT,
-                                           "malformed path");
+                                           json_string_value (value));
       }
     }
   }
@@ -172,21 +174,22 @@ TMH_private_patch_orders_ID_forget (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR,
-                                       "Failed to run DB transaction to update 
contract terms");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
+    // FIXME: We should not re-try a few times AND make this a larger 
transaction!
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_ORDERS_CLAIM_SOFT_DB_ERROR,
-                                       "Failed to serialize DB transaction to 
update contract terms");
+                                       NULL);
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        TALER_EC_FORGET_ORDER_NOT_FOUND,
-                                       "unknown order id");
+                                       order_id);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     break;
   }
-
   json_decref (contract_terms);
   json_decref (fields);
 
diff --git a/src/backend/taler-merchant-httpd_private-patch-products-ID.c 
b/src/backend/taler-merchant-httpd_private-patch-products-ID.c
index 2e01b76..0d722b5 100644
--- a/src/backend/taler-merchant-httpd_private-patch-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-patch-products-ID.c
@@ -60,42 +60,32 @@ determine_cause (struct MHD_Connection *connection,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_PRODUCTS_PATCH_DB_COMMIT_HARD_ERROR,
-                                       "Failed to get existing product");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_INTERNAL_INVARIANT_FAILURE,
-                                       "Serialization error for 
single-statment request");
+                                       "unexpected serialization problem");
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        TALER_EC_PRODUCTS_PATCH_UNKNOWN_PRODUCT,
-                                       "The specified product is unknown");
+                                       product_id);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     break; /* do below */
   }
 
   {
     enum TALER_ErrorCode ec;
-    const char *hint;
 
     ec = TALER_EC_INTERNAL_INVARIANT_FAILURE;
-    hint = "transaction failed for causes unknown";
     if (pdx.total_lost > pd->total_lost)
-    {
       ec = TALER_EC_PRODUCTS_PATCH_TOTAL_LOST_REDUCED;
-      hint = "total lost cannot be lowered";
-    }
     if (pdx.total_stock > pd->total_stock)
-    {
       ec = TALER_EC_PRODUCTS_PATCH_TOTAL_STOCKED_REDUCED;
-      hint = "total stocked cannot be lowered";
-    }
     if (pd->total_stock - pdx.total_sold > pd->total_lost)
-    {
       ec = TALER_EC_PRODUCTS_PATCH_TOTAL_LOST_EXCEEDS_STOCKS;
-      hint = "total lost cannot exceed total stock minus total sold";
-    }
     GNUNET_free (pdx.description);
     json_decref (pdx.description_i18n);
     GNUNET_free (pdx.unit);
@@ -105,7 +95,7 @@ determine_cause (struct MHD_Connection *connection,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_CONFLICT,
                                        ec,
-                                       hint);
+                                       NULL);
   }
 }
 
@@ -206,14 +196,14 @@ TMH_private_patch_products_ID (const struct 
TMH_RequestHandler *rh,
       ret = TALER_MHD_reply_with_error (connection,
                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
                                         
TALER_EC_PRODUCTS_PATCH_DB_COMMIT_HARD_ERROR,
-                                        "Failed to commit change");
+                                        NULL);
       break;
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0);
       ret = TALER_MHD_reply_with_error (connection,
                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
                                         TALER_EC_INTERNAL_INVARIANT_FAILURE,
-                                        "Serialization error for 
single-statment request");
+                                        "unexpected serialization problem");
       break;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       ret = determine_cause (connection,
diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c 
b/src/backend/taler-merchant-httpd_private-post-instances.c
index 0fec449..19d6b80 100644
--- a/src/backend/taler-merchant-httpd_private-post-instances.c
+++ b/src/backend/taler-merchant-httpd_private-post-instances.c
@@ -190,7 +190,7 @@ TMH_private_post_instances (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_POST_INSTANCES_BAD_CURRENCY,
-                                       "Max deposit fee or max wire fee 
currency incompatible with config");
+                                       NULL);
   }
 
   {
@@ -241,7 +241,7 @@ TMH_private_post_instances (const struct TMH_RequestHandler 
*rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_CONFLICT,
                                            
TALER_EC_POST_INSTANCES_ALREADY_EXISTS,
-                                           "An instance using this identifier 
already exists");
+                                           is.id);
       }
     }
   }
@@ -339,7 +339,7 @@ TMH_private_post_instances (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_BAD_REQUEST,
                                          
TALER_EC_POST_INSTANCES_BAD_PAYTO_URIS,
-                                         "Invalid bank account information");
+                                         NULL);
     }
   }
 
@@ -370,7 +370,7 @@ TMH_private_post_instances (const struct TMH_RequestHandler 
*rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_POST_INSTANCES_DB_START_ERROR,
-                                           "failed to start database 
transaction");
+                                           NULL);
       }
       qs = TMH_db->insert_instance (TMH_db->cls,
                                     &mi->merchant_pub,
@@ -425,7 +425,7 @@ retry:
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_POST_INSTANCES_DB_COMMIT_ERROR,
-                                         "failed to add instance to database");
+                                         NULL);
     }
     /* Finally, also update our running process */
     GNUNET_assert (GNUNET_OK ==
diff --git a/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c 
b/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c
index d308bf4..859603b 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c
@@ -138,7 +138,7 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_REFUND_STORE_DB_ERROR,
-                                         "Could not begin DB transaction");
+                                         NULL);
     }
     rs = TMH_db->increase_refund (TMH_db->cls,
                                   hc->instance->settings.id,
@@ -179,12 +179,12 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
                                        MHD_HTTP_CONFLICT,
                                        TALER_EC_REFUND_INCONSISTENT_AMOUNT,
                                        "Amount above payment");
-  case TALER_MERCHANTDB_RS_HARD_ERROR:
   case TALER_MERCHANTDB_RS_SOFT_ERROR:
+  case TALER_MERCHANTDB_RS_HARD_ERROR:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_REFUND_MERCHANT_DB_COMMIT_ERROR,
-                                       "Internal database error");
+                                       NULL);
   case TALER_MERCHANTDB_RS_NO_SUCH_ORDER:
     {
       enum GNUNET_DB_QueryStatus qs;
@@ -202,14 +202,14 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_CONFLICT,
                                            TALER_EC_REFUND_ORDER_ID_UNPAID,
-                                           "Order never paid");
+                                           hc->infix);
       }
       else
       {
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_NOT_FOUND,
                                            TALER_EC_REFUND_ORDER_ID_UNKNOWN,
-                                           "Order unknown");
+                                           hc->infix);
       }
     }
   case TALER_MERCHANTDB_RS_SUCCESS:
@@ -228,7 +228,7 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_NOT_FOUND,
                                            TALER_EC_REFUND_ORDER_ID_UNKNOWN,
-                                           "Order unknown when looking up 
contract");
+                                           hc->infix);
       }
       if (GNUNET_OK !=
           TALER_JSON_contract_hash (contract_terms,
@@ -271,7 +271,7 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_REFUND_DB_INCONSISTENT,
-                                         "Database inconsistent, could not 
trigger notifications");
+                                         NULL);
     }
     TMH_notify_order_change (hc->instance,
                              hc->infix,
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c 
b/src/backend/taler-merchant-httpd_private-post-orders.c
index 13a2127..fd9c8ce 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -382,7 +382,7 @@ execute_order (struct MHD_Connection *connection,
       connection,
       MHD_HTTP_BAD_REQUEST,
       TALER_EC_PROPOSAL_ORDER_BAD_CURRENCY,
-      "Total amount must be in currency supported by backend");
+      TMH_currency);
   }
 
   if (wire_transfer_deadline.abs_value_us <
@@ -453,19 +453,14 @@ execute_order (struct MHD_Connection *connection,
       else
       {
         /* This request is not idempotent */
-        MHD_RESULT rv;
-        char *msg;
-
-        GNUNET_asprintf (&msg,
-                         "order ID `%s' already exists, and the request was 
not idempotent",
-                         order_id);
-        rv = TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_BAD_REQUEST, /* or conflict? 
*/
-                                         
TALER_EC_PROPOSAL_STORE_DB_ERROR_ALREADY_EXISTS,
-                                         msg);
-        GNUNET_free (msg);
+        MHD_RESULT ret;
+
+        ret = TALER_MHD_reply_with_error (connection,
+                                          MHD_HTTP_BAD_REQUEST, /* or 
conflict? */
+                                          
TALER_EC_PROPOSAL_STORE_DB_ERROR_ALREADY_EXISTS,
+                                          order_id);
         GNUNET_JSON_parse_free (spec);
-        return rv;
+        return ret;
       }
     }
   }
@@ -498,7 +493,7 @@ execute_order (struct MHD_Connection *connection,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_PROPOSAL_STORE_DB_ERROR_SOFT,
-                                         "serialization error, maybe try 
again?");
+                                         NULL);
     }
 
     /* If we have a product that has insufficient quantities,
@@ -536,7 +531,7 @@ execute_order (struct MHD_Connection *connection,
       connection,
       MHD_HTTP_INTERNAL_SERVER_ERROR,
       TALER_EC_PROPOSAL_STORE_DB_ERROR_HARD,
-      "Failed to store the order in the DB");
+      NULL);
   }
   /* DB transaction succeeded, generate positive response */
   {
@@ -604,11 +599,11 @@ patch_order (struct MHD_Connection *connection,
     tm_info = localtime (&timer);
     if (NULL == tm_info)
     {
-      return TALER_MHD_reply_with_error
-               (connection,
-               MHD_HTTP_INTERNAL_SERVER_ERROR,
-               TALER_EC_PROPOSAL_NO_LOCALTIME,
-               "failed to determine local time");
+      return TALER_MHD_reply_with_error (
+        connection,
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_PROPOSAL_NO_LOCALTIME,
+        NULL);
     }
     off = strftime (buf,
                     sizeof (buf),
@@ -926,7 +921,7 @@ add_payment_details (struct MHD_Connection *connection,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_NOT_FOUND,
                                        
TALER_EC_PROPOSAL_INSTANCE_CONFIGURATION_LACKS_WIRE,
-                                       "No wire method configured for 
instance");
+                                       payment_target);
   }
   GNUNET_assert (0 ==
                  json_object_set_new (order,
diff --git a/src/backend/taler-merchant-httpd_private-post-products-ID-lock.c 
b/src/backend/taler-merchant-httpd_private-post-products-ID-lock.c
index d7f87c7..5758362 100644
--- a/src/backend/taler-merchant-httpd_private-post-products-ID-lock.c
+++ b/src/backend/taler-merchant-httpd_private-post-products-ID-lock.c
@@ -82,8 +82,9 @@ TMH_private_post_products_ID_lock (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_PRODUCTS_PATCH_DB_COMMIT_HARD_ERROR,
-                                       "Failed to execute DB transaction to 
lock product");
+                                       NULL);
   case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_INTERNAL_INVARIANT_FAILURE,
@@ -97,12 +98,12 @@ TMH_private_post_products_ID_lock (const struct 
TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          
TALER_EC_PRODUCTS_LOCK_UNKNOWN_PRODUCT,
-                                         "The specified product is unknown");
+                                         product_id);
     else
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_GONE,
                                          
TALER_EC_PRODUCTS_LOCK_INSUFFICIENT_STOCKS,
-                                         "The specified product is out of 
stock");
+                                         product_id);
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     return TALER_MHD_reply_static (connection,
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/backend/taler-merchant-httpd_private-post-products.c 
b/src/backend/taler-merchant-httpd_private-post-products.c
index b7d240a..88c5908 100644
--- a/src/backend/taler-merchant-httpd_private-post-products.c
+++ b/src/backend/taler-merchant-httpd_private-post-products.c
@@ -166,7 +166,7 @@ TMH_private_post_products (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_PRODUCTS_POST_DB_START_ERROR,
-                                         "Failed to start transaction");
+                                         NULL);
     }
     qs = TMH_db->lookup_product (TMH_db->cls,
                                  mi->settings.id,
@@ -203,7 +203,7 @@ TMH_private_post_products (const struct TMH_RequestHandler 
*rh,
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_CONFLICT,
                                            
TALER_EC_PRODUCTS_POST_CONFLICT_PRODUCT_EXISTS,
-                                           "different product exists under 
this product ID");
+                                           product_id);
       }
     }
 
@@ -225,14 +225,13 @@ retry:
   }
   GNUNET_JSON_parse_free (spec);
   if (qs < 0)
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       (GNUNET_DB_STATUS_SOFT_ERROR == qs)
-                                       ?
-                                       
TALER_EC_PRODUCTS_POST_DB_COMMIT_SOFT_ERROR
-                                       :
-                                       
TALER_EC_PRODUCTS_POST_DB_COMMIT_HARD_ERROR,
-                                       "Failed to commit transaction");
+    return TALER_MHD_reply_with_error (
+      connection,
+      MHD_HTTP_INTERNAL_SERVER_ERROR,
+      (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+      ? TALER_EC_PRODUCTS_POST_DB_COMMIT_SOFT_ERROR
+      : TALER_EC_PRODUCTS_POST_DB_COMMIT_HARD_ERROR,
+      NULL);
   return TALER_MHD_reply_static (connection,
                                  MHD_HTTP_NO_CONTENT,
                                  NULL,
diff --git 
a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c 
b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
index 2181f1e..da5a315 100644
--- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
+++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
@@ -81,37 +81,31 @@ authorize_tip (const struct TMH_RequestHandler *rh,
   /* handle errors */
   if (TALER_EC_NONE != ec)
   {
-    unsigned int rc;
-    const char *msg;
+    unsigned int http_status;
 
     switch (ec)
     {
     case TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS:
-      rc = MHD_HTTP_PRECONDITION_FAILED;
-      msg = "Failed to approve tip: merchant has insufficient tipping funds";
+      http_status = MHD_HTTP_PRECONDITION_FAILED;
       break;
     case TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED:
-      msg = "Failed to approve tip: merchant's tipping reserve expired";
-      rc = MHD_HTTP_GONE;
+      http_status = MHD_HTTP_GONE;
       break;
     case TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN:
-      msg = "Failed to approve tip: merchant's tipping reserve does not exist";
-      rc = MHD_HTTP_SERVICE_UNAVAILABLE;
+      http_status = MHD_HTTP_SERVICE_UNAVAILABLE;
       break;
     case TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND:
-      msg = "Failed to approve tip: merchant's tipping reserve does not exist";
-      rc = MHD_HTTP_NOT_FOUND;
+      http_status = MHD_HTTP_NOT_FOUND;
       break;
     default:
-      rc = MHD_HTTP_INTERNAL_SERVER_ERROR;
-      msg = "Failed to approve tip: internal server error";
+      http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
       break;
     }
 
     return TALER_MHD_reply_with_error (connection,
-                                       rc,
+                                       http_status,
                                        ec,
-                                       msg);
+                                       NULL);
   }
 
   /* generate success response */
@@ -173,7 +167,7 @@ TMH_private_post_reserves_ID_authorize_tip (const struct 
TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_RESERVES_INVALID_RESERVE_PUB,
-                                       "reserve public key malformed");
+                                       hc->infix);
   }
   return authorize_tip (rh,
                         connection,
diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.c 
b/src/backend/taler-merchant-httpd_private-post-reserves.c
index 3e72650..4f78b89 100644
--- a/src/backend/taler-merchant-httpd_private-post-reserves.c
+++ b/src/backend/taler-merchant-httpd_private-post-reserves.c
@@ -284,7 +284,7 @@ TMH_private_post_reserves (const struct TMH_RequestHandler 
*rh,
     return TALER_MHD_reply_with_error (connection,
                                        rc->http_status,
                                        rc->ec,
-                                       "Exchange does not support wire 
method");
+                                       NULL);
   }
   {
     struct TALER_ReservePublicKeyP reserve_pub;
@@ -310,7 +310,7 @@ TMH_private_post_reserves (const struct TMH_RequestHandler 
*rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_RESERVES_POST_DB_COMMIT_HARD_ERROR,
-                                         "Failed to commit transaction");
+                                         NULL);
     return TALER_MHD_reply_json_pack (connection,
                                       MHD_HTTP_OK,
                                       "{s:o,s:s}",
diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.c 
b/src/backend/taler-merchant-httpd_private-post-transfers.c
index 45b6742..34c32d1 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.c
@@ -308,7 +308,8 @@ check_transfer (void *cls,
           "code",
           (json_int_t) TALER_EC_POST_TRANSFERS_CONFLICTING_REPORTS,
           "hint",
-          "disagreement about deposit valuation",
+          TALER_ErrorCode_get_hint (
+            TALER_EC_POST_TRANSFERS_CONFLICTING_REPORTS),
           "exchange_url",
           exchange_url,
           "deposit_timestamp",
@@ -404,7 +405,8 @@ check_wire_fee (struct PostTransfersContext *ptc,
     TALER_MHD_make_json_pack (
       "{s:I, s:s, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
       "code", (json_int_t) TALER_EC_POST_TRANSFERS_JSON_BAD_WIRE_FEE,
-      "hint", "exchange provided conflicting wire fee information",
+      "hint",
+      TALER_ErrorCode_get_hint (TALER_EC_POST_TRANSFERS_JSON_BAD_WIRE_FEE),
       "wire_fee", TALER_JSON_from_amount (wire_fee),
       "execution_time", GNUNET_JSON_from_time_abs (execution_time),
       "expected_wire_fee", TALER_JSON_from_amount (&expected_fee),
@@ -547,7 +549,8 @@ process_transfer_with_exchange (void *cls,
         (NULL != hr->reply)
         ? "{s:s, s:I, s:I, s:I, s:O}"
         : "{s:s, s:I, s:I, s:I}",
-        "hint", "failed to obtain meta-data from exchange",
+        "hint", TALER_ErrorCode_get_hint (
+          TALER_EC_POST_TRANSFERS_EXCHANGE_KEYS_FAILURE),
         "code", (json_int_t) TALER_EC_POST_TRANSFERS_EXCHANGE_KEYS_FAILURE,
         "exchange_http_status", (json_int_t) hr->http_status,
         "exchange_code", (json_int_t) hr->ec,
@@ -923,7 +926,7 @@ queue:
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_POST_TRANSFERS_DB_LOOKUP_ERROR,
-                                         "Failed to query database about 
transfer details");
+                                         NULL);
     }
     if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
       goto fetch;
@@ -978,7 +981,7 @@ queue:
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_POST_TRANSFERS_DB_LOOKUP_ERROR,
-                                           "Failed to query database about 
transfer details");
+                                           NULL);
       }
 
       deposit_sums = json_array ();
@@ -1017,7 +1020,7 @@ fetch:
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_POST_TRANSFERS_DB_STORE_ERROR,
-                                       "Fail to update database with transfer 
record");
+                                       NULL);
   }
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
   {
@@ -1034,7 +1037,7 @@ fetch:
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_NOT_FOUND,
                                          
TALER_EC_POST_TRANSFERS_ACCOUNT_NOT_FOUND,
-                                         "Instance does not have this bank 
account");
+                                         ptc->payto_uri);
   }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/lib/merchant_api_merchant_get_order.c 
b/src/lib/merchant_api_merchant_get_order.c
index a339c69..21e60ef 100644
--- a/src/lib/merchant_api_merchant_get_order.c
+++ b/src/lib/merchant_api_merchant_get_order.c
@@ -234,7 +234,7 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle 
*omgh,
         GNUNET_JSON_spec_uint32 ("code",
                                  &c32),
         GNUNET_JSON_spec_string ("hint",
-                                 &wr->hint),
+                                 &wr->hint), /* FIXME: should return "detail" 
instead! */
         GNUNET_JSON_spec_uint32 ("exchange_ec",
                                  &eec32),
         GNUNET_JSON_spec_uint32 ("exchange_hc",

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]