summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/pay-merchant.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/pay-merchant.ts')
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts104
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, {