commit 66219dc6d7466730f6517361ce51e3678195cd85
parent 06031bd0da5159367ced82ca33cfc7ad26e42ad0
Author: Florian Dold <florian@dold.me>
Date: Tue, 25 Apr 2023 15:32:12 +0200
fixes, simplify diagrams
Diffstat:
3 files changed, 88 insertions(+), 83 deletions(-)
diff --git a/design-documents/037-wallet-transactions-lifecycle.rst b/design-documents/037-wallet-transactions-lifecycle.rst
@@ -162,6 +162,9 @@ the account needed to be frozen. The user should contact the exchange
provider's customer service department and seek resolution (possibly through
the courts) to avoid loosing the funds for good.
+``user`` / ``user-*``: The user needs to do some interaction
+for the transaction to proceed.
+
Transaction Type: Withdrawal
----------------------------
@@ -249,7 +252,7 @@ Transaction Type: Withdrawal
* ``[processed-success] => done``
* ``[processed-kyc-required] => pending(kyc)``
* ``[processed-aml-required] => pending(aml)``
- * ``[reserve-expired] => fail``
+ * ``[reserve-expired] => failed(reserve-expired)``
* ``[action:suspend] => suspended(withdrawing-coins)``
* ``pending(kyc)``
@@ -348,7 +351,7 @@ Transaction Type: Payment to Merchant
Let the user accept (or refuse) the payment.
* ``[action:pay-accept] => pending(submit-payment)``
- * ``[action:pay-refuse] => ``aborting(unclaim)`` -- The user explicitly
+ * ``[action:pay-refuse] => ``aborted(refused)`` -- The user explicitly
decided not to proceed (at least not with this wallet).
* ``[expired] => failed(expired)`` -- The offer has expired before the user made any
decision. Note that we should use this transition at
@@ -363,49 +366,41 @@ Transaction Type: Payment to Merchant
Submit coin-by-coin (or in bulk groups) until payment is complete.
- * ``[action:abort] => aborting(refund)`` -- The user explicitly decided to
+ * ``[action:abort] => aborting(pay-incomplete)`` -- 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
+ nevertheless end up in a ``pending(auto-refund)`` state (and subsequently
a ``done`` state) instead!
- * ``[success] => pending(refundable)`` -- Upon receiving confirmation from
+ * ``[success] => pending(auto-refund)`` -- Upon receiving confirmation from
the merchant that the purchase was completed.
- * ``[error(insufficient balance)] => aborting(refresh)`` This transition
+ * ``[error(insufficient balance)] => aborting(pay-incomplete)`` 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)``
+* ``pending(auto-refund)``
- The payment succeed. We remain in this tate as long as an auto-refund-check
+ The payment succeed. We remain in this state as long as an auto-refund-check
is active. If auto refunds are not enabled, we immediately continue to
``done``.
+ * ``[no-auto-refund] => done``
* ``[timeout] => done`` -- This happens when the auto refund set by the
contract expired.
- * ``[long-poll:refund] => aborting(refund)`` -- An auto-refund was detected.
+ * ``[long-poll:refund] => aborting(pay-incomplete)`` -- An auto-refund was detected.
* ``[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)``
-
- The wallet should interact with the merchant to confirm that a refund
- was approved.
+* ``aborting(pay-incomplete)``
- * ``[success] => aborting(refresh)``
- * ``[failure] => aborting(refresh)``: Try refresh anyway.
- * ``[action:force-delete] => deleted``: User may loose money.
+ The wallet should interact with the merchant to request
+ a refund on the incomplete payment.
-* ``aborting(refresh)``
-
- The wallet should interact with the exchange to obtain fresh coins for
- the refunded balance.
-
- * ``[success] => aborted(refunded)``
- * ``[failure] => failed``
- * ``[action:force-delete] => deleted``: User may loose money.
+ * ``[success] => aborted(pay-incomplete)``
+ * ``[already-paid] => done``
+ * ``[action:force-delete] => deleted``: User may lose money.
* ``aborted(refunded)``
@@ -424,6 +419,22 @@ Transaction Type: Payment to Merchant
* ``[repurchase] => pending(repurchase-session-reset)``: Another offer
became pending for this product and we need to update the session so
that the user does not have to buy it again.
+ * ``[check-refunds]` => pending(check-refunds)``: New refunds
+ might be available for this purchase.
+
+* ``pending(check-refunds)``
+
+ New refunds might be available for this purchase.
+ This state must only be entered *after* the payment has successfully
+ completed. It is not relevant for auto-refunds or refunds for incomplete
+ payments.
+
+ * ``[refunds-checked] => done`` --- Refunds were checked, this
+ might create new refund transactions.
+ * ``[action:stop-refund-query] => done`` ---
+ This action would usually only be offered when the state is pending
+ with errors. It stops the refund query, but the payment of course
+ is left intact.
* ``pending(repurchase-session-reset)``
diff --git a/transaction-payment-states.dot b/transaction-payment-states.dot
@@ -4,44 +4,39 @@ digraph G {
pending_pr[label="pending(proposed)", shape="box"];
pending_dp[label="pending(claim-proposal)"];
pending_sp[label="pending(submit-payment)"];
- pending_rf[label="pending(refundable)"];
+ pending_ar[label="pending(auto-refund)"];
pending_re[label="pending(repurchase-session-reset)"];
- aborting_unclaim[label="aborting(unclaim)"];
- aborting_refund[label="aborting(refund)"];
- aborting_refresh[label="aborting(refresh)"];
- aborted_refund[label="aborted(refunded)", shape="box"];
- failed[label="failed", shape="box"];
+ pending_cr[label="pending(check-refunds)"];
+ aborting_pi[label="aborting(payment-incomplete)"];
+ aborted_pi[label="aborted(payment-incomplete)", shape="box"];
+ aborted_refused[label="aborted(refused)", shape="box"];
+ failed_pi[label="failed(payment-incomplete)", shape="box"]
+ failed_ac[label="failed(already-claimed)", shape="box"];
+ failed_ip[label="failed(invalid-proposal)", shape="box"];
done[label="done", shape="box"];
- deleted[label="deleted", shape="box"];
- subgraph {
- rank = same; pending_dp; pending_pr; pending_sp; pending_rf;
- }
-
- initial->pending_dp [color="blue", label="URI trigger"];
- pending_dp->pending_pr;
- pending_re->done;
- pending_dp->deleted [label="repurchase\ndetected"];
- pending_dp->deleted [color="red", label="already\nclaimed"];
- pending_dp->deleted [color="red", label="invalid\nproposal"];
- pending_pr->pending_sp [color="blue", label="pay-accept"];
- pending_pr->aborting_unclaim [color="blue", label="pay-refuse"];
- pending_pr->deleted [label="expired"];
- pending_sp->pending_rf;
- pending_sp->aborting_refund [color="blue", label="abort"]; pending_sp->aborting_refund [color="red", label="insufficient balance"];
- pending_rf->aborting_refund [label="long-poll:refund"];
- aborting_refund->aborting_refresh;
- aborting_refund->deleted [color="blue", label="force-delete"];
- aborting_refund->aborting_refresh [color="red", label="failure"];
- aborting_refresh->failed [color="red", label="failure"];
- aborting_refresh->aborted_refund;
- aborting_refresh->deleted [color="blue", label="force-delete"];
- aborted_refund->deleted [color="blue", label="delete"];
- pending_rf->done [label="timeout"];
- pending_rf->done [color="blue", label="abort"];
- aborting_unclaim->deleted;
- failed->deleted [color="blue", label="delete"];
- done->deleted [color="blue", xlabel="delete"];
- done->pending_re [color="purple", label="repurchase"];
- pending_re->done [color="blue", label="abort"];
+ initial -> pending_dp;
+
+ pending_dp -> failed_ip;
+ pending_dp -> failed_ac;
+ pending_dp -> pending_pr;
+
+ pending_pr -> aborted_refused;
+ pending_pr -> pending_sp;
+
+ pending_sp -> pending_ar;
+ pending_sp -> aborting_pi;
+
+ aborting_pi->done;
+ aborting_pi->aborted_pi;
+ aborting_pi->failed_pi;
+
+ pending_ar -> done;
+
+ done -> pending_cr;
+ done -> pending_re;
+
+ pending_cr -> done;
+
+ pending_re -> done;
}
diff --git a/transaction-withdrawal-states.dot b/transaction-withdrawal-states.dot
@@ -1,18 +1,17 @@
-
digraph G {
- ranksep=1;
- initial_manual[label="", shape="circle"];
- initial_bank[label="", shape="circle"];
+ initial_manual[label="", xlabel="manual" shape="circle"];
+ initial_bank[label="", xlabel="bank-integrated" shape="circle"];
pending_brr[label="pending(bank-register-reserve)"];
pending_bc[label="pending(bank-confirming)"];
pending_ewr[label="pending(exchange-wait-reserve)"];
pending_wc[label="pending(withdrawing-coins)"];
pending_kyc[label="pending(kyc)"];
pending_aml[label="pending(aml)"];
- done[label="done", shape="doubleoctagon"];
+ done[label="done", shape="box"];
aborting_bank[label="aborting(bank)"];
- aborted[label="aborted", shape="doubleoctagon"];
- failed[label="failed", shape="doubleoctagon"];
+ aborted_bank[label="aborted(bank)", shape="box"];
+ failed_expired[label="failed(reserve-expired)", shape="box"];
+ failed_bank[label="failed(bank)", shape="box"];
//deleted[label="deleted", shape="box"];
suspended_ewr[label="suspended(exchange-wait-reserve)", shape="box"];
// Boring suspended states
@@ -20,31 +19,31 @@ digraph G {
// suspended_kyc[label="suspended(kyc)", shape="box"];
// suspended_wc[label="suspended(withdrawing-coins)", shape="box"];
- initial_bank->pending_brr [color="blue", label="bank integrated withdrawal"];
- initial_manual->pending_ewr [color="blue", label="manual withdrawal"];
+ initial_bank->pending_brr;
+ initial_manual->pending_ewr;
pending_brr->pending_bc;
- pending_brr->aborting_bank [color="blue", fontcolor="blue", label="abort"];
- pending_brr->failed [color="red", label="error"];
+ pending_brr->aborting_bank;
+ pending_brr->failed_bank;
- pending_bc->pending_ewr [label="bank-poll:\napproved"];
+ pending_bc->pending_ewr;
//pending_bc->pending_wc [xlabel="exchange-poll:\nreserve ready",style="dotted"];
- pending_bc->aborting_bank [color="blue", label="abort", fontcolor=blue]
- pending_bc->failed;
+ pending_bc->aborting_bank;
+ pending_bc->aborted_bank;
+ pending_bc->failed_bank;
- pending_ewr->pending_wc [color=purple];
+ pending_ewr->pending_wc;
pending_wc->pending_kyc;
pending_wc->pending_aml;
- pending_kyc->pending_wc [color="purple"];
- pending_aml->pending_wc [color="purple"];
+ pending_kyc->pending_wc;
+ pending_aml->pending_wc;
- pending_wc->failed [label="expired"];
+ pending_wc->failed_expired;
- aborting_bank->suspended_ewr [color="red", label="already-confirmed"];
- aborting_bank->aborted;
- aborting_bank->failed [color="red"];
+ aborting_bank->suspended_ewr;
+ aborting_bank->aborted_bank;
// Interesting suspended states
- pending_ewr->suspended_ewr [dir=both, fontcolor=blue, color="blue", label="suspend/resume"];
+ pending_ewr->suspended_ewr [dir=both];
// Boring suspended states
// pending_kyc->suspended_kyc [color="blue", label="suspend"];