[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant] 217/277: implement merchant_api_merchant_get_order.c
From: |
gnunet |
Subject: |
[taler-merchant] 217/277: implement merchant_api_merchant_get_order.c |
Date: |
Sun, 05 Jul 2020 20:52:10 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository merchant.
commit 8716f80c3ad14e5bd8a7af0b424e480aafa18c57
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jun 14 17:22:05 2020 +0200
implement merchant_api_merchant_get_order.c
---
.../taler-merchant-httpd_private-get-orders-ID.c | 7 +-
src/include/taler_merchant_service.h | 11 +-
src/lib/merchant_api_merchant_get_order.c | 324 ++++++++++++++++-----
3 files changed, 253 insertions(+), 89 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index 5c7d6d8..02fda29 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -825,11 +825,10 @@ TMH_private_get_orders_ID (const struct
TMH_RequestHandler *rh,
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
- GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_GET_ORDERS_ORDER_NOT_FOUND,
- "Did not find order in DB");
+ "Did not find contract terms for
order in DB");
}
/* extract the fulfillment URL and total amount from the contract terms! */
@@ -935,11 +934,9 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler
*rh,
hc->instance->settings.id);
ret = TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:s, s:O, s:b, s:s}",
+ "{s:s, s:b, s:s}",
"taler_pay_uri",
taler_pay_uri,
- "contract_terms",
- gorc->contract_terms,
"paid",
false,
"already_paid_order_id",
diff --git a/src/include/taler_merchant_service.h
b/src/include/taler_merchant_service.h
index 4df40af..62e6224 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -1434,7 +1434,7 @@ struct TALER_MERCHANT_WireTransfer
/**
* Base URL of the exchange that made the transfer.
*/
- const char *exchange_uri;
+ const char *exchange_url;
/**
* When the transfer took place (note: may not be exact,
@@ -1523,11 +1523,6 @@ struct TALER_MERCHANT_RefundOrderDetail
struct TALER_MERCHANT_OrderStatusResponse
{
- /**
- * The full contract terms of the order.
- */
- const json_t *contract_terms;
-
/**
* true if the payment is settled, false if not settled.
*/
@@ -1556,9 +1551,9 @@ struct TALER_MERCHANT_OrderStatusResponse
struct TALER_Amount deposit_total;
/**
- * Hash of the contract terms.
+ * The full contract terms of the order.
*/
- struct GNUNET_HashCode h_contract_terms;
+ const json_t *contract_terms;
/**
* Array of wire transfers made for this payment to the
diff --git a/src/lib/merchant_api_merchant_get_order.c
b/src/lib/merchant_api_merchant_get_order.c
index 279376d..2cb5ebd 100644
--- a/src/lib/merchant_api_merchant_get_order.c
+++ b/src/lib/merchant_api_merchant_get_order.c
@@ -65,6 +65,249 @@ struct TALER_MERCHANT_OrderMerchantGetHandle
};
+/**
+ * Function called when we're done processing the GET /private/orders/$ORDER
+ * request and we got an HTTP status of OK and the order was unpaid. Parse
+ * the response and call the callback.
+ *
+ * @param omgh handle for the request
+ * @param[in,out] hr HTTP response we got
+ */
+static void
+handle_unpaid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh,
+ struct TALER_MERCHANT_HttpResponse *hr)
+{
+ const char *taler_pay_uri
+ = json_string_value (json_object_get (hr->reply,
+ "taler_pay_uri"));
+ const char *already_paid_order_id
+ = json_string_value (json_object_get (hr->reply,
+ "already_paid_order_id"));
+ if (NULL == taler_pay_uri)
+ {
+ GNUNET_break_op (0);
+ hr->http_status = 0;
+ hr->ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ NULL);
+ return;
+ }
+ {
+ struct TALER_MERCHANT_OrderStatusResponse osr = {
+ .paid = false,
+ .details.unpaid.taler_pay_uri = taler_pay_uri,
+ .details.unpaid.already_paid_order_id = already_paid_order_id
+ };
+
+ omgh->cb (omgh->cb_cls,
+ hr,
+ &osr);
+ }
+}
+
+
+/**
+ * Function called when we're done processing the GET /private/orders/$ORDER
+ * request and we got an HTTP status of OK and the order was paid. Parse
+ * the response and call the callback.
+ *
+ * @param omgh handle for the request
+ * @param[in,out] hr HTTP response we got
+ */
+static void
+handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh,
+ struct TALER_MERCHANT_HttpResponse *hr)
+{
+ uint32_t ec32;
+ uint32_t hc32;
+ json_t *wire_details;
+ json_t *wire_reports;
+ json_t *refund_details;
+ struct TALER_MERCHANT_OrderStatusResponse osr = {
+ .paid = true
+ };
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_bool ("refunded",
+ &osr.details.paid.refunded),
+ GNUNET_JSON_spec_bool ("wired",
+ &osr.details.paid.wired),
+ TALER_JSON_spec_amount ("deposit_total",
+ &osr.details.paid.deposit_total),
+ GNUNET_JSON_spec_uint32 ("exchange_ec",
+ &ec32),
+ GNUNET_JSON_spec_uint32 ("exchange_hc",
+ &hc32),
+ TALER_JSON_spec_amount ("refund_amount",
+ &osr.details.paid.refund_amount),
+ GNUNET_JSON_spec_json ("contract_terms",
+ (json_t **) &osr.details.paid.contract_terms),
+ GNUNET_JSON_spec_json ("wire_details",
+ &wire_details),
+ GNUNET_JSON_spec_json ("wire_reports",
+ &wire_reports),
+ GNUNET_JSON_spec_json ("refund_details",
+ &refund_details),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (hr->reply,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ hr->http_status = 0;
+ hr->ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ NULL);
+ return;
+ }
+ if (! (json_is_array (wire_details) &&
+ json_is_array (wire_reports) &&
+ json_is_array (refund_details) &&
+ json_is_object (osr.details.paid.contract_terms)) )
+ {
+ GNUNET_break_op (0);
+ hr->http_status = 0;
+ hr->ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ NULL);
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
+ osr.details.paid.exchange_ec = (enum TALER_ErrorCode) ec32;
+ osr.details.paid.exchange_hc = (unsigned int) hc32;
+ {
+ unsigned int wts_len = json_array_size (wire_details);
+ unsigned int wrs_len = json_array_size (wire_reports);
+ unsigned int ref_len = json_array_size (refund_details);
+ struct TALER_MERCHANT_WireTransfer wts[wts_len];
+ struct TALER_MERCHANT_WireReport wrs[wrs_len];
+ struct TALER_MERCHANT_RefundOrderDetail ref[ref_len];
+
+ for (unsigned int i = 0; i<wts_len; i++)
+ {
+ struct TALER_MERCHANT_WireTransfer *wt = &wts[i];
+ const json_t *w = json_array_get (wire_details,
+ i);
+ struct GNUNET_JSON_Specification ispec[] = {
+ GNUNET_JSON_spec_string ("exchange_url",
+ &wt->exchange_url),
+ GNUNET_JSON_spec_fixed_auto ("wtid",
+ &wt->wtid),
+ GNUNET_JSON_spec_absolute_time ("execution_time",
+ &wt->execution_time),
+ TALER_JSON_spec_amount ("amount",
+ &wt->total_amount),
+ GNUNET_JSON_spec_bool ("confirmed",
+ &wt->confirmed),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (w,
+ ispec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ hr->http_status = 0;
+ hr->ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ NULL);
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
+ }
+
+ for (unsigned int i = 0; i<wrs_len; i++)
+ {
+ struct TALER_MERCHANT_WireReport *wr = &wrs[i];
+ const json_t *w = json_array_get (wire_reports, i);
+ uint32_t c32;
+ uint32_t eec32;
+ uint32_t ehs32;
+ struct GNUNET_JSON_Specification ispec[] = {
+ GNUNET_JSON_spec_uint32 ("code",
+ &c32),
+ GNUNET_JSON_spec_uint32 ("exchange_ec",
+ &eec32),
+ GNUNET_JSON_spec_uint32 ("exchange_hc",
+ &ehs32),
+ GNUNET_JSON_spec_string ("hint",
+ &wr->hint),
+ GNUNET_JSON_spec_fixed_auto ("coin_pub",
+ &wr->coin_pub),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (w,
+ ispec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ hr->http_status = 0;
+ hr->ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ NULL);
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
+ wr->code = (enum TALER_ErrorCode) c32;
+ wr->hr.ec = (enum TALER_ErrorCode) eec32;
+ wr->hr.http_status = (unsigned int) ehs32;
+ }
+
+ for (unsigned int i = 0; i<ref_len; i++)
+ {
+ struct TALER_MERCHANT_RefundOrderDetail *ro = &ref[i];
+ const json_t *w = json_array_get (refund_details,
+ i);
+ struct GNUNET_JSON_Specification ispec[] = {
+ TALER_JSON_spec_amount ("amount",
+ &ro->refund_amount),
+ GNUNET_JSON_spec_string ("reason",
+ &ro->reason),
+ GNUNET_JSON_spec_absolute_time ("timestamp",
+ &ro->refund_time),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (w,
+ ispec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ hr->http_status = 0;
+ hr->ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ NULL);
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
+ }
+
+ osr.details.paid.wts = wts;
+ osr.details.paid.wts_len = wts_len;
+ osr.details.paid.wrs = wrs;
+ osr.details.paid.wrs_len = wrs_len;
+ osr.details.paid.refunds = ref;
+ osr.details.paid.refunds_len = ref_len;
+ omgh->cb (omgh->cb_cls,
+ hr,
+ &osr);
+ }
+ GNUNET_JSON_parse_free (spec);
+}
+
+
/**
* Function called when we're done processing the GET /private/orders/$ORDER
* request.
@@ -79,22 +322,13 @@ handle_merchant_order_get_finished (void *cls,
const void *response)
{
struct TALER_MERCHANT_OrderMerchantGetHandle *omgh = cls;
-#if FIXME
- struct TALER_Amount refund_amount = { 0 };
const json_t *json = response;
- const json_t *refunded;
struct TALER_MERCHANT_HttpResponse hr = {
.http_status = (unsigned int) response_code,
.reply = json
};
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount ("refund_amount",
- &refund_amount),
- GNUNET_JSON_spec_end ()
- };
omgh->job = NULL;
-
switch (response_code)
{
case MHD_HTTP_NOT_FOUND:
@@ -102,9 +336,6 @@ handle_merchant_order_get_finished (void *cls,
hr.hint = TALER_JSON_get_error_hint (json);
omgh->cb (omgh->cb_cls,
&hr,
- GNUNET_NO,
- GNUNET_NO,
- NULL,
NULL);
TALER_MERCHANT_merchant_order_get_cancel (omgh);
return;
@@ -121,9 +352,6 @@ handle_merchant_order_get_finished (void *cls,
GNUNET_break_op (0);
omgh->cb (omgh->cb_cls,
&hr,
- GNUNET_SYSERR,
- GNUNET_SYSERR,
- NULL,
NULL);
TALER_MERCHANT_merchant_order_get_cancel (omgh);
return;
@@ -131,67 +359,11 @@ handle_merchant_order_get_finished (void *cls,
/* HTTP OK */
if (! json_boolean_value (json_object_get (json, "paid")))
- {
- const char *taler_pay_uri = json_string_value (json_object_get (json,
-
"taler_pay_uri"));
- if (NULL == taler_pay_uri)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "no taler_pay_uri in unpaid poll-payment response\n");
- GNUNET_break_op (0);
- hr.http_status = 0;
- hr.ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
- omgh->cb (omgh->cb_cls,
- &hr,
- GNUNET_SYSERR,
- GNUNET_SYSERR,
- NULL,
- NULL);
- }
- else
- {
- omgh->cb (omgh->cb_cls,
- &hr,
- GNUNET_NO,
- GNUNET_NO,
- NULL,
- taler_pay_uri);
- }
- TALER_MERCHANT_merchant_order_get_cancel (omgh);
- return;
- }
-
- if ( (NULL == (refunded = json_object_get (json,
- "refunded"))) ||
- ( (json_true () == refunded) &&
- (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL)) ) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "poll payment failed to parse JSON\n");
- GNUNET_break_op (0);
- hr.http_status = 0;
- hr.ec = TALER_EC_MERCHANT_ORDER_GET_REPLY_MALFORMED;
- omgh->cb (omgh->cb_cls,
- &hr,
- GNUNET_SYSERR,
- GNUNET_SYSERR,
- NULL,
- NULL);
- TALER_MERCHANT_merchant_order_get_cancel (omgh);
- return;
- }
-
- omgh->cb (omgh->cb_cls,
- &hr,
- GNUNET_YES,
- (json_true () == refunded),
- (json_true () == refunded) ? &refund_amount : NULL,
- NULL);
-#endif
- TALER_MERCHANT_merchant_order_get_cancel (omgh);
+ handle_unpaid (omgh,
+ &hr);
+ else
+ handle_paid (omgh,
+ &hr);
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-merchant] 208/277: implement missing SQL, (continued)
- [taler-merchant] 208/277: implement missing SQL, gnunet, 2020/07/05
- [taler-merchant] 211/277: adjust API to current spec, gnunet, 2020/07/05
- [taler-merchant] 215/277: this was done by Jonathan, gnunet, 2020/07/05
- [taler-merchant] 213/277: starting with merchant_api_merchant_get_order.c, gnunet, 2020/07/05
- [taler-merchant] 218/277: allow refund_delay to be specified with POST /orders, fix FTBFS, gnunet, 2020/07/05
- [taler-merchant] 216/277: clean up logic: use new EXCHANGE_YNA enum, avoid crazy macro construction to build URLs, use full power of TALER_url_join() instead, gnunet, 2020/07/05
- [taler-merchant] 219/277: tests for new db methods, gnunet, 2020/07/05
- [taler-merchant] 204/277: moved yna to exchange, gnunet, 2020/07/05
- [taler-merchant] 214/277: add logic to parse refund details, gnunet, 2020/07/05
- [taler-merchant] 212/277: adjust GET /orders/ID to match spec, gnunet, 2020/07/05
- [taler-merchant] 217/277: implement merchant_api_merchant_get_order.c,
gnunet <=
- [taler-merchant] 221/277: test for GET /private/reserves/, gnunet, 2020/07/05
- [taler-merchant] 224/277: stricter tests for tips/reserves, gnunet, 2020/07/05
- [taler-merchant] 223/277: implementations, tests, and renames for GET /tips/ & GET /private/tips/, gnunet, 2020/07/05
- [taler-merchant] 226/277: naive tests for the family of GET order(s) methods, gnunet, 2020/07/05
- [taler-merchant] 230/277: add amount checks, gnunet, 2020/07/05
- [taler-merchant] 232/277: 413 limits, gnunet, 2020/07/05
- [taler-merchant] 233/277: improved backenddb tests, gnunet, 2020/07/05
- [taler-merchant] 234/277: add missing notifications to private-get-orders long poller, gnunet, 2020/07/05
- [taler-merchant] 229/277: finish taler-merchant-httpd_reserves implementation, gnunet, 2020/07/05
- [taler-merchant] 235/277: Merge branch 'protocolV1' of git+ssh://git.taler.net/merchant into protocolV1, gnunet, 2020/07/05