summaryrefslogtreecommitdiff
path: root/design-documents
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-04-08 22:13:55 +0200
committerChristian Grothoff <christian@grothoff.org>2023-04-08 22:13:55 +0200
commitb617c6452ec92c06533e98a26b09c23165fbbf44 (patch)
treed5e12c87517c813a14eecd8d7e7e20bbc7a2cd86 /design-documents
parent343f392149caadaf8e4209863364a61672f5c876 (diff)
downloaddocs-b617c6452ec92c06533e98a26b09c23165fbbf44.tar.gz
docs-b617c6452ec92c06533e98a26b09c23165fbbf44.tar.bz2
docs-b617c6452ec92c06533e98a26b09c23165fbbf44.zip
review payment states
Diffstat (limited to 'design-documents')
-rw-r--r--design-documents/037-wallet-transactions-lifecycle.rst137
1 files changed, 84 insertions, 53 deletions
diff --git a/design-documents/037-wallet-transactions-lifecycle.rst b/design-documents/037-wallet-transactions-lifecycle.rst
index e2a04820..366079a2 100644
--- a/design-documents/037-wallet-transactions-lifecycle.rst
+++ b/design-documents/037-wallet-transactions-lifecycle.rst
@@ -286,87 +286,120 @@ shown in the above diagram to keep it on point.
Transaction Type: Payment to Merchant
-------------------------------------
-XXX: Also consider re-selection when the wallet accidentally double-spends coins
-or the selected coins have expired. Do we ask the user in this case?
+* ``pending(claim-proposal)``
-CG: I think no. We correct our balance (after all, we got a proof of
-double-spending) and try other coins. If we do not have enough money left, we
-abort and simply inform the user that their balance was insufficient to make
-the payment after all (very sorry...).
+ Initial state. Download (claim) the proposal from the merchant. Can fail if
+ the proposal was already claimed by someone else. If repurchase detection
+ tells us that we already paid for this product, we go immediately to
+ ``delete`` state for this transaction, but with a side-effect of
+ transitioning the UI into a ``pending(repurchase-session-reset)`` on a
+ *different* transaction (which before was in ``done``).
-Note that the case of selected coins having expired shouldn't really happen,
-as the wallet should have noticed that when is started up, tried to refresh,
-and if that already failed should have update the balance with a transaction
-history entry saying something like "coins expired, offline too long" or
-something like that.
+ * ``[error: already claimed] => deleted`` -- the proposal was
+ already claimed by someone else; we go directly into the ``deleted``
+ state and only show a transient warning.
+ * ``[error: invalid proposal] => deleted`` -- the merchant provided a
+ proposal that is invalid (e.g. malformed contract
+ terms or bad signature); we go directly into the ``deleted`` state
+ and only show a transient warning.
-(??) If transaction can be aborted while in-progress then it should return
-instructedAmount, effectiveAmount and the affectedAmount (partially effective amount)
-
-* ``initial(download-proposal)``
-
- Initial state. Download (claim) the proposal from the merchant.
-
- XXX: Also consider repurchase detection here?
-
- CG: Well, we could mention that this is a possible transition from
- ``pending(download-proposal)`` to ``deleted`` with a side-effect
- of transitioning the UI into a ``pending(repurchase-session-reset)``
- on a different transaction (which before was in ``done``).
-
- (??) should not reset another transaction?
* ``pending(proposed)``
Let the user accept (or refuse) the payment.
* ``[action:pay-accept] => pending(submit-payment)``
- * ``[action:abort] => deleted`` -- user explicitly decides not
- to proceed
- * ``[action:expired] => deleted`` -- when the offer expires
- before the user decides to make the payment! (We can keep
- pending contracts even in a 'pending transaction' list to
- allow the user to choose to not proceed, but then this
- transition would clean up that list).
+ * ``[action:pay-refuse] => ``aborting(unclaim)`` -- The user explicitly
+ decided not to proceed (at least not with this wallet).
+ * ``[expired] => deleted`` -- The offer has expired before the user made any
+ decision. (We can keep pending contracts even in a 'pending transaction'
+ list to allow the user to choose to not proceed, but then this transition
+ would clean up that list). Note that we should use this transition at
+ least a few seconds before the offer *actually* expires to avoid
+ encountering an expiration during ``pending(submit-payment)`` in most
+ real-world scenarios. Basically, we should prevent last-second payments to
+ be event attempted client-side.
+
+* ``aborting(unclaim)``
+
+ Tells the merchant that some *other* wallet is now again free to claim this
+ offer.
* ``pending(submit-payment)``
-Submit coin by coin (or in bulk groups) until payment is complete.
-
- * ``[action:abort] => aborting(refund)``
- * ``[processed-success(auto-refund-enabled)] => pending(refundable)``
- * ``[processed-success(auto-refund-disabled)] => done``
- * ``[processed-error(expired)] => aborting(refresh)`` XXX: If the order is expired but the payment
- succeeded partially before, do we still try an abort-refund? CG: YES, but of course
- we probably should use the ``expired`` transition above a few seconds before the
- offer *actually* expires to avoid this problem in 99.9% of real-world scenarios
- ("prevent last-second payments client-side")
+ Submit coin-by-coin (or in bulk groups) until payment is complete.
+
+ * ``[action:abort] => aborting(refund)`` -- The user explicitly decided to
+ abort the process while the payment was happening. Note that if the
+ payment was already completed (and hence the merchant refuses any
+ refunds), it is theoretically possible that pressing the abort button will
+ nevertheless end up in a ``pending(refundable)`` state (and subsequently
+ a ``done`` state) instead!
+ * ``[success] => pending(refundable)`` -- Upon receiving confirmation from
+ the merchant that the purchase was completed.
+ * ``[error(insufficient balance)] => aborting(refresh)`` This transition
+ happens if we detect double-spending and our balance is not sufficient
+ after the double-spending. It is also conceivable (but should be rare)
+ that this transition happens because the offer expired.
* ``pending(refundable)``
-The payment succeed but if auto-refund-check is active it will be checking for refunds
+ The payment succeed. We remain in this tate as long as an auto-refund-check
+ is active. If auto refunds are not enabled, we immediately continue to
+ ``done``.
- * ``[auto-refund-timeout] => done``
+ * ``[timeout] => done`` -- This happens when the auto refund set by the contract expired.
+ * ``[action:abort] => done`` -- The user may explicitly request to abort the auto-refund processing (for example to enable subsequent deletion before the auto-refund delay expires).
* ``aborting(refund)``
- * ``[processed-success] => aborted(refunded)``
- * ``[processed-failure] => aborting(refresh)``
+ The wallet should interact with the merchant to confirm that a refund
+ was approved.
-* ``aborting(refresh)``
+ * ``[success] => aborted(refunded)``
+ * ``[failure] => aborting(refresh)``
-* ``failed(invalid-proposal)``
+* ``aborting(refresh)``
- The merchant provided a proposal that is invalid (e.g. malformed contract terms or bad signature).
+ The wallet should interact with the exchange to obtain fresh coins for
+ the refunded balance.
* ``aborted(refunded)``
+ The purchase ended with a (partial) refund. The state (and UI) should show
+ the specific provenance of the state, which may include an insufficient
+ balance (due to double-spending being detected during payment), and one or
+ more partial or full refunds.
+
+ * ``[URI:refund] => aborting(refund)`` -- The previous refund was partial,
+ and we have received an additional refund for this transaction.
+ * ``[action:delete] => deleted``
+
+* ``done``
+
+ The purchase is completed.
+
* ``[action:delete] => deleted``
+ * ``[refund URI trigger] => aborting(refund)`` -- A refund was initiated for the purchase.
+ * ``[repurchase] => pending(repurchase-session-reset)`` -- Another offer became pending for this product.
+
+* ``pending(repurchase-session-reset)``
+
+ The wallet should reset the associated session for the already purchased item.
+
+ * ``[success] => done``
+ * ``[action:abort] => done`` -- User aborted the session reset.
* ``deleted``
- When a payment is deleted, associated refunds are always deleted with it
+ When a payment is deleted, associated refunds are always deleted with it.
+.. image:: ../transaction-payment-states.png
+ :width: 800
+
+Purple arrows are used to indicate transitions triggered in special ways outside
+of the user interface for this transaction, such as side-effects of repurchase
+detection for another purchase or opening of a refund URI.
Transaction Type: Refund
@@ -709,8 +742,6 @@ Alternatives
not ask again."). Probably at best a post-1.0 feature.
-
-
Drawbacks
=========