commit 2861254de6321015394591e0da1a61086134e86e
parent cf3495ccc44df0eb9cae3799333b744982588bb2
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date: Wed, 16 Jul 2025 12:13:15 +0200
adding some comments to taler_merchant_pay_service.c/.h
Diffstat:
2 files changed, 237 insertions(+), 97 deletions(-)
diff --git a/src/include/taler_merchant_pay_service.h b/src/include/taler_merchant_pay_service.h
@@ -67,7 +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
+ TALER_MERCHANT_OrderPayOptionType_WALLET_DATA, // Used privately so no #define is present for it
TALER_MERCHANT_OrderPayOptionType_DONAU_URL,
TALER_MERCHANT_OrderPayOptionType_DONAU_YEAR,
TALER_MERCHANT_OrderPayOptionType_DONAU_BUDIS,
@@ -95,21 +95,24 @@ struct TALER_MERCHANT_OrderPayOption
struct GNUNET_TIME_Timestamp pay_deadline;
struct TALER_MerchantWireHashP h_wire;
const char *order_id;
- struct {
+ struct
+ {
unsigned int num_coins;
const struct TALER_MERCHANT_PayCoin *coins;
} coins;
- struct {
+ struct
+ {
unsigned int num_tokens;
const struct TALER_MERCHANT_UseToken *tokens;
} input_tokens;
- struct {
+ struct
+ {
unsigned int num_output_tokens;
const struct TALER_MERCHANT_OutputToken *output_tokens;
} output_tokens;
#ifdef HAVE_DONAU_DONAU_SERVICE_H
const char *donau_url;
- uint64_t donau_year;
+ uint64_t donau_year;
json_t *donau_budis_json;
#endif
} details;
@@ -131,143 +134,174 @@ enum TALER_MERCHANT_OrderPayOptionErrorCode
#define TALER_MERCHANT_ORDER_PAY_OPTION_TERMINATE() \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_END \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_END \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_MERCHANT_URL(_url) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_MERCHANT_URL, \
- .details.merchant_url = (_url) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_MERCHANT_URL, \
+ .details.merchant_url = (_url) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_SESSION_ID(_sid) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_SESSION_ID,\
- .details.session_id = (_sid) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_SESSION_ID, \
+ .details.session_id = (_sid) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_H_CONTRACT(_h) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_H_CONTRACT, \
- .details.h_contract = (_h) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_H_CONTRACT, \
+ .details.h_contract = (_h) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_CHOICE_INDEX(_idx) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_CHOICE_INDEX,\
- .details.choice_index = (_idx) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_CHOICE_INDEX, \
+ .details.choice_index = (_idx) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_AMOUNT(_amt) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_AMOUNT,\
- .details.amount = *(_amt) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_AMOUNT, \
+ .details.amount = *(_amt) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_MAX_FEE(_fee) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_MAX_FEE,\
- .details.max_fee = *(_fee) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_MAX_FEE, \
+ .details.max_fee = *(_fee) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_MERCHANT_PUB(_mpub) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_MERCHANT_PUB, \
- .details.merchant_pub = *(_mpub) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_MERCHANT_PUB, \
+ .details.merchant_pub = *(_mpub) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_TIMESTAMP(_ts) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_TIMESTAMP, \
- .details.timestamp = (_ts) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_TIMESTAMP, \
+ .details.timestamp = (_ts) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_REFUND_DEADLINE(_ts) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_REFUND_DEADLINE, \
- .details.refund_deadline = (_ts) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_REFUND_DEADLINE, \
+ .details.refund_deadline = (_ts) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_PAY_DEADLINE(_ts) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_PAY_DEADLINE, \
- .details.pay_deadline = (_ts) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_PAY_DEADLINE, \
+ .details.pay_deadline = (_ts) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_H_WIRE(_hwire) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_H_WIRE, \
- .details.h_wire = *(_hwire) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_H_WIRE, \
+ .details.h_wire = *(_hwire) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_ORDER_ID(_oid) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_ORDER_ID,\
- .details.order_id = (_oid) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_ORDER_ID, \
+ .details.order_id = (_oid) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_COINS(_num,_coins) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_COINS, \
- .details.coins = { .num_coins = (_num), \
- .coins = (_coins) } \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_COINS, \
+ .details.coins = { .num_coins = (_num), \
+ .coins = (_coins) } \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_INPUT_TOKENS(_num,_tokens) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_INPUT_TOKENS, \
- .details.input_tokens = { .num_tokens = (_num), \
- .tokens = (_tokens) } \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_INPUT_TOKENS, \
+ .details.input_tokens = { .num_tokens = (_num), \
+ .tokens = (_tokens) } \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_OUTPUT_TOKENS(_num,_otokens) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_OUTPUT_TOKENS, \
- .details.output_tokens = { .num_output_tokens = (_num), \
- .output_tokens = (_otokens) } \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_OUTPUT_TOKENS, \
+ .details.output_tokens = { .num_output_tokens = (_num), \
+ .output_tokens = (_otokens) } \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_DONAU_URL(_u) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_DONAU_URL,\
- .details.donau_url = (_u) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_DONAU_URL, \
+ .details.donau_url = (_u) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_DONAU_YEAR(_y) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_DONAU_YEAR,\
- .details.donau_year = (_y) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_DONAU_YEAR, \
+ .details.donau_year = (_y) \
+ }
#define TALER_MERCHANT_ORDER_PAY_OPTION_DONAU_BUDIS(_js) \
(struct TALER_MERCHANT_OrderPayOption){ \
- .ot = TALER_MERCHANT_OrderPayOptionType_DONAU_BUDIS, \
- .details.donau_budis_json = (_js) \
- }
+ .ot = TALER_MERCHANT_OrderPayOptionType_DONAU_BUDIS, \
+ .details.donau_budis_json = (_js) \
+ }
#define TALER_MERCHANT_ORDER_PAY_SET_OPTIONS(ph,...) \
- MHD_NOWARN_COMPOUND_LITERALS_ \
- TALER_MERCHANT_order_pay_set_options ( \
- daemon, \
- ((const struct TALER_MERCHANT_OrderPayHandle[]) \
- {__VA_ARGS__, TALER_MERCHANT_ORDER_PAY_OPTION_TERMINATE ()}), \
- MHD_OPTIONS_ARRAY_MAX_SIZE) \
+ MHD_NOWARN_COMPOUND_LITERALS_ \
+ TALER_MERCHANT_order_pay_set_options ( \
+ daemon, \
+ ((const struct TALER_MERCHANT_OrderPayHandle[]) \
+ {__VA_ARGS__, TALER_MERCHANT_ORDER_PAY_OPTION_TERMINATE ()}), \
+ MHD_OPTIONS_ARRAY_MAX_SIZE) \
+/**
+ * @brief Create and initialize a new payment handle.
+ *
+ * @param ctx GNUNET CURL context used for HTTP operations
+ * @param pay_cb callback to invoke when the payment completes or fails
+ * @param pay_cb_cls closure data passed back to @a pay_cb
+ * @return pointer to a newly allocated handle, or NULL on error
+ */
struct TALER_MERCHANT_OrderPayHandle *
TALER_MERCHANT_order_pay_create (struct GNUNET_CURL_Context *ctx,
TALER_MERCHANT_OrderPayCallback pay_cb,
- TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE *pay_cb_cls);
+ TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE
+ *pay_cb_cls);
+/**
+ * @brief Configure payment options on a handle.
+ *
+ * @param ph payment handle to configure
+ * @param options NULL-terminated array of options (use
+ * TALER_MERCHANT_ORDER_PAY_OPTION_* macros)
+ * @param max_options maximum number of options in the @a options array
+ * @return #TALER_MERCHANT_OPOEC_OK on success;
+ * error code otherwise
+ */
enum TALER_MERCHANT_OrderPayOptionErrorCode
TALER_MERCHANT_order_pay_set_options (struct TALER_MERCHANT_OrderPayHandle *ph,
- const struct TALER_MERCHANT_OrderPayOption options[],
+ const struct TALER_MERCHANT_OrderPayOption
+ options[],
size_t max_options);
+/**
+ * @brief Start processing the payment request.
+ *
+ * @param ph fully configured payment handle
+ * @return #TALER_MERCHANT_OPOEC_OK on successful dispatch;
+ * error code on validation or dispatch failure
+ */
enum TALER_MERCHANT_OrderPayOptionErrorCode
TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph);
+/**
+ * @brief Cancel an in-flight or pending payment.
+ *
+ * @param ph payment handle to cancel and free
+ */
void
TALER_MERCHANT_order_pay_cancel1 (struct TALER_MERCHANT_OrderPayHandle *ph);
-
#endif /* TALER_MERCHANT_PAY_SERVICE_H */
\ No newline at end of file
diff --git a/src/lib/taler_merchant_pay_service.c b/src/lib/taler_merchant_pay_service.c
@@ -43,93 +43,200 @@
*/
struct TALER_MERCHANT_OrderPayHandle
{
+ /**
+ * Reference to the GNUNET CURL execution context.
+ */
struct GNUNET_CURL_Context *ctx;
/**
- * Function to call with the result in "pay" @e mode.
+ * Callback to invoke with the payment result ("pay" mode).
*/
TALER_MERCHANT_OrderPayCallback cb;
/**
- * Closure for @a pay_cb.
+ * Closure data for @a cb.
*/
TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE *cb_cls;
- /* mandatory scalars: */
+ /* Mandatory scalars: */
+
+ /**
+ * Base URL of the merchant service.
+ */
char *merchant_url;
+
+ /**
+ * Identifier of the order being paid.
+ */
char *order_id;
+
+ /**
+ * Session identifier for this payment attempt.
+ */
char *session_id;
+ /**
+ * Timestamp when the payment request was created.
+ */
struct GNUNET_TIME_Timestamp timestamp;
+
+ /**
+ * Deadline after which refunds are no longer allowed.
+ */
struct GNUNET_TIME_Timestamp refund_deadline;
+ /**
+ * Wire hash for communicating payment details.
+ */
struct TALER_MerchantWireHashP h_wire;
+
+ /**
+ * Indicates whether @a h_wire has been set.
+ */
bool has_h_wire;
- /* for wallet mode: */
+ /* Wallet mode fields: */
+
+ /**
+ * Indicates whether a contract hash was provided.
+ */
bool has_h_contract;
+
+ /**
+ * Hash of the private contract terms (wallet mode only).
+ */
struct TALER_PrivateContractHashP h_contract_terms;
+ /**
+ * Indicates whether the merchant public key was provided.
+ */
bool has_merchant_pub;
+
+ /**
+ * Merchant’s public key for verifying signatures (wallet mode).
+ */
struct TALER_MerchantPublicKeyP merchant_pub;
+ /**
+ * Indicates whether a choice index was provided.
+ */
bool has_choice_index;
+
+ /**
+ * Selected index of the contract choice (for token operations).
+ */
int choice_index;
- /*Used for strcmp in the legacy we just keep it for this time*/
+ /**
+ * Legacy: pointer to the amount structure for strcmp checks.
+ */
const struct TALER_Amount *amount;
+
+ /**
+ * Legacy: pointer to the maximum fee structure for strcmp checks.
+ */
const struct TALER_Amount *max_fee;
- /* raw arrays as passed in via set_options(): */
+ /* Raw arrays as passed in via set_options(): */
+
+ /**
+ * Coins used for payment.
+ */
struct
{
+ /**
+ * Number of coins provided.
+ */
unsigned int num_coins;
+ /**
+ * Array of coins to spend.
+ */
const struct TALER_MERCHANT_PayCoin *coins;
} coins;
+ /**
+ * Input tokens to use (wallet mode).
+ */
struct
{
+ /**
+ * Number of tokens provided.
+ */
unsigned int num_tokens;
+ /**
+ * Array of tokens to redeem.
+ */
const struct TALER_MERCHANT_UseToken *tokens;
} input_tokens;
+ /**
+ * Output tokens expected from the merchant.
+ */
struct
{
+ /**
+ * Number of output tokens expected.
+ */
unsigned int num_output_tokens;
+ /**
+ * Array of expected output tokens.
+ */
const struct TALER_MERCHANT_OutputToken *output_tokens;
} output_tokens;
+ /**
+ * JSON array of token envelope events (from Donau).
+ */
json_t *tokens_evs;
- /* computed once we see both choice_index and tokens_evs(outputs in the env): */
+ /* Computed once both choice_index and tokens_evs are available: */
+
+ /**
+ * JSON object containing wallet-specific data payload.
+ */
json_t *wallet_data;
+
+ /**
+ * Hash code of @a wallet_data for integrity checks.
+ */
struct GNUNET_HashCode wallet_data_hash;
- /* the JSON body we’ll keep appending into… */
+ /**
+ * JSON body being constructed for the HTTP POST.
+ */
json_t *body;
- /* final URL and CURL plumbing */
+ /* Final URL and CURL plumbing: */
+
+ /**
+ * Fully formed URL for the POST /order/$ID/pay request.
+ */
char *url;
+
+ /**
+ * CURL post context managing headers and body.
+ */
struct TALER_CURL_PostContext post_ctx;
+
+ /**
+ * Handle for the asynchronous CURL job.
+ */
struct GNUNET_CURL_Job *job;
+ /**
+ * Flags indicating which payment options have been set.
+ */
bool field_seen[TALER_MERCHANT_OrderPayOptionType_LENGTH];
+ /**
+ * True if operating in wallet mode (using tokens/contracts).
+ */
bool am_wallet;
+ /**
+ * Raw JSON data of `donau` for `wallet_data`.
+ */
json_t *donau_data;
- // TODO: Remove this block;
- /* --- Donau (optional) ------------------------------------------------- */
- #ifdef HAVE_DONAU_DONAU_SERVICE_H
- bool has_donau_url;
- char *donau_url;
-
- bool has_donau_year;
- uint64_t donau_year;
-
- bool has_donau_budis;
- json_t *donau_budikeypairs; /* array we’ll own */
- #endif
};
/**
@@ -467,9 +574,8 @@ TALER_MERCHANT_order_pay_cancel1 (struct TALER_MERCHANT_OrderPayHandle *ph)
json_decref (ph->tokens_evs);
ph->tokens_evs = NULL;
- GNUNET_free (ph->donau_url);
- if (ph->donau_budikeypairs)
- json_decref (ph->donau_budikeypairs);
+ if (ph->donau_data)
+ json_decref (ph->donau_data);
GNUNET_free (ph->url);
GNUNET_free (ph->merchant_url);