From 97a05ff659af274dcfcd9c76bf19100bbd51ce0e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 19 Aug 2021 00:34:47 -0300 Subject: new wallet history and view refactoring --- packages/taler-wallet-webextension/src/cta/Pay.tsx | 253 +++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 packages/taler-wallet-webextension/src/cta/Pay.tsx (limited to 'packages/taler-wallet-webextension/src/cta/Pay.tsx') diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx new file mode 100644 index 000000000..a5849bb28 --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx @@ -0,0 +1,253 @@ +/* + 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 { useState, useEffect } from "preact/hooks"; + +import { ConfirmPayResultDone, getJsonI18n, i18n } from "@gnu-taler/taler-util"; +import { + PreparePayResult, + ConfirmPayResult, + AmountJson, + PreparePayResultType, + Amounts, + ContractTerms, + ConfirmPayResultType, +} from "@gnu-taler/taler-util"; +import { JSX, VNode } from "preact"; + +interface Props { + talerPayUri?: string +} + +export function AlreadyPaid({ payStatus }: { payStatus: PreparePayResult }) { + const fulfillmentUrl = payStatus.contractTerms.fulfillment_url; + let message; + if (fulfillmentUrl) { + message = ( + + You have already paid for this article. Click{" "} + here to view it again. + + ); + } else { + message = + You have already paid for this article:{" "} + + {payStatus.contractTerms.fulfillment_message ?? "no message given"} + + ; + } + return
+

GNU Taler Wallet

+
+ {message} +
+
+} + +const doPayment = async (payStatus: PreparePayResult): Promise => { + if (payStatus.status !== "payment-possible") { + throw Error(`invalid state: ${payStatus.status}`); + } + const proposalId = payStatus.proposalId; + const res = await wxApi.confirmPay(proposalId, undefined); + if (res.type !== ConfirmPayResultType.Done) { + throw Error("payment pending"); + } + const fu = res.contractTerms.fulfillment_url; + if (fu) { + document.location.href = fu; + } + return res; +}; + + + +export function PayPage({ talerPayUri }: Props): JSX.Element { + const [payStatus, setPayStatus] = useState(undefined); + const [payResult, setPayResult] = useState(undefined); + const [payErrMsg, setPayErrMsg] = useState(""); + + useEffect(() => { + if (!talerPayUri) return; + const doFetch = async (): Promise => { + const p = await wxApi.preparePay(talerPayUri); + setPayStatus(p); + }; + doFetch(); + }, [talerPayUri]); + + if (!talerPayUri) { + return missing pay uri + } + + if (!payStatus) { + return Loading payment information ...; + } + + if (payResult && payResult.type === ConfirmPayResultType.Done) { + if (payResult.contractTerms.fulfillment_message) { + const obj = { + fulfillment_message: payResult.contractTerms.fulfillment_message, + fulfillment_message_i18n: + payResult.contractTerms.fulfillment_message_i18n, + }; + const msg = getJsonI18n(obj, "fulfillment_message"); + return ( +
+

Payment succeeded.

+

{msg}

+
+ ); + } else { + return Redirecting ...; + } + } + + const onClick = async () => { + try { + const res = await doPayment(payStatus) + setPayResult(res); + } catch (e) { + console.error(e); + setPayErrMsg(e.message); + } + + } + + return ; +} + +export interface PaymentRequestViewProps { + payStatus: PreparePayResult; + onClick: () => void; + payErrMsg?: string; + +} +export function PaymentRequestView({ payStatus, onClick, payErrMsg }: PaymentRequestViewProps) { + let totalFees: AmountJson | undefined = undefined; + let insufficientBalance = false; + const [loading, setLoading] = useState(false); + const contractTerms: ContractTerms = payStatus.contractTerms; + + if ( + payStatus.status === PreparePayResultType.AlreadyConfirmed + ) { + return + } + + if (!contractTerms) { + return ( + + Error: did not get contract terms from merchant or wallet backend. + + ); + } + + if (payStatus.status == PreparePayResultType.InsufficientBalance) { + insufficientBalance = true; + } + + if (payStatus.status === PreparePayResultType.PaymentPossible) { + const amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); + const amountEffective: AmountJson = Amounts.parseOrThrow( + payStatus.amountEffective, + ); + totalFees = Amounts.sub(amountEffective, amountRaw).amount; + } + + let merchantName: VNode; + if (contractTerms.merchant && contractTerms.merchant.name) { + merchantName = {contractTerms.merchant.name}; + } else { + merchantName = (pub: {contractTerms.merchant_pub}); + } + + const amount = ( + {renderAmount(Amounts.parseOrThrow(contractTerms.amount))} + ); + + return
+

GNU Taler Wallet

+
+
+

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

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

+ + {insufficientBalance ? ( +
+

+ Unable to pay: Your balance is insufficient. +

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

Payment failed: {payErrMsg}

+ +
+ ) : ( +
+ + {i18n.str`Confirm payment`} + +
+ )} +
+
+
+ + +} \ No newline at end of file -- cgit v1.2.3