wallet-core: expose more info about refund query

This commit is contained in:
Florian Dold 2023-02-14 11:16:58 +01:00
parent 6106caeba9
commit 6a4da88719
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
6 changed files with 109 additions and 12 deletions

View File

@ -29,6 +29,8 @@ import {
MerchantContractTerms,
Duration,
PreparePayResultType,
NotificationType,
WithdrawalGroupFinishedNotification,
} from "@gnu-taler/taler-util";
import {
BankAccessApi,
@ -466,6 +468,53 @@ export async function startWithdrawViaBank(
// Some tests rely on the final withdraw failing.
}
export interface WithdrawViaBankResult {
withdrawalFinishedCond: Promise<WithdrawalGroupFinishedNotification>;
}
export async function withdrawViaBankV2(
t: GlobalTestState,
p: {
walletClient: WalletClient;
bank: BankService;
exchange: ExchangeServiceInterface;
amount: AmountString;
restrictAge?: number;
},
): Promise<WithdrawViaBankResult> {
const { walletClient: wallet, bank, exchange, amount } = p;
const user = await BankApi.createRandomBankUser(bank);
const wop = await BankAccessApi.createWithdrawalOperation(bank, user, amount);
// Hand it to the wallet
await wallet.client.call(WalletApiOperation.GetWithdrawalDetailsForUri, {
talerWithdrawUri: wop.taler_withdraw_uri,
restrictAge: p.restrictAge,
});
const withdrawalFinishedCond = wallet.waitForNotificationCond((x) =>
x.type === NotificationType.WithdrawGroupFinished ? x : false,
);
// Withdraw (AKA select)
await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
exchangeBaseUrl: exchange.baseUrl,
talerWithdrawUri: wop.taler_withdraw_uri,
restrictAge: p.restrictAge,
});
// Confirm it
await BankApi.confirmWithdrawalOperation(bank, user, wop);
return {
withdrawalFinishedCond,
};
}
/**
* Withdraw balance.
*/

View File

@ -17,12 +17,16 @@
/**
* Imports.
*/
import { Duration, durationFromSpec } from "@gnu-taler/taler-util";
import {
Duration,
durationFromSpec,
NotificationType,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
import {
createSimpleTestkudosEnvironment,
withdrawViaBank,
createSimpleTestkudosEnvironmentV2,
withdrawViaBankV2,
} from "../harness/helpers.js";
/**
@ -31,12 +35,23 @@ import {
export async function runRefundTest(t: GlobalTestState) {
// Set up test environment
const { wallet, bank, exchange, merchant } =
await createSimpleTestkudosEnvironment(t);
const {
walletClient: wallet,
bank,
exchange,
merchant,
} = await createSimpleTestkudosEnvironmentV2(t);
// Withdraw digital cash into the wallet.
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
const withdrawalRes = await withdrawViaBankV2(t, {
walletClient: wallet,
bank,
exchange,
amount: "TESTKUDOS:20",
});
await withdrawalRes.withdrawalFinishedCond;
// Set up order.
@ -85,12 +100,15 @@ export async function runRefundTest(t: GlobalTestState) {
console.log(ref);
{
const refundFinishedCond = wallet.waitForNotificationCond(
(x) => x.type === NotificationType.RefundFinished,
);
const r = await wallet.client.call(WalletApiOperation.ApplyRefund, {
talerRefundUri: ref.talerRefundUri,
});
console.log(r);
await wallet.runUntilDone();
await refundFinishedCond;
}
{
@ -103,6 +121,9 @@ export async function runRefundTest(t: GlobalTestState) {
}
{
const refundQueriedCond = wallet.waitForNotificationCond(
(x) => x.type === NotificationType.RefundQueried,
);
const r3 = await wallet.client.call(
WalletApiOperation.ApplyRefundFromPurchaseId,
{
@ -110,11 +131,8 @@ export async function runRefundTest(t: GlobalTestState) {
},
);
console.log(r3);
await wallet.runUntilDone();
await refundQueriedCond;
}
await t.shutdown();
}
runRefundTest.suites = ["wallet"];

View File

@ -96,6 +96,10 @@ export interface RefundStartedNotification {
export interface RefundQueriedNotification {
type: NotificationType.RefundQueried;
/**
* Transaction ID of the purchase (NOT the refund transaction).
*/
transactionId: string;
}
export interface ProposalDownloadedNotification {
@ -171,6 +175,11 @@ export interface WaitingForRetryNotification {
export interface RefundFinishedNotification {
type: NotificationType.RefundFinished;
/**
* Transaction ID of the purchase (NOT the refund transaction).
*/
transactionId: string;
}
export interface ExchangeAddedNotification {

View File

@ -395,6 +395,11 @@ export interface TransactionPayment extends TransactionCommon {
* Reference to applied refunds
*/
refunds: RefundInfoShort[];
/**
* Is the wallet currently checking for a refund?
*/
refundQueryActive: boolean;
}
export interface OrderShortInfo {

View File

@ -2415,6 +2415,13 @@ async function acceptRefunds(
p.purchaseStatus = PurchaseStatus.Paid;
}
logger.trace("refund query done");
ws.notify({
type: NotificationType.RefundFinished,
transactionId: makeTransactionId(
TransactionType.Payment,
p.proposalId,
),
});
} else {
// No error, but we need to try again!
p.timestampLastRefundStatus = now;
@ -2426,6 +2433,7 @@ async function acceptRefunds(
ws.notify({
type: NotificationType.RefundQueried,
transactionId: makeTransactionId(TransactionType.Payment, proposalId),
});
}
@ -2694,6 +2702,13 @@ export async function processPurchaseQueryRefund(
await tx.purchases.put(purchase);
});
// No new refunds, but we still need to notify
// the wallet client that the query finished.
ws.notify({
type: NotificationType.RefundQueried,
transactionId: makeTransactionId(TransactionType.Payment, proposalId),
});
return OperationAttemptResult.finishedEmpty();
}
}

View File

@ -58,7 +58,6 @@ import {
WithdrawalGroupStatus,
} from "../db.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { assertUnreachable } from "../util/assertUnreachable.js";
import { checkDbInvariant } from "../util/invariants.js";
import { RetryTags } from "../util/retries.js";
import {
@ -846,6 +845,8 @@ async function buildTransactionForPurchase(
),
proposalId: purchaseRecord.proposalId,
info,
refundQueryActive:
purchaseRecord.purchaseStatus === PurchaseStatus.QueryingRefund,
frozen:
purchaseRecord.purchaseStatus === PurchaseStatus.PaymentAbortFinished ??
false,