aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-10-07 12:40:07 +0200
committerChristian Grothoff <christian@grothoff.org>2020-10-07 12:40:07 +0200
commit7d81706ca0d905a2d7e8c7c18a6e2d48d0a67bae (patch)
treea58a9a3d0a54e628045057782e2168f4812e1c94
parente24064063f5d7dc36ab14e1f911708e6d981a10e (diff)
refuse refunds categorically if refund_delay was 0, instead of trying to give refunds anyway
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c96
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c46
2 files changed, 97 insertions, 45 deletions
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 859603bb..7af14873 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
@@ -116,6 +116,70 @@ TMH_private_post_orders_ID_refund (const struct TMH_RequestHandler *rh,
struct GNUNET_HashCode h_contract;
{
+ enum GNUNET_DB_QueryStatus qs;
+ json_t *contract_terms;
+ uint64_t order_serial;
+ struct GNUNET_TIME_Absolute refund_deadline;
+ struct GNUNET_TIME_Absolute timestamp;
+
+ qs = TMH_db->lookup_contract_terms (TMH_db->cls,
+ hc->instance->settings.id,
+ hc->infix,
+ &contract_terms,
+ &order_serial);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+ {
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_absolute_time ("refund_deadline",
+ &refund_deadline),
+ TALER_JSON_spec_absolute_time ("timestamp",
+ &timestamp),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_YES !=
+ GNUNET_JSON_parse (contract_terms,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ json_decref (contract_terms);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_INTERNAL_LOGIC_ERROR,
+ "Failed to parse contract terms from DB");
+ }
+ json_decref (contract_terms);
+ if (timestamp.abs_value_us == refund_deadline.abs_value_us)
+ {
+ /* refund was never allowed, so we should refuse hard */
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+#ifndef TALER_EC_MERCHANT_REFUND_NOT_ALLOWED_BY_CONTRACT
+ 2609, /* remove post 0.8.0 release */
+#else
+ TALER_EC_MERCHANT_REFUND_NOT_ALLOWED_BY_CONTRACT,
+#endif
+ NULL);
+ }
+ if (0 == GNUNET_TIME_absolute_get_remaining (refund_deadline).rel_value_us)
+ {
+ /* it is too late for refunds */
+ /* NOTE: We MAY still be lucky that the exchange did not yet
+ wire the funds, so we will try to give the refund anyway */
+ }
+ }
+ else
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFUND_ORDER_ID_UNKNOWN,
+ hc->infix);
+ }
+ }
+
+ {
enum GNUNET_GenericReturnValue res;
res = TALER_MHD_parse_json_data (connection,
@@ -187,30 +251,14 @@ TMH_private_post_orders_ID_refund (const struct TMH_RequestHandler *rh,
NULL);
case TALER_MERCHANTDB_RS_NO_SUCH_ORDER:
{
- enum GNUNET_DB_QueryStatus qs;
- json_t *contract_terms;
- uint64_t order_serial;
-
- qs = TMH_db->lookup_contract_terms (TMH_db->cls,
- hc->instance->settings.id,
- hc->infix,
- &contract_terms,
- &order_serial);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- {
- json_decref (contract_terms);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_CONFLICT,
- TALER_EC_REFUND_ORDER_ID_UNPAID,
- hc->infix);
- }
- else
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_REFUND_ORDER_ID_UNKNOWN,
- hc->infix);
- }
+ /* We know the order exists from the
+ "lookup_contract_terms" at the beginning;
+ so if we get 'no such order' here, it
+ must be read as "no PAID order" */
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_REFUND_ORDER_ID_UNPAID,
+ hc->infix);
}
case TALER_MERCHANTDB_RS_SUCCESS:
{
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c
index 0b3bf500..7fc40324 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -673,31 +673,35 @@ patch_order (struct MHD_Connection *connection,
}
}
- /* Add timestamp if it doesn't exist */
- if (NULL == json_object_get (order,
- "timestamp"))
{
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
-
(void) GNUNET_TIME_round_abs (&now);
- GNUNET_assert (0 ==
- json_object_set_new (order,
- "timestamp",
- GNUNET_JSON_from_time_abs (now)));
- }
-
- /* If no refund_deadline given, set one based on refund_delay. */
- if (NULL == json_object_get (order,
- "refund_deadline"))
- {
- struct GNUNET_TIME_Absolute rd =
- GNUNET_TIME_relative_to_absolute (refund_delay);
- (void) GNUNET_TIME_round_abs (&rd);
- GNUNET_assert (0 ==
- json_object_set_new (order,
- "refund_deadline",
- GNUNET_JSON_from_time_abs (rd)));
+ /* Add timestamp if it doesn't exist */
+ if (NULL == json_object_get (order,
+ "timestamp"))
+ {
+ GNUNET_assert (0 ==
+ json_object_set_new (order,
+ "timestamp",
+ GNUNET_JSON_from_time_abs (now)));
+ }
+
+ /* If no refund_deadline given, set one based on refund_delay. */
+ if (NULL == json_object_get (order,
+ "refund_deadline"))
+ {
+ struct GNUNET_TIME_Absolute rd =
+ GNUNET_TIME_relative_to_absolute (refund_delay);
+
+ (void) GNUNET_TIME_round_abs (&rd);
+ if (0 == refund_delay.rel_value_us)
+ rd = now; /* if delay was 0, ensure that refund_deadline == timestamp */
+ GNUNET_assert (0 ==
+ json_object_set_new (order,
+ "refund_deadline",
+ GNUNET_JSON_from_time_abs (rd)));
+ }
}
if (NULL == json_object_get (order,