diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_post-orders-ID-refund.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-refund.c | 101 |
1 files changed, 72 insertions, 29 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c index cc12dc03..8c445680 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c @@ -130,8 +130,7 @@ struct PostRefundData { /** - * Hashed version of contract terms. All zeros if - * not provided. + * Hashed version of contract terms. All zeros if not provided. */ struct GNUNET_HashCode h_contract_terms; @@ -215,6 +214,11 @@ struct PostRefundData enum TALER_ErrorCode ec; /** + * HTTP status to use for the reply, 0 if not yet known. + */ + unsigned int http_status; + + /** * Set to true if we are dealing with an unclaimed order * (and thus @e h_contract_terms is not set, and certain * DB queries will not work). @@ -340,7 +344,8 @@ exchange_operations_pending (struct PostRefundData *prd) static void check_resume_prd (struct PostRefundData *prd) { - if (exchange_operations_pending (prd)) + if ( (TALER_EC_NONE == prd->ec) && + exchange_operations_pending (prd) ) return; GNUNET_CONTAINER_DLL_remove (prd_head, prd_tail, @@ -423,25 +428,34 @@ exchange_found_cb (void *cls, bool exchange_trusted) { struct CoinRefund *cr = cls; + struct PostRefundData *prd = cr->prd; (void) payto_uri; + (void) wire_fee; + (void) exchange_trusted; cr->fo = NULL; - if (TALER_EC_NONE == hr->ec) + if (NULL == hr) { - cr->rh = TALER_EXCHANGE_refund (eh, - &cr->refund_amount, - &cr->prd->h_contract_terms, - &cr->coin_pub, - cr->rtransaction_id, - &cr->prd->hc->instance->merchant_priv, - &refund_cb, - cr); + prd->http_status = MHD_HTTP_GATEWAY_TIMEOUT; + prd->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT; + check_resume_prd (prd); return; } - cr->exchange_status = hr->http_status; - cr->exchange_code = hr->ec; - cr->exchange_reply = json_incref ((json_t*) hr->reply); - check_resume_prd (cr->prd); + if (NULL == eh) + { + prd->http_status = MHD_HTTP_BAD_GATEWAY; + prd->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE; + check_resume_prd (prd); + return; + } + cr->rh = TALER_EXCHANGE_refund (eh, + &cr->refund_amount, + &prd->h_contract_terms, + &cr->coin_pub, + cr->rtransaction_id, + &prd->hc->instance->merchant_priv, + &refund_cb, + cr); } @@ -569,16 +583,16 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh, GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, - NULL); + TALER_EC_GENERIC_DB_FETCH_FAILED, + "contract terms"); } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { json_decref (contract_terms); return TALER_MHD_reply_with_error (connection, MHD_HTTP_NOT_FOUND, - TALER_EC_GET_ORDERS_ORDER_NOT_FOUND, - NULL); + TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN, + hc->infix); } { struct GNUNET_HashCode h_contract_terms; @@ -590,21 +604,50 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh, json_decref (contract_terms); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH, + TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH, NULL); } json_decref (contract_terms); if (0 != GNUNET_memcmp (&h_contract_terms, &prd->h_contract_terms)) { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_GET_ORDER_WRONG_CONTRACT, - NULL); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_MERCHANT_GENERIC_CONTRACT_HASH_DOES_NOT_MATCH_ORDER, + NULL); } } } } + + if (TALER_EC_NONE != prd->ec) + { + GNUNET_break (0 != prd->http_status); + /* kill pending coin refund operations immediately, just to be + extra sure they don't modify 'prd' after we already created + a reply (this might not be needed, but feels safer). */ + for (struct CoinRefund *cr = prd->cr_head; + NULL != cr; + cr = cr->next) + { + if (NULL != cr->fo) + { + TMH_EXCHANGES_find_exchange_cancel (cr->fo); + cr->fo = NULL; + } + if (NULL != cr->rh) + { + TALER_EXCHANGE_refund_cancel (cr->rh); + cr->rh = NULL; + } + } + return TALER_MHD_reply_with_error (connection, + prd->http_status, + prd->ec, + NULL); + } + { GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (TMH_currency, &prd->refund_amount)); @@ -618,8 +661,8 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh, GNUNET_break (0); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR, - NULL); + TALER_EC_GENERIC_DB_FETCH_FAILED, + "detailed refunds"); } } @@ -641,8 +684,8 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh, case GNUNET_DB_STATUS_SOFT_ERROR: return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR, - NULL); + TALER_EC_GENERIC_DB_FETCH_FAILED, + "refund proof"); case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: if (NULL == cr->exchange_reply) { |