gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: implementing long-polling for re


From: gnunet
Subject: [taler-merchant] branch master updated: implementing long-polling for refunds (#5985)
Date: Fri, 10 Apr 2020 23:21:13 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 6d978ef  implementing long-polling for refunds (#5985)
6d978ef is described below

commit 6d978efe14aa90564ce9257a23bcb2854ba07036
Author: Christian Grothoff <address@hidden>
AuthorDate: Fri Apr 10 23:21:11 2020 +0200

    implementing long-polling for refunds (#5985)
---
 src/backend/taler-merchant-httpd.c                 | 77 ++++++++++++++++-
 src/backend/taler-merchant-httpd.h                 | 29 ++++++-
 src/backend/taler-merchant-httpd_check-payment.c   |  3 +-
 src/backend/taler-merchant-httpd_pay.c             | 65 +--------------
 src/backend/taler-merchant-httpd_poll-payment.c    | 86 +++++++++++++++++--
 src/backend/taler-merchant-httpd_refund_increase.c |  5 ++
 src/include/taler_merchant_service.h               |  4 +
 src/include/taler_merchant_testing_lib.h           | 96 ++++++++++------------
 src/lib/merchant_api_poll_payment.c                |  7 ++
 src/lib/test_merchant_api.c                        |  2 +
 src/lib/testing_api_cmd_poll_payment.c             | 22 +++++
 11 files changed, 270 insertions(+), 126 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index f577c47..1f9d439 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -300,15 +300,23 @@ do_resume (void *cls)
  * Suspend connection from @a sc until payment has been received.
  *
  * @param sc connection to suspend
+ * @param min_refund refund amount we are waiting on to be exceeded before 
resuming,
+ *                   NULL if we are not waiting for refunds
  */
 void
-TMH_long_poll_suspend (struct TMH_SuspendedConnection *sc)
+TMH_long_poll_suspend (struct TMH_SuspendedConnection *sc,
+                       const struct TALER_Amount *min_refund)
 {
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONTAINER_multihashmap_put (payment_trigger_map,
                                                     &sc->key,
                                                     sc,
                                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
+  if (NULL != min_refund)
+  {
+    sc->awaiting_refund = GNUNET_YES;
+    sc->refund_expected = *min_refund;
+  }
   sc->hn = GNUNET_CONTAINER_heap_insert (resume_timeout_heap,
                                          sc,
                                          sc->long_poll_timeout.abs_value_us);
@@ -325,6 +333,73 @@ TMH_long_poll_suspend (struct TMH_SuspendedConnection *sc)
 }
 
 
+/**
+ * Function called to resume suspended connections.
+ *
+ * @param cls pointer to a `struct TALER_Amount` indicating the refund amount, 
or NULL
+ * @param key key in the #payment_trigger_map
+ * @param value a `struct TMH_SuspendedConnection` to resume
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+resume_operation (void *cls,
+                  const struct GNUNET_HashCode *key,
+                  void *value)
+{
+  const struct TALER_Amount *have_refund = cls;
+  struct TMH_SuspendedConnection *sc = value;
+
+  if ( (GNUNET_YES == sc->awaiting_refund) &&
+       ( (NULL == have_refund) ||
+         (1 != TALER_amount_cmp (have_refund,
+                                 &sc->refund_expected)) ) )
+    return GNUNET_OK; /* skip */
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Resuming operation suspended pending payment on key %s\n",
+              GNUNET_h2s (key));
+  GNUNET_assert (GNUNET_YES ==
+                 GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map,
+                                                       key,
+                                                       sc));
+  GNUNET_assert (sc ==
+                 GNUNET_CONTAINER_heap_remove_node (sc->hn));
+  sc->hn = NULL;
+  MHD_resume_connection (sc->con);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Find out if we have any clients long-polling for @a order_id to be
+ * confirmed at merchant @a mpub, and if so, tell them to resume.
+ *
+ * @param order_id the order that was paid
+ * @param mpub the merchant's public key of the instance where the payment 
happened
+ * @param have_refund refunded amount, NULL if there was no refund
+ */
+void
+TMH_long_poll_resume (const char *order_id,
+                      const struct TALER_MerchantPublicKeyP *mpub,
+                      const struct TALER_Amount *have_refund)
+{
+  struct GNUNET_HashCode key;
+
+  TMH_compute_pay_key (order_id,
+                       mpub,
+                       &key);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Resuming operations suspended pending payment on key %s\n",
+              GNUNET_h2s (&key));
+  GNUNET_CONTAINER_multihashmap_get_multiple (payment_trigger_map,
+                                              &key,
+                                              &resume_operation,
+                                              (void *) have_refund);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "%u operations remain suspended pending payment\n",
+              GNUNET_CONTAINER_multihashmap_size (payment_trigger_map));
+}
+
+
 /**
  * Create a taler://pay/ URI for the given @a con and @a order_id
  * and @a session_id and @a instance_id.
diff --git a/src/backend/taler-merchant-httpd.h 
b/src/backend/taler-merchant-httpd.h
index b24b321..ad83a66 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -289,6 +289,16 @@ struct TMH_SuspendedConnection
    */
   struct GNUNET_TIME_Absolute long_poll_timeout;
 
+  /**
+   * Minimum refund amount to be exceeded (exclusive this value!) for resume.
+   */
+  struct TALER_Amount refund_expected;
+
+  /**
+   * #GNUNET_YES if we are waiting for a refund.
+   */
+  int awaiting_refund;
+
 };
 
 
@@ -412,9 +422,26 @@ TMH_compute_pay_key (const char *order_id,
  * Suspend connection from @a sc until payment has been received.
  *
  * @param sc connection to suspend
+ * @param min_refund refund amount we are waiting on to be exceeded before 
resuming,
+ *                   NULL if we are not waiting for refunds
+ */
+void
+TMH_long_poll_suspend (struct TMH_SuspendedConnection *sc,
+                       const struct TALER_Amount *min_refund);
+
+
+/**
+ * Find out if we have any clients long-polling for @a order_id to be
+ * confirmed at merchant @a mpub, and if so, tell them to resume.
+ *
+ * @param order_id the order that was paid
+ * @param mpub the merchant's public key of the instance where the payment 
happened
+ * @param refund_amount refunded amount, if the trigger was a refund, 
otherwise NULL
  */
 void
-TMH_long_poll_suspend (struct TMH_SuspendedConnection *sc);
+TMH_long_poll_resume (const char *order_id,
+                      const struct TALER_MerchantPublicKeyP *mpub,
+                      const struct TALER_Amount *refund_amount);
 
 
 /**
diff --git a/src/backend/taler-merchant-httpd_check-payment.c 
b/src/backend/taler-merchant-httpd_check-payment.c
index 66b4941..bb5384d 100644
--- a/src/backend/taler-merchant-httpd_check-payment.c
+++ b/src/backend/taler-merchant-httpd_check-payment.c
@@ -194,7 +194,8 @@ send_pay_request (struct CheckPaymentRequestContext *cprc)
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Suspending /check-payment on key %s\n",
                 GNUNET_h2s (&cprc->sc.key));
-    TMH_long_poll_suspend (&cprc->sc);
+    TMH_long_poll_suspend (&cprc->sc,
+                           NULL);
     return MHD_YES;
   }
 
diff --git a/src/backend/taler-merchant-httpd_pay.c 
b/src/backend/taler-merchant-httpd_pay.c
index 4c1e236..446320b 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -443,66 +443,6 @@ MH_force_pc_resume ()
 }
 
 
-/**
- * Function called to resume suspended connections.
- *
- * @param cls NULL
- * @param key key in the #payment_trigger_map
- * @param value a `struct TMH_SuspendedConnection` to resume
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-resume_operation (void *cls,
-                  const struct GNUNET_HashCode *key,
-                  void *value)
-{
-  struct TMH_SuspendedConnection *sc = value;
-
-  (void) cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Resuming operation suspended pending payment on key %s\n",
-              GNUNET_h2s (key));
-  GNUNET_assert (GNUNET_YES ==
-                 GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map,
-                                                       key,
-                                                       sc));
-  GNUNET_assert (sc ==
-                 GNUNET_CONTAINER_heap_remove_node (sc->hn));
-  sc->hn = NULL;
-  MHD_resume_connection (sc->con);
-  return GNUNET_OK;
-}
-
-
-/**
- * Find out if we have any clients long-polling for @a order_id to be
- * confirmed at merchant @a mpub, and if so, tell them to resume.
- *
- * @param order_id the order that was paid
- * @param mpub the merchant's public key of the instance where the payment 
happened
- */
-static void
-resume_suspended_payment_checks (const char *order_id,
-                                 const struct TALER_MerchantPublicKeyP *mpub)
-{
-  struct GNUNET_HashCode key;
-
-  TMH_compute_pay_key (order_id,
-                       mpub,
-                       &key);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Resuming operations suspended pending payment on key %s\n",
-              GNUNET_h2s (&key));
-  GNUNET_CONTAINER_multihashmap_get_multiple (payment_trigger_map,
-                                              &key,
-                                              &resume_operation,
-                                              NULL);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%u operations remain suspended pending payment\n",
-              GNUNET_CONTAINER_multihashmap_size (payment_trigger_map));
-}
-
-
 /**
  * Resume the given pay context and send the given response.
  * Stores the response in the @a pc and signals MHD to resume
@@ -2166,8 +2106,9 @@ begin_transaction (struct PayContext *pc)
         "Merchant database error: could not commit to mark proposal as 
'paid'");
       return;
     }
-    resume_suspended_payment_checks (pc->order_id,
-                                     &pc->mi->pubkey);
+    TMH_long_poll_resume (pc->order_id,
+                          &pc->mi->pubkey,
+                          NULL);
     generate_success_response (pc);
     return;
   }
diff --git a/src/backend/taler-merchant-httpd_poll-payment.c 
b/src/backend/taler-merchant-httpd_poll-payment.c
index 8db7289..49f9489 100644
--- a/src/backend/taler-merchant-httpd_poll-payment.c
+++ b/src/backend/taler-merchant-httpd_poll-payment.c
@@ -101,12 +101,24 @@ struct PollPaymentRequestContext
    */
   struct TALER_Amount refund_amount;
 
+  /**
+   * Minimum refund amount the client would like to poll for.
+   * Only initialized if
+   * @e awaiting_refund is set to #GNUNET_YES.
+   */
+  struct TALER_Amount min_refund;
+
   /**
    * Set to #GNUNET_YES if this payment has been refunded and
    * @e refund_amount is initialized.
    */
   int refunded;
 
+  /**
+   * Set to #GNUNET_YES if this client is waiting for a refund.
+   */
+  int awaiting_refund;
+
   /**
    * Initially #GNUNET_SYSERR. If we queued a response, set to the
    * result code (i.e. #MHD_YES or #MHD_NO). FIXME: fix type!
@@ -124,8 +136,8 @@ struct PollPaymentRequestContext
 static void
 pprc_cleanup (struct TM_HandlerContext *hc)
 {
-  struct PollPaymentRequestContext *pprc = (struct
-                                            PollPaymentRequestContext *) hc;
+  struct PollPaymentRequestContext *pprc
+    = (struct PollPaymentRequestContext *) hc;
 
   if (NULL != pprc->contract_terms)
     json_decref (pprc->contract_terms);
@@ -170,6 +182,27 @@ process_refunds_cb (void *cls,
 }
 
 
+/**
+ * Suspend this @a pprc until the trigger is satisfied.
+ *
+ * @param ppr
+ */
+static void
+suspend_pprc (struct PollPaymentRequestContext *pprc)
+{
+  TMH_compute_pay_key (pprc->order_id,
+                       &pprc->mi->pubkey,
+                       &pprc->sc.key);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Suspending /poll-payment on key %s\n",
+              GNUNET_h2s (&pprc->sc.key));
+  TMH_long_poll_suspend (&pprc->sc,
+                         (pprc->awaiting_refund)
+                         ? &pprc->min_refund
+                         : NULL);
+}
+
+
 /**
  * The client did not yet pay, send it the payment request.
  *
@@ -188,13 +221,7 @@ send_pay_request (struct PollPaymentRequestContext *pprc)
   if (0 != remaining.rel_value_us)
   {
     /* long polling: do not queue a response, suspend connection instead */
-    TMH_compute_pay_key (pprc->order_id,
-                         &pprc->mi->pubkey,
-                         &pprc->sc.key);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Suspending /poll-payment on key %s\n",
-                GNUNET_h2s (&pprc->sc.key));
-    TMH_long_poll_suspend (&pprc->sc);
+    suspend_pprc (pprc);
     return MHD_YES;
   }
 
@@ -274,6 +301,7 @@ MH_handler_poll_payment (struct TMH_RequestHandler *rh,
     /* First time here, parse request and check order is known */
     const char *long_poll_timeout_s;
     const char *cts;
+    const char *min_refund;
 
     pprc = GNUNET_new (struct PollPaymentRequestContext);
     pprc->hc.cc = &pprc_cleanup;
@@ -343,6 +371,27 @@ MH_handler_poll_payment (struct TMH_RequestHandler *rh,
     {
       pprc->sc.long_poll_timeout = GNUNET_TIME_UNIT_ZERO_ABS;
     }
+
+    min_refund = MHD_lookup_connection_value (connection,
+                                              MHD_GET_ARGUMENT_KIND,
+                                              "refund");
+    if (NULL != min_refund)
+    {
+      if ( (GNUNET_OK !=
+            TALER_string_to_amount (min_refund,
+                                    &pprc->min_refund)) ||
+           (0 != strcasecmp (pprc->min_refund.currency,
+                             TMH_currency) ) )
+      {
+        GNUNET_break_op (0);
+        return TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_BAD_REQUEST,
+                                           TALER_EC_PARAMETER_MALFORMED,
+                                           "invalid amount given for refund 
argument");
+      }
+      pprc->awaiting_refund = GNUNET_YES;
+    }
+
     pprc->contract_url = MHD_lookup_connection_value (connection,
                                                       MHD_GET_ARGUMENT_KIND,
                                                       "contract_url");
@@ -495,6 +544,25 @@ MH_handler_poll_payment (struct TMH_RequestHandler *rh,
                                        TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR,
                                        "Merchant database error");
   }
+  if ( (pprc->awaiting_refund) &&
+       ( (! pprc->refunded) ||
+         (1 != TALER_amount_cmp (&pprc->refund_amount,
+                                 &pprc->min_refund)) ) )
+  {
+    /* Client is waiting for a refund larger than what we have, suspend
+       until timeout */
+    struct GNUNET_TIME_Relative remaining;
+
+    remaining = GNUNET_TIME_absolute_get_remaining 
(pprc->sc.long_poll_timeout);
+    if (0 != remaining.rel_value_us)
+    {
+      /* yes, indeed suspend */
+      pprc->refunded = GNUNET_NO;
+      suspend_pprc (pprc);
+      return MHD_YES;
+    }
+  }
+
   if (pprc->refunded)
     return TALER_MHD_reply_json_pack (connection,
                                       MHD_HTTP_OK,
diff --git a/src/backend/taler-merchant-httpd_refund_increase.c 
b/src/backend/taler-merchant-httpd_refund_increase.c
index 1832dee..6d49dfc 100644
--- a/src/backend/taler-merchant-httpd_refund_increase.c
+++ b/src/backend/taler-merchant-httpd_refund_increase.c
@@ -257,6 +257,11 @@ process_refund (struct MHD_Connection *connection,
                                        "Amount above payment");
   }
 
+  /* Resume /public/poll-payments clients that may wait for this refund */
+  TMH_long_poll_resume (order_id,
+                        &mi->pubkey,
+                        refund);
+
   {
     MHD_RESULT ret;
     char *taler_refund_uri;
diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index ef616c1..7298b8b 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -1386,6 +1386,9 @@ typedef void
  *        before generating an unpaid response). Note that this is just 
provided to
  *        the server, we as client will block until the response comes back or 
until
  *        #TALER_MERCHANT_poll_payment_cancel() is called.
+ * @param min_refund long poll for the service to approve a refund exceeding 
this value;
+ *        use NULL to not wait for any refund (only for payment). Only makes 
sense
+ *        with a non-zero @a timeout.
  * @param poll_payment_cb callback which will work the response gotten from 
the backend
  * @param poll_payment_cb_cls closure to pass to @a poll_payment_cb
  * @return handle for this operation, NULL upon errors
@@ -1398,6 +1401,7 @@ TALER_MERCHANT_poll_payment (
   const struct GNUNET_HashCode *h_contract,
   const char *session_id,
   struct GNUNET_TIME_Relative timeout,
+  const struct TALER_Amount *min_refund,
   TALER_MERCHANT_PollPaymentCallback poll_payment_cb,
   void *poll_payment_cls);
 
diff --git a/src/include/taler_merchant_testing_lib.h 
b/src/include/taler_merchant_testing_lib.h
index e7c47f1..c14ee2e 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -179,6 +179,7 @@ TALER_TESTING_cmd_check_payment_conclude (const char *label,
  * @param merchant_url merchant base url
  * @param proposal_reference the proposal whose payment status
  *        is going to be checked.
+ * @param min_refund minimum refund to wait for
  * @param timeout which timeout to use
  * @return the command
  */
@@ -186,6 +187,7 @@ struct TALER_TESTING_Command
 TALER_TESTING_cmd_poll_payment_start (const char *label,
                                       const char *merchant_url,
                                       const char *proposal_reference,
+                                      const char *min_refund,
                                       struct GNUNET_TIME_Relative timeout);
 
 
@@ -439,7 +441,6 @@ TALER_TESTING_cmd_merchant_track_transaction (const char 
*label,
  * @param check_bank_reference reference to a "check bank" CMD
  *        that will provide the WTID and exchange URL to issue
  *        the track against.
- * @param pay_reference FIXME not used.
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_merchant_track_transfer (const char *label,
@@ -455,13 +456,12 @@ TALER_TESTING_cmd_merchant_track_transfer (const char 
*label,
  * @param index which signature to offer if there are multiple
  *        on offer
  * @param merchant_sig set to the offered signature.
- *
  * @return the trait
  */
 struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_merchant_sig (unsigned int index,
-                                       const struct
-                                       TALER_MerchantSignatureP *merchant_sig);
+TALER_TESTING_make_trait_merchant_sig (
+  unsigned int index,
+  const struct TALER_MerchantSignatureP *merchant_sig);
 
 
 /**
@@ -475,10 +475,10 @@ TALER_TESTING_make_trait_merchant_sig (unsigned int index,
  * @return #GNUNET_OK on success
  */
 int
-TALER_TESTING_get_trait_merchant_sig (const struct TALER_TESTING_Command *cmd,
-                                      unsigned int index,
-                                      struct TALER_MerchantSignatureP **
-                                      merchant_sig);
+TALER_TESTING_get_trait_merchant_sig (
+  const struct TALER_TESTING_Command *cmd,
+  unsigned int index,
+  struct TALER_MerchantSignatureP **merchant_sig);
 
 /**
  * Obtain a reference to a proposal command.  Any command that
@@ -491,15 +491,14 @@ TALER_TESTING_get_trait_merchant_sig (const struct 
TALER_TESTING_Command *cmd,
  * @param cmd command to extract the trait from.
  * @param index which reference to pick if @a cmd has multiple
  *        on offer.
- * @param proposal_reference[out] set to the wanted reference.
- *
+ * @param[out] proposal_reference set to the wanted reference.
  * @return #GNUNET_OK on success
  */
 int
-TALER_TESTING_get_trait_proposal_reference (const struct
-                                            TALER_TESTING_Command *cmd,
-                                            unsigned int index,
-                                            const char **proposal_reference);
+TALER_TESTING_get_trait_proposal_reference (
+  const struct TALER_TESTING_Command *cmd,
+  unsigned int index,
+  const char **proposal_reference);
 
 /**
  * Offer a proposal reference.
@@ -534,7 +533,7 @@ TALER_TESTING_make_trait_coin_reference (unsigned int index,
  * @param cmd command to extract trait from
  * @param index which reference to pick if @a cmd has multiple
  *        on offer
- * @param coin_reference[out] set to the wanted reference.
+ * @param[out] coin_reference set to the wanted reference.
  *        NOTE: a _single_ reference can contain
  *        _multiple_ instances, using semi-colon as separator.
  *        For example, a _single_ reference can be this:
@@ -556,29 +555,25 @@ TALER_TESTING_get_trait_coin_reference (const struct 
TALER_TESTING_Command *cmd,
  * @param cmd command to extract trait from.
  * @param index index of the trait.
  * @param planchet_secrets[out] set to the wanted secrets.
- *
  * @return #GNUNET_OK on success
  */
 int
-TALER_TESTING_get_trait_planchet_secrets (const struct
-                                          TALER_TESTING_Command *cmd,
-                                          unsigned int index,
-                                          struct TALER_PlanchetSecretsP **
-                                          planchet_secrets);
+TALER_TESTING_get_trait_planchet_secrets (
+  const struct TALER_TESTING_Command *cmd,
+  unsigned int index,
+  struct TALER_PlanchetSecretsP **planchet_secrets);
 
 /**
  * Offer planchet secrets.
  *
  * @param index of the trait.
  * @param planchet_secrets set to the offered secrets.
- *
  * @return the trait
  */
 struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_planchet_secrets (unsigned int index,
-                                           const struct
-                                           TALER_PlanchetSecretsP *
-                                           planchet_secrets);
+TALER_TESTING_make_trait_planchet_secrets (
+  unsigned int index,
+  const struct TALER_PlanchetSecretsP *planchet_secrets);
 
 /**
  * Offer tip id.
@@ -598,8 +593,7 @@ TALER_TESTING_make_trait_tip_id (unsigned int index,
  * @param cmd command to extract the trait from.
  * @param index which tip id to pick if @a
  *        cmd has multiple on offer
- * @param tip_id[out] set to the wanted data.
- *
+ * @param[out] tip_id set to the wanted data.
  * @return #GNUNET_OK on success
  */
 int
@@ -618,9 +612,9 @@ TALER_TESTING_get_trait_tip_id (const struct 
TALER_TESTING_Command *cmd,
  * @return the trait
  */
 struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_h_contract_terms (unsigned int index,
-                                           const struct
-                                           GNUNET_HashCode *h_contract_terms);
+TALER_TESTING_make_trait_h_contract_terms (
+  unsigned int index,
+  const struct GNUNET_HashCode *h_contract_terms);
 
 
 /**
@@ -628,15 +622,14 @@ TALER_TESTING_make_trait_h_contract_terms (unsigned int 
index,
  *
  * @param cmd command to extract the trait from.
  * @param index index number of the trait to fetch.
- * @param h_contract_terms[out] set to the wanted data.
+ * @param[out] h_contract_terms set to the wanted data.
  * @return #GNUNET_OK on success
  */
 int
-TALER_TESTING_get_trait_h_contract_terms (const struct
-                                          TALER_TESTING_Command *cmd,
-                                          unsigned int index,
-                                          const struct
-                                          GNUNET_HashCode **h_contract_terms);
+TALER_TESTING_get_trait_h_contract_terms (
+  const struct TALER_TESTING_Command *cmd,
+  unsigned int index,
+  const struct GNUNET_HashCode **h_contract_terms);
 
 /**
  * Offer refund entry.
@@ -646,9 +639,9 @@ TALER_TESTING_get_trait_h_contract_terms (const struct
  * @return the trait
  */
 struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_refund_entry (unsigned int index,
-                                       const struct
-                                       TALER_MERCHANT_RefundEntry 
*refund_entry);
+TALER_TESTING_make_trait_refund_entry (
+  unsigned int index,
+  const struct TALER_MERCHANT_RefundEntry *refund_entry);
 
 
 /**
@@ -656,15 +649,14 @@ TALER_TESTING_make_trait_refund_entry (unsigned int index,
  *
  * @param cmd command to extract the trait from.
  * @param index the trait index.
- * @param refund_entry[out] set to the wanted data.
- *
+ * @param[out] refund_entry set to the wanted data.
  * @return #GNUNET_OK on success
  */
 int
-TALER_TESTING_get_trait_refund_entry (const struct TALER_TESTING_Command *cmd,
-                                      unsigned int index,
-                                      const struct
-                                      TALER_MERCHANT_RefundEntry 
**refund_entry);
+TALER_TESTING_get_trait_refund_entry (
+  const struct TALER_TESTING_Command *cmd,
+  unsigned int index,
+  const struct TALER_MERCHANT_RefundEntry **refund_entry);
 
 /**
  * Create a /tip-authorize CMD, specifying the Taler error code
@@ -699,12 +691,12 @@ TALER_TESTING_cmd_tip_authorize_with_ec (const char 
*label,
  * to test against such a case.
  *
  * @param label command label.
- *
  * @return the command.
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_tip_authorize_fake (const char *label);
 
+
 /**
  * Create a /tip-authorize CMD.
  *
@@ -810,10 +802,10 @@ TALER_TESTING_cmd_tip_pickup (const char *label,
  *
  * @param label command label
  * @param new_ip new instruction pointer's value.  Note that,
- * when the next instruction will be called, the interpreter
- * will increment the ip _anyway_ so this value must be
- * set to the index of the instruction we want to execute next
- * MINUS one.
+ *    when the next instruction will be called, the interpreter
+ *    will increment the ip _anyway_ so this value must be
+ *    set to the index of the instruction we want to execute next
+ *    MINUS one.
  * @param counter counts how many times the rewinding has
  * to happen.
  */
diff --git a/src/lib/merchant_api_poll_payment.c 
b/src/lib/merchant_api_poll_payment.c
index bef2aac..6b0190a 100644
--- a/src/lib/merchant_api_poll_payment.c
+++ b/src/lib/merchant_api_poll_payment.c
@@ -205,6 +205,9 @@ handle_poll_payment_finished (void *cls,
  *        before generating an unpaid response). Note that this is just 
provided to
  *        the server, we as client will block until the response comes back or 
until
  *        #TALER_MERCHANT_poll_payment_cancel() is called.
+ * @param min_refund long poll for the service to approve a refund exceeding 
this value;
+ *        use NULL to not wait for any refund (only for payment). Only makes 
sense
+ *        with a non-zero @a timeout.
  * @param poll_payment_cb callback which will work the response gotten from 
the backend
  * @param poll_payment_cb_cls closure to pass to @a poll_payment_cb
  * @return handle for this operation, NULL upon errors
@@ -217,6 +220,7 @@ TALER_MERCHANT_poll_payment (
   const struct GNUNET_HashCode *h_contract,
   const char *session_id,
   struct GNUNET_TIME_Relative timeout,
+  const struct TALER_Amount *min_refund,
   TALER_MERCHANT_PollPaymentCallback poll_payment_cb,
   void *poll_payment_cb_cls)
 {
@@ -253,6 +257,9 @@ TALER_MERCHANT_poll_payment (
                              "h_contract", h_contract_s,
                              (0 != ts) ? "timeout" : NULL,
                              timeout_s,
+                             (NULL != min_refund) ? "refund" : NULL,
+                             (NULL != min_refund) ? TALER_amount2s (
+                               min_refund) : NULL,
                              NULL);
   GNUNET_free (h_contract_s);
   GNUNET_free (timeout_s);
diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c
index f16cf5f..1f3626e 100644
--- a/src/lib/test_merchant_api.c
+++ b/src/lib/test_merchant_api.c
@@ -279,6 +279,7 @@ run (void *cls,
     TALER_TESTING_cmd_poll_payment_start ("poll-payment-1",
                                           merchant_url,
                                           "create-proposal-1",
+                                          NULL,
                                           GNUNET_TIME_UNIT_MILLISECONDS),
     TALER_TESTING_cmd_poll_payment_conclude ("poll-payment-conclude-1",
                                              MHD_HTTP_OK,
@@ -287,6 +288,7 @@ run (void *cls,
     TALER_TESTING_cmd_poll_payment_start ("poll-payment-2",
                                           merchant_url,
                                           "create-proposal-1",
+                                          NULL,
                                           GNUNET_TIME_UNIT_MINUTES),
     TALER_TESTING_cmd_check_payment_start ("check-payment-2",
                                            merchant_url,
diff --git a/src/lib/testing_api_cmd_poll_payment.c 
b/src/lib/testing_api_cmd_poll_payment.c
index 6d8c37c..32fcadd 100644
--- a/src/lib/testing_api_cmd_poll_payment.c
+++ b/src/lib/testing_api_cmd_poll_payment.c
@@ -84,6 +84,11 @@ struct PollPaymentStartState
    */
   struct TALER_Amount refund;
 
+  /**
+   * Refund to wait for, set if @e wait_for_refund is #GNUNET_YES
+   */
+  struct TALER_Amount min_refund;
+
   /**
    * Final HTTP response status code.
    */
@@ -99,6 +104,11 @@ struct PollPaymentStartState
    */
   int refunded;
 
+  /**
+   * #GNUNET_YES if we are waiting for a refund.
+   */
+  int wait_for_refund;
+
 };
 
 
@@ -325,6 +335,9 @@ poll_payment_start_run (void *cls,
                                           h_contract,
                                           NULL, /* session id */
                                           cps->timeout,
+                                          (GNUNET_YES == cps->wait_for_refund)
+                                          ? &cps->min_refund
+                                          : NULL,
                                           &poll_payment_cb,
                                           cps);
   GNUNET_assert (NULL != cps->cpo);
@@ -341,6 +354,7 @@ poll_payment_start_run (void *cls,
  * @param merchant_url merchant base url
  * @param proposal_reference the proposal whose payment status
  *        is going to be checked.
+ * @param min_refund minimum refund to wait for
  * @param timeout which timeout to use
  * @return the command
  */
@@ -348,6 +362,7 @@ struct TALER_TESTING_Command
 TALER_TESTING_cmd_poll_payment_start (const char *label,
                                       const char *merchant_url,
                                       const char *proposal_reference,
+                                      const char *min_refund,
                                       struct GNUNET_TIME_Relative timeout)
 {
   struct PollPaymentStartState *cps;
@@ -356,6 +371,13 @@ TALER_TESTING_cmd_poll_payment_start (const char *label,
   cps->proposal_reference = proposal_reference;
   cps->merchant_url = merchant_url;
   cps->timeout = timeout;
+  if (NULL != min_refund)
+  {
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_string_to_amount (min_refund,
+                                           &cps->min_refund));
+    cps->wait_for_refund = GNUNET_YES;
+  }
   {
     struct TALER_TESTING_Command cmd = {
       .cls = cps,

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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