From b69168984a55d7318cb9316e73affbfabfeb088c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 28 Dec 2017 17:00:46 +0100 Subject: more work towards /pay abort mode --- .../taler-merchant-httpd_track-transaction.c | 1 + src/backend/taler-merchant-httpd_track-transfer.c | 1 + src/include/taler_merchant_service.h | 13 +++- src/lib/merchant_api_pay.c | 91 ++++++++++++++++------ 4 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c index 27d2d06e..e59e89ae 100644 --- a/src/backend/taler-merchant-httpd_track-transaction.c +++ b/src/backend/taler-merchant-httpd_track-transaction.c @@ -940,6 +940,7 @@ coin_cb (void *cls, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_Amount *refund_fee, + const struct TALER_Amount *wire_fee, const json_t *exchange_proof) { struct TrackTransactionContext *tctx = cls; diff --git a/src/backend/taler-merchant-httpd_track-transfer.c b/src/backend/taler-merchant-httpd_track-transfer.c index 3d4b4184..6297c8fa 100644 --- a/src/backend/taler-merchant-httpd_track-transfer.c +++ b/src/backend/taler-merchant-httpd_track-transfer.c @@ -447,6 +447,7 @@ check_transfer (void *cls, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_Amount *refund_fee, + const struct TALER_Amount *wire_fee, const json_t *exchange_proof) { struct TrackTransferContext *rctx = cls; diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h index ca907220..8c6c7702 100644 --- a/src/include/taler_merchant_service.h +++ b/src/include/taler_merchant_service.h @@ -309,7 +309,7 @@ struct TALER_MERCHANT_PayCoin * Amount this coin is to contribute (without fee). */ struct TALER_Amount amount_without_fee; - + /** * URL of the exchange that issued @e coin_priv. */ @@ -371,16 +371,22 @@ TALER_MERCHANT_pay_wallet (struct GNUNET_CURL_Context *ctx, * was with a merchant frontend or backend; * 0 if the merchant's reply is bogus (fails to follow the protocol) * @param ec taler-specific error code + * @param merchant_pub public key of the merchant + * @param h_contract hash of the contract * @param num_refunds size of the @a merchant_sigs array, 0 on errors * @param merchant_sigs merchant signatures refunding coins, NULL on errors + * @param rtids refund transaction IDs (array of length @a num_refunds) * @param obj the received JSON reply, with error details if the request failed */ typedef void (*TALER_MERCHANT_PayRefundCallback) (void *cls, unsigned int http_status, enum TALER_ErrorCode ec, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct GNUNET_HashCode *h_contract, unsigned int num_refunds, const struct TALER_MerchantSignatureP *merchant_sigs, + const uint64_t *rtids, const json_t *obj); @@ -469,6 +475,11 @@ struct TALER_MERCHANT_PaidCoin */ struct TALER_Amount amount_without_fee; + /** + * Fee the exchange charges for refunds of this coin. + */ + struct TALER_Amount refund_fee; + /** * What is the URL of the exchange that issued @a coin_pub? */ diff --git a/src/lib/merchant_api_pay.c b/src/lib/merchant_api_pay.c index 276680e2..4856d288 100644 --- a/src/lib/merchant_api_pay.c +++ b/src/lib/merchant_api_pay.c @@ -83,16 +83,21 @@ struct TALER_MERCHANT_Pay */ struct GNUNET_CURL_Context *ctx; + /** + * The coins we are paying with. + */ + struct TALER_MERCHANT_PaidCoin *coins; + /** * Number of @e coins we are paying with. */ unsigned int num_coins; /** - * The coins we are paying with. + * Hash of the contract, only available in "abort-refund" mode. */ - struct TALER_MERCHANT_PaidCoin *coins; - + struct GNUNET_HashCode h_contract_terms; + }; @@ -111,8 +116,10 @@ check_abort_refund (struct TALER_MERCHANT_Pay *ph, { json_t *refunds; unsigned int num_refunds; + struct TALER_MerchantPublicKeyP merchant_pub; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("refunds", &refunds), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), GNUNET_JSON_spec_end() }; @@ -133,15 +140,19 @@ check_abort_refund (struct TALER_MERCHANT_Pay *ph, } { struct TALER_MerchantSignatureP sigs[num_refunds]; + uint64_t rtids[num_refunds]; for (unsigned int i=0;ih_contract_terms; + rr.coin_pub = ph->coins[i].coin_pub; + rr.merchant = merchant_pub; + rr.rtransaction_id = GNUNET_htonll (rtransaction_id); + TALER_amount_hton (&rr.refund_amount, + &ph->coins[i].amount_with_fee); + TALER_amount_hton (&rr.refund_fee, + &ph->coins[i].refund_fee); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND, + &rr.purpose, + &sig->eddsa_sig, + &merchant_pub.eddsa_pub)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + rtids[i] = rtransaction_id; } - /* FIXME: check that signature is valid! */ ph->abort_cb (ph->abort_cb_cls, MHD_HTTP_OK, TALER_EC_NONE, + &merchant_pub, + &ph->h_contract_terms, num_refunds, sigs, + rtids, json); ph->abort_cb = NULL; } @@ -383,8 +417,11 @@ handle_pay_finished (void *cls, ph->abort_cb (ph->abort_cb_cls, response_code, TALER_JSON_get_error_code (json), + NULL, + NULL, 0, NULL, + NULL, json); } @@ -613,7 +650,7 @@ prepare_pay_generic (struct GNUNET_CURL_Context *ctx, GNUNET_break (0); return NULL; } - + dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); dr.h_contract_terms = *h_contract_terms; @@ -786,26 +823,30 @@ TALER_MERCHANT_pay_abort (struct GNUNET_CURL_Context *ctx, TALER_MERCHANT_PayRefundCallback payref_cb, void *payref_cb_cls) { - return prepare_pay_generic (ctx, - merchant_url, - instance, - h_contract, - amount, - max_fee, - merchant_pub, - merchant_sig, - timestamp, - refund_deadline, - pay_deadline, - h_wire, - order_id, - num_coins, - coins, - "abort-refund", - NULL, - NULL, - payref_cb, - payref_cb_cls); + struct TALER_MERCHANT_Pay *ph; + + ph = prepare_pay_generic (ctx, + merchant_url, + instance, + h_contract, + amount, + max_fee, + merchant_pub, + merchant_sig, + timestamp, + refund_deadline, + pay_deadline, + h_wire, + order_id, + num_coins, + coins, + "abort-refund", + NULL, + NULL, + payref_cb, + payref_cb_cls); + ph->h_contract_terms = *h_contract; + return ph; } -- cgit v1.2.3