summaryrefslogtreecommitdiff
path: root/src/lib/merchant_api_wallet_post_order_refund.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/merchant_api_wallet_post_order_refund.c')
-rw-r--r--src/lib/merchant_api_wallet_post_order_refund.c287
1 files changed, 101 insertions, 186 deletions
diff --git a/src/lib/merchant_api_wallet_post_order_refund.c b/src/lib/merchant_api_wallet_post_order_refund.c
index fc4b0abd..e72982f3 100644
--- a/src/lib/merchant_api_wallet_post_order_refund.c
+++ b/src/lib/merchant_api_wallet_post_order_refund.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2020 Taler Systems SA
+ Copyright (C) 2020-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
@@ -32,6 +32,10 @@
#include <taler/taler_signatures.h>
#include <taler/taler_curl_lib.h>
+/**
+ * Maximum number of refunds we return.
+ */
+#define MAX_REFUNDS 1024
/**
* Handle for a (public) POST /orders/ID/refund operation.
@@ -71,33 +75,6 @@ struct TALER_MERCHANT_WalletOrderRefundHandle
/**
- * Convenience function to call the callback in @a owgh with an error code of
- * @a ec and the exchange body being set to @a reply.
- *
- * @param orh handle providing callback
- * @param ec error code to return to application
- * @param reply JSON reply we got from the exchange, can be NULL
- */
-static void
-cb_failure (struct TALER_MERCHANT_WalletOrderRefundHandle *orh,
- enum TALER_ErrorCode ec,
- const json_t *reply)
-{
- struct TALER_MERCHANT_HttpResponse hr = {
- .ec = ec,
- .reply = reply
- };
-
- orh->cb (orh->cb_cls,
- &hr,
- NULL,
- NULL,
- NULL,
- 0);
-}
-
-
-/**
* Callback to process (public) POST /orders/ID/refund response
*
* @param cls the `struct TALER_MERCHANT_OrderRefundHandle`
@@ -111,37 +88,31 @@ handle_refund_finished (void *cls,
{
struct TALER_MERCHANT_WalletOrderRefundHandle *orh = cls;
const json_t *json = response;
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = (unsigned int) response_code,
- .reply = json
+ struct TALER_MERCHANT_WalletRefundResponse wrr = {
+ .hr.http_status = (unsigned int) response_code,
+ .hr.reply = json
};
orh->job = NULL;
-
switch (response_code)
{
case 0:
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- orh->cb (orh->cb_cls,
- &hr,
- NULL,
- NULL,
- NULL,
- 0);
+ wrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
{
- struct TALER_Amount refund_amount;
- json_t *refunds;
- struct TALER_MerchantPublicKeyP merchant_pub;
+ const json_t *refunds;
unsigned int refund_len;
struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount_any ("refund_amount",
- &refund_amount),
- GNUNET_JSON_spec_json ("refunds",
- &refunds),
- GNUNET_JSON_spec_fixed_auto ("merchant_pub",
- &merchant_pub),
+ TALER_JSON_spec_amount_any (
+ "refund_amount",
+ &wrr.details.ok.refund_amount),
+ GNUNET_JSON_spec_array_const (
+ "refunds",
+ &refunds),
+ GNUNET_JSON_spec_fixed_auto (
+ "merchant_pub",
+ &wrr.details.ok.merchant_pub),
GNUNET_JSON_spec_end ()
};
@@ -151,27 +122,21 @@ handle_refund_finished (void *cls,
NULL, NULL))
{
GNUNET_break_op (0);
- cb_failure (orh,
- TALER_EC_GENERIC_REPLY_MALFORMED,
- json);
- TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
- return;
+ wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ wrr.hr.http_status = 0;
+ break;
}
-
- if (! json_is_array (refunds))
+ refund_len = json_array_size (refunds);
+ if ( (json_array_size (refunds) != (size_t) refund_len) ||
+ (refund_len > MAX_REFUNDS) )
{
- GNUNET_break_op (0);
- cb_failure (orh,
- TALER_EC_GENERIC_REPLY_MALFORMED,
- json);
- GNUNET_JSON_parse_free (spec);
- TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
- return;
+ GNUNET_break (0);
+ wrr.hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE;
+ wrr.hr.http_status = 0;
+ break;
}
-
- refund_len = json_array_size (refunds);
{
- struct TALER_MERCHANT_RefundDetail rds[refund_len];
+ struct TALER_MERCHANT_RefundDetail rds[GNUNET_NZL (refund_len)];
memset (rds,
0,
@@ -183,10 +148,26 @@ handle_refund_finished (void *cls,
i);
const char *refund_status_type;
uint32_t exchange_status;
- int ret;
+ uint32_t eec = 0;
struct GNUNET_JSON_Specification espec[] = {
+ GNUNET_JSON_spec_string ("type",
+ &refund_status_type),
GNUNET_JSON_spec_uint32 ("exchange_status",
&exchange_status),
+ GNUNET_JSON_spec_uint64 ("rtransaction_id",
+ &rd->rtransaction_id),
+ GNUNET_JSON_spec_fixed_auto ("coin_pub",
+ &rd->coin_pub),
+ TALER_JSON_spec_amount_any ("refund_amount",
+ &rd->refund_amount),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_object_const ("exchange_reply",
+ &rd->hr.reply),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("exchange_code",
+ &eec),
+ NULL),
GNUNET_JSON_spec_end ()
};
@@ -196,151 +177,85 @@ handle_refund_finished (void *cls,
NULL, NULL))
{
GNUNET_break_op (0);
- cb_failure (orh,
- TALER_EC_GENERIC_REPLY_MALFORMED,
- json);
- TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
- return;
+ wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ wrr.hr.http_status = 0;
+ goto finish;
}
- if (MHD_HTTP_OK == exchange_status)
+ rd->hr.http_status = exchange_status;
+ rd->hr.ec = (enum TALER_ErrorCode) eec;
+ switch (exchange_status)
{
- struct GNUNET_JSON_Specification rspec[] = {
- GNUNET_JSON_spec_string ("type",
- &refund_status_type),
- GNUNET_JSON_spec_fixed_auto ("exchange_sig",
- &rd->exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub",
- &rd->exchange_pub),
- GNUNET_JSON_spec_uint64 ("rtransaction_id",
- &rd->rtransaction_id),
- GNUNET_JSON_spec_fixed_auto ("coin_pub",
- &rd->coin_pub),
- TALER_JSON_spec_amount_any ("refund_amount",
- &rd->refund_amount),
- GNUNET_JSON_spec_end ()
- };
-
- ret = GNUNET_JSON_parse (jrefund,
- rspec,
- NULL, NULL);
- if (GNUNET_OK == ret)
+ case MHD_HTTP_OK:
{
- /* check that type field is correct */
- if (0 != strcmp ("success", refund_status_type))
- {
- GNUNET_break_op (0);
- ret = GNUNET_SYSERR;
- }
- }
- }
- else
- {
- struct GNUNET_JSON_Specification rspec[] = {
- GNUNET_JSON_spec_string ("type",
- &refund_status_type),
- GNUNET_JSON_spec_fixed_auto ("coin_pub",
- &rd->coin_pub),
- GNUNET_JSON_spec_uint64 ("rtransaction_id",
- &rd->rtransaction_id),
- TALER_JSON_spec_amount_any ("refund_amount",
- &rd->refund_amount),
- GNUNET_JSON_spec_end ()
- };
-
- ret = GNUNET_JSON_parse (jrefund,
+ struct GNUNET_JSON_Specification rspec[] = {
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig",
+ &rd->details.ok.exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub",
+ &rd->details.ok.exchange_pub),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (jrefund,
rspec,
- NULL, NULL);
- if (GNUNET_OK == ret)
- {
- /* parse optional arguments */
- json_t *jec;
-
- jec = json_object_get (jrefund,
- "exchange_code");
- if (NULL != jec)
+ NULL,
+ NULL))
{
- if (! json_is_integer (jec))
- {
- GNUNET_break_op (0);
- ret = GNUNET_SYSERR;
- }
- else
- {
- rd->hr.ec = (enum TALER_ErrorCode) json_integer_value (jec);
- }
+ GNUNET_break_op (0);
+ wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ wrr.hr.http_status = 0;
+ goto finish;
}
- rd->hr.reply = json_object_get (jrefund,
- "exchange_reply");
/* check that type field is correct */
- if (0 != strcmp ("failure", refund_status_type))
+ if (0 != strcmp ("success",
+ refund_status_type))
{
GNUNET_break_op (0);
- ret = GNUNET_SYSERR;
+ wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ wrr.hr.http_status = 0;
+ goto finish;
}
}
- }
- if (GNUNET_OK != ret)
- {
- GNUNET_break_op (0);
- cb_failure (orh,
- TALER_EC_GENERIC_REPLY_MALFORMED,
- json);
- TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
- return;
- }
- rd->hr.http_status = exchange_status;
- }
-
- {
- struct TALER_MERCHANT_HttpResponse hr = {
- .reply = json,
- .http_status = MHD_HTTP_OK
- };
+ break; /* end MHD_HTTP_OK */
+ default:
+ if (0 != strcmp ("failure",
+ refund_status_type))
+ {
+ GNUNET_break_op (0);
+ wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ wrr.hr.http_status = 0;
+ goto finish;
+ }
+ } /* switch on exchange status code */
+ } /* for all refunds */
- orh->cb (orh->cb_cls,
- &hr,
- &refund_amount,
- &merchant_pub,
- rds,
- refund_len);
- }
- }
- GNUNET_JSON_parse_free (spec);
- }
+ wrr.details.ok.refunds = rds;
+ wrr.details.ok.refunds_length = refund_len;
+ orh->cb (orh->cb_cls,
+ &wrr);
+ TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
+ return;
+ } /* end 'rds' scope */
+ } /* case MHD_HTTP_OK */
break;
case MHD_HTTP_NO_CONTENT:
- orh->cb (orh->cb_cls,
- &hr,
- NULL,
- NULL,
- NULL,
- 0);
break;
case MHD_HTTP_CONFLICT:
case MHD_HTTP_NOT_FOUND:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
- orh->cb (orh->cb_cls,
- &hr,
- NULL,
- NULL,
- NULL,
- 0);
+ wrr.hr.ec = TALER_JSON_get_error_code (json);
+ wrr.hr.hint = TALER_JSON_get_error_hint (json);
break;
default:
GNUNET_break_op (0); /* unexpected status code */
TALER_MERCHANT_parse_error_details_ (json,
response_code,
- &hr);
- orh->cb (orh->cb_cls,
- &hr,
- NULL,
- NULL,
- NULL,
- 0);
+ &wrr.hr);
break;
}
+finish:
+ orh->cb (orh->cb_cls,
+ &wrr);
TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
}