summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-01-10 16:04:53 -0300
committerSebastian <sebasjm@gmail.com>2022-01-10 16:07:27 -0300
commitfb22009ec4799a624f00c228fbd7435b44c1cbac (patch)
treeb1f8427e845bb3687b8a64deb3545eff2290ec67 /packages/taler-wallet-webextension/src/cta
parent83b9d32b7812e63640a60b5b42a27c96d8053bce (diff)
downloadwallet-core-fb22009ec4799a624f00c228fbd7435b44c1cbac.tar.gz
wallet-core-fb22009ec4799a624f00c228fbd7435b44c1cbac.tar.bz2
wallet-core-fb22009ec4799a624f00c228fbd7435b44c1cbac.zip
deposit design from belen, feature missing: kyc
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx168
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit.tsx251
-rw-r--r--packages/taler-wallet-webextension/src/cta/Pay.tsx29
3 files changed, 421 insertions, 27 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx
new file mode 100644
index 000000000..df5947bb1
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx
@@ -0,0 +1,168 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { ContractTerms, PreparePayResultType } from "@gnu-taler/taler-util";
+import { createExample } from "../test-utils";
+import { PaymentRequestView as TestedComponent } from "./Deposit";
+
+export default {
+ title: "cta/deposit",
+ component: TestedComponent,
+ argTypes: {},
+};
+
+export const NoBalance = createExample(TestedComponent, {
+ payStatus: {
+ status: PreparePayResultType.InsufficientBalance,
+ noncePriv: "",
+ proposalId: "proposal1234",
+ contractTerms: {
+ merchant: {
+ name: "someone",
+ },
+ summary: "some beers",
+ amount: "USD:10",
+ } as Partial<ContractTerms> as any,
+ amountRaw: "USD:10",
+ },
+});
+
+export const NoEnoughBalance = createExample(TestedComponent, {
+ payStatus: {
+ status: PreparePayResultType.InsufficientBalance,
+ noncePriv: "",
+ proposalId: "proposal1234",
+ contractTerms: {
+ merchant: {
+ name: "someone",
+ },
+ summary: "some beers",
+ amount: "USD:10",
+ } as Partial<ContractTerms> as any,
+ amountRaw: "USD:10",
+ },
+ balance: {
+ currency: "USD",
+ fraction: 40000000,
+ value: 9,
+ },
+});
+
+export const PaymentPossible = createExample(TestedComponent, {
+ uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0",
+ payStatus: {
+ status: PreparePayResultType.PaymentPossible,
+ amountEffective: "USD:10",
+ amountRaw: "USD:10",
+ noncePriv: "",
+ contractTerms: {
+ nonce: "123213123",
+ merchant: {
+ name: "someone",
+ },
+ amount: "USD:10",
+ summary: "some beers",
+ } as Partial<ContractTerms> as any,
+ contractTermsHash: "123456",
+ proposalId: "proposal1234",
+ },
+});
+
+export const PaymentPossibleWithFee = createExample(TestedComponent, {
+ uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0",
+ payStatus: {
+ status: PreparePayResultType.PaymentPossible,
+ amountEffective: "USD:10.20",
+ amountRaw: "USD:10",
+ noncePriv: "",
+ contractTerms: {
+ nonce: "123213123",
+ merchant: {
+ name: "someone",
+ },
+ amount: "USD:10",
+ summary: "some beers",
+ } as Partial<ContractTerms> as any,
+ contractTermsHash: "123456",
+ proposalId: "proposal1234",
+ },
+});
+
+export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, {
+ payStatus: {
+ status: PreparePayResultType.AlreadyConfirmed,
+ amountEffective: "USD:10",
+ amountRaw: "USD:10",
+ contractTerms: {
+ merchant: {
+ name: "someone",
+ },
+ fulfillment_message:
+ "congratulations! you are looking at the fulfillment message! ",
+ summary: "some beers",
+ amount: "USD:10",
+ } as Partial<ContractTerms> as any,
+ contractTermsHash: "123456",
+ proposalId: "proposal1234",
+ paid: false,
+ },
+});
+
+export const AlreadyConfirmedWithoutFullfilment = createExample(
+ TestedComponent,
+ {
+ payStatus: {
+ status: PreparePayResultType.AlreadyConfirmed,
+ amountEffective: "USD:10",
+ amountRaw: "USD:10",
+ contractTerms: {
+ merchant: {
+ name: "someone",
+ },
+ summary: "some beers",
+ amount: "USD:10",
+ } as Partial<ContractTerms> as any,
+ contractTermsHash: "123456",
+ proposalId: "proposal1234",
+ paid: false,
+ },
+ },
+);
+
+export const AlreadyPaid = createExample(TestedComponent, {
+ payStatus: {
+ status: PreparePayResultType.AlreadyConfirmed,
+ amountEffective: "USD:10",
+ amountRaw: "USD:10",
+ contractTerms: {
+ merchant: {
+ name: "someone",
+ },
+ fulfillment_message:
+ "congratulations! you are looking at the fulfillment message! ",
+ summary: "some beers",
+ amount: "USD:10",
+ } as Partial<ContractTerms> as any,
+ contractTermsHash: "123456",
+ proposalId: "proposal1234",
+ paid: true,
+ },
+});
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.tsx
new file mode 100644
index 000000000..3696b0c2d
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/cta/Deposit.tsx
@@ -0,0 +1,251 @@
+/*
+ This file is part of TALER
+ (C) 2015 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Page shown to the user to confirm entering
+ * a contract.
+ */
+
+/**
+ * Imports.
+ */
+// import * as i18n from "../i18n";
+
+import {
+ AmountJson,
+ Amounts,
+ amountToPretty,
+ ConfirmPayResult,
+ ConfirmPayResultDone,
+ ConfirmPayResultType,
+ ContractTerms,
+ i18n,
+ NotificationType,
+ PreparePayResult,
+ PreparePayResultType,
+} from "@gnu-taler/taler-util";
+import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
+import { Fragment, h, VNode } from "preact";
+import { useEffect, useState } from "preact/hooks";
+import { ErrorTalerOperation } from "../components/ErrorTalerOperation";
+import { LogoHeader } from "../components/LogoHeader";
+import { Part } from "../components/Part";
+import {
+ ErrorBox,
+ SuccessBox,
+ WalletAction,
+ WarningBox,
+} from "../components/styled";
+import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
+import * as wxApi from "../wxApi";
+
+interface Props {
+ talerPayUri?: string;
+ goBack: () => void;
+}
+
+export function DepositPage({ talerPayUri, goBack }: Props): VNode {
+ const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>(
+ undefined,
+ );
+ const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(
+ undefined,
+ );
+ const [payErrMsg, setPayErrMsg] = useState<
+ OperationFailedError | string | undefined
+ >(undefined);
+
+ const balance = useAsyncAsHook(wxApi.getBalance, [
+ NotificationType.CoinWithdrawn,
+ ]);
+ const balanceWithoutError = balance?.hasError
+ ? []
+ : balance?.response.balances || [];
+
+ const foundBalance = balanceWithoutError.find(
+ (b) =>
+ payStatus &&
+ Amounts.parseOrThrow(b.available).currency ===
+ Amounts.parseOrThrow(payStatus?.amountRaw).currency,
+ );
+ const foundAmount = foundBalance
+ ? Amounts.parseOrThrow(foundBalance.available)
+ : undefined;
+ // We use a string here so that dependency tracking for useEffect works properly
+ const foundAmountStr = foundAmount
+ ? Amounts.stringify(foundAmount)
+ : undefined;
+
+ useEffect(() => {
+ if (!talerPayUri) return;
+ const doFetch = async (): Promise<void> => {
+ try {
+ const p = await wxApi.preparePay(talerPayUri);
+ setPayStatus(p);
+ } catch (e) {
+ console.log("Got error while trying to pay", e);
+ if (e instanceof OperationFailedError) {
+ setPayErrMsg(e);
+ }
+ if (e instanceof Error) {
+ setPayErrMsg(e.message);
+ }
+ }
+ };
+ doFetch();
+ }, [talerPayUri, foundAmountStr]);
+
+ if (!talerPayUri) {
+ return <span>missing pay uri</span>;
+ }
+
+ if (!payStatus) {
+ if (payErrMsg instanceof OperationFailedError) {
+ return (
+ <WalletAction>
+ <LogoHeader />
+ <h2>{i18n.str`Digital cash payment`}</h2>
+ <section>
+ <ErrorTalerOperation
+ title="Could not get the payment information for this order"
+ error={payErrMsg?.operationError}
+ />
+ </section>
+ </WalletAction>
+ );
+ }
+ if (payErrMsg) {
+ return (
+ <WalletAction>
+ <LogoHeader />
+ <h2>{i18n.str`Digital cash payment`}</h2>
+ <section>
+ <p>Could not get the payment information for this order</p>
+ <ErrorBox>{payErrMsg}</ErrorBox>
+ </section>
+ </WalletAction>
+ );
+ }
+ return <span>Loading payment information ...</span>;
+ }
+
+ const onClick = async (): Promise<void> => {
+ // try {
+ // const res = await doPayment(payStatus);
+ // setPayResult(res);
+ // } catch (e) {
+ // console.error(e);
+ // if (e instanceof Error) {
+ // setPayErrMsg(e.message);
+ // }
+ // }
+ };
+
+ return (
+ <PaymentRequestView
+ uri={talerPayUri}
+ payStatus={payStatus}
+ payResult={payResult}
+ onClick={onClick}
+ balance={foundAmount}
+ />
+ );
+}
+
+export interface PaymentRequestViewProps {
+ payStatus: PreparePayResult;
+ payResult?: ConfirmPayResult;
+ onClick: () => void;
+ payErrMsg?: string;
+ uri: string;
+ balance: AmountJson | undefined;
+}
+export function PaymentRequestView({
+ uri,
+ payStatus,
+ payResult,
+ onClick,
+ balance,
+}: PaymentRequestViewProps): VNode {
+ let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw);
+ const contractTerms: ContractTerms = payStatus.contractTerms;
+
+ return (
+ <WalletAction>
+ <LogoHeader />
+
+ <h2>{i18n.str`Digital cash deposit`}</h2>
+ {payStatus.status === PreparePayResultType.AlreadyConfirmed &&
+ (payStatus.paid ? (
+ <SuccessBox> Already paid </SuccessBox>
+ ) : (
+ <WarningBox> Already claimed </WarningBox>
+ ))}
+ {payResult && payResult.type === ConfirmPayResultType.Done && (
+ <SuccessBox>
+ <h3>Payment complete</h3>
+ <p>
+ {!payResult.contractTerms.fulfillment_message
+ ? "You will now be sent back to the merchant you came from."
+ : payResult.contractTerms.fulfillment_message}
+ </p>
+ </SuccessBox>
+ )}
+ <section>
+ {payStatus.status !== PreparePayResultType.InsufficientBalance &&
+ Amounts.isNonZero(totalFees) && (
+ <Part
+ big
+ title="Total to pay"
+ text={amountToPretty(
+ Amounts.parseOrThrow(payStatus.amountEffective),
+ )}
+ kind="negative"
+ />
+ )}
+ <Part
+ big
+ title="Purchase amount"
+ text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))}
+ kind="neutral"
+ />
+ {Amounts.isNonZero(totalFees) && (
+ <Fragment>
+ <Part
+ big
+ title="Fee"
+ text={amountToPretty(totalFees)}
+ kind="negative"
+ />
+ </Fragment>
+ )}
+ <Part
+ title="Merchant"
+ text={contractTerms.merchant.name}
+ kind="neutral"
+ />
+ <Part title="Purchase" text={contractTerms.summary} kind="neutral" />
+ {contractTerms.order_id && (
+ <Part
+ title="Receipt"
+ text={`#${contractTerms.order_id}`}
+ kind="neutral"
+ />
+ )}
+ </section>
+ </WalletAction>
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx
index d7419d410..e61d3a9d6 100644
--- a/packages/taler-wallet-webextension/src/cta/Pay.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx
@@ -57,35 +57,10 @@ import * as wxApi from "../wxApi";
interface Props {
talerPayUri?: string;
- goToWalletManualWithdraw: () => void;
+ goToWalletManualWithdraw: (currency?: string) => void;
+ goBack: () => void;
}
-// export function AlreadyPaid({ payStatus }: { payStatus: PreparePayResult }) {
-// const fulfillmentUrl = payStatus.contractTerms.fulfillment_url;
-// let message;
-// if (fulfillmentUrl) {
-// message = (
-// <span>
-// You have already paid for this article. Click{" "}
-// <a href={fulfillmentUrl} target="_bank" rel="external">here</a> to view it again.
-// </span>
-// );
-// } else {
-// message = <span>
-// You have already paid for this article:{" "}
-// <em>
-// {payStatus.contractTerms.fulfillment_message ?? "no message given"}
-// </em>
-// </span>;
-// }
-// return <section class="main">
-// <h1>GNU Taler Wallet</h1>
-// <article class="fade">
-// {message}
-// </article>
-// </section>
-// }
-
const doPayment = async (
payStatus: PreparePayResult,
): Promise<ConfirmPayResultDone> => {