summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/Makefile.am2
-rw-r--r--src/backend/legacy.c67
-rw-r--r--src/backend/taler-merchant-httpd.c9
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c409
4 files changed, 230 insertions, 257 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 049e0f4e..55029b01 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -22,6 +22,8 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd_auditors.c taler-merchant-httpd_auditors.h \
taler-merchant-httpd_config.c taler-merchant-httpd_config.h \
taler-merchant-httpd_exchanges.c taler-merchant-httpd_exchanges.h \
+ taler-merchant-httpd_get-orders-ID.c \
+ taler-merchant-httpd_get-orders-ID.h \
taler-merchant-httpd_mhd.c taler-merchant-httpd_mhd.h \
taler-merchant-httpd_private-delete-instances-ID.c \
taler-merchant-httpd_private-delete-instances-ID.h \
diff --git a/src/backend/legacy.c b/src/backend/legacy.c
index c105ecb3..2fb7baad 100644
--- a/src/backend/legacy.c
+++ b/src/backend/legacy.c
@@ -1,71 +1,4 @@
/**
- * Create a taler://pay/ URI for the given @a con and @a order_id
- * and @a session_id and @a instance_id.
- *
- * @param con HTTP connection
- * @param order_id the order id
- * @param session_id session, may be NULL
- * @param instance_id instance, may be "default"
- * @return corresponding taler://pay/ URI, or NULL on missing "host"
- */
-char *
-TMH_make_taler_pay_uri (struct MHD_Connection *con,
- const char *order_id,
- const char *session_id,
- const char *instance_id)
-{
- const char *host;
- const char *forwarded_host;
- const char *uri_path;
- const char *uri_instance_id;
- const char *query;
- char *result;
-
- host = MHD_lookup_connection_value (con,
- MHD_HEADER_KIND,
- "Host");
- forwarded_host = MHD_lookup_connection_value (con,
- MHD_HEADER_KIND,
- "X-Forwarded-Host");
-
- uri_path = MHD_lookup_connection_value (con,
- MHD_HEADER_KIND,
- "X-Forwarded-Prefix");
- if (NULL == uri_path)
- uri_path = "-";
- if (NULL != forwarded_host)
- host = forwarded_host;
- if (0 == strcmp (instance_id,
- "default"))
- uri_instance_id = "-";
- else
- uri_instance_id = instance_id;
- if (NULL == host)
- {
- /* Should never happen, at least the host header should be defined */
- GNUNET_break (0);
- return NULL;
- }
-
- if (GNUNET_YES == TALER_mhd_is_https (con))
- query = "";
- else
- query = "?insecure=1";
- GNUNET_assert (NULL != order_id);
- GNUNET_assert (0 < GNUNET_asprintf (&result,
- "taler://pay/%s/%s/%s/%s%s%s%s",
- host,
- uri_path,
- uri_instance_id,
- order_id,
- (NULL == session_id) ? "" : "/",
- (NULL == session_id) ? "" : session_id,
- query));
- return result;
-}
-
-
-/**
* Closure for the #wireformat_iterator_cb().
*/
struct WireFormatIteratorContext
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 27541b53..47443470 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -27,6 +27,7 @@
#include "taler-merchant-httpd_auditors.h"
#include "taler-merchant-httpd_config.h"
#include "taler-merchant-httpd_exchanges.h"
+#include "taler-merchant-httpd_get-orders-ID.h"
#include "taler-merchant-httpd_mhd.h"
#include "taler-merchant-httpd_private-delete-instances-ID.h"
#include "taler-merchant-httpd_private-delete-products-ID.h"
@@ -36,6 +37,7 @@
#include "taler-merchant-httpd_private-get-products.h"
#include "taler-merchant-httpd_private-get-products-ID.h"
#include "taler-merchant-httpd_private-get-orders.h"
+// #include "taler-merchant-httpd_private-get-orders-ID.h"
#include "taler-merchant-httpd_private-patch-instances-ID.h"
#include "taler-merchant-httpd_private-patch-products-ID.h"
#include "taler-merchant-httpd_private-post-instances.h"
@@ -879,6 +881,13 @@ url_handler (void *cls,
.method = MHD_HTTP_METHOD_POST,
.handler = &TMH_post_orders_ID_pay
},
+ /* GET /orders/$ID: */
+ {
+ .url_prefix = "/orders/",
+ .method = MHD_HTTP_METHOD_GET,
+ .have_id_segment = true,
+ .handler = &TMH_get_orders_ID
+ },
{
NULL
}
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index ba0d3544..0fae0a98 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -24,9 +24,8 @@
#include <taler/taler_signatures.h>
#include <taler/taler_json_lib.h>
#include <taler/taler_exchange_service.h>
-#include "taler-merchant-httpd.h"
#include "taler-merchant-httpd_exchanges.h"
-#include "taler-merchant-httpd_refund.h"
+#include "taler-merchant-httpd_get-orders-ID.h"
/**
* How often do we retry DB transactions on serialization failures?
@@ -70,6 +69,12 @@ struct CoinRefund
char *exchange_url;
/**
+ * Fully reply from the exchange, only possibly set if
+ * we got a JSON reply and a non-#MHD_HTTP_OK error code
+ */
+ json_t *exchange_reply;
+
+ /**
* Coin to refund.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -80,14 +85,14 @@ struct CoinRefund
uint64_t rtransaction_id;
/**
- * Amount to refund.
+ * Unique serial number identifying the refund.
*/
- struct TALER_Amount refund_amount;
+ uint64_t refund_serial;
/**
- * Applicable refund transaction fee.
+ * Amount to refund.
*/
- struct TALER_Amount refund_fee;
+ struct TALER_Amount refund_amount;
/**
* Public key of the exchange affirming the refund.
@@ -110,12 +115,6 @@ struct CoinRefund
*/
enum TALER_ErrorCode exchange_code;
- /**
- * Fully reply from the exchange, only possibly set if
- * we got a JSON reply and a non-#MHD_HTTP_OK error code
- */
- json_t *exchange_reply;
-
};
@@ -141,19 +140,19 @@ struct GetOrderData
struct GetOrderData *prev;
/**
- * Context of the request.
+ * Refunds for this order. Head of DLL.
*/
- struct TMH_HandlerContext *hc;
+ struct CoinRefund *cr_head;
/**
- * Did we suspend @a connection?
+ * Refunds for this order. Tail of DLL.
*/
- int suspended;
+ struct CoinRefund *cr_tail;
/**
- * Return code: #TALER_EC_NONE if successful.
+ * Context of the request.
*/
- enum TALER_ErrorCode ec;
+ struct TMH_HandlerContext *hc;
/**
* Entry in the #resume_timeout_heap for this check payment, if we are
@@ -167,11 +166,6 @@ struct GetOrderData
struct MerchantInstance *mi;
/**
- * URL where the final contract can be found for this payment.
- */
- char *final_contract_url;
-
- /**
* order ID for the payment
*/
const char *order_id;
@@ -199,18 +193,22 @@ struct GetOrderData
json_t *contract_terms;
/**
- * Hash of @e contract_terms, set only once @e contract_terms
- * is available.
- */
- struct GNUNET_HashCode h_contract_terms;
-
- /**
* Total refunds granted for this payment. Only initialized
* if @e refunded is set to true.
*/
struct TALER_Amount refund_amount;
/**
+ * Did we suspend @a connection?
+ */
+ int suspended;
+
+ /**
+ * Return code: #TALER_EC_NONE if successful.
+ */
+ enum TALER_ErrorCode ec;
+
+ /**
* Set to true if this payment has been refunded and
* @e refund_amount is initialized.
*/
@@ -227,14 +225,14 @@ struct GetOrderData
/**
- * HEad of DLL of (suspended) requests.
+ * Head of DLL of (suspended) requests.
*/
-static struct GetOrderData *prd_head;
+static struct GetOrderData *god_head;
/**
* Tail of DLL of (suspended) requests.
*/
-static struct GetOrderData *prd_tail;
+static struct GetOrderData *god_tail;
/**
@@ -252,15 +250,105 @@ TMH_force_wallet_get_order_resume (void)
god);
GNUNET_assert (god->suspended);
god->suspended = GNUNET_NO;
- MHD_resume_connection (god->connection);
+ MHD_resume_connection (god->sc.con);
}
}
/**
+ * Suspend this @a god until the trigger is satisfied.
+ *
+ * @param god request to suspend
+ */
+static void
+suspend_god (struct GetOrderData *god)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Suspending GET /orders/%s\n",
+ god->order_id);
+ TMH_long_poll_suspend (god->order_id,
+ god->hc->instance,
+ &god->sc,
+ (god->sc.awaiting_refund)
+ ? &god->sc.refund_expected
+ : NULL);
+}
+
+
+/**
+ * Create a taler://pay/ URI for the given @a con and @a order_id
+ * and @a session_id and @a instance_id.
+ *
+ * @param con HTTP connection
+ * @param order_id the order id
+ * @param session_id session, may be NULL
+ * @param instance_id instance, may be "default"
+ * @return corresponding taler://pay/ URI, or NULL on missing "host"
+ */
+char *
+TMH_make_taler_pay_uri (struct MHD_Connection *con,
+ const char *order_id,
+ const char *session_id,
+ const char *instance_id)
+{
+ const char *host;
+ const char *forwarded_host;
+ const char *uri_path;
+ const char *uri_instance_id;
+ const char *query;
+ char *result;
+
+ host = MHD_lookup_connection_value (con,
+ MHD_HEADER_KIND,
+ "Host");
+ forwarded_host = MHD_lookup_connection_value (con,
+ MHD_HEADER_KIND,
+ "X-Forwarded-Host");
+
+ uri_path = MHD_lookup_connection_value (con,
+ MHD_HEADER_KIND,
+ "X-Forwarded-Prefix");
+ if (NULL == uri_path)
+ uri_path = "-";
+ if (NULL != forwarded_host)
+ host = forwarded_host;
+ if (0 == strcmp (instance_id,
+ "default"))
+ uri_instance_id = "-";
+ else
+ uri_instance_id = instance_id;
+ if (NULL == host)
+ {
+ /* Should never happen, at least the host header should be defined */
+ GNUNET_break (0);
+ return NULL;
+ }
+
+ if (GNUNET_YES == TALER_mhd_is_https (con))
+ query = "";
+ else
+ query = "?insecure=1";
+ GNUNET_assert (NULL != order_id);
+ GNUNET_assert (0 < GNUNET_asprintf (&result,
+ "taler://pay/%s/%s/%s/%s%s%s%s",
+ host,
+ uri_path,
+ uri_instance_id,
+ order_id,
+ (NULL == session_id) ? "" : "/",
+ (NULL == session_id) ? "" : session_id,
+ query));
+ return result;
+}
+
+
+/**
* The client did not yet pay, send it the payment request.
*
* @param god check pay request context
+ * @param already_paid_order_id if for the fulfillment URI there is
+ * already a paid order, this is the order ID to redirect
+ * the wallet to; NULL if not applicable
* @return #MHD_YES on success
*/
static MHD_RESULT
@@ -287,13 +375,12 @@ send_pay_request (struct GetOrderData *god,
taler_pay_uri = TMH_make_taler_pay_uri (god->sc.con,
god->order_id,
god->session_id,
- god->mi->id);
+ god->hc->instance->settings.id);
ret = TALER_MHD_reply_json_pack (god->sc.con,
MHD_HTTP_OK,
- "{s:s, s:s, s:b, s:s?}",
+ "{s:s, s:b, s:s?}",
"taler_pay_uri", taler_pay_uri,
- "contract_url", god->final_contract_url,
- "paid", 0,
+ "paid", false,
"already_paid_order_id",
already_paid_order_id);
GNUNET_free (taler_pay_uri);
@@ -305,25 +392,20 @@ send_pay_request (struct GetOrderData *god,
* Check if @a god has sub-activities still pending.
*
* @param god request to check
- * @return #GNUNET_YES if activities are still pending
+ * @return true if activities are still pending
*/
-static int
+static bool
god_pending (struct GetOrderData *god)
{
- int pending = GNUNET_NO;
-
for (struct CoinRefund *cr = god->cr_head;
NULL != cr;
cr = cr->next)
{
if ( (NULL != cr->fo) ||
(NULL != cr->rh) )
- {
- pending = GNUNET_YES;
- break;
- }
+ return true;
}
- return pending;
+ return false;
}
@@ -342,7 +424,7 @@ check_resume_god (struct GetOrderData *god)
god);
GNUNET_assert (god->suspended);
god->suspended = GNUNET_NO;
- MHD_resume_connection (god->connection);
+ MHD_resume_connection (god->sc.con);
TMH_trigger_daemon ();
}
@@ -381,13 +463,10 @@ refund_cb (void *cls,
cr->exchange_pub = *exchange_pub;
cr->exchange_sig = *exchange_sig;
- qs = db->put_refund_proof (db->cls,
- &cr->god->merchant->pubkey,
- &cr->god->h_contract_terms,
- &cr->coin_pub,
- cr->rtransaction_id,
- exchange_pub,
- exchange_sig);
+ qs = TMH_db->insert_refund_proof (TMH_db->cls,
+ cr->refund_serial,
+ exchange_sig,
+ exchange_pub);
if (0 >= qs)
{
/* generally, this is relatively harmless for the merchant, but let's at
@@ -425,11 +504,10 @@ exchange_found_cb (void *cls,
{
cr->rh = TALER_EXCHANGE_refund (eh,
&cr->refund_amount,
- &cr->refund_fee,
&cr->god->h_contract_terms,
&cr->coin_pub,
cr->rtransaction_id,
- &cr->god->merchant->privkey,
+ &cr->god->hc->instance->merchant_priv,
&refund_cb,
cr);
return;
@@ -442,25 +520,27 @@ exchange_found_cb (void *cls,
/**
- * Function called with information about a refund.
+ * Function called with detailed information about a refund.
* It is responsible for packing up the data to return.
*
* @param cls closure
+ * @param refund_serial unique serial number of the refund
+ * @param timestamp time of the refund (for grouping of refunds in the wallet UI)
* @param coin_pub public coin from which the refund comes from
* @param exchange_url URL of the exchange that issued @a coin_pub
* @param rtransaction_id identificator of the refund
* @param reason human-readable explanation of the refund
* @param refund_amount refund amount which is being taken from @a coin_pub
- * @param refund_fee cost of this refund operation
*/
static void
process_refunds_cb (void *cls,
+ uint64_t refund_serial,
+ struct GNUNET_TIME_Absolute timestamp,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const char *exchange_url,
uint64_t rtransaction_id,
const char *reason,
- const struct TALER_Amount *refund_amount,
- const struct TALER_Amount *refund_fee)
+ const struct TALER_Amount *refund_amount)
{
struct GetOrderData *god = cls;
struct CoinRefund *cr;
@@ -471,12 +551,12 @@ process_refunds_cb (void *cls,
TALER_amount2s (refund_amount),
reason);
cr = GNUNET_new (struct CoinRefund);
+ cr->refund_serial = refund_serial;
cr->exchange_url = GNUNET_strdup (exchange_url);
cr->god = god;
cr->coin_pub = *coin_pub;
cr->rtransaction_id = rtransaction_id;
cr->refund_amount = *refund_amount;
- cr->refund_fee = *refund_fee;
GNUNET_CONTAINER_DLL_insert (god->cr_head,
god->cr_tail,
cr);
@@ -494,27 +574,6 @@ process_refunds_cb (void *cls,
/**
- * Suspend this @a god until the trigger is satisfied.
- *
- * @param ppr
- */
-static void
-suspend_god (struct GetOrderData *god)
-{
- TMH_compute_pay_key (god->order_id,
- &god->mi->pubkey,
- &god->sc.key);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Suspending /poll-payment on key %s\n",
- GNUNET_h2s (&god->sc.key));
- TMH_long_poll_suspend (&god->sc,
- (god->sc.awaiting_refund)
- ? &god->sc.refund_expected
- : NULL);
-}
-
-
-/**
* Clean up the session state for a GET /orders/$ID request.
*
* @param cls must be a `struct GetOrderData *`
@@ -523,6 +582,7 @@ static void
god_cleanup (void *cls)
{
struct GetOrderData *god = cls;
+ struct CoinRefund *cr;
while (NULL != (cr = god->cr_head))
{
@@ -550,7 +610,6 @@ god_cleanup (void *cls)
if (NULL != god->contract_terms)
json_decref (god->contract_terms);
- GNUNET_free_non_null (god->final_contract_url);
GNUNET_free (god);
}
@@ -576,10 +635,9 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
{
god = GNUNET_new (struct GetOrderData);
hc->ctx = god;
- god->hc.cc = &god_cleanup;
+ hc->cc = &god_cleanup;
god->sc.con = connection;
god->ec = TALER_EC_NONE;
- god->connection = connection;
god->hc = hc;
god->ret = GNUNET_SYSERR;
@@ -666,36 +724,16 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
}
}
- // FIXME: what is this about again???
- god->contract_url = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- "contract_url");
- if (NULL == god->contract_url)
- {
- // FIXME: this can't be right anymore...
- god->final_contract_url = TALER_url_absolute_mhd (connection,
- "/public/proposal",
- "instance", mi->id,
- "order_id",
- god->order_id,
- NULL);
- GNUNET_assert (NULL != god->final_contract_url);
- }
- else
- {
- god->final_contract_url = GNUNET_strdup (god->contract_url);
- }
-
god->session_id = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
"session_id");
- /* Convert order id to h_contract_terms */
- db->preflight (db->cls);
- qs = db->find_contract_terms (db->cls,
- hc->instance->settings.id,
- order_id,
- &god->contract_terms);
+ /* Convert order_id to h_contract_terms */
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->lookup_contract_terms (TMH_db->cls,
+ hc->instance->settings.id,
+ order_id,
+ &god->contract_terms);
if (0 > qs)
{
/* single, read-only SQL statements should never cause
@@ -705,7 +743,7 @@ TMH_get_orders_ID (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_REFUND_LOOKUP_DB_ERROR,
+ TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
"database error looking up contract");
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -715,7 +753,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
order_id);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
- TALER_EC_ORDER_ID_UNKNOWN,
+ TALER_EC_GET_ORDERS_ID_UNKNOWN,
"order_id not found in database");
}
@@ -741,7 +779,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
- TALER_EC_WRONG_CONTRACT,
+ TALER_EC_GET_ORDERS_WRONG_CONTRACT,
"Contract hash does not match order");
}
}
@@ -761,7 +799,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_CHECK_PAYMENT_DB_FETCH_CONTRACT_TERMS_ERROR,
+ TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
"Merchant database error (contract terms corrupted)");
}
}
@@ -773,11 +811,11 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
/* Check if paid within a session. */
char *already_paid_order_id = NULL;
- qs = db->find_session_info (db->cls,
- &already_paid_order_id,
- god->session_id,
- god->fulfillment_url,
- &mi->pubkey);
+ qs = TMH_db->lookup_order_by_fulfillment (TMH_db->cls,
+ hc->instance->settings.id,
+ god->fulfillment_url,
+ god->session_id,
+ &already_paid_order_id);
if (qs < 0)
{
/* single, read-only SQL statements should never cause
@@ -787,17 +825,21 @@ TMH_get_orders_ID (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_CHECK_PAYMENT_DB_FETCH_ORDER_ERROR,
+ TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
"db error fetching pay session info");
}
- else if (0 == qs)
+ if (0 == qs)
{
+ MHD_RESULT ret;
+
ret = send_pay_request (god,
already_paid_order_id);
GNUNET_free_non_null (already_paid_order_id);
return ret;
}
GNUNET_break (1 == qs);
+ // FIXME: eh, what? shouldn't we be possibly REDIRECTING to
+ // already_paid_order_id?
GNUNET_break (0 == strcmp (order_id,
already_paid_order_id));
GNUNET_free_non_null (already_paid_order_id);
@@ -805,48 +847,47 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
else
{
/* Check if paid regardless of session. */
- json_t *xcontract_terms = NULL;
-
- qs = db->find_paid_contract_terms_from_hash (db->cls,
- &xcontract_terms,
- &god->h_contract_terms,
- &mi->pubkey);
- if (0 > qs)
+ struct GNUNET_HashCode h_contract;
+ bool paid;
+
+ qs = TMH_db->lookup_order_status (TMH_db->cls,
+ hc->instance->settings.id,
+ order_id,
+ &h_contract,
+ &paid);
+ if (0 >= qs)
{
/* Always report on hard error as well to enable diagnostics */
GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR,
+ TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
"Merchant database error");
}
- if (0 == qs)
+ GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
+ GNUNET_break (0 ==
+ GNUNET_memcmp (&h_contract,
+ &god->h_contract_terms));
+ if (! paid)
{
return send_pay_request (god,
NULL);
}
- GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
- GNUNET_assert (NULL != xcontract_terms);
- json_decref (xcontract_terms);
}
-
- for (unsigned int i = 0; i<MAX_RETRIES; i++)
- {
- qs = db->get_refunds_from_contract_terms_hash (db->cls,
- hc->instance->settings.id,
- &god->h_contract_terms,
- &process_refunds_cb,
- god);
- if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
- break;
- }
+ /* At this point, we know the contract was paid. Let's check for
+ refunds */
+ qs = TMH_db->lookup_refunds_detailed (TMH_db->cls,
+ hc->instance->settings.id,
+ &god->h_contract_terms,
+ &process_refunds_cb,
+ god);
if (0 > qs)
{
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_REFUND_LOOKUP_DB_ERROR,
+ TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
"Failed to lookup refunds for contract");
}
@@ -858,28 +899,37 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
{
enum GNUNET_DB_QueryStatus qs;
- qs = db->get_refund_proof (db->cls,
- &cr->god->merchant->pubkey,
- &cr->god->h_contract_terms,
- &cr->coin_pub,
- cr->rtransaction_id,
- &cr->exchange_pub,
- &cr->exchange_sig);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+ qs = TMH_db->lookup_refund_proof (TMH_db->cls,
+ cr->refund_serial,
+ &cr->exchange_sig,
+ &cr->exchange_pub);
+ switch (qs)
{
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ 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,
+ "Merchant database error");
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
/* We need to talk to the exchange */
cr->fo = TMH_EXCHANGES_find_exchange (cr->exchange_url,
NULL,
GNUNET_NO,
&exchange_found_cb,
cr);
+ break;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ /* We got a reply earlier, set status accordingly */
+ cr->exchange_status = MHD_HTTP_OK;
+ break;
}
}
- if ( (god->awaiting_refund) &&
+ if ( (god->sc.awaiting_refund) &&
( (! god->refunded) ||
(1 != TALER_amount_cmp (&god->refund_amount,
- &god->min_refund)) ) )
+ &god->sc.refund_expected)) ) )
{
/* Client is waiting for a refund larger than what we have, suspend
until timeout */
@@ -891,15 +941,14 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
/* yes, indeed suspend */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Awaiting refund exceeding %s\n",
- TALER_amount2s (&god->min_refund));
+ TALER_amount2s (&god->sc.refund_expected));
suspend_god (god);
return MHD_YES;
}
}
-
/* Check if there are still exchange operations pending */
- if (GNUNET_YES == god_pending (god))
+ if (god_pending (god))
{
if (! god->suspended)
{
@@ -928,14 +977,12 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
ra,
(MHD_HTTP_OK != cr->exchange_status)
? json_pack ((NULL != cr->exchange_reply)
- ? "{s:o,s:o,s:o,s:I,s:I,s:I,s:O}"
- : "{s:o,s:o,s:o,s:I,s:I:s:I}",
+ ? "{s:o,s:o,s:I,s:I,s:I,s:O}"
+ : "{s:o,s:o,s:I,s:I:s:I}",
"coin_pub",
GNUNET_JSON_from_data_auto (&cr->coin_pub),
"refund_amount",
TALER_JSON_from_amount (&cr->refund_amount),
- "refund_fee",
- TALER_JSON_from_amount (&cr->refund_fee),
"exchange_http_status",
(json_int_t) cr->exchange_status,
"rtransaction_id",
@@ -944,13 +991,11 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
(json_int_t) cr->exchange_code,
"exchange_reply",
cr->exchange_reply)
- : json_pack ("{s:o,s:o,s:o,s:I,s:I,s:o,s:o}",
+ : json_pack ("{s:o,s:o,s:I,s:I,s:o,s:o}",
"coin_pub",
GNUNET_JSON_from_data_auto (&cr->coin_pub),
"refund_amount",
TALER_JSON_from_amount (&cr->refund_amount),
- "refund_fee",
- TALER_JSON_from_amount (&cr->refund_fee),
"exchange_http_status",
(json_int_t) cr->exchange_status,
"rtransaction_id",
@@ -962,32 +1007,16 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
)));
}
- if (god->refunded)
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:b, s:b, s:o}",
- "paid", 1,
- "refunded", god->refunded,
- "refund_amount",
- TALER_JSON_from_amount (
- &god->refund_amount));
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:b, s:b }",
- "paid", 1,
- "refunded", 0);
-
-
- return TALER_MHD_reply_json_pack (
- connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o}",
- "refunds",
- ra,
- "merchant_pub",
- GNUNET_JSON_from_data_auto (&mi->pubkey),
- "h_contract_terms",
- GNUNET_JSON_from_data_auto (&god->h_contract_terms));
+ "{s:b, s:b, s:o, s:o}",
+ "paid", true,
+ "refunded", god->refunded,
+ "refund_amount",
+ TALER_JSON_from_amount (
+ &god->refund_amount),
+ "refunds",
+ ra);
}
}