diff options
author | Özgür Kesim <oec-taler@kesim.org> | 2023-05-12 13:40:22 +0200 |
---|---|---|
committer | Özgür Kesim <oec-taler@kesim.org> | 2023-05-12 13:40:22 +0200 |
commit | 4833234df63d7da774299b336adb925e700bd4b4 (patch) | |
tree | abb478b860c2d3f292ded9364300ce73b1d60d11 /doc | |
parent | 9130cda9e775131d3ced613b7f238a4c9e43ad5a (diff) | |
parent | ff1a28319fe31741958a0b1cfa761fd44878db45 (diff) | |
download | exchange-4833234df63d7da774299b336adb925e700bd4b4.tar.xz |
Merge branch 'master' into age-withdraw
Diffstat (limited to 'doc')
-rw-r--r-- | doc/doxygen/taler.doxy | 56 | ||||
-rw-r--r-- | doc/flows/Makefile | 3 | ||||
-rw-r--r-- | doc/flows/fees-coins.tex | 39 | ||||
-rw-r--r-- | doc/flows/fees-wire.tex | 30 | ||||
-rw-r--r-- | doc/flows/int-deposit.tex | 52 | ||||
-rw-r--r-- | doc/flows/int-pay.tex | 58 | ||||
-rw-r--r-- | doc/flows/int-pull.tex | 55 | ||||
-rw-r--r-- | doc/flows/int-push.tex | 47 | ||||
-rw-r--r-- | doc/flows/int-refund.tex | 39 | ||||
-rw-r--r-- | doc/flows/int-shutdown.tex | 48 | ||||
-rw-r--r-- | doc/flows/int-withdraw.tex | 49 | ||||
-rw-r--r-- | doc/flows/kyc-balance.tex | 57 | ||||
-rw-r--r-- | doc/flows/kyc-deposit.tex | 71 | ||||
-rw-r--r-- | doc/flows/kyc-pull.tex | 78 | ||||
-rw-r--r-- | doc/flows/kyc-push.tex | 79 | ||||
-rw-r--r-- | doc/flows/kyc-withdraw.tex | 45 | ||||
-rw-r--r-- | doc/flows/main.tex | 159 | ||||
-rw-r--r-- | doc/flows/proc-aml.tex | 47 | ||||
-rw-r--r-- | doc/flows/proc-domestic.tex | 66 | ||||
-rw-r--r-- | doc/flows/proc-kyc.tex | 88 |
20 files changed, 1115 insertions, 51 deletions
diff --git a/doc/doxygen/taler.doxy b/doc/doxygen/taler.doxy index 6eeb514a5..b1c8637a2 100644 --- a/doc/doxygen/taler.doxy +++ b/doc/doxygen/taler.doxy @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "GNU Taler: Exchange" -PROJECT_NUMBER = 0.8.3 +PROJECT_NUMBER = 0.9.3 PROJECT_LOGO = logo.svg OUTPUT_DIRECTORY = . CREATE_SUBDIRS = YES @@ -97,59 +97,11 @@ WARN_LOGFILE = INPUT = ../../src INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.vhd \ - *.vhdl \ - *.C \ - *.CC \ - *.C++ \ - *.II \ - *.I++ \ - *.H \ - *.HH \ - *.H++ \ - *.CS \ - *.PHP \ - *.PHP3 \ - *.M \ - *.MM \ - *.PY \ - *.F90 \ - *.F \ - *.VHD \ - *.VHDL + *.h RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = */test_* \ - */.svn/* \ */.git/* \ */perf_* .* \ .* \ @@ -191,7 +143,9 @@ HTML_STYLESHEET = GENERATE_HTMLHELP = NO GENERATE_DOCSET = NO DOCSET_FEEDNAME = "GNU Taler Source Documentation" -DOCSET_BUNDLE_ID = net.taler +DOCSET_BUNDLE_ID = net.taler.exchange +DOCSET_PUBLISHER_ID = net.taler +DOCSET_PUBLISHER_NAME = Taler Systems SA HTML_DYNAMIC_SECTIONS = NO CHM_FILE = HHC_LOCATION = diff --git a/doc/flows/Makefile b/doc/flows/Makefile new file mode 100644 index 000000000..e6af0897c --- /dev/null +++ b/doc/flows/Makefile @@ -0,0 +1,3 @@ +all: + pdflatex main.tex + pdflatex main.tex diff --git a/doc/flows/fees-coins.tex b/doc/flows/fees-coins.tex new file mode 100644 index 000000000..c24f19a28 --- /dev/null +++ b/doc/flows/fees-coins.tex @@ -0,0 +1,39 @@ +\section{Fees per coin} \label{sec:fees:coin} + +Payments with Taler are always made using coins. Each coin has a specific +denomination, and an exchange will issue coins in different denominations (in +the same currency). The fees per coin depend on the operation and the +denomination. + +The primary fee to be paid is a {\bf deposit} fee that is +charged whenever a coin is fully or partially deposited +into a bank account or another wallet. + +A secondary fee to be paid is a {\bf change} fee that is +charged whenever a coin partially spent and change must +be rendered. + +Coins also have an {\bf expiration} date of approximately {\bf one year}. +After the expiration date, coins become worthless. Wallets that are online +{\bf three months} {\em before} a coin expires will automatically trade any +such coins for one or more fresh coins with a later expiration date. This +process is also subject to the {\bf change} fee. + + +\begin{table}[h!] + \caption{Fees per coin. Coin denomination values are given in units of CHF 0.01.} + \label{table:fees:coins} + \begin{center} + \begin{tabular}{l|c|r} + {\bf Denomination} & {\bf Fee type} & {\bf Amount} \\ \hline \hline + $2^{-4}-2^{ 0}$ & deposit & {\em CHF 0.00125} \\ + $2^{-4}-2^{ 0}$ & change & {\em CHF 0.00125} \\ + $2^{ 0}-2^{ 3}$ & deposit & {\em CHF 0.00250} \\ + $2^{ 0}-2^{ 3}$ & change & {\em CHF 0.00125} \\ + $2^{ 4}-2^{ 8}$ & deposit & {\em CHF 0.005} \\ + $2^{ 4}-2^{ 8}$ & change & {\em CHF 0.00125} \\ + $2^{ 8}-2^{12}$ & deposit & {\em CHF 0.01} \\ + $2^{ 8}-2^{12}$ & change & {\em CHF 0.00125} \\ + \end{tabular} + \end{center} +\end{table} diff --git a/doc/flows/fees-wire.tex b/doc/flows/fees-wire.tex new file mode 100644 index 000000000..214a69021 --- /dev/null +++ b/doc/flows/fees-wire.tex @@ -0,0 +1,30 @@ +\section{Fees per wire} \label{sec:fees:wire} + +Wire fees apply whenever an exchange needs to initiate a wire transfer to +another bank account. Wire fees do not apply to every individual payment to a +merchant, as merchants can choose to {\em aggregate} multiple micropayments +into one large payment on the wire. Wire fees also do not apply to +wallet-to-wallet payments within the Taler system. + +A {\bf wire} fee is applied when a merchant receives +an aggregated payment into their bank account. + +A {\bf closing} fee is applied when a wallet fails to +withdraw coins and money has to be sent back to the +originating bank account. + +\begin{table}[h!] + \caption{Table with wire fees. Wire fees are set annually.} + \label{table:fees:wire} + \begin{center} + \begin{tabular}{l|c|r} + {\bf Year} & {\bf Fee type} & {\bf Amount} \\ \hline \hline + 2023 & wire & {\em CHF 0.05} \\ + 2023 & closing & {\em CHF 0.10} \\ + 2024 & wire & {\em CHF 0.05} \\ + 2024 & closing & {\em CHF 0.10} \\ + 2025 & wire & {\em CHF 0.05} \\ + 2025 & closing & {\em CHF 0.10} \\ + \end{tabular} + \end{center} +\end{table} diff --git a/doc/flows/int-deposit.tex b/doc/flows/int-deposit.tex new file mode 100644 index 000000000..4b1f657ba --- /dev/null +++ b/doc/flows/int-deposit.tex @@ -0,0 +1,52 @@ +\section{Deposit} + + + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer wallet \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{bank}{\shortstack{Customer bank \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] {Checking \\ Accounts}; + \end{tikzpicture} + }} + \postlevel + \begin{callself}{wallet}{Review deposit fees}{} + \end{callself} + \mess[0]{wallet}{Deposit {(Coins)}}{exchange} + \begin{sdblock}{Acceptable account?}{} + \mess[0]{exchange}{{Refuse deposit}}{wallet} + \end{sdblock} + \begin{sdblock}{KYC/AML required?}{} + \begin{callself}{exchange}{Figures~\ref{fig:proc:kyc}, \ref{fig:proc:aml}}{} + \end{callself} + \end{sdblock} +% \prelevel +% \prelevel +% \begin{sdblock}{User abort?}{} +% \mess[0]{wallet}{{Request abort}}{exchange} +% \mess[0]{exchange}{{Abort confirmation}}{wallet} +% \end{sdblock} + \mess[0]{exchange}{{Initiate transfer}}{bank} + +\end{sequencediagram} + \caption{Deposit interactions between customer, Taler exchange (payment + service provider) and customer's bank.} + \label{fig:int:deposit} +\end{figure} + +We do {\bf not} permit the customer to regain control over their funds {\em + unless} they pass the KYC/AML checks. The technical reason is simply that +the KYC/AML checks happen {\em after} the aggregation logic and at this point +refunds are no longer permitted. From a compliance perspective, this also +prevents malicious customers from risk-free probing of the system. diff --git a/doc/flows/int-pay.tex b/doc/flows/int-pay.tex new file mode 100644 index 000000000..d2f0fb585 --- /dev/null +++ b/doc/flows/int-pay.tex @@ -0,0 +1,58 @@ +\section{Pay} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer wallet \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \newinst[1]{merchant}{\shortstack{Merchant \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[1]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[1]{bank}{\shortstack{Merchant bank \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] {Commercial \\ Accounts}; + \end{tikzpicture} + }} + \postlevel + \mess[0]{wallet}{Browse catalog}{merchant} + \mess[0]{merchant}{Commercial offer}{wallet} + \begin{callself}{wallet}{Review offer}{} + \end{callself} + \mess[0]{wallet}{Send payment {(Coins)}}{merchant} + \mess[0]{merchant}{Deposit {(Coins)}}{exchange} + \begin{sdblock}{Acceptable account?}{} + \mess[0]{exchange}{{Refuse deposit}}{merchant} + \mess[0]{merchant}{{Refund purchase}}{wallet} + \end{sdblock} + \mess[0]{exchange}{{Confirm deposit}}{merchant} + \mess[0]{merchant}{Fulfill order}{wallet} + \begin{callself}{exchange}{Aggregate transactions}{} + \end{callself} + \begin{sdblock}{KYC/AML required?}{} + \begin{callself}{exchange}{Figures~\ref{fig:proc:kyc}, \ref{fig:proc:aml}}{} + \end{callself} + \end{sdblock} + \mess[0]{exchange}{{Initiate transfer}}{bank} + \end{sequencediagram} + \caption{Deposit interactions between customer, merchant, + Taler exchange (payment service provider) and merchant bank.} + \label{fig:int:pay} +\end{figure} + +{\bf Internal note:} The exchange refusing a deposit immediately based on +unaccaptable merchant accounts may not be fully implemented (this is a very +recent feature, after all); especially the merchant then automatically +refunding the purchase to the customer is certainly missing. However, +the entire situation only arises when a merchant is incorrectly configured +and in violation of the terms of service. diff --git a/doc/flows/int-pull.tex b/doc/flows/int-pull.tex new file mode 100644 index 000000000..8c9b66b1b --- /dev/null +++ b/doc/flows/int-pull.tex @@ -0,0 +1,55 @@ +\section{Pull payment (aka invoicing)} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{payer}{\shortstack{Payer \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] {Pre-funded \\ Wallet}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{payee}{\shortstack{Payee \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \postlevel + \begin{callself}{payee}{Review pull payment fees}{} + \end{callself} + \mess[0]{payee}{{Create invoice (Wallet ID)}}{exchange} + + \mess[0]{exchange}{{Invoice ready}}{payee} + \mess[0]{payee}{{Send invoice (e.g. via QR code)}}{payer} + + \begin{callself}{payer}{Review invoice}{} + \end{callself} + \mess[0]{payer}{{Make payment (Coins)}}{exchange} + + \begin{sdblock}{Domestic wallet?}{} + \begin{callself}{exchange}{Figure~\ref{fig:proc:domestic}}{} + \end{callself} + \end{sdblock} + \begin{sdblock}{KYC/AML required?}{} + \begin{callself}{exchange}{Figures~\ref{fig:proc:kyc}, \ref{fig:proc:aml}}{} + \end{callself} + \end{sdblock} + + \mess[0]{exchange}{{Distribute digital cash}}{payee} + +\end{sequencediagram} + \caption{Interactions between wallets and Taler exchange + in a pull payment.} + \label{fig:int:pull} +\end{figure} + +We do {\bf not} permit the payer to regain control over their funds, once the +payment was made they are locked {\em until} the payee passes the KYC/AML +checks. We only do the AML/KYC process once the funds are locked at the +exchange. This ensures we know the actual transacted amounts (which may be +lower than the total amounts requested) and prevents risk-free probing +attacks. diff --git a/doc/flows/int-push.tex b/doc/flows/int-push.tex new file mode 100644 index 000000000..fd49e8d40 --- /dev/null +++ b/doc/flows/int-push.tex @@ -0,0 +1,47 @@ +\section{Push payment} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{payer}{\shortstack{Payer \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] {Pre-funded \\ Wallet}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{payee}{\shortstack{Payee \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \postlevel + \begin{callself}{payer}{Review push payment fees}{} + \end{callself} + \mess[0]{payer}{{Push funds (Coins)}}{exchange} + \mess[0]{payer}{{Offer payment (e.g. via QR code)}}{payee} + \begin{callself}{payee}{Review payment offer}{} + \end{callself} + \mess[0]{payee}{{Request funds (Wallet ID)}}{exchange} + \begin{sdblock}{Domestic wallet?}{} + \begin{callself}{exchange}{Figure~\ref{fig:proc:domestic}}{} + \end{callself} + \end{sdblock} + \begin{sdblock}{KYC/AML required?}{} + \begin{callself}{exchange}{Figures~\ref{fig:proc:kyc}, \ref{fig:proc:aml}}{} + \end{callself} + \end{sdblock} + \mess[0]{exchange}{{Distribute digital cash}}{payee} +% \postlevel + \begin{sdblock}{Payment offer expired?}{} + \mess[0]{exchange}{{Return funds}}{payer} + \end{sdblock} + +\end{sequencediagram} + \caption{Interactions between wallets and Taler exchange + in a push payment.} + \label{fig:int:push} +\end{figure} diff --git a/doc/flows/int-refund.tex b/doc/flows/int-refund.tex new file mode 100644 index 000000000..3f11e5600 --- /dev/null +++ b/doc/flows/int-refund.tex @@ -0,0 +1,39 @@ +\section{Refund} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer wallet \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \newinst[2]{merchant}{\shortstack{Merchant \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \postlevel + \begin{callself}{merchant}{Initiate refund}{} + \end{callself} + \mess[0]{merchant}{{Refund offer (QR code)}}{wallet} + \mess[0]{wallet}{Download refund}{merchant} + \mess[0]{merchant}{Approve refund}{exchange} + \mess[0]{exchange}{Confirm refund}{merchant} + \mess[0]{merchant}{Return refund confirmation}{wallet} + \end{sequencediagram} + \caption{Refund processing when a merchant is unable to fulfill + a contract. Refunds must happen {\em before} the + exchange has aggregated the original transaction for + a bank transfer to the merchant. Furthermore, refunds + can only go to the customer who made the original payment + and the refund cannot exceed the amount of the original + payment.} + \label{fig:int:refund} +\end{figure} diff --git a/doc/flows/int-shutdown.tex b/doc/flows/int-shutdown.tex new file mode 100644 index 000000000..e8ee6feed --- /dev/null +++ b/doc/flows/int-shutdown.tex @@ -0,0 +1,48 @@ +\section{Shutdown} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer wallet \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{bank}{\shortstack{Customer bank \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] {Checking \\ Accounts}; + \end{tikzpicture} + }} + \postlevel + + \begin{callself}{exchange}{Operator initiates shutdown}{} + \end{callself} + \mess[0]{exchange}{{Shutdown alert}}{wallet} + \begin{sdblock}{Bank account known?}{} + \begin{callself}{wallet}{Designate bank account}{} + \end{callself} + \end{sdblock} + \mess[0]{wallet}{{Deposit (Coins)}}{exchange} + \begin{sdblock}{Acceptable account?}{} + \mess[0]{exchange}{{Refuse deposit}}{wallet} + \end{sdblock} + \begin{sdblock}{KYC/AML required?}{} + \begin{callself}{exchange}{Figures~\ref{fig:proc:kyc}, \ref{fig:proc:aml}}{} + \end{callself} + \end{sdblock} + \mess[0]{exchange}{{Initiate transfer}}{bank} +\end{sequencediagram} + \caption{Shutdown interactions between customer, Taler exchange (payment + service provider) and bank.} + \label{fig:int:shutdown} +\end{figure} + +KYC/AML requirements are relaxed in cases where the customer is able to +cryptographically demonstrate that they previously withdrew these coins from +the designated checking account. Thus, KYC/AML checks here primarily still +apply if the customer received the funds via P2P transfers from other wallets. diff --git a/doc/flows/int-withdraw.tex b/doc/flows/int-withdraw.tex new file mode 100644 index 000000000..9b044df67 --- /dev/null +++ b/doc/flows/int-withdraw.tex @@ -0,0 +1,49 @@ +\section{Withdraw} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer wallet \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{bank}{\shortstack{Customer bank \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] {Checking \\ Accounts}; + \end{tikzpicture} + }} + \postlevel + \mess[0]{wallet}{Withdraw {(Amount)}}{exchange} + \mess[0]{exchange}{{Configuration (ToS, Fees)}}{wallet} + \begin{sdblock}{once}{} + \begin{callself}{wallet}{Accept ToS}{} + \end{callself} + \end{sdblock} + \begin{callself}{wallet}{Review withdraw fees}{} + \end{callself} + \mess[0]{wallet}{{Initiate transfer (Amount, Credit account, Wallet ID)}}{bank} + \mess[0]{bank}{{Credit (Wallet ID)}}{exchange} + + \begin{sdblock}{Acceptable transfer?}{} + \mess[0]{exchange}{{Bounce funds}}{bank} + \end{sdblock} + \postlevel + \mess[0]{exchange}{Confirm wire transfer}{wallet} + \mess[0]{wallet}{Request digital cash}{exchange} + \mess[0]{exchange}{Distribute digital cash}{wallet} + \postlevel + \begin{sdblock}{Withdraw period expired?}{} + \mess[0]{exchange}{{Return remaining funds}}{bank} + \end{sdblock} +\end{sequencediagram} + \caption{Withdraw interactions between customer, Taler exchange (payment + service provider) and bank. The amount of digital cash distributed is + subject to limits per origin account (see Figure~\ref{fig:kyc:withdraw}).} + \label{fig:int:withdraw} +\end{figure} diff --git a/doc/flows/kyc-balance.tex b/doc/flows/kyc-balance.tex new file mode 100644 index 000000000..1192021b3 --- /dev/null +++ b/doc/flows/kyc-balance.tex @@ -0,0 +1,57 @@ +\section{KYC: Balance} + +Note: this process is not implemented and would require non-trivial extra work +if required. + +\begin{figure}[h!] + \begin{center} +\begin{tikzpicture}[node distance=1cm,font=\sffamily, + start/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=yellow!30}, + end/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30}, + process/.style={rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + failed/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + io/.style={trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30}, + decision/.style={diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30}, + arr/.style={very thick,-latex}, + every edge quotes/.style = {auto, font=\footnotesize, sloped} + ] + \node (start) [start] {Start}; + \node (balance) [decision,below=of start,text width=3cm] {Transaction leaves wallet balance below AML threshold?}; + \node (registered) [decision,below=of balance,text width=3cm] {Wallet has been subject to KYC?}; + \node (kyc) [process, below=of registered] {KYC process}; + \node (aml) [process, left=of kyc] {AML process}; + \node (allow) [end, right=of balance] {Allow}; + \node (deny) [failed, right=of registered] {Deny}; + \draw[arr] (start) -> (balance) {}; + \draw[arr] (balance) -> (registered); + \draw (balance) edge["No"] (registered); + \draw[arr] (balance) -> (allow); + \draw (balance) edge["Yes"] (allow); + + \draw[arr] (registered) -> (kyc); + \draw (registered) edge["No"] (kyc); + \draw[arr] (registered) -> (deny); + \draw (registered) edge["Yes"] (deny); + + \draw[arr] (kyc) -> (deny); + \draw (kyc) edge["Failed"] (deny); + \draw[arr] (kyc) -> (aml); + \draw (kyc) edge["Ok"] (aml); + + \draw[arr] (aml) -> (balance.west); + \draw (aml) edge["New threshold"] (balance.west); +\end{tikzpicture} + \end{center} + \caption{Regulatory process when a wallet exceeds its AML threshold. + When the transfer is denied the transaction (withdraw, P2P transfer) + is refused by the wallet.} +\end{figure} + + +\begin{table}[h!] + \caption{Settings for the balance trigger} + \begin{tabular}{l|l|r} + {\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline + Default AML threshold & Amount & {\em 1000 CHF} \\ + \end{tabular} +\end{table} diff --git a/doc/flows/kyc-deposit.tex b/doc/flows/kyc-deposit.tex new file mode 100644 index 000000000..2423235ab --- /dev/null +++ b/doc/flows/kyc-deposit.tex @@ -0,0 +1,71 @@ +\section{KYC: Deposit} + +\begin{figure}[h!] + \begin{center} +\begin{tikzpicture}[node distance=1cm,font=\sffamily, + start/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=yellow!30}, + end/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30}, + process/.style={rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + failed/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + io/.style={trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30}, + decision/.style={diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30}, + arr/.style={very thick,-latex}, + every edge quotes/.style = {auto, font=\footnotesize, sloped} + ] + \node (start) [start] {Start}; + \node (country) [decision,below=of start,text width=2.5cm] {Target account in allowed country?}; + \node (amount) [decision, below=of country,text width=2.5cm] {Target account received less than KYC threshold?}; + \node (kyc) [process, right=of amount] {KYC process}; + \node (high) [decision, below=of amount,text width=2.5cm] {Target account received more than its AML threshold?}; + \node (aml) [process, right=of high] {AML process}; + \node (dummy) [below right=of aml] {}; + \node (allow) [end, below right=of dummy] {Allow}; + \node (deny) [failed, right=of kyc] {Deny}; + \draw[arr] (start) -> (country) {}; + + \draw[arr] (country) -> (amount); + \draw (country) edge["Yes"] (amount); + + \draw[arr] (country.east) -> (deny); + \draw (country.east) edge["No"] (deny); + + \draw[arr] (amount) -> (high); + \draw (amount) edge["Yes"] (high); + + \draw[arr] (amount.east) -> (kyc); + \draw (amount.east) edge["No"] (kyc); + + \draw[arr] (kyc) -> (deny); + \draw (kyc) edge["Failed"] (deny); + + \draw[arr] (kyc) -> (high); + \draw (kyc) edge["Succeeded"] (high); + + \draw[arr] (high.south) -> (allow); + \draw (high.south) edge["Yes"] (allow); + + \draw[arr] (high.east) -> (aml); + \draw (high.east) edge["No"] (aml); + + \draw[arr] (aml) -> (deny); + \draw (aml) edge["Violation"] (deny); + + \draw[arr] (aml) -> (allow); + \draw (aml) edge["Ok"] (allow); +\end{tikzpicture} + \end{center} + \caption{Regulatory process when depositing digital cash into a bank + account. When the transfer is denied, the money is returned to the + originating wallet.} +\end{figure} + + +\begin{table}[h!] + \caption{Settings for the deposit trigger} + \begin{tabular}{l|l|r} + {\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline + Allowed bank accounts & RFC 8905 RegEx & {\em CH*} \\ \hline + KYC deposit threshold & Amount & {\em 1000 CHF} \\ + Default AML deposit threshold & Amount & {\em 2500 CHF} \\ + \end{tabular} +\end{table} diff --git a/doc/flows/kyc-pull.tex b/doc/flows/kyc-pull.tex new file mode 100644 index 000000000..b7cd34477 --- /dev/null +++ b/doc/flows/kyc-pull.tex @@ -0,0 +1,78 @@ +\section{KYC/AML: Pull Payment} + +\begin{figure}[h!] + \begin{center} +\begin{tikzpicture}[node distance=0.9cm,font=\sffamily, + start/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=yellow!30}, + end/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30}, + process/.style={rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + failed/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + io/.style={trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30}, + decision/.style={diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30}, + arr/.style={very thick,-latex}, + every edge quotes/.style = {auto, font=\footnotesize, sloped} + ] + \node (start) [start] {Start}; + \node (wallet) [decision,below=of start,text width=2.5cm] {Wallet linked to (domestic) phone number?}; + \node (domestic) [process, right=of wallet] {Validate phone number}; + \node (amount) [decision, below=of wallet,text width=2.5cm] {Wallet received less than KYC threshold from other wallets?}; + \node (kyc) [process, right=of amount] {KYC process}; + \node (high) [decision, below=of amount,text width=2.5cm] {Wallet received more than its AML threshold?}; + \node (aml) [process, right=of high] {AML process}; + \node (dummy) [below right=of aml] {}; + \node (allow) [end, below right=of dummy] {Allow invoicing}; + \node (deny) [failed, right=of kyc] {Deny}; + \draw[arr] (start) -> (wallet) {}; + + \draw[arr] (wallet) -> (amount); + \draw (wallet) edge["Yes"] (amount); + + \draw[arr] (wallet.east) -> (domestic); + \draw (wallet.east) edge["No"] (domestic); + + \draw[arr] (domestic) -> (amount); + \draw (domestic) edge["Confirmed"] (amount); + + \draw[arr] (domestic) -> (deny); + \draw (domestic) edge["Failed"] (deny); + + \draw[arr] (amount) -> (high); + \draw (amount) edge["Yes"] (high); + + \draw[arr] (amount.east) -> (kyc); + \draw (amount.east) edge["No"] (kyc); + + \draw[arr] (kyc) -> (deny); + \draw (kyc) edge["Failed"] (deny); + + \draw[arr] (kyc) -> (high); + \draw (kyc) edge["Succeeded"] (high); + + \draw[arr] (high.south) -> (allow); + \draw (high.south) edge["Yes"] (allow); + + \draw[arr] (high.east) -> (aml); + \draw (high.east) edge["No"] (aml); + + \draw[arr] (aml) -> (deny); + \draw (aml) edge["Violation"] (deny); + + \draw[arr] (aml) -> (allow); + \draw (aml) edge["Ok"] (allow); +\end{tikzpicture} + \end{center} + \caption{Regulatory process when receiving payments from another wallet. + The threshold depends on the risk profile from the KYC process. + When invoicing is denied the wallet cannot generate the invoice.} +\end{figure} + + +\begin{table}[h!] + \caption{Settings for the pull payment trigger} + \begin{tabular}{l|l|r} + {\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline + Permitted phone numbers & Dialing prefix & {\em +41} \\ + P2P KYC threshold & Amount & {\em 100 CHF} \\ + Default P2P AML threshold & Amount & {\em 1000 CHF} \\ + \end{tabular} +\end{table} diff --git a/doc/flows/kyc-push.tex b/doc/flows/kyc-push.tex new file mode 100644 index 000000000..6d25ac7ef --- /dev/null +++ b/doc/flows/kyc-push.tex @@ -0,0 +1,79 @@ +\section{KYC/AML: Push Payment} + +\begin{figure}[h!] + \begin{center} +\begin{tikzpicture}[node distance=0.9cm,font=\sffamily, + start/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=yellow!30}, + end/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30}, + process/.style={rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + failed/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + io/.style={trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30}, + decision/.style={diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30}, + arr/.style={very thick,-latex}, + every edge quotes/.style = {auto, font=\footnotesize, sloped} + ] + \node (start) [start] {Start}; + \node (wallet) [decision,below=of start,text width=2.5cm] {Wallet linked to (domestic) phone number?}; + \node (domestic) [process, right=of wallet] {Validate phone number}; + \node (amount) [decision, below=of wallet,text width=2.5cm] {Wallet received less than KYC threshold from other wallets?}; + \node (kyc) [process, right=of amount] {KYC process}; + \node (high) [decision, below=of amount,text width=2.5cm] {Wallet received more than its AML threshold?}; + \node (aml) [process, right=of high] {AML process}; + \node (dummy) [below right=of aml] {}; + \node (allow) [end, below right=of dummy] {Allow}; + \node (deny) [failed, right=of kyc] {Deny}; + \draw[arr] (start) -> (wallet) {}; + + \draw[arr] (wallet) -> (amount); + \draw (wallet) edge["Yes"] (amount); + + \draw[arr] (wallet.east) -> (domestic); + \draw (wallet.east) edge["No"] (domestic); + + \draw[arr] (domestic) -> (amount); + \draw (domestic) edge["Confirmed"] (amount); + + \draw[arr] (domestic) -> (deny); + \draw (domestic) edge["Failed"] (deny); + + \draw[arr] (amount) -> (high); + \draw (amount) edge["Yes"] (high); + + \draw[arr] (amount.east) -> (kyc); + \draw (amount.east) edge["No"] (kyc); + + \draw[arr] (kyc) -> (deny); + \draw (kyc) edge["Failed"] (deny); + + \draw[arr] (kyc) -> (high); + \draw (kyc) edge["Succeeded"] (high); + + \draw[arr] (high.south) -> (allow); + \draw (high.south) edge["Yes"] (allow); + + \draw[arr] (high.east) -> (aml); + \draw (high.east) edge["No"] (aml); + + \draw[arr] (aml) -> (deny); + \draw (aml) edge["Violation"] (deny); + + \draw[arr] (aml) -> (allow); + \draw (aml) edge["Ok"] (allow); +\end{tikzpicture} + \end{center} + \caption{Regulatory process when receiving payments from another wallet. + The threshold depends on the risk profile from the KYC process. + When the transfer is denied the money is (eventually) returned to + the originating wallet.} +\end{figure} + + +\begin{table}[h!] + \caption{Settings for the push payment trigger} + \begin{tabular}{l|l|r} + {\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline + Permitted phone numbers & Dialing prefix & {\em +41} \\ + P2P KYC threshold & Amount & {\em 100 CHF} \\ + Default P2P AML threshold & Amount & {\em 1000 CHF} \\ + \end{tabular} +\end{table} diff --git a/doc/flows/kyc-withdraw.tex b/doc/flows/kyc-withdraw.tex new file mode 100644 index 000000000..ecdc9a399 --- /dev/null +++ b/doc/flows/kyc-withdraw.tex @@ -0,0 +1,45 @@ +\section{KYC: Withdraw} + +\begin{figure}[h!] + \begin{center} +\begin{tikzpicture}[node distance=1cm,font=\sffamily, + start/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=yellow!30}, + end/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30}, + process/.style={rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + failed/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + io/.style={trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30}, + decision/.style={diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30}, + arr/.style={very thick,-latex}, + every edge quotes/.style = {auto, font=\footnotesize, sloped} + ] + \node (start) [start] {Start}; + \node (country) [decision,below=of start,text width=3cm] {Wire transfer originates from allowed country?}; + \node (amount) [decision, below=of country,text width=3cm] {Transferred less than maximum amount from origin account over last month?}; + \node (allow) [end, below=of amount] {Allow}; + \node (deny) [failed, right=of allow] {Deny}; + \draw[arr] (start) -> (country) {}; + \draw[arr] (country) -> (amount); + \draw (country) edge["Yes"] (amount); + \draw[arr] (country.east) -> (deny); + \draw (country.east) edge["No"] (deny); + \draw[arr] (amount) -> (allow); + \draw (amount) edge["Yes"] (allow); + \draw[arr] (amount.east) -> (deny); + \draw (amount.east) edge["No"] (deny); +\end{tikzpicture} + \end{center} + \caption{Regulatory process when withdrawing digital cash from a + bank account. + When the transfer is denied the money is (eventually) returned to + the originating bank account.} + \label{fig:kyc:withdraw} +\end{figure} + +\begin{table}[h!] + \caption{Settings for the withdraw trigger} + \begin{tabular}{l|l|r} + {\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline + Allowed bank accounts & RFC 8905 RegEx & {\em CH*} \\ \hline + Monthly withdraw maximum & Amount & {\em 1000 CHF} \\ + \end{tabular} +\end{table} diff --git a/doc/flows/main.tex b/doc/flows/main.tex new file mode 100644 index 000000000..c2aee65ac --- /dev/null +++ b/doc/flows/main.tex @@ -0,0 +1,159 @@ +\documentclass[10pt,a4paper,oneside]{book} +\usepackage[utf8]{inputenc} +\usepackage{url} +\usepackage{graphicx} +\usepackage{hyperref} +\usepackage{qrcode} +\usepackage{pgf-umlsd} +\usepackage{tikz} +\usetikzlibrary{shapes,arrows} +\usetikzlibrary{positioning} +\usetikzlibrary{calc} +\usetikzlibrary{quotes} +\author{Christian Grothoff} +\title{Flows in the GNU Taler System} + +\begin{document} + +\tableofcontents + +\chapter{Interactions} \label{chap:interactions} + +This chapter introduces the main payment interactions in the GNU Taler payment +system. For each interaction, we introduce the parties involved and in which +order they interact and how. In each interaction it is possible that the +Taler exchange needs to trigger a compliance process. These regulatory +riggers are described in more detail in Chapter~\ref{chap:triggers}. + +The main interactions of the system are: + +\begin{description} + \item[withdraw] a customer withdraws digital cash to their wallet + \item[deposit] a customer returns digital cash into their bank account + \item[pay] a customer pays into bank account of a merchant + \item[refund] a merchant decides to return funds to a customer + \item[push] a customer sends a payment to another wallet + \item[pull] a customer requests a payment from another wallet (effectively sending an invoice) + \item[shutdown] the Taler payment system operator informs the customers that the system is being shut down for good +\end{description} + +Taler has no accounts (this is digital cash) and thus there is no ``opening'' +or ``closing'' of accounts. The equivalent of ``opening'' an account is thus +to withdraw digital cash. The equivalent of ``closing'' an account is to +either (1) deposit the funds explicitly into a bank account, or (2) the coins +will expire if the wallet was lost (including long-term offline or +uninstalled). Finally, if a wallet remains (occasionally) online but a user +does simply not spend the coins will (3) diminish in value from the change +fees (see Section~\ref{sec:fees:coin}) that apply to prevent the coins from +expiring outright. + +The following sections describe the respective processes for each of these +interactions. + +\include{int-withdraw} +\include{int-deposit} +\include{int-pay} +\include{int-refund} +\include{int-push} +\include{int-pull} +\include{int-shutdown} + + +\chapter{Regulatory Triggers} \label{chap:triggers} + +In this chapter we show decision diagrams for regulatory processes of the +various core operations of the GNU Taler payment system. In each case, the +{\bf start} state refers to one of the interactions described in the previous +chapter. The payment system will then use the process to arrive at an {\bf + allow} decision which permits the transaction to go through, or at a {\bf + deny} decision which ensures that the funds are not moved. + +The specific {\em decisions} (in green) depend on the risk profile and the +regulatory environment. The tables in each section list the specific values +that are to be configured. + +There are five types if interactions that can trigger regulatory processes: + +\begin{description} + \item[withdraw] a customer withdraws digital cash from their {\bf bank account} + \item[deposit] a merchant's {\bf bank account} is designated to receive a payment in digital cash + \item[push] a {\bf wallet} accepts a payment from another wallet + \item[pull] a {\bf wallet} requests a payment from another wallet + \item[balance] a withdraw or P2P payment causes the balance of a {\bf wallet} to exceed a given threshold +\end{description} + +We note in bold the {\bf anchor} for the regulator process. The anchor is used +to link the interaction to an identity. Once an identity has been established +for a particular anchor, that link is considered established for all types of +activities involving that anchor. A wallet is uniquely identified in the +system by its unique cryptographic key. A bank account is uniquely identified +in the system by its (RFC 8905) bank routing data (usually including BIC, IBAN +and account owner name). + +The KYC and AML processes themselves are described in +Chapter~\ref{chap:regproc}. + +\include{kyc-withdraw} +\include{kyc-deposit} +\include{kyc-push} +\include{kyc-pull} +\include{kyc-balance} + +\chapter{Regulatory Processes} \label{chap:regproc} + +This chapter describes the interactions between the customer, exchange and +organizations or staff assisting with regulatory processes designed to ensure +that customers are residents in the area of operation of the payment service +provider, are properly identified, and do not engage in money laundering. + +The three main regulatory processes are: + +\begin{description} +\item[domestic check] This process establishes that a user is generally + eligible to use the payment system. The process checks that the user has an + eligible address, but stops short of establishing the user's identity. +\item[kyc] This process establishes a user's legal identity, possibly + using external providers to review documents and check against blacklists. +\item[aml] The AML process reviews suspicious payment activities for + money laundering. Here AML staff reviews all collected information. +\end{description} + +\include{proc-domestic} +\include{proc-kyc} +\include{proc-aml} + +\chapter{Fees} \label{chap:fees} + +The business model for operating a Taler exchange is to charge transaction +fees. Fees are charged on certain operations by the exchange. There are two +types of fees, {\bf wire fees} and {\bf coin fees}. This chapter describes +the fee structure. + +Fixed, amount-independent {\bf wire fees} are charged on wire transfers using +the core banking system. Details on wire fees are described in +Section~\ref{sec:fees:wire}. + +Coin fees are more complex, as they do not exactly follow neither the usual +percentage of volume model of other payment systems. Instead, coin fees are +applied per coin, resulting in a {\em logarithmic} fee structure. As a +result, the effective fee {\em percentage} for tiny transactions is high (for +example 50\% for transactions of 0.0025 CHF) while the effective fee +percentage for large transactions is nominal (for example $\approx$ 0.05\% for +transactions of $\approx$ 40 CHF). Details on coin fees are described in +Section~\ref{sec:fees:coin}. + +Fees are configurable (and that fee types beyond those described here are +supported by the software). Thus, the specific fees may be adjusted in the +future based on business decisions. However, changes to the fees are never +retroactively applied to coins already in circulation. Wire fees that have +been publicly announced for a particular time period also cannot be changed. +Finally, any change to the terms of service must also be explicitly accepted +by the users before they withdraw additional funds. + + +\include{fees-wire} +\include{fees-coins} +%\include{fees-other} + + +\end{document} diff --git a/doc/flows/proc-aml.tex b/doc/flows/proc-aml.tex new file mode 100644 index 000000000..04700faf8 --- /dev/null +++ b/doc/flows/proc-aml.tex @@ -0,0 +1,47 @@ +\section{AML process} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Action}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{staff}{\shortstack{AML staff \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Access \\ Token}; + \end{tikzpicture} + }} + \postlevel + \mess[0]{wallet}{{Initial action}}{exchange} + \begin{callself}{exchange}{Establish AML requirement}{} + \end{callself} + \begin{callself}{exchange}{Queue AML task}{} + \end{callself} + \mess[0]{exchange}{Wait for AML}{wallet} + \mess[0]{staff}{Request AML work}{exchange} + \mess[0]{exchange}{{Open AML task(s)}}{staff} + \mess[0]{staff}{Request details}{exchange} + \mess[0]{exchange}{KYC/AML data}{staff} + \begin{callself}{staff}{Review and decide}{} + \end{callself} + \mess[0]{staff}{{Decision documentation}}{exchange} + \mess[0]{exchange}{AML decision}{wallet} + \mess[0]{wallet}{{Retry action}}{exchange} +\end{sequencediagram} + \caption{Deposit interactions between customer, Taler exchange (payment + service provider) and the AML staff. The process can be + triggered by various {\em actions} described in Chapter~\ref{chap:triggers}. + AML staff interactions are cryptographically secured and + decisions and the provided reasoning are archived by the exchange. + AML staff may interact with the customer (out-of-band) + in its decision process. + } + \label{fig:proc:aml} +\end{figure} diff --git a/doc/flows/proc-domestic.tex b/doc/flows/proc-domestic.tex new file mode 100644 index 000000000..387b964d5 --- /dev/null +++ b/doc/flows/proc-domestic.tex @@ -0,0 +1,66 @@ +\section{Domestic wallet check} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer wallet \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Wallet ID}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{sms}{\shortstack{Address validator}} + + \postlevel + \mess[0]{wallet}{{P2P payment (Wallet ID)}}{exchange} + \begin{callself}{exchange}{New wallet?}{} + \end{callself} + \mess[0]{exchange}{Request address validation}{sms} + \mess[0]{sms}{Validation process ID}{exchange} + \mess[0]{exchange}{Request address validation}{wallet} + \mess[0]{wallet}{Send address}{sms} + \mess[0]{sms}{{Send confirmation code (to address)}}{wallet} + \mess[0]{wallet}{Supply confirmation code}{sms} + \mess[0]{sms}{{Confirmed customer address}}{exchange} + \mess[0]{exchange}{{Confirm completion}}{wallet} + \mess[0]{wallet}{{Retry action}}{exchange} +\end{sequencediagram} + \caption{Deposit interactions between customer, Taler exchange (payment + service provider) and external address validation service. The process can be + triggered by wallet-to-wallet (P2P) payments described in Chapter~\ref{chap:triggers}.} + \label{fig:proc:domestic} +\end{figure} + +Our users have to accept the terms of service which restrict the use of the +service to domestic customers. For interactions with the core banking system, +this simply means that we only accept payments from or to domestic bank +accounts. For P2P payments between wallets, we require that the wallets are +controlled by a domestic entity. We define domestic entities as those that +are able to receive messages at a domestic address. Two types of addresses are +supported: + +\begin{itemize} +\item Control over a domestic {\bf mobile phone number} is established + by sending an SMS message with a confirmation code to the MSIN. +\item Control over a domestic {\bf postal address} is established by + sending a letter with a confirmation code to the address. +\end{itemize} + +Depending on the type of address, a validation has a limited validity period, +as shown in Table~\ref{table:proc:domestic}. When the validity period is +over, a wallet has to re-do the address validation before they can receive any +further funds through the service. + +\begin{table}[h!] + \caption{Restrictions on address validations} + \label{table:proc:domestic} + \begin{tabular}{l|l|r} + {\bf Type} & {\bf Validity period} & {\bf Restricted to} \\ \hline \hline + Mobile phone number & 12 months & {\em +41} \\ + Postal address & 36 months & {\em Switzerland} \\ + \end{tabular} +\end{table} diff --git a/doc/flows/proc-kyc.tex b/doc/flows/proc-kyc.tex new file mode 100644 index 000000000..006a05561 --- /dev/null +++ b/doc/flows/proc-kyc.tex @@ -0,0 +1,88 @@ +\section{KYC process} + +\begin{figure}[h!] + \begin{sequencediagram} + \newinst{wallet}{\shortstack{Customer \\ + \\ \begin{tikzpicture} + \node [fill=gray!20,draw=black,thick,align=center] { Unique \\ Action}; + \end{tikzpicture} + }} + \newinst[2]{exchange}{\shortstack{Taler (exchange) \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + \newinst[2]{kyc}{\shortstack{KYC provider \\ + \\ \begin{tikzpicture}[shape aspect=.5] + \tikzset{every node/.style={cylinder,shape border rotate=90, draw,fill=gray!25}} + \node at (1.5,0) {\shortstack{{{\tiny Database}}}}; + \end{tikzpicture} + }} + + \postlevel + \mess[0]{wallet}{{Initial action}}{exchange} + \begin{callself}{exchange}{Establish KYC requirement}{} + \end{callself} + \mess[0]{exchange}{Request new KYC process}{kyc} + \mess[0]{kyc}{{Process identifier (PI)}}{exchange} + \mess[0]{exchange}{{KYC required (PI)}}{wallet} + \mess[0]{wallet}{{KYC start (PI)}}{kyc} + \mess[0]{kyc}{{Request identity documentation}}{wallet} + \mess[0]{wallet}{{Upload identity documentation}}{kyc} + \begin{callself}{kyc}{Validate documentation}{} + \end{callself} + \mess[0]{kyc}{{Share documentation (PI)}}{exchange} + \mess[0]{kyc}{{Confirm completion}}{wallet} + \mess[0]{wallet}{{Retry action}}{exchange} +\end{sequencediagram} + \caption{Deposit interactions between customer, Taler exchange (payment + service provider) and external KYC provider. The process can be + triggered by various {\em actions} described in Chapter~\ref{chap:triggers}.} + \label{fig:proc:kyc} +\end{figure} + +At the beginning of the KYC process, the user needs to specify +whether they are an {\bf individual} or a {\bf business}. This +then determines which types of attributes are collected in the +KYC process (Table~\ref{table:proc:kyc:individual} vs. +Table~\ref{table:proc:kyc:business}). + +\begin{table} + \caption{Information collected for individuals} + \label{table:proc:kyc:individual} + \begin{center} + \begin{tabular}{l|c|r} + {\bf Type} & {\bf Required} & {\bf Example} \\ \hline \hline + Surname & yes & Mustermann \\ + First name(s) & yes & Max \\ + Date of birth & yes & 1.1.1980 \\ + Nationality & yes & Swiss \\ + Actual address of domicile & yes & Seestrasse 3, 8008 Zuerich \\ + Phone number & no & +41-123456789 \\ + E-mail & no & me@example.com \\ + Identification document & yes & JPG image \\ + \end{tabular} + \end{center} +\end{table} + + +\begin{table} + \caption{Information collected for businesses} + \label{table:proc:kyc:business} + \begin{center} + \begin{tabular}{l|c|r} + {\bf Type} & {\bf Required} & {\bf Example} \\ \hline \hline + Company name & yes & Mega AG \\ + Registered office & yes & Seestrasse 4, 8008 Zuerich \\ + Company identification document & yes & PDF file \\ \hline + Contact person name & yes & Max Mustermann \\ + Phone number & no & +41-123456789 \\ + E-mail & yes & me@example.com \\ + Identification document & yes & JPG image \\ + Date of birth & yes & 1.1.1980 \\ + Nationality & yes & Swiss \\ \hline + Power of attorney arrangement & yes & PDF file \\ + \end{tabular} + \end{center} +\end{table} |