[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-cashless2ecash] branch master updated: feat+docs: wallee app
From: |
gnunet |
Subject: |
[taler-cashless2ecash] branch master updated: feat+docs: wallee app |
Date: |
Sun, 05 May 2024 22:10:54 +0200 |
This is an automated email from the git hooks/post-receive script.
joel-haeberli pushed a commit to branch master
in repository cashless2ecash.
The following commit(s) were added to refs/heads/master by this push:
new c7271f6 feat+docs: wallee app
c7271f6 is described below
commit c7271f6ab1e7bdaa5f0efb753e6338c08ef08f43
Author: Joel-Haeberli <haebu@rubigen.ch>
AuthorDate: Sun May 5 22:10:36 2024 +0200
feat+docs: wallee app
---
c2ec/api-bank-integration.go | 12 ++-
docs/content/appendix/meeting_notes.tex | 44 ++++++++++
docs/content/architecture/c2ec.tex | 97 +++++++++++++--------
docs/content/implementation/a-c2ec.tex | 47 ++++++++--
docs/content/implementation/a-security.tex | 5 +-
docs/content/implementation/b-terminal.tex | 76 ++++++++++++++++
docs/content/implementation/concepts.tex | 72 +--------------
docs/content/implementation/database.tex | 2 +-
docs/content/implementation/terminal.tex | 1 -
docs/pictures/diagrams/system_overview.png | Bin 100725 -> 99686 bytes
docs/pictures/diagrams/terminal_flow.png | Bin 0 -> 77052 bytes
docs/pictures/wallee/amount_screen.png | Bin 0 -> 20085 bytes
.../wallee/authorize_transaction_screen_1.png | Bin 0 -> 14035 bytes
.../wallee/authorize_transaction_screen_2.png | Bin 0 -> 47933 bytes
docs/pictures/wallee/choose_exchange_screen.png | Bin 0 -> 54922 bytes
.../pictures/wallee/register_parameters_screen.png | Bin 0 -> 65893 bytes
docs/project.bib | 39 ++++++++-
docs/thesis.pdf | Bin 1767995 -> 1971697
bytes
docs/thesis.tex | 2 +-
specs/system_overview.odg | Bin 28197 -> 28733 bytes
specs/terminal_flow.plantuml | 43 +++++++++
wallee-c2ec/.idea/deploymentTargetSelector.xml | 3 +
wallee-c2ec/app/src/main/AndroidManifest.xml | 2 +
.../wallee_c2ec/client/taler/TerminalClient.kt | 4 +-
.../client/taler/TerminalClientImplementation.kt | 13 +--
.../wallee_c2ec/client/taler/TerminalClientMock.kt | 8 +-
.../client/taler/config/TerminalConfig.kt | 8 --
.../client/taler/model/TerminalsApiModel.kt | 2 +-
.../habej2/wallee_c2ec/withdrawal/AmountScreen.kt | 37 ++++++--
.../withdrawal/AuthorizePaymentScreen.kt | 82 +++++++++++++----
.../withdrawal/ExchangeSelectionScreen.kt | 61 ++++++++++---
.../wallee_c2ec/withdrawal/QRCodeComposable.kt | 4 +-
.../withdrawal/RegisterParametersScreen.kt | 67 ++++++++++++++
.../withdrawal/RegisterWithdrawalScreen.kt | 44 ----------
.../wallee_c2ec/withdrawal/WithdrawalActivity.kt | 13 ++-
.../wallee_c2ec/withdrawal/WithdrawalViewModel.kt | 64 ++++++++++++--
36 files changed, 608 insertions(+), 244 deletions(-)
diff --git a/c2ec/api-bank-integration.go b/c2ec/api-bank-integration.go
index bcd574d..894f4ae 100644
--- a/c2ec/api-bank-integration.go
+++ b/c2ec/api-bank-integration.go
@@ -62,8 +62,16 @@ type BankWithdrawalOperationStatus struct {
func bankIntegrationConfig(res http.ResponseWriter, req *http.Request) {
cfg := BankIntegrationConfig{
- Name: "taler-bank-integration",
- Version: "0:0:1",
+ Name: "taler-bank-integration",
+ Version: "0:0:1",
+ Currency: CONFIG.Server.Currency,
+ CurrencySpecification: CurrencySpecification{
+ Name: CONFIG.Server.Currency,
+ Currency: CONFIG.Server.Currency,
+ NumFractionalInputDigits: 2,
+ NumFractionalNormalDigits: 1000000000,
+ NumFractionalTrailingZeroDigits: 0,
+ },
}
serializedCfg, err :=
NewJsonCodec[BankIntegrationConfig]().EncodeToBytes(&cfg)
diff --git a/docs/content/appendix/meeting_notes.tex
b/docs/content/appendix/meeting_notes.tex
index 52a8dc4..47cd9f3 100644
--- a/docs/content/appendix/meeting_notes.tex
+++ b/docs/content/appendix/meeting_notes.tex
@@ -266,6 +266,50 @@
\item The Wire Gateway API must implement "/history/outgoing" and return
entries of the transfer table.
\end{itemize}
+\subsection*{24.04.2024}
+
+\textbf{Participants}
+
+\begin{itemize}
+ \item Fehrensen Benjamin
+ \item Grothoff Christian
+ \item Taler App Team
+ \item BFH Guests and Students
+ \item H\"aberli Joel
+\end{itemize}
+
+\textbf{Topics}
+\begin{itemize}
+ \item New Terminals API
+ \item Exponential Backoff, Self-Synchronization
+\end{itemize}
+
+\textbf{Action points}
+\begin{itemize}
+ \item Integrate new API
+ \item The Book entry
+\end{itemize}
+
+\subsection*{01.05.2024}
+
+\textbf{Participants}
+
+\begin{itemize}
+ \item Fehrensen Benjamin
+ \item H\"aberli Joel
+\end{itemize}
+
+\textbf{Topics}
+\begin{itemize}
+ \item Wallee Terminal Version
+ \item Completion Behavior of the transaction
+\end{itemize}
+
+\textbf{Action points}
+\begin{itemize}
+ \item Use Version 0.9.20 (not 0.9.12)
+\end{itemize}
+
% TEMPLATE %
\subsection*{TEMPLATE}
diff --git a/docs/content/architecture/c2ec.tex
b/docs/content/architecture/c2ec.tex
index b8ba67b..2b6b566 100644
--- a/docs/content/architecture/c2ec.tex
+++ b/docs/content/architecture/c2ec.tex
@@ -29,90 +29,119 @@ Basically C2EC mediates between the stakeholders of a
withdrawal in order to mai
\subsection{Authentication}
-Terminals and the Exchange which authenticate against the C2EC API must
provide their respective access token. Therefore, they provide a
\texttt{Authorization: Bearer \$ACCESS\_TOKEN} header, where
\texttt{\$ACCESS\_TOKEN} is a secret authentication token configured by the
exchange and must begin with the prefix specified in RFC 8959 \cite{rfc8959}:
\textit{secret-token}.
+Terminals and the Exchange Wire Watch which authenticate against the C2EC API
using Basic-Auth \cite{rfc7617} must provide their respective access token.
Therefore, they provide a \texttt{Authorization: Basic \$ACCESS\_TOKEN} header,
where \texttt{\$ACCESS\_TOKEN} is a secret authentication token configured by
the operator of the exchange. The header value must begin with the prefix
specified in RFC 7617 \cite{rfc7617}: \textit{Basic}.
\subsection{The C2EC RESTful API}
-This section describes the various API implemented in the C2EC component. The
description contains a short list of the consumers of the respective API.
Consumer in this context does not necessarily mean that data is consumed but
rather that the consumer uses the API to either gather data or send data to
C2EC.
+This section describes the various API implemented in the C2EC component. The
description contains a short list of the consumers of the respective API.
Consumer in this context does not necessarily mean that data is consumed but
rather that the consumer uses the API to either gather data or send reqeusts or
data to C2EC.
-\subsubsection{Taler Bank Integration API}
+\subsubsection{Terminals API}
-Withdrawals with a C2EC are based on withdrawal operations which register a
withdrawal identifier (nonce) at the C2EC component. The provider must first
create a unique identifier for the withdrawal operation (the \texttt{WOPID}) to
interact with the withdrawal operation and eventually withdraw using the
wallet. The withdrawal operation API is an implementation of the \textit{Bank
Integration API} \cite{taler-bank-integration-api}.
+That terminal can initiate and serve withdrawals in Taler, the Terminals API
\cite{taler-terminal-api} is implemented, which mirrors all actions of a
terminal at the C2EC component.
-\textbf{GET - config}
+\textbf{Config}
\begin{itemize}
\item \textbf{Method:} GET
\item \textbf{Endpoint:} /config
\item \textbf{Description:} Return the protocol version and configuration
information about the C2EC API.
- \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{C2ECConfig} object.
- \item \textbf{Consumers:} Components who want to use the API and therefore
want to load the config of the instance.
+ \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{TerminalsConfig} object.
+ \item \textbf{Consumers:} Terminals who want to use the API and therefore
want to load the config of the instance.
\end{itemize}
-\textbf{POST - withdrawal-operation}
-
-This API is not specified within the standard Bank Integration API and
therefore an extension to the official specification. The Wallet must implement
the initialization through this flow.
-
+\textbf{Withdrawals}
\begin{itemize}
\item \textbf{Method:} POST
- \item \textbf{Endpoint:} /withdrawal-operation
- \item \textbf{Description:} Initiate the withdrawal operation, identified by
the \texttt{WOPID}.
- \item \textbf{Request:} The request body contains a
\texttt{C2ECWithdrawRegistration} object.
- \item \textbf{Response:} The response is HTTP status code 204 No Content on
success and a 400 or 500 status code on failure (with respective
\texttt{ErrorDetail})
- \item \textbf{Consumers:} The \textit{Taler Wallet} registers and
initializes the withdrawal operation through this API.
+ \item \textbf{Endpoint:} /withdrawals
+ \item \textbf{Description:} Register a withdrawal operation at C2EC.
+ \item \textbf{Response:} HTTP status code 200 OK. The \textit{WOPID}
generated by C2EC. On any other status code, terminate the withdrawal.
+ \item \textbf{Consumers:} Terminals who want to initiate a withdrawal
operation.
\end{itemize}
-\textbf{GET - withdrawal-operation by wopid}
+\textbf{Status of the withdrawal operation}
\begin{itemize}
\item \textbf{Method:} GET
- \item \textbf{Endpoint:} /withdrawal-operation/\$WOPID
+ \item \textbf{Endpoint:} /withdrawals/\$WOPID
\item \textbf{Description:} Query information about a withdrawal operation,
identified by the \texttt{WOPID}.
- \item \textbf{Response:} HTTP status code 200 OK and body containing a
\texttt{C2ECWithdrawalStatus} object or 404 Not found.
+ \item \textbf{Response:} HTTP status code 200 OK and body containing a
\texttt{BankWithdrawalOperationStatus} object or 404 Not found.
\item \textbf{Consumers:} The API is used by the \textit{Terminal} and
\textit{Taler Wallet} to retrieve information about the current state of the
withdrawal operation. The API allows long-polling and can therefore be used by
the consumer to be updated if the status of the withdrawal operation changes.
\end{itemize}
-\textbf{POST - withdrawal-operation by wopid}
+\textbf{Check transaction}
\begin{itemize}
\item \textbf{Method:} POST
- \item \textbf{Endpoint:} /withdrawal-operation/\$WOPID
+ \item \textbf{Endpoint:} /withdrawals/\$WOPID/check
\item \textbf{Description:} Notifies C2EC about an executed payment for a
specific withdrawal.
- \item \textbf{Request:} The request body contains a
\texttt{C2ECPaymentNotification} object.
+ \item \textbf{Request:} The request body contains a
\texttt{WithdrawalConfirmationRequest} object.
\item \textbf{Response:} HTTP status code 204 No content, 400 Bad request,
404 Not found, or 500 Internal Server error.
- \item \textbf{Consumers:} The API is used by the \textit{Terminal} to notify
the C2EC component that a payment was made and to give the C2EC component
information about the payment itself (e.g. the provider specific transaction
identifier).
+ \item \textbf{Consumers:} The API is used by the \textit{Terminal} to notify
the C2EC component that a payment was made and to give the C2EC component
information about the payment itself (e.g. the provider specific transaction
identifier or optional fees).
+\end{itemize}
+
+\textbf{Terminal abortion}
+\begin{itemize}
+ \item \textbf{Method:} DELETE
+ \item \textbf{Endpoint:} /withdrawals/\$WOPID/abort
+ \item \textbf{Description:} Aborts the withdrawal specified by the
\texttt{WOPID}.
+ \item \textbf{Request:} The request body contains a
\texttt{WithdrawalConfirmationRequest} object.
+ \item \textbf{Response:} HTTP status code 204 No content, 400 Bad request,
404 Not found, or 500 Internal Server error.
+ \item \textbf{Consumers:} The API is used by the \textit{Terminal} to notify
the C2EC component that a payment was made and to give the C2EC component
information about the payment itself (e.g. the provider specific transaction
identifier or optional fees).
+\end{itemize}
+
+\subsubsection{Taler Bank Integration API}
+
+Withdrawals with a C2EC are based on withdrawal operations which register a
withdrawal identifier (nonce) at the C2EC component. The provider must first
create a unique identifier for the withdrawal operation (the \texttt{WOPID}) to
interact with the withdrawal operation and eventually withdraw using the
wallet. The withdrawal operation API is an implementation of the \textit{Bank
Integration API} \cite{taler-bank-integration-api}.
+
+\textbf{Config}
+\begin{itemize}
+ \item \textbf{Method:} GET
+ \item \textbf{Endpoint:} /config
+ \item \textbf{Description:} Return the protocol version and configuration
information about the C2EC API.
+ \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{C2ECConfig} object.
+ \item \textbf{Consumers:} Wallets who want to use the API and therefore want
to load the config of the instance.
\end{itemize}
\subsection{Taler Wirewatch Gateway API}
+
The Taler Wirewatch Gateway \cite{taler-wire-gateway-api} must be implemented
in order to capture incoming transactions and allow the withdrawal of digital
cash. The specification of the Taler Wirewatch Gateway can be found in the
official Taler documentation \cite{taler-wire-gateway-api}.
The wirewatch gateway helps the Exchange communicate with the C2EC component
using a the API. It helps the Exchange to fetch guarantees, that a certain
transaction went through and that the reserve can be created and withdrawn.
This will help C2EC to capture the transaction of the Terminal Backend to the
Exchange's account and therefore allow the withdrawal by the customer.
Therefore the wirewatch gateway API is implemented as part of C2EC. When the
wirewatch gateway can get the proof, t [...]
For C2EC not all endpoints of the Wire Gateway API are needed. Therefore the
endoints which are not needed will be implemented but always return http status
code 400 with explanatory error details as specified by the specification.
-\textbf{GET - config}
+\textbf{Config}
\begin{itemize}
\item \textbf{Method:} GET
\item \textbf{Endpoint:} /config
\item \textbf{Description:} Returns a \texttt{WireConfig} object with
configuration information about the Wirewatch Gateway API of the C2EC component.
- \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{C2ECConfig} object.
+ \item \textbf{Response:} HTTP status code 200 OK and the wirewatch gateway
configuration
\item \textbf{Consumers:} Components who want to use the API and therefore
want to load the config of the instance.
\end{itemize}
-\textbf{POST - transfer}
+\textbf{Transfer}
\begin{itemize}
- \item \textbf{Method:} GET
+ \item \textbf{Method:} POST
\item \textbf{Endpoint:} /transfer
- \item \textbf{Description:} Allows the \textit{Exchange} to make a
transaction. This API is used in case of a refund. The transfer will therefore
pointed towards a \texttt{payto://wallee-transaction} address.
+ \item \textbf{Description:} Allows the \textit{Exchange} to make a
transaction. This API is used in case of a refund. The transfer will therefore
be pointed towards a provider specific payto-address
(\texttt{payto://wallee-transaction} in case of Wallee).
\item \textbf{Request:} The request contains a \texttt{TransferRequest}
object.
- \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{C2ECConfig} object.
- \item \textbf{Consumers:} The \textit{Exchange} who wants to transfer
digital cash to a account which can be handled by the C2EC component.
+ \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{TransferResponse} object.
+ \item \textbf{Consumers:} The \textit{Exchange Wirewatch} who wants to
transfer money using C2EC.
\end{itemize}
-\textbf{GET - history of incoming transactions}
+\textbf{History of incoming transactions}
\begin{itemize}
\item \textbf{Method:} GET
\item \textbf{Endpoint:} /history/incoming
\item \textbf{Description:} Returns a list of transactions which were
recently created in the C2EC component. In case of C2EC, this are withdrawal
operations which are confirmed and a reserve can therefore be created by the
exchange.
\item \textbf{Response:} HTTP status code 200 OK. The exchange responds with
a \texttt{C2ECConfig} object.
- \item \textbf{Consumers:} The \textit{Exchange} who will create the reserve
which then can be withdrawn by the \textit{Taler Wallet}.
+ \item \textbf{Consumers:} The \textit{Exchange Wirewatch} who will create
the reserve which then can be withdrawn by the \textit{Taler Wallet}.
+\end{itemize}
+
+\textbf{History of outgoing transactions}
+\begin{itemize}
+ \item \textbf{Method:} GET
+ \item \textbf{Endpoint:} /history/outgoing
+ \item \textbf{Description:} Returns a list of transfers which were executed
by the C2EC component.
+ \item \textbf{Response:} HTTP status code 200 OK and a list of outgoing
transfers.
+ \item \textbf{Consumers:} The \textit{Exchange Wirewatch} who will create
the reserve which then can be withdrawn by the \textit{Taler Wallet}.
\end{itemize}
\subsection{The C2EC database}
@@ -165,7 +194,7 @@ RFC 8905 \cite{rfc8905} specifies a URI scheme (complying
with RFC 3986 \cite{rf
In case a refund becomes necessary, which might occur if a credit card
transaction does not succeed, a new \textit{target type} called
\textit{wallee-transaction} is registered. It takes a transaction identifier as
\textit{target identifier} which identifies the transaction for which a refund
process shall be triggered. The idea is that the handler of the payto URI is
able to deduct the transaction from the payto-uri and trigger the refund
process.
\subsection{Payto refund using Wallee}
-Wallee allows to trigger refunds using the Refund Service of the Wallee
backend. The service allows to trigger a refund given a transaction identifier.
Therefore the C2EC component can trigger the refund using the refund service if
needed, and the payto-uri retrieved as debit account by the wirewatch gateway
API, is leveraged to delegate the refund process to the Wallee Backend using
the Refund Service and parsing the transaction identifier of the payto-uri.
+Wallee allows to trigger refunds using the Refund Service of the Wallee
backend. The service allows to trigger a refund given a transaction identifier.
Therefore the C2EC component can trigger the refund using the refund service if
needed. The payto-uri retrieved as debit account by the wire gateway API, is
leveraged to delegate the refund process to the Wallee Backend using the Refund
Service and parsing the transaction identifier of the payto-uri.
\subsection{Extensibility}
-The flow is extensible and other providers like Wallee might be added. They
must therefore register their own refund payto-uri with the GANA and then the
refund process can be implemented likewise.
\ No newline at end of file
+The flow is extensible and other providers like Wallee might be added. They
must therefore register their own refund payto-uri (if needed) with the GANA
and then the refund process can be implemented likewise.
diff --git a/docs/content/implementation/a-c2ec.tex
b/docs/content/implementation/a-c2ec.tex
index e9cddb9..4d83373 100644
--- a/docs/content/implementation/a-c2ec.tex
+++ b/docs/content/implementation/a-c2ec.tex
@@ -7,15 +7,48 @@ This section treats the implementation of the C2EC component.
C2EC is the core o
The diagram in \autoref{fig-diagram-c2ec-apis-sequence} shows the perspective
of the C2EC component in the withdrawal flow. The numbers in brackets represent
can be mapped to the diagram in \autoref{fig-diagram-all-sequence} of the
process description in the architecture chapter at
\autoref{sec-architecture-process}. The requests represented in
\autoref{fig-diagram-c2ec-apis-sequence} only show the requests of the
succesful path. In case of an error in the process, various other endpoint [...]
-\begin{figure}[h]
- \centering
- \includegraphics[width=0.7\textwidth]{pictures/diagrams/c2ec_apis.png}
- \caption{The C2EC component and its related clients}
- \label{fig-diagram-c2ec-apis-sequence}
-\end{figure}
-
The implementation of the terminals API can be found in
\autoref{sec-implementation-terminal-api}, the bank integration API is
documented in \autoref{sec-implementation-bank-integration-api} and the wire
gateway API implementation is documented in
\autoref{sec-implementation-wire-gateway-api}
+\subsubsection{Decoupling steps using Events}
+
+The concept of publishers and subscribers is used heavily in the
implementation. It allows decoupling different steps of the process and allows
different steps to be handled and executed in their own processes. Publishers
can also be called notifiers or similar, while the subscriber can also be
called listener or similar.
+
+The communication of publishers and subscribers happends through channels. A
publisher will publish to a certain channel when a defined state is reached.
The subscriber who is subscribed or listens to this channel will capture the
message sent through the channel by the publisher and start processing it.
+
+The publish-subscribe scheme enables loose coupling and therefore helps to
improve the performance of individual processes, because they cannot be
hindered by others.
+
+To decouple different steps in the withdrawal process an event based
architecture is implemented. This means that every write action to the database
will represent an operation which will trigger an event. The applications
processes are listening to those events. The consumer of the API can wait to be
notified by the API, by registering to those events via a long polling request
at the API. This long-polling will then wait until the listener receives the
event and return the received eve [...]
+
+Following a short list of events and from whom they are triggered and who
listens to them:
+
+\begin{itemize}
+ \item Registration of the withdrawal operation parameters.
+ \begin{itemize}
+ \item Registered by: Wallet
+ \item Listened by: Terminal
+ \end{itemize}
+ \item Payment confirmation request sent to the Bank-Integration API of
C2EC.
+ \begin{itemize}
+ \item Registered by: Terminal
+ \item Listened by: Attestor
+ \end{itemize}
+ \item Payment attestation success will send a withdrawal operation status
update event.
+ \begin{itemize}
+ \item Registered by: Attestor
+ \item Listened by: Consumers (via Bank-Integration-API)
+ \end{itemize}
+ \item Payment attestation failure will trigger a retry event.
+ \begin{itemize}
+ \item Registered by: Attestor
+ \item Listened by: Retrier
+ \end{itemize}
+ \item Transfers which represent refunds in C2EC.
+ \begin{itemize}
+ \item Registered by: Exchange (through the wire gateway API)
+ \item Listened by: Transfer
+ \end{itemize}
+\end{itemize}
+
\include{content/implementation/a-terminal-api}
\include{content/implementation/a-bank-integration-api}
diff --git a/docs/content/implementation/a-security.tex
b/docs/content/implementation/a-security.tex
index 9c64087..e1b0417 100644
--- a/docs/content/implementation/a-security.tex
+++ b/docs/content/implementation/a-security.tex
@@ -1,8 +1,9 @@
\subsection{Security}
-\subsubsection{WOPID}
+
+\subsubsection{Withdrawal Operation Identifier (WOPID)}
\label{sec-security-wopid}
-% TODO
+The \textit{WOPID} is the achiles heel of the withdrawal operation and
therefore needs great care when generated. When the \textit{WOPID} becomes
somehow foreseeable, it opens the door for attackers allowing them to hijack
the withdrawal from a remote location. Therefore the \textit{WOPID} needs to
leverage high entropy sources to be generated.
\subsubsection{Authenticating at the Wallee ReST API}
\label{sec-security-auth-wallee}
diff --git a/docs/content/implementation/b-terminal.tex
b/docs/content/implementation/b-terminal.tex
new file mode 100644
index 0000000..1ec4b72
--- /dev/null
+++ b/docs/content/implementation/b-terminal.tex
@@ -0,0 +1,76 @@
+\section{Wallee POS Terminal}
+
+\subsection{Withdrawal flow}
+\label{sec-wallee-withdrawal-flow}
+
+The process (\autoref{fig-diagram-terminal-flow}) starts by first selecting
the exchange and loading the configuration of the respective terminals-api.
When this is successful, we will switch to the amount screen. Otherwise the
withdrawal will be terminated.
+
+On the amount screen the terminal operator enters the amount to withdraw and
clicks on the "withdraw" button. If the operator clicks on the abort button,
the withdrawal is terminated. When the user clicks the "withdraw" button, the
terminal sets up the withdrawal at the exchanges terminals api and retrieves
the wopid. When this step is unsuccessful, the withdrawal operation is aborted
and terminated. Otherwise the terminal navigates to the register parameters
screen.
+
+In the register parameters screen, a QR code is displayed, which must be
scanned by the withdrawer using their wallet app. The Terminal starts a long
polling the terminals api to be notified, when the withdrawal operation is in
state 'selected' which means, the wallet has successfully registered its
withdrawal parameters. In this case the terminal application changes to the
authorize payment screen in which the withdrawing person must authorize the
transaction using their credit card. In [...]
+
+If this request is successful, the terminals shows a summary of the
transaction and a button to leave the withdrawal activity. The wallet of the
user should eventually be able to withdraw the amount authorized from the
exchange.
+
+\begin{figure}[h]
+ \centering
+ \includegraphics[width=0.7\textwidth]{pictures/diagrams/terminal_flow.png}
+ \caption{The flow of the terminal app}
+ \label{fig-diagram-terminal-flow}
+\end{figure}
+
+\subsection{Screens}
+
+The Application is implemented using jetpack compose
\cite{app-jetpack-compose} and each of the screens described in
\autoref{sec-wallee-withdrawal-flow} is implemented as composable screen. This
allows to handle the entire withdrawal flow in one single activity and
therefore makes state handling easier, because the state of the withdrawal can
be bound to the activity and also will be removed when the activity finishes or
is terminated due to an error. It also prevents illegal states and [...]
+
+\subsubsection{Choose Exchange Screen}
+
+On the screen \autoref{fig-terminal-screen-choose-exchange} the user chooses
the exchange to withdraw from. This allows the terminal to support withdrawals
from various exchanges and therefore enhances the flexibility. When the user
selected the exchange, the configuration of the exchange is loaded. This will
define the currency of the withdrawal and tell the terminal where to reach the
Terminals API of the C2EC server.
+
+\begin{figure}[h]
+ \centering
+
\includegraphics[width=0.7\textwidth]{pictures/wallee/choose_exchange_screen.png}
+ \caption{Terminal: Select the exchange to withdraw from}
+ \label{fig-terminal-screen-choose-exchange}
+\end{figure}
+
+\subsubsection{Amount Screen}
+
+The amount screen in \autoref{fig-terminal-screen-amount} is used to ask the
user what amount they would like to withdraw. When the amount was entered and
the \textit{withdraw}-button was clicked, the terminal sets up the withdrawal
using the Terminal API. The Terminals API will send the \textit{WOPID} to the
terminal, which allows the terminal to generate the taler withdraw URI
according to \cite{taler-uri-scheme-rfc}.
+
+\begin{figure}[h]
+ \centering
+ \includegraphics[width=0.7\textwidth]{pictures/wallee/amount_screen.png}
+ \caption{Terminal: Enter the desired amount to withdraw}
+ \label{fig-terminal-screen-amount}
+\end{figure}
+
+\subsubsection{Parameter Registration Screen}
+
+This screen in \autoref{fig-terminal-screen-register-parameters} displays a QR
code which contains the taler withdraw URI of the withdrawal. This allows the
customer to scan it using their Taler Wallet app and register the parameters
for the withdrawal (namely the reserve public key). The withdrawal can be
aborted on the screen. This step is important to make sure, that the customer
has a working Taler Wallet installed and allows them to accept the terms of
service for the respective exc [...]
+
+\begin{figure}[h]
+ \centering
+
\includegraphics[width=0.7\textwidth]{pictures/wallee/register_parameters_screen.png}
+ \caption{Terminal: Register withdrawal parameters}
+ \label{fig-terminal-screen-register-parameters}
+\end{figure}
+
+\subsubsection{Authorization Screen}
+
+The authorization screen will use Wallee's \textit{Android Till SDK}
\cite{wallee-till-sdk} to authorize the amount at the Wallee backend. The
response handler of the SDK will delegate the response to the implementation of
the terminal, which allows triggering the attestation of the payment by C2EC
using the Terminals API. When the authorization process is not started and the
transaction therefore is created at the backend system of Wallee, the screen
displayed at \autoref{fig-terminal-s [...]
+
+\begin{figure}[h]
+ \centering
+
\includegraphics[width=0.7\textwidth]{pictures/wallee/authorize_transaction_screen_1.png}
+ \caption{Terminal: Waiting to start the authorization of the android till
SDK}
+ \label{fig-terminal-screen-authorizing}
+\end{figure}
+
+When the transaction was processed successfully, the summary of the
transaction will be displayed on this screen as can be seen in
\autoref{fig-terminal-screen-authorized}.
+
+\begin{figure}[h]
+ \centering
+
\includegraphics[width=0.7\textwidth]{pictures/wallee/authorize_transaction_screen_2.png}
+ \caption{Terminal: Payment authorized}
+ \label{fig-terminal-screen-authorized}
+\end{figure}
\ No newline at end of file
diff --git a/docs/content/implementation/concepts.tex
b/docs/content/implementation/concepts.tex
index f217ab3..bb119bf 100644
--- a/docs/content/implementation/concepts.tex
+++ b/docs/content/implementation/concepts.tex
@@ -1,71 +1,3 @@
-\section{Concepts}
+\section{How to read this section}
-This chapter describes high level concepts which are used in the
implementation of the components. The short explanations aim to support the
understanding of the reader to faster and better understand the implementation
of the components.
-
-\subsection{Long-Polling}
-\label{sec-concepts-long-poll}
-
-Long-Polling is the concept of not closing a connection until a a response can
be delivered or a given duration exceeds. This allows a consumer to ask for
information which it assumes will arrive in the future at the producer. The
producer therefore will not close the request of the consumer but instead keep
the connection open and respond with the response, once it is available. The
consumer and the producer can both close the connection after a certain amount
of time, which is called t [...]
-
-\subsection{Publish-Subscribe Pattern}
-\label{sec-concepts-pub-sub}
-
-The concept of publishers and subscribers is used heavily in the
implementation. It allows decoupling different steps of the process and allows
different steps to be handled and executed in their own processes. Publishers
can also be called notifiers or similar, while the subscriber can also be
called listener or similar.
-
-The communication of publishers and subscribers happends through channels. A
publisher will publish to a certain channel when a defined state is reached.
The subscriber who is subscribed or listens to this channel will capture the
message sent through the channel by the publisher and start processing it.
-
-The publish-subscribe scheme enables loose coupling and therefore helps to
improve the performance of individual processes, because they cannot be
hindered by others.
-
-\subsubsection{Decoupling steps}
-
-To decouple different steps in the withdrawal process an event based
architecture is implemented. This means that every write action to the database
will represent an operation which will trigger an event. The applications
processes are listening to those events. The consumer of the API can wait to be
notified by the API, by registering to those events via a long polling request
at the API. This long-polling will then wait until the listener receives the
event and return the received eve [...]
-
-Following a short list of events and from whom they are triggered and who
listens to them:
-
-\begin{itemize}
- \item Registration of the withdrawal operation parameters.
- \begin{itemize}
- \item Registered by: Wallet
- \item Listened by: Terminal
- \end{itemize}
- \item Payment confirmation sent to the Bank-Integration API of C2EC.
- \begin{itemize}
- \item Registered by: Terminal
- \item Listened by: Attestor
- \end{itemize}
- \item Payment attestation success will send a withdrawal operation status
update event.
- \begin{itemize}
- \item Registered by: Attestor
- \item Listened by: Consumers (via Bank-Integration-API)
- \end{itemize}
- \item Payment attestation failure will trigger a retry event.
- \begin{itemize}
- \item Registered by: Attestor
- \item Listened by: Retrier
- \end{itemize}
- \item Transfers which represent refunds in C2EC.
- \begin{itemize}
- \item Registered by: Exchange (through the wire gateway API)
- \item Listened by: Transfer
- \end{itemize}
-\end{itemize}
-
-\subsection{Go Language}
-
-Go comes with handy features to implement the concepts like pub/sub
\autoref{sec-concepts-pub-sub} or long polling \autoref{sec-concepts-long-poll}.
-
-\subsubsection{Contexts}
-
-Go standard library contians a package called \textit{context}. You will
stumble over this package all the time, even when using third party libraries
or when writing your own code. The \textit{context} package allows to control
the lifetime and cancellation activities for function and allows concurrent
running threads to be executed within the same context. For example if you have
a function which can sort a list concurrently and will fail if any thread has a
failure, supplying each con [...]
-
-\subsubsection{Go Routines}
-
-In concurrent programs it is a challenge to keep up with the complexity which
they add to the code. Also one has to take care of interprocess communication
and if memory is accessed in shared manner by the program, the access to the
data stored should be mutual exclusive. Go therefore comes with the concept of
Goroutines. They are designed to be very cheap, lightweight threads. They share
the same address space and are just executed besides each other as simple
functions. Also Go encoura [...]
-
-\subsubsection{Coroutines}
-
-\textit{Coroutines} are the coutnerpart to the \textit{Go routines} in Kotlin
and are leveraged in the development of the Terminal Application.
-
-\subsubsection{Memory safety}
-
-Even when Go is a low level language which compiles to native bytecode
directly, it implements a garbage collector and memory management which takes
care of allocating and releasing memory as needed. This reduces the risk of
memory leaks to bugs in the memory management and the garbage collector itself.
+The implementation is documented per component (C2EC, Terminal, Database).
This means that each feature is documented from the perspective of the
respective component in another section. Remarkable interactions with other
components are linked with and shall support the reader to jump between the
different components explanations interacting with each other. The reader is
therefore advised to read the document on a digital device for easier reading.
Also diagrams might be hard to see whe [...]
\ No newline at end of file
diff --git a/docs/content/implementation/database.tex
b/docs/content/implementation/database.tex
index db4dc9c..38806d6 100644
--- a/docs/content/implementation/database.tex
+++ b/docs/content/implementation/database.tex
@@ -4,7 +4,7 @@ The Database is implemented using Postgresql. This database is
also used by othe
Besides the standard SQL features to insert and select data, Postgres also
comes with handy features like LISTEN and NOTIFY.
-This allows the implementation of neat pub/sub models allowing better
performance and separation of concerns.
+This allows the implementation of neat pub/sub models allowing better
performance, separation of concerns and loose coupling.
\subsection{Schema}
diff --git a/docs/content/implementation/terminal.tex
b/docs/content/implementation/terminal.tex
deleted file mode 100644
index d564bac..0000000
--- a/docs/content/implementation/terminal.tex
+++ /dev/null
@@ -1 +0,0 @@
-\section{Wallee POS Terminal}
\ No newline at end of file
diff --git a/docs/pictures/diagrams/system_overview.png
b/docs/pictures/diagrams/system_overview.png
index cbef44a..efa520a 100644
Binary files a/docs/pictures/diagrams/system_overview.png and
b/docs/pictures/diagrams/system_overview.png differ
diff --git a/docs/pictures/diagrams/terminal_flow.png
b/docs/pictures/diagrams/terminal_flow.png
new file mode 100644
index 0000000..8d9ee41
Binary files /dev/null and b/docs/pictures/diagrams/terminal_flow.png differ
diff --git a/docs/pictures/wallee/amount_screen.png
b/docs/pictures/wallee/amount_screen.png
new file mode 100644
index 0000000..1d3ddc0
Binary files /dev/null and b/docs/pictures/wallee/amount_screen.png differ
diff --git a/docs/pictures/wallee/authorize_transaction_screen_1.png
b/docs/pictures/wallee/authorize_transaction_screen_1.png
new file mode 100644
index 0000000..a335cda
Binary files /dev/null and
b/docs/pictures/wallee/authorize_transaction_screen_1.png differ
diff --git a/docs/pictures/wallee/authorize_transaction_screen_2.png
b/docs/pictures/wallee/authorize_transaction_screen_2.png
new file mode 100644
index 0000000..be6e31b
Binary files /dev/null and
b/docs/pictures/wallee/authorize_transaction_screen_2.png differ
diff --git a/docs/pictures/wallee/choose_exchange_screen.png
b/docs/pictures/wallee/choose_exchange_screen.png
new file mode 100644
index 0000000..98d3ef1
Binary files /dev/null and b/docs/pictures/wallee/choose_exchange_screen.png
differ
diff --git a/docs/pictures/wallee/register_parameters_screen.png
b/docs/pictures/wallee/register_parameters_screen.png
new file mode 100644
index 0000000..85cf5c6
Binary files /dev/null and
b/docs/pictures/wallee/register_parameters_screen.png differ
diff --git a/docs/project.bib b/docs/project.bib
index b5ac697..2de67f3 100644
--- a/docs/project.bib
+++ b/docs/project.bib
@@ -52,7 +52,7 @@
@misc{wallee-till-sdk,
author = {Wallee},
- title = {Wallee Android Till SDK},
+ title = {Android Till SDK},
url = {https://github.com/wallee-payment/android-till-sdk},
howpublished = {\url{https://github.com/wallee-payment/android-till-sdk}}
}
@@ -248,6 +248,22 @@
howpublished = {\url{https://docs.taler.net/taler-wallet.html#withdrawal}}
}
+@techreport{taler-uri-scheme-rfc,
+ number = {draft-grothoff-taler-01},
+ type = {Internet-Draft},
+ institution = {Internet Engineering Task Force},
+ publisher = {Internet Engineering Task Force},
+ note = {Work in Progress},
+ url = {https://datatracker.ietf.org/doc/draft-grothoff-taler/01/},
+ author = {Christian Grothoff and Florian Dold},
+ title = {{The 'taler' URI scheme for GNU Taler Wallet interactions}},
+ pagetotal = 14,
+ year = 2022,
+ month = nov,
+ day = 16,
+ abstract = {This document defines the 'taler' Uniform Resource Identifier
(URI) scheme for triggering interactions with a GNU Taler wallet. This URI
scheme allows applications to trigger interactions with the GNU Taler wallet,
such as withdrawing money, making payments, receiving refunds and restoring a
wallet from a backup. Applications may receive such URIs in many ways
(including via NFC, QR codes, Web links or messaging applications), or might
generate them internally to interac [...]
+}
+
@misc{postgres-notify,
author = {PostgreSQL},
title = {NOTIFY},
@@ -329,3 +345,24 @@
isbn = {978-1-4842-7467-5},
doi = {10.1007/978-1-4842-7468-2}
}
+
+@misc{app-jetpack-compose,
+ author = {Developer-Android},
+ title = {Build better apps faster with Jetpack Compose},
+ url = {https://developer.android.com/develop/ui/compose},
+ howpublished = {\url{https://developer.android.com/develop/ui/compose}},
+}
+
+@misc{app-viewmodel,
+ author = {Developer-Android},
+ title = {ViewModel overview},
+ url =
{https://developer.android.com/topic/libraries/architecture/viewmodel},
+ howpublished =
{\url{https://developer.android.com/topic/libraries/architecture/viewmodel}},
+}
+
+@misc{app-navigation,
+ author = {Developer-Android},
+ title = {Navigation},
+ url = {https://developer.android.com/guide/navigation},
+ howpublished = {\url{https://developer.android.com/guide/navigation}},
+}
diff --git a/docs/thesis.pdf b/docs/thesis.pdf
index 03699c1..161abf6 100644
Binary files a/docs/thesis.pdf and b/docs/thesis.pdf differ
diff --git a/docs/thesis.tex b/docs/thesis.tex
index 3514cf0..c83bece 100644
--- a/docs/thesis.tex
+++ b/docs/thesis.tex
@@ -198,7 +198,7 @@
\input{content/implementation/concepts}
\input{content/implementation/database}
\input{content/implementation/a-c2ec}
-\input{content/implementation/terminal}
+\input{content/implementation/b-terminal}
\input{content/implementation/wallet}
\chapter{Results}
diff --git a/specs/system_overview.odg b/specs/system_overview.odg
index dac9bc7..77a87f8 100644
Binary files a/specs/system_overview.odg and b/specs/system_overview.odg differ
diff --git a/specs/terminal_flow.plantuml b/specs/terminal_flow.plantuml
new file mode 100644
index 0000000..f61a369
--- /dev/null
+++ b/specs/terminal_flow.plantuml
@@ -0,0 +1,43 @@
+@startuml
+
+start
+
+if (Select exchange and load configuration) then (successful)
+ :Switch to amount screen;
+ if (Enter amount and click "withdraw") then (successful)
+ :Setup withdrawal at exchange's terminals API and retrieve wopid;
+ if (Setup successful) then (yes)
+ :Navigate to register parameters screen;
+ if (Scan QR code with wallet app) then (successful)
+ :Start long polling for 'selected' state;
+ if ('selected' state reached) then (yes)
+ :Authorize payment using credit card;
+ if (Authorization response received) then (successful)
+ :Send check notification to terminals API;
+ if (Notification successful) then (successful)
+ :Show transaction summary and leave withdrawal activity;
+ else (unsuccessful)
+ :Abort and terminate withdrawal;
+ endif
+ else (unsuccessful)
+ :Abort and terminate withdrawal;
+ endif
+ else (unsuccessful)
+ :Abort and terminate withdrawal;
+ endif
+ else (unsuccessful)
+ :Abort and terminate withdrawal;
+ endif
+ else (unsuccessful)
+ :Abort and terminate withdrawal;
+ endif
+ else (unsuccessful)
+ :Abort and terminate withdrawal;
+ endif
+else (unsuccessful)
+ :Terminate withdrawal;
+endif
+
+stop
+
+@enduml
diff --git a/wallee-c2ec/.idea/deploymentTargetSelector.xml
b/wallee-c2ec/.idea/deploymentTargetSelector.xml
index b268ef3..1096d02 100644
--- a/wallee-c2ec/.idea/deploymentTargetSelector.xml
+++ b/wallee-c2ec/.idea/deploymentTargetSelector.xml
@@ -5,6 +5,9 @@
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
+ <SelectionState runConfigName="AuthorizePaymentScreenPreview">
+ <option name="selectionMode" value="DROPDOWN" />
+ </SelectionState>
</selectionStates>
</component>
</project>
\ No newline at end of file
diff --git a/wallee-c2ec/app/src/main/AndroidManifest.xml
b/wallee-c2ec/app/src/main/AndroidManifest.xml
index 5d5d90f..a44ee2d 100644
--- a/wallee-c2ec/app/src/main/AndroidManifest.xml
+++ b/wallee-c2ec/app/src/main/AndroidManifest.xml
@@ -13,6 +13,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Walleec2ec"
+ android:allowClearUserData="true"
+ android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClient.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClient.kt
index 9ced0c2..055b08a 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClient.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClient.kt
@@ -1,6 +1,6 @@
package ch.bfh.habej2.wallee_c2ec.client.taler
-import
ch.bfh.habej2.wallee_c2ec.client.taler.model.BankWitdrawalOperationStatus
+import
ch.bfh.habej2.wallee_c2ec.client.taler.model.BankWithdrawalOperationStatus
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalApiConfig
import
ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalConfirmationRequest
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetup
@@ -23,7 +23,7 @@ interface TerminalClient {
wopid: String,
longPollMs: Int,
oldState: WithdrawalOperationStatus =
WithdrawalOperationStatus.PENDING,
- callback: (Optional<BankWitdrawalOperationStatus>) -> Unit
+ callback: (Optional<BankWithdrawalOperationStatus>) -> Unit
)
fun sendConfirmationRequest(
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
index 6575c87..0c5f2b2 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
@@ -1,16 +1,14 @@
package ch.bfh.habej2.wallee_c2ec.client.taler
import ch.bfh.habej2.wallee_c2ec.client.taler.config.TalerTerminalConfig
-import
ch.bfh.habej2.wallee_c2ec.client.taler.model.BankWitdrawalOperationStatus
+import
ch.bfh.habej2.wallee_c2ec.client.taler.model.BankWithdrawalOperationStatus
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalApiConfig
import
ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalConfirmationRequest
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetup
import
ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetupResponse
import ch.bfh.habej2.wallee_c2ec.client.taler.model.WithdrawalOperationStatus
import com.squareup.moshi.Moshi
-import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.asCoroutineDispatcher
-import kotlinx.coroutines.newSingleThreadContext
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
@@ -22,11 +20,6 @@ import okio.IOException
import java.util.Optional
import java.util.concurrent.Executors
-class TerminalClientException(
- val status: Int,
- msg: String
-): RuntimeException(msg)
-
class TerminalClientImplementation (
private val config: TalerTerminalConfig
): TerminalClient {
@@ -96,7 +89,7 @@ class TerminalClientImplementation (
wopid: String,
longPollMs: Int,
oldState: WithdrawalOperationStatus,
- callback: (Optional<BankWitdrawalOperationStatus>) -> Unit
+ callback: (Optional<BankWithdrawalOperationStatus>) -> Unit
) = dispatcher.executor.execute {
val req = Request.Builder()
.get()
@@ -162,7 +155,7 @@ class TerminalClientImplementation (
}
return Optional.empty()
}
- throw TerminalClientException(response.code, "request unsuccessful")
+ return Optional.empty()
}
private class C2ECBasicAuthInterceptor(
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
index cf11d5b..ae0b769 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
@@ -1,7 +1,7 @@
package ch.bfh.habej2.wallee_c2ec.client.taler
import ch.bfh.habej2.wallee_c2ec.client.taler.encoding.CyptoUtils.encodeCrock
-import
ch.bfh.habej2.wallee_c2ec.client.taler.model.BankWitdrawalOperationStatus
+import
ch.bfh.habej2.wallee_c2ec.client.taler.model.BankWithdrawalOperationStatus
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalApiConfig
import
ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalConfirmationRequest
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetup
@@ -40,13 +40,13 @@ class TerminalClientMock: TerminalClient {
wopid: String,
longPollMs: Int,
oldState: WithdrawalOperationStatus,
- callback: (Optional<BankWitdrawalOperationStatus>) -> Unit
+ callback: (Optional<BankWithdrawalOperationStatus>) -> Unit
) {
Thread.sleep(longPollMs.toLong())
callback.invoke(
Optional.of(
- BankWitdrawalOperationStatus(
+ BankWithdrawalOperationStatus(
WithdrawalOperationStatus.SELECTED,
Amount(10,0),
Amount(10,0),
@@ -82,7 +82,7 @@ class TerminalClientMock: TerminalClient {
println("aborting withdrawal")
}
- private fun mockWopidOrReservePubKey(): String {
+ fun mockWopidOrReservePubKey(): String {
val wopid = ByteArray(32)
SecureRandom().nextBytes(wopid)
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/config/TerminalConfig.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/config/TerminalConfig.kt
deleted file mode 100644
index 0ef0ae6..0000000
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/config/TerminalConfig.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package ch.bfh.habej2.wallee_c2ec.client.taler.config
-
-// TODO how to configure ??
-
-data class TerminalConfig(
- val terminalId: String,
- val accessToken: String
-)
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
index 1d5389b..c3997ad 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
@@ -32,7 +32,7 @@ enum class WithdrawalOperationStatus(val value: String) {
ABORTED("aborted")
}
-data class BankWitdrawalOperationStatus(
+data class BankWithdrawalOperationStatus(
val status: WithdrawalOperationStatus,
val amount: Amount,
val suggestedAmount: Amount,
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AmountScreen.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AmountScreen.kt
index 7eae4ca..c984416 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AmountScreen.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AmountScreen.kt
@@ -2,56 +2,65 @@ package ch.bfh.habej2.wallee_c2ec.withdrawal
import android.annotation.SuppressLint
import android.app.Activity
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
-@SuppressLint("StateFlowValueCalledInComposition")
@Composable
-fun AmountScreen(model: WithdrawalViewModel, navigateToWhenAmountEntered: ()
-> Unit) {
+fun AmountScreen(model: WithdrawalViewModel, activity: Activity,
navigateToWhenAmountEntered: () -> Unit) {
- val activity = LocalContext.current as Activity
+ val uiState by model.uiState.collectAsState()
+ val configuration = LocalConfiguration.current
Column(
+ Modifier.width(configuration.screenWidthDp.dp),
+ verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- Text(model.uiState.value.amountError, color = Color.Red)
+ Text(uiState.amountError, color = Color.Red)
TextField(
- model.uiState.value.amountStr,
+ uiState.amountStr,
onValueChange = {
println(it)
if (!model.validateInput(it)) {
model.resetAmountStr()
}
},
- label = { Text(text = "Enter amount") },
+ label = { Text(text = "Withdrawal amount") },
keyboardOptions = KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Number
)
)
- Text(text = model.uiState.value.amountStr)
+ //Text(text = uiState.amountStr)
Button(onClick = {
println("clicked 'pay'")
model.setupWithdrawal(activity)
navigateToWhenAmountEntered()
- }, enabled = model.validAmount(model.uiState.value.amountStr)) {
- Text(text = "pay")
+ }, enabled = model.validAmount(uiState.amountStr)) {
+ Text(text = "withdraw")
}
Button(onClick = {
@@ -62,3 +71,13 @@ fun AmountScreen(model: WithdrawalViewModel,
navigateToWhenAmountEntered: () ->
}
}
}
+
+//@Preview
+//@Composable
+//fun AmountScreenPreview() {
+//
+// val m = WithdrawalViewModel()
+// m.validateInput("15.0")
+//
+// AmountScreen(model = m, Activity()) {}
+//}
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt
index 7761aa4..f1068d7 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/AuthorizePaymentScreen.kt
@@ -1,14 +1,24 @@
package ch.bfh.habej2.wallee_c2ec.withdrawal
import android.app.Activity
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.TextUnit
+import androidx.compose.ui.unit.dp
+import ch.bfh.habej2.wallee_c2ec.client.wallee.WalleeResponseHandler
import com.wallee.android.till.sdk.ApiClient
import com.wallee.android.till.sdk.data.LineItem
import com.wallee.android.till.sdk.data.Transaction
@@ -18,35 +28,59 @@ import java.math.BigDecimal
import java.util.Currency
@Composable
-fun AuthorizePaymentScreen(model: WithdrawalViewModel, client: ApiClient) {
+fun AuthorizePaymentScreen(model: WithdrawalViewModel, activity: Activity,
client: ApiClient) {
val uiState by model.uiState.collectAsState()
- val activity = LocalContext.current as Activity
+ val configuration = LocalConfiguration.current
-// val withdrawalAmount = LineItem
-// .ListBuilder(
-// uiState.encodedWopid,
-// BigDecimal("${uiState.amount.value}.${uiState.amount.frac}")
-// )
-// .build()
+ val withdrawalAmount = LineItem
+ .ListBuilder(uiState.encodedWopid, uiState.amount.toBigDecimal())
+ .build()
Column(
+ Modifier.width(configuration.screenWidthDp.dp),
+ verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- Text(text = "Authorizing transaction...")
+ if (uiState.transaction == null) {
+
+ Text(text = "Authorizing transaction...")
+
+ Button(onClick = {
+ model.withdrawalOperationFailed()
+ activity.finish()
+ }) {
+ Text(text = "abort")
+ }
+
+ } else {
- Button(onClick = { activity.finish() }) {
- Text(text = "finish")
+ Text(
+ text = "Amount authorized",
+ color = Color.Yellow,
+ modifier = Modifier.background(color = Color.Black)
+ )
+ Text(text = "Summary")
+ Text(text = "Withdrawable Amount: ${uiState.amount}
${uiState.currency}")
+ Text(text = "Fees: 0.30 ${uiState.currency}") // TODO fees
+ Text(text = "Withdrawal Operation ID (QR Code):")
+ QRCode(qrCodeContent = uiState.encodedWopid, 2.dp)
+
+ Button(onClick = {
+ activity.finish()
+ }) {
+ Text(text = "finish")
+ }
}
}
- val withdrawalAmount = LineItem
- .ListBuilder(
- uiState.encodedWopid,
- BigDecimal("3.0")
- )
- .build()
+// val withdrawalAmount = LineItem
+// .ListBuilder(
+// uiState.encodedWopid,
+// BigDecimal("3.0")
+// )
+// .build()
val transaction = Transaction.Builder(withdrawalAmount)
.setCurrency(Currency.getInstance(uiState.currency))
@@ -65,3 +99,17 @@ fun AuthorizePaymentScreen(model: WithdrawalViewModel,
client: ApiClient) {
e.printStackTrace()
}
}
+
+//@Preview
+//@Composable
+//fun AuthorizePaymentScreenPreview() {
+//
+// val m = WithdrawalViewModel()
+// m.mockExchange()
+// m.mockCurrency()
+// m.validateInput("75.50")
+// m.mockWopid()
+// m.mockTransaction()
+//
+// AuthorizePaymentScreen(model = m, activity = Activity(), client =
ApiClient(WalleeResponseHandler(WithdrawalActivity(), m)))
+//}
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
index 43ae57f..b7c8527 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
@@ -1,46 +1,72 @@
package ch.bfh.habej2.wallee_c2ec.withdrawal
import android.app.Activity
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.font.FontVariation.width
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
import ch.bfh.habej2.wallee_c2ec.client.taler.config.TalerTerminalConfig
val exchanges = listOf(
TalerTerminalConfig(
- "C2EC-Test",
+ "KUDOS Exchange (BFH)",
"http://taler-c2ec.ti.bfh.ch",
- "Wallee-2",
- "1A92pgloFR8WIgr0LDA+s9hbkO4EgyJlHj+3dQ9IJ9U="
+ "",
+ ""
+ ),
+
+ TalerTerminalConfig(
+ "CHF Exchange (PostFinance)",
+ "https://taler-c2ec.ti.bfh.ch",
+ "",
+ ""
+ ),
+
+ TalerTerminalConfig(
+ "EUR Exchange (UBS)",
+ "http://taler-c2ec.ti.bfh.ch",
+ "",
+ ""
)
)
@Composable
fun ExchangeSelectionScreen(
model: WithdrawalViewModel,
+ activity: Activity,
onNavigateToWithdrawal: () -> Unit
) {
- val activity = LocalContext.current as Activity
+ val configuration = LocalConfiguration.current
Column(
+ Modifier.width(configuration.screenWidthDp.dp),
+ verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Choose the exchange to withdraw from")
- Row {
- exchanges.forEach {
- Text(text = it.displayName)
- Button(onClick = {
- model.chooseExchange(it, activity)
- onNavigateToWithdrawal()
- }) {
- Text(text = "withdraw")
+ exchanges.forEach {
+ Row {
+ Column(
+ ) {
+ Button(onClick = {
+ model.chooseExchange(it, activity)
+ onNavigateToWithdrawal()
+ }, modifier =
Modifier.width(configuration.screenWidthDp.dp)) {
+ Text(text = it.displayName)
+ }
}
}
}
@@ -49,4 +75,13 @@ fun ExchangeSelectionScreen(
Text(text = "abort")
}
}
-}
\ No newline at end of file
+}
+
+//@Preview
+//@Composable
+//fun ExchangeSelectionScreenPreview() {
+//
+// ExchangeSelectionScreen(model = WithdrawalViewModel(), activity =
Activity()) {
+//
+// }
+//}
\ No newline at end of file
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/QRCodeComposable.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/QRCodeComposable.kt
index ed7cbc8..dfa2c4b 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/QRCodeComposable.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/QRCodeComposable.kt
@@ -37,7 +37,7 @@ import com.google.zxing.BarcodeFormat.QR_CODE
import com.google.zxing.qrcode.QRCodeWriter
@Composable
-fun QRCode(qrCodeContent: String) {
+fun QRCode(qrCodeContent: String, padding: Dp = 8.dp) {
Column {
@@ -47,7 +47,7 @@ fun QRCode(qrCodeContent: String) {
Image(
modifier = androidx.compose.ui.Modifier
.size(qrCodeSize)
- .padding(vertical = 8.dp),
+ .padding(vertical = padding),
bitmap = btmp,
contentDescription = "Scan the QR Code to start withdrawal",
)
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterParametersScreen.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterParametersScreen.kt
new file mode 100644
index 0000000..eff0fe6
--- /dev/null
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterParametersScreen.kt
@@ -0,0 +1,67 @@
+package ch.bfh.habej2.wallee_c2ec.withdrawal
+
+import android.app.Activity
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import ch.bfh.habej2.wallee_c2ec.client.wallee.WalleeResponseHandler
+import com.wallee.android.till.sdk.ApiClient
+
+@Composable
+fun RegisterParametersScreen(
+ model: WithdrawalViewModel,
+ activity: Activity,
+ navigateToWhenRegistered: () -> Unit
+) {
+
+ val uiState by model.uiState.collectAsState()
+ val configuration = LocalConfiguration.current
+
+ Column(
+ Modifier.width(configuration.screenWidthDp.dp),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+
+ Text(text = "Scan the QR Code with your Taler Wallet to")
+ Text(text = "register the withdrawal parameters")
+ // Text(text = "QR-Code content:
${TalerConstants.formatTalerUri(uiState.exchangeBankIntegrationApiUrl,
uiState.encodedWopid)}")
+
+
QRCode(TalerConstants.formatTalerUri(uiState.exchangeBankIntegrationApiUrl,
uiState.encodedWopid))
+
+ Button(onClick = {
+ model.withdrawalOperationFailed()
+ activity.finish()
+ }) {
+ Text(text = "abort")
+ }
+ }
+
+ model.startAuthorizationWhenReadyOrAbort(navigateToWhenRegistered) {
+ activity.finish()
+ }
+}
+
+//@Preview
+//@Composable
+//fun RegisterParametersScreenPreview() {
+//
+// val m = WithdrawalViewModel()
+// m.mockExchange()
+// m.mockCurrency()
+// m.validateInput("105.70")
+// m.mockWopid()
+//
+// RegisterParametersScreen(model = m, activity = Activity()) {}
+//}
\ No newline at end of file
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterWithdrawalScreen.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterWithdrawalScreen.kt
deleted file mode 100644
index 8a9fd70..0000000
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/RegisterWithdrawalScreen.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package ch.bfh.habej2.wallee_c2ec.withdrawal
-
-import android.app.Activity
-import androidx.compose.foundation.layout.Column
-import androidx.compose.material3.Button
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.getValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.platform.LocalContext
-
-@Composable
-fun RegisterWithdrawalScreen(
- model: WithdrawalViewModel,
- navigateToWhenRegistered: () -> Unit
-) {
-
- val uiState by model.uiState.collectAsState()
- val activity = (LocalContext.current as Activity)
-
- Column(
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
-
- Text(text = "QR-Code content:
${formatTalerUri(uiState.exchangeBankIntegrationApiUrl, uiState.encodedWopid)}")
-
- QRCode(formatTalerUri(uiState.exchangeBankIntegrationApiUrl,
uiState.encodedWopid))
-
- Button(onClick = {
- model.withdrawalOperationFailed()
- activity.finish()
- }) {
- Text(text = "abort")
- }
- }
-
- model.startAuthorizationWhenReadyOrAbort(navigateToWhenRegistered) {
- activity.finish()
- }
-}
-
-private fun formatTalerUri(exchangeBankIntegrationApiPath: String,
encodedWopid: String) =
- "taler://withdraw/$exchangeBankIntegrationApiPath/$encodedWopid"
\ No newline at end of file
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalActivity.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalActivity.kt
index 1f27bb1..7e4ca59 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalActivity.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalActivity.kt
@@ -3,7 +3,6 @@ package ch.bfh.habej2.wallee_c2ec.withdrawal
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
-import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
@@ -25,22 +24,22 @@ class WithdrawalActivity : ComponentActivity() {
NavHost(navController = navController, startDestination =
"chooseExchangeScreen") {
composable("chooseExchangeScreen") {
- ExchangeSelectionScreen(model) {
+ ExchangeSelectionScreen(model, this@WithdrawalActivity) {
navController.navigate("amountScreen")
}
}
composable("amountScreen") {
- AmountScreen(model) {
- navController.navigate("registerWithdrawalScreen")
+ AmountScreen(model, this@WithdrawalActivity) {
+ navController.navigate("registerParametersScreen")
}
}
- composable("registerWithdrawalScreen") {
- RegisterWithdrawalScreen(model) {
+ composable("registerParametersScreen") {
+ RegisterParametersScreen(model, this@WithdrawalActivity) {
navController.navigate("authorizePaymentScreen")
}
}
composable("authorizePaymentScreen") {
- AuthorizePaymentScreen(model, walleeClient)
+ AuthorizePaymentScreen(model, this@WithdrawalActivity,
walleeClient)
}
}
}
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
index d2c83a2..102cc35 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
@@ -14,28 +14,37 @@ import
ch.bfh.habej2.wallee_c2ec.client.taler.TerminalClientMock
import ch.bfh.habej2.wallee_c2ec.client.taler.config.TalerTerminalConfig
import
ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalConfirmationRequest
import ch.bfh.habej2.wallee_c2ec.client.taler.model.TerminalWithdrawalSetup
+import com.wallee.android.till.sdk.data.LineItem
+import com.wallee.android.till.sdk.data.ResultCode
import com.wallee.android.till.sdk.data.State
+import com.wallee.android.till.sdk.data.Transaction
import com.wallee.android.till.sdk.data.TransactionCompletionResponse
import com.wallee.android.till.sdk.data.TransactionResponse
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import java.io.Closeable
+import java.math.BigDecimal
import java.util.Optional
import java.util.UUID
-data class Amount(
- val value: Int,
- val frac: Int
-) {
+data class Amount(val value: Int, val frac: Int) {
- // fun toBigDecimal(): BigDecimal = BigDecimal("$value.$frac")
+ fun toBigDecimal(): BigDecimal = BigDecimal("$value.$frac")
override fun toString(): String {
return "$value.$frac"
}
}
+object TalerConstants {
+ const val TALER_INTEGRATION = "/taler-integration"
+ const val TALER_INTEGRATION_WITHDRAWAL_OPERATION = "/withdrawal-operation"
+
+ fun formatTalerUri(bankIntegrationApiPath: String, encodedWopid: String) =
+
"taler://withdraw/$bankIntegrationApiPath$TALER_INTEGRATION_WITHDRAWAL_OPERATION/$encodedWopid"
+}
+
@Stable
interface WithdrawalOperationState{
val requestUid: String
@@ -79,14 +88,15 @@ class WithdrawalViewModel(
return
}
- //terminalClient = TerminalClientImplementation(cfg)
- terminalClient = TerminalClientMock()
+ terminalClient = TerminalClientImplementation(cfg)
+ //terminalClient = TerminalClientMock()
_uiState.value = MutableWithdrawalOperationState() // reset withdrawal
operation
terminalClient!!.terminalsConfig {
if (!it.isPresent) {
activity.finish()
}
+ _uiState.value.exchangeBankIntegrationApiUrl =
"${cfg.terminalApiBaseUrl}${TalerConstants.TALER_INTEGRATION}"
this@WithdrawalViewModel.updateCurrency(it.get().currency)
}
exchangeSelected = true
@@ -110,7 +120,7 @@ class WithdrawalViewModel(
}
}
- fun validateInput(amount: String): Boolean {
+ fun validateInput(amount: String): Boolean {
println("validating amount input: $amount")
val validAmount = parseAmount(amount)
@@ -225,4 +235,42 @@ class WithdrawalViewModel(
println("resetting amountStr. was ${_uiState.value.amountStr}")
_uiState.value.amountStr = ""
}
+
+ // API's FOR TESTING / PREVIEW
+// fun mockExchange() {
+// val cfg = TalerTerminalConfig(
+// "CHF Exchange (BFH)",
+// "http://taler-c2ec.ti.bfh.ch",
+// "salut",
+// "ciao"
+// )
+//
+// _uiState.value.exchangeBankIntegrationApiUrl =
"${cfg.terminalApiBaseUrl}${TalerConstants.TALER_INTEGRATION}"
+// //chooseExchange(cfg, Activity())
+// }
+//
+// fun mockCurrency() {
+// updateCurrency("CHF")
+// }
+//
+// fun mockWopid() {
+// _uiState.value.encodedWopid =
TerminalClientMock().mockWopidOrReservePubKey()
+// }
+//
+// fun mockTransaction() {
+//
+// val mockedWopid = TerminalClientMock().mockWopidOrReservePubKey()
+// _uiState.value.transaction = TransactionResponse.Builder(
+// Transaction.Builder(
+// listOf(
+// LineItem.Builder("id", BigDecimal(23.50)).build()
+// )
+// )
+// .setMerchantReference(mockedWopid)
+// .setInvoiceReference(mockedWopid)
+// .build(),
+// State.SUCCESSFUL,
+// ResultCode("judihui", "the judihui result code indicates
absolute happiness"),
+// listOf()).build()
+// }
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-cashless2ecash] branch master updated: feat+docs: wallee app,
gnunet <=