summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c10
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-abort.c3
-rw-r--r--src/backend/taler-merchant-httpd_private-post-transfers.c106
-rw-r--r--src/backend/taler-merchant-httpd_private-post-transfers.h26
-rw-r--r--src/backenddb/merchant-0001.sql13
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c595
-rw-r--r--src/include/taler_merchantdb_plugin.h2
7 files changed, 313 insertions, 442 deletions
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 0fae0a98..f22ac8a3 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -75,6 +75,12 @@ struct CoinRefund
json_t *exchange_reply;
/**
+ * When did the merchant grant the refund. To be used to group events
+ * in the wallet.
+ */
+ struct GNUNET_TIME_Absolute execution_time;
+
+ /**
* Coin to refund.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -435,12 +441,14 @@ check_resume_god (struct GetOrderData *god)
*
* @param cls a `struct CoinRefund`
* @param hr HTTP response data
+ * @param refund_fee fee the exchange charged
* @param exchange_pub exchange key used to sign refund confirmation
* @param exchange_sig exchange's signature over refund
*/
static void
refund_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
+ const struct TALER_Amount *refund_fee,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_ExchangeSignatureP *exchange_sig)
{
@@ -465,6 +473,7 @@ refund_cb (void *cls,
cr->exchange_sig = *exchange_sig;
qs = TMH_db->insert_refund_proof (TMH_db->cls,
cr->refund_serial,
+ refund_fee,
exchange_sig,
exchange_pub);
if (0 >= qs)
@@ -557,6 +566,7 @@ process_refunds_cb (void *cls,
cr->coin_pub = *coin_pub;
cr->rtransaction_id = rtransaction_id;
cr->refund_amount = *refund_amount;
+ cr->execution_time = timestamp;
GNUNET_CONTAINER_DLL_insert (god->cr_head,
god->cr_tail,
cr);
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
index 4c7960ef..564f0e3c 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
@@ -438,12 +438,14 @@ find_next_exchange (struct AbortContext *ac);
*
* @param cls closure
* @param hr HTTP response data
+ * @param refund_fee fee the exchange charged
* @param sign_key exchange key used to sign @a obj, or NULL
* @param signature the actual signature, or NULL on error
*/
static void
refund_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
+ const struct TALER_Amount *refund_fee,
const struct TALER_ExchangePublicKeyP *sign_key,
const struct TALER_ExchangeSignatureP *signature)
{
@@ -452,6 +454,7 @@ refund_cb (void *cls,
(void) sign_key;
(void) signature;
+ (void) refund_fee;
rd->rh = NULL;
rd->http_status = hr->http_status;
rd->exchange_reply = json_incref ((json_t*) hr->reply);
diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.c b/src/backend/taler-merchant-httpd_private-post-transfers.c
index 6304761f..ce76a6f2 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.c
@@ -258,12 +258,12 @@ build_deposits_response (void *cls,
json_t *contract_terms;
json_t *order_id;
- db->preflight (db->cls);
+ TMH_db->preflight (TMH_db->cls);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
- db->find_contract_terms_from_hash (db->cls,
- &contract_terms,
- key,
- &rctx->mi->pubkey))
+ TMH_db->find_contract_terms_from_hash (TMH_db->cls,
+ &contract_terms,
+ key,
+ &rctx->mi->pubkey))
{
GNUNET_break_op (0);
return GNUNET_NO;
@@ -541,16 +541,16 @@ check_wire_fee (struct TrackTransferContext *rctx,
char *wire_method;
wire_method = TALER_payto_get_method (rctx->payto_uri);
- db->preflight (db->cls);
- qs = db->lookup_wire_fee (db->cls,
- &rctx->master_pub,
- wire_method,
- execution_time,
- &expected_fee,
- &closing_fee,
- &start_date,
- &end_date,
- &master_sig);
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->lookup_wire_fee (TMH_db->cls,
+ &rctx->master_pub,
+ wire_method,
+ execution_time,
+ &expected_fee,
+ &closing_fee,
+ &start_date,
+ &end_date,
+ &master_sig);
if (0 >= qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -636,16 +636,16 @@ wire_transfer_cb (void *cls,
"exchange_reply", hr->reply));
return;
}
- db->preflight (db->cls);
- qs = db->insert_transfer_details (db->cls,
- rctx->exchange_url,
- rctx->payto_uri,
- &rctx->wtid,
- total_amount,
- wire_fee,
- execution_time,
- details_length,
- details);
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->insert_transfer_details (TMH_db->cls,
+ rctx->exchange_url,
+ rctx->payto_uri,
+ &rctx->wtid,
+ total_amount,
+ wire_fee,
+ execution_time,
+ details_length,
+ details);
if (0 > qs)
{
/* Special report if retries insufficient */
@@ -685,13 +685,13 @@ wire_transfer_cb (void *cls,
rctx->current_detail = &details[i];
/* Set the coin as "never seen" before. */
rctx->check_transfer_result = GNUNET_NO;
- db->preflight (db->cls);
- qs = db->find_payments_by_hash_and_coin (db->cls,
- &details[i].h_contract_terms,
- &rctx->mi->pubkey,
- &details[i].coin_pub,
- &check_transfer,
- rctx);
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->find_payments_by_hash_and_coin (TMH_db->cls,
+ &details[i].h_contract_terms,
+ &rctx->mi->pubkey,
+ &details[i].coin_pub,
+ &check_transfer,
+ rctx);
if (0 > qs)
{
/* single, read-only SQL statements should never cause
@@ -752,11 +752,11 @@ wire_transfer_cb (void *cls,
remember it for future reference */
for (unsigned int r = 0; r<MAX_RETRIES; r++)
{
- db->preflight (db->cls);
- qs = db->store_coin_to_transfer (db->cls,
- &details[i].h_contract_terms,
- &details[i].coin_pub,
- &rctx->wtid);
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->store_coin_to_transfer (TMH_db->cls,
+ &details[i].h_contract_terms,
+ &details[i].coin_pub,
+ &rctx->wtid);
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
break;
}
@@ -918,7 +918,7 @@ handle_track_transfer_timeout (void *cls)
/**
- * Manages a POST /private/transfers call. It calls the /track/wtid
+ * Manages a POST /private/transfers call. It calls the GET /transfers/$WTID
* offered by the exchange in order to obtain the set of transfers
* (of coins) associated with a given wire transfer.
*
@@ -1015,16 +1015,16 @@ TMH_private_post_transfers (const struct TMH_RequestHandler *rh,
deposit_sums = json_array ();
GNUNET_assert (NULL != deposit_sums);
- db->preflight (db->cls);
- qs = db->lookup_transfer_details (db->cls,
- rctx->exchange_url,
- rctx->payto_uri,
- &rctx->wtid,
- &total_amount,
- &wire_fee,
- &execution_time,
- &transfer_details_cb,
- deposit_sums);
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->lookup_transfer_details (TMH_db->cls,
+ rctx->exchange_url,
+ rctx->payto_uri,
+ &rctx->wtid,
+ &total_amount,
+ &wire_fee,
+ &execution_time,
+ &transfer_details_cb,
+ deposit_sums);
if (0 > qs)
{
/* Simple select queries should not cause serialization issues */
@@ -1053,11 +1053,11 @@ TMH_private_post_transfers (const struct TMH_RequestHandler *rh,
/* reply not in database, ensure the POST is in the database, and
start work to obtain the reply from the exchange */
- qs = db->insert_transfer (db->cls,
- rctx->exchange_url,
- &rctx->wtid,
- &rctx->amount,
- rctx->payto_uri);
+ qs = TMH_db->insert_transfer (TMH_db->cls,
+ rctx->exchange_url,
+ &rctx->wtid,
+ &rctx->amount,
+ rctx->payto_uri);
if (0 > qs)
{
/* Simple select queries should not cause serialization issues */
diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.h b/src/backend/taler-merchant-httpd_private-post-transfers.h
index 0463295e..2c548f77 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.h
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.h
@@ -14,36 +14,30 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
- * @file backend/taler-merchant-httpd_track-transfer.h
+ * @file backend/taler-merchant-httpd_private-post-transfers.h
* @brief headers for /track/transfer handler
* @author Christian Grothoff
* @author Marcello Stanisci
*/
-#ifndef TALER_MERCHANT_HTTPD_TRACK_TRANSFER_H
-#define TALER_MERCHANT_HTTPD_TRACK_TRANSFER_H
+#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_TRANSFERS_H
+#define TALER_MERCHANT_HTTPD_PRIVATE_POST_TRANSFERS_H
#include <microhttpd.h>
#include "taler-merchant-httpd.h"
/**
- * Manages a /track/transfer call, thus it calls the /wire/transfer
- * offered by the exchange in order to return the set of transfers
- * (of coins) associated with a given wire transfer
+ * Manages a POST /private/transfers call. It calls the GET /transfers/$WTID
+ * offered by the exchange in order to obtain the set of transfers
+ * (of coins) associated with a given wire transfer.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @param mi merchant backend instance, never NULL
+ * @param[in,out] hc context with further information about the request
* @return MHD result code
*/
MHD_RESULT
-MH_handler_track_transfer (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size,
- struct MerchantInstance *mi);
+TMH_private_post_transfers (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc);
#endif
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 6abc0554..3feb3470 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -334,20 +334,15 @@ CREATE TABLE IF NOT EXISTS merchant_refund_proofs
(refund_serial BIGINT PRIMARY KEY
REFERENCES merchant_refunds (refund_serial) ON DELETE CASCADE
,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64)
- ,execution_time INT8 NOT NULL
- ,total_amount_val INT8 NOT NULL
- ,total_amount_frac INT4 NOT NULL
- ,wire_fee_val INT8 NOT NULL
- ,wire_fee_frac INT4 NOT NULL
+ ,refund_fee_val INT8 NOT NULL
+ ,refund_fee_frac INT4 NOT NULL
,signkey_serial BIGINT NOT NULL
REFERENCES merchant_exchange_signing_keys (signkey_serial) ON DELETE CASCADE
);
COMMENT ON TABLE merchant_refund_proofs
IS 'Refunds confirmed by the exchange (not all approved refunds are grabbed by the wallet)';
-COMMENT ON COLUMN merchant_refund_proofs.execution_time
- IS 'When did the exchange claim to execute the wire transfer';
-COMMENT ON COLUMN merchant_refund_proofs.total_amount_val
- IS 'Amount the exchange claims to have deducted from the merchant balance; actual transfer amount is this minus the wire fee';
+COMMENT ON COLUMN merchant_refund_proofs.refund_fee_val
+ IS 'Refund fee exchange charged';
-------------------- Wire transfers ---------------------------
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 15996425..ef7deabb 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -2445,159 +2445,255 @@ postgres_increase_refund (void *cls,
/**
- * Retrieve the order ID that was used to pay for a resource within a session.
+ * Closure for #lookup_refunds_detailed_cb().
+ */
+struct LookupRefundsDetailedContext
+{
+ /**
+ * Function to call for each refund.
+ */
+ TALER_MERCHANTDB_RefundDetailCallback rc;
+
+ /**
+ * Closure for @e rc.
+ */
+ void *rc_cls;
+
+ /**
+ * Plugin context.
+ */
+ struct PostgresClosure *pg;
+
+ /**
+ * Transaction result.
+ */
+ enum GNUNET_DB_QueryStatus qs;
+};
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
*
- * @param cls closure
- * @param instance_id identifying the instance
- * @param fulfillment_url URL that canonically identifies the resource
- * being paid for
- * @param session_id session id
- * @param[out] order_id where to store the order ID that was used when
- * paying for the resource URL
+ * @param cls of type `struct GetRefundsContext *`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+lookup_refunds_detailed_cb (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRefundsDetailedContext *lrdc = cls;
+ struct PostgresClosure *pg = lrdc->pg;
+
+ for (unsigned int i = 0; i<num_results; i++)
+ {
+ uint64_t refund_serial;
+ struct GNUNET_TIME_Absolute timestamp;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ uint64_t rtransaction_id;
+ struct TALER_Amount refund_amount;
+ char *reason;
+ char *exchange_url;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("refund_serial",
+ &refund_serial),
+ GNUNET_PQ_result_spec_absolute_time ("refund_timestamp",
+ &timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &coin_pub),
+ GNUNET_PQ_result_spec_string ("exchange_url",
+ &exchange_url),
+ GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
+ &rtransaction_id),
+ GNUNET_PQ_result_spec_string ("reason",
+ &reason),
+ TALER_PQ_RESULT_SPEC_AMOUNT ("refund_amount",
+ &refund_amount),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ lrdc->qs = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
+ }
+ lrdc->qs = i + 1;
+ lrdc->rc (lrdc->rc_cls,
+ refund_serial,
+ timestamp,
+ &coin_pub,
+ exchange_url,
+ rtransaction_id,
+ reason,
+ &refund_amount);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Obtain detailed refund data associated with a contract.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param instance_id instance to lookup refunds for
+ * @param h_contract_terms hash code of the contract
+ * @param rc function to call for each coin on which there is a refund
+ * @param rc_cls closure for @a rc
* @return transaction status
*/
-enum GNUNET_DB_QueryStatus
-postgres_lookup_order_by_fulfillment (void *cls,
- const char *instance_id,
- const char *fulfillment_url,
- const char *session_id,
- char **order_id)
+static enum GNUNET_DB_QueryStatus
+postgres_lookup_refunds_detailed (
+ void *cls,
+ const char *instance_id,
+ const struct GNUNET_HashCode *h_contract_terms,
+ TALER_MERCHANTDB_RefundDetailCallback rc,
+ void *rc_cls)
{
struct PostgresClosure *pg = cls;
-
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (instance_id),
- GNUNET_PQ_query_param_string (fulfillment_url),
- GNUNET_PQ_query_param_string (session_id),
+ GNUNET_PQ_query_param_auto_from_type (instance_id),
+ GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
GNUNET_PQ_query_param_end
};
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_string ("order_id",
- order_id),
- GNUNET_PQ_result_spec_end
+ struct LookupRefundsDetailedContext lrdc = {
+ .rc = rc,
+ .rc_cls = rc_cls,
+ .pg = pg
};
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_order_by_fulfillment",
- params,
- rs);
-}
+ enum GNUNET_DB_QueryStatus qs;
+ /* no preflight check here, run in transaction by caller! */
+ TALER_LOG_DEBUG ("Looking for refund %s + %s\n",
+ GNUNET_h2s (h_contract_terms),
+ instance_id);
+ check_connection (pg);
+ qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+ "lookup_refunds_detailed",
+ params,
+ &lookup_refunds_detailed_cb,
+ &lrdc);
+ if (0 >= qs)
+ return qs;
+ return lrdc.qs;
+}
-/* ********************* OLD API ************************** */
/**
- * Retrieve proposal data given its proposal data's hashcode
+ * Insert refund proof data from the exchange into the database.
*
* @param cls closure
- * @param contract_terms where to store the retrieved proposal data
- * @param h_contract_terms proposal data's hashcode that will be used to
- * perform the lookup
+ * @param refund_serial serial number of the refund
+ * @param refund_fee refund fee the exchange said it charged
+ * @param exchange_sig signature from exchange that coin was refunded
+ * @param exchange_pub signing key that was used for @a exchange_sig
* @return transaction status
*/
static enum GNUNET_DB_QueryStatus
-postgres_find_contract_terms_from_hash (
+postgres_insert_refund_proof (
void *cls,
- json_t **contract_terms,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub)
+ uint64_t refund_serial,
+ const struct TALER_Amount *refund_fee,
+ const struct TALER_ExchangeSignatureP *exchange_sig,
+ const struct TALER_ExchangePublicKeyP *exchange_pub)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+ GNUNET_PQ_query_param_uint64 (&refund_serial),
+ GNUNET_PQ_query_param_auto_from_type (exchange_sig),
+ TALER_PQ_query_param_amount (refund_fee),
+ GNUNET_PQ_query_param_auto_from_type (exchange_pub),
GNUNET_PQ_query_param_end
};
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_result_spec_json ("contract_terms",
- contract_terms),
- GNUNET_PQ_result_spec_end
- };
- check_connection (pg);
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "find_contract_terms_from_hash",
- params,
- rs);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_refund_proof",
+ params);
}
/**
- * Retrieve proposal data given its proposal data's hashcode
+ * Lookup refund proof data.
*
* @param cls closure
- * @param contract_terms where to store the retrieved proposal data
- * @param h_contract_terms proposal data's hashcode that will be used to
- * perform the lookup
+ * @param refund_serial serial number of the refund
+ * @param[out] exchange_sig set to signature from exchange
+ * @param[out] exchange_pub signing key that was used for @a exchange_sig
* @return transaction status
*/
static enum GNUNET_DB_QueryStatus
-postgres_find_paid_contract_terms_from_hash (void *cls,
- json_t **contract_terms,
- const struct
- GNUNET_HashCode *h_contract_terms,
- const struct
- TALER_MerchantPublicKeyP *
- merchant_pub)
+postgres_lookup_refund_proof (void *cls,
+ uint64_t refund_serial,
+ struct TALER_ExchangeSignatureP *exchange_sig,
+ struct TALER_ExchangePublicKeyP *exchange_pub)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+ GNUNET_PQ_query_param_uint64 (&refund_serial),
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_result_spec_json ("contract_terms",
- contract_terms),
+ GNUNET_PQ_result_spec_auto_from_type ("exchange_sig",
+ exchange_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("exchange_pub",
+ exchange_pub),
GNUNET_PQ_result_spec_end
};
- /* no preflight check here, runs in its own transaction from
- caller (in /pay case) */
check_connection (pg);
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "find_paid_contract_terms_from_hash",
+ "lookup_refund_proof",
params,
rs);
}
/**
- * Store the order ID that was used to pay for a resource within a session.
+ * Retrieve the order ID that was used to pay for a resource within a session.
*
* @param cls closure
- * @param session_id session id
+ * @param instance_id identifying the instance
* @param fulfillment_url URL that canonically identifies the resource
* being paid for
- * @param order_id the order ID that was used when paying for the resource URL
- * @param merchant_pub public key of the merchant, identifying the instance
+ * @param session_id session id
+ * @param[out] order_id where to store the order ID that was used when
+ * paying for the resource URL
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
-postgres_insert_session_info (void *cls,
- const char *session_id,
- const char *fulfillment_url,
- const char *order_id,
- const struct
- TALER_MerchantPublicKeyP *merchant_pub)
+postgres_lookup_order_by_fulfillment (void *cls,
+ const char *instance_id,
+ const char *fulfillment_url,
+ const char *session_id,
+ char **order_id)
{
struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (session_id),
+ GNUNET_PQ_query_param_string (instance_id),
GNUNET_PQ_query_param_string (fulfillment_url),
- GNUNET_PQ_query_param_string (order_id),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_string (session_id),
GNUNET_PQ_query_param_end
};
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_session_info",
- params);
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("order_id",
+ order_id),
+ GNUNET_PQ_result_spec_end
+ };
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "lookup_order_by_fulfillment",
+ params,
+ rs);
}
+/* ********************* OLD API ************************** */
+
/**
* Insert mapping of @a coin_pub and @a h_contract_terms to
* corresponding @a wtid.
@@ -3373,233 +3469,6 @@ postgres_find_deposits_by_wtid (void *cls,
/**
- * Closure for #get_refunds_cb().
- */
-struct GetRefundsContext
-{
- /**
- * Function to call for each refund.
- */
- TALER_MERCHANTDB_CoinRefundCallback rc;
-
- /**
- * Closure for @e rc.
- */
- void *rc_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Transaction result.
- */
- enum GNUNET_DB_QueryStatus qs;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls of type `struct GetRefundsContext *`
- * @param result the postgres result
- * @param num_result the number of results in @a result
- */
-static void
-get_refunds_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct GetRefundsContext *grc = cls;
- struct PostgresClosure *pg = grc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_CoinSpendPublicKeyP coin_pub;
- uint64_t rtransaction_id;
- struct TALER_Amount refund_amount;
- struct TALER_Amount refund_fee;
- char *reason;
- char *exchange_url;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &coin_pub),
- GNUNET_PQ_result_spec_string ("exchange_url",
- &exchange_url),
- GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
- &rtransaction_id),
- TALER_PQ_RESULT_SPEC_AMOUNT ("refund_amount",
- &refund_amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("refund_fee",
- &refund_fee),
- GNUNET_PQ_result_spec_string ("reason",
- &reason),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- grc->qs = GNUNET_DB_STATUS_HARD_ERROR;
- return;
- }
- grc->qs = i + 1;
- grc->rc (grc->rc_cls,
- &coin_pub,
- exchange_url,
- rtransaction_id,
- reason,
- &refund_amount,
- &refund_fee);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Obtain refunds associated with a contract.
- *
- * @param cls closure, typically a connection to the db
- * @param merchant_pub public key of the merchant instance
- * @param h_contract_terms hash code of the contract
- * @param rc function to call for each coin on which there is a refund
- * @param rc_cls closure for @a rc
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-postgres_get_refunds_from_contract_terms_hash (
- void *cls,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_contract_terms,
- TALER_MERCHANTDB_CoinRefundCallback rc,
- void *rc_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_end
- };
- struct GetRefundsContext grc = {
- .rc = rc,
- .rc_cls = rc_cls,
- .pg = pg
- };
- enum GNUNET_DB_QueryStatus qs;
-
- /* no preflight check here, run in transaction by caller! */
- TALER_LOG_DEBUG ("Looking for refund %s + %s\n",
- GNUNET_h2s (h_contract_terms),
- TALER_B2S (merchant_pub));
- check_connection (pg);
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "find_refunds_from_contract_terms_hash",
- params,
- &get_refunds_cb,
- &grc);
- if (0 >= qs)
- return qs;
- return grc.qs;
-}
-
-
-/**
- * Obtain refund proofs associated with a refund operation on a
- * coin.
- *
- * @param cls closure, typically a connection to the db
- * @param merchant_pub public key of the merchant instance
- * @param h_contract_terms hash code of the contract
- * @param coin_pub public key of the coin
- * @param rtransaction_id identificator of the refund
- * @param[out] exchange_pub public key of the exchange affirming the refund
- * @param[out] exchange_sig signature of the exchange affirming the refund
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_refund_proof (
- void *cls,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t rtransaction_id,
- struct TALER_ExchangePublicKeyP *exchange_pub,
- struct TALER_ExchangeSignatureP *exchange_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_uint64 (&rtransaction_id),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("exchange_sig",
- exchange_sig),
- GNUNET_PQ_result_spec_auto_from_type ("exchange_pub",
- exchange_pub),
- GNUNET_PQ_result_spec_end
- };
-
- check_connection (pg);
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_refund_proof",
- params,
- rs);
-}
-
-
-/**
- * Store refund proofs associated with a refund operation on a
- * coin.
- *
- * @param cls closure, typically a connection to the db
- * @param merchant_pub public key of the merchant instance
- * @param h_contract_terms hash code of the contract
- * @param coin_pub public key of the coin
- * @param rtransaction_id identificator of the refund
- * @param exchange_pub public key of the exchange affirming the refund
- * @param exchange_sig signature of the exchange affirming the refund
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_put_refund_proof (
- void *cls,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t rtransaction_id,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_ExchangeSignatureP *exchange_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&rtransaction_id),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_auto_from_type (exchange_sig),
- GNUNET_PQ_query_param_auto_from_type (exchange_pub),
- GNUNET_PQ_query_param_end
- };
-
- TALER_LOG_DEBUG ("Inserting refund proof %s + %s\n",
- GNUNET_h2s (h_contract_terms),
- TALER_B2S (coin_pub));
- check_connection (pg);
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_refund_proof",
- params);
-}
-
-
-/**
* Store information about wire fees charged by an exchange,
* including signature (so we have proof).
*
@@ -5630,6 +5499,53 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" FROM merchant_instances"
" WHERE merchant_id=$1))",
2),
+ /* for postgres_lookup_refunds_detailed() */
+ GNUNET_PQ_make_prepare ("lookup_refunds_detailed",
+ "SELECT"
+ " refund_serial"
+ ",refund_timestamp"
+ ",coin_pub"
+ ",merchant_deposits.exchange_url"
+ ",rtransaction_id"
+ ",reason"
+ ",refund_amount_val"
+ ",refund_amount_frac"
+ " FROM merchant_refunds"
+ " JOIN merchant_deposits USING (order_serial, coin_pub)"
+ " WHERE order_serial="
+ " (SELECT order_serial"
+ " FROM merchant_contract_terms"
+ " WHERE h_contract_terms=$2"
+ " AND merchant_serial="
+ " (SELECT merchant_serial"
+ " FROM merchant_instances"
+ " WHERE merchant_id=$1))",
+ 2),
+ /* for postgres_insert_refund_proof() */
+ GNUNET_PQ_make_prepare ("insert_refund_proof",
+ "INSERT INTO merchant_refund_proofs"
+ "(refund_serial"
+ ",exchange_sig"
+ ",refund_fee_val"
+ ",refund_fee_frac"
+ ",signkey_serial)"
+ "SELECT $1, $2, $3, $4, signkey_serial"
+ " FROM merchant_exchange_signing_keys"
+ " WHERE exchange_pub=$5"
+ " ORDER BY start_date DESC"
+ " LIMIT 1",
+ 5),
+ /* for postgres_lookup_refund_proof() */
+ GNUNET_PQ_make_prepare ("lookup_refund_proof",
+ "SELECT"
+ " merchant_exchange_signing_keys.exchange_pub"
+ ",exchange_sig"
+ " FROM merchant_refund_proofs"
+ " JOIN merchant_exchange_signing_keys"
+ " USING (signkey_serial)"
+ " WHERE"
+ " refund_serial=$1",
+ 1),
/* for postgres_lookup_order_by_fulfillment() */
GNUNET_PQ_make_prepare ("lookup_order_by_fulfillment",
"SELECT"
@@ -5653,15 +5569,6 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
",wtid) VALUES "
"($1, $2, $3)",
3),
- GNUNET_PQ_make_prepare ("insert_proof",
- "INSERT INTO merchant_proofs"
- "(exchange_url"
- ",wtid"
- ",execution_time"
- ",signkey_pub"
- ",proof) VALUES "
- "($1, $2, $3, $4, $5)",
- 5),
GNUNET_PQ_make_prepare ("insert_contract_terms",
"INSERT INTO merchant_contract_terms"
"(order_id"
@@ -5733,43 +5640,6 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" FROM merchant_refunds"
" WHERE coin_pub=$1",
1),
- GNUNET_PQ_make_prepare ("find_refunds_from_contract_terms_hash",
- "SELECT"
- " coin_pub"
- ",merchant_deposits.exchange_url"
- ",rtransaction_id"
- ",refund_amount_val"
- ",refund_amount_frac"
- ",merchant_deposits.refund_fee_val"
- ",merchant_deposits.refund_fee_frac"
- ",reason"
- " FROM merchant_refunds"
- " JOIN merchant_deposits USING (merchant_pub, coin_pub)"
- " WHERE merchant_refunds.merchant_pub=$1"
- " AND merchant_refunds.h_contract_terms=$2",
- 2),
- GNUNET_PQ_make_prepare ("get_refund_proof",
- "SELECT"
- " exchange_pub"
- ",exchange_sig"
- " FROM merchant_refund_proofs"
- " WHERE"
- " h_contract_terms=$1"
- " AND merchant_pub=$2"
- " AND coin_pub=$3"
- " AND rtransaction_id=$4",
- 4),
- GNUNET_PQ_make_prepare ("insert_refund_proof",
- "INSERT INTO merchant_refund_proofs"
- "(rtransaction_id"
- ",merchant_pub"
- ",h_contract_terms"
- ",coin_pub"
- ",exchange_sig"
- ",exchange_pub)"
- " VALUES "
- "($1, $2, $3, $4, $5, $6)",
- 6),
GNUNET_PQ_make_prepare ("find_deposits",
"SELECT"
" coin_pub"
@@ -6022,12 +5892,11 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->refund_coin = &postgres_refund_coin;
plugin->lookup_order_status = &postgres_lookup_order_status;
plugin->increase_refund = &postgres_increase_refund;
+ plugin->lookup_refunds_detailed = &postgres_lookup_refunds_detailed;
+ plugin->insert_refund_proof = &postgres_insert_refund_proof;
+ plugin->lookup_refund_proof = &postgres_lookup_refund_proof;
plugin->lookup_order_by_fulfillment = &postgres_lookup_order_by_fulfillment;
/* OLD API: */
- plugin->find_contract_terms_from_hash =
- &postgres_find_contract_terms_from_hash;
- plugin->find_paid_contract_terms_from_hash =
- &postgres_find_paid_contract_terms_from_hash;
plugin->store_coin_to_transfer = &postgres_store_coin_to_transfer;
plugin->store_transfer_to_proof = &postgres_store_transfer_to_proof;
plugin->store_wire_fee_by_exchange = &postgres_store_wire_fee_by_exchange;
@@ -6038,8 +5907,6 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->find_proof_by_wtid = &postgres_find_proof_by_wtid;
plugin->get_authorized_tip_amount = &postgres_get_authorized_tip_amount;
plugin->lookup_wire_fee = &postgres_lookup_wire_fee;
- plugin->get_refund_proof = &postgres_get_refund_proof;
- plugin->put_refund_proof = &postgres_put_refund_proof;
plugin->enable_tip_reserve_TR = &postgres_enable_tip_reserve_TR;
plugin->authorize_tip_TR = &postgres_authorize_tip_TR;
plugin->lookup_tip_by_id = &postgres_lookup_tip_by_id;
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index eb4b272d..6e2f8005 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1146,6 +1146,7 @@ struct TALER_MERCHANTDB_Plugin
*
* @param cls closure
* @param refund_serial serial number of the refund
+ * @param refund_fee refund fee the exchange said it charged
* @param exchange_sig signature from exchange that coin was refunded
* @param exchange_pub signing key that was used for @a exchange_sig
* @return transaction status
@@ -1153,6 +1154,7 @@ struct TALER_MERCHANTDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_refund_proof)(void *cls,
uint64_t refund_serial,
+ const struct TALER_Amount *refund_fee,
const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_ExchangePublicKeyP *exchange_pub);