diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2017-06-14 15:29:05 +0200 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2017-06-14 15:29:05 +0200 |
commit | 4432516e0d11f513bb5bfa7b4045a74ba28b42f6 (patch) | |
tree | 644d79476a2bcf5685f27e892256b8b9cb6cd95a | |
parent | e486247621e71d4f7586b9439fc98f6dbc8b6fd2 (diff) | |
download | merchant-4432516e0d11f513bb5bfa7b4045a74ba28b42f6.tar.gz merchant-4432516e0d11f513bb5bfa7b4045a74ba28b42f6.tar.bz2 merchant-4432516e0d11f513bb5bfa7b4045a74ba28b42f6.zip |
Implementing POST /refund logic.
-rw-r--r-- | src/backend/taler-merchant-httpd_parsing.c | 3 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_refund.c | 105 | ||||
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 2 |
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 |