summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcello Stanisci <marcello.stanisci@inria.fr>2017-06-14 15:29:05 +0200
committerMarcello Stanisci <marcello.stanisci@inria.fr>2017-06-14 15:29:05 +0200
commit4432516e0d11f513bb5bfa7b4045a74ba28b42f6 (patch)
tree644d79476a2bcf5685f27e892256b8b9cb6cd95a
parente486247621e71d4f7586b9439fc98f6dbc8b6fd2 (diff)
downloadmerchant-4432516e0d11f513bb5bfa7b4045a74ba28b42f6.tar.gz
merchant-4432516e0d11f513bb5bfa7b4045a74ba28b42f6.tar.bz2
merchant-4432516e0d11f513bb5bfa7b4045a74ba28b42f6.zip
Implementing POST /refund logic.
-rw-r--r--src/backend/taler-merchant-httpd_parsing.c3
-rw-r--r--src/backend/taler-merchant-httpd_refund.c105
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c2
3 files changed, 108 insertions, 2 deletions
diff --git a/src/backend/taler-merchant-httpd_parsing.c b/src/backend/taler-merchant-httpd_parsing.c
index 754ea902..6dc91ac1 100644
--- a/src/backend/taler-merchant-httpd_parsing.c
+++ b/src/backend/taler-merchant-httpd_parsing.c
@@ -303,6 +303,9 @@ TMH_PARSE_json_data (struct MHD_Connection *connection,
{
if (NULL == error_json_name)
error_json_name = "<no field>";
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Parsing failed due to field '%s'\n",
+ error_json_name);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
diff --git a/src/backend/taler-merchant-httpd_refund.c b/src/backend/taler-merchant-httpd_refund.c
index a55eb707..6167a9fc 100644
--- a/src/backend/taler-merchant-httpd_refund.c
+++ b/src/backend/taler-merchant-httpd_refund.c
@@ -85,7 +85,21 @@ MH_handler_refund_increase (struct TMH_RequestHandler *rh,
{
int res;
struct TMH_JsonParseContext *ctx;
+ struct TALER_Amount refund;
json_t *root;
+ json_t *contract_terms;
+ const char *order_id;
+ const char *reason;
+ struct MerchantInstance *mi;
+ struct GNUNET_HashCode h_contract_terms;
+
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_amount ("refund", &refund),
+ GNUNET_JSON_spec_string ("order_id", &order_id),
+ GNUNET_JSON_spec_string ("reason", &reason),
+ GNUNET_JSON_spec_end
+ };
+
if (NULL == *connection_cls)
{
@@ -109,9 +123,98 @@ MH_handler_refund_increase (struct TMH_RequestHandler *rh,
if ((GNUNET_NO == res) || (NULL == root))
return MHD_YES;
- /* FIXME: TBD */
+ res = TMH_PARSE_json_data (connection,
+ root,
+ spec);
+ if (GNUNET_NO == res)
+ {
+ GNUNET_break_op (0);
+ return MHD_YES;
+ }
+
+ if (GNUNET_SYSERR == res)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Hard error from JSON parser\n");
+ return MHD_NO;
+ }
+
+ mi = get_instance (root);
+ if (NULL == mi)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No instance found\n");
+ GNUNET_JSON_parse_free (spec);
+ return TMH_RESPONSE_reply_not_found (connection,
+ TALER_EC_REFUND_INSTANCE_UNKNOWN,
+ "Unknown instance given");
+ }
+
+ /* Convert order id to h_contract_terms */
+ if (GNUNET_OK != db->find_contract_terms (db->cls,
+ &contract_terms,
+ order_id,
+ &mi->pubkey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unknown order id given: %s\n",
+ order_id);
+ return TMH_RESPONSE_reply_not_found (connection,
+ TALER_EC_REFUND_ORDER_ID_UNKNOWN,
+ "Order id not found in database");
+ }
+
+ if (GNUNET_OK !=
+ TALER_JSON_hash (contract_terms,
+ &h_contract_terms))
+ {
+ GNUNET_JSON_parse_free (spec);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Could not hash contract terms\n");
+ /**
+ * Do we really need a error code for failing to hash something?
+ * The HTTP 500 Internal server error sufficies for now.
+ */
+ return TMH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_NONE,
+ "Could not hash contract terms");
+ }
+
+ res = db->increase_refund_for_contract (db->cls,
+ &h_contract_terms,
+ &mi->pubkey,
+ &refund,
+ reason);
+ if (GNUNET_NO == res)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Inconsistent refund amount: %s\n",
+ TALER_amount_to_string (&refund));
+ GNUNET_JSON_parse_free (spec);
+ /**
+ * FIXME: should the db function distinguish between a refund amount
+ * lower than the previous one and a one which is too big to be paid back?
+ */
+ return TMH_RESPONSE_reply_external_error (connection,
+ TALER_EC_REFUND_INCONSISTENT_AMOUNT,
+ "Amount either lower than the previous"
+ " or too big to be paid back");
+ }
+
+ /**
+ * FIXME: return to the frontend. The frontend will then return
+ * a "402 Payment required" carrying a "X-Taler-Refund-Url: www"
+ * where 'www' is the URL where the wallet can automatically fetch
+ * the refund permission.
+ *
+ * Just a "200 OK" should be fine here, as the frontend has all
+ * the information needed to generate the right response.
+ */
+ return MHD_YES;
+ json_decref (contract_terms);
json_decref (root);
+ GNUNET_JSON_parse_free (spec);
return res;
}
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 33350513..679b0552 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -602,7 +602,7 @@ postgres_find_contract_terms_from_hash (void *cls,
* Retrieve proposal data given its order id.
*
* @param cls closure
- * @param[out] contract_terms where to store the retrieved proposal data
+ * @param[out] contract_terms where to store the retrieved contract terms
* @param order id order id used to perform the lookup
* @return #GNUNET_OK on success, #GNUNET_NO if no proposal is
* found, #GNUNET_SYSERR upon error