/* This file is part of GNU Taler (C) 2021-2023 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 */ /** * * @author Sebastian Javier Marchano (sebasjm) */ import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { QR } from "../../../../components/exception/QR.js"; import { FormErrors, FormProvider, } from "../../../../components/form/FormProvider.js"; import { Input } from "../../../../components/form/Input.js"; import { InputCurrency } from "../../../../components/form/InputCurrency.js"; import { ConfirmModal } from "../../../../components/modal/index.js"; import { useBackendContext } from "../../../../context/backend.js"; import { useConfigContext } from "../../../../context/config.js"; import { useInstanceContext } from "../../../../context/instance.js"; import { MerchantBackend } from "../../../../declaration.js"; type Entity = MerchantBackend.Template.UsingTemplateDetails; interface Props { template: MerchantBackend.Template.TemplateDetails; id: string; onBack?: () => void; } export function QrPage({ template, id: templateId, onBack }: Props): VNode { const { i18n } = useTranslationContext(); const { url: backendUrl } = useBackendContext(); const { id: instanceId } = useInstanceContext(); const config = useConfigContext(); const [setupTOTP, setSetupTOTP] = useState(false); const [state, setState] = useState>({ amount: template.template_contract.amount, summary: template.template_contract.summary, }); const errors: FormErrors = {}; const hasErrors = Object.keys(errors).some( (k) => (errors as any)[k] !== undefined, ); const fixedAmount = !!template.template_contract.amount; const fixedSummary = !!template.template_contract.summary; const params = new URLSearchParams(); if (!fixedAmount) { if (state.amount) { params.append("amount", state.amount); } else { params.append("amount", config.currency); } } if (!fixedSummary) { params.append("summary", state.summary ?? ""); } const paramsStr = fixedAmount && fixedSummary ? "" : "?" + params.toString(); const merchantURL = new URL(backendUrl); const talerProto = merchantURL.protocol === "http:" ? "taler+http:" : "taler:"; const payTemplateUri = `${talerProto}//pay-template/${merchantURL.hostname}/${templateId}${paramsStr}`; const issuer = encodeURIComponent( `${new URL(backendUrl).hostname}/${instanceId}`, ); const oauthUri = !template.pos_algorithm ? undefined : template.pos_algorithm === 1 ? `otpauth://totp/${issuer}:${templateId}?secret=${template.pos_key}&issuer=${issuer}&algorithm=SHA1&digits=8&period=30` : template.pos_algorithm === 2 ? `otpauth://totp/${issuer}:${templateId}?secret=${template.pos_key}&issuer=${issuer}&algorithm=SHA1&digits=8&period=30` : undefined; const keySlice = template.pos_key?.substring(0, 4); const oauthUriWithoutSecret = !template.pos_algorithm ? undefined : template.pos_algorithm === 1 ? `otpauth://totp/${issuer}:${templateId}?secret=${keySlice}...&issuer=${issuer}&algorithm=SHA1&digits=8&period=30` : template.pos_algorithm === 2 ? `otpauth://totp/${issuer}:${templateId}?secret=${keySlice}...&issuer=${issuer}&algorithm=SHA1&digits=8&period=30` : undefined; return (
{oauthUri && ( { setSetupTOTP(false); }} >

Scan this qr code with your TOTP device

            {oauthUriWithoutSecret}
          
)}

Here you can specify a default value for fields that are not fixed. Default values can be edited by the customer before the payment.

name="amount" label={ fixedAmount ? i18n.str`Fixed amount` : i18n.str`Default amount` } readonly={fixedAmount} tooltip={i18n.str`Amount of the order`} /> name="summary" inputType="multiline" readonly={fixedSummary} label={ fixedSummary ? i18n.str`Fixed summary` : i18n.str`Default summary` } tooltip={i18n.str`Title of the order to be shown to the customer`} />
{onBack && ( )} {oauthUri && ( )}
          {payTemplateUri}
        
); } function saveAsPDF(name: string): void { const printWindow = window.open("", "", "height=400,width=800"); if (!printWindow) return; const divContents = document.getElementById("printThis"); if (!divContents) return; printWindow.document.write( `Order template for ${name} "); printWindow.document.close(); printWindow.document.body.appendChild(divContents.cloneNode(true)); printWindow.addEventListener("load", () => { printWindow.print(); printWindow.close(); }); }