merchant

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

commit 863065d0a7676555b3bcd65a73e81b8690fc0a36
parent a7eac286d3e87097c16c5189b4518c64113f4867
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Wed,  6 Aug 2025 16:42:30 +0200

adding diagnostics

Diffstat:
Msrc/backend/taler-merchant-httpd_post-orders-ID-pay.c | 19+++++++++++++------
Msrc/include/taler_merchant_testing_lib.h | 151++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/testing/test_merchant_api.c | 17+++++++++--------
Msrc/testing/testing_api_cmd_pay_order.c | 147++++++++++++++++++++++++++++++++++++++++++-------------------------------------
4 files changed, 177 insertions(+), 157 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -2096,7 +2096,8 @@ phase_final_output_token_processing (struct PayContext *pc) TALER_MHD_reply_with_error (pc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_STORE_FAILED, - "insert blinded donation receipts")); + "insert blinded donation receipts") + ); return; } } @@ -3424,11 +3425,11 @@ handle_output_donation_receipt ( return GNUNET_NO; #else const struct TALER_Amount *wallet_amount = - DONAU_get_donation_amount_from_bkps (pc->parse_wallet_data.donau_keys, - pc->parse_wallet_data.bkps, - pc->parse_wallet_data.num_bkps, - pc->parse_wallet_data.donau. - donation_year); + DONAU_get_donation_amount_from_bkps ( + pc->parse_wallet_data.donau_keys, + pc->parse_wallet_data.bkps, + pc->parse_wallet_data.num_bkps, + pc->parse_wallet_data.donau.donation_year); if (NULL == wallet_amount) { GNUNET_break_op (0); @@ -3457,6 +3458,12 @@ handle_output_donation_receipt ( if (0 != TALER_amount_cmp (wallet_amount, &output->details.donation_receipt.amount)) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Wallet amount: %s\n", + TALER_amount2s (wallet_amount)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Donation receipt amount: %s\n", + TALER_amount2s (&output->details.donation_receipt.amount)); GNUNET_break_op (0); pay_end (pc, TALER_MHD_reply_with_error ( diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h @@ -38,7 +38,7 @@ #define MERCHANT_FAIL() \ - do {GNUNET_break (0); return NULL; } while (0) + do {GNUNET_break (0); return NULL; } while (0) /** @@ -1125,19 +1125,20 @@ TALER_TESTING_cmd_merchant_pay_order_choices ( * @return the command */ struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_pay_order_donau (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *session_id, - int choice_index, - const char *charity_reference, - const uint64_t year, - const char *donor_tax_id, - const char *salt); +TALER_TESTING_cmd_merchant_pay_order_donau ( + const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee, + const char *session_id, + int choice_index, + const char *charity_reference, + uint64_t year, + const char *donor_tax_id, + const char *salt); #endif @@ -2047,53 +2048,53 @@ TALER_TESTING_cmd_merchant_get_statisticsamount (const char *label, */ // FIXME: rename: refund_entry->refund_detail #define TALER_MERCHANT_TESTING_SIMPLE_TRAITS(op) \ - op (claim_nonce, const struct GNUNET_CRYPTO_EddsaPublicKey) \ - op (pickup_id, const struct TALER_PickupIdentifierP) \ - op (instance_name, const char) \ - op (instance_id, const char) \ - op (address, const json_t) \ - op (product_description, const char) \ - op (product_image, const char) \ - op (product_stock, const int64_t) \ - op (product_unit, const char) \ - op (product_id, const char) \ - op (reason, const char) \ - op (lock_uuid, const char) \ - op (auth_token, const char) \ - op (bearer_token, const char) \ - op (paths_length, const uint32_t) \ - op (payto_length, const uint32_t) \ - op (num_planchets, const uint32_t) \ - op (i18n_description, const json_t) \ - op (taxes, const json_t) \ - op (fee, const struct TALER_Amount) \ - op (use_stefan, const bool) \ - op (jurisdiction, const json_t) \ - op (wire_delay, const struct GNUNET_TIME_Relative) \ - op (pay_delay, const struct GNUNET_TIME_Relative) \ - op (refund_entry, const struct TALER_MERCHANT_RefundDetail) \ - op (order_terms, const json_t) \ - op (h_contract_terms, const struct TALER_PrivateContractHashP) \ - op (h_wire, const struct TALER_MerchantWireHashP) \ - op (proposal_reference, const char) \ - op (template_description, const char) \ - op (otp_device_description, const char) \ - op (otp_id, const char) \ - op (otp_key, const char) \ - op (otp_alg, const enum TALER_MerchantConfirmationAlgorithm) \ - op (template_id, const char) \ - op (template_contract, const json_t) \ - op (event_type, const char) \ - op (webhook_id, const char) \ - op (merchant_base_url, const char) \ - op (url, const char) \ - op (http_method, const char) \ - op (header_template, const char) \ - op (body_template, const char) \ - op (summary, const char) \ - op (token_family_slug, const char) \ - op (token_family_duration, const struct GNUNET_TIME_Relative) \ - op (token_family_kind, const char) + op (claim_nonce, const struct GNUNET_CRYPTO_EddsaPublicKey) \ + op (pickup_id, const struct TALER_PickupIdentifierP) \ + op (instance_name, const char) \ + op (instance_id, const char) \ + op (address, const json_t) \ + op (product_description, const char) \ + op (product_image, const char) \ + op (product_stock, const int64_t) \ + op (product_unit, const char) \ + op (product_id, const char) \ + op (reason, const char) \ + op (lock_uuid, const char) \ + op (auth_token, const char) \ + op (bearer_token, const char) \ + op (paths_length, const uint32_t) \ + op (payto_length, const uint32_t) \ + op (num_planchets, const uint32_t) \ + op (i18n_description, const json_t) \ + op (taxes, const json_t) \ + op (fee, const struct TALER_Amount) \ + op (use_stefan, const bool) \ + op (jurisdiction, const json_t) \ + op (wire_delay, const struct GNUNET_TIME_Relative) \ + op (pay_delay, const struct GNUNET_TIME_Relative) \ + op (refund_entry, const struct TALER_MERCHANT_RefundDetail) \ + op (order_terms, const json_t) \ + op (h_contract_terms, const struct TALER_PrivateContractHashP) \ + op (h_wire, const struct TALER_MerchantWireHashP) \ + op (proposal_reference, const char) \ + op (template_description, const char) \ + op (otp_device_description, const char) \ + op (otp_id, const char) \ + op (otp_key, const char) \ + op (otp_alg, const enum TALER_MerchantConfirmationAlgorithm) \ + op (template_id, const char) \ + op (template_contract, const json_t) \ + op (event_type, const char) \ + op (webhook_id, const char) \ + op (merchant_base_url, const char) \ + op (url, const char) \ + op (http_method, const char) \ + op (header_template, const char) \ + op (body_template, const char) \ + op (summary, const char) \ + op (token_family_slug, const char) \ + op (token_family_duration, const struct GNUNET_TIME_Relative) \ + op (token_family_kind, const char) /** @@ -2102,20 +2103,20 @@ TALER_TESTING_cmd_merchant_get_statisticsamount (const char *label, * @param op macro to call */ #define TALER_MERCHANT_TESTING_INDEXED_TRAITS(op) \ - op (coin_reference, const char) \ - op (paths, const char) \ - op (payto_uris, const struct TALER_FullPayto) \ - op (h_wires, const struct TALER_MerchantWireHashP) \ - op (amounts, const struct TALER_Amount) \ - op (urls, const char) \ - op (http_methods, const char) \ - op (http_header, const char) \ - op (http_body, const void) \ - op (http_body_size, const size_t) \ - op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ - op (token_priv, const struct TALER_TokenUsePrivateKeyP) \ - op (token_issue_sig, const struct TALER_TokenIssueSignature) \ - op (token_issue_pub, const struct TALER_TokenIssuePublicKey) + op (coin_reference, const char) \ + op (paths, const char) \ + op (payto_uris, const struct TALER_FullPayto) \ + op (h_wires, const struct TALER_MerchantWireHashP) \ + op (amounts, const struct TALER_Amount) \ + op (urls, const char) \ + op (http_methods, const char) \ + op (http_header, const char) \ + op (http_body, const void) \ + op (http_body_size, const size_t) \ + op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ + op (token_priv, const struct TALER_TokenUsePrivateKeyP) \ + op (token_issue_sig, const struct TALER_TokenIssueSignature) \ + op (token_issue_pub, const struct TALER_TokenIssuePublicKey) TALER_MERCHANT_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT) diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c @@ -48,7 +48,7 @@ * commands should NOT wait for this timeout! */ #define POLL_ORDER_TIMEOUT \ - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) /** * The 'poll-orders-conclude-1x' and other 'conclude' @@ -56,7 +56,7 @@ * here we use a short value! */ #define POLL_ORDER_SHORT_TIMEOUT \ - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) /** * Configuration file we use. One (big) configuration is used @@ -176,8 +176,8 @@ cmd_exec_wirewatch (const char *label) * @param label label to use for the command. */ #define CMD_EXEC_AGGREGATOR(label) \ - TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \ - TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file) + TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \ + TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file) /** @@ -1877,12 +1877,13 @@ run (void *cls, "EUR:0", // receipts_to_date 2025, // current year &bearer, - "create-another-order-with-input-and-output", // reusing the merhcant_reference for merchant_pub + "create-another-order-with-input-and-output", + // reusing the merchant_reference for merchant_pub MHD_HTTP_CREATED), TALER_TESTING_cmd_merchant_post_donau_instance ( "post-donau-instance", merchant_url, - "create-another-order-with-input-and-output", // reusing the merhcant_reference + "create-another-order-with-input-and-output", // reusing the merchant_reference MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_sleep ( "In this time donaukeyupdate must fetch the keys from the donau", @@ -1907,8 +1908,8 @@ run (void *cls, MHD_HTTP_OK, "create-donau-order", "withdraw-coin-3", - "EUR:0.05", - "EUR:0.04", + "EUR:0.05", /* full amount */ + "EUR:0.04", /* amount without fees */ NULL, 0, "post-charity", diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c @@ -146,6 +146,7 @@ struct MerchantDonauPayData json_t *budis_json; }; + /** * Prepares the donau data for the /pay CMD. * @@ -165,6 +166,7 @@ prepare_donau_data (struct TALER_TESTING_Interpreter *is, is, ss->charity_reference); + // FIXME: fix charity_id type trait to use uint64_t! if (GNUNET_OK != TALER_TESTING_get_trait_charity_id (charity_post_cmd, &charity_id)) @@ -222,11 +224,12 @@ prepare_donau_data (struct TALER_TESTING_Interpreter *is, DONAU_donation_unit_pub_hash (&ss->keys->donation_unit_keys[0].key, &ss->bkps[cnt].h_donation_unit_pub); - ss->receipts[cnt].h_donation_unit_pub = ss->bkps[cnt].h_donation_unit_pub; - udi_nonce = - &ss->receipts[cnt].nonce; - blinded_udi = - &ss->bkps[cnt].blinded_udi; + ss->receipts[cnt].h_donation_unit_pub + = ss->bkps[cnt].h_donation_unit_pub; + udi_nonce + = &ss->receipts[cnt].nonce; + blinded_udi + = &ss->bkps[cnt].blinded_udi; udi_hash = &ss->h_udis[cnt]; GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, @@ -1060,7 +1063,8 @@ pay_run (void *cls, TALER_TESTING_FAIL (is); } - if (0 == strcmp ("tax-receipt", kind)) + if (0 == strcmp ("tax-receipt", + kind)) { const json_t *donau_urls; const char *donau_url_str = NULL; @@ -1107,7 +1111,7 @@ pay_run (void *cls, ps->donau_data.donau_url = GNUNET_strdup (donau_url_str); - if (ps->donau_data.charity_reference != NULL) + if (NULL != ps->donau_data.charity_reference) { switch (prepare_donau_data (is, &ps->donau_data)) @@ -1128,7 +1132,8 @@ pay_run (void *cls, #endif /* HAVE_DONAU_DONAU_SERVICE_H */ } - if (0 == strcmp ("token", kind)) + if (0 == strcmp ("token", + kind)) { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_string ("token_family_slug", @@ -1157,7 +1162,8 @@ pay_run (void *cls, TALER_TESTING_FAIL (is); } - if (0 != strcmp ("token", kind)) + if (0 != strcmp ("token", + kind)) { continue; } @@ -1277,8 +1283,8 @@ pay_run (void *cls, ps->num_issued_tokens); for (unsigned int i = 0; i<len_output_tokens; i++) { - output_tokens[i].envelope.blinded_pub = ps->issued_tokens[i].envelope. - blinded_pub; + output_tokens[i].envelope.blinded_pub + = ps->issued_tokens[i].envelope.blinded_pub; } if (GNUNET_OK != @@ -1484,16 +1490,17 @@ pay_traits (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_pay_order_choices (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *session_id, - int choice_index, - const char *token_reference) +TALER_TESTING_cmd_merchant_pay_order_choices ( + const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee, + const char *session_id, + int choice_index, + const char *token_reference) { struct PayState *ps; @@ -1524,19 +1531,20 @@ TALER_TESTING_cmd_merchant_pay_order_choices (const char *label, #ifdef HAVE_DONAU_DONAU_SERVICE_H struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_pay_order_donau (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *session_id, - int choice_index, - const char *charity_reference, - const uint64_t year, - const char *donor_tax_id, - const char *salt) +TALER_TESTING_cmd_merchant_pay_order_donau ( + const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee, + const char *session_id, + int choice_index, + const char *charity_reference, + uint64_t year, + const char *donor_tax_id, + const char *salt) { struct PayState *ps; @@ -1550,26 +1558,27 @@ TALER_TESTING_cmd_merchant_pay_order_donau (const char *label, ps->session_id = session_id; ps->token_reference = NULL; ps->choice_index = choice_index; - ps->donau_data.year = year; ps->donau_data.num_bkps = 5; ps->donau_data.charity_reference = charity_reference; /* Compute h_donor_tax_id directly into ps->donau_data: */ -{ - crypto_hash_sha512_state state; - size_t tax_length = strlen(donor_tax_id); - size_t salt_length = strlen(salt); - crypto_hash_sha512_init(&state); - crypto_hash_sha512_update(&state, - (const unsigned char*)donor_tax_id, - tax_length); - crypto_hash_sha512_update(&state, - (const unsigned char*)salt, - salt_length); - crypto_hash_sha512_final(&state, - ps->donau_data.h_donor_tax_id.hash); -} - + // FIXME: donau should export a helper function for this! + { + crypto_hash_sha512_state state; + size_t tax_length = strlen (donor_tax_id); + size_t salt_length = strlen (salt); + + crypto_hash_sha512_init (&state); + crypto_hash_sha512_update (&state, + (const unsigned char*) donor_tax_id, + tax_length); + crypto_hash_sha512_update (&state, + (const unsigned char*) salt, + salt_length); + crypto_hash_sha512_final (&state, + ps->donau_data.h_donor_tax_id.hash); + } + { struct TALER_TESTING_Command cmd = { .cls = ps, @@ -1588,25 +1597,27 @@ TALER_TESTING_cmd_merchant_pay_order_donau (const char *label, struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_pay_order (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *session_id) +TALER_TESTING_cmd_merchant_pay_order ( + const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee, + const char *session_id) { - return TALER_TESTING_cmd_merchant_pay_order_choices (label, - merchant_url, - http_status, - proposal_reference, - coin_reference, - amount_with_fee, - amount_without_fee, - session_id, - -1, - NULL); + return TALER_TESTING_cmd_merchant_pay_order_choices ( + label, + merchant_url, + http_status, + proposal_reference, + coin_reference, + amount_with_fee, + amount_without_fee, + session_id, + -1, + NULL); }