merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

merchant_api_post-templates-TEMPLATE_ID.c (6665B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2022-2023 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU Lesser General Public License as
      7   published by the Free Software Foundation; either version 2.1,
      8   or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General
     16   Public License along with TALER; see the file COPYING.LGPL.
     17   If not, see <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file merchant_api_post-templates-TEMPLATE_ID.c
     21  * @brief Implementation of the POST /using_templates request
     22  *        of the merchant's HTTP API
     23  * @author Priscilla HUANG
     24  */
     25 #include "taler/platform.h"
     26 #include <curl/curl.h>
     27 #include <jansson.h>
     28 #include <microhttpd.h> /* just for HTTP status codes */
     29 #include <gnunet/gnunet_util_lib.h>
     30 #include "taler/taler_merchant_service.h"
     31 #include "merchant_api_common.h"
     32 #include "merchant_api_curl_defaults.h"
     33 #include <taler/taler_json_lib.h>
     34 #include <taler/taler_curl_lib.h>
     35 
     36 
     37 /**
     38  * Handle for a POST /templates/$ID operation.
     39  */
     40 struct TALER_MERCHANT_UsingTemplatesPostHandle
     41 {
     42 
     43   /**
     44    * The url for this request.
     45    */
     46   char *url;
     47 
     48   /**
     49    * Handle for the request.
     50    */
     51   struct GNUNET_CURL_Job *job;
     52 
     53   /**
     54    * Function to call with the result.
     55    */
     56   TALER_MERCHANT_PostOrdersCallback cb;
     57 
     58   /**
     59    * Closure for @a cb.
     60    */
     61   void *cb_cls;
     62 
     63   /**
     64    * Reference to the execution context.
     65    */
     66   struct GNUNET_CURL_Context *ctx;
     67 
     68   /**
     69    * Minor context that holds body and headers.
     70    */
     71   struct TALER_CURL_PostContext post_ctx;
     72 };
     73 
     74 /**
     75  * Function called when we're done processing the
     76  * HTTP POST /using-templates request.
     77  *
     78  * @param cls the `struct TALER_MERCHANT_UsingTemplatesPostHandle`
     79  * @param response_code HTTP response code, 0 on error
     80  * @param response response body, NULL if not in JSON
     81  */
     82 static void
     83 handle_post_using_templates_finished (void *cls,
     84                                       long response_code,
     85                                       const void *response)
     86 {
     87   struct TALER_MERCHANT_UsingTemplatesPostHandle *utph = cls;
     88   const json_t *json = response;
     89 
     90   utph->job = NULL;
     91   TALER_MERCHANT_handle_order_creation_response_ (utph->cb,
     92                                                   utph->cb_cls,
     93                                                   response_code,
     94                                                   json);
     95   TALER_MERCHANT_using_templates_post_cancel (utph);
     96 }
     97 
     98 
     99 /**
    100  * Helper to submit a POST /templates/$ID request.
    101  *
    102  * @param ctx the context
    103  * @param backend_url HTTP base URL for the backend
    104  * @param template_id identifier of the template to use
    105  * @param req_obj JSON request body (consumed)
    106  * @param cb function to call with the backend's result
    107  * @param cb_cls closure for @a cb
    108  * @return the request handle; NULL upon error
    109  */
    110 static struct TALER_MERCHANT_UsingTemplatesPostHandle *
    111 using_templates_post_internal (
    112   struct GNUNET_CURL_Context *ctx,
    113   const char *backend_url,
    114   const char *template_id,
    115   json_t *req_obj,
    116   TALER_MERCHANT_PostOrdersCallback cb,
    117   void *cb_cls)
    118 {
    119   struct TALER_MERCHANT_UsingTemplatesPostHandle *utph;
    120 
    121   utph = GNUNET_new (struct TALER_MERCHANT_UsingTemplatesPostHandle);
    122   utph->ctx = ctx;
    123   utph->cb = cb;
    124   utph->cb_cls = cb_cls;
    125   {
    126     char *path;
    127 
    128     GNUNET_asprintf (&path,
    129                      "templates/%s",
    130                      template_id);
    131     utph->url = TALER_url_join (backend_url,
    132                                 path,
    133                                 NULL);
    134     GNUNET_free (path);
    135   }
    136   if (NULL == utph->url)
    137   {
    138     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    139                 "Could not construct request URL.\n");
    140     json_decref (req_obj);
    141     GNUNET_free (utph);
    142     return NULL;
    143   }
    144   {
    145     CURL *eh;
    146 
    147     eh = TALER_MERCHANT_curl_easy_get_ (utph->url);
    148     GNUNET_assert (GNUNET_OK ==
    149                    TALER_curl_easy_post (&utph->post_ctx,
    150                                          eh,
    151                                          req_obj));
    152     json_decref (req_obj);
    153     utph->job = GNUNET_CURL_job_add2 (ctx,
    154                                       eh,
    155                                       utph->post_ctx.headers,
    156                                       &handle_post_using_templates_finished,
    157                                       utph);
    158     GNUNET_assert (NULL != utph->job);
    159   }
    160   return utph;
    161 }
    162 
    163 
    164 struct TALER_MERCHANT_UsingTemplatesPostHandle *
    165 TALER_MERCHANT_using_templates_post (
    166   struct GNUNET_CURL_Context *ctx,
    167   const char *backend_url,
    168   const char *template_id,
    169   const char *summary,
    170   const struct TALER_Amount *amount,
    171   TALER_MERCHANT_PostOrdersCallback cb,
    172   void *cb_cls)
    173 {
    174   json_t *req_obj;
    175 
    176   req_obj = GNUNET_JSON_PACK (
    177     GNUNET_JSON_pack_string ("template_type",
    178                              "fixed-order"),
    179     GNUNET_JSON_pack_allow_null (
    180       GNUNET_JSON_pack_string ("summary",
    181                                summary)),
    182     GNUNET_JSON_pack_allow_null (
    183       TALER_JSON_pack_amount ("amount",
    184                               amount)));
    185   return using_templates_post_internal (ctx,
    186                                         backend_url,
    187                                         template_id,
    188                                         req_obj,
    189                                         cb,
    190                                         cb_cls);
    191 }
    192 
    193 
    194 struct TALER_MERCHANT_UsingTemplatesPostHandle *
    195 TALER_MERCHANT_using_templates_post2 (
    196   struct GNUNET_CURL_Context *ctx,
    197   const char *backend_url,
    198   const char *template_id,
    199   const json_t *details,
    200   TALER_MERCHANT_PostOrdersCallback cb,
    201   void *cb_cls)
    202 {
    203   if (NULL == details)
    204   {
    205     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    206                 "No request body provided for using templates.\n");
    207     return NULL;
    208   }
    209   return using_templates_post_internal (ctx,
    210                                         backend_url,
    211                                         template_id,
    212                                         (json_t *) details,
    213                                         cb,
    214                                         cb_cls);
    215 }
    216 
    217 
    218 void
    219 TALER_MERCHANT_using_templates_post_cancel (
    220   struct TALER_MERCHANT_UsingTemplatesPostHandle *utph)
    221 {
    222   if (NULL != utph->job)
    223   {
    224     GNUNET_CURL_job_cancel (utph->job);
    225     utph->job = NULL;
    226   }
    227   TALER_curl_easy_post_finished (&utph->post_ctx);
    228   GNUNET_free (utph->url);
    229   GNUNET_free (utph);
    230 }
    231 
    232 
    233 /* end of merchant_api_post_using_templates.c */