merchant

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

commit ccee6c1506ff1352be8ab3f4c824075bd8bb04c0
parent a65da9794522bbad20cfc22bdc4d47c956134f3f
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date:   Fri, 14 Mar 2025 18:23:58 +0100

adding some logic steps, cleaning some code

Diffstat:
Msrc/backend/taler-merchant-httpd_post-orders-ID-pay.c | 131++++++++++++-------------------------------------------------------------------
1 file changed, 19 insertions(+), 112 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 @@ -1720,6 +1720,8 @@ phase_success_response (struct PayContext *pc) ? NULL : build_token_sigs (pc); // FIXME: add signatures obtained from donau to response + // theoretically, we could just add the json object received from donau + // aka BlindedDonationReceiptSignatures pay_end (pc, TALER_MHD_REPLY_JSON_PACK ( pc->connection, @@ -2486,7 +2488,17 @@ phase_execute_pay_transaction (struct PayContext *pc) // FIXME: if we have donation receipts, do NEW phase // DONAU interaction here, otherwise skip DONAU phase // and move to payment notification - pc->phase = PP_PAYMENT_NOTIFICATION; + // aka + if (NULL != pc->parse_wallet_data.donau.donau_url) + { + /* We have a Donau URL => we do the new donation receipt phase. */ + pc->phase = PP_GENERATE_DONATION_RECEIPT; + } + else + { + /* No Donau URL, skip donation phase. */ + pc->phase = PP_PAYMENT_NOTIFICATION; + } } @@ -2853,111 +2865,6 @@ handle_output_token(struct PayContext *pc, return GNUNET_OK; } -/** - * Handle contract output of type TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN. - * Looks up the token family, loads the matching private key, - * and signs the corresponding token envelopes from the wallet. - * - * @param pc context for the pay request - * @param output contract output we need to process - * @param output_index index of this output in the contract's outputs array - * @return GNUNET_OK on success, GNUNET_NO if an error was encountered - */ -static enum GNUNET_GenericReturnValue -handle_output_validate_token(struct PayContext *pc, - const struct TALER_MERCHANT_ContractOutput *output, - unsigned int output_index) -{ - const struct TALER_MERCHANT_ContractTokenFamily *family; - struct TALER_MERCHANT_ContractTokenFamilyKey *key; - struct TALER_MERCHANTDB_TokenFamilyKeyDetails details; - enum GNUNET_DB_QueryStatus qs; - bool mandatory; - - /* Locate token family in the contract. This should never fail if - * the contract passed validation before insertion. */ - family = find_family(pc, - output->details.token.token_family_slug); - if (NULL == family) - { - /* This "should never happen", so treat it as an internal error */ - GNUNET_break(0); - pay_end(pc, - TALER_MHD_reply_with_error( - pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "token family not found in order")); - return GNUNET_NO; /* signals error */ - } - - /* Check the key_index field from the output. */ - if (output->details.token.key_index >= family->keys_len) - { - /* Also "should never happen", contract was presumably validated on insert */ - GNUNET_break(0); - pay_end(pc, - TALER_MHD_reply_with_error( - pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "key index invalid for token family")); - return GNUNET_NO; - } - - /* Pick the correct key inside that family. */ - key = &family->keys[output->details.token.key_index]; - - /* Fetch the private key from the DB for the merchant instance and - * this particular family/time interval. */ - qs = TMH_db->lookup_token_family_key( - TMH_db->cls, - pc->hc->instance->settings.id, - family->slug, - pc->check_contract.contract_terms->timestamp, - pc->check_contract.contract_terms->pay_deadline, - &details); - if (qs <= 0) - { - GNUNET_log( - GNUNET_ERROR_TYPE_ERROR, - "Did not find key for %s at [%llu,%llu]\n", - family->slug, - (unsigned long long) pc->check_contract.contract_terms->timestamp.abs_time.abs_value_us, - (unsigned long long) pc->check_contract.contract_terms->pay_deadline.abs_time.abs_value_us); - GNUNET_break(0); - pay_end(pc, - TALER_MHD_reply_with_error( - pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - NULL)); - return GNUNET_NO; - } - GNUNET_assert(NULL != details.priv.private_key); - - /* Depending on the token family, decide if the token envelope - * is mandatory or optional. (Simplified logic here: adapt as needed.) */ - mandatory = test_tfk_mandatory(details.token_family.kind); - - /* Actually sign the number of token envelopes specified in 'count'. - * 'output_index' is the offset into the parse_wallet_data arrays. */ - if (GNUNET_OK != - sign_token_envelopes(pc, - key, - &details.priv, - mandatory, - output_index, - output->details.token.count)) - { - /* sign_token_envelopes() already queued up an error via pay_end() */ - return GNUNET_NO; - } - - /* Everything OK. */ - return GNUNET_OK; -} - /** * Validate tokens and token envelopes. First, we check if all tokens listed @@ -3041,9 +2948,9 @@ phase_validate_tokens (struct PayContext *pc) switch(output->type){ case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN: if (GNUNET_OK != - handle_output_validate_token (pc, - output, - i)) + handle_output_token (pc, + output, + i)) { /* Error is already scheduled from handle_output_token. */ return; @@ -4080,9 +3987,9 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh, phase_payment_notification (pc); break; // FIXME: donau phase -// case PP_GENERATE_DONATION_RECEIPT: -// phase_generate_donation_receipt (pc); -// break; + case PP_GENERATE_DONATION_RECEIPT: + phase_generate_donation_receipt (pc); + break; case PP_SUCCESS_RESPONSE: phase_success_response (pc); break;