[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant] 07/31: add choices array to v0 contract logic
From: |
gnunet |
Subject: |
[taler-merchant] 07/31: add choices array to v0 contract logic |
Date: |
Thu, 18 Apr 2024 08:39:00 +0200 |
This is an automated email from the git hooks/post-receive script.
christian-blaettler pushed a commit to branch master
in repository merchant.
commit 1ae1dcbbbba24b3135659dd8b38b9dc1c392f515
Author: Christian Blättler <blatc2@bfh.ch>
AuthorDate: Thu Mar 7 17:02:59 2024 +0100
add choices array to v0 contract logic
---
src/backend/taler-merchant-httpd_contract.h | 2 +-
.../taler-merchant-httpd_private-post-orders.c | 367 ++++++++++++++++-----
2 files changed, 278 insertions(+), 91 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_contract.h
b/src/backend/taler-merchant-httpd_contract.h
index db1b9315..190a5328 100644
--- a/src/backend/taler-merchant-httpd_contract.h
+++ b/src/backend/taler-merchant-httpd_contract.h
@@ -237,7 +237,7 @@ struct TALER_MerchantContractChoice
/**
* Array of products that are part of the purchase.
*/
- json_t *products;
+ const json_t *products;
/**
* List of inputs the wallet must provision (all of them) to satisfy the
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c
b/src/backend/taler-merchant-httpd_private-post-orders.c
index f1bea926..45402a1b 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -225,7 +225,142 @@ struct OrderContext
/**
* Information set in the ORDER_PHASE_PARSE_ORDER phase.
*/
- struct TALER_MerchantContract parse_order;
+ struct
+ {
+ /**
+ * Our order ID.
+ */
+ const char *order_id;
+
+ /**
+ * Array of possible specific contracts the wallet/customer may choose
+ * from by selecting the respective index when signing the deposit
+ * confirmation.
+ */
+ struct TALER_MerchantContractChoice *choices;
+
+ /**
+ * Length of the @e choices array.
+ */
+ unsigned int choices_len;
+
+ /**
+ * Summary of the order.
+ */
+ // const char *summary;
+
+ /**
+ * Internationalized summary.
+ */
+ // json_t *summary_i18n;
+
+ /**
+ * URL where the same contract could be ordered again (if available).
+ */
+ const char *public_reorder_url;
+
+ /**
+ * URL that will show that the order was successful
+ * after it has been paid for.
+ */
+ // const char *fulfillment_url;
+
+ /**
+ * Message shown to the customer after paying for the order.
+ * Either fulfillment_url or fulfillment_message must be specified.
+ */
+ // const char *fulfillment_message;
+
+ /**
+ * Map from IETF BCP 47 language tags to localized fulfillment messages.
+ */
+ // json_t *fulfillment_message_i18n;
+
+ /**
+ * Merchant base URL.
+ */
+ 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;
+
+ /**
+ * Delivery date.
+ */
+ struct GNUNET_TIME_Timestamp delivery_date;
+
+ /**
+ * Delivery location.
+ */
+ json_t *delivery_location;
+
+ /**
+ * Array of products that are part of the purchase.
+ */
+ // const json_t *products;
+
+ /**
+ * TODO: Maybe remove this and set it from settings where we serialize
+ * the order to JSON?
+ *
+ * Information like name, website, email, etc. about the merchant.
+ */
+ json_t *merchant;
+
+ /**
+ * TODO: Maybe remove this and set it from settings where we serialize
+ * the order to JSON?
+ *
+ * Merchant's public key
+ */
+ struct TALER_MerchantPublicKeyP merchant_pub;
+
+ /**
+ * Gross amount value of the contract. Used to
+ * compute @e max_stefan_fee.
+ */
+ struct TALER_Amount brutto;
+
+ /**
+ * Maximum fee as given by the client request.
+ */
+ struct TALER_Amount max_fee;
+
+ /**
+ * 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;
+
+ } parse_order;
/**
* Information set in the ORDER_PHASE_MERGE_INVENTORY phase.
@@ -547,7 +682,7 @@ execute_transaction (struct OrderContext *oc)
&oc->parse_request.h_post_data,
oc->parse_order.pay_deadline,
&oc->parse_request.claim_token,
- oc->serialize_order.contract, /* called
'contract terms' in database. */
+ oc->serialize_order.contract, /* called
'contract terms' at database. */
oc->parse_request.pos_key,
oc->parse_request.pos_algorithm);
if (qs <= 0)
@@ -1139,19 +1274,90 @@ get_exchange_keys (void *cls,
static void
serialize_order (struct OrderContext *oc)
{
- const struct TALER_MERCHANTDB_InstanceSettings *settings =
- &oc->hc->instance->settings;
- enum GNUNET_GenericReturnValue ret;
-
- ret = TMH_serialize_contract(
- oc->parse_order,
- oc->hc->instance,
- oc->add_payment_details.wm,
- oc->set_exchanges.exchanges,
- oc->merge_inventory.products,
- oc->set_max_fee.max_fee,
- oc->serialize_order.contract
- );
+ struct TALER_MerchantContractChoice *choice = oc->parse_order.choices;
+
+ GNUNET_assert (1 == oc->parse_order.choices_len && NULL != choice);
+
+ oc->serialize_order.contract = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("summary",
+ choice->summary),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_object_incref ("summary_i18n",
+ choice->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",
+ choice->fulfillment_message)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_object_incref ("fulfillment_message_i18n",
+ choice->fulfillment_message_i18n)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("fulfillment_url",
+ choice->fulfillment_url)),
+ GNUNET_JSON_pack_array_incref ("products",
+ oc->merge_inventory.products),
+ GNUNET_JSON_pack_data_auto ("h_wire",
+ &oc->add_payment_details.wm->h_wire),
+ GNUNET_JSON_pack_string ("wire_method",
+ oc->add_payment_details.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",
+ oc->parse_order.delivery_location)),
+ GNUNET_JSON_pack_string ("merchant_base_url",
+ oc->parse_order.merchant_base_url),
+ GNUNET_JSON_pack_object_incref ("merchant",
+ oc->parse_order.merchant),
+ GNUNET_JSON_pack_data_auto ("merchant_pub",
+ &oc->hc->instance->merchant_pub),
+ GNUNET_JSON_pack_array_incref ("exchanges",
+ oc->set_exchanges.exchanges),
+ TALER_JSON_pack_amount ("max_fee",
+ &oc->set_max_fee.max_fee),
+ TALER_JSON_pack_amount ("amount",
+ &oc->parse_order.brutto),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_object_incref ("extra",
+ (json_t *) oc->parse_order.extra))
+ );
+
+ /* Pack does not work here, because it doesn't set zero-values for
timestamps */
+ GNUNET_assert (0 ==
+ json_object_set_new (oc->serialize_order.contract,
+ "refund_deadline",
+ GNUNET_JSON_from_timestamp (
+ oc->parse_order.refund_deadline)));
+ GNUNET_log (
+ GNUNET_ERROR_TYPE_INFO,
+ "Refund deadline for contact is %llu\n",
+ (unsigned long long)
oc->parse_order.refund_deadline.abs_time.abs_value_us);
+ GNUNET_log (
+ GNUNET_ERROR_TYPE_INFO,
+ "Wallet timestamp for contact is %llu\n",
+ (unsigned long long) oc->parse_order.timestamp.abs_time.abs_value_us);
+
+ /* Pack does not work here, because it sets zero-values for relative times */
+ /* auto_refund should only be set if it is not 0 */
+ if (! GNUNET_TIME_relative_is_zero (oc->parse_order.auto_refund))
+ {
+ GNUNET_assert (0 ==
+ json_object_set_new (oc->serialize_order.contract,
+ "auto_refund",
+ GNUNET_JSON_from_time_rel (
+ oc->parse_order.auto_refund)));
+ }
oc->phase++;
}
@@ -1252,6 +1458,7 @@ set_exchanges (struct OrderContext *oc)
return false;
}
+
/**
* Add missing fields to the order. Upon success, continue
* processing with merge_inventory().
@@ -1260,57 +1467,6 @@ set_exchanges (struct OrderContext *oc)
*/
static void
parse_order (struct OrderContext *oc)
-{
- const char *version = NULL;
-
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("version",
- &version),
- NULL),
- GNUNET_JSON_spec_end ()
- };
- enum GNUNET_GenericReturnValue ret;
-
- ret = TALER_MHD_parse_json_data (oc->connection,
- oc->parse_request.order,
- spec);
-
- if (GNUNET_OK != ret)
- {
- GNUNET_break_op (0);
- finalize_order2 (oc,
- ret);
- return;
- }
-
- if (0 == strcmp("v0", version))
- {
- oc->parse_order.version = TALER_MCV_V0;
- }
- else if (0 != strcmp("v1", version))
- {
- oc->parse_order.version = TALER_MCV_V1;
- }
- else
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- reply_with_error (oc,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_VERSION_MALFORMED,
- "invalid version specified in order, supported are 'v0'
or 'v1'");
- return;
- }
-}
-
-/**
- * Parse order fields if order.version is null or 0.
- *
- * @param[in,out] oc order context
- */
-static void
-parse_order_v0 (struct OrderContext *oc)
{
struct TALER_MerchantContractChoice *choice;
struct TALER_MerchantContractLimits *limits;
@@ -1384,7 +1540,7 @@ parse_order_v0 (struct OrderContext *oc)
NULL),
GNUNET_JSON_spec_mark_optional (
TALER_JSON_spec_amount_any ("max_fee",
- &limits->max_fee),
+ &oc->parse_order.max_fee),
&no_fee),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("delivery_location",
@@ -1432,7 +1588,7 @@ parse_order_v0 (struct OrderContext *oc)
if ( (! no_fee) &&
(GNUNET_OK !=
TALER_amount_cmp_currency (&oc->parse_order.brutto,
- &limits->max_fee)) )
+ &oc->parse_order.max_fee)) )
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
@@ -1443,11 +1599,6 @@ parse_order_v0 (struct OrderContext *oc)
return;
}
- GNUNET_snprintf (limits->currency,
- sizeof (limits->currency),
- "%s",
- oc->parse_order.brutto.currency);
-
/* Add order_id if it doesn't exist. */
if (NULL == oc->parse_order.order_id)
{
@@ -1700,6 +1851,53 @@ parse_order_v0 (struct OrderContext *oc)
return;
}
+ {
+ oc->parse_order.merchant = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("name",
+ settings->name),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("website",
+ settings->website)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("email",
+ settings->email)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("logo",
+ settings->logo)));
+ GNUNET_assert (NULL != oc->parse_order.merchant);
+ {
+ json_t *loca;
+
+ /* Handle merchant address */
+ loca = settings->address;
+ if (NULL != loca)
+ {
+ loca = json_deep_copy (loca);
+ GNUNET_assert (NULL != loca);
+ GNUNET_assert (0 ==
+ json_object_set_new (oc->parse_order.merchant,
+ "address",
+ loca));
+ }
+ }
+ {
+ json_t *juri;
+
+ /* Handle merchant jurisdiction */
+ juri = settings->jurisdiction;
+ if (NULL != juri)
+ {
+ juri = json_deep_copy (juri);
+ GNUNET_assert (NULL != juri);
+ GNUNET_assert (0 ==
+ json_object_set_new (oc->parse_order.merchant,
+ "jurisdiction",
+ juri));
+ }
+ }
+ }
+
+ oc->parse_order.merchant_pub = oc->hc->instance->merchant_pub;
if ( (NULL != oc->parse_order.delivery_location) &&
(! TMH_location_object_valid (oc->parse_order.delivery_location)) )
{
@@ -1711,24 +1909,9 @@ parse_order_v0 (struct OrderContext *oc)
return;
}
- oc->parse_order.choices = choice;
- oc->parse_order.choices_len = 1;
- oc->parse_order.limits = limits;
- oc->parse_order.limits_len = 1;
-
oc->phase++;
}
-/**
- * Parse order fields if order.version is 1.
- *
- * @param[in,out] oc order context
- */
-static void
-parse_order_v1 (struct OrderContext *oc)
-{
-
-}
/**
* Process the @a payment_target and add the details of how the
@@ -1776,13 +1959,17 @@ add_payment_details (struct OrderContext *oc)
static void
merge_inventory (struct OrderContext *oc)
{
+ struct TALER_MerchantContractChoice *choice = oc->parse_order.choices;
+
+ GNUNET_assert (1 == oc->parse_order.choices_len && NULL != choice);
+
/**
* parse_request.inventory_products => instructions to add products to
contract terms
* parse_order.products => contains products that are not from the
backend-managed inventory.
*/
- if (NULL != oc->parse_order.products)
+ if (NULL != choice->products)
oc->merge_inventory.products
- = json_deep_copy (oc->parse_order.products);
+ = json_deep_copy (choice->products);
else
oc->merge_inventory.products
= json_array ();
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-merchant] 05/31: add serialization switch based on version field, (continued)
- [taler-merchant] 05/31: add serialization switch based on version field, gnunet, 2024/04/18
- [taler-merchant] 01/31: rought first draft of v1 contract terms data structures, gnunet, 2024/04/18
- [taler-merchant] 02/31: separate structs implement discussed changes, gnunet, 2024/04/18
- [taler-merchant] 03/31: serialize v0 contract, gnunet, 2024/04/18
- [taler-merchant] 04/31: use v1 contract structure for v0 internally, gnunet, 2024/04/18
- [taler-merchant] 13/31: add merchant struct to contract datastructure, gnunet, 2024/04/18
- [taler-merchant] 15/31: serialize v1 contract ready for db, gnunet, 2024/04/18
- [taler-merchant] 11/31: implement parsing of choices array for v1 contracts, gnunet, 2024/04/18
- [taler-merchant] 20/31: add db functions to select & insert token family keys, gnunet, 2024/04/18
- [taler-merchant] 17/31: Merge branch 'master' into tokens, gnunet, 2024/04/18
- [taler-merchant] 07/31: add choices array to v0 contract logic,
gnunet <=
- [taler-merchant] 27/31: add post tokenfamilies cmd, gnunet, 2024/04/18
- [taler-merchant] 19/31: implement memory management review feedback, gnunet, 2024/04/18
- [taler-merchant] 08/31: parse v0 max_fee into limits struct, gnunet, 2024/04/18
- [taler-merchant] 23/31: Merge branch 'master' into tokens, gnunet, 2024/04/18
- [taler-merchant] 10/31: remove unused merchant_pub field (set directly in serialize order phase), gnunet, 2024/04/18
- [taler-merchant] 16/31: simplify contract structs, gnunet, 2024/04/18
- [taler-merchant] 12/31: first shot at v1 contract serialization, gnunet, 2024/04/18
- [taler-merchant] 18/31: first smoke tests, gnunet, 2024/04/18
- [taler-merchant] 29/31: update build system, gnunet, 2024/04/18
- [taler-merchant] 09/31: build merchant information in serialization phase, gnunet, 2024/04/18