summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/taler-merchant-httpd.c55
-rw-r--r--src/backend/taler-merchant-httpd.h9
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c472
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c3
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-refund.c25
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-refund.h8
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c3
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c3
8 files changed, 108 insertions, 470 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index f65b4292..54b8d163 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -154,6 +154,24 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
+ * Holds data needed to determine when to resume a connection for
+ * GET /orders/$ORDER_ID
+ */
+struct ResumeData
+{
+ /**
+ * How much of the order has been refunded.
+ */
+ const struct TALER_Amount *refund_amount;
+
+ /**
+ * Whether the refunds for the order were obtained.
+ */
+ bool obtained;
+};
+
+
+/**
* Decrement reference counter of @a mi, and free if it hits zero.
*
* @param[in,out] mi merchant instance to update and possibly free
@@ -370,12 +388,30 @@ resume_operation (void *cls,
const struct GNUNET_HashCode *key,
void *value)
{
- const struct TALER_Amount *have_refund = cls;
+ const struct ResumeData *rd = cls;
struct TMH_SuspendedConnection *sc = value;
+ /* If the conditions are satisfied partially, turn them off for future
+ calls. */
+ if ( (sc->awaiting_refund_obtained) &&
+ (rd->obtained))
+ sc->awaiting_refund_obtained = false;
if ( (sc->awaiting_refund) &&
- ( (NULL == have_refund) ||
- (1 != TALER_amount_cmp (have_refund,
+ ( (NULL != rd->refund_amount) &&
+ (1 == TALER_amount_cmp (rd->refund_amount,
+ &sc->refund_expected)) ) )
+ sc->awaiting_refund = false;
+
+ if ( (sc->awaiting_refund_obtained) &&
+ (! rd->obtained))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Not awaking client, refunds not yet obtained\n");
+ return GNUNET_OK;
+ }
+ if ( (sc->awaiting_refund) &&
+ ( (NULL == rd->refund_amount) ||
+ (1 != TALER_amount_cmp (rd->refund_amount,
&sc->refund_expected)) ) )
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -405,14 +441,20 @@ resume_operation (void *cls,
*
* @param order_id the order that was paid or refunded
* @param mi the merchant instance where the payment or refund happened
- * @param have_refund refunded amount, NULL if there was no refund
+ * @param refund_amount refunded amount, if the trigger was a refund, otherwise NULL
+ * @param obtained if true, the wallet has obtained the refunds for the order
*/
void
TMH_long_poll_resume (const char *order_id,
const struct TMH_MerchantInstance *mi,
- const struct TALER_Amount *have_refund)
+ const struct TALER_Amount *refund_amount,
+ bool obtained)
{
struct GNUNET_HashCode key;
+ struct ResumeData rd = {
+ .refund_amount = refund_amount,
+ .obtained = obtained
+ };
compute_pay_key (order_id,
&mi->merchant_pub,
@@ -423,7 +465,7 @@ TMH_long_poll_resume (const char *order_id,
GNUNET_CONTAINER_multihashmap_get_multiple (payment_trigger_map,
&key,
&resume_operation,
- (void *) have_refund);
+ (void *) &rd);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%u operations remain suspended pending payment\n",
GNUNET_CONTAINER_multihashmap_size (payment_trigger_map));
@@ -447,6 +489,7 @@ do_shutdown (void *cls)
TMH_force_rc_resume ();
TMH_force_post_transfers_resume ();
TMH_force_tip_pickup_resume ();
+ TMH_force_wallet_refund_order_resume ();
if (NULL != mhd_task)
{
GNUNET_SCHEDULER_cancel (mhd_task);
diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h
index 8ee900b3..0d78312e 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -359,6 +359,11 @@ struct TMH_SuspendedConnection
*/
bool awaiting_refund;
+ /**
+ * Whether we're waiting for the refunds to be obtained.
+ */
+ bool awaiting_refund_obtained;
+
};
@@ -425,11 +430,13 @@ TMH_long_poll_suspend (const char *order_id,
* @param order_id the order that was paid or refunded
* @param mi the merchant instance where the payment or refund happened
* @param refund_amount refunded amount, if the trigger was a refund, otherwise NULL
+ * @param obtained if true, the wallet has obtained the refunds for the order
*/
void
TMH_long_poll_resume (const char *order_id,
const struct TMH_MerchantInstance *mi,
- const struct TALER_Amount *refund_amount);
+ const struct TALER_Amount *refund_amount,
+ bool obtained);
/**
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index d6a52f40..142ba999 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -35,97 +35,6 @@
*/
#define MAX_RETRIES 5
-/**
- * Information we keep for each coin to be refunded.
- */
-struct CoinRefund
-{
-
- /**
- * Kept in a DLL.
- */
- struct CoinRefund *next;
-
- /**
- * Kept in a DLL.
- */
- struct CoinRefund *prev;
-
- /**
- * Request to connect to the target exchange.
- */
- struct TMH_EXCHANGES_FindOperation *fo;
-
- /**
- * Handle for the refund operation with the exchange.
- */
- struct TALER_EXCHANGE_RefundHandle *rh;
-
- /**
- * Request this operation is part of.
- */
- struct GetOrderData *god;
-
- /**
- * URL of the exchange for this @e coin_pub.
- */
- char *exchange_url;
-
- /**
- * Fully reply from the exchange, only possibly set if
- * we got a JSON reply and a non-#MHD_HTTP_OK error code
- */
- json_t *exchange_reply;
-
- /**
- * When did the merchant grant the refund. To be used to group events
- * in the wallet.
- */
- struct GNUNET_TIME_Absolute execution_time;
-
- /**
- * Coin to refund.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Refund transaction ID to use.
- */
- uint64_t rtransaction_id;
-
- /**
- * Unique serial number identifying the refund.
- */
- uint64_t refund_serial;
-
- /**
- * Amount to refund.
- */
- struct TALER_Amount refund_amount;
-
- /**
- * Public key of the exchange affirming the refund.
- */
- struct TALER_ExchangePublicKeyP exchange_pub;
-
- /**
- * Signature of the exchange affirming the refund.
- */
- struct TALER_ExchangeSignatureP exchange_sig;
-
- /**
- * HTTP status from the exchange, #MHD_HTTP_OK if
- * @a exchange_pub and @a exchange_sig are valid.
- */
- unsigned int exchange_status;
-
- /**
- * HTTP error code from the exchange.
- */
- enum TALER_ErrorCode exchange_code;
-
-};
-
/**
* Context for the operation.
@@ -156,16 +65,6 @@ struct GetOrderData
struct GetOrderData *prev;
/**
- * Refunds for this order. Head of DLL.
- */
- struct CoinRefund *cr_head;
-
- /**
- * Refunds for this order. Tail of DLL.
- */
- struct CoinRefund *cr_tail;
-
- /**
* Context of the request.
*/
struct TMH_HandlerContext *hc;
@@ -653,144 +552,6 @@ send_pay_request (struct GetOrderData *god,
/**
- * Check if @a god has sub-activities still pending.
- *
- * @param god request to check
- * @return true if activities are still pending
- */
-static bool
-god_pending (struct GetOrderData *god)
-{
- for (struct CoinRefund *cr = god->cr_head;
- NULL != cr;
- cr = cr->next)
- {
- if ( (NULL != cr->fo) ||
- (NULL != cr->rh) )
- return true;
- }
- return false;
-}
-
-
-/**
- * Check if @a god is ready to be resumed, and if so, do it.
- *
- * @param god refund request to be possibly ready
- */
-static void
-check_resume_god (struct GetOrderData *god)
-{
- if (god_pending (god))
- return;
- GNUNET_CONTAINER_DLL_remove (god_head,
- god_tail,
- god);
- GNUNET_assert (god->suspended);
- god->suspended = false;
- MHD_resume_connection (god->sc.con);
- TMH_trigger_daemon ();
-}
-
-
-//#if 0
-/**
- * Callbacks of this type are used to serve the result of submitting a
- * refund request to an exchange.
- *
- * @param cls a `struct CoinRefund`
- * @param hr HTTP response data
- * @param exchange_pub exchange key used to sign refund confirmation
- * @param exchange_sig exchange's signature over refund
- */
-static void
-refund_cb (void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_ExchangeSignatureP *exchange_sig)
-{
- struct CoinRefund *cr = cls;
-
- cr->rh = NULL;
- cr->exchange_status = hr->http_status;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Exchange refund status for coin %s is %u\n",
- TALER_B2S (&cr->coin_pub),
- hr->http_status);
- if (MHD_HTTP_OK != hr->http_status)
- {
- cr->exchange_code = hr->ec;
- cr->exchange_reply = json_incref ((json_t*) hr->reply);
- }
- else
- {
- enum GNUNET_DB_QueryStatus qs;
-
- cr->exchange_pub = *exchange_pub;
- cr->exchange_sig = *exchange_sig;
- qs = TMH_db->insert_refund_proof (TMH_db->cls,
- cr->refund_serial,
- exchange_sig,
- exchange_pub);
- if (0 >= qs)
- {
- /* generally, this is relatively harmless for the merchant, but let's at
- least log this. */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to persist exchange response to /refund in database: %d\n",
- qs);
- }
- }
- check_resume_god (cr->god);
-}
-//#endif
-
-
-//#if 0
-/**
- * Function called with the result of a #TMH_EXCHANGES_find_exchange()
- * operation.
- *
- * @param cls a `struct CoinRefund *`
- * @param hr HTTP response details
- * @param eh handle to the exchange context
- * @param payto_uri payto://-URI of the exchange
- * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if not available
- * @param exchange_trusted true if this exchange is trusted by config
- */
-static void
-exchange_found_cb (void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- struct TALER_EXCHANGE_Handle *eh,
- const char *payto_uri,
- const struct TALER_Amount *wire_fee,
- bool exchange_trusted)
-{
- struct CoinRefund *cr = cls;
-
- (void) payto_uri;
- cr->fo = NULL;
- if (TALER_EC_NONE == hr->ec)
- {
- cr->rh = TALER_EXCHANGE_refund (eh,
- &cr->refund_amount,
- &cr->god->h_contract_terms,
- &cr->coin_pub,
- cr->rtransaction_id,
- &cr->god->hc->instance->merchant_priv,
- &refund_cb,
- cr);
- return;
- }
- cr->exchange_status = hr->http_status;
- cr->exchange_code = hr->ec;
- cr->exchange_reply = json_incref ((json_t*) hr->reply);
- check_resume_god (cr->god);
-}
-//#endif
-
-
-/**
* Function called with detailed information about a refund.
* It is responsible for packing up the data to return.
*
@@ -816,24 +577,12 @@ process_refunds_cb (void *cls,
bool pending)
{
struct GetOrderData *god = cls;
- struct CoinRefund *cr;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Found refund of %s for coin %s with reason `%s' in database\n",
TALER_amount2s (refund_amount),
TALER_B2S (coin_pub),
reason);
- cr = GNUNET_new (struct CoinRefund);
- cr->refund_serial = refund_serial;
- cr->exchange_url = GNUNET_strdup (exchange_url);
- cr->god = god;
- cr->coin_pub = *coin_pub;
- cr->rtransaction_id = rtransaction_id;
- cr->refund_amount = *refund_amount;
- cr->execution_time = timestamp;
- GNUNET_CONTAINER_DLL_insert (god->cr_head,
- god->cr_tail,
- cr);
if (god->refunded)
{
GNUNET_assert (0 <=
@@ -849,42 +598,6 @@ process_refunds_cb (void *cls,
/**
- * Clean up refund processing.
- *
- * @param god handle to clean up refund processing for
- */
-static void
-rf_cleanup (struct GetOrderData *god)
-{
- struct CoinRefund *cr;
-
- while (NULL != (cr = god->cr_head))
- {
- GNUNET_CONTAINER_DLL_remove (god->cr_head,
- god->cr_tail,
- cr);
- if (NULL != cr->fo)
- {
- TMH_EXCHANGES_find_exchange_cancel (cr->fo);
- cr->fo = NULL;
- }
- if (NULL != cr->rh)
- {
- TALER_EXCHANGE_refund_cancel (cr->rh);
- cr->rh = NULL;
- }
- if (NULL != cr->exchange_reply)
- {
- json_decref (cr->exchange_reply);
- cr->exchange_reply = NULL;
- }
- GNUNET_free (cr->exchange_url);
- GNUNET_free (cr);
- }
-}
-
-
-/**
* Clean up the session state for a GET /orders/$ID request.
*
* @param cls must be a `struct GetOrderData *`
@@ -894,7 +607,6 @@ god_cleanup (void *cls)
{
struct GetOrderData *god = cls;
- rf_cleanup (god);
if (NULL != god->contract_terms)
json_decref (god->contract_terms);
GNUNET_free (god);
@@ -1005,7 +717,6 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
}
}
-#if 0
{
const char *await_refund_obtained_s;
@@ -1019,7 +730,6 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
? 0 == strcasecmp (await_refund_obtained_s, "yes")
: false;
}
-#endif
{
const char *min_refund;
@@ -1302,19 +1012,8 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
}
}
- /* Before we reset the refunds, make sure we notify the client in the case
- of a non-200 status from the exchange. */
- for (struct CoinRefund *cr = god->cr_head;
- NULL != cr;
- cr = cr->next)
- {
- if (MHD_HTTP_OK != cr->exchange_status)
- goto REPLY;
- }
-
/* At this point, we know the contract was paid. Let's check for
refunds. First, clear away refunds found from previous invocations. */
- rf_cleanup (god);
GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (TMH_currency,
&god->refund_amount));
qs = TMH_db->lookup_refunds_detailed (TMH_db->cls,
@@ -1331,66 +1030,12 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
"Failed to lookup refunds for contract");
}
-//#if 0
- /* Now launch exchange interactions, unless we already have the
- response in the database! */
- for (struct CoinRefund *cr = god->cr_head;
- NULL != cr;
- cr = cr->next)
- {
- enum GNUNET_DB_QueryStatus qs;
-
- qs = TMH_db->lookup_refund_proof (TMH_db->cls,
- cr->refund_serial,
- &cr->exchange_sig,
- &cr->exchange_pub);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
- "Merchant database error");
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* We need to talk to the exchange */
- cr->fo = TMH_EXCHANGES_find_exchange (cr->exchange_url,
- NULL,
- GNUNET_NO,
- &exchange_found_cb,
- cr);
- break;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- /* We got a reply earlier, set status accordingly */
- cr->exchange_status = MHD_HTTP_OK;
- break;
- }
- }
-//#endif
-#if 0
- if ( (god->sc.awaiting_refund_obtained) &&
- (god->refund_available))
- {
- /* Client is waiting for pending refunds to be picked up, suspend
- until timeout */
- struct GNUNET_TIME_Relative remaining;
-
- remaining = GNUNET_TIME_absolute_get_remaining (god->sc.long_poll_timeout);
- if (0 != remaining.rel_value_us)
- {
- /* yes, indeed suspend */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Awaiting pending refunds\n");
- suspend_god (god);
- return MHD_YES;
- }
- }
-#endif
-
- if ( (god->sc.awaiting_refund) &&
- ( (! god->refunded) ||
- (1 != TALER_amount_cmp (&god->refund_amount,
- &god->sc.refund_expected)) ) )
+ if ( ((god->sc.awaiting_refund) &&
+ ( (! god->refunded) ||
+ (1 != TALER_amount_cmp (&god->refund_amount,
+ &god->sc.refund_expected)) )) ||
+ ((god->sc.awaiting_refund_obtained) &&
+ (god->refund_available)) )
{
/* Client is waiting for a refund larger than what we have, suspend
until timeout */
@@ -1400,106 +1045,21 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
if (0 != remaining.rel_value_us)
{
/* yes, indeed suspend */
+ if (god->sc.awaiting_refund)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Awaiting refund exceeding %s\n",
+ TALER_amount2s (&god->sc.refund_expected));
+ if (god->sc.awaiting_refund_obtained)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Awaiting refund exceeding %s\n",
+ "Awaiting pending refunds\n",
TALER_amount2s (&god->sc.refund_expected));
suspend_god (god);
return MHD_YES;
}
}
- /* Check if there are still exchange operations pending */
- if (god_pending (god))
- {
- if (! god->suspended)
- {
- god->suspended = true;
- MHD_suspend_connection (connection);
- GNUNET_CONTAINER_DLL_insert (god_head,
- god_tail,
- god);
- }
- return MHD_YES; /* we're still talking to the exchange */
- }
-
/* All operations done, build final response */
-REPLY:
{
- json_t *ra;
-
- ra = json_array ();
- GNUNET_assert (NULL != ra);
- for (struct CoinRefund *cr = god->cr_head;
- NULL != cr;
- cr = cr->next)
- {
- json_t *refund;
-
- if (MHD_HTTP_OK != cr->exchange_status)
- {
- if (NULL == cr->exchange_reply)
- {
- refund = json_pack ("{s:s, s:I,s:I,s:o,s:o,s:o}"
- "type",
- "failure",
- "exchange_status",
- (json_int_t) cr->exchange_status,
- "rtransaction_id",
- (json_int_t) cr->rtransaction_id,
- "coin_pub",
- GNUNET_JSON_from_data_auto (&cr->coin_pub),
- "refund_amount",
- TALER_JSON_from_amount (&cr->refund_amount),
- "execution_time",
- GNUNET_JSON_from_time_abs (cr->execution_time));
- }
- else
- {
- refund = json_pack ("{s:s,s:I,s:I,s:O,s:I,s:o,s:o,s:o}"
- "type",
- "failure",
- "exchange_status",
- (json_int_t) cr->exchange_status,
- "exchange_code",
- (json_int_t) cr->exchange_code,
- "exchange_reply",
- cr->exchange_reply,
- "rtransaction_id",
- (json_int_t) cr->rtransaction_id,
- "coin_pub",
- GNUNET_JSON_from_data_auto (&cr->coin_pub),
- "refund_amount",
- TALER_JSON_from_amount (&cr->refund_amount),
- "execution_time",
- GNUNET_JSON_from_time_abs (cr->execution_time));
- }
- }
- else
- {
- refund = json_pack ("{s:s,s:I,s:o,s:o,s:I,s:o,s:o,s:o}",
- "type",
- "success",
- "exchange_status",
- (json_int_t) cr->exchange_status,
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&cr->exchange_sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&cr->exchange_pub),
- "rtransaction_id",
- (json_int_t) cr->rtransaction_id,
- "coin_pub",
- GNUNET_JSON_from_data_auto (&cr->coin_pub),
- "refund_amount",
- TALER_JSON_from_amount (&cr->refund_amount),
- "execution_time",
- GNUNET_JSON_from_time_abs (cr->execution_time));
- }
- GNUNET_assert (
- 0 ==
- json_array_append_new (ra,
- refund));
- }
-
if (god->generate_html)
{
enum GNUNET_GenericReturnValue res;
@@ -1587,15 +1147,11 @@ REPLY:
return TALER_MHD_reply_json_pack (
connection,
MHD_HTTP_OK,
- "{s:b, s:b, s:o, s:o, s:o}",
+ "{s:b, s:b, s:o}",
"refunded", god->refunded,
"refund_pending", god->refund_available,
"refund_amount",
- TALER_JSON_from_amount (&god->refund_amount),
- "refunds",
- ra,
- "merchant_pub",
- GNUNET_JSON_from_data_auto (&hc->instance->merchant_pub));
+ TALER_JSON_from_amount (&god->refund_amount));
}
}
}
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 64ba5e66..a709b3e3 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -1422,7 +1422,8 @@ begin_transaction (struct PayContext *pc)
/* Notify clients that have been waiting for the payment to succeed */
TMH_long_poll_resume (pc->order_id,
hc->instance,
- NULL);
+ NULL,
+ false);
TMH_notify_order_change (hc->instance,
pc->order_id,
true, /* paid */
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 bfdb6ca2..7fafdd5e 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
@@ -253,7 +253,24 @@ static struct PostRefundData *prd_head;
static struct PostRefundData *prd_tail;
-/* FIXME: Handle shutdown and other events that require ending all requests */
+/**
+ * Force resuming all suspended order lookups, needed during shutdown.
+ */
+void
+TMH_force_wallet_refund_order_resume (void)
+{
+ struct PostRefundData *prd;
+
+ while (NULL != (prd = prd_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (prd_head,
+ prd_tail,
+ prd);
+ GNUNET_assert (prd->suspended);
+ prd->suspended = false;
+ MHD_resume_connection (prd->sc.con);
+ }
+}
/**
@@ -581,7 +598,11 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh,
"Merchant database error");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
/* We need to talk to the exchange */
- /* FIXME: notify clients polling for this to happen */
+ /* Notify clients waiting for the refund to be obtained. */
+ TMH_long_poll_resume (hc->infix,
+ hc->instance,
+ &prd->refund_amount,
+ true);
cr->fo = TMH_EXCHANGES_find_exchange (cr->exchange_url,
NULL,
GNUNET_NO,
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-refund.h b/src/backend/taler-merchant-httpd_post-orders-ID-refund.h
index 8bf0a6ee..31201774 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-refund.h
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-refund.h
@@ -37,4 +37,12 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh,
struct MHD_Connection *connection,
struct TMH_HandlerContext *hc);
+
+/**
+ * Force resuming all suspended order lookups, needed during shutdown.
+ */
+void
+TMH_force_wallet_refund_order_resume (void);
+
+
#endif
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 92b7590c..16f21d14 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
@@ -220,7 +220,8 @@ TMH_private_post_orders_ID_refund (const struct TMH_RequestHandler *rh,
TALER_amount2s (&refund));
TMH_long_poll_resume (hc->infix,
hc->instance,
- &refund);
+ &refund,
+ false);
{
struct GNUNET_TIME_Absolute timestamp;
uint64_t order_serial;
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c
index 706d125d..d23f33bc 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -282,7 +282,8 @@ execute_transaction (struct TMH_HandlerContext *hc,
/* Notify clients that have been waiting for the payment to succeed */
TMH_long_poll_resume (order_id,
hc->instance,
- NULL);
+ NULL,
+ false);
TMH_notify_order_change (hc->instance,
order_id,
false, /* paid */