From ffd2a62c3f7df94365980302fef3bc3376b48182 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 3 Aug 2020 13:00:48 +0530 Subject: modularize repo, use pnpm, improve typechecking --- .../taler-wallet-webextension/src/pages/pay.tsx | 180 +++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 packages/taler-wallet-webextension/src/pages/pay.tsx (limited to 'packages/taler-wallet-webextension/src/pages/pay.tsx') diff --git a/packages/taler-wallet-webextension/src/pages/pay.tsx b/packages/taler-wallet-webextension/src/pages/pay.tsx new file mode 100644 index 000000000..2abd423bd --- /dev/null +++ b/packages/taler-wallet-webextension/src/pages/pay.tsx @@ -0,0 +1,180 @@ +/* + 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 * as i18n from "../i18n"; + + +import { renderAmount, ProgressButton } from "../renderHtml"; +import * as wxApi from "../wxApi"; + +import React, { useState, useEffect } from "react"; + +import { Amounts, AmountJson, walletTypes, talerTypes } from "taler-wallet-core"; + +function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { + const [payStatus, setPayStatus] = useState(); + const [payErrMsg, setPayErrMsg] = useState(""); + const [numTries, setNumTries] = useState(0); + const [loading, setLoading] = useState(false); + let amountEffective: AmountJson | undefined = undefined; + + useEffect(() => { + const doFetch = async (): Promise => { + const p = await wxApi.preparePay(talerPayUri); + setPayStatus(p); + }; + doFetch(); + }, [numTries, talerPayUri]); + + if (!payStatus) { + return Loading payment information ...; + } + + let insufficientBalance = false; + if (payStatus.status == "insufficient-balance") { + insufficientBalance = true; + } + + if (payStatus.status === "payment-possible") { + amountEffective = Amounts.parseOrThrow(payStatus.amountEffective); + } + + if (payStatus.status === walletTypes.PreparePayResultType.AlreadyConfirmed && numTries === 0) { + return ( + + You have already paid for this article. Click{" "} + here to view it again. + + ); + } + + let contractTerms: talerTypes.ContractTerms; + + try { + contractTerms = talerTypes.codecForContractTerms().decode(payStatus.contractTerms); + } catch (e) { + // This should never happen, as the wallet is supposed to check the contract terms + // before storing them. + console.error(e); + console.log("raw contract terms were", payStatus.contractTerms); + return Invalid contract terms.; + } + + if (!contractTerms) { + return ( + + Error: did not get contract terms from merchant or wallet backend. + + ); + } + + let merchantName: React.ReactElement; + if (contractTerms.merchant && contractTerms.merchant.name) { + merchantName = {contractTerms.merchant.name}; + } else { + merchantName = (pub: {contractTerms.merchant_pub}); + } + + const amount = ( + {renderAmount(Amounts.parseOrThrow(contractTerms.amount))} + ); + + const doPayment = async (): Promise => { + if (payStatus.status !== "payment-possible") { + throw Error(`invalid state: ${payStatus.status}`); + } + const proposalId = payStatus.proposalId; + setNumTries(numTries + 1); + try { + setLoading(true); + const res = await wxApi.confirmPay(proposalId, undefined); + document.location.href = res.nextUrl; + } catch (e) { + console.error(e); + setPayErrMsg(e.message); + } + }; + + return ( +
+

+ + The merchant {merchantName} offers you to purchase: + +

+ {contractTerms.summary} +
+ {amountEffective ? ( + + The total price is {amount} + (plus {renderAmount(amountEffective)} fees). + + ) : ( + + The total price is {amount}. + + )} +

+ + {insufficientBalance ? ( +
+

+ Unable to pay: Your balance is insufficient. +

+
+ ) : null} + + {payErrMsg ? ( +
+

Payment failed: {payErrMsg}

+ +
+ ) : ( +
+ doPayment()} + > + {i18n.str`Confirm payment`} + +
+ )} +
+ ); +} + +export function createPayPage(): JSX.Element { + const url = new URL(document.location.href); + const talerPayUri = url.searchParams.get("talerPayUri"); + if (!talerPayUri) { + throw Error("invalid parameter"); + } + return ; +} -- cgit v1.2.3