gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]