summaryrefslogtreecommitdiff
path: root/design-documents
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-04-09 11:43:11 +0200
committerChristian Grothoff <christian@grothoff.org>2023-04-09 11:43:11 +0200
commiteaa726572e42adc623190f4922d0bd0d6363b5b9 (patch)
treec7e5815274a305a1c58b02b4bb6c8e38f21d6e07 /design-documents
parentb617c6452ec92c06533e98a26b09c23165fbbf44 (diff)
downloaddocs-eaa726572e42adc623190f4922d0bd0d6363b5b9.tar.gz
docs-eaa726572e42adc623190f4922d0bd0d6363b5b9.tar.bz2
docs-eaa726572e42adc623190f4922d0bd0d6363b5b9.zip
more spec work on dd37
Diffstat (limited to 'design-documents')
-rw-r--r--design-documents/037-wallet-transactions-lifecycle.rst175
1 files changed, 109 insertions, 66 deletions
diff --git a/design-documents/037-wallet-transactions-lifecycle.rst b/design-documents/037-wallet-transactions-lifecycle.rst
index 366079a2..7001e287 100644
--- a/design-documents/037-wallet-transactions-lifecycle.rst
+++ b/design-documents/037-wallet-transactions-lifecycle.rst
@@ -160,7 +160,7 @@ Transaction Type: Withdrawal
so we must still *try* to abort the transaction at the bank.
* ``[processed-success] => pending(bank-confirming)``
- * ``[processed-error] => aborted(bank-to-wallet)``
+ * ``[processed-error] => deleted``: We show a transient warning.
* ``[action:abort] => aborting(bank-to-wallet)``
* ``pending(bank-confirming)``
@@ -177,10 +177,35 @@ Transaction Type: Withdrawal
the bank did not return success or failure.
* ``[bank-poll-success] => pending(exchange-wait-reserve)``
- * ``[bank-poll-denied] => aborted(wallet-to-bank)``
+ * ``[bank-poll-denied] => deleted``: We show a transient message that the operation was denied in the bank.
* ``[exchange-poll-success] => pending(withdrawing-coins)``
* ``[action:abort] => aborting(wallet-to-bank)``
+* ``aborting(wallet-to-bank)``
+
+ The user aborted the withdraw operation in the wallet. The wallet must now
+ try to signal the bank that the wire transfer should no longer be performed.
+ Note that it is possible that the bank registration never succeeded (if the
+ user aborted us during ``pending(bank-register-service)``) and in this case
+ we get an ``unknown transaction`` failure here. It is also theoretically
+ possible that the user approved the transaction in the bank while
+ simultaneously aborting in the wallet. In this case, we transition to
+ ``suspended(after-wired)`` (treating the ``abort`` action as a ``suspend``
+ action).
+
+ * ``[processed-success] => deleted``: We show a transient message that the operation was aborted.
+ * ``[processed-error(already-confirmed)] => suspended(after-wired)``: We keep a transaction history entry reminding the user about when the already wired funds will be returned.
+ * ``[processed-error(unknown-transaction)] => deleted``
+
+* ``suspended(after-wired)``
+
+ In this state, the wallet should show to the user that the money from the withdrawal
+ reserve will be sent back to the originating bank account after ``$closing_delay``.
+ Note that the ``resume`` action should be disabled after ``$closing_delay``.
+
+ * ``[action:delete] => deleted``
+ * ``[action:resume] => pending(exchange-wait-reserve)``
+
* ``pending(exchange-wait-reserve)``
Initial state for manual withdrawals. Here, the wallet long-polls the
@@ -188,7 +213,15 @@ Transaction Type: Withdrawal
at the exchange.
* ``[exchange-poll-success] => pending(withdrawing-coins)``
- * ``[action:abort] => aborted(after-wired)``
+ * ``[action:suspend] => suspended(after-wired)``
+
+* ``suspended(after-wired)``
+
+ State where funds were (presumably) wired to the exchange but the wallet
+ was asked to not proceed with the withdraw, but we still resume.
+
+ * ``[action:resume] => pending(exchange-wait-reserves)``
+ * ``[action:delete] => deleted``
* ``pending(withdrawing-coins)``
@@ -197,11 +230,11 @@ Transaction Type: Withdrawal
holding pattern on the AML or KYC checks of the exchange.
* ``[processed-success] => done``
- * ``[processed-kyc-required] => pending(kyc-required)``
- * ``[processed-aml-required] => pending(aml-required)``
- * ``[action:abort] => aborted(partially-withdrawn)``
+ * ``[processed-kyc-required] => pending(kyc)``
+ * ``[processed-aml-required] => pending(aml)``
+ * ``[action:suspend] => suspended(withdrawing-coins)``
-* ``pending(kyc-required)``
+* ``pending(kyc)``
State where the user needs to provide some identity data to pass a KYC
check. The wallet only shows the user the link for starting the KYC
@@ -209,64 +242,55 @@ Transaction Type: Withdrawal
completing the KYC requirement.
* ``[poll-success] => pending(withdrawing-coins)``
- * ``[action:abort] => aborted(partially-withdrawn)``
+ * ``[action:suspend] => suspended(kyc)``
-* ``pending(aml-required)``
+* ``suspended(kyc)``
- State where the wallet needs to wait for completion of an AML process
- by an AML officer of the exchange. The wallet shows that the AML process
- is pending at the exchange and long-polls for it to complete. The user
- is urged to simply wait.
+ State where the user needs to provide some identity data to pass a KYC
+ check, but the long-polling was explicitly stopped. The user can
+ choose to resume or delete.
- * ``[poll-success] => pending(withdrawing-coins)``
- * ``[action:abort] => aborted(partially-withdrawn)``
+ * ``[action:delete] => deleted``
+ * ``[action:resume] => pending(kyc)``
-* ``pending(aml-frozen)``
+* ``pending(aml)``
- State where the wallet informs the user that their funds were frozen
- due to an AML decision. The user is urged to contact the exchange
- operator's AML department out-of-band. The wallet long-polls in
- anticipation of the account being unfrozen.
+ State where the wallet needs to wait for completion of an AML process by an
+ AML officer of the exchange. The wallet shows that the AML process is
+ blocking progress. The message shown should distinguish between a mere
+ pending AML process and an AML freezing decision in terms of the message
+ shown to the user. If the AML decision is pending at the exchange, he user
+ should be urged to simply wait. If the funds were frozen, the wallet
+ informs the user that their funds were frozen due to an AML decision. The
+ user is urged to contact the exchange operator's AML department out-of-band.
+ In any case, the wallet long-polls for the AML decision to be made or change
+ (possibly at a lower frequeny in case of a freeze).
* ``[poll-success] => pending(withdrawing-coins)``
- * ``[action:abort] => aborted(partially-withdrawn)``
-
-* ``aborting(wallet-to-bank)``
-
- The user aborted the withdraw operation in the wallet.
- The wallet must now try to signal the bank that the wire
- transfer should no longer be performed. Note that it
- is possible that the bank registration never succeeded
- (if the user aborted us during ``pending(bank-register-service)``)
- and in this case we get an ``unknown transaction`` failure here.
- It is also theoretically possible that the user approved the
- transaction in the bank while simultaneously aborting in the
- wallet. In this case, we transition to ``aborted(after-wired)``.
-
- * ``[processed-success] => aborted(wallet-to-bank)``
- * ``[processed-error(already-confirmed)] => aborted(after-wired)``
- * ``[processed-error(unknown-transaction)] => aborted(bank-to-wallet)``
-
-* ``aborted(wallet-to-bank)``: The wallet notified the bank that the withdrawal
- should be aborted, before any money was wired.
+ * ``[action:suspend] => suspended(aml)``
-* ``aborted(bank-to-wallet)``: The bank notified the wallet that the withdrawal
- was denied on the side of the bank (or the request never succeeded in the
- first place) and won't proceed.
+* ``suspended(aml)``
-* ``aborted(after-wired)``:
+ State where the user needs to await some AML decision by the exchange.
+ The long-polling was explicitly stopped. The user can choose to resume or delete.
- In this state, the wallet should show to the user that the money from the withdrawal
- reserve will be sent back to the originating bank account after ``$closing_delay``.
+ * ``[action:delete] => deleted``
+ * ``[action:resume] => pending(aml)``
-* ``aborted(partially-withdrawn)``:
+* ``suspended(withdrawing-coins)``
In this state, the wallet should show how much money arrived into the wallet
and the rest of the money will be sent back to the originating bank account
- after ``$closing_delay``.
+ after ``$closing_delay``. Note that the ``resume`` action should be
+ disabled after ``$closing_delay``.
+
+ * ``[action:delete] => deleted``
+ * ``[action:resume] => pending(exchange-wait-reserve)``
* ``done``
+ The withdrawal operation is complete.
+
* ``[action:delete] => deleted``
* ``deleted``
@@ -279,16 +303,13 @@ Transaction Type: Withdrawal
.. image:: ../transaction-withdrawal-states.png
:width: 800
-Transitions relating to deletion, suspending and resuming are not
-shown in the above diagram to keep it on point.
-
Transaction Type: Payment to Merchant
-------------------------------------
* ``pending(claim-proposal)``
- Initial state. Download (claim) the proposal from the merchant. Can fail if
+ We received a ``pay`` URI. 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
@@ -380,7 +401,6 @@ Transaction Type: Payment to Merchant
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)``
@@ -407,29 +427,52 @@ Transaction Type: Refund
A refund is a pseudo-transaction that is always associated with a merchant payment transaction.
-* ``initial``
+* ``pending(lookup-refund)``
- The wallet has downloaded metadata for the refund from the merchant and
- stored it in the database. The user needs to accept/refuse it.
+ We received a ``refund`` URI. Download refund details (like the amount) from the merchant. If the merchant responds with a permanent failure, we only show a transient warning and delete the transaction.
- * ``[processed-success] => pending``: the refund is accepted
- * ``[processed-abort] => aborted`` : the refund is not accepted
+ * ``[success] => pending(user-accept)``
+ * ``[action:suspend] => suspended(lookup-refund)``
+ * ``[failure] => deleted``
-* ``pending``
+* ``suspended(lookup-refund)``
+
+ The user suspended while we were looking up the refund details. Allow resuming or permanent deletion.
- A refund is pending when the merchant is getting a non-permanent error from
- the exchange (and relaying that error response to the wallet).
+ * ``[action:resume] => pending(lookup-refund)``
+ * ``[action:delete] => deleted``
+
+* ``pending(user-accept)``
+
+ The wallet has downloaded metadata for the refund from the merchant and stored it in the database. The user needs to accept/refuse it.
+
+ * ``[action:accept] => pending(merchant)``: the refund is accepted
+ * ``[action:delete] => deleted`` : the refund is not accepted
+
+* ``pending(merchant)``
+
+ A refund is pending in this state while we are waiting for the merchant to get a successful response from the exchange (and relaying that error response to the wallet).
+
+ * ``[action:suspend] => suspended(merchant)``
+ * ``[processed-success] => pending(refresh)``
+ * ``[processed-error] => failed``: we received a permanent failure (such as money already wired to the merchant)
+
+* ``pending(refresh)``
+
+ The wallet is now refreshing the coins.
* ``[processed-success] => done``
- * ``[processed-error] => failed``
+ * ``[action:suspend] => suspended(refresh)``
+ * ``[processed-error] => failed``: we received a permanent failure.
+
* ``failed``
- A failed refund can technically still transition to ``done``, because the wallet
- doesn't query some refund resource, but the purchase for refunds. Thus, a previously
- failed refund can suddenly transition to ``done``.
+ The refund failed permanently.
+
+.. image:: ../transaction-refund-states.png
+ :width: 800
- (??) separate transient error vs permanent error ?
Transaction Type: Refresh
-------------------------