diff options
Diffstat (limited to 'packages/taler-wallet-core/src/pay-merchant.ts')
-rw-r--r-- | packages/taler-wallet-core/src/pay-merchant.ts | 104 |
1 files changed, 81 insertions, 23 deletions
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts index 49ebc282e..090a11cf0 100644 --- a/packages/taler-wallet-core/src/pay-merchant.ts +++ b/packages/taler-wallet-core/src/pay-merchant.ts @@ -34,13 +34,17 @@ import { assertUnreachable, AsyncFlag, checkDbInvariant, + CheckPaymentResponse, + CheckPayTemplateReponse, + CheckPayTemplateRequest, codecForAbortResponse, codecForMerchantContractTerms, codecForMerchantOrderStatusPaid, codecForMerchantPayResponse, - codecForMerchantPostOrderResponse, + codecForPostOrderResponse, codecForProposal, codecForWalletRefundResponse, + codecForWalletTemplateDetails, CoinDepositPermission, CoinRefreshRequest, ConfirmPayResult, @@ -76,6 +80,8 @@ import { TalerError, TalerErrorCode, TalerErrorDetail, + TalerMerchantApi, + TalerMerchantInstanceHttpClient, TalerPreciseTimestamp, TalerProtocolViolationError, TalerUriAction, @@ -1578,39 +1584,92 @@ async function internalWaitProposalDownloaded( } } +async function downloadTemplate( + wex: WalletExecutionContext, + merchantBaseUrl: string, + templateId: string, +): Promise<TalerMerchantApi.WalletTemplateDetails> { + const reqUrl = new URL(`templates/${templateId}`, merchantBaseUrl); + const httpReq = await wex.http.fetch(reqUrl.href, { + method: "GET", + cancellationToken: wex.cancellationToken, + }); + const resp = await readSuccessResponseJsonOrThrow( + httpReq, + codecForWalletTemplateDetails(), + ); + return resp; +} + +export async function checkPayForTemplate( + wex: WalletExecutionContext, + req: CheckPayTemplateRequest, +): Promise<CheckPayTemplateReponse> { + const parsedUri = parsePayTemplateUri(req.talerPayTemplateUri); + if (!parsedUri) { + throw Error("invalid taler-template URI"); + } + const templateDetails = await downloadTemplate( + wex, + parsedUri.merchantBaseUrl, + parsedUri.templateId, + ); + + const merchantApi = new TalerMerchantInstanceHttpClient( + parsedUri.merchantBaseUrl, + wex.http, + ); + + const cfg = await merchantApi.getConfig(); + if (cfg.type === "fail") { + throw TalerError.fromUncheckedDetail(cfg.detail); + } + + return { + templateDetails, + supportedCurrencies: Object.keys(cfg.body.currencies), + }; +} + export async function preparePayForTemplate( wex: WalletExecutionContext, req: PreparePayTemplateRequest, ): Promise<PreparePayResult> { const parsedUri = parsePayTemplateUri(req.talerPayTemplateUri); - const templateDetails: MerchantUsingTemplateDetails = {}; if (!parsedUri) { throw Error("invalid taler-template URI"); } logger.trace(`parsed URI: ${j2s(parsedUri)}`); + const templateDetails: MerchantUsingTemplateDetails = {}; - const amountFromUri = parsedUri.templateParams.amount; - if (amountFromUri != null) { - const templateParamsAmount = req.templateParams?.amount; - if (templateParamsAmount != null) { - templateDetails.amount = templateParamsAmount as AmountString; - } else { - if (Amounts.isCurrency(amountFromUri)) { - throw Error( - "Amount from template URI only has a currency without value. The value must be provided in the templateParams.", - ); - } else { - templateDetails.amount = amountFromUri as AmountString; - } + const templateInfo = await downloadTemplate( + wex, + parsedUri.merchantBaseUrl, + parsedUri.templateId, + ); + + const templateParamsAmount = req.templateParams?.amount as + | AmountString + | undefined; + if (templateParamsAmount === null) { + const amountFromUri = templateInfo.editable_defaults?.amount; + if (amountFromUri != null) { + templateDetails.amount = amountFromUri as AmountString; } + } else { + templateDetails.amount = templateParamsAmount; } - if ( - parsedUri.templateParams.summary !== undefined && - typeof parsedUri.templateParams.summary === "string" - ) { - templateDetails.summary = - req.templateParams?.summary ?? parsedUri.templateParams.summary; + + const templateParamsSummary = req.templateParams?.summary; + if (templateParamsSummary === null) { + const summaryFromUri = templateInfo.editable_defaults?.summary; + if (summaryFromUri != null) { + templateDetails.summary = summaryFromUri; + } + } else { + templateDetails.summary = templateParamsSummary; } + const reqUrl = new URL( `templates/${parsedUri.templateId}`, parsedUri.merchantBaseUrl, @@ -1621,7 +1680,7 @@ export async function preparePayForTemplate( }); const resp = await readSuccessResponseJsonOrThrow( httpReq, - codecForMerchantPostOrderResponse(), + codecForPostOrderResponse(), ); const payUri = stringifyPayUri({ @@ -2875,7 +2934,6 @@ async function processPurchaseAutoRefund( ); requestUrl.searchParams.set("timeout_ms", "10000"); - requestUrl.searchParams.set("await_refund_obtained", "yes"); requestUrl.searchParams.set("refund", Amounts.stringify(totalKnownRefund)); const resp = await wex.http.fetch(requestUrl.href, { |