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 */