add prepareRefund operation to gather information about the refund before confirm
This commit is contained in:
parent
9996c27488
commit
e5c9f588e4
@ -276,6 +276,18 @@ export class ReturnCoinsRequest {
|
|||||||
static checked: (obj: any) => ReturnCoinsRequest;
|
static checked: (obj: any) => ReturnCoinsRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PrepareRefundResult {
|
||||||
|
proposalId: string;
|
||||||
|
|
||||||
|
applied: number;
|
||||||
|
failed: number;
|
||||||
|
total: number;
|
||||||
|
|
||||||
|
amountEffectivePaid: AmountString;
|
||||||
|
|
||||||
|
info: OrderShortInfo;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PrepareTipResult {
|
export interface PrepareTipResult {
|
||||||
/**
|
/**
|
||||||
* Unique ID for the tip assigned by the wallet.
|
* Unique ID for the tip assigned by the wallet.
|
||||||
@ -1003,6 +1015,17 @@ export const codecForForceRefreshRequest = (): Codec<ForceRefreshRequest> =>
|
|||||||
.property("coinPubList", codecForList(codecForString()))
|
.property("coinPubList", codecForList(codecForString()))
|
||||||
.build("ForceRefreshRequest");
|
.build("ForceRefreshRequest");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface PrepareRefundRequest {
|
||||||
|
talerRefundUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const codecForPrepareRefundRequest = (): Codec<PrepareRefundRequest> =>
|
||||||
|
buildCodecForObject<PrepareRefundRequest>()
|
||||||
|
.property("talerRefundUri", codecForString())
|
||||||
|
.build("PrepareRefundRequest");
|
||||||
|
|
||||||
export interface PrepareTipRequest {
|
export interface PrepareTipRequest {
|
||||||
talerTipUri: string;
|
talerTipUri: string;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ import {
|
|||||||
AbsoluteTime,
|
AbsoluteTime,
|
||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
Duration,
|
Duration,
|
||||||
|
PrepareRefundRequest,
|
||||||
|
PrepareRefundResult,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
AbortStatus,
|
AbortStatus,
|
||||||
@ -69,6 +71,72 @@ import { guardOperationException } from "./common.js";
|
|||||||
|
|
||||||
const logger = new Logger("refund.ts");
|
const logger = new Logger("refund.ts");
|
||||||
|
|
||||||
|
|
||||||
|
export async function prepareRefund(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
talerRefundUri: string,
|
||||||
|
): Promise<PrepareRefundResult> {
|
||||||
|
const parseResult = parseRefundUri(talerRefundUri);
|
||||||
|
|
||||||
|
logger.trace("preparing refund offer", parseResult);
|
||||||
|
|
||||||
|
if (!parseResult) {
|
||||||
|
throw Error("invalid refund URI");
|
||||||
|
}
|
||||||
|
|
||||||
|
const purchase = await ws.db
|
||||||
|
.mktx((x) => ({
|
||||||
|
purchases: x.purchases,
|
||||||
|
}))
|
||||||
|
.runReadOnly(async (tx) => {
|
||||||
|
return tx.purchases.indexes.byMerchantUrlAndOrderId.get([
|
||||||
|
parseResult.merchantBaseUrl,
|
||||||
|
parseResult.orderId,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!purchase) {
|
||||||
|
throw Error(
|
||||||
|
`no purchase for the taler://refund/ URI (${talerRefundUri}) was found`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const proposalId = purchase.proposalId;
|
||||||
|
const rfs = Object.values(purchase.refunds)
|
||||||
|
|
||||||
|
let applied = 0;
|
||||||
|
let failed = 0;
|
||||||
|
const total = rfs.length;
|
||||||
|
rfs.forEach((refund) => {
|
||||||
|
if (refund.type === RefundState.Failed) {
|
||||||
|
failed = failed + 1;
|
||||||
|
}
|
||||||
|
if (refund.type === RefundState.Applied) {
|
||||||
|
applied = applied + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { contractData: c } = purchase.download
|
||||||
|
|
||||||
|
return {
|
||||||
|
proposalId,
|
||||||
|
amountEffectivePaid: Amounts.stringify(purchase.totalPayCost),
|
||||||
|
applied,
|
||||||
|
failed,
|
||||||
|
total,
|
||||||
|
info: {
|
||||||
|
contractTermsHash: c.contractTermsHash,
|
||||||
|
merchant: c.merchant,
|
||||||
|
orderId: c.orderId,
|
||||||
|
products: c.products,
|
||||||
|
summary: c.summary,
|
||||||
|
fulfillmentMessage: c.fulfillmentMessage,
|
||||||
|
summary_i18n: c.summaryI18n,
|
||||||
|
fulfillmentMessage_i18n:
|
||||||
|
c.fulfillmentMessageI18n,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Retry querying and applying refunds for an order later.
|
* Retry querying and applying refunds for an order later.
|
||||||
*/
|
*/
|
||||||
|
@ -23,9 +23,7 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
AcceptManualWithdrawalResult,
|
AbsoluteTime, AcceptManualWithdrawalResult, AmountJson,
|
||||||
AcceptWithdrawalResponse,
|
|
||||||
AmountJson,
|
|
||||||
Amounts,
|
Amounts,
|
||||||
BalancesResponse,
|
BalancesResponse,
|
||||||
codecForAbortPayWithRefundRequest,
|
codecForAbortPayWithRefundRequest,
|
||||||
@ -48,8 +46,7 @@ import {
|
|||||||
codecForImportDbRequest,
|
codecForImportDbRequest,
|
||||||
codecForIntegrationTestArgs,
|
codecForIntegrationTestArgs,
|
||||||
codecForListKnownBankAccounts,
|
codecForListKnownBankAccounts,
|
||||||
codecForPreparePayRequest,
|
codecForPreparePayRequest, codecForPrepareRefundRequest, codecForPrepareTipRequest,
|
||||||
codecForPrepareTipRequest,
|
|
||||||
codecForRetryTransactionRequest,
|
codecForRetryTransactionRequest,
|
||||||
codecForSetCoinSuspendedRequest,
|
codecForSetCoinSuspendedRequest,
|
||||||
codecForSetWalletDeviceIdRequest,
|
codecForSetWalletDeviceIdRequest,
|
||||||
@ -59,8 +56,7 @@ import {
|
|||||||
codecForWithdrawFakebankRequest,
|
codecForWithdrawFakebankRequest,
|
||||||
codecForWithdrawTestBalance,
|
codecForWithdrawTestBalance,
|
||||||
CoinDumpJson,
|
CoinDumpJson,
|
||||||
CoreApiResponse,
|
CoreApiResponse, Duration, durationFromSpec,
|
||||||
durationFromSpec,
|
|
||||||
durationMin,
|
durationMin,
|
||||||
ExchangeListItem,
|
ExchangeListItem,
|
||||||
ExchangesListRespose,
|
ExchangesListRespose,
|
||||||
@ -73,14 +69,23 @@ import {
|
|||||||
parsePaytoUri,
|
parsePaytoUri,
|
||||||
PaytoUri,
|
PaytoUri,
|
||||||
RefreshReason,
|
RefreshReason,
|
||||||
TalerErrorCode,
|
TalerErrorCode, URL,
|
||||||
AbsoluteTime,
|
WalletNotification
|
||||||
URL,
|
|
||||||
WalletNotification,
|
|
||||||
Duration,
|
|
||||||
CancellationToken,
|
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { timeStamp } from "console";
|
import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js";
|
||||||
|
import {
|
||||||
|
CryptoDispatcher,
|
||||||
|
CryptoWorkerFactory
|
||||||
|
} from "./crypto/workers/cryptoDispatcher.js";
|
||||||
|
import {
|
||||||
|
AuditorTrustRecord,
|
||||||
|
CoinSourceType,
|
||||||
|
exportDb,
|
||||||
|
importDb,
|
||||||
|
ReserveRecordStatus,
|
||||||
|
WalletStoresV1
|
||||||
|
} from "./db.js";
|
||||||
|
import { getErrorDetailFromException, TalerError } from "./errors.js";
|
||||||
import {
|
import {
|
||||||
DenomInfo,
|
DenomInfo,
|
||||||
ExchangeOperations,
|
ExchangeOperations,
|
||||||
@ -89,21 +94,8 @@ import {
|
|||||||
MerchantOperations,
|
MerchantOperations,
|
||||||
NotificationListener,
|
NotificationListener,
|
||||||
RecoupOperations,
|
RecoupOperations,
|
||||||
ReserveOperations,
|
ReserveOperations
|
||||||
} from "./internal-wallet-state.js";
|
} from "./internal-wallet-state.js";
|
||||||
import {
|
|
||||||
CryptoDispatcher,
|
|
||||||
CryptoWorkerFactory,
|
|
||||||
} from "./crypto/workers/cryptoDispatcher.js";
|
|
||||||
import {
|
|
||||||
AuditorTrustRecord,
|
|
||||||
CoinSourceType,
|
|
||||||
exportDb,
|
|
||||||
importDb,
|
|
||||||
ReserveRecordStatus,
|
|
||||||
WalletStoresV1,
|
|
||||||
} from "./db.js";
|
|
||||||
import { getErrorDetailFromException, TalerError } from "./errors.js";
|
|
||||||
import { exportBackup } from "./operations/backup/export.js";
|
import { exportBackup } from "./operations/backup/export.js";
|
||||||
import {
|
import {
|
||||||
addBackupProvider,
|
addBackupProvider,
|
||||||
@ -115,7 +107,7 @@ import {
|
|||||||
loadBackupRecovery,
|
loadBackupRecovery,
|
||||||
processBackupForProvider,
|
processBackupForProvider,
|
||||||
removeBackupProvider,
|
removeBackupProvider,
|
||||||
runBackupCycle,
|
runBackupCycle
|
||||||
} from "./operations/backup/index.js";
|
} from "./operations/backup/index.js";
|
||||||
import { setWalletDeviceId } from "./operations/backup/state.js";
|
import { setWalletDeviceId } from "./operations/backup/state.js";
|
||||||
import { getBalances } from "./operations/balance.js";
|
import { getBalances } from "./operations/balance.js";
|
||||||
@ -123,7 +115,7 @@ import {
|
|||||||
createDepositGroup,
|
createDepositGroup,
|
||||||
getFeeForDeposit,
|
getFeeForDeposit,
|
||||||
processDepositGroup,
|
processDepositGroup,
|
||||||
trackDepositGroup,
|
trackDepositGroup
|
||||||
} from "./operations/deposits.js";
|
} from "./operations/deposits.js";
|
||||||
import {
|
import {
|
||||||
acceptExchangeTermsOfService,
|
acceptExchangeTermsOfService,
|
||||||
@ -132,69 +124,69 @@ import {
|
|||||||
getExchangeRequestTimeout,
|
getExchangeRequestTimeout,
|
||||||
getExchangeTrust,
|
getExchangeTrust,
|
||||||
updateExchangeFromUrl,
|
updateExchangeFromUrl,
|
||||||
updateExchangeTermsOfService,
|
updateExchangeTermsOfService
|
||||||
} from "./operations/exchanges.js";
|
} from "./operations/exchanges.js";
|
||||||
import { getMerchantInfo } from "./operations/merchants.js";
|
import { getMerchantInfo } from "./operations/merchants.js";
|
||||||
import {
|
import {
|
||||||
confirmPay,
|
confirmPay,
|
||||||
preparePayForUri,
|
preparePayForUri,
|
||||||
processDownloadProposal,
|
processDownloadProposal,
|
||||||
processPurchasePay,
|
processPurchasePay
|
||||||
} from "./operations/pay.js";
|
} from "./operations/pay.js";
|
||||||
import { getPendingOperations } from "./operations/pending.js";
|
import { getPendingOperations } from "./operations/pending.js";
|
||||||
import { createRecoupGroup, processRecoupGroup } from "./operations/recoup.js";
|
import { createRecoupGroup, processRecoupGroup } from "./operations/recoup.js";
|
||||||
import {
|
import {
|
||||||
autoRefresh,
|
autoRefresh,
|
||||||
createRefreshGroup,
|
createRefreshGroup,
|
||||||
processRefreshGroup,
|
processRefreshGroup
|
||||||
} from "./operations/refresh.js";
|
} from "./operations/refresh.js";
|
||||||
import {
|
import {
|
||||||
abortFailedPayWithRefund,
|
abortFailedPayWithRefund,
|
||||||
applyRefund,
|
applyRefund,
|
||||||
processPurchaseQueryRefund,
|
prepareRefund,
|
||||||
|
processPurchaseQueryRefund
|
||||||
} from "./operations/refund.js";
|
} from "./operations/refund.js";
|
||||||
import {
|
import {
|
||||||
createReserve,
|
createReserve,
|
||||||
createTalerWithdrawReserve,
|
createTalerWithdrawReserve,
|
||||||
getFundingPaytoUris,
|
getFundingPaytoUris,
|
||||||
processReserve,
|
processReserve
|
||||||
} from "./operations/reserves.js";
|
} from "./operations/reserves.js";
|
||||||
import {
|
import {
|
||||||
runIntegrationTest,
|
runIntegrationTest,
|
||||||
testPay,
|
testPay,
|
||||||
withdrawTestBalance,
|
withdrawTestBalance
|
||||||
} from "./operations/testing.js";
|
} from "./operations/testing.js";
|
||||||
import { acceptTip, prepareTip, processTip } from "./operations/tip.js";
|
import { acceptTip, prepareTip, processTip } from "./operations/tip.js";
|
||||||
import {
|
import {
|
||||||
deleteTransaction,
|
deleteTransaction,
|
||||||
getTransactions,
|
getTransactions,
|
||||||
retryTransaction,
|
retryTransaction
|
||||||
} from "./operations/transactions.js";
|
} from "./operations/transactions.js";
|
||||||
import {
|
import {
|
||||||
getExchangeWithdrawalInfo,
|
getExchangeWithdrawalInfo,
|
||||||
getWithdrawalDetailsForUri,
|
getWithdrawalDetailsForUri,
|
||||||
processWithdrawGroup,
|
processWithdrawGroup
|
||||||
} from "./operations/withdraw.js";
|
} from "./operations/withdraw.js";
|
||||||
import {
|
import {
|
||||||
PendingOperationsResponse,
|
PendingOperationsResponse,
|
||||||
PendingTaskInfo,
|
PendingTaskInfo,
|
||||||
PendingTaskType,
|
PendingTaskType
|
||||||
} from "./pending-types.js";
|
} from "./pending-types.js";
|
||||||
import { assertUnreachable } from "./util/assertUnreachable.js";
|
import { assertUnreachable } from "./util/assertUnreachable.js";
|
||||||
import { AsyncOpMemoMap, AsyncOpMemoSingle } from "./util/asyncMemo.js";
|
import { AsyncOpMemoMap, AsyncOpMemoSingle } from "./util/asyncMemo.js";
|
||||||
import {
|
import {
|
||||||
HttpRequestLibrary,
|
HttpRequestLibrary,
|
||||||
readSuccessResponseJsonOrThrow,
|
readSuccessResponseJsonOrThrow
|
||||||
} from "./util/http.js";
|
} from "./util/http.js";
|
||||||
import {
|
import {
|
||||||
AsyncCondition,
|
AsyncCondition,
|
||||||
OpenedPromise,
|
OpenedPromise,
|
||||||
openPromise,
|
openPromise
|
||||||
} from "./util/promiseUtils.js";
|
} from "./util/promiseUtils.js";
|
||||||
import { DbAccess, GetReadWriteAccess } from "./util/query.js";
|
import { DbAccess, GetReadWriteAccess } from "./util/query.js";
|
||||||
import { TimerAPI, TimerGroup } from "./util/timer.js";
|
import { TimerAPI, TimerGroup } from "./util/timer.js";
|
||||||
import { WalletCoreApiClient } from "./wallet-api-types.js";
|
import { WalletCoreApiClient } from "./wallet-api-types.js";
|
||||||
import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js";
|
|
||||||
|
|
||||||
const builtinAuditors: AuditorTrustRecord[] = [
|
const builtinAuditors: AuditorTrustRecord[] = [
|
||||||
{
|
{
|
||||||
@ -908,6 +900,10 @@ async function dispatchRequestInternal(
|
|||||||
const req = codecForPrepareTipRequest().decode(payload);
|
const req = codecForPrepareTipRequest().decode(payload);
|
||||||
return await prepareTip(ws, req.talerTipUri);
|
return await prepareTip(ws, req.talerTipUri);
|
||||||
}
|
}
|
||||||
|
case "prepareRefund": {
|
||||||
|
const req = codecForPrepareRefundRequest().decode(payload);
|
||||||
|
return await prepareRefund(ws, req.talerRefundUri);
|
||||||
|
}
|
||||||
case "acceptTip": {
|
case "acceptTip": {
|
||||||
const req = codecForAcceptTipRequest().decode(payload);
|
const req = codecForAcceptTipRequest().decode(payload);
|
||||||
await acceptTip(ws, req.walletTipId);
|
await acceptTip(ws, req.walletTipId);
|
||||||
|
Loading…
Reference in New Issue
Block a user