merchant

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

commit 03117c758125946a29fe8c89a52c0fb70ed11213
parent 1e5a506bacdec7a2fe972aaa476a3bb53d965dc7
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date:   Tue, 24 Jun 2025 14:46:06 +0200

kyc passes

Diffstat:
Msrc/backend/taler-merchant-httpd_post-orders-ID-pay.c | 21+++++++++++++++++----
Msrc/include/taler_merchant_pay_service.h | 1+
Msrc/lib/taler_merchant_pay_service.c | 104+++++++++++++++++++++++++++++++-------------------------------------------------
Msrc/testing/testing_api_cmd_pay_order.c | 13+++++++------
4 files changed, 65 insertions(+), 74 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 @@ -2823,10 +2823,7 @@ phase_execute_pay_transaction (struct PayContext *pc) return; } } - // REVIEW: if we have donation receipts, do NEW phase - // DONAU interaction here, otherwise skip DONAU phase - // and move to payment notification - // aka + if (NULL != pc->parse_wallet_data.donau.donau_url) { /* We have a Donau URL => we do the new donation receipt phase. */ @@ -4003,6 +4000,22 @@ phase_parse_pay (struct PayContext *pc) GNUNET_JSON_spec_end () }; + { + // TODO: Clean up this block when done + // Print the request body for debugging purposes + char *dump = json_dumps (pc->hc->request_body, + JSON_INDENT (2) /* human friendly */ + | JSON_ENCODE_ANY /* handle UTF-8 as \uXXXX */ + | JSON_SORT_KEYS /* deterministic output */); + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "POST /orders/%s/pay – request body follows:\n%s\n", + pc->order_id, + dump); + + free (dump); + } + GNUNET_assert (PP_PARSE_PAY == pc->phase); { enum GNUNET_GenericReturnValue res; diff --git a/src/include/taler_merchant_pay_service.h b/src/include/taler_merchant_pay_service.h @@ -67,6 +67,7 @@ enum TALER_MERCHANT_OrderPayOptionType TALER_MERCHANT_OrderPayOptionType_COINS, TALER_MERCHANT_OrderPayOptionType_INPUT_TOKENS, TALER_MERCHANT_OrderPayOptionType_OUTPUT_TOKENS, + TALER_MERCHANT_OrderPayOptionType_WALLET_DATA, //Used privately so no #define is present for it /*New objects go in here*/ TALER_MERCHANT_OrderPayOptionType_LENGTH }; diff --git a/src/lib/taler_merchant_pay_service.c b/src/lib/taler_merchant_pay_service.c @@ -76,6 +76,10 @@ struct TALER_MERCHANT_OrderPayHandle bool has_choice_index; int choice_index; + /*Used for strcmp in the legacy we just keep it for this time*/ + struct TALER_Amount *amount; + struct TALER_Amount *max_fee; + /* raw arrays as passed in via set_options(): */ struct { unsigned int num_coins; @@ -87,7 +91,6 @@ struct TALER_MERCHANT_OrderPayHandle const struct TALER_MERCHANT_UseToken *tokens; } input_tokens; - //FIXME: Remove this as we move to the json object for it struct { unsigned int num_output_tokens; const struct TALER_MERCHANT_OutputToken *output_tokens; @@ -476,22 +479,18 @@ TALER_MERCHANT_order_pay_set_options (struct TALER_MERCHANT_OrderPayHandle *ph, } case TALER_MERCHANT_OrderPayOptionType_ORDER_ID: - ph->order_id = GNUNET_strdup (o->details.order_id); + { + ph->order_id = GNUNET_strdup(o->details.order_id); break; + } case TALER_MERCHANT_OrderPayOptionType_H_CONTRACT: + { ph->h_contract_terms = *o->details.h_contract; - ph->has_h_contract = true; - { - json_t *js = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("h_contract", o->details.h_contract) - ); - enum TALER_MERCHANT_OrderPayOptionErrorCode ec = - store_json_option (ph, o->ot, js); - if (TALER_MERCHANT_OPOEC_OK != ec) - return ec; - break; - } + ph->has_h_contract = true; + + break; + } case TALER_MERCHANT_OrderPayOptionType_CHOICE_INDEX: ph->choice_index = o->details.choice_index; @@ -510,58 +509,28 @@ TALER_MERCHANT_order_pay_set_options (struct TALER_MERCHANT_OrderPayHandle *ph, case TALER_MERCHANT_OrderPayOptionType_AMOUNT: { - json_t *js = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("amount", - &o->details.amount) - ); - enum TALER_MERCHANT_OrderPayOptionErrorCode ec = - store_json_option (ph, o->ot, js); - if (TALER_MERCHANT_OPOEC_OK != ec) - return ec; - break; + ph->amount = &o->details.amount; + break; } case TALER_MERCHANT_OrderPayOptionType_MAX_FEE: { - json_t *js = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("max_fee", - &o->details.max_fee) - ); - enum TALER_MERCHANT_OrderPayOptionErrorCode ec = - store_json_option (ph, o->ot, js); - if (TALER_MERCHANT_OPOEC_OK != ec) - return ec; - break; + ph->max_fee = &o->details.max_fee; + break; } case TALER_MERCHANT_OrderPayOptionType_MERCHANT_PUB: - ph->merchant_pub = o->details.merchant_pub; + { + ph->merchant_pub = o->details.merchant_pub; ph->has_merchant_pub = true; - { - json_t *js = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("merchant_pub", - &o->details.merchant_pub) - ); - enum TALER_MERCHANT_OrderPayOptionErrorCode ec = - store_json_option (ph, o->ot, js); - if (TALER_MERCHANT_OPOEC_OK != ec) - return ec; - break; - } + + break; + } case TALER_MERCHANT_OrderPayOptionType_TIMESTAMP: { ph->timestamp = o->details.timestamp; - - json_t *js = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_timestamp ("timestamp", - o->details.timestamp) - ); - enum TALER_MERCHANT_OrderPayOptionErrorCode ec = - store_json_option (ph, o->ot, js); - if (TALER_MERCHANT_OPOEC_OK != ec) - return ec; - break; + break; } case TALER_MERCHANT_OrderPayOptionType_REFUND_DEADLINE: @@ -582,15 +551,7 @@ TALER_MERCHANT_order_pay_set_options (struct TALER_MERCHANT_OrderPayHandle *ph, ph->h_wire = o->details.h_wire; ph->has_h_wire = true; - json_t *js = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("h_wire", - &o->details.h_wire) - ); - enum TALER_MERCHANT_OrderPayOptionErrorCode ec = - store_json_option (ph, o->ot, js); - if (TALER_MERCHANT_OPOEC_OK != ec) - return ec; - break; + break; } case TALER_MERCHANT_OrderPayOptionType_COINS: @@ -646,15 +607,28 @@ TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph) if ( !(ph->coins.num_coins > 0) ) return TALER_MERCHANT_OPOEC_MISSING_MANDATORY; + if (GNUNET_YES != + TALER_amount_cmp_currency (ph->amount, + ph->max_fee)) + { + return TALER_MERCHANT_OPOEC_INVALID_VALUE; + } + /* --- build wallet_data hash for signing coins & tokens --- */ if (ph->has_choice_index) { - /* wallet_data = { choice_index: …, tokens_evs: … } */ ph->wallet_data = GNUNET_JSON_PACK ( GNUNET_JSON_pack_int64("choice_index", ph->choice_index), GNUNET_JSON_pack_allow_null( GNUNET_JSON_pack_array_incref("tokens_evs", ph->tokens_evs)) ); - TALER_json_hash (ph->wallet_data, &ph->wallet_data_hash); + TALER_json_hash (ph->wallet_data, + &ph->wallet_data_hash); + + store_json_option (ph, + TALER_MERCHANT_OrderPayOptionType_WALLET_DATA, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_object_incref ("wallet_data", + ph->wallet_data))); } /* --- sign coins AND build the “coins” JSON in one pass --------------- */ @@ -828,6 +802,8 @@ TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph) ph->post_ctx.headers, &handle_finished, ph); + + ph->am_wallet = true; return TALER_MERCHANT_OPOEC_OK; } } diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c @@ -1226,7 +1226,6 @@ pay_run (void *cls, &h_proposal)) TALER_TESTING_FAIL (is); ps->h_contract_terms = *h_proposal; - //TODO: Most probably that's the thing we would like to replace with our own implementation of the pay_function // ps->oph = TALER_MERCHANT_order_pay ( // TALER_TESTING_interpreter_get_context (is), // ps->merchant_url, @@ -1250,6 +1249,12 @@ pay_run (void *cls, // output_tokens, // &pay_cb, // ps); +// +// GNUNET_array_grow (pay_coins, +// npay_coins, +// 0); +// if (NULL == ps->oph) +// TALER_TESTING_FAIL (is); // New logic of setting params { struct GNUNET_CURL_Context *ctx = @@ -1302,11 +1307,7 @@ pay_run (void *cls, TALER_MERCHANT_order_pay_start (ps->oph)) TALER_TESTING_FAIL (is); } -// GNUNET_array_grow (pay_coins, -// npay_coins, -// 0); -// if (NULL == ps->oph) -// TALER_TESTING_FAIL (is); + }