diff options
Diffstat (limited to 'doc')
| -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 | 43 | 
19 files changed, 1065 insertions, 0 deletions
| diff --git a/doc/flows/Makefile b/doc/flows/Makefile new file mode 100644 index 00000000..e6af0897 --- /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 00000000..c24f19a2 --- /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 00000000..214a6902 --- /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 00000000..4b1f657b --- /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 00000000..d2f0fb58 --- /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 00000000..8c9b66b1 --- /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 00000000..fd49e8d4 --- /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 00000000..351ecda2 --- /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}{Request 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 00000000..e8ee6fee --- /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 00000000..9b044df6 --- /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 00000000..1192021b --- /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 00000000..2423235a --- /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 00000000..b7cd3447 --- /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 00000000..6d25ac7e --- /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 00000000..ecdc9a39 --- /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 00000000..c2aee65a --- /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 00000000..04700faf --- /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 00000000..6ea43b8e --- /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 PIN/TAN code (to address)}}{wallet} +    \mess[0]{wallet}{Supply PIN/TAN 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 PIN/TAN to the MSIN. +\item Control over a domestic {\bf postal address} is established by +  sending a letter with a PIN/TAN 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 00000000..33883c40 --- /dev/null +++ b/doc/flows/proc-kyc.tex @@ -0,0 +1,43 @@ +\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} | 
