LCOV - code coverage report
Current view: top level - lib - merchant_api_get-private-orders-ORDER_ID.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 250 0
Test Date: 2026-04-12 12:58:13 Functions: 0.0 % 8 0

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2018-2026 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU Lesser General Public License as published by the Free Software
       7              :   Foundation; either version 2.1, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU Lesser General Public License along with
      14              :   TALER; see the file COPYING.LGPL.  If not, see
      15              :   <http://www.gnu.org/licenses/>
      16              : */
      17              : /**
      18              :  * @file merchant_api_get-private-orders-ORDER_ID-new.c
      19              :  * @brief Implementation of the GET /private/orders/$ORDER_ID request
      20              :  * @author Christian Grothoff
      21              :  */
      22              : #include "taler/platform.h"
      23              : #include <curl/curl.h>
      24              : #include <jansson.h>
      25              : #include <microhttpd.h> /* just for HTTP status codes */
      26              : #include <gnunet/gnunet_util_lib.h>
      27              : #include <gnunet/gnunet_curl_lib.h>
      28              : #include <taler/merchant/get-private-orders-ORDER_ID.h>
      29              : #include "merchant_api_curl_defaults.h"
      30              : #include <taler/taler_json_lib.h>
      31              : 
      32              : 
      33              : /**
      34              :  * Maximum number of refund details we return.
      35              :  */
      36              : #define MAX_REFUND_DETAILS 1024
      37              : 
      38              : /**
      39              :  * Maximum number of wire details we return.
      40              :  */
      41              : #define MAX_WIRE_DETAILS 1024
      42              : 
      43              : 
      44              : /**
      45              :  * Handle for a GET /private/orders/$ORDER_ID operation.
      46              :  */
      47              : struct TALER_MERCHANT_GetPrivateOrderHandle
      48              : {
      49              :   /**
      50              :    * Base URL of the merchant backend.
      51              :    */
      52              :   char *base_url;
      53              : 
      54              :   /**
      55              :    * The full URL for this request.
      56              :    */
      57              :   char *url;
      58              : 
      59              :   /**
      60              :    * Handle for the request.
      61              :    */
      62              :   struct GNUNET_CURL_Job *job;
      63              : 
      64              :   /**
      65              :    * Function to call with the result.
      66              :    */
      67              :   TALER_MERCHANT_GetPrivateOrderCallback cb;
      68              : 
      69              :   /**
      70              :    * Closure for @a cb.
      71              :    */
      72              :   TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls;
      73              : 
      74              :   /**
      75              :    * Reference to the execution context.
      76              :    */
      77              :   struct GNUNET_CURL_Context *ctx;
      78              : 
      79              :   /**
      80              :    * Order ID.
      81              :    */
      82              :   char *order_id;
      83              : 
      84              :   /**
      85              :    * Session ID for repurchase detection, or NULL.
      86              :    */
      87              :   char *session_id;
      88              : 
      89              :   /**
      90              :    * Long polling timeout.
      91              :    */
      92              :   struct GNUNET_TIME_Relative timeout;
      93              : 
      94              :   /**
      95              :    * Long-poll ETag to suppress unchanged responses.
      96              :    */
      97              :   struct GNUNET_ShortHashCode lp_not_etag;
      98              : 
      99              :   /**
     100              :    * True if @e lp_not_etag was set.
     101              :    */
     102              :   bool have_lp_not_etag;
     103              : 
     104              :   /**
     105              :    * If true, try to obtain wire transfer status from the exchange.
     106              :    */
     107              :   bool transfer;
     108              : 
     109              :   /**
     110              :    * If true, allow refunded orders under already_paid_order_id.
     111              :    */
     112              :   bool allow_refunded_for_repurchase;
     113              : };
     114              : 
     115              : 
     116              : /**
     117              :  * Handle HTTP OK response for an unpaid order.
     118              :  *
     119              :  * @param oph handle for the request
     120              :  * @param[in,out] osr HTTP response we got
     121              :  */
     122              : static void
     123            0 : handle_unpaid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph,
     124              :                struct TALER_MERCHANT_GetPrivateOrderResponse *osr)
     125              : {
     126              :   struct GNUNET_JSON_Specification spec[] = {
     127            0 :     GNUNET_JSON_spec_mark_optional (
     128              :       GNUNET_JSON_spec_string (
     129              :         "already_paid_order_id",
     130              :         &osr->details.ok.details.unpaid.already_paid_order_id),
     131              :       NULL),
     132            0 :     GNUNET_JSON_spec_mark_optional (
     133              :       GNUNET_JSON_spec_string (
     134              :         "already_paid_fulfillment_url",
     135              :         &osr->details.ok.details.unpaid.already_paid_fulfillment_url),
     136              :       NULL),
     137            0 :     GNUNET_JSON_spec_string (
     138              :       "taler_pay_uri",
     139              :       &osr->details.ok.details.unpaid.taler_pay_uri),
     140            0 :     GNUNET_JSON_spec_string (
     141              :       "summary",
     142              :       &osr->details.ok.details.unpaid.summary),
     143            0 :     GNUNET_JSON_spec_mark_optional (
     144              :       GNUNET_JSON_spec_object_const (
     145              :         "proto_contract_terms",
     146              :         &osr->details.ok.details.unpaid.proto_contract_terms),
     147              :       NULL),
     148            0 :     GNUNET_JSON_spec_string (
     149              :       "order_status_url",
     150              :       &osr->details.ok.details.unpaid.order_status_url),
     151            0 :     GNUNET_JSON_spec_timestamp (
     152              :       "creation_time",
     153              :       &osr->details.ok.details.unpaid.creation_time),
     154            0 :     GNUNET_JSON_spec_mark_optional (
     155              :       GNUNET_JSON_spec_timestamp (
     156              :         "pay_deadline",
     157              :         &osr->details.ok.details.unpaid.pay_deadline),
     158              :       NULL),
     159            0 :     GNUNET_JSON_spec_end ()
     160              :   };
     161              : 
     162            0 :   if (GNUNET_OK !=
     163            0 :       GNUNET_JSON_parse (osr->hr.reply,
     164              :                          spec,
     165              :                          NULL, NULL))
     166              :   {
     167            0 :     GNUNET_break_op (0);
     168            0 :     osr->hr.http_status = 0;
     169            0 :     osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     170            0 :     oph->cb (oph->cb_cls,
     171              :              osr);
     172            0 :     return;
     173              :   }
     174            0 :   osr->details.ok.status = TALER_MERCHANT_OSC_UNPAID;
     175            0 :   oph->cb (oph->cb_cls,
     176              :            osr);
     177              : }
     178              : 
     179              : 
     180              : /**
     181              :  * Handle HTTP OK response for a claimed order.
     182              :  *
     183              :  * @param oph handle for the request
     184              :  * @param[in,out] osr HTTP response we got
     185              :  */
     186              : static void
     187            0 : handle_claimed (struct TALER_MERCHANT_GetPrivateOrderHandle *oph,
     188              :                 struct TALER_MERCHANT_GetPrivateOrderResponse *osr)
     189              : {
     190              :   struct GNUNET_JSON_Specification spec[] = {
     191            0 :     GNUNET_JSON_spec_object_const (
     192              :       "contract_terms",
     193              :       &osr->details.ok.details.claimed.contract_terms),
     194            0 :     GNUNET_JSON_spec_mark_optional (
     195              :       GNUNET_JSON_spec_string (
     196              :         "order_status_url",
     197              :         &osr->details.ok.details.claimed.order_status_url),
     198              :       NULL),
     199            0 :     GNUNET_JSON_spec_end ()
     200              :   };
     201              : 
     202            0 :   if (GNUNET_OK !=
     203            0 :       GNUNET_JSON_parse (osr->hr.reply,
     204              :                          spec,
     205              :                          NULL, NULL))
     206              :   {
     207            0 :     GNUNET_break_op (0);
     208            0 :     osr->hr.http_status = 0;
     209            0 :     osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     210            0 :     oph->cb (oph->cb_cls,
     211              :              osr);
     212            0 :     return;
     213              :   }
     214            0 :   osr->details.ok.status = TALER_MERCHANT_OSC_CLAIMED;
     215            0 :   oph->cb (oph->cb_cls,
     216              :            osr);
     217              : }
     218              : 
     219              : 
     220              : /**
     221              :  * Handle HTTP OK response for a paid order.
     222              :  *
     223              :  * @param oph handle for the request
     224              :  * @param[in,out] osr HTTP response we got
     225              :  */
     226              : static void
     227            0 : handle_paid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph,
     228              :              struct TALER_MERCHANT_GetPrivateOrderResponse *osr)
     229              : {
     230              :   uint32_t hc32;
     231              :   uint32_t ci32;
     232              :   bool ci_missing;
     233              :   const json_t *wire_details;
     234              :   const json_t *refund_details;
     235              :   struct GNUNET_JSON_Specification spec[] = {
     236            0 :     GNUNET_JSON_spec_bool ("refunded",
     237              :                            &osr->details.ok.details.paid.refunded),
     238            0 :     GNUNET_JSON_spec_bool ("refund_pending",
     239              :                            &osr->details.ok.details.paid.refund_pending),
     240            0 :     GNUNET_JSON_spec_bool ("wired",
     241              :                            &osr->details.ok.details.paid.wired),
     242            0 :     TALER_JSON_spec_amount_any ("deposit_total",
     243              :                                 &osr->details.ok.details.paid.deposit_total),
     244            0 :     TALER_JSON_spec_ec ("exchange_code",
     245              :                         &osr->details.ok.details.paid.exchange_ec),
     246            0 :     GNUNET_JSON_spec_uint32 ("exchange_http_status",
     247              :                              &hc32),
     248            0 :     TALER_JSON_spec_amount_any ("refund_amount",
     249              :                                 &osr->details.ok.details.paid.refund_amount),
     250            0 :     GNUNET_JSON_spec_object_const (
     251              :       "contract_terms",
     252              :       &osr->details.ok.details.paid.contract_terms),
     253            0 :     GNUNET_JSON_spec_mark_optional (
     254              :       GNUNET_JSON_spec_uint32 ("choice_index",
     255              :                                &ci32),
     256              :       &ci_missing),
     257            0 :     GNUNET_JSON_spec_array_const ("wire_details",
     258              :                                   &wire_details),
     259            0 :     GNUNET_JSON_spec_array_const ("refund_details",
     260              :                                   &refund_details),
     261            0 :     GNUNET_JSON_spec_mark_optional (
     262              :       GNUNET_JSON_spec_timestamp ("last_payment",
     263              :                                   &osr->details.ok.details.paid.last_payment),
     264              :       NULL),
     265            0 :     GNUNET_JSON_spec_string (
     266              :       "order_status_url",
     267              :       &osr->details.ok.details.paid.order_status_url),
     268            0 :     GNUNET_JSON_spec_end ()
     269              :   };
     270              : 
     271            0 :   if (GNUNET_OK !=
     272            0 :       GNUNET_JSON_parse (osr->hr.reply,
     273              :                          spec,
     274              :                          NULL, NULL))
     275              :   {
     276            0 :     GNUNET_break_op (0);
     277            0 :     osr->hr.http_status = 0;
     278            0 :     osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     279            0 :     oph->cb (oph->cb_cls,
     280              :              osr);
     281            0 :     return;
     282              :   }
     283            0 :   osr->details.ok.status = TALER_MERCHANT_OSC_PAID;
     284            0 :   osr->details.ok.details.paid.exchange_hc = (unsigned int) hc32;
     285            0 :   osr->details.ok.details.paid.choice_index = ci_missing
     286              :                                                ? -1
     287            0 :                                                : (int) ci32;
     288              :   {
     289            0 :     unsigned int wts_len = (unsigned int) json_array_size (wire_details);
     290            0 :     unsigned int ref_len = (unsigned int) json_array_size (refund_details);
     291              : 
     292            0 :     if ( (json_array_size (wire_details) != (size_t) wts_len) ||
     293              :          (wts_len > MAX_WIRE_DETAILS) )
     294              :     {
     295            0 :       GNUNET_break (0);
     296            0 :       osr->hr.http_status = 0;
     297            0 :       osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     298            0 :       oph->cb (oph->cb_cls,
     299              :                osr);
     300            0 :       return;
     301              :     }
     302            0 :     if ( (json_array_size (refund_details) != (size_t) ref_len) ||
     303              :          (ref_len > MAX_REFUND_DETAILS) )
     304              :     {
     305            0 :       GNUNET_break (0);
     306            0 :       osr->hr.http_status = 0;
     307            0 :       osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     308            0 :       oph->cb (oph->cb_cls,
     309              :                osr);
     310            0 :       return;
     311              :     }
     312            0 :     {
     313            0 :       struct TALER_MERCHANT_WireTransfer wts[GNUNET_NZL (wts_len)];
     314            0 :       struct TALER_MERCHANT_GetPrivateOrderRefundDetail ref[
     315            0 :         GNUNET_NZL (ref_len)];
     316              : 
     317            0 :       for (unsigned int i = 0; i<wts_len; i++)
     318              :       {
     319            0 :         struct TALER_MERCHANT_WireTransfer *wt = &wts[i];
     320            0 :         const json_t *w = json_array_get (wire_details,
     321              :                                           i);
     322              :         struct GNUNET_JSON_Specification ispec[] = {
     323            0 :           TALER_JSON_spec_web_url ("exchange_url",
     324              :                                    &wt->exchange_url),
     325            0 :           GNUNET_JSON_spec_fixed_auto ("wtid",
     326              :                                        &wt->wtid),
     327            0 :           GNUNET_JSON_spec_timestamp ("execution_time",
     328              :                                       &wt->execution_time),
     329            0 :           TALER_JSON_spec_amount_any ("amount",
     330              :                                       &wt->total_amount),
     331            0 :           GNUNET_JSON_spec_mark_optional (
     332              :             TALER_JSON_spec_amount_any ("deposit_fee",
     333              :                                         &wt->deposit_fee),
     334              :             NULL),
     335            0 :           GNUNET_JSON_spec_bool ("confirmed",
     336              :                                  &wt->confirmed),
     337            0 :           GNUNET_JSON_spec_mark_optional (
     338              :             GNUNET_JSON_spec_uint64 ("expected_transfer_serial_id",
     339              :                                      &wt->expected_transfer_serial_id),
     340              :             NULL),
     341            0 :           GNUNET_JSON_spec_end ()
     342              :         };
     343              : 
     344            0 :         if (GNUNET_OK !=
     345            0 :             GNUNET_JSON_parse (w,
     346              :                                ispec,
     347              :                                NULL, NULL))
     348              :         {
     349            0 :           GNUNET_break_op (0);
     350            0 :           osr->hr.http_status = 0;
     351            0 :           osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     352            0 :           oph->cb (oph->cb_cls,
     353              :                    osr);
     354            0 :           return;
     355              :         }
     356              :       }
     357              : 
     358            0 :       for (unsigned int i = 0; i<ref_len; i++)
     359              :       {
     360            0 :         struct TALER_MERCHANT_GetPrivateOrderRefundDetail *ro = &ref[i];
     361            0 :         const json_t *w = json_array_get (refund_details,
     362              :                                           i);
     363              :         struct GNUNET_JSON_Specification ispec[] = {
     364            0 :           TALER_JSON_spec_amount_any ("amount",
     365              :                                       &ro->refund_amount),
     366            0 :           GNUNET_JSON_spec_string ("reason",
     367              :                                    &ro->reason),
     368            0 :           GNUNET_JSON_spec_bool ("pending",
     369              :                                  &ro->pending),
     370            0 :           GNUNET_JSON_spec_timestamp ("timestamp",
     371              :                                       &ro->refund_time),
     372            0 :           GNUNET_JSON_spec_end ()
     373              :         };
     374              : 
     375            0 :         if (GNUNET_OK !=
     376            0 :             GNUNET_JSON_parse (w,
     377              :                                ispec,
     378              :                                NULL, NULL))
     379              :         {
     380            0 :           GNUNET_break_op (0);
     381            0 :           osr->hr.http_status = 0;
     382            0 :           osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     383            0 :           oph->cb (oph->cb_cls,
     384              :                    osr);
     385            0 :           return;
     386              :         }
     387              :       }
     388              : 
     389            0 :       osr->details.ok.details.paid.wts = wts;
     390            0 :       osr->details.ok.details.paid.wts_len = wts_len;
     391            0 :       osr->details.ok.details.paid.refunds = ref;
     392            0 :       osr->details.ok.details.paid.refunds_len = ref_len;
     393            0 :       oph->cb (oph->cb_cls,
     394              :                osr);
     395              :     }
     396              :   }
     397              : }
     398              : 
     399              : 
     400              : /**
     401              :  * Function called when we're done processing the
     402              :  * HTTP GET /private/orders/$ORDER_ID request.
     403              :  *
     404              :  * @param cls the `struct TALER_MERCHANT_GetPrivateOrderHandle`
     405              :  * @param response_code HTTP response code, 0 on error
     406              :  * @param response response body, NULL if not in JSON
     407              :  */
     408              : static void
     409            0 : handle_get_private_order_finished (void *cls,
     410              :                                    long response_code,
     411              :                                    const void *response)
     412              : {
     413            0 :   struct TALER_MERCHANT_GetPrivateOrderHandle *oph = cls;
     414            0 :   const json_t *json = response;
     415              :   const char *order_status;
     416            0 :   struct TALER_MERCHANT_GetPrivateOrderResponse osr = {
     417            0 :     .hr.http_status = (unsigned int) response_code,
     418              :     .hr.reply = json
     419              :   };
     420              : 
     421            0 :   oph->job = NULL;
     422            0 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     423              :               "Got /private/orders/$ORDER_ID response with status code %u\n",
     424              :               (unsigned int) response_code);
     425            0 :   switch (response_code)
     426              :   {
     427            0 :   case MHD_HTTP_OK:
     428              :     /* see below */
     429            0 :     break;
     430            0 :   case MHD_HTTP_NOT_MODIFIED:
     431            0 :     oph->cb (oph->cb_cls,
     432              :              &osr);
     433            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     434            0 :     return;
     435            0 :   case MHD_HTTP_ACCEPTED:
     436            0 :     oph->cb (oph->cb_cls,
     437              :              &osr);
     438            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     439            0 :     return;
     440            0 :   case MHD_HTTP_UNAUTHORIZED:
     441            0 :     osr.hr.ec = TALER_JSON_get_error_code (json);
     442            0 :     osr.hr.hint = TALER_JSON_get_error_hint (json);
     443            0 :     oph->cb (oph->cb_cls,
     444              :              &osr);
     445            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     446            0 :     return;
     447            0 :   case MHD_HTTP_NOT_FOUND:
     448            0 :     osr.hr.ec = TALER_JSON_get_error_code (json);
     449            0 :     osr.hr.hint = TALER_JSON_get_error_hint (json);
     450            0 :     oph->cb (oph->cb_cls,
     451              :              &osr);
     452            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     453            0 :     return;
     454            0 :   case MHD_HTTP_GATEWAY_TIMEOUT:
     455            0 :     osr.hr.ec = TALER_JSON_get_error_code (json);
     456            0 :     osr.hr.hint = TALER_JSON_get_error_hint (json);
     457            0 :     oph->cb (oph->cb_cls,
     458              :              &osr);
     459            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     460            0 :     return;
     461            0 :   default:
     462            0 :     osr.hr.ec = TALER_JSON_get_error_code (json);
     463            0 :     osr.hr.hint = TALER_JSON_get_error_hint (json);
     464            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     465              :                 "Polling order status failed with HTTP status code %u/%d\n",
     466              :                 (unsigned int) response_code,
     467              :                 (int) osr.hr.ec);
     468            0 :     GNUNET_break_op (0);
     469            0 :     oph->cb (oph->cb_cls,
     470              :              &osr);
     471            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     472            0 :     return;
     473              :   }
     474              : 
     475            0 :   order_status = json_string_value (json_object_get (json,
     476              :                                                      "order_status"));
     477            0 :   if (NULL == order_status)
     478              :   {
     479            0 :     GNUNET_break_op (0);
     480            0 :     osr.hr.http_status = 0;
     481            0 :     osr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     482            0 :     oph->cb (oph->cb_cls,
     483              :              &osr);
     484            0 :     TALER_MERCHANT_get_private_order_cancel (oph);
     485            0 :     return;
     486              :   }
     487              : 
     488            0 :   if (0 == strcmp ("paid",
     489              :                    order_status))
     490              :   {
     491            0 :     handle_paid (oph,
     492              :                  &osr);
     493              :   }
     494            0 :   else if (0 == strcmp ("claimed",
     495              :                         order_status))
     496              :   {
     497            0 :     handle_claimed (oph,
     498              :                     &osr);
     499              :   }
     500            0 :   else if (0 == strcmp ("unpaid",
     501              :                         order_status))
     502              :   {
     503            0 :     handle_unpaid (oph,
     504              :                    &osr);
     505              :   }
     506              :   else
     507              :   {
     508            0 :     GNUNET_break_op (0);
     509            0 :     osr.hr.http_status = 0;
     510            0 :     osr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     511            0 :     oph->cb (oph->cb_cls,
     512              :              &osr);
     513              :   }
     514            0 :   TALER_MERCHANT_get_private_order_cancel (oph);
     515              : }
     516              : 
     517              : 
     518              : struct TALER_MERCHANT_GetPrivateOrderHandle *
     519            0 : TALER_MERCHANT_get_private_order_create (
     520              :   struct GNUNET_CURL_Context *ctx,
     521              :   const char *url,
     522              :   const char *order_id)
     523              : {
     524              :   struct TALER_MERCHANT_GetPrivateOrderHandle *oph;
     525              : 
     526            0 :   oph = GNUNET_new (struct TALER_MERCHANT_GetPrivateOrderHandle);
     527            0 :   oph->ctx = ctx;
     528            0 :   oph->base_url = GNUNET_strdup (url);
     529            0 :   oph->order_id = GNUNET_strdup (order_id);
     530            0 :   return oph;
     531              : }
     532              : 
     533              : 
     534              : enum GNUNET_GenericReturnValue
     535            0 : TALER_MERCHANT_get_private_order_set_options_ (
     536              :   struct TALER_MERCHANT_GetPrivateOrderHandle *oph,
     537              :   unsigned int num_options,
     538              :   const struct TALER_MERCHANT_GetPrivateOrderOptionValue *options)
     539              : {
     540            0 :   for (unsigned int i = 0; i < num_options; i++)
     541              :   {
     542            0 :     const struct TALER_MERCHANT_GetPrivateOrderOptionValue *opt =
     543            0 :       &options[i];
     544              : 
     545            0 :     switch (opt->option)
     546              :     {
     547            0 :     case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END:
     548            0 :       return GNUNET_OK;
     549            0 :     case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID:
     550            0 :       GNUNET_free (oph->session_id);
     551            0 :       if (NULL != opt->details.session_id)
     552            0 :         oph->session_id = GNUNET_strdup (opt->details.session_id);
     553            0 :       break;
     554            0 :     case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT:
     555            0 :       oph->timeout = opt->details.timeout;
     556            0 :       break;
     557            0 :     case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TRANSFER:
     558            0 :       oph->transfer = opt->details.transfer;
     559            0 :       break;
     560            0 :     case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_LP_NOT_ETAG:
     561            0 :       if (NULL != opt->details.lp_not_etag)
     562              :       {
     563            0 :         oph->lp_not_etag = *opt->details.lp_not_etag;
     564            0 :         oph->have_lp_not_etag = true;
     565              :       }
     566            0 :       break;
     567            0 :     case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_ALLOW_REFUNDED_FOR_REPURCHASE:
     568              :       oph->allow_refunded_for_repurchase
     569            0 :         = opt->details.allow_refunded_for_repurchase;
     570            0 :       break;
     571            0 :     default:
     572            0 :       GNUNET_break (0);
     573            0 :       return GNUNET_NO;
     574              :     }
     575              :   }
     576            0 :   return GNUNET_OK;
     577              : }
     578              : 
     579              : 
     580              : enum TALER_ErrorCode
     581            0 : TALER_MERCHANT_get_private_order_start (
     582              :   struct TALER_MERCHANT_GetPrivateOrderHandle *oph,
     583              :   TALER_MERCHANT_GetPrivateOrderCallback cb,
     584              :   TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls)
     585              : {
     586              :   CURL *eh;
     587              :   unsigned int tms;
     588              : 
     589            0 :   oph->cb = cb;
     590            0 :   oph->cb_cls = cb_cls;
     591            0 :   tms = (unsigned int) (oph->timeout.rel_value_us
     592            0 :                         / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
     593              :   {
     594              :     char *path;
     595              :     char timeout_ms[32];
     596              :     char etag_str[sizeof (struct GNUNET_ShortHashCode) * 2 + 1];
     597              : 
     598            0 :     GNUNET_snprintf (timeout_ms,
     599              :                      sizeof (timeout_ms),
     600              :                      "%u",
     601              :                      tms);
     602            0 :     if (oph->have_lp_not_etag)
     603              :     {
     604              :       char *end;
     605              : 
     606            0 :       end = GNUNET_STRINGS_data_to_string (
     607            0 :         &oph->lp_not_etag,
     608              :         sizeof (oph->lp_not_etag),
     609              :         etag_str,
     610              :         sizeof (etag_str) - 1);
     611            0 :       *end = '\0';
     612              :     }
     613            0 :     GNUNET_asprintf (&path,
     614              :                      "private/orders/%s",
     615              :                      oph->order_id);
     616            0 :     oph->url = TALER_url_join (oph->base_url,
     617              :                                path,
     618              :                                "session_id",
     619              :                                oph->session_id,
     620              :                                "timeout_ms",
     621              :                                (0 != tms)
     622              :                                ? timeout_ms
     623              :                                : NULL,
     624              :                                "transfer",
     625            0 :                                oph->transfer
     626              :                                ? "YES"
     627              :                                : NULL,
     628              :                                "lp_not_etag",
     629            0 :                                oph->have_lp_not_etag
     630              :                                ? etag_str
     631              :                                : NULL,
     632              :                                "allow_refunded_for_repurchase",
     633            0 :                                oph->allow_refunded_for_repurchase
     634              :                                ? "YES"
     635              :                                : NULL,
     636              :                                NULL);
     637            0 :     GNUNET_free (path);
     638              :   }
     639            0 :   if (NULL == oph->url)
     640            0 :     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
     641            0 :   eh = TALER_MERCHANT_curl_easy_get_ (oph->url);
     642            0 :   if (NULL == eh)
     643            0 :     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
     644            0 :   if (0 != tms)
     645              :   {
     646            0 :     GNUNET_break (CURLE_OK ==
     647              :                   curl_easy_setopt (eh,
     648              :                                     CURLOPT_TIMEOUT_MS,
     649              :                                     (long) (tms + 100L)));
     650              :   }
     651            0 :   oph->job = GNUNET_CURL_job_add (oph->ctx,
     652              :                                   eh,
     653              :                                   &handle_get_private_order_finished,
     654              :                                   oph);
     655            0 :   if (NULL == oph->job)
     656            0 :     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
     657            0 :   return TALER_EC_NONE;
     658              : }
     659              : 
     660              : 
     661              : void
     662            0 : TALER_MERCHANT_get_private_order_cancel (
     663              :   struct TALER_MERCHANT_GetPrivateOrderHandle *oph)
     664              : {
     665            0 :   if (NULL != oph->job)
     666              :   {
     667            0 :     GNUNET_CURL_job_cancel (oph->job);
     668            0 :     oph->job = NULL;
     669              :   }
     670            0 :   GNUNET_free (oph->url);
     671            0 :   GNUNET_free (oph->order_id);
     672            0 :   GNUNET_free (oph->session_id);
     673            0 :   GNUNET_free (oph->base_url);
     674            0 :   GNUNET_free (oph);
     675            0 : }
     676              : 
     677              : 
     678              : /* end of merchant_api_get-private-orders-ORDER_ID-new.c */
        

Generated by: LCOV version 2.0-1