/* 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, PreparePayResult, PreparePayResultType, ContractTerms, ConfirmPayResultType, ConfirmPayResult, getJsonI18n, } from "@gnu-taler/taler-wallet-core"; function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { const [payStatus, setPayStatus] = useState(); const [payResult, setPayResult] = useState(); const [payErrMsg, setPayErrMsg] = useState(""); const [numTries, setNumTries] = useState(0); const [loading, setLoading] = useState(false); let totalFees: 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 == PreparePayResultType.InsufficientBalance) { insufficientBalance = true; } if (payStatus.status === PreparePayResultType.PaymentPossible) { let amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); let amountEffective: AmountJson = Amounts.parseOrThrow(payStatus.amountEffective); totalFees = Amounts.sub(amountEffective, amountRaw).amount; } if ( payStatus.status === PreparePayResultType.AlreadyConfirmed && numTries === 0 ) { const fulfillmentUrl = payStatus.contractTerms.fulfillment_url; if (fulfillmentUrl) { return ( You have already paid for this article. Click{" "} here to view it again. ); } else { You have already paid for this article:{" "} {payStatus.contractTerms.fulfillment_message ?? "no message given"} ; } } let contractTerms: ContractTerms = payStatus.contractTerms; 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); if (res.type !== ConfirmPayResultType.Done) { throw Error("payment pending"); } const fu = res.contractTerms.fulfillment_url; if (fu) { document.location.href = fu; } setPayResult(res); } catch (e) { console.error(e); setPayErrMsg(e.message); } }; 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 ...; } } return (

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}

) : (
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 ; }