commit bb1e888f8b6a520dd66ac1f5b6eaf4417cad161b
parent e1cb7a087c986d8ce3d23dc2767e82fa5c72b11c
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 25 May 2026 00:07:06 +0200
fix most of backend build
Diffstat:
11 files changed, 264 insertions(+), 649 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_get-orders-ORDER_ID.c b/src/backend/taler-merchant-httpd_get-orders-ORDER_ID.c
@@ -166,7 +166,7 @@ struct GetOrderData
/**
* Common terms from @e order or @e contract
*/
- const struct TALER_MERCHANT_CommonTerms *ct;
+ const struct TALER_MERCHANT_ContractBaseTerms *ct;
/**
* Total refunds granted for this payment. Only initialized
@@ -792,7 +792,7 @@ phase_parse_contract (struct GetOrderData *god)
return;
}
god->contract_parsed = true;
- god->ct = &god->contract_terms->common;
+ god->ct = god->contract_terms->pc->base;
}
if (NULL != god->order_json)
{
@@ -807,7 +807,7 @@ phase_parse_contract (struct GetOrderData *god)
return;
}
god->order_parsed = true;
- god->ct = &god->order->common;
+ god->ct = god->order->base;
}
GNUNET_assert ( (NULL != god->order) ||
(NULL != god->contract_terms) );
@@ -1375,8 +1375,8 @@ phase_check_refunded (struct GetOrderData *god)
switch (god->ct->version)
{
case TALER_MERCHANT_CONTRACT_VERSION_0:
- refund_amount = god->contract_terms->details.v0.brutto;
- refund_currency = god->contract_terms->details.v0.brutto.currency;
+ refund_amount = god->contract_terms->pc->details.v0.brutto;
+ refund_currency = god->contract_terms->pc->details.v0.brutto.currency;
break;
case TALER_MERCHANT_CONTRACT_VERSION_1:
if (god->choice_index < 0)
@@ -1386,11 +1386,12 @@ phase_check_refunded (struct GetOrderData *god)
return false;
}
GNUNET_assert (god->choice_index <
- god->contract_terms->details.v1.choices_len);
- refund_currency = god->contract_terms->details.v1.choices[god->choice_index]
- .amount.currency;
- GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (refund_currency,
- &refund_amount));
+ god->contract_terms->pc->details.v1.choices_len);
+ refund_currency = god->contract_terms->pc->details.v1.choices[
+ god->choice_index].amount.currency;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (refund_currency,
+ &refund_amount));
break;
default:
{
@@ -1570,7 +1571,7 @@ phase_return_status (struct GetOrderData *god)
GNUNET_assert (NULL != god->contract_terms_json);
GNUNET_assert (NULL != god->contract_terms);
- uri = make_taler_refund_uri (god->ct->merchant_base_url,
+ uri = make_taler_refund_uri (god->contract_terms->pc->merchant_base_url,
god->order_id);
if (NULL == uri)
{
diff --git a/src/backend/taler-merchant-httpd_get-private-orders-ORDER_ID.c b/src/backend/taler-merchant-httpd_get-private-orders-ORDER_ID.c
@@ -276,7 +276,12 @@ struct GetOrderRequestContext
/**
* Common terms of @e order and @e contract.
*/
- const struct TALER_MERCHANT_CommonTerms *ct;
+ const struct TALER_MERCHANT_ContractBaseTerms *ct;
+
+ /**
+ * Timestamp of the contract or order.
+ */
+ struct GNUNET_TIME_Timestamp timestamp;
/**
* Claim token of the order.
@@ -790,7 +795,8 @@ phase_parse_contract (struct GetOrderRequestContext *gorc)
hc->infix));
return;
}
- gorc->ct = &gorc->order->common;
+ gorc->ct = gorc->order->base;
+ gorc->timestamp = gorc->order->timestamp;
}
if ( (NULL == gorc->contract_terms) &&
(NULL != gorc->contract_terms_json) )
@@ -809,7 +815,8 @@ phase_parse_contract (struct GetOrderRequestContext *gorc)
hc->infix));
return;
}
- gorc->ct = &gorc->contract_terms->common;
+ gorc->ct = gorc->contract_terms->pc->base;
+ gorc->timestamp = gorc->contract_terms->pc->timestamp;
}
switch (gorc->ct->version)
@@ -817,14 +824,16 @@ phase_parse_contract (struct GetOrderRequestContext *gorc)
case TALER_MERCHANT_CONTRACT_VERSION_0:
gorc->contract_amount
= (NULL != gorc->contract_terms)
- ? gorc->contract_terms->details.v0.brutto
+ ? gorc->contract_terms->pc->details.v0.brutto
: gorc->order->details.v0.brutto;
break;
case TALER_MERCHANT_CONTRACT_VERSION_1:
if (gorc->choice_index >= 0)
{
if (gorc->choice_index >=
- gorc->contract_terms->details.v1.choices_len)
+ (NULL != gorc->contract_terms)
+ ? gorc->contract_terms->pc->details.v1.choices_len
+ : gorc->order->details.v1.choices_len)
{
GNUNET_break (0);
phase_end (gorc,
@@ -837,16 +846,15 @@ phase_parse_contract (struct GetOrderRequestContext *gorc)
}
gorc->contract_amount =
(NULL != gorc->contract_terms)
- ? gorc->contract_terms->details.v1.choices[gorc->choice_index].amount
+ ? gorc->contract_terms->pc->details.v1.choices[gorc->choice_index].amount
: gorc->order->details.v1.choices[gorc->choice_index].amount;
}
else
{
GNUNET_break (gorc->order_only);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Choice index %i for order %s is invalid or not yet available",
- gorc->choice_index,
- gorc->ct->order_id);
+ "Choice index %i is invalid",
+ gorc->choice_index);
}
break;
default:
@@ -1130,9 +1138,11 @@ phase_check_repurchase (struct GetOrderRequestContext *gorc)
GNUNET_JSON_pack_string ("summary",
gorc->ct->summary),
GNUNET_JSON_pack_timestamp ("pay_deadline",
- gorc->ct->pay_deadline),
+ NULL != gorc->contract_terms
+ ? gorc->contract_terms->pc->pay_deadline
+ : gorc->order->pay_deadline),
GNUNET_JSON_pack_timestamp ("creation_time",
- gorc->ct->timestamp));
+ gorc->timestamp));
GNUNET_free (order_status_url);
GNUNET_free (taler_pay_uri);
@@ -1226,7 +1236,7 @@ phase_unpaid_finish (struct GetOrderRequestContext *gorc)
GNUNET_JSON_pack_string ("summary",
gorc->ct->summary),
GNUNET_JSON_pack_timestamp ("creation_time",
- gorc->ct->timestamp));
+ gorc->timestamp));
check_reply (gorc,
reply);
json_decref (reply);
@@ -1640,7 +1650,7 @@ phase_check_local_transfers (struct GetOrderRequestContext *gorc)
TMH_notify_order_change (hc->instance,
TMH_OSF_PAID
| TMH_OSF_WIRED,
- gorc->ct->timestamp,
+ gorc->timestamp,
gorc->order_serial);
}
}
@@ -1686,7 +1696,7 @@ phase_reply_result (struct GetOrderRequestContext *gorc)
{
GNUNET_break (GNUNET_YES ==
TALER_amount_is_zero (&gorc->contract_amount));
- gorc->last_payment = gorc->ct->timestamp;
+ gorc->last_payment = gorc->timestamp;
}
{
json_t *reply;
diff --git a/src/backend/taler-merchant-httpd_get-private-orders.c b/src/backend/taler-merchant-httpd_get-private-orders.c
@@ -479,7 +479,7 @@ add_order (void *cls,
char amount_buf[128];
char refund_buf[128];
char pending_buf[128];
- const struct TALER_MERCHANT_CommonTerms *ct = NULL;
+ const struct TALER_MERCHANT_ContractBaseTerms *ct = NULL;
/* Bail early if we already have an error */
if (TALER_EC_NONE != po->result)
@@ -541,7 +541,7 @@ add_order (void *cls,
po->result = TALER_EC_MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID;
goto cleanup;
}
- ct = &contract->common;
+ ct = contract->pc->base;
}
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -566,7 +566,7 @@ add_order (void *cls,
po->result = TALER_EC_MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID;
goto cleanup;
}
- ct = &order->common;
+ ct = order->base;
}
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -592,14 +592,14 @@ add_order (void *cls,
switch (ct->version)
{
case TALER_MERCHANT_CONTRACT_VERSION_0:
- brutto = &contract->details.v0.brutto;
+ brutto = &contract->pc->details.v0.brutto;
break;
case TALER_MERCHANT_CONTRACT_VERSION_1:
{
struct TALER_MERCHANT_ContractChoice *choice
- = &contract->details.v1.choices[choice_index];
+ = &contract->pc->details.v1.choices[choice_index];
- GNUNET_assert (choice_index < contract->details.v1.choices_len);
+ GNUNET_assert (choice_index < contract->pc->details.v1.choices_len);
brutto = &choice->amount;
}
break;
@@ -634,7 +634,7 @@ add_order (void *cls,
if (0 > TALER_amount_cmp (&prc.total_refund_amount,
brutto) &&
GNUNET_TIME_absolute_is_future (
- contract->common.refund_deadline.abs_time))
+ contract->pc->refund_deadline.abs_time))
refundable = true;
}
@@ -645,7 +645,7 @@ add_order (void *cls,
case TALER_MERCHANT_CONTRACT_VERSION_0:
{
amount = (NULL != contract)
- ? &contract->details.v0.brutto
+ ? &contract->pc->details.v0.brutto
: &order->details.v0.brutto;
if (TALER_amount_is_zero (amount) &&
@@ -681,9 +681,9 @@ add_order (void *cls,
if (NULL != contract)
{
struct TALER_MERCHANT_ContractChoice *choice
- = &contract->details.v1.choices[choice_index];
+ = &contract->pc->details.v1.choices[choice_index];
- GNUNET_assert (choice_index < contract->details.v1.choices_len);
+ GNUNET_assert (choice_index < contract->pc->details.v1.choices_len);
amount = &choice->amount;
/* Accumulate order total */
accumulate_total (po,
diff --git a/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c
@@ -1059,7 +1059,7 @@ batch_deposit_transaction (
dr->details.ok.deposit_timestamp,
&pc->check_contract.h_contract_terms,
eg->exchange_url,
- pc->check_contract.contract_terms->common.wire_deadline,
+ pc->check_contract.contract_terms->pc->wire_deadline,
&dr->details.ok.accumulated_total_without_fee,
&eg->wire_fee,
&pc->check_contract.wm->h_wire,
@@ -1096,7 +1096,7 @@ batch_deposit_transaction (
&dc->deposit_fee,
&dc->refund_fee,
GNUNET_TIME_absolute_add (
- pc->check_contract.contract_terms->common.wire_deadline.abs_time,
+ pc->check_contract.contract_terms->pc->wire_deadline.abs_time,
GNUNET_TIME_randomize (GNUNET_TIME_UNIT_MINUTES)));
if (qs < 0)
return qs;
@@ -1220,8 +1220,8 @@ notify_kyc_required (const struct ExchangeGroup *eg)
char *extra;
hws = GNUNET_STRINGS_data_to_string_alloc (
- &eg->pc->check_contract.contract_terms->common.h_wire,
- sizeof (eg->pc->check_contract.contract_terms->common.h_wire));
+ &eg->pc->check_contract.contract_terms->pc->h_wire,
+ sizeof (eg->pc->check_contract.contract_terms->pc->h_wire));
GNUNET_asprintf (&extra,
"%s %s",
hws,
@@ -1414,7 +1414,7 @@ do_batch_deposits (struct ExchangeGroup *eg)
{
struct TALER_EXCHANGE_DepositContractDetail dcd = {
.wire_deadline
- = pc->check_contract.contract_terms->common.wire_deadline,
+ = pc->check_contract.contract_terms->pc->wire_deadline,
.merchant_payto_uri
= pc->check_contract.wm->payto_uri,
.extra_wire_subject_metadata
@@ -1426,11 +1426,11 @@ do_batch_deposits (struct ExchangeGroup *eg)
.wallet_data_hash
= pc->parse_wallet_data.h_wallet_data,
.wallet_timestamp
- = pc->check_contract.contract_terms->common.timestamp,
+ = pc->check_contract.contract_terms->pc->timestamp,
.merchant_pub
= hc->instance->merchant_pub,
.refund_deadline
- = pc->check_contract.contract_terms->common.refund_deadline
+ = pc->check_contract.contract_terms->pc->refund_deadline
};
/* Collect up to TALER_MAX_COINS eligible coins for this batch */
struct TALER_EXCHANGE_CoinDepositDetail cdds[group_size];
@@ -1682,7 +1682,7 @@ process_pay_with_keys (
is_age_restricted_denom = (0 != denom_details->key.age_mask.bits);
if (is_age_restricted_denom &&
- (0 < pc->check_contract.contract_terms->common.minimum_age))
+ (0 < pc->check_contract.contract_terms->pc->base->minimum_age))
{
/* Minimum age given and restricted coin provided: We need to verify the
* minimum age */
@@ -1706,7 +1706,7 @@ process_pay_with_keys (
if (GNUNET_OK !=
TALER_age_commitment_verify (
&dc->age_commitment,
- pc->check_contract.contract_terms->common.minimum_age,
+ pc->check_contract.contract_terms->pc->base->minimum_age,
&dc->minimum_age_sig))
code = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_VERIFICATION_FAILED;
AGE_FAIL:
@@ -1941,7 +1941,7 @@ phase_success_response (struct PayContext *pc)
pc->check_contract.pos_key,
pc->check_contract.pos_alg,
&pc->validate_tokens.brutto,
- pc->check_contract.contract_terms->common.timestamp);
+ pc->check_contract.contract_terms->pc->timestamp);
pay_end (pc,
TALER_MHD_REPLY_JSON_PACK (
pc->connection,
@@ -2004,7 +2004,7 @@ phase_payment_notification (struct PayContext *pc)
0);
}
if ( (NULL != pc->parse_pay.session_id) &&
- (NULL != pc->check_contract.contract_terms->common.fulfillment_url) )
+ (NULL != pc->check_contract.contract_terms->pc->base->fulfillment_url) )
{
struct TMH_SessionEventP session_eh = {
.header.size = htons (sizeof (session_eh)),
@@ -2015,13 +2015,13 @@ phase_payment_notification (struct PayContext *pc)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Notifying clients about session change to %s for %s\n",
pc->parse_pay.session_id,
- pc->check_contract.contract_terms->common.fulfillment_url);
+ pc->check_contract.contract_terms->pc->base->fulfillment_url);
GNUNET_CRYPTO_hash (pc->parse_pay.session_id,
strlen (pc->parse_pay.session_id),
&session_eh.h_session_id);
GNUNET_CRYPTO_hash (
- pc->check_contract.contract_terms->common.fulfillment_url,
- strlen (pc->check_contract.contract_terms->common.fulfillment_url),
+ pc->check_contract.contract_terms->pc->base->fulfillment_url,
+ strlen (pc->check_contract.contract_terms->pc->base->fulfillment_url),
&session_eh.h_fulfillment_url);
TALER_MERCHANTDB_event_notify (TMH_db,
&session_eh.header,
@@ -2404,10 +2404,10 @@ phase_compute_money_pots (struct PayContext *pc)
TALER_amount_set_zero (pc->parse_pay.dc[0].cdd.amount.currency,
&assigned));
GNUNET_assert (NULL != contract);
- for (size_t i = 0; i<contract->common.products_len; i++)
+ for (size_t i = 0; i<contract->pc->products_len; i++)
{
const struct TALER_MERCHANT_ProductSold *product
- = &contract->common.products[i];
+ = &contract->pc->products[i];
const struct TALER_Amount *price = NULL;
/* find price in the right currency */
@@ -2468,14 +2468,14 @@ phase_compute_money_pots (struct PayContext *pc)
}
if ( (! TALER_amount_is_zero (&left)) &&
- (0 != contract->common.default_money_pot) )
+ (0 != contract->pc->base->default_money_pot) )
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Computing money pot %llu increment as %s\n",
- (unsigned long long) contract->common.default_money_pot,
+ (unsigned long long) contract->pc->base->default_money_pot,
TALER_amount2s (&left));
increment_pot (pc,
- contract->common.default_money_pot,
+ contract->pc->base->default_money_pot,
&left);
}
}
@@ -3132,7 +3132,7 @@ phase_execute_pay_transaction (struct PayContext *pc)
{
const struct TALER_MERCHANT_ContractChoice *choice =
- &pc->check_contract.contract_terms->details.v1
+ &pc->check_contract.contract_terms->pc->details.v1
.choices[pc->parse_wallet_data.choice_index];
for (size_t i = 0; i<pc->output_tokens_len; i++)
@@ -3203,7 +3203,7 @@ phase_execute_pay_transaction (struct PayContext *pc)
TMH_notify_order_change (
hc->instance,
TMH_OSF_CLAIMED | TMH_OSF_PAID,
- pc->check_contract.contract_terms->common.timestamp,
+ pc->check_contract.contract_terms->pc->timestamp,
pc->check_contract.order_serial);
{
enum GNUNET_DB_QueryStatus qs;
@@ -3540,11 +3540,11 @@ find_family (const struct PayContext *pc,
const char *slug)
{
for (unsigned int i = 0;
- i < pc->check_contract.contract_terms->details.v1.token_authorities_len;
+ i < pc->check_contract.contract_terms->pc->details.v1.token_authorities_len;
i++)
{
const struct TALER_MERCHANT_ContractTokenFamily *tfi
- = &pc->check_contract.contract_terms->details.v1.token_authorities[i];
+ = &pc->check_contract.contract_terms->pc->details.v1.token_authorities[i];
if (0 == strcmp (tfi->slug,
slug))
@@ -3622,8 +3622,8 @@ handle_output_token (struct PayContext *pc,
TMH_db,
pc->hc->instance->settings.id,
family->slug,
- pc->check_contract.contract_terms->common.timestamp,
- pc->check_contract.contract_terms->common.pay_deadline,
+ pc->check_contract.contract_terms->pc->timestamp,
+ pc->check_contract.contract_terms->pc->pay_deadline,
&details);
switch (qs)
{
@@ -3646,9 +3646,9 @@ handle_output_token (struct PayContext *pc,
"Token-family key for %s not found at [%llu,%llu]\n",
family->slug,
(unsigned long long)
- pc->check_contract.contract_terms->common.timestamp.abs_time.abs_value_us,
+ pc->check_contract.contract_terms->pc->timestamp.abs_time.abs_value_us,
(unsigned long long)
- pc->check_contract.contract_terms->common.pay_deadline.abs_time.abs_value_us
+ pc->check_contract.contract_terms->pc->pay_deadline.abs_time.abs_value_us
);
GNUNET_break (0);
pay_end (pc,
@@ -3846,20 +3846,20 @@ phase_validate_tokens (struct PayContext *pc)
/* We haven't seen a donau output yet. */
pc->validate_tokens.donau_output_index = -1;
- switch (pc->check_contract.contract_terms->common.version)
+ switch (pc->check_contract.contract_terms->pc->base->version)
{
case TALER_MERCHANT_CONTRACT_VERSION_0:
/* No tokens to validate */
pc->phase = PP_COMPUTE_MONEY_POTS;
pc->validate_tokens.max_fee
- = pc->check_contract.contract_terms->details.v0.max_fee;
+ = pc->check_contract.contract_terms->pc->details.v0.max_fee;
pc->validate_tokens.brutto
- = pc->check_contract.contract_terms->details.v0.brutto;
+ = pc->check_contract.contract_terms->pc->details.v0.brutto;
break;
case TALER_MERCHANT_CONTRACT_VERSION_1:
{
const struct TALER_MERCHANT_ContractChoice *selected
- = &pc->check_contract.contract_terms->details.v1.choices[
+ = &pc->check_contract.contract_terms->pc->details.v1.choices[
pc->parse_wallet_data.choice_index];
unsigned int output_off;
unsigned int cnt;
@@ -4184,8 +4184,8 @@ append_output_token_sig (void *cls,
0,
sizeof (out));
GNUNET_assert (TALER_MERCHANT_CONTRACT_VERSION_1 ==
- pc->check_contract.contract_terms->common.version);
- choice = &pc->check_contract.contract_terms->details.v1
+ pc->check_contract.contract_terms->pc->base->version);
+ choice = &pc->check_contract.contract_terms->pc->details.v1
.choices[pc->parse_wallet_data.choice_index];
output = &choice->outputs[pc->output_index_gen];
cnt = count_output_tokens (pc,
@@ -4472,7 +4472,7 @@ phase_check_contract (struct PayContext *pc)
/* Check fundamentals */
{
- switch (pc->check_contract.contract_terms->common.version)
+ switch (pc->check_contract.contract_terms->pc->base->version)
{
case TALER_MERCHANT_CONTRACT_VERSION_0:
{
@@ -4507,14 +4507,15 @@ phase_check_contract (struct PayContext *pc)
return;
}
if (pc->parse_wallet_data.choice_index >=
- pc->check_contract.contract_terms->details.v1.choices_len)
+ pc->check_contract.contract_terms->pc->details.v1.choices_len)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Order `%s' has choices array with %u elements but "
- "request has 'choice_index' field with value %d\n",
- pc->order_id,
- pc->check_contract.contract_terms->details.v1.choices_len,
- pc->parse_wallet_data.choice_index);
+ GNUNET_log (
+ GNUNET_ERROR_TYPE_INFO,
+ "Order `%s' has choices array with %u elements but "
+ "request has 'choice_index' field with value %d\n",
+ pc->order_id,
+ pc->check_contract.contract_terms->pc->details.v1.choices_len,
+ pc->parse_wallet_data.choice_index);
GNUNET_break (0);
pay_end (pc,
TALER_MHD_reply_with_error (
@@ -4540,9 +4541,9 @@ phase_check_contract (struct PayContext *pc)
}
if (GNUNET_TIME_timestamp_cmp (
- pc->check_contract.contract_terms->common.wire_deadline,
+ pc->check_contract.contract_terms->pc->wire_deadline,
<,
- pc->check_contract.contract_terms->common.refund_deadline))
+ pc->check_contract.contract_terms->pc->refund_deadline))
{
/* This should already have been checked when creating the order! */
GNUNET_break (0);
@@ -4555,7 +4556,7 @@ phase_check_contract (struct PayContext *pc)
return;
}
if (GNUNET_TIME_absolute_is_past (
- pc->check_contract.contract_terms->common.pay_deadline.abs_time))
+ pc->check_contract.contract_terms->pc->pay_deadline.abs_time))
{
/* too late */
pay_end (pc,
@@ -4574,7 +4575,7 @@ phase_check_contract (struct PayContext *pc)
wm = pc->hc->instance->wm_head;
while (0 !=
GNUNET_memcmp (
- &pc->check_contract.contract_terms->common.h_wire,
+ &pc->check_contract.contract_terms->pc->h_wire,
&wm->h_wire))
wm = wm->next;
if (NULL == wm)
diff --git a/src/backend/taler-merchant-httpd_post-private-orders.c b/src/backend/taler-merchant-httpd_post-private-orders.c
@@ -318,169 +318,20 @@ struct OrderContext
{
/**
- * Our order ID.
+ * The main order data as provided by the client.
*/
- char *order_id;
+ struct TALER_MERCHANT_Order *order;
/**
- * Summary of the contract.
- */
- const char *summary;
-
- /**
- * Internationalized summary.
- */
- const json_t *summary_i18n;
-
- /**
- * URL that will show that the contract was successful
- * after it has been paid for.
- */
- const char *fulfillment_url;
-
- /**
- * Message shown to the customer after paying for the contract.
- * Either fulfillment_url or fulfillment_message must be specified.
- */
- const char *fulfillment_message;
-
- /**
- * Map from IETF BCP 47 language tags to localized fulfillment messages.
- */
- const json_t *fulfillment_message_i18n;
-
- /**
- * Length of the @e products array.
- */
- size_t products_len;
-
- /**
- * Array of products that are being sold.
- */
- struct TALER_MERCHANT_ProductSold *products;
-
- /**
- * URL where the same contract could be ordered again (if available).
- */
- const char *public_reorder_url;
-
- /**
- * Merchant base URL.
+ * Base URL of this merchant.
*/
char *merchant_base_url;
/**
- * Timestamp of the order.
- */
- struct GNUNET_TIME_Timestamp timestamp;
-
- /**
- * Deadline for refunds.
- */
- struct GNUNET_TIME_Timestamp refund_deadline;
-
- /**
- * Payment deadline.
- */
- struct GNUNET_TIME_Timestamp pay_deadline;
-
- /**
- * Wire transfer deadline.
- */
- struct GNUNET_TIME_Timestamp wire_deadline;
-
- /**
* Wire transfer round-up interval to apply.
*/
enum GNUNET_TIME_RounderInterval wire_deadline_rounder;
- /**
- * Delivery date.
- */
- struct GNUNET_TIME_Timestamp delivery_date;
-
- /**
- * Delivery location.
- */
- const json_t *delivery_location;
-
- /**
- * Specifies for how long the wallet should try to get an
- * automatic refund for the purchase.
- */
- struct GNUNET_TIME_Relative auto_refund;
-
- /**
- * Nonce generated by the wallet and echoed by the merchant
- * in this field when the proposal is generated.
- */
- const char *nonce;
-
- /**
- * Extra data that is only interpreted by the merchant frontend.
- */
- const json_t *extra;
-
- /**
- * Minimum age required by the order.
- */
- uint32_t minimum_age;
-
- /**
- * Money pot to increment for whatever order payment amount
- * is not yet assigned to a pot via the Product.
- */
- uint64_t order_default_money_pot;
-
- /**
- * Version of the contract terms.
- */
- enum TALER_MERCHANT_ContractVersion version;
-
- /**
- * Details present depending on @e version.
- */
- union
- {
- /**
- * Details only present for v0.
- */
- struct
- {
- /**
- * Gross amount value of the contract. Used to
- * compute @e max_stefan_fee.
- */
- struct TALER_Amount brutto;
-
- /**
- * Tip included by the customer (part of the total amount).
- */
- struct TALER_Amount tip;
-
- /**
- * True if @e tip was not provided.
- */
- bool no_tip;
-
- /**
- * Maximum fee as given by the client request.
- */
- struct TALER_Amount max_fee;
- } v0;
-
- /**
- * Details only present for v1.
- */
- struct
- {
- /**
- * Array of contract choices. Is null for v0 contracts.
- */
- const json_t *choices;
- } v1;
- } details;
-
} parse_order;
/**
@@ -956,14 +807,20 @@ clean_order (void *cls)
json_decref (oc->set_exchanges.exchange_rejections);
oc->set_exchanges.exchange_rejections = NULL;
}
- switch (oc->parse_order.version)
+ if (NULL != oc->parse_order.order)
{
- case TALER_MERCHANT_CONTRACT_VERSION_0:
- break;
- case TALER_MERCHANT_CONTRACT_VERSION_1:
- GNUNET_free (oc->set_max_fee.details.v1.max_fees);
- GNUNET_free (oc->set_exchanges.details.v1.max_stefan_fees);
- break;
+ switch (oc->parse_order.order->base->version)
+ {
+ case TALER_MERCHANT_CONTRACT_VERSION_0:
+ break;
+ case TALER_MERCHANT_CONTRACT_VERSION_1:
+ GNUNET_free (oc->set_max_fee.details.v1.max_fees);
+ GNUNET_free (oc->set_exchanges.details.v1.max_stefan_fees);
+ break;
+ }
+ TALER_MERCHANT_order_free (oc->parse_order.order);
+ oc->parse_order.order = NULL;
+ GNUNET_free (oc->parse_order.merchant_base_url);
}
if (NULL != oc->merge_inventory.products)
{
@@ -977,12 +834,6 @@ clean_order (void *cls)
GNUNET_array_grow (oc->parse_choices.choices,
oc->parse_choices.choices_len,
0);
- for (size_t i = 0; i<oc->parse_order.products_len; i++)
- {
- TALER_MERCHANT_product_sold_free (&oc->parse_order.products[i]);
- }
- GNUNET_free (oc->parse_order.products);
- oc->parse_order.products_len = 0;
for (unsigned int i = 0; i<oc->parse_choices.token_families_len; i++)
{
struct TALER_MERCHANT_ContractTokenFamily *mctf
@@ -1028,8 +879,6 @@ clean_order (void *cls)
GNUNET_free (oc->parse_request.pos_key);
json_decref (oc->parse_request.order);
json_decref (oc->serialize_order.contract);
- GNUNET_free (oc->parse_order.order_id);
- GNUNET_free (oc->parse_order.merchant_base_url);
GNUNET_free (oc);
}
@@ -1126,7 +975,7 @@ execute_transaction (struct OrderContext *oc)
qs = TALER_MERCHANTDB_lookup_order (TMH_db,
oc->hc->instance->settings.id,
- oc->parse_order.order_id,
+ oc->parse_order.order->order_id,
&oc->execute_order.token,
&orig_post,
&contract_terms);
@@ -1160,10 +1009,10 @@ execute_transaction (struct OrderContext *oc)
/* Setup order */
qs = TALER_MERCHANTDB_insert_order (TMH_db,
oc->hc->instance->settings.id,
- oc->parse_order.order_id,
+ oc->parse_order.order->order_id,
oc->parse_request.session_id,
&oc->parse_request.h_post_data,
- oc->parse_order.pay_deadline,
+ oc->parse_order.order->pay_deadline,
&oc->parse_request.claim_token,
oc->serialize_order.contract, /* called 'contract terms' at database. */
oc->parse_request.pos_key,
@@ -1196,7 +1045,7 @@ execute_transaction (struct OrderContext *oc)
qs = TALER_MERCHANTDB_insert_order_lock (
TMH_db,
oc->hc->instance->settings.id,
- oc->parse_order.order_id,
+ oc->parse_order.order->order_id,
oc->parse_request.inventory_products[i].product_id,
oc->parse_request.inventory_products[i].quantity,
oc->parse_request.inventory_products[i].quantity_frac);
@@ -1217,11 +1066,12 @@ execute_transaction (struct OrderContext *oc)
/* Get the order serial and timestamp for the order we just created to
update long-poll clients. */
- qs = TALER_MERCHANTDB_lookup_order_summary (TMH_db,
- oc->hc->instance->settings.id,
- oc->parse_order.order_id,
- ×tamp,
- &order_serial);
+ qs = TALER_MERCHANTDB_lookup_order_summary (
+ TMH_db,
+ oc->hc->instance->settings.id,
+ oc->parse_order.order->order_id,
+ ×tamp,
+ &order_serial);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
TALER_MERCHANTDB_rollback (TMH_db);
@@ -1233,7 +1083,7 @@ execute_transaction (struct OrderContext *oc)
jhook = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("order_id",
- oc->parse_order.order_id),
+ oc->parse_order.order->order_id),
GNUNET_JSON_pack_object_incref ("contract",
oc->serialize_order.contract),
GNUNET_JSON_pack_string ("instance_id",
@@ -1287,9 +1137,9 @@ yield_success_response (struct OrderContext *oc,
oc->connection,
MHD_HTTP_OK,
GNUNET_JSON_pack_string ("order_id",
- oc->parse_order.order_id),
+ oc->parse_order.order->order_id),
GNUNET_JSON_pack_timestamp ("pay_deadline",
- oc->parse_order.pay_deadline),
+ oc->parse_order.order->pay_deadline),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_data_auto (
"token",
@@ -1315,7 +1165,7 @@ phase_execute_order (struct OrderContext *oc)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Executing database transaction to create order '%s' for instance '%s'\n",
- oc->parse_order.order_id,
+ oc->parse_order.order->order_id,
settings->id);
for (unsigned int i = 0; i<MAX_RETRIES; i++)
{
@@ -1344,7 +1194,7 @@ phase_execute_order (struct OrderContext *oc)
oc,
MHD_HTTP_CONFLICT,
TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS,
- oc->parse_order.order_id);
+ oc->parse_order.order->order_id);
return;
}
/* Other hard transaction error (disk full, etc.) */
@@ -1372,7 +1222,7 @@ phase_execute_order (struct OrderContext *oc)
oc,
MHD_HTTP_CONFLICT,
TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS,
- oc->parse_order.order_id);
+ oc->parse_order.order->order_id);
return;
}
@@ -1797,7 +1647,7 @@ add_input_token_family (struct OrderContext *oc,
const char *slug)
{
struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get ();
- struct GNUNET_TIME_Timestamp end = oc->parse_order.pay_deadline;
+ struct GNUNET_TIME_Timestamp end = oc->parse_order.order->pay_deadline;
enum GNUNET_DB_QueryStatus qs;
enum TALER_ErrorCode ec = TALER_EC_INVALID; /* make compiler happy */
unsigned int http_status = 0; /* make compiler happy */
@@ -1945,12 +1795,13 @@ add_output_token_family (struct OrderContext *oc,
valid_at,
key_index)) )
return GNUNET_OK;
- qs = TALER_MERCHANTDB_lookup_token_family_key (TMH_db,
- oc->hc->instance->settings.id,
- slug,
- valid_at,
- oc->parse_order.pay_deadline,
- &key_details);
+ qs = TALER_MERCHANTDB_lookup_token_family_key (
+ TMH_db,
+ oc->hc->instance->settings.id,
+ slug,
+ valid_at,
+ oc->parse_order.order->pay_deadline,
+ &key_details);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -2289,66 +2140,39 @@ phase_serialize_order (struct OrderContext *oc)
}
oc->serialize_order.contract = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_int64 ("version",
- oc->parse_order.version),
- GNUNET_JSON_pack_string ("summary",
- oc->parse_order.summary),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_object_incref (
- "summary_i18n",
- (json_t *) oc->parse_order.summary_i18n)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("public_reorder_url",
- oc->parse_order.public_reorder_url)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("fulfillment_message",
- oc->parse_order.fulfillment_message)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_object_incref (
- "fulfillment_message_i18n",
- (json_t *) oc->parse_order.fulfillment_message_i18n)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("fulfillment_url",
- oc->parse_order.fulfillment_url)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_uint64 ("minimum_age",
- oc->parse_order.minimum_age)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_uint64 ("default_money_pot",
- oc->parse_order.order_default_money_pot)),
- GNUNET_JSON_pack_array_incref ("products",
- oc->merge_inventory.products),
- GNUNET_JSON_pack_data_auto ("h_wire",
- &oc->select_wire_method.wm->h_wire),
- GNUNET_JSON_pack_string ("wire_method",
- oc->select_wire_method.wm->wire_method),
- GNUNET_JSON_pack_string ("order_id",
- oc->parse_order.order_id),
- GNUNET_JSON_pack_timestamp ("timestamp",
- oc->parse_order.timestamp),
- GNUNET_JSON_pack_timestamp ("pay_deadline",
- oc->parse_order.pay_deadline),
- GNUNET_JSON_pack_timestamp ("wire_transfer_deadline",
- oc->parse_order.wire_deadline),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_timestamp ("delivery_date",
- oc->parse_order.delivery_date)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_object_incref (
- "delivery_location",
- (json_t *) oc->parse_order.delivery_location)),
- GNUNET_JSON_pack_string ("merchant_base_url",
- oc->parse_order.merchant_base_url),
- GNUNET_JSON_pack_object_steal ("merchant",
- merchant),
- GNUNET_JSON_pack_data_auto ("merchant_pub",
- &oc->hc->instance->merchant_pub),
- GNUNET_JSON_pack_array_incref ("exchanges",
- oc->select_wire_method.exchanges),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_object_incref ("extra",
- (json_t *) oc->parse_order.extra))
- );
+ GNUNET_JSON_pack_object_steal (
+ NULL,
+ TALER_MERCHANT_base_terms_serialize (oc->parse_order.order->base)),
+ GNUNET_JSON_pack_array_incref (
+ "products",
+ oc->merge_inventory.products),
+ GNUNET_JSON_pack_data_auto (
+ "h_wire",
+ &oc->select_wire_method.wm->h_wire),
+ GNUNET_JSON_pack_string (
+ "wire_method",
+ oc->select_wire_method.wm->wire_method),
+ GNUNET_JSON_pack_timestamp (
+ "timestamp",
+ oc->parse_order.order->timestamp),
+ GNUNET_JSON_pack_timestamp (
+ "pay_deadline",
+ oc->parse_order.order->pay_deadline),
+ GNUNET_JSON_pack_timestamp (
+ "wire_transfer_deadline",
+ oc->parse_order.order->wire_transfer_deadline),
+ GNUNET_JSON_pack_string (
+ "merchant_base_url",
+ oc->parse_order.merchant_base_url),
+ GNUNET_JSON_pack_object_steal (
+ "merchant",
+ merchant),
+ GNUNET_JSON_pack_data_auto (
+ "merchant_pub",
+ &oc->hc->instance->merchant_pub),
+ GNUNET_JSON_pack_array_incref (
+ "exchanges",
+ oc->select_wire_method.exchanges));
{
json_t *xtra;
@@ -3240,7 +3064,8 @@ phase_add_payment_details (struct OrderContext *oc)
{
oc->add_payment_details.need_exchange = true;
}
- for (unsigned int j = 0; j<oc->add_payment_details.num_max_choice_limits;
+ for (unsigned int j = 0;
+ j<oc->add_payment_details.num_max_choice_limits;
j++)
{
struct TALER_Amount *mx = &oc->add_payment_details.max_choice_limits[j];
@@ -3942,246 +3767,40 @@ phase_parse_order (struct OrderContext *oc)
{
const struct TALER_MERCHANTDB_InstanceSettings *settings =
&oc->hc->instance->settings;
- const char *merchant_base_url = NULL;
- uint64_t version = 0;
- const json_t *jmerchant = NULL;
- const json_t *products = NULL;
- const char *order_id = NULL;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_uint64 ("version",
- &version),
- NULL),
- GNUNET_JSON_spec_string ("summary",
- &oc->parse_order.summary),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_array_const ("products",
- &products),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_object_const ("summary_i18n",
- &oc->parse_order.summary_i18n),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_slug ("order_id",
- &order_id),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("fulfillment_message",
- &oc->parse_order.fulfillment_message),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_object_const ("fulfillment_message_i18n",
- &oc->parse_order.fulfillment_message_i18n),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("fulfillment_url",
- &oc->parse_order.fulfillment_url),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("public_reorder_url",
- &oc->parse_order.public_reorder_url),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_web_url ("merchant_base_url",
- &merchant_base_url),
- NULL),
- /* For sanity check, this field must NOT be present */
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_object_const ("merchant",
- &jmerchant),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_timestamp ("timestamp",
- &oc->parse_order.timestamp),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_timestamp ("refund_deadline",
- &oc->parse_order.refund_deadline),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_timestamp ("pay_deadline",
- &oc->parse_order.pay_deadline),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_timestamp ("wire_transfer_deadline",
- &oc->parse_order.wire_deadline),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_object_const ("delivery_location",
- &oc->parse_order.delivery_location),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_timestamp ("delivery_date",
- &oc->parse_order.delivery_date),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_uint32 ("minimum_age",
- &oc->parse_order.minimum_age),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_relative_time ("auto_refund",
- &oc->parse_order.auto_refund),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_object_const ("extra",
- &oc->parse_order.extra),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_uint64 ("order_default_money_pot",
- &oc->parse_order.order_default_money_pot),
- NULL),
- GNUNET_JSON_spec_end ()
- };
enum GNUNET_GenericReturnValue ret;
bool computed_refund_deadline = false;
- oc->parse_order.refund_deadline = GNUNET_TIME_UNIT_FOREVER_TS;
- oc->parse_order.wire_deadline = GNUNET_TIME_UNIT_FOREVER_TS;
- ret = TALER_MHD_parse_json_data (oc->connection,
- oc->parse_request.order,
- spec);
- if (GNUNET_OK != ret)
+ oc->parse_order.order
+ = TALER_MERCHANT_order_parse (
+ oc->parse_request.order);
+ if (NULL == oc->parse_order.order)
{
GNUNET_break_op (0);
- finalize_order2 (oc,
- ret);
+ reply_with_error (oc,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "order");
return;
}
- if ( (NULL != products) &&
- (0 != (oc->parse_order.products_len = json_array_size (products))) )
- {
- size_t i;
- json_t *p;
- oc->parse_order.products
- = GNUNET_new_array (oc->parse_order.products_len,
- struct TALER_MERCHANT_ProductSold);
- json_array_foreach (products, i, p)
- {
- if (GNUNET_OK !=
- TALER_MERCHANT_parse_product_sold (p,
- &oc->parse_order.products[i]))
- {
- GNUNET_break_op (0);
- reply_with_error (oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "order.products");
- return;
- }
- }
- }
- switch (version)
+ switch (oc->parse_order.order->base->version)
{
- case 0:
- {
- bool no_fee;
- const json_t *choices = NULL;
- struct GNUNET_JSON_Specification specv0[] = {
- TALER_JSON_spec_amount_any (
- "amount",
- &oc->parse_order.details.v0.brutto),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_amount_any (
- "tip",
- &oc->parse_order.details.v0.tip),
- &oc->parse_order.details.v0.no_tip),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_amount_any (
- "max_fee",
- &oc->parse_order.details.v0.max_fee),
- &no_fee),
- /* for sanity check, must be *absent*! */
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_array_const ("choices",
- &choices),
- NULL),
- GNUNET_JSON_spec_end ()
- };
-
- ret = TALER_MHD_parse_json_data (oc->connection,
- oc->parse_request.order,
- specv0);
- if (GNUNET_OK != ret)
- {
- GNUNET_break_op (0);
- finalize_order2 (oc,
- ret);
- return;
- }
- if ( (! no_fee) &&
- (GNUNET_OK !=
- TALER_amount_cmp_currency (&oc->parse_order.details.v0.brutto,
- &oc->parse_order.details.v0.max_fee)) )
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- reply_with_error (oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_CURRENCY_MISMATCH,
- "different currencies used for 'max_fee' and 'amount' currency");
- return;
- }
- if ( (! oc->parse_order.details.v0.no_tip) &&
- (GNUNET_OK !=
- TALER_amount_cmp_currency (&oc->parse_order.details.v0.brutto,
- &oc->parse_order.details.v0.tip)) )
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- reply_with_error (oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_CURRENCY_MISMATCH,
- "tip and amount");
- return;
- }
- if (! TMH_test_exchange_configured_for_currency (
- oc->parse_order.details.v0.brutto.currency))
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- reply_with_error (oc,
- MHD_HTTP_CONFLICT,
- TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_NO_EXCHANGE_FOR_CURRENCY,
- oc->parse_order.details.v0.brutto.currency);
- return;
- }
- if (NULL != choices)
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- reply_with_error (oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_UNEXPECTED_REQUEST_ERROR,
- "choices array must be null for v0 contracts");
- return;
- }
- oc->parse_order.version = TALER_MERCHANT_CONTRACT_VERSION_0;
- break;
- }
- case 1:
+ case TALER_MERCHANT_CONTRACT_VERSION_0:
+ if (! TMH_test_exchange_configured_for_currency (
+ oc->parse_order.order->details.v0.brutto.currency))
{
- struct GNUNET_JSON_Specification specv1[] = {
- GNUNET_JSON_spec_array_const (
- "choices",
- &oc->parse_order.details.v1.choices),
- GNUNET_JSON_spec_end ()
- };
-
- ret = TALER_MHD_parse_json_data (oc->connection,
- oc->parse_request.order,
- specv1);
- if (GNUNET_OK != ret)
- {
- GNUNET_break_op (0);
- finalize_order2 (oc,
- ret);
- return;
- }
- oc->parse_order.version = TALER_MERCHANT_CONTRACT_VERSION_1;
- break;
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ reply_with_error (
+ oc,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_NO_EXCHANGE_FOR_CURRENCY,
+ oc->parse_order.order->details.v0.brutto.currency);
+ return;
}
+ break;
+ case TALER_MERCHANT_CONTRACT_VERSION_1:
+ break;
default:
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
@@ -4193,11 +3812,7 @@ phase_parse_order (struct OrderContext *oc)
}
/* Add order_id if it doesn't exist. */
- if (NULL != order_id)
- {
- oc->parse_order.order_id = GNUNET_strdup (order_id);
- }
- else
+ if (NULL == oc->parse_order.order->order_id)
{
char buf[256];
time_t timer;
@@ -4237,17 +3852,15 @@ phase_parse_order (struct OrderContext *oc)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Assigning order ID `%s' server-side\n",
buf);
-
- oc->parse_order.order_id = GNUNET_strdup (buf);
- GNUNET_assert (NULL != oc->parse_order.order_id);
+ oc->parse_order.order->order_id = GNUNET_strdup (buf);
}
/* Patch fulfillment URL with order_id (implements #6467). */
- if (NULL != oc->parse_order.fulfillment_url)
+ if (NULL != oc->parse_order.order->base->fulfillment_url)
{
const char *pos;
- pos = strstr (oc->parse_order.fulfillment_url,
+ pos = strstr (oc->parse_order.odrer->base->fulfillment_url,
"${ORDER_ID}");
if (NULL != pos)
{
@@ -4266,32 +3879,35 @@ phase_parse_order (struct OrderContext *oc)
return;
}
- GNUNET_asprintf (&nurl,
- "%.*s%s%s",
- /* first output URL until ${ORDER_ID} */
- (int) (pos - oc->parse_order.fulfillment_url),
- oc->parse_order.fulfillment_url,
- /* replace ${ORDER_ID} with the right order_id */
- oc->parse_order.order_id,
- /* append rest of original URL */
- pos + strlen ("${ORDER_ID}"));
-
- oc->parse_order.fulfillment_url = GNUNET_strdup (nurl);
-
+ GNUNET_asprintf (
+ &nurl,
+ "%.*s%s%s",
+ /* first output URL until ${ORDER_ID} */
+ (int) (pos - oc->parse_order.order->base->fulfillment_url),
+ oc->parse_order.order->base->fulfillment_url,
+ /* replace ${ORDER_ID} with the right order_id */
+ oc->parse_order.order->order_id,
+ /* append rest of original URL */
+ pos + strlen ("${ORDER_ID}"));
+ oc->parse_order.order->base->fulfillment_url = GNUNET_strdup (nurl);
GNUNET_free (nurl);
}
}
- if ( (GNUNET_TIME_absolute_is_zero (oc->parse_order.pay_deadline.abs_time)) ||
- (GNUNET_TIME_absolute_is_never (oc->parse_order.pay_deadline.abs_time)) )
+ if ( (GNUNET_TIME_absolute_is_zero (
+ oc->parse_order.order->pay_deadline.abs_time)) ||
+ (GNUNET_TIME_absolute_is_never (
+ oc->parse_order.order->pay_deadline.abs_time)) )
{
oc->parse_order.pay_deadline = GNUNET_TIME_relative_to_timestamp (
settings->default_pay_delay);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Pay deadline was zero (or never), setting to %s\n",
- GNUNET_TIME_timestamp2s (oc->parse_order.pay_deadline));
+ GNUNET_TIME_timestamp2s (
+ oc->parse_order.order->pay_deadline));
}
- else if (GNUNET_TIME_absolute_is_past (oc->parse_order.pay_deadline.abs_time))
+ else if (GNUNET_TIME_absolute_is_past (
+ oc->parse_order.order->pay_deadline.abs_time))
{
GNUNET_break_op (0);
reply_with_error (
@@ -4303,7 +3919,8 @@ phase_parse_order (struct OrderContext *oc)
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Pay deadline is %s\n",
- GNUNET_TIME_timestamp2s (oc->parse_order.pay_deadline));
+ GNUNET_TIME_timestamp2s (
+ oc->parse_order.order->pay_deadline));
/* Check soundness of refund deadline, and that a timestamp
* is actually present. */
@@ -4311,35 +3928,38 @@ phase_parse_order (struct OrderContext *oc)
struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get ();
/* Add timestamp if it doesn't exist (or is zero) */
- if (GNUNET_TIME_absolute_is_zero (oc->parse_order.timestamp.abs_time))
+ if (GNUNET_TIME_absolute_is_zero (
+ oc->parse_order.order->timestamp.abs_time))
{
- oc->parse_order.timestamp = now;
+ oc->parse_order.order->timestamp = now;
}
/* If no refund_deadline given, set one based on refund_delay. */
if (GNUNET_TIME_absolute_is_never (
- oc->parse_order.refund_deadline.abs_time))
+ oc->parse_order.order->refund_deadline.abs_time))
{
- if (GNUNET_TIME_relative_is_zero (oc->parse_request.refund_delay))
+ if (GNUNET_TIME_relative_is_zero (
+ oc->parse_request.refund_delay))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Refund delay is zero, no refunds are possible for this order\n");
- oc->parse_order.refund_deadline = GNUNET_TIME_UNIT_ZERO_TS;
+ oc->parse_order.order->refund_deadline = GNUNET_TIME_UNIT_ZERO_TS;
}
else
{
computed_refund_deadline = true;
- oc->parse_order.refund_deadline
+ oc->parse_order.order->refund_deadline
= GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (oc->parse_order.pay_deadline.abs_time,
- oc->parse_request.refund_delay));
+ GNUNET_TIME_absolute_add (
+ oc->parse_order.order->pay_deadline.abs_time,
+ oc->parse_request.refund_delay));
}
}
if ( (! GNUNET_TIME_absolute_is_zero (
- oc->parse_order.delivery_date.abs_time)) &&
+ oc->parse_order.order->base->delivery_date.abs_time)) &&
(GNUNET_TIME_absolute_is_past (
- oc->parse_order.delivery_date.abs_time)) )
+ oc->parse_order.order->base->delivery_date.abs_time)) )
{
GNUNET_break_op (0);
reply_with_error (
@@ -4352,9 +3972,9 @@ phase_parse_order (struct OrderContext *oc)
}
if ( (! GNUNET_TIME_absolute_is_zero (
- oc->parse_order.refund_deadline.abs_time)) &&
+ oc->parse_order.order->refund_deadline.abs_time)) &&
(GNUNET_TIME_absolute_is_past (
- oc->parse_order.refund_deadline.abs_time)) )
+ oc->parse_order.order->refund_deadline.abs_time)) )
{
GNUNET_break_op (0);
reply_with_error (
@@ -4365,14 +3985,15 @@ phase_parse_order (struct OrderContext *oc)
return;
}
- if (GNUNET_TIME_absolute_is_never (oc->parse_order.wire_deadline.abs_time))
+ if (GNUNET_TIME_absolute_is_never (
+ oc->parse_order.order->wire_deadline.abs_time))
{
struct GNUNET_TIME_Absolute start;
start = GNUNET_TIME_absolute_max (
- oc->parse_order.refund_deadline.abs_time,
- oc->parse_order.pay_deadline.abs_time);
- oc->parse_order.wire_deadline
+ oc->parse_order.order->refund_deadline.abs_time,
+ oc->parse_order.order->pay_deadline.abs_time);
+ oc->parse_order.order->wire_deadline
= GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_round_up (
GNUNET_TIME_absolute_add (
@@ -4380,7 +4001,7 @@ phase_parse_order (struct OrderContext *oc)
settings->default_wire_transfer_delay),
settings->default_wire_transfer_rounding_interval));
if (GNUNET_TIME_absolute_is_never (
- oc->parse_order.wire_deadline.abs_time))
+ oc->parse_order.order->wire_deadline.abs_time))
{
GNUNET_break_op (0);
reply_with_error (
@@ -4396,13 +4017,13 @@ phase_parse_order (struct OrderContext *oc)
/* if we computed the refund_deadline from default settings
and did have a configured wire_deadline, make sure that
the refund_deadline is at or below the wire_deadline. */
- oc->parse_order.refund_deadline
- = GNUNET_TIME_timestamp_min (oc->parse_order.refund_deadline,
- oc->parse_order.wire_deadline);
+ oc->parse_order.order->refund_deadline
+ = GNUNET_TIME_timestamp_min (oc->parse_order.order->refund_deadline,
+ oc->parse_order.order->wire_deadline);
}
- if (GNUNET_TIME_timestamp_cmp (oc->parse_order.wire_deadline,
+ if (GNUNET_TIME_timestamp_cmp (oc->parse_order.order->wire_deadline,
<,
- oc->parse_order.refund_deadline))
+ oc->parse_order.order->refund_deadline))
{
GNUNET_break_op (0);
reply_with_error (
@@ -4413,23 +4034,6 @@ phase_parse_order (struct OrderContext *oc)
return;
}
- if (NULL != merchant_base_url)
- {
- if (('\0' == *merchant_base_url) ||
- ('/' != merchant_base_url[strlen (merchant_base_url) - 1]))
- {
- GNUNET_break_op (0);
- reply_with_error (
- oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR,
- "merchant_base_url is not valid");
- return;
- }
- oc->parse_order.merchant_base_url
- = GNUNET_strdup (merchant_base_url);
- }
- else
{
char *url;
@@ -4448,20 +4052,9 @@ phase_parse_order (struct OrderContext *oc)
oc->parse_order.merchant_base_url = url;
}
- /* Merchant information must not already be present */
- if (NULL != jmerchant)
- {
- GNUNET_break_op (0);
- reply_with_error (
- oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR,
- "'merchant' field already set, but must be provided by backend");
- return;
- }
-
- if ( (NULL != oc->parse_order.delivery_location) &&
- (! TMH_location_object_valid (oc->parse_order.delivery_location)) )
+ // FIXME: move to util during parsing!
+ if ( (NULL != oc->parse_order.order->base->delivery_location) &&
+ (! TMH_location_object_valid (oc->parse_order.order->base->delivery_location)) )
{
GNUNET_break_op (0);
reply_with_error (oc,
diff --git a/src/include/taler/taler_merchant_util.h b/src/include/taler/taler_merchant_util.h
@@ -1364,11 +1364,6 @@ struct TALER_MERCHANT_ContractBaseTerms
json_t *summary_i18n;
/**
- * Our order ID.
- */
- char *order_id;
-
- /**
* URL where the same contract could be ordered again (if available).
* Optional.
*/
@@ -1455,6 +1450,11 @@ struct TALER_MERCHANT_Order
struct TALER_MERCHANT_ContractBaseTerms *base;
/**
+ * Our order ID. Optional.
+ */
+ char *order_id;
+
+ /**
* Array of products that are part of the purchase.
*/
struct TALER_MERCHANT_ProductSold *products;
@@ -1567,6 +1567,11 @@ struct TALER_MERCHANT_ProtoContract
struct TALER_MERCHANT_ContractBaseTerms *base;
/**
+ * Our order ID.
+ */
+ char *order_id;
+
+ /**
* Timestamp of the contract.
*/
struct GNUNET_TIME_Timestamp timestamp;
diff --git a/src/util/base_terms_parse.c b/src/util/base_terms_parse.c
@@ -46,8 +46,6 @@ TALER_MERCHANT_base_terms_parse (
GNUNET_JSON_spec_object_copy ("summary_i18n",
&ct->summary_i18n),
NULL),
- GNUNET_JSON_spec_string_copy ("order_id",
- &ct->order_id),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string_copy ("public_reorder_url",
&ct->public_reorder_url),
@@ -135,7 +133,6 @@ TALER_MERCHANT_base_terms_free (
if (NULL == ct)
return;
GNUNET_free (ct->public_reorder_url);
- GNUNET_free (ct->order_id);
GNUNET_free (ct->summary);
GNUNET_free (ct->fulfillment_url);
GNUNET_free (ct->fulfillment_message);
diff --git a/src/util/base_terms_serialize.c b/src/util/base_terms_serialize.c
@@ -46,8 +46,6 @@ TALER_MERCHANT_base_terms_serialize (
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_object_steal ("summary_i18n",
ct->summary_i18n)),
- GNUNET_JSON_pack_string ("order_id",
- ct->order_id),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("public_reorder_url",
ct->public_reorder_url)),
diff --git a/src/util/contract_parse.c b/src/util/contract_parse.c
@@ -158,6 +158,8 @@ TALER_MERCHANT_proto_contract_parse (
{
const json_t *products = NULL;
struct GNUNET_JSON_Specification espec[] = {
+ GNUNET_JSON_spec_string_copy ("order_id",
+ &pc->order_id),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_array_const ("products",
&products),
@@ -296,6 +298,7 @@ TALER_MERCHANT_proto_contract_free (
json_decref (pc->exchanges);
pc->exchanges = NULL;
}
+ GNUNET_free (pc->order_id);
GNUNET_free (pc);
}
diff --git a/src/util/contract_serialize.c b/src/util/contract_serialize.c
@@ -135,6 +135,8 @@ success:
return GNUNET_JSON_PACK (
GNUNET_JSON_pack_object_steal (NULL,
bj),
+ GNUNET_JSON_pack_string ("order_id",
+ pc->order_id),
GNUNET_JSON_pack_timestamp ("timestamp",
pc->timestamp),
GNUNET_JSON_pack_timestamp ("refund_deadline",
diff --git a/src/util/order_parse.c b/src/util/order_parse.c
@@ -164,6 +164,10 @@ TALER_MERCHANT_order_parse (json_t *input)
&products),
NULL),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string_copy ("order_id",
+ &order->order_id),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_timestamp ("timestamp",
&order->timestamp),
NULL),
@@ -276,6 +280,7 @@ TALER_MERCHANT_order_free (
GNUNET_free (order->products);
order->products_len = 0;
}
+ GNUNET_free (order->order_id);
if (NULL != order->base)
{
TALER_MERCHANT_base_terms_free (order->base);