/* 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 */ /** * Page shown to the user to confirm entering * a contract. */ /** * Imports. */ import { AmountJson, Amounts, amountToPretty, ConfirmPayResult, ConfirmPayResultType, ContractTerms, NotificationType, PreparePayResult, PreparePayResultType, Translate, } from "@gnu-taler/taler-util"; import { TalerError } 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 { useTranslationContext } from "../context/translation"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import * as wxApi from "../wxApi"; interface Props { talerPayUri?: string; goBack: () => void; } export function DepositPage({ talerPayUri, goBack }: Props): VNode { const { i18n } = useTranslationContext(); const [payStatus, setPayStatus] = useState( undefined, ); const [payResult, setPayResult] = useState( undefined, ); const [payErrMsg, setPayErrMsg] = useState( 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 => { try { const p = await wxApi.preparePay(talerPayUri); setPayStatus(p); } catch (e) { console.log("Got error while trying to pay", e); if (e instanceof TalerError) { setPayErrMsg(e); } if (e instanceof Error) { setPayErrMsg(e.message); } } }; doFetch(); }, [talerPayUri, foundAmountStr]); if (!talerPayUri) { return ( missing pay uri ); } if (!payStatus) { if (payErrMsg instanceof TalerError) { return (

Digital cash payment

Could not get the payment information for this order } error={payErrMsg?.errorDetail} />
); } if (payErrMsg) { return (

Digital cash payment

Could not get the payment information for this order

{payErrMsg}
); } return ( Loading payment information ... ); } const onClick = async (): Promise => { // try { // const res = await doPayment(payStatus); // setPayResult(res); // } catch (e) { // console.error(e); // if (e instanceof Error) { // setPayErrMsg(e.message); // } // } }; return ( ); } export interface PaymentRequestViewProps { payStatus: PreparePayResult; payResult?: ConfirmPayResult; onClick: () => void; payErrMsg?: string; uri: string; balance: AmountJson | undefined; } export function PaymentRequestView({ payStatus, payResult, }: PaymentRequestViewProps): VNode { let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw); const contractTerms: ContractTerms = payStatus.contractTerms; const { i18n } = useTranslationContext(); return (

Digital cash deposit

{payStatus.status === PreparePayResultType.AlreadyConfirmed && (payStatus.paid ? ( Already paid ) : ( Already claimed ))} {payResult && payResult.type === ConfirmPayResultType.Done && (

Payment complete

{!payResult.contractTerms.fulfillment_message ? ( You will now be sent back to the merchant you came from. ) : ( payResult.contractTerms.fulfillment_message )}

)}
{payStatus.status !== PreparePayResultType.InsufficientBalance && Amounts.isNonZero(totalFees) && ( Total to pay} text={amountToPretty( Amounts.parseOrThrow(payStatus.amountEffective), )} kind="negative" /> )} Purchase amount} text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))} kind="neutral" /> {Amounts.isNonZero(totalFees) && ( Fee} text={amountToPretty(totalFees)} kind="negative" /> )} Merchant} text={contractTerms.merchant.name} kind="neutral" /> Purchase} text={contractTerms.summary} kind="neutral" /> {contractTerms.order_id && ( Receipt} text={`#${contractTerms.order_id}`} kind="neutral" /> )}
); }