summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_private-get-orders.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-get-orders.c')
-rw-r--r--src/backend/taler-merchant-httpd_private-get-orders.c282
1 files changed, 134 insertions, 148 deletions
diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c b/src/backend/taler-merchant-httpd_private-get-orders.c
index d4f74184..4c6a104e 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders.c
@@ -225,6 +225,23 @@ cleanup (void *ctx)
/**
+ * Closure for #process_refunds_cb().
+ */
+struct ProcessRefundsClosure
+{
+ /**
+ * Place where we accumulate the refunds.
+ */
+ struct TALER_Amount total_refund_amount;
+
+ /**
+ * Set to an error code if something goes wrong.
+ */
+ enum TALER_ErrorCode ec;
+};
+
+
+/**
* Function called with information about a refund.
* It is responsible for summing up the refund amount.
*
@@ -249,11 +266,20 @@ process_refunds_cb (void *cls,
const struct TALER_Amount *refund_amount,
bool pending)
{
- struct TALER_Amount *total_refund_amount = cls;
+ struct ProcessRefundsClosure *prc = cls;
+ if (GNUNET_OK !=
+ TALER_amount_cmp_currency (&prc->total_refund_amount,
+ refund_amount))
+ {
+ /* Database error, refunds in mixed currency in DB. Not OK! */
+ prc->ec = TALER_EC_GENERIC_DB_INVARIANT_FAILURE;
+ GNUNET_break (0);
+ return;
+ }
GNUNET_assert (0 <=
- TALER_amount_add (total_refund_amount,
- total_refund_amount,
+ TALER_amount_add (&prc->total_refund_amount,
+ &prc->total_refund_amount,
refund_amount));
}
@@ -316,14 +342,12 @@ add_order (void *cls,
{
/* First try to find the order in the contracts */
uint64_t os;
- bool paid = false;
qs = TMH_db->lookup_contract_terms (TMH_db->cls,
po->instance_id,
order_id,
&contract_terms,
&os,
- &paid,
NULL);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
GNUNET_break (os == order_serial);
@@ -361,9 +385,8 @@ add_order (void *cls,
{
struct GNUNET_TIME_Timestamp rd;
struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount ("amount",
- TMH_currency,
- &order_amount),
+ TALER_JSON_spec_amount_any ("amount",
+ &order_amount),
GNUNET_JSON_spec_timestamp ("refund_deadline",
&rd),
GNUNET_JSON_spec_string ("summary",
@@ -383,19 +406,33 @@ add_order (void *cls,
return;
}
+ if (TALER_amount_is_zero (&order_amount) &&
+ (po->of.wired != TALER_EXCHANGE_YNA_ALL) )
+ {
+ /* If we are actually filtering by wire status,
+ and the order was over an amount of zero,
+ do not return it as wire status is not
+ exactly meaningful for orders over zero. */
+ json_decref (contract_terms);
+ GNUNET_free (order_id);
+ return;
+ }
+
if (GNUNET_TIME_absolute_is_future (rd.abs_time) &&
paid)
{
- struct TALER_Amount refund_amount;
+ struct ProcessRefundsClosure prc = {
+ .ec = TALER_EC_NONE
+ };
GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TMH_currency,
- &refund_amount));
+ TALER_amount_set_zero (order_amount.currency,
+ &prc.total_refund_amount));
qs = TMH_db->lookup_refunds_detailed (TMH_db->cls,
po->instance_id,
&h_contract_terms,
&process_refunds_cb,
- &refund_amount);
+ &prc);
if (0 > qs)
{
GNUNET_break (0);
@@ -404,7 +441,15 @@ add_order (void *cls,
GNUNET_free (order_id);
return;
}
- if (0 > TALER_amount_cmp (&refund_amount,
+ if (TALER_EC_NONE != prc.ec)
+ {
+ GNUNET_break (0);
+ po->result = prc.ec;
+ json_decref (contract_terms);
+ GNUNET_free (order_id);
+ return;
+ }
+ if (0 > TALER_amount_cmp (&prc.total_refund_amount,
&order_amount))
refundable = true;
}
@@ -602,7 +647,6 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
{
struct TMH_PendingOrder *po = hc->ctx;
enum GNUNET_DB_QueryStatus qs;
- struct TALER_MERCHANTDB_OrderFilter of;
if (NULL != po)
{
@@ -622,11 +666,19 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
GNUNET_JSON_pack_array_incref ("orders",
po->pa));
}
+ po = GNUNET_new (struct TMH_PendingOrder);
+ hc->ctx = po;
+ hc->cc = &cleanup;
+ po->con = connection;
+ po->pa = json_array ();
+ GNUNET_assert (NULL != po->pa);
+ po->instance_id = hc->instance->settings.id;
+ po->mi = hc->instance;
if (! (TALER_arg_to_yna (connection,
"paid",
TALER_EXCHANGE_YNA_ALL,
- &of.paid)) )
+ &po->of.paid)) )
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
@@ -634,7 +686,7 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
if (! (TALER_arg_to_yna (connection,
"refunded",
TALER_EXCHANGE_YNA_ALL,
- &of.refunded)) )
+ &po->of.refunded)) )
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
@@ -642,49 +694,28 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
if (! (TALER_arg_to_yna (connection,
"wired",
TALER_EXCHANGE_YNA_ALL,
- &of.wired)) )
+ &po->of.wired)) )
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
"wired");
+ po->of.delta = -20;
+ /* deprecated in protocol v12 */
+ TALER_MHD_parse_request_snumber (connection,
+ "delta",
+ &po->of.delta);
+ /* since protocol v12 */
+ TALER_MHD_parse_request_snumber (connection,
+ "limit",
+ &po->of.delta);
+ if ( (-MAX_DELTA > po->of.delta) ||
+ (po->of.delta > MAX_DELTA) )
{
- const char *delta_str;
-
- delta_str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- "delta");
- if (NULL == delta_str)
- {
- of.delta = -20;
- }
- else
- {
- char dummy;
- long long ll;
-
- if (1 !=
- sscanf (delta_str,
- "%lld%c",
- &ll,
- &dummy))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "delta");
- }
- of.delta = (int64_t) ll;
- if ( (-MAX_DELTA > of.delta) ||
- (of.delta > MAX_DELTA) )
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "delta");
- }
- }
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "delta");
}
{
const char *date_s_str;
@@ -694,10 +725,10 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
"date_s");
if (NULL == date_s_str)
{
- if (of.delta > 0)
- of.date = GNUNET_TIME_UNIT_ZERO_TS;
+ if (po->of.delta > 0)
+ po->of.date = GNUNET_TIME_UNIT_ZERO_TS;
else
- of.date = GNUNET_TIME_UNIT_FOREVER_TS;
+ po->of.date = GNUNET_TIME_UNIT_FOREVER_TS;
}
else
{
@@ -717,9 +748,9 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
"date_ms");
}
- of.date = GNUNET_TIME_absolute_to_timestamp (
+ po->of.date = GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_absolute_from_s (ll));
- if (GNUNET_TIME_absolute_is_never (of.date.abs_time))
+ if (GNUNET_TIME_absolute_is_never (po->of.date.abs_time))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
@@ -729,99 +760,56 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
}
}
}
+ if (po->of.delta > 0)
+ po->of.start_row = 0;
+ else
+ po->of.start_row = INT64_MAX;
+ /* deprecated in protocol v12 */
+ TALER_MHD_parse_request_number (connection,
+ "start",
+ &po->of.start_row);
+ /* since protocol v12 */
+ TALER_MHD_parse_request_number (connection,
+ "offset",
+ &po->of.start_row);
+ if (INT64_MAX < po->of.start_row)
{
- const char *start_row_str;
-
- start_row_str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- "start");
- if (NULL == start_row_str)
- {
- if (of.delta > 0)
- of.start_row = 0;
- else
- of.start_row = INT64_MAX;
- }
- else
- {
- char dummy;
- unsigned long long ull;
-
- if (1 !=
- sscanf (start_row_str,
- "%llu%c",
- &ull,
- &dummy))
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "start");
- of.start_row = (uint64_t) ull;
- if (INT64_MAX < of.start_row)
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "start");
- }
- }
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "start");
}
+ po->of.session_id
+ = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "session_id");
+ po->of.fulfillment_url
+ = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "fulfillment_url");
+ TALER_MHD_parse_request_timeout (connection,
+ &po->long_poll_timeout);
+ if (GNUNET_TIME_absolute_is_never (po->long_poll_timeout))
{
- const char *timeout_ms_str;
-
- timeout_ms_str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- "timeout_ms");
- if (NULL == timeout_ms_str)
- {
- of.timeout = GNUNET_TIME_UNIT_ZERO;
- }
- else
- {
- char dummy;
- unsigned long long ull;
-
- if (1 !=
- sscanf (timeout_ms_str,
- "%llu%c",
- &ull,
- &dummy))
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "timeout_ms");
- of.timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
- ull);
- if (GNUNET_TIME_relative_is_forever (of.timeout))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "timeout_ms");
- }
- }
-
- if ( (0 >= of.delta) &&
- (! GNUNET_TIME_relative_is_zero (of.timeout)) )
- {
- GNUNET_break_op (0);
- of.timeout = GNUNET_TIME_UNIT_ZERO;
- }
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "timeout_ms");
+ }
+ po->of.timeout = GNUNET_TIME_absolute_get_remaining (po->long_poll_timeout);
+ if ( (0 >= po->of.delta) &&
+ (GNUNET_TIME_absolute_is_future (po->long_poll_timeout)) )
+ {
+ GNUNET_break_op (0);
+ po->of.timeout = GNUNET_TIME_UNIT_ZERO;
+ po->long_poll_timeout = GNUNET_TIME_UNIT_ZERO_ABS;
}
- po = GNUNET_new (struct TMH_PendingOrder);
- hc->ctx = po;
- hc->cc = &cleanup;
- po->con = connection;
- po->pa = json_array ();
- GNUNET_assert (NULL != po->pa);
- po->instance_id = hc->instance->settings.id;
- po->mi = hc->instance;
qs = TMH_db->lookup_orders (TMH_db->cls,
po->instance_id,
- &of,
+ &po->of,
&add_order,
po);
if (0 > qs)
@@ -838,7 +826,7 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
NULL);
}
if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) &&
- (! GNUNET_TIME_relative_is_zero (of.timeout)) )
+ (GNUNET_TIME_absolute_is_future (po->long_poll_timeout)) )
{
struct TMH_MerchantInstance *mi = hc->instance;
@@ -849,8 +837,6 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh,
po->hn = GNUNET_CONTAINER_heap_insert (order_timeout_heap,
po,
po->long_poll_timeout.abs_value_us);
- po->long_poll_timeout = GNUNET_TIME_relative_to_absolute (of.timeout);
- po->of = of;
GNUNET_CONTAINER_DLL_insert (mi->po_head,
mi->po_tail,
po);