summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-09 17:45:08 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-09 17:45:08 +0200
commit5b0f4ae9e68c3f5065c2c62bed7c7d3bc0b4423a (patch)
treedc2301c91223601b5f76b1a8289e137df9f3ccfa
parent714b0ef777cf0ef736a80f070936716609ccade3 (diff)
downloadmerchant-5b0f4ae9e68c3f5065c2c62bed7c7d3bc0b4423a.tar.gz
merchant-5b0f4ae9e68c3f5065c2c62bed7c7d3bc0b4423a.tar.bz2
merchant-5b0f4ae9e68c3f5065c2c62bed7c7d3bc0b4423a.zip
implement protocol v14 / fix #8717
-rw-r--r--src/backend/taler-merchant-httpd_config.c10
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c4
-rw-r--r--src/backend/taler-merchant-httpd_private-get-orders-ID.c125
-rw-r--r--src/backenddb/pg_lookup_deposits_by_order.c7
-rw-r--r--src/backenddb/test_merchantdb.c91
-rw-r--r--src/include/taler_merchant_service.h10
-rw-r--r--src/include/taler_merchantdb_plugin.h4
-rw-r--r--src/lib/merchant_api_get_config.c4
-rw-r--r--src/lib/merchant_api_merchant_get_order.c5
9 files changed, 163 insertions, 97 deletions
diff --git a/src/backend/taler-merchant-httpd_config.c b/src/backend/taler-merchant-httpd_config.c
index bb4462bb..3777904f 100644
--- a/src/backend/taler-merchant-httpd_config.c
+++ b/src/backend/taler-merchant-httpd_config.c
@@ -42,7 +42,7 @@
* #MERCHANT_PROTOCOL_CURRENT and #MERCHANT_PROTOCOL_AGE in
* merchant_api_config.c!
*/
-#define MERCHANT_PROTOCOL_VERSION "13:1:9"
+#define MERCHANT_PROTOCOL_VERSION "14:0:10"
/**
@@ -116,7 +116,8 @@ MH_handler_config (struct TMH_RequestHandler *rh,
GNUNET_assert (0 ==
json_object_set_new (specs,
cspec->currency,
- TALER_CONFIG_currency_specs_to_json (
+ TALER_CONFIG_currency_specs_to_json
+ (
cspec)));
}
response = TALER_MHD_MAKE_JSON_PACK (
@@ -126,8 +127,9 @@ MH_handler_config (struct TMH_RequestHandler *rh,
specs),
GNUNET_JSON_pack_array_steal ("exchanges",
exchanges),
- GNUNET_JSON_pack_string ("implementation",
- "urn:net:taler:specs:taler-merchant:c-reference"),
+ GNUNET_JSON_pack_string (
+ "implementation",
+ "urn:net:taler:specs:taler-merchant:c-reference"),
GNUNET_JSON_pack_string ("name",
"taler-merchant"),
GNUNET_JSON_pack_string ("version",
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 07a6233a..14edfd55 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -2032,9 +2032,10 @@ phase_execute_pay_transaction (struct PayContext *pc)
* @param cls closure with our `struct PayContext *`
* @param deposit_serial which deposit operation is this about
* @param exchange_url URL of the exchange that issued the coin
+ * @param h_wire hash of merchant's wire details
+ * @param deposit_timestamp when was the deposit made
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
- * @param h_wire hash of merchant's wire details
* @param coin_pub public key of the coin
*/
static void
@@ -2043,6 +2044,7 @@ deposit_paid_check (
uint64_t deposit_serial,
const char *exchange_url,
const struct TALER_MerchantWireHashP *h_wire,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub)
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index 1c850990..98653997 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -263,6 +263,11 @@ struct GetOrderRequestContext
struct GNUNET_TIME_Timestamp timestamp;
/**
+ * Timestamp of the last payment.
+ */
+ struct GNUNET_TIME_Timestamp last_payment;
+
+ /**
* Order summary. Pointer into @e contract_terms.
*/
const char *summary;
@@ -996,15 +1001,16 @@ phase_unpaid_finish (struct GetOrderRequestContext *gorc)
* @param pending true if the this refund was not yet processed by the wallet/exchange
*/
static void
-process_refunds_cb (void *cls,
- uint64_t refund_serial,
- struct GNUNET_TIME_Timestamp timestamp,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const char *exchange_url,
- uint64_t rtransaction_id,
- const char *reason,
- const struct TALER_Amount *refund_amount,
- bool pending)
+process_refunds_cb (
+ void *cls,
+ uint64_t refund_serial,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const char *exchange_url,
+ uint64_t rtransaction_id,
+ const char *reason,
+ const struct TALER_Amount *refund_amount,
+ bool pending)
{
struct GetOrderRequestContext *gorc = cls;
@@ -1013,18 +1019,19 @@ process_refunds_cb (void *cls,
(unsigned long long) rtransaction_id,
TALER_amount2s (refund_amount),
reason);
- GNUNET_assert (0 ==
- json_array_append_new (
- gorc->refund_details,
- GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("amount",
- refund_amount),
- GNUNET_JSON_pack_bool ("pending",
- pending),
- GNUNET_JSON_pack_timestamp ("timestamp",
- timestamp),
- GNUNET_JSON_pack_string ("reason",
- reason))));
+ GNUNET_assert (
+ 0 ==
+ json_array_append_new (
+ gorc->refund_details,
+ GNUNET_JSON_PACK (
+ TALER_JSON_pack_amount ("amount",
+ refund_amount),
+ GNUNET_JSON_pack_bool ("pending",
+ pending),
+ GNUNET_JSON_pack_timestamp ("timestamp",
+ timestamp),
+ GNUNET_JSON_pack_string ("reason",
+ reason))));
/* For refunded coins, we are not charged deposit fees, so subtract those
again */
for (struct TransferQuery *tq = gorc->tq_head;
@@ -1044,10 +1051,11 @@ process_refunds_cb (void *cls,
return;
}
- GNUNET_assert (0 <=
- TALER_amount_subtract (&gorc->deposit_fees_total,
- &gorc->deposit_fees_total,
- &tq->deposit_fee));
+ GNUNET_assert (
+ 0 <=
+ TALER_amount_subtract (&gorc->deposit_fees_total,
+ &gorc->deposit_fees_total,
+ &tq->deposit_fee));
}
}
if (GNUNET_OK !=
@@ -1084,29 +1092,32 @@ phase_check_refunds (struct GetOrderRequestContext *gorc)
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (gorc->contract_amount.currency,
&gorc->refund_amount));
- qs = TMH_db->lookup_refunds_detailed (TMH_db->cls,
- hc->instance->settings.id,
- &gorc->h_contract_terms,
- &process_refunds_cb,
- gorc);
+ qs = TMH_db->lookup_refunds_detailed (
+ TMH_db->cls,
+ hc->instance->settings.id,
+ &gorc->h_contract_terms,
+ &process_refunds_cb,
+ gorc);
if (0 > qs)
{
GNUNET_break (0);
phase_end (gorc,
- TALER_MHD_reply_with_error (gorc->sc.con,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "detailed refunds"));
+ TALER_MHD_reply_with_error (
+ gorc->sc.con,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "detailed refunds"));
return;
}
if (gorc->refund_currency_mismatch)
{
GNUNET_break (0);
phase_end (gorc,
- TALER_MHD_reply_with_error (gorc->sc.con,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "refunds in different currency than original order price"));
+ TALER_MHD_reply_with_error (
+ gorc->sc.con,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "refunds in different currency than original order price"));
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1127,19 +1138,22 @@ phase_check_refunds (struct GetOrderRequestContext *gorc)
* @param cls a `struct GetOrderRequestContext`
* @param deposit_serial identifies the deposit operation
* @param exchange_url URL of the exchange that issued @a coin_pub
+ * @param h_wire hash of the merchant's wire account into which the deposit was made
+ * @param deposit_timestamp when was the deposit made
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
- * @param h_wire hash of the merchant's wire account into which the deposit was made
* @param coin_pub public key of the deposited coin
*/
static void
-deposit_cb (void *cls,
- uint64_t deposit_serial,
- const char *exchange_url,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *deposit_fee,
- const struct TALER_CoinSpendPublicKeyP *coin_pub)
+deposit_cb (
+ void *cls,
+ uint64_t deposit_serial,
+ const char *exchange_url,
+ const struct TALER_MerchantWireHashP *h_wire,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_Amount *deposit_fee,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub)
{
struct GetOrderRequestContext *gorc = cls;
struct TransferQuery *tq;
@@ -1148,6 +1162,9 @@ deposit_cb (void *cls,
"Checking deposit status for coin %s (over %s)\n",
TALER_B2S (coin_pub),
TALER_amount2s (amount_with_fee));
+ gorc->last_payment
+ = GNUNET_TIME_timestamp_max (gorc->last_payment,
+ deposit_timestamp);
tq = GNUNET_new (struct TransferQuery);
tq->gorc = gorc;
tq->exchange_url = GNUNET_strdup (exchange_url);
@@ -1380,7 +1397,12 @@ phase_reply_result (struct GetOrderRequestContext *gorc)
&gorc->claim_token,
h_contract);
}
-
+ if (GNUNET_TIME_absolute_is_zero (gorc->last_payment.abs_time))
+ {
+ GNUNET_break (GNUNET_YES ==
+ TALER_amount_is_zero (&gorc->contract_amount));
+ gorc->last_payment = gorc->timestamp;
+ }
ret = TALER_MHD_REPLY_JSON_PACK (
gorc->sc.con,
MHD_HTTP_OK,
@@ -1403,6 +1425,8 @@ phase_reply_result (struct GetOrderRequestContext *gorc)
gorc->contract_terms),
GNUNET_JSON_pack_string ("order_status",
"paid"),
+ GNUNET_JSON_pack_timestamp ("last_payment",
+ gorc->last_payment),
GNUNET_JSON_pack_bool ("refunded",
gorc->refunded),
GNUNET_JSON_pack_bool ("wired",
@@ -1443,9 +1467,10 @@ phase_error (struct GetOrderRequestContext *gorc)
MHD_RESULT
-TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc)
+TMH_private_get_orders_ID (
+ const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc)
{
struct GetOrderRequestContext *gorc = hc->ctx;
diff --git a/src/backenddb/pg_lookup_deposits_by_order.c b/src/backenddb/pg_lookup_deposits_by_order.c
index fdaf1dfc..fb7637f0 100644
--- a/src/backenddb/pg_lookup_deposits_by_order.c
+++ b/src/backenddb/pg_lookup_deposits_by_order.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
+ Copyright (C) 2023, 2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -74,6 +74,7 @@ lookup_deposits_by_order_cb (void *cls,
char *exchange_url;
struct TALER_MerchantWireHashP h_wire;
struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct GNUNET_TIME_Timestamp deposit_timestamp;
struct TALER_Amount amount_with_fee;
struct TALER_Amount deposit_fee;
struct GNUNET_PQ_ResultSpec rs[] = {
@@ -81,6 +82,8 @@ lookup_deposits_by_order_cb (void *cls,
&deposit_serial),
GNUNET_PQ_result_spec_string ("exchange_url",
&exchange_url),
+ GNUNET_PQ_result_spec_timestamp ("deposit_timestamp",
+ &deposit_timestamp),
GNUNET_PQ_result_spec_auto_from_type ("h_wire",
&h_wire),
TALER_PQ_result_spec_amount_with_currency ("amount_with_fee",
@@ -105,6 +108,7 @@ lookup_deposits_by_order_cb (void *cls,
deposit_serial,
exchange_url,
&h_wire,
+ deposit_timestamp,
&amount_with_fee,
&deposit_fee,
&coin_pub);
@@ -139,6 +143,7 @@ TMH_PG_lookup_deposits_by_order (void *cls,
" dep.deposit_serial"
",mcon.exchange_url"
",acc.h_wire"
+ ",mcon.deposit_timestamp"
",dep.amount_with_fee"
",dep.deposit_fee"
",dep.coin_pub"
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 1a4c15db..fbb662f8 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -42,28 +42,28 @@ static struct TALER_MERCHANTDB_Plugin *plugin;
* @param test 0 on success, non-zero on failure
*/
#define TEST_WITH_FAIL_CLAUSE(test, on_fail) \
- if ((test)) \
- { \
- GNUNET_break (0); \
- on_fail \
- }
+ if ((test)) \
+ { \
+ GNUNET_break (0); \
+ on_fail \
+ }
#define TEST_COND_RET_ON_FAIL(cond, msg) \
- if (! (cond)) \
- { \
- GNUNET_break (0); \
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
- msg); \
- return 1; \
- }
+ if (! (cond)) \
+ { \
+ GNUNET_break (0); \
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
+ msg); \
+ return 1; \
+ }
/**
* @param __test 0 on success, non-zero on failure
*/
#define TEST_RET_ON_FAIL(__test) \
- TEST_WITH_FAIL_CLAUSE (__test, \
- return 1; \
- )
+ TEST_WITH_FAIL_CLAUSE (__test, \
+ return 1; \
+ )
/* ********** Instances ********** */
@@ -1136,7 +1136,8 @@ run_test_products (struct TestProducts_Closure *cls)
stock_dec.product.total_stock = 40;
TEST_RET_ON_FAIL (test_update_product (&cls->instance,
&stock_dec,
- GNUNET_DB_STATUS_SUCCESS_NO_RESULTS));
+ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS))
+ ;
}
{
struct ProductData lost_dec = cls->products[0];
@@ -1144,7 +1145,8 @@ run_test_products (struct TestProducts_Closure *cls)
lost_dec.product.total_lost = 1;
TEST_RET_ON_FAIL (test_update_product (&cls->instance,
&lost_dec,
- GNUNET_DB_STATUS_SUCCESS_NO_RESULTS));
+ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS))
+ ;
}
TEST_RET_ON_FAIL (test_lookup_product (&cls->instance,
&cls->products[0]));
@@ -2195,14 +2197,16 @@ run_test_orders (struct TestOrders_Closure *cls)
cls->orders));
/* Test marking orders as wired */
TEST_RET_ON_FAIL (test_mark_order_wired (serial,
- GNUNET_DB_STATUS_SUCCESS_ONE_RESULT));
+ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT))
+ ;
TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id,
cls->orders[0].id,
NULL,
true,
true));
TEST_RET_ON_FAIL (test_mark_order_wired (1007,
- GNUNET_DB_STATUS_SUCCESS_NO_RESULTS));
+ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS))
+ ;
/* If an order has been claimed and we aren't past
the pay deadline, we can't delete it. */
TEST_RET_ON_FAIL (test_delete_order (&cls->instance,
@@ -2478,7 +2482,8 @@ test_insert_exchange_signkey (const struct ExchangeSignkeyData *signkey,
TEST_COND_RET_ON_FAIL (expected_result ==
plugin->insert_exchange_signkey (plugin->cls,
&signkey->master_pub,
- &signkey->exchange_pub,
+ &signkey->exchange_pub
+ ,
signkey->start_date,
signkey->expire_date,
signkey->end_date,
@@ -2806,8 +2811,8 @@ test_lookup_deposits_contract_and_coin (
* @param cls pointer to the test lookup closure.
* @param deposit_serial row number of the deposit in the database.
* @param exchange_url URL to the exchange
- * @param amount_with_fee amount of the deposit with fees.
* @param h_wire hash of the wire transfer details.
+ * @param deposit_timestamp when was the deposit made
* @param amount_with_fee amount of the deposit with fees.
* @param deposit_fee fee charged for the deposit.
* @param coin_pub public key of the coin deposited.
@@ -2817,11 +2822,13 @@ lookup_deposits_order_cb (void *cls,
uint64_t deposit_serial,
const char *exchange_url,
const struct TALER_MerchantWireHashP *h_wire,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub)
{
struct TestLookupDeposits_Closure *cmp = cls;
+
if (NULL == cmp)
return;
cmp->results_length += 1;
@@ -2871,11 +2878,11 @@ test_lookup_deposits_by_order (uint64_t order_serial,
memset (results_matching,
0,
sizeof (unsigned int) * deposits_length);
- if (deposits_length != plugin->lookup_deposits_by_order (plugin->cls,
- order_serial,
- &
- lookup_deposits_order_cb,
- &cmp))
+ if (deposits_length !=
+ plugin->lookup_deposits_by_order (plugin->cls,
+ order_serial,
+ &lookup_deposits_order_cb,
+ &cmp))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup deposits by order failed\n");
@@ -2923,8 +2930,8 @@ struct LookupDepositSerial_Closure
* @param cls pointer to the test lookup closure.
* @param deposit_serial row number of the deposit in the database.
* @param exchange_url URL to the exchange
- * @param amount_with_fee amount of the deposit with fees.
* @param h_wire hash of the wire transfer details.
+ * @param deposit_timestamp when was the deposit made.
* @param amount_with_fee amount of the deposit with fees.
* @param deposit_fee fee charged for the deposit.
* @param coin_pub public key of the coin deposited.
@@ -2934,11 +2941,14 @@ get_deposit_serial_cb (void *cls,
uint64_t deposit_serial,
const char *exchange_url,
const struct TALER_MerchantWireHashP *h_wire,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub)
{
struct LookupDepositSerial_Closure *lookup_cls = cls;
+
+ (void) deposit_timestamp;
if (NULL == lookup_cls)
return;
if ((0 == strcmp (lookup_cls->deposit->exchange_url,
@@ -4090,7 +4100,8 @@ test_insert_transfer_details (
TEST_COND_RET_ON_FAIL (expected_result ==
plugin->insert_transfer_details (plugin->cls,
instance->instance.id,
- transfer->exchange_url,
+ transfer->exchange_url
+ ,
account->payto_uri,
&transfer->wtid,
&transfer->data),
@@ -4458,7 +4469,8 @@ test_lookup_refunds (const struct InstanceData *instance,
if (refunds_length != cmp.results_length)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup refunds failed: incorrect number of results returned\n");
+ "Lookup refunds failed: incorrect number of results returned\n")
+ ;
return 1;
}
for (unsigned int i = 0; refunds_length > i; ++i)
@@ -4666,7 +4678,8 @@ test_lookup_refunds_detailed (
if (refunds_length != cmp.results_length)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup refunds detailed failed: incorrect number of results\n");
+ "Lookup refunds detailed failed: incorrect number of results\n")
+ ;
return 1;
}
for (unsigned int i = 0; refunds_length > i; ++i)
@@ -4980,7 +4993,8 @@ run_test_refunds (struct TestRefunds_Closure *cls)
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
plugin->refund_coin (plugin->cls,
cls->instance.instance.id,
- &cls->deposits[0].h_contract_terms,
+ &cls->deposits[0].h_contract_terms
+ ,
cls->refunds[0].timestamp,
cls->refunds[0].coin_pub,
cls->refunds[0].reason),
@@ -4992,7 +5006,8 @@ run_test_refunds (struct TestRefunds_Closure *cls)
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
plugin->refund_coin (plugin->cls,
cls->instance.instance.id,
- &cls->deposits[0].h_contract_terms,
+ &cls->deposits[0].h_contract_terms
+ ,
cls->refunds[0].timestamp,
cls->refunds[0].coin_pub,
cls->refunds[0].reason),
@@ -5016,14 +5031,16 @@ run_test_refunds (struct TestRefunds_Closure *cls)
refund_serial,
&cls->refund_proof.
exchange_sig,
- &cls->signkey.exchange_pub),
+ &cls->signkey.exchange_pub
+ ),
"Insert refund proof failed\n");
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
plugin->insert_refund_proof (plugin->cls,
refund_serial,
&cls->refund_proof.
exchange_sig,
- &cls->signkey.exchange_pub),
+ &cls->signkey.exchange_pub
+ ),
"Insert refund proof failed\n");
/* Test that we can't give too much in refunds */
GNUNET_assert (GNUNET_OK ==
@@ -6568,7 +6585,8 @@ test_insert_pending_webhook (const struct InstanceData *instance,
http_method,
pwebhook->pwebhook.
header,
- pwebhook->pwebhook.body),
+ pwebhook->pwebhook.body
+ ),
"Insert pending webhook failed\n");
return 0;
}
@@ -7020,7 +7038,8 @@ run_test_pending_webhooks (struct TestPendingWebhooks_Closure *cls)
&cls->pwebhooks[1]));
TEST_RET_ON_FAIL (test_update_pending_webhook (&cls->instance,
&cls->pwebhooks[1],
- GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); // ???
+ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS));
+ // ???
TEST_RET_ON_FAIL (test_lookup_all_webhooks (&cls->instance,
2,
cls->pwebhooks));
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 263a6fec..43d67aff 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -34,7 +34,7 @@
/**
* Library version (in hex) for compatibility tests.
*/
-#define TALER_MERCHANT_SERVICE_VERSION 0x00090403
+#define TALER_MERCHANT_SERVICE_VERSION 0x00100000
/**
@@ -949,7 +949,7 @@ TALER_MERCHANT_instance_delete_cancel (
* @param arg request to cancel.
*/
#define TALER_MERCHANT_instance_purge_cancel(arg) \
- TALER_MERCHANT_instance_delete_cancel (arg)
+ TALER_MERCHANT_instance_delete_cancel (arg)
/* *************** Accounts **************** */
@@ -2664,6 +2664,12 @@ struct TALER_MERCHANT_OrderStatusResponse
*/
bool wired;
+ /**
+ * Time of the last payment made on this order.
+ * Only availalbe if the server supports protocol
+ * **v14** or higher, otherwise zero.
+ */
+ struct GNUNET_TIME_Timestamp last_payment;
} paid;
/**
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index e7eb2d0f..c83b3c93 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -932,9 +932,10 @@ typedef void
* @param cls closure
* @param deposit_serial which deposit operation is this about
* @param exchange_url URL of the exchange that issued the coin
+ * @param h_wire hash of merchant's wire details
+ * @param deposit_timestamp when was the deposit made
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
- * @param h_wire hash of merchant's wire details
* @param coin_pub public key of the coin
*/
typedef void
@@ -943,6 +944,7 @@ typedef void
uint64_t deposit_serial,
const char *exchange_url,
const struct TALER_MerchantWireHashP *h_wire,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub);
diff --git a/src/lib/merchant_api_get_config.c b/src/lib/merchant_api_get_config.c
index ddbc20a3..b4b700bd 100644
--- a/src/lib/merchant_api_get_config.c
+++ b/src/lib/merchant_api_get_config.c
@@ -34,12 +34,12 @@
* Which version of the Taler protocol is implemented
* by this library? Used to determine compatibility.
*/
-#define MERCHANT_PROTOCOL_CURRENT 13
+#define MERCHANT_PROTOCOL_CURRENT 14
/**
* How many configs are we backwards-compatible with?
*/
-#define MERCHANT_PROTOCOL_AGE 1
+#define MERCHANT_PROTOCOL_AGE 2
/**
* How many exchanges do we allow at most per merchant?
diff --git a/src/lib/merchant_api_merchant_get_order.c b/src/lib/merchant_api_merchant_get_order.c
index 3a49db34..3bd4003b 100644
--- a/src/lib/merchant_api_merchant_get_order.c
+++ b/src/lib/merchant_api_merchant_get_order.c
@@ -202,6 +202,11 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh,
&wire_details),
GNUNET_JSON_spec_array_const ("refund_details",
&refund_details),
+ /* Only available since **v14** */
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_timestamp ("last_payment",
+ &osr->details.ok.details.paid.last_payment),
+ NULL),
GNUNET_JSON_spec_end ()
};