summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-04-26 00:15:30 +0200
committerChristian Grothoff <christian@grothoff.org>2023-04-26 00:17:19 +0200
commit7afc01815adb8d8d8d638526d1bf8caa66b7f3b4 (patch)
treefd1df4a32ca5f0dd55173f665c3597c79263689e /src
parentfd591efee4be6d6500c59d459385f0950c9c0439 (diff)
downloadmerchant-7afc01815adb8d8d8d638526d1bf8caa66b7f3b4.tar.gz
merchant-7afc01815adb8d8d8d638526d1bf8caa66b7f3b4.tar.bz2
merchant-7afc01815adb8d8d8d638526d1bf8caa66b7f3b4.zip
address #7820
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-paid.c43
-rw-r--r--src/include/taler_merchant_service.h32
-rw-r--r--src/lib/merchant_api_post_order_paid.c58
-rw-r--r--src/testing/test_kyc_api.c4
-rw-r--r--src/testing/test_merchant_api.c2
-rw-r--r--src/testing/testing_api_cmd_post_orders_paid.c10
6 files changed, 113 insertions, 36 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-paid.c b/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
index 946e30a1..54d4b930 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2014-2021 Taler Systems SA
+ (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@@ -31,6 +31,26 @@
/**
+ * Function called with information about a refund.
+ * Sets the boolean in @a cls to true when called.
+ *
+ * @param cls closure, a `bool *`
+ * @param coin_pub public coin from which the refund comes from
+ * @param refund_amount refund amount which is being taken from @a coin_pub
+ */
+static void
+refund_cb (
+ void *cls,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_Amount *refund_amount)
+{
+ bool *refunded = cls;
+
+ *refunded = true;
+}
+
+
+/**
* Use database to notify other clients about the
* session being captured.
*
@@ -202,12 +222,21 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler *rh,
session_id,
fulfillment_url);
/* fulfillment_url is part of the contract_terms */
- json_decref (contract_terms);
- return TALER_MHD_reply_static (connection,
- MHD_HTTP_NO_CONTENT,
- NULL,
- NULL,
- 0);
+ {
+ bool refunded = false;
+
+ qs = TMH_db->lookup_refunds (TMH_db->cls,
+ hc->instance->settings.id,
+ &hct,
+ &refund_cb,
+ &refunded);
+ json_decref (contract_terms);
+ return TALER_MHD_REPLY_JSON_PACK (
+ connection,
+ MHD_HTTP_OK,
+ GNUNET_JSON_pack_bool ("refunded",
+ refunded));
+ }
}
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 8cf8fbcc..143556b1 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -2529,18 +2529,46 @@ TALER_MERCHANT_order_pay_cancel (struct TALER_MERCHANT_OrderPayHandle *oph);
*/
struct TALER_MERCHANT_OrderPaidHandle;
+/**
+ * Reponse to an /orders/$ID/paid request.
+ */
+struct TALER_MERCHANT_OrderPaidResponse
+{
+ /**
+ * HTTP response details.
+ */
+ struct TALER_MERCHANT_HttpResponse hr;
+ /**
+ * HTTP-status code dependent details.
+ */
+ union
+ {
+ /**
+ * Details on success.
+ */
+ struct
+ {
+ /**
+ * Set to true if the order was paid but also
+ * refunded.
+ */
+ bool refunded;
+ } success;
+ } details;
+};
+
/**
* Callbacks of this type are used to serve the result of submitting a
* POST /orders/$ID/paid request to a merchant.
*
* @param cls closure
- * @param hr HTTP response details
+ * @param oprr response details
*/
typedef void
(*TALER_MERCHANT_OrderPaidCallback) (
void *cls,
- const struct TALER_MERCHANT_HttpResponse *hr);
+ const struct TALER_MERCHANT_OrderPaidResponse *opr);
/**
diff --git a/src/lib/merchant_api_post_order_paid.c b/src/lib/merchant_api_post_order_paid.c
index a42b1255..a483ba41 100644
--- a/src/lib/merchant_api_post_order_paid.c
+++ b/src/lib/merchant_api_post_order_paid.c
@@ -90,9 +90,9 @@ handle_paid_finished (void *cls,
{
struct TALER_MERCHANT_OrderPaidHandle *oph = cls;
const json_t *json = response;
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = (unsigned int) response_code,
- .reply = json
+ struct TALER_MERCHANT_OrderPaidResponse opr = {
+ .hr.http_status = (unsigned int) response_code,
+ .hr.reply = json
};
oph->job = NULL;
@@ -102,61 +102,81 @@ handle_paid_finished (void *cls,
switch (response_code)
{
case 0:
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
- case MHD_HTTP_NO_CONTENT:
+ case MHD_HTTP_OK:
+ {
+ bool refunded;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_bool ("refunded",
+ &refunded),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (opr.hr.reply,
+ spec,
+ NULL,
+ NULL))
+ {
+ GNUNET_break_op (0);
+ opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
+ }
+ break;
+ }
break;
case MHD_HTTP_BAD_REQUEST:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ opr.hr.ec = TALER_JSON_get_error_code (json);
+ opr.hr.hint = TALER_JSON_get_error_hint (json);
/* This should never happen, either us
* or the merchant is buggy (or API version conflict);
* just pass JSON reply to the application */
break;
case MHD_HTTP_FORBIDDEN:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ opr.hr.ec = TALER_JSON_get_error_code (json);
+ opr.hr.hint = TALER_JSON_get_error_hint (json);
/* The signature provided was invalid */
break;
case MHD_HTTP_NOT_FOUND:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ opr.hr.ec = TALER_JSON_get_error_code (json);
+ opr.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the
application */
break;
case MHD_HTTP_CONFLICT:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ opr.hr.ec = TALER_JSON_get_error_code (json);
+ opr.hr.hint = TALER_JSON_get_error_hint (json);
/* The hashed contract terms don't match with the order_id. */
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ opr.hr.ec = TALER_JSON_get_error_code (json);
+ opr.hr.hint = TALER_JSON_get_error_hint (json);
/* Server had an internal issue; we should retry,
but this API leaves this to the application */
break;
case MHD_HTTP_SERVICE_UNAVAILABLE:
TALER_MERCHANT_parse_error_details_ (json,
response_code,
- &hr);
+ &opr.hr);
/* Exchange couldn't respond properly; the retry is
left to the application */
break;
default:
TALER_MERCHANT_parse_error_details_ (json,
response_code,
- &hr);
+ &opr.hr);
/* unexpected response code */
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d\n",
(unsigned int) response_code,
- (int) hr.ec);
+ (int) opr.hr.ec);
GNUNET_break_op (0);
break;
}
oph->paid_cb (oph->paid_cb_cls,
- &hr);
+ &opr);
TALER_MERCHANT_order_paid_cancel (oph);
}
diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c
index 8cb30f8b..902a46ce 100644
--- a/src/testing/test_kyc_api.c
+++ b/src/testing/test_kyc_api.c
@@ -210,7 +210,7 @@ run (void *cls,
merchant_url,
"deposit-simple",
"session-1",
- MHD_HTTP_NO_CONTENT),
+ MHD_HTTP_OK),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-1"),
CMD_EXEC_AGGREGATOR ("run-aggregator"),
/* KYC: hence nothing happened at the bank yet: */
@@ -324,7 +324,7 @@ run (void *cls,
merchant_url,
"deposit-simple",
"session-aml",
- MHD_HTTP_NO_CONTENT),
+ MHD_HTTP_OK),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-aml-1"),
CMD_EXEC_AGGREGATOR ("run-aggregator-aml-frozen"),
/* AML-frozen: hence nothing happened at the bank yet: */
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index a106b8be..99ed291b 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -451,7 +451,7 @@ run (void *cls,
merchant_url,
"deposit-simple",
"session-1",
- MHD_HTTP_NO_CONTENT),
+ MHD_HTTP_OK),
TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1-2",
merchant_url,
"create-proposal-1",
diff --git a/src/testing/testing_api_cmd_post_orders_paid.c b/src/testing/testing_api_cmd_post_orders_paid.c
index 6c4e41cd..645a0010 100644
--- a/src/testing/testing_api_cmd_post_orders_paid.c
+++ b/src/testing/testing_api_cmd_post_orders_paid.c
@@ -71,21 +71,21 @@ struct PostOrdersPaidState
* Response from the merchant after POST /paid.
*
* @param cls pointer to `struct PostOrdersPaidState`.
- * @param hr the http response.
+ * @param opr the response.
*/
static void
paid_cb (void *cls,
- const struct TALER_MERCHANT_HttpResponse *hr)
+ const struct TALER_MERCHANT_OrderPaidResponse *opr)
{
struct PostOrdersPaidState *ops = cls;
ops->oph = NULL;
- if (ops->http_status != hr->http_status)
+ if (ops->http_status != opr->hr.http_status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u (%d) to command %s\n",
- hr->http_status,
- (int) hr->ec,
+ opr->hr.http_status,
+ (int) opr->hr.ec,
TALER_TESTING_interpreter_get_current_label (ops->is));
TALER_TESTING_FAIL (ops->is);
}