diff --git a/doc/Makefile.am b/doc/Makefile.am
index 9481e41..94c0ef4 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -12,7 +12,6 @@ arch.jpg: arch.dot
 AM_MAKEINFOHTMLFLAGS = --no-split --css-ref=docstyle.css --css-ref=brown-paper.css
 
 man_MANS = \
-  taler-merchant-tip-enable.1 \
   taler-merchant-generate-payments.1 \
   taler-merchant-httpd.1
 
diff --git a/doc/manual.texi b/doc/manual.texi
index 3c7c3c0..b8e2c6c 100644
--- a/doc/manual.texi
+++ b/doc/manual.texi
@@ -1125,36 +1125,16 @@ Make your wire transfer and (optionally) check at
 ``https://exchange:443/reserve/status/reserve_pub=QPE24X...''
 whether your transfer has arrived at the exchange.
 @c FIXME: we should create a nicer tool to do this check!
-Once the funds have arrived, you can now enable tipping using:
 
-@example
-$ taler-merchant-tip-enable \
-    --amount=AMOUNT \
-    --backend=BACKEND_URI \
-    --credit-uuid=CREDIT_UUID \
-    --instance=INSTANCE \
-    --expiration=EXPIRATION
-@end example
-For ``AMOUNT'', specify the amount you transferred in the usual Taler
-format of ``CURRENCY:VALUE[.FRACTION]'', i.e. ``EUR:50''.  The
-``BACKEND_URI'' should be the URI where your Taler merchant backend is
-running.  For ``CREDIT_UUID'', you need to specify a unique number
-that identifies your wire transfer.  You may have gotten one from your
-bank, or you can just make one up! The important thing is that you
-must never use the same UUID twice, except to repeat a failed command.
-For INSTANCE, specify the backend instance (i.e. ``default'').
-Finally, for EXPIRATION, pick a date two weeks after the wire
-transfer, unless you know that the exchange that is being used has a
-different period for closing reserves.  The format @code{YYYY-MM-DD}
-is accepted.
-
-Note that an exchange will typically close a reserve after two weeks,
+Once the funds have arrived, you can start to use the reserve
+for tipping.
+
+Note that an exchange will typically close a reserve after four weeks,
 wiring all remaining funds back to the sender's account.  Thus, you
 should plan to wire funds corresponding to a campaign of about two
 weeks to the exchange initially. If your campaign runs longer, you
-should wire further funds to the reserve every week to prevent it from
-expiring.  You need to run the ``taler-merchant-tip-enable'' command
-each time after you wire more funds to the reserve.
+should wire further funds to the reserve every other week to prevent
+it from expiring.
 
 
 @subsection Authorize a tip
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 648f2af..a83a185 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -23,7 +23,6 @@ taler_merchant_httpd_SOURCES = \
   taler-merchant-httpd_pay.c taler-merchant-httpd_pay.h \
   taler-merchant-httpd_history.c taler-merchant-httpd_history.h \
   taler-merchant-httpd_tip-authorize.c taler-merchant-httpd_tip-authorize.h \
-  taler-merchant-httpd_tip-enable.c taler-merchant-httpd_tip-enable.h \
   taler-merchant-httpd_tip-pickup.c taler-merchant-httpd_tip-pickup.h \
   taler-merchant-httpd_tip-query.c taler-merchant-httpd_tip-query.h \
   taler-merchant-httpd_track-transaction.c taler-merchant-httpd_track-transaction.h \
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 2bf927d..af32f27 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -245,12 +245,6 @@ url_handler (void *cls,
       { "/tip-pickup", NULL, "application/json",
         "Only POST is allowed", 0,
         &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED},
-      { "/tip-enable", MHD_HTTP_METHOD_POST, "text/plain",
-        NULL, 0,
-        &MH_handler_tip_enable, MHD_HTTP_OK},
-      { "/tip-enable", NULL, "application/json",
-        "Only POST is allowed", 0,
-        &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED},
       { "/tip-query", MHD_HTTP_METHOD_GET, "text/plain",
         NULL, 0,
         &MH_handler_tip_query, MHD_HTTP_OK},
diff --git a/src/backend/taler-merchant-httpd_tip-authorize.c b/src/backend/taler-merchant-httpd_tip-authorize.c
index c55b41b..aaa62c4 100644
--- a/src/backend/taler-merchant-httpd_tip-authorize.c
+++ b/src/backend/taler-merchant-httpd_tip-authorize.c
@@ -29,13 +29,8 @@
 #include "taler-merchant-httpd_tip-authorize.h"
 
 
-/**
- * Information we keep for individual calls
- * to requests that parse JSON, but keep no other state.
- */
-struct TMH_JsonParseContext
+struct TipAuthContext
 {
-
   /**
    * This field MUST be first.
    * FIXME: Explain why!
@@ -46,21 +41,218 @@ struct TMH_JsonParseContext
    * Placeholder for #TMH_PARSE_post_json() to keep its internal state.
    */
   void *json_parse_context;
+
+  /**
+   * HTTP connection we are handling.
+   */
+  struct MHD_Connection *connection;
+
+  /**
+   * Tip amount requested.
+   */
+  struct TALER_Amount amount;
+
+  /**
+   * Merchant instance to use.
+   */
+  const char *instance;
+
+  /**
+   * Justification to use.
+   */
+  const char *justification;
+
+  /**
+   * Pickup URL to use.
+   */
+  const char *pickup_url;
+
+  /**
+   * URL to navigate to after tip.
+   */
+  const char *next_url;
+
+  /**
+   * JSON request received.
+   */
+  json_t *root;
+
+  /**
+   * Handle to pending /reserve/status request.
+   */
+  struct TALER_EXCHANGE_ReserveStatusHandle *rsh;
+
+  /**
+   * Handle for operation to obtain exchange handle.
+   */
+  struct TMH_EXCHANGES_FindOperation *fo;
+
+  /**
+   * Private key used by this merchant for the tipping reserve.
+   */
+  struct TALER_ReservePrivateKeyP reserve_priv;
+
+  /**
+   * Flag set to #GNUNET_YES when we have tried /reserve/status of the
+   * tipping reserve already.
+   */
+  int checked_status;
+
+  /**
+   * Flag set to #GNUNET_YES when we have parsed the incoming JSON already.
+   */
+  int parsed_json;
 };
 
 
 /**
- * Custom cleanup routine for a `struct TMH_JsonParseContext`.
+ * Custom cleanup routine for a `struct TipAuthContext`.
  *
  * @param hc the `struct TMH_JsonParseContext` to clean up.
  */
 static void
-json_parse_cleanup (struct TM_HandlerContext *hc)
+cleanup_tac (struct TM_HandlerContext *hc)
+{
+  struct TipAuthContext *tac = (struct TipAuthContext *) hc;
+
+  if (NULL != tac->root)
+  {
+    json_decref (tac->root);
+    tac->root = NULL;
+  }
+  if (NULL != tac->rsh)
+  {
+    TALER_EXCHANGE_reserve_status_cancel (tac->rsh);
+    tac->rsh = NULL;
+  }
+  if (NULL != tac->fo)
+  {
+    TMH_EXCHANGES_find_exchange_cancel (tac->fo);
+    tac->fo = NULL;
+  }
+  TMH_PARSE_post_cleanup_callback (tac->json_parse_context);
+  GNUNET_free (tac);
+}
+
+
+/**
+ * Function called with the result of the /reserve/status request
+ * for the tipping reserve.  Update our database balance with the
+ * result.
+ *
+ * @param cls closure with a `struct TipAuthContext *'
+ * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
+ *                    0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
+ * @param[in] json original response in JSON format (useful only for diagnostics)
+ * @param balance current balance in the reserve, NULL on error
+ * @param history_length number of entries in the transaction history, 0 on error
+ * @param history detailed transaction history, NULL on error
+ */
+static void
+handle_status (void *cls,
+               unsigned int http_status,
+               enum TALER_ErrorCode ec,
+               const json_t *json,
+               const struct TALER_Amount *balance,
+               unsigned int history_length,
+               const struct TALER_EXCHANGE_ReserveHistory *history)
+{
+  struct TipAuthContext *tac = cls;
+  struct GNUNET_TIME_Relative idle_reserve_expiration_time;
+
+  if (MHD_HTTP_OK != http_status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Failed to obtain tipping reserve status from exchange (%u/%d)\n"),
+                http_status,
+                ec);
+    MHD_resume_connection (tac->connection);
+    return;
+  }
+
+  /* TODO: get this from the exchange! (See #5254.) */
+  idle_reserve_expiration_time = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_WEEKS,
+                                                                4);
+
+  /* Update DB based on status! */
+  for (unsigned int i=0;i<history_length;i++)
+  {
+    switch (history[i].type)
+    {
+    case TALER_EXCHANGE_RTT_DEPOSIT:
+      {
+        enum GNUNET_DB_QueryStatus qs;
+        struct GNUNET_HashCode uuid;
+        struct GNUNET_TIME_Absolute expiration;
+
+        expiration = GNUNET_TIME_absolute_add (history[i].details.in_details.timestamp,
+                                               idle_reserve_expiration_time);
+        GNUNET_CRYPTO_hash (history[i].details.in_details.wire_reference,
+                            history[i].details.in_details.wire_reference_size,
+                            &uuid);
+        qs = db->enable_tip_reserve (db->cls,
+                                     &tac->reserve_priv,
+                                     &uuid,
+                                     &history[i].amount,
+                                     expiration);
+        if (0 > qs)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                      _("Database error updating tipping reserve status: %d\n"),
+                      qs);
+        }
+      }
+    case TALER_EXCHANGE_RTT_WITHDRAWAL:
+      /* expected */
+      break;
+    case TALER_EXCHANGE_RTT_PAYBACK:
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("Encountered unsupported /payback operation on tipping reserve\n"));
+      break;
+    case TALER_EXCHANGE_RTT_CLOSE:
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("Exchange closed reserve (due to expiration), balance calulation is likely wrong. Please create a fresh reserve.\n"));
+      break;
+    }
+  }
+  /* Finally, resume processing */
+  MHD_resume_connection (tac->connection);
+}
+
+
+/**
+ * Function called with the result of a #TMH_EXCHANGES_find_exchange()
+ * operation.
+ *
+ * @param cls closure with a `struct TipAuthContext *'
+ * @param eh handle to the exchange context
+ * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if not available
+ * @param exchange_trusted #GNUNET_YES if this exchange is trusted by config
+ */
+static void
+exchange_cont (void *cls,
+               struct TALER_EXCHANGE_Handle *eh,
+               const struct TALER_Amount *wire_fee,
+               int exchange_trusted)
 {
-  struct TMH_JsonParseContext *jpc = (struct TMH_JsonParseContext *) hc;
+  struct TipAuthContext *tac = cls;
+  struct TALER_ReservePublicKeyP reserve_pub;
 
-  TMH_PARSE_post_cleanup_callback (jpc->json_parse_context);
-  GNUNET_free (jpc);
+  tac->fo = NULL;
+  if (NULL == eh)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Failed to contact exchange configured for tipping!\n"));
+    MHD_resume_connection (tac->connection);
+    return;
+  }
+  GNUNET_CRYPTO_eddsa_key_get_public (&tac->reserve_priv.eddsa_priv,
+                                      &reserve_pub.eddsa_pub);
+  tac->rsh = TALER_EXCHANGE_reserve_status (eh,
+                                            &reserve_pub,
+                                            &handle_status,
+                                            tac);
 }
 
 
@@ -81,66 +273,63 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
                           const char *upload_data,
                           size_t *upload_data_size)
 {
-  struct MerchantInstance *mi;
+  struct TipAuthContext *tac;
   int res;
-  struct TALER_Amount amount;
-  const char *instance;
-  const char *justification;
-  const char *pickup_url;
-  const char *next_url;
-  struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("amount", &amount),
-    GNUNET_JSON_spec_string ("instance", &instance),
-    GNUNET_JSON_spec_string ("justification", &justification),
-    GNUNET_JSON_spec_string ("pickup_url", &pickup_url),
-    GNUNET_JSON_spec_string ("next_url", &next_url),
-    GNUNET_JSON_spec_end()
-  };
-  json_t *root;
+  struct MerchantInstance *mi;
+  enum TALER_ErrorCode ec;
   struct GNUNET_TIME_Absolute expiration;
   struct GNUNET_HashCode tip_id;
-  struct TMH_JsonParseContext *ctx;
-  enum TALER_ErrorCode ec;
 
   if (NULL == *connection_cls)
   {
-    ctx = GNUNET_new (struct TMH_JsonParseContext);
-    ctx->hc.cc = &json_parse_cleanup;
-    *connection_cls = ctx;
+    tac = GNUNET_new (struct TipAuthContext);
+    tac->hc.cc = &cleanup_tac;
+    *connection_cls = tac;
   }
   else
   {
-    ctx = *connection_cls;
+    tac = *connection_cls;
   }
   res = TMH_PARSE_post_json (connection,
-                             &ctx->json_parse_context,
+                             &tac->json_parse_context,
                              upload_data,
                              upload_data_size,
-                             &root);
+                             &tac->root);
   if (GNUNET_SYSERR == res)
     return MHD_NO;
   /* the POST's body has to be further fetched */
   if ( (GNUNET_NO == res) ||
-       (NULL == root) )
+       (NULL == tac->root) )
     return MHD_YES;
 
-  res = TMH_PARSE_json_data (connection,
-                             root,
-                             spec);
-  if (GNUNET_YES != res)
+  if (GNUNET_NO == tac->parsed_json)
   {
-    GNUNET_break_op (0);
-    json_decref (root);
-    return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+    struct GNUNET_JSON_Specification spec[] = {
+      TALER_JSON_spec_amount ("amount", &tac->amount),
+      GNUNET_JSON_spec_string ("instance", &tac->instance),
+      GNUNET_JSON_spec_string ("justification", &tac->justification),
+      GNUNET_JSON_spec_string ("pickup_url", &tac->pickup_url),
+      GNUNET_JSON_spec_string ("next_url", &tac->next_url),
+      GNUNET_JSON_spec_end()
+    };
+
+    res = TMH_PARSE_json_data (connection,
+                               tac->root,
+                               spec);
+    if (GNUNET_YES != res)
+    {
+      GNUNET_break_op (0);
+      return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+    }
+    tac->parsed_json = GNUNET_YES;
   }
 
-  mi = TMH_lookup_instance (instance);
+  mi = TMH_lookup_instance (tac->instance);
   if (NULL == mi)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Instance `%s' not configured\n",
-                instance);
-    json_decref (root);  
+                tac->instance);
     return TMH_RESPONSE_reply_not_found (connection,
 					 TALER_EC_TIP_AUTHORIZE_INSTANCE_UNKNOWN,
 					 "unknown instance");
@@ -149,19 +338,35 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Instance `%s' not configured for tipping\n",
-                instance);
-    json_decref (root);
+                tac->instance);
     return TMH_RESPONSE_reply_not_found (connection,
 					 TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP,
 					 "exchange for tipping not configured for the instance");
   }
+  tac->reserve_priv = mi->tip_reserve;
   ec = db->authorize_tip (db->cls,
-                          justification,
-                          &amount,
+                          tac->justification,
+                          &tac->amount,
                           &mi->tip_reserve,
 			  mi->tip_exchange,
                           &expiration,
                           &tip_id);
+  /* If we have insufficient funds according to OUR database,
+     check with exchange to see if the reserve has been topped up
+     in the meantime (or if tips were not withdrawn yet). */
+  if ( (TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS == ec) &&
+       (GNUNET_NO == tac->checked_status) )
+  {
+    MHD_suspend_connection (connection);
+    tac->checked_status = GNUNET_YES;
+    tac->fo = TMH_EXCHANGES_find_exchange (mi->tip_exchange,
+                                           NULL,
+                                           &exchange_cont,
+                                           tac);
+    return MHD_YES;
+  }
+
+  /* handle irrecoverable errors */
   if (TALER_EC_NONE != ec)
   {
     unsigned int rc;
@@ -184,43 +389,31 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
       rc = MHD_HTTP_INTERNAL_SERVER_ERROR;
       break;
     }
-    json_decref (root);      
     return TMH_RESPONSE_reply_rc (connection,
-				  rc,
-				  ec,
-				  "Database error approving tip");
+                                  rc,
+                                  ec,
+                                  "Database error approving tip");
   }
-  if (0)
+
+  /* generate success response */
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Insufficient funds to authorize tip over `%s' at instance `%s'\n",
-                TALER_amount2s (&amount),
-                instance);
-    json_decref (root);
-    return TMH_RESPONSE_reply_rc (connection,
-                                  MHD_HTTP_PRECONDITION_FAILED,
-                                  TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS,
-                                  "Insufficient funds for tip");
+    json_t *tip_token;
+
+    tip_token = json_pack ("{s:o, s:o, s:o, s:s, s:s, s:s}",
+                           "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
+                           "expiration", GNUNET_JSON_from_time_abs (expiration),
+                           "amount", TALER_JSON_from_amount (&tac->amount),
+                           "exchange_url", mi->tip_exchange,
+                           "next_url", tac->next_url,
+                           "pickup_url", tac->pickup_url);
+    return TMH_RESPONSE_reply_json_pack (connection,
+                                         MHD_HTTP_OK,
+                                         "{s:o, s:o, s:s, s:o}",
+                                         "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
+                                         "expiration", GNUNET_JSON_from_time_abs (expiration),
+                                         "exchange_url", mi->tip_exchange,
+                                         "tip_token", tip_token);
   }
-  json_t *tip_token = json_pack ("{s:o, s:o, s:o, s:s, s:s, s:s}",
-                                 "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
-                                 "expiration", GNUNET_JSON_from_time_abs (expiration),
-                                 "amount", TALER_JSON_from_amount (&amount),
-                                 "exchange_url", mi->tip_exchange,
-                                 "next_url", next_url,
-                                 "pickup_url", pickup_url);
-  char *tip_token_str = json_dumps (tip_token,  JSON_ENSURE_ASCII | JSON_COMPACT);
-  json_decref (tip_token);
-  json_decref (root);
-  int ret = TMH_RESPONSE_reply_json_pack (connection,
-                                          MHD_HTTP_OK,
-                                          "{s:o, s:o, s:s, s:s}",
-                                          "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
-                                          "expiration", GNUNET_JSON_from_time_abs (expiration),
-                                          "exchange_url", mi->tip_exchange,
-                                          "tip_token", tip_token_str);
-  GNUNET_free (tip_token_str);
-  return ret;
 }
 
 /* end of taler-merchant-httpd_tip-authorize.c */
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 51db135..81f1219 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -309,7 +309,7 @@ struct TALER_MERCHANT_PayCoin
    * Amount this coin is to contribute (without fee).
    */
   struct TALER_Amount amount_without_fee;
-  
+
   /**
    * Fee the exchange charges for refunds of this coin.
    */
@@ -317,7 +317,7 @@ struct TALER_MERCHANT_PayCoin
 
   /**
    * URL of the exchange that issued @e coin_priv.
-   */ 
+   */
   const char *exchange_url;
 
 };
@@ -373,12 +373,12 @@ struct TALER_MERCHANT_RefundEntry
 {
   /**
    * Merchant signature affirming the refund.
-   */ 
+   */
   struct TALER_MerchantSignatureP merchant_sig;
 
   /**
    * Public key of the refunded coin.
-   */ 
+   */
   struct TALER_CoinSpendPublicKeyP coin_pub;
 
   /**
@@ -789,71 +789,6 @@ void
 TALER_MERCHANT_history_cancel (struct TALER_MERCHANT_HistoryOperation *ho);
 
 
-/* ********************** /tip-enable ************************* */
-
-
-/**
- * Handle for a /tip-enable operation.
- */
-struct TALER_MERCHANT_TipEnableOperation;
-
-
-/**
- * Callback for a /tip-enable request.  Returns the result of
- * the operation.
- *
- * @param cls closure
- * @param http_status HTTP status returned by the merchant backend
- * @param ec taler-specific error code
- */
-typedef void
-(*TALER_MERCHANT_TipEnableCallback) (void *cls,
-                                     unsigned int http_status,
-                                     enum TALER_ErrorCode ec);
-
-
-/**
- * Issue a /tip-enable request to the backend.  Informs the backend
- * that a reserve is now available for tipping.  Note that the
- * respective @a reserve_priv must also be bound to one or more
- * instances (together with the URL of the exchange) via the backend's
- * configuration file before it can be used.  Usually, the process
- * is that one first configures an exchange and a @a reserve_priv for
- * an instance, and then enables (or re-enables) the reserve by
- * performing wire transfers and informs the backend about it using
- * this API.
- *
- * @param ctx execution context
- * @param backend_url base URL of the merchant backend
- * @param amount amount that was credited to the reserve
- * @param expiration when will the reserve expire
- * @param reserve_priv private key of the reserve
- * @param credit_uuid unique ID of the wire transfer
- * @param enable_cb callback which will work the response gotten from the backend
- * @param enable_cb_cls closure to pass to @a enable_cb
- * @return handle for this operation, NULL upon errors
- */
-struct TALER_MERCHANT_TipEnableOperation *
-TALER_MERCHANT_tip_enable (struct GNUNET_CURL_Context *ctx,
-                           const char *backend_url,
-                           const struct TALER_Amount *amount,
-                           struct GNUNET_TIME_Absolute expiration,
-                           const struct TALER_ReservePrivateKeyP *reserve_priv,
-                           const struct GNUNET_HashCode *credit_uuid,
-                           TALER_MERCHANT_TipEnableCallback enable_cb,
-                           void *enable_cb_cls);
-
-
-
-/**
- * Cancel a pending /tip-enable request
- *
- * @param teo handle from the operation to cancel
- */
-void
-TALER_MERCHANT_tip_enable_cancel (struct TALER_MERCHANT_TipEnableOperation *teo);
-
-
 /* ********************** /tip-authorize ********************** */
 
 /**
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 5f46122..4c6d5f8 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -18,7 +18,6 @@ libtalermerchant_la_SOURCES = \
   merchant_api_proposal.c \
   merchant_api_pay.c \
   merchant_api_tip_authorize.c \
-  merchant_api_tip_enable.c \
   merchant_api_tip_pickup.c \
   merchant_api_track_transaction.c \
   merchant_api_track_transfer.c \
diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c
index b09d78a..a51ac2e 100644
--- a/src/lib/test_merchant_api.c
+++ b/src/lib/test_merchant_api.c
@@ -175,14 +175,14 @@ enum OpCode
 
   /**
    * Resume pay operation with additional coins.
-   */ 
+   */
   OC_PAY_AGAIN,
-  
+
   /**
    * Abort payment with coins, requesting refund.
    */
   OC_PAY_ABORT,
-  
+
   /**
    * Abort payment with coins, executing refund.
    */
@@ -233,11 +233,6 @@ enum OpCode
    */
   OC_REFUND_LOOKUP,
 
-  /**
-   * Start a reserve for tipping.
-   */
-  OC_TIP_ENABLE,
-
   /**
    * Authorize a tip.
    */
@@ -551,12 +546,12 @@ struct Command
        */
       const char *amount_without_fee;
 
-      /** 
+      /**
        * Refund fee to use for each coin (only relevant if we
        * exercise /pay's abort functionality).
        */
       const char *refund_fee;
-      
+
       /**
        * Pay handle while operation is running.
        */
@@ -594,7 +589,7 @@ struct Command
        * Pay handle while operation is running.
        */
       struct TALER_MERCHANT_Pay *ph;
-      
+
     } pay_again;
 
     struct {
@@ -609,7 +604,7 @@ struct Command
        */
       struct TALER_MERCHANT_Pay *ph;
 
-      /** 
+      /**
        * Set in #pay_refund_cb to number of refunds obtained.
        */
       unsigned int num_refunds;
@@ -621,12 +616,12 @@ struct Command
 
       /**
        * Set to the hash of the original contract.
-       */ 
-      struct GNUNET_HashCode h_contract;      
+       */
+      struct GNUNET_HashCode h_contract;
 
       /**
        * Set to the merchant's public key.
-       */ 
+       */
       struct TALER_MerchantPublicKeyP merchant_pub;
 
     } pay_abort;
@@ -635,7 +630,7 @@ struct Command
 
       /**
        * Reference to the pay_abort command to be refunded.
-       */ 
+       */
       const char *abort_ref;
 
       /**
@@ -652,7 +647,7 @@ struct Command
        * Refund fee to expect.
        */
       const char *refund_fee;
-      
+
       /**
        * Handle to the refund operation.
        */
@@ -1870,7 +1865,7 @@ pay_again_cb (void *cls,
   }
   GNUNET_assert (NULL != (pref = find_command
 			  (is,
-			   cmd->details.pay_again.pay_ref)));    
+			   cmd->details.pay_again.pay_ref)));
   if (MHD_HTTP_OK == http_status)
   {
     struct PaymentResponsePS mr;
@@ -1882,7 +1877,7 @@ pay_again_cb (void *cls,
 				   &mr.h_contract_terms),
       GNUNET_JSON_spec_end ()
     };
-    
+
     GNUNET_assert (GNUNET_OK ==
         GNUNET_JSON_parse (obj,
                            spec,
@@ -2056,45 +2051,6 @@ track_transaction_cb (void *cls,
 }
 
 
-/**
- * Callback for a /tip-enable request.  Returns the result of
- * the operation.
- *
- * @param cls closure
- * @param http_status HTTP status returned by the merchant backend
- * @param ec taler-specific error code
- */
-static void
-tip_enable_cb (void *cls,
-               unsigned int http_status,
-               enum TALER_ErrorCode ec)
-{
-  struct InterpreterState *is = cls;
-  struct Command *cmd = &is->commands[is->ip];
-
-  cmd->details.tip_enable.teo = NULL;
-  if (cmd->expected_response_code != http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected response code %u to command %s\n",
-                http_status,
-                cmd->label);
-    fail (is);
-    return;
-  }
-  if (cmd->details.tip_enable.expected_ec != ec)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected error code %u to command %s\n",
-                ec,
-                cmd->label);
-    fail (is);
-    return;
-  }
-  next_command (is);
-}
-
-
 /**
  * Callback for a /tip-authorize request.  Returns the result of
  * the operation.
@@ -2553,13 +2509,6 @@ cleanup_state (struct InterpreterState *is)
         cmd->details.refund_lookup.rlo = NULL;
       }
       break;
-    case OC_TIP_ENABLE:
-      if (NULL != cmd->details.tip_enable.teo)
-      {
-        TALER_MERCHANT_tip_enable_cancel (cmd->details.tip_enable.teo);
-        cmd->details.tip_enable.teo = NULL;
-      }
-      break;
     case OC_TIP_AUTHORIZE:
       if (NULL != cmd->details.tip_authorize.tao)
       {
@@ -2626,7 +2575,7 @@ cleanup_state (struct InterpreterState *is)
  * Parse the @a coins specification and grow the @a pc
  * array with the coins found, updating @a npc.
  *
- * @param[in,out] pc pointer to array of coins found 
+ * @param[in,out] pc pointer to array of coins found
  * @param[in,out] npc length of array at @a pc
  * @param[in] coins string specifying coins to add to @a pc,
  *            clobbered in the process
@@ -2641,8 +2590,8 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
 	     struct InterpreterState *is,
 	     const struct Command *pref)
 {
-  char *token;  
-  
+  char *token;
+
   for (token = strtok (coins, ";");
        NULL != token;
        token = strtok (NULL, ";"))
@@ -2651,7 +2600,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
     char *ctok;
     unsigned int ci;
     struct TALER_MERCHANT_PayCoin *icoin;
-    
+
     /* Token syntax is "LABEL[/NUMBER]" */
     ctok = strchr (token, '/');
     ci = 0;
@@ -2692,7 +2641,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
     default:
       GNUNET_assert (0);
     }
-    
+
     GNUNET_assert (GNUNET_OK ==
 		   TALER_string_to_amount (pref->details.pay.amount_with_fee,
 					   &icoin->amount_with_fee));
@@ -2735,7 +2684,7 @@ pay_refund_cb (void *cls,
 {
   struct InterpreterState *is = cls;
   struct Command *cmd = &is->commands[is->ip];
-  
+
   cmd->details.pay_abort.ph = NULL;
   if (cmd->expected_response_code != http_status)
   {
@@ -2784,7 +2733,7 @@ abort_refund_cb (void *cls,
 {
   struct InterpreterState *is = cls;
   struct Command *cmd = &is->commands[is->ip];
-  
+
   cmd->details.pay_abort_refund.rh = NULL;
   if (cmd->expected_response_code != http_status)
   {
@@ -3289,7 +3238,7 @@ interpreter_run (void *cls)
       GNUNET_break (0);
       fail (is);
     }
-    break;    
+    break;
   case OC_PAY_ABORT:
     {
       struct TALER_MERCHANT_PayCoin *pc;
@@ -3420,7 +3369,7 @@ interpreter_run (void *cls)
       GNUNET_assert (ref->details.pay_abort.num_refunds >
 		     cmd->details.pay_abort_refund.num_coin);
       re = &ref->details.pay_abort.res[cmd->details.pay_abort_refund.num_coin];
-		     
+
       GNUNET_assert (GNUNET_OK ==
 		     TALER_string_to_amount
 		     (cmd->details.pay_abort_refund.refund_amount,
@@ -3650,83 +3599,6 @@ interpreter_run (void *cls)
       }
       break;
     }
-  case OC_TIP_ENABLE:
-    {
-      const struct Command *uuid_ref;
-      struct TALER_ReservePrivateKeyP reserve_priv;
-      struct GNUNET_TIME_Absolute expiration;
-
-      if (NULL != cmd->details.tip_enable.admin_add_incoming_ref)
-      {
-        ref = find_command (is,
-                            cmd->details.tip_enable.admin_add_incoming_ref);
-        GNUNET_assert (NULL != ref);
-        GNUNET_assert (OC_ADMIN_ADD_INCOMING == ref->oc);
-      }
-      else
-      {
-        ref = NULL;
-      }
-
-      /* Initialize 'credit_uuid' */
-      if (NULL != cmd->details.tip_enable.uuid_ref)
-      {
-        uuid_ref = find_command (is,
-                                 cmd->details.tip_enable.uuid_ref);
-        GNUNET_assert (NULL != uuid_ref);
-        GNUNET_assert (OC_TIP_ENABLE == uuid_ref->oc);
-        cmd->details.tip_enable.credit_uuid
-          = uuid_ref->details.tip_enable.credit_uuid;
-      }
-      else
-      {
-        uuid_ref = NULL;
-        GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
-                                    &cmd->details.tip_enable.credit_uuid,
-                                    sizeof (cmd->details.tip_enable.credit_uuid));
-      }
-
-      /* Initialize 'amount' */
-      if ( (NULL != ref) &&
-           (NULL == cmd->details.tip_enable.amount) )
-      {
-        GNUNET_assert (GNUNET_OK ==
-                       TALER_string_to_amount (ref->details.admin_add_incoming.amount,
-                                               &amount));
-      }
-      else
-      {
-        GNUNET_assert (NULL != cmd->details.tip_enable.amount);
-        GNUNET_assert (GNUNET_OK ==
-                       TALER_string_to_amount (cmd->details.tip_enable.amount,
-                                               &amount));
-      }
-      if (NULL == ref)
-        GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
-                                    &reserve_priv,
-                                    sizeof (reserve_priv));
-      /* Simply picked long enough for the test (we do not test expiration
-         behavior for now), should be short enough so that the reserve
-	 expires before the test is run again, so that we avoid old
-	 state messing up fresh runs. */
-      expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
-
-      if (NULL == (cmd->details.tip_enable.teo
-                   = TALER_MERCHANT_tip_enable
-                   (ctx,
-                    MERCHANT_URL,
-                    &amount,
-                    expiration,
-                    (ref != NULL) ? &ref->details.admin_add_incoming.reserve_priv : &reserve_priv,
-                    &cmd->details.tip_enable.credit_uuid,
-                    &tip_enable_cb,
-                    is)))
-      {
-        GNUNET_break (0);
-        fail (is);
-      }
-      break;
-    }
   case OC_TIP_AUTHORIZE:
     {
       GNUNET_assert (NULL != cmd->details.tip_authorize.amount);
@@ -4318,17 +4190,6 @@ run (void *cls)
       .details.check_bank_transfer.account_debit = 62,
       .details.check_bank_transfer.account_credit = EXCHANGE_ACCOUNT_NO
     },
-    { .oc = OC_TIP_ENABLE,
-      .label = "enable-tip-1",
-      .expected_response_code = MHD_HTTP_OK,
-      .details.tip_enable.admin_add_incoming_ref = "create-reserve-tip-1",
-      .details.tip_enable.amount = "EUR:5.01" },
-    /* Test incrementing active reserve balance */
-    { .oc = OC_TIP_ENABLE,
-      .label = "enable-tip-2",
-      .expected_response_code = MHD_HTTP_OK,
-      .details.tip_enable.admin_add_incoming_ref = "create-reserve-tip-1",
-      .details.tip_enable.amount = "EUR:5.01" },
     /* Authorize two tips */
     { .oc = OC_TIP_AUTHORIZE,
       .label = "authorize-tip-1",
@@ -4519,7 +4380,7 @@ run (void *cls)
       .details.pay.refund_fee = "EUR:0.01",
       .details.pay_again.pay_ref = "pay-fail-partial-double-10",
       .details.pay_again.coin_ref = "withdraw-coin-10a;withdraw-coin-10b" },
-    
+
     /* Run transfers. */
     { .oc = OC_RUN_AGGREGATOR,
       .label = "run-aggregator-10" },
@@ -4632,14 +4493,14 @@ run (void *cls)
       .details.pay_abort_refund.num_coin = 0,
       .details.pay_abort_refund.refund_amount = "EUR:5",
       .details.pay_abort_refund.refund_fee = "EUR:0.01" },
-    
+
     /* Run transfers. */
     { .oc = OC_RUN_AGGREGATOR,
       .label = "run-aggregator-11" },
     /* Check that there are no other unusual transfers */
     { .oc = OC_CHECK_BANK_TRANSFERS_EMPTY,
       .label = "check_bank_empty-11" },
-    
+
     /* end of testcase */
     { .oc = OC_END }
   };
diff --git a/src/merchant-tools/Makefile.am b/src/merchant-tools/Makefile.am
index 7811d04..4e68837 100644
--- a/src/merchant-tools/Makefile.am
+++ b/src/merchant-tools/Makefile.am
@@ -3,8 +3,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include
 
 bin_PROGRAMS = \
   taler-merchant-dbinit \
-  taler-merchant-generate-payments \
-  taler-merchant-tip-enable
+  taler-merchant-generate-payments
 
 taler_merchant_dbinit_SOURCES = \
   taler-merchant-dbinit.c
@@ -16,16 +15,6 @@ taler_merchant_dbinit_LDADD = \
   -ltalerutil \
   -ltalerpq
 
-taler_merchant_tip_enable_SOURCES = \
-  taler-merchant-tip-enable.c
-
-taler_merchant_tip_enable_LDADD = \
-  $(LIBGCRYPT_LIBS) \
-  $(top_builddir)/src/lib/libtalermerchant.la \
-  -lgnunetcurl \
-  -lgnunetutil \
-  -ltalerutil
-
 taler_merchant_generate_payments_SOURCES = \
   taler-merchant-generate-payments.c
 
