merchant

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

commit 3421048ed589e7230307028f1949937413b343fc
parent a99831004017312d7c85044b94753b4f67194cc7
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date:   Sat, 25 Jun 2016 14:33:58 +0200

Merge branch '4540' of ssh://taler.net/var/git/merchant into 4540

Diffstat:
Msrc/backend/merchant.conf | 14+++++++++-----
Msrc/backend/taler-merchant-httpd.c | 3++-
Msrc/backend/taler-merchant-httpd.h | 2+-
Msrc/backend/taler-merchant-httpd_contract.c | 9+++++++++
Msrc/backend/taler-merchant-httpd_track-transaction.c | 28+++++++++++++++++++++++++++-
Msrc/include/taler_merchant_service.h | 8++++++++
Msrc/lib/merchant_api_pay.c | 9+++++++++
Msrc/lib/merchant_api_track_transaction.c | 2++
Msrc/lib/merchant_api_track_transfer.c | 2++
Msrc/lib/test_merchant_api.c | 26+++++++++++++++++++++++++-
Msrc/lib/test_merchant_api.conf | 15+++++++++++++++
11 files changed, 109 insertions(+), 9 deletions(-)

diff --git a/src/backend/merchant.conf b/src/backend/merchant.conf @@ -30,10 +30,14 @@ WIRE_TRANSFER_DELAY = 3 week [merchantdb-postgres] CONFIG = postgres:///talermerchant +[merchant-instance-default] +KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv + +[merchant-instance-tor] +KEYFILE = ${TALER_DATA_HOME}/merchant/tor.priv -# Configuration of our bank account details -[merchant-wireformat] -# Default location for the 'test' wire plugin +[default-wireformat] TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/test.json -# Default location for the 'sepa' wire plugin -SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/sepa.json + +[tor-wireformat] +TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/tor.json diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -258,6 +258,7 @@ do_shutdown (void *cls) for (i=0; NULL != instances[i]; i++) { json_decref (instances[i]->j_wire); + GNUNET_free (instances[i]->id); GNUNET_free (instances[i]); } } @@ -455,7 +456,7 @@ instances_iterator_cb (void *cls, GNUNET_free (pk); /** To free or not to free **/ - mi->id = token + 1; + mi->id = GNUNET_strdup (token + 1); if (0 == strcmp ("default", mi->id)) iic->default_instance = GNUNET_YES; diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h @@ -81,7 +81,7 @@ struct MerchantInstance { * the configuration is kept in memory, as it's as substring of * a section name */ - const char *id; + char *id; /** * File holding the merchant's private key diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c @@ -223,6 +223,15 @@ MH_handler_contract (struct TMH_RequestHandler *rh, } mi = get_instance (root); + if (NULL == mi) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Not able to find the specified receiver\n"); + json_decref (root); + return TMH_RESPONSE_reply_external_error (connection, + "Unknown receiver given"); + } + /* add fields to the contract that the backend should provide */ json_object_set (jcontract, "exchanges", diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c @@ -43,6 +43,10 @@ */ struct TrackTransactionContext; +/** + * Merchant instance being tracked + */ +struct MerchantInstance; /** * Information we keep for each coin in a /track/transaction operation. @@ -205,6 +209,11 @@ struct TrackTransactionContext */ unsigned int response_code; + /** + * Which merchant instance is being tracked + */ + struct MerchantInstance *mi; + }; @@ -591,7 +600,7 @@ trace_coins (struct TrackTransactionContext *tctx) return; } tcc->dwh = TALER_EXCHANGE_track_transaction (tctx->eh, - &privkey, + &tctx->mi->privkey, &tctx->h_wire, &tctx->h_contract, &tcc->coin_pub, @@ -752,6 +761,7 @@ coin_cb (void *cls, tcc)); } +extern struct MerchantInstance **instances; /** * Handle a "/track/transaction" request. @@ -773,6 +783,8 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, struct TrackTransactionContext *tctx; unsigned long long transaction_id; const char *str; + const char *receiver; + unsigned int i; int ret; if (NULL == *connection_cls) @@ -824,6 +836,20 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, if (NULL == str) return TMH_RESPONSE_reply_bad_request (connection, "id argument missing"); + receiver = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "receiver"); + if (NULL == receiver) + receiver = "default"; + + tctx->mi = NULL; + for (i=0; NULL != instances[i]; i++) + if (0 == strcmp (receiver, instances[i]->id)) + tctx->mi = instances[i]; + + if (NULL == tctx->mi) + return TMH_RESPONSE_reply_bad_request (connection, + "unknown receiver"); if (1 != sscanf (str, "%llu", diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h @@ -161,6 +161,7 @@ struct TALER_MERCHANT_PayCoin * * @param ctx execution context * @param merchant_uri base URI of the merchant + * @param receiver which merchant instance will receive this payment * @param h_wire hash of the merchant’s account details * @param h_contract hash of the contact of the merchant with the customer * @param transaction_id transaction id for the transaction between merchant and customer @@ -181,6 +182,7 @@ struct TALER_MERCHANT_PayCoin struct TALER_MERCHANT_Pay * TALER_MERCHANT_pay_wallet (struct GNUNET_CURL_Context *ctx, const char *merchant_uri, + const char *receiver, const struct GNUNET_HashCode *h_contract, uint64_t transaction_id, const struct TALER_Amount *amount, @@ -249,6 +251,7 @@ struct TALER_MERCHANT_PaidCoin * * @param ctx execution context * @param merchant_uri base URI of the merchant + * @param receiver which merchant instance will receive this payment * @param h_contract hash of the contact of the merchant with the customer * @param amount total value of the contract to be paid to the merchant * @param max_fee maximum fee covered by the merchant (according to the contract) @@ -268,6 +271,7 @@ struct TALER_MERCHANT_PaidCoin struct TALER_MERCHANT_Pay * TALER_MERCHANT_pay_frontend (struct GNUNET_CURL_Context *ctx, const char *merchant_uri, + const char *receiver, const struct GNUNET_HashCode *h_contract, const struct TALER_Amount *amount, const struct TALER_Amount *max_fee, @@ -333,6 +337,7 @@ typedef void * * @param ctx execution context * @param backend_uri base URI of the backend + * @param receiver which merchant instance is going to be tracked * @param wtid base32 string indicating a wtid * @param exchange base URL of the exchange in charge of returning the wanted information * @param track_transfer_cb the callback to call when a reply for this request is available @@ -342,6 +347,7 @@ typedef void struct TALER_MERCHANT_TrackTransferHandle * TALER_MERCHANT_track_transfer (struct GNUNET_CURL_Context *ctx, const char *backend_uri, + const char *receiver, const struct TALER_WireTransferIdentifierRawP *wtid, const char *exchange_uri, TALER_MERCHANT_TrackTransferCallback track_transfer_cb, @@ -442,6 +448,7 @@ typedef void * * @param ctx execution context * @param backend_uri base URI of the backend + * @param receiver which merchant instance is going to be tracked * @param transaction_id which transaction should we trace * @param track_transaction_cb the callback to call when a reply for this request is available * @param track_transaction_cb_cls closure for @a track_transaction_cb @@ -450,6 +457,7 @@ typedef void struct TALER_MERCHANT_TrackTransactionHandle * TALER_MERCHANT_track_transaction (struct GNUNET_CURL_Context *ctx, const char *backend_uri, + const char *receiver, uint64_t transaction_id, TALER_MERCHANT_TrackTransactionCallback track_transaction_cb, void *track_transaction_cb_cls); diff --git a/src/lib/merchant_api_pay.c b/src/lib/merchant_api_pay.c @@ -251,6 +251,7 @@ handle_pay_finished (void *cls, * * @param ctx the execution loop context * @param merchant_uri base URI of the merchant's backend + * @param receiver which merchant instance will receive this payment * @param h_wire hash of the merchant’s account details * @param h_contract hash of the contact of the merchant with the customer * @param transaction_id transaction id for the transaction between merchant and customer @@ -275,6 +276,7 @@ handle_pay_finished (void *cls, struct TALER_MERCHANT_Pay * TALER_MERCHANT_pay_wallet (struct GNUNET_CURL_Context *ctx, const char *merchant_uri, + const char *receiver, const struct GNUNET_HashCode *h_contract, uint64_t transaction_id, const struct TALER_Amount *amount, @@ -337,6 +339,7 @@ TALER_MERCHANT_pay_wallet (struct GNUNET_CURL_Context *ctx, } return TALER_MERCHANT_pay_frontend (ctx, merchant_uri, + receiver, h_contract, amount, max_fee, @@ -361,6 +364,7 @@ TALER_MERCHANT_pay_wallet (struct GNUNET_CURL_Context *ctx, * * @param ctx the execution loop context * @param merchant_uri base URI of the merchant's backend + * @param receiver which merchant instance will receive this payment * @param h_contract hash of the contact of the merchant with the customer * @param timestamp timestamp when the contract was finalized, must match approximately the current time of the merchant * @param transaction_id transaction id for the transaction between merchant and customer @@ -379,6 +383,7 @@ TALER_MERCHANT_pay_wallet (struct GNUNET_CURL_Context *ctx, struct TALER_MERCHANT_Pay * TALER_MERCHANT_pay_frontend (struct GNUNET_CURL_Context *ctx, const char *merchant_uri, + const char *receiver, const struct GNUNET_HashCode *h_contract, const struct TALER_Amount *amount, const struct TALER_Amount *max_fee, @@ -557,6 +562,10 @@ TALER_MERCHANT_pay_frontend (struct GNUNET_CURL_Context *ctx, "max_fee", TALER_JSON_from_amount (max_fee), "amount", TALER_JSON_from_amount (amount), "merchant_sig", GNUNET_JSON_from_data_auto (merchant_sig)); + if (NULL != receiver) + json_object_set_new (pay_obj, + "receiver", + json_string (receiver)); if (0 != wire_transfer_deadline.abs_value_us) { diff --git a/src/lib/merchant_api_track_transaction.c b/src/lib/merchant_api_track_transaction.c @@ -230,6 +230,7 @@ handle_track_transaction_finished (void *cls, * * @param ctx execution context * @param backend_uri base URI of the backend + * @param receiver which merchant instance is going to be tracked * @param transaction_id which transaction should we trace * @param track_transaction_cb the callback to call when a reply for this request is available * @param track_transaction_cb_cls closure for @a track_transaction_cb @@ -238,6 +239,7 @@ handle_track_transaction_finished (void *cls, struct TALER_MERCHANT_TrackTransactionHandle * TALER_MERCHANT_track_transaction (struct GNUNET_CURL_Context *ctx, const char *backend_uri, + const char *receiver, uint64_t transaction_id, TALER_MERCHANT_TrackTransactionCallback track_transaction_cb, void *track_transaction_cb_cls) diff --git a/src/lib/merchant_api_track_transfer.c b/src/lib/merchant_api_track_transfer.c @@ -272,6 +272,7 @@ handle_track_transfer_finished (void *cls, * * @param ctx execution context * @param backend_uri base URI of the backend + * @param receiver which merchant instance is going to be tracked * @param wtid base32 string indicating a wtid * @param exchange base URL of the exchange in charge of returning the wanted information * @param track_transfer_cb the callback to call when a reply for this request is available @@ -281,6 +282,7 @@ handle_track_transfer_finished (void *cls, struct TALER_MERCHANT_TrackTransferHandle * TALER_MERCHANT_track_transfer (struct GNUNET_CURL_Context *ctx, const char *backend_uri, + const char *receiver, const struct TALER_WireTransferIdentifierRawP *wtid, const char *exchange_uri, TALER_MERCHANT_TrackTransferCallback track_transfer_cb, diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c @@ -61,6 +61,12 @@ static struct TALER_EXCHANGE_Handle *exchange; static struct GNUNET_CURL_Context *ctx; /** + * Which merchant instance we will run the testcase for + */ +static char *receiver = NULL; + + +/** * Public key of the merchant, matches the private * key from "test_merchant.priv". */ @@ -1436,6 +1442,10 @@ interpreter_run (void *cls) proposal = json_loads (cmd->details.contract.proposal, JSON_REJECT_DUPLICATES, &error); + if (NULL != receiver) + json_object_set_new (proposal, + "receiver", + json_string (receiver)); if (NULL == proposal) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1558,10 +1568,13 @@ interpreter_run (void *cls) return; } } - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Using receiver '%s'\n", + receiver); cmd->details.pay.ph = TALER_MERCHANT_pay_wallet (ctx, MERCHANT_URI, + receiver, &h_contract, transaction_id, &total_amount, @@ -1656,6 +1669,7 @@ interpreter_run (void *cls) cmd->details.track_transfer.tdo = TALER_MERCHANT_track_transfer (ctx, MERCHANT_URI, + receiver, &ref->details.check_bank_transfer.wtid, EXCHANGE_URI, &track_transfer_cb, @@ -1668,6 +1682,7 @@ interpreter_run (void *cls) cmd->details.track_transaction.tth = TALER_MERCHANT_track_transaction (ctx, MERCHANT_URI, + receiver, ref->details.pay.transaction_id, &track_transaction_cb, is); @@ -1838,6 +1853,7 @@ do_shutdown (void *cls) is->task = NULL; } GNUNET_free (is); + GNUNET_free_non_null (receiver); if (NULL != exchange) { TALER_EXCHANGE_disconnect (exchange); @@ -2150,6 +2166,14 @@ main (int argc, GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, "test_merchant_api.conf")); + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, + "merchant", + "INSTANCE", + &receiver)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Using non default receiver '%s'\n", + receiver); + db = TALER_MERCHANTDB_plugin_load (cfg); if (NULL == db) { diff --git a/src/lib/test_merchant_api.conf b/src/lib/test_merchant_api.conf @@ -36,11 +36,26 @@ DB = postgres # Which wireformat do we use? WIREFORMAT = test +# If set, this option will drive the testcase so that +# `INSTANCE' will be the used merchant instance. Otherwise +# we use the 'default' instance +INSTANCE = tor + [merchant-exchange-test] URI = http://localhost:8081/ MASTER_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG +[merchant-instance-default] +KEYFILE = test_merchant.priv + +[default-wireformat] +TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/test.json + +[merchant-instance-tor] +KEYFILE = test_merchant.priv +[tor-wireformat] +TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/test.json # Auditors must be in sections "auditor-", the rest of the section # name could be anything.