show QR with nonce
This commit is contained in:
Sebastian 2023-07-03 12:43:47 -03:00
parent 5d76573ac0
commit 545bf16cdf
No known key found for this signature in database
GPG Key ID: 173909D1A5F66069
4 changed files with 39 additions and 22 deletions

View File

@ -21,6 +21,8 @@ import {
PreparePayResult, PreparePayResult,
PreparePayResultType, PreparePayResultType,
TranslatedString, TranslatedString,
parsePayUri,
stringifyPayUri,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
@ -32,6 +34,8 @@ import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { Button } from "../mui/Button.js"; import { Button } from "../mui/Button.js";
import { ButtonHandler } from "../mui/handlers.js"; import { ButtonHandler } from "../mui/handlers.js";
import { assertUnreachable } from "../utils/index.js"; import { assertUnreachable } from "../utils/index.js";
import { useBackendContext } from "../context/backend.js";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
interface Props { interface Props {
payStatus: PreparePayResult; payStatus: PreparePayResult;
@ -50,8 +54,6 @@ export function PaymentButtons({
}: Props): VNode { }: Props): VNode {
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
if (payStatus.status === PreparePayResultType.PaymentPossible) { if (payStatus.status === PreparePayResultType.PaymentPossible) {
const privateUri = `${uri}&n=${payStatus.noncePriv}`;
return ( return (
<Fragment> <Fragment>
<section> <section>
@ -66,7 +68,7 @@ export function PaymentButtons({
</i18n.Translate> </i18n.Translate>
</Button> </Button>
</section> </section>
<PayWithMobile uri={privateUri} /> <PayWithMobile uri={uri} />
</Fragment> </Fragment>
); );
} }
@ -125,7 +127,6 @@ export function PaymentButtons({
default: default:
assertUnreachable(reason); assertUnreachable(reason);
} }
const uriPrivate = `${uri}&n=${payStatus.noncePriv}`;
return ( return (
<Fragment> <Fragment>
@ -141,7 +142,7 @@ export function PaymentButtons({
<i18n.Translate>Get digital cash</i18n.Translate> <i18n.Translate>Get digital cash</i18n.Translate>
</Button> </Button>
</section> </section>
<PayWithMobile uri={uriPrivate} /> <PayWithMobile uri={uri} />
</Fragment> </Fragment>
); );
} }
@ -159,7 +160,6 @@ export function PaymentButtons({
/> />
)} )}
</section> </section>
{!payStatus.paid && <PayWithMobile uri={uri} />}
</Fragment> </Fragment>
); );
} }
@ -169,20 +169,36 @@ export function PaymentButtons({
function PayWithMobile({ uri }: { uri: string }): VNode { function PayWithMobile({ uri }: { uri: string }): VNode {
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
const api = useBackendContext();
const [showQR, setShowQR] = useState<boolean>(false); const payUri = parsePayUri(uri);
const [showQR, setShowQR] = useState<string | undefined>(undefined);
async function sharePrivatePaymentURI() {
if (!payUri) {
return;
}
if (!showQR) {
const result = await api.wallet.call(WalletApiOperation.SharePayment, {
merchantBaseUrl: payUri.merchantBaseUrl,
orderId: payUri.orderId,
});
setShowQR(result.privatePayUri);
} else {
setShowQR(undefined);
}
}
return ( return (
<section> <section>
<LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}> <LinkSuccess upperCased onClick={sharePrivatePaymentURI}>
{!showQR ? i18n.str`Pay with a mobile phone` : i18n.str`Hide QR`} {!showQR ? i18n.str`Pay with a mobile phone` : i18n.str`Hide QR`}
</LinkSuccess> </LinkSuccess>
{showQR && ( {showQR && (
<div> <div>
<QR text={uri} /> <QR text={showQR} />
<i18n.Translate> <i18n.Translate>
Scan the QR code or &nbsp; Scan the QR code or &nbsp;
<a href={uri}> <a href={showQR}>
<i18n.Translate>click here</i18n.Translate> <i18n.Translate>click here</i18n.Translate>
</a> </a>
</i18n.Translate> </i18n.Translate>

View File

@ -102,7 +102,6 @@ export function useComponentState({
contractTermsHash: "asd", contractTermsHash: "asd",
amountRaw: hook.response.p2p.amount, amountRaw: hook.response.p2p.amount,
amountEffective: hook.response.p2p.amount, amountEffective: hook.response.p2p.amount,
noncePriv: "",
} as PreparePayResult; } as PreparePayResult;
const insufficientBalance: PreparePayResult = { const insufficientBalance: PreparePayResult = {

View File

@ -61,7 +61,7 @@ export const NoEnoughBalanceAvailable = tests.createExample(BaseView, {
feeGapEstimate: "USD:1", feeGapEstimate: "USD:1",
}, },
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
noncePriv: "",
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
contractTerms: { contractTerms: {
merchant: { merchant: {
@ -101,7 +101,7 @@ export const NoEnoughBalanceMaterial = tests.createExample(BaseView, {
feeGapEstimate: "USD:1", feeGapEstimate: "USD:1",
}, },
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
noncePriv: "",
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
contractTerms: { contractTerms: {
merchant: { merchant: {
@ -141,7 +141,7 @@ export const NoEnoughBalanceAgeAcceptable = tests.createExample(BaseView, {
feeGapEstimate: "USD:1", feeGapEstimate: "USD:1",
}, },
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
noncePriv: "",
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
contractTerms: { contractTerms: {
merchant: { merchant: {
@ -182,7 +182,7 @@ export const NoEnoughBalanceMerchantAcceptable = tests.createExample(BaseView, {
feeGapEstimate: "USD:1", feeGapEstimate: "USD:1",
}, },
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
noncePriv: "",
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
contractTerms: { contractTerms: {
merchant: { merchant: {
@ -224,7 +224,7 @@ export const NoEnoughBalanceMerchantDepositable = tests.createExample(
feeGapEstimate: "USD:1", feeGapEstimate: "USD:1",
}, },
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
noncePriv: "",
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
contractTerms: { contractTerms: {
merchant: { merchant: {
@ -265,7 +265,7 @@ export const NoEnoughBalanceFeeGap = tests.createExample(BaseView, {
feeGapEstimate: "USD:1", feeGapEstimate: "USD:1",
}, },
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
noncePriv: "",
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
contractTerms: { contractTerms: {
merchant: { merchant: {
@ -302,7 +302,7 @@ export const PaymentPossible = tests.createExample(BaseView, {
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
amountEffective: "USD:10", amountEffective: "USD:10",
amountRaw: "USD:10", amountRaw: "USD:10",
noncePriv: "",
contractTerms: { contractTerms: {
nonce: "123213123", nonce: "123213123",
merchant: { merchant: {
@ -342,7 +342,7 @@ export const PaymentPossibleWithFee = tests.createExample(BaseView, {
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
amountEffective: "USD:10.20", amountEffective: "USD:10.20",
amountRaw: "USD:10", amountRaw: "USD:10",
noncePriv: "",
contractTerms: { contractTerms: {
nonce: "123213123", nonce: "123213123",
merchant: { merchant: {
@ -379,7 +379,7 @@ export const TicketWithAProductList = tests.createExample(BaseView, {
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
amountEffective: "USD:10.20", amountEffective: "USD:10.20",
amountRaw: "USD:10", amountRaw: "USD:10",
noncePriv: "",
contractTerms: { contractTerms: {
nonce: "123213123", nonce: "123213123",
merchant: { merchant: {
@ -435,7 +435,7 @@ export const TicketWithShipping = tests.createExample(BaseView, {
talerUri: "taler://pay/..", talerUri: "taler://pay/..",
amountEffective: "USD:10.20", amountEffective: "USD:10.20",
amountRaw: "USD:10", amountRaw: "USD:10",
noncePriv: "",
contractTerms: { contractTerms: {
nonce: "123213123", nonce: "123213123",
merchant: { merchant: {

View File

@ -47,7 +47,9 @@ export function BaseView(state: SupportedStates): VNode {
const effective = const effective =
"amountEffective" in state.payStatus "amountEffective" in state.payStatus
? state.payStatus.amountEffective
? Amounts.parseOrThrow(state.payStatus.amountEffective) ? Amounts.parseOrThrow(state.payStatus.amountEffective)
: Amounts.zeroOfCurrency(state.amount.currency)
: state.amount; : state.amount;
return ( return (