diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/merchant_api_merchant_get_order.c | 324 |
1 files changed, 248 insertions, 76 deletions
diff --git a/src/lib/merchant_api_merchant_get_order.c b/src/lib/merchant_api_merchant_get_order.c index 279376d3..2cb5ebdf 100644 --- a/src/lib/merchant_api_merchant_get_order.c +++ b/src/lib/merchant_api_merchant_get_order.c @@ -67,6 +67,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. * * @param cls the `struct TALER_MERCHANT_OrderMerchantGetHandle` @@ -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); } |