taler-merchant-httpd_post-private-transfers.c (5149B)
1 /* 2 This file is part of TALER 3 (C) 2014-2023, 2025, 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 Affero General Public License as published by the Free Software 7 Foundation; either version 3, 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 General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file src/backend/taler-merchant-httpd_post-private-transfers.c 18 * @brief implement API for registering wire transfers 19 * @author Marcello Stanisci 20 * @author Christian Grothoff 21 */ 22 #include "platform.h" 23 #include <jansson.h> 24 #include <taler/taler_signatures.h> 25 #include <taler/taler_json_lib.h> 26 #include <taler/taler_dbevents.h> 27 #include "taler-merchant-httpd_get-exchanges.h" 28 #include "taler-merchant-httpd_helper.h" 29 #include "taler-merchant-httpd_post-private-transfers.h" 30 #include "merchant-database/insert_transfer.h" 31 32 33 /** 34 * How often do we retry the simple INSERT database transaction? 35 */ 36 #define MAX_RETRIES 5 37 38 39 enum MHD_Result 40 TMH_private_post_transfers (const struct TMH_RequestHandler *rh, 41 struct MHD_Connection *connection, 42 struct TMH_HandlerContext *hc) 43 { 44 struct TALER_FullPayto payto_uri; 45 const char *exchange_url; 46 struct TALER_WireTransferIdentifierRawP wtid; 47 struct TALER_Amount amount; 48 struct GNUNET_JSON_Specification spec[] = { 49 TALER_JSON_spec_amount_any ("credit_amount", 50 &amount), 51 GNUNET_JSON_spec_fixed_auto ("wtid", 52 &wtid), 53 TALER_JSON_spec_full_payto_uri ("payto_uri", 54 &payto_uri), 55 TALER_JSON_spec_web_url ("exchange_url", 56 &exchange_url), 57 GNUNET_JSON_spec_end () 58 }; 59 enum GNUNET_GenericReturnValue res; 60 enum GNUNET_DB_QueryStatus qs; 61 bool no_instance; 62 bool no_account; 63 bool conflict; 64 65 res = TALER_MHD_parse_json_data (connection, 66 hc->request_body, 67 spec); 68 if (GNUNET_OK != res) 69 return (GNUNET_NO == res) 70 ? MHD_YES 71 : MHD_NO; 72 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 73 "New inbound wire transfer over %s to %s from %s\n", 74 TALER_amount2s (&amount), 75 payto_uri.full_payto, 76 exchange_url); 77 78 /* Check if transfer data is in database, if not, add it. */ 79 qs = TALER_MERCHANTDB_insert_transfer (TMH_db, 80 hc->instance->settings.id, 81 exchange_url, 82 &wtid, 83 &amount, 84 payto_uri, 85 0 /* no bank serial known! */, 86 &no_instance, 87 &no_account, 88 &conflict); 89 switch (qs) 90 { 91 case GNUNET_DB_STATUS_HARD_ERROR: 92 GNUNET_break (0); 93 return TALER_MHD_reply_with_error (connection, 94 MHD_HTTP_INTERNAL_SERVER_ERROR, 95 TALER_EC_GENERIC_DB_STORE_FAILED, 96 "insert_transfer"); 97 case GNUNET_DB_STATUS_SOFT_ERROR: 98 GNUNET_break (0); 99 return TALER_MHD_reply_with_error (connection, 100 MHD_HTTP_INTERNAL_SERVER_ERROR, 101 TALER_EC_GENERIC_DB_STORE_FAILED, 102 "insert_transfer"); 103 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 104 GNUNET_assert (0); /* should be impossible */ 105 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 106 break; 107 } 108 if (no_instance) 109 { 110 /* should be only possible if instance was concurrently deleted, 111 that's so theoretical we rather log as error... */ 112 GNUNET_break (0); 113 return TALER_MHD_reply_with_error ( 114 connection, 115 MHD_HTTP_NOT_FOUND, 116 TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN, 117 hc->instance->settings.id); 118 } 119 if (no_account) 120 { 121 GNUNET_break_op (0); 122 return TALER_MHD_reply_with_error ( 123 connection, 124 MHD_HTTP_CONFLICT, 125 TALER_EC_MERCHANT_GENERIC_ACCOUNT_UNKNOWN, 126 payto_uri.full_payto); 127 } 128 if (conflict) 129 { 130 GNUNET_break_op (0); 131 return TALER_MHD_reply_with_error ( 132 connection, 133 MHD_HTTP_CONFLICT, 134 TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION, 135 NULL); 136 } 137 return TALER_MHD_reply_static (connection, 138 MHD_HTTP_NO_CONTENT, 139 NULL, 140 NULL, 141 0); 142 } 143 144 145 /* end of taler-merchant-httpd_post-private-transfers.c */