wallet-core: return pending status instead of error
This allows clients to get the transaction ID of the confirmed payment.
This commit is contained in:
parent
72ca5ee8dd
commit
cbf848dd2a
@ -18,7 +18,7 @@
|
||||
* Imports.
|
||||
*/
|
||||
import { PreparePayResultType, TalerErrorCode } from "@gnu-taler/taler-util";
|
||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||
import { Wallet, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||
import {
|
||||
createSimpleTestkudosEnvironment,
|
||||
@ -55,7 +55,6 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
|
||||
fulfillment_url: "taler://fulfillment-success/thx",
|
||||
};
|
||||
|
||||
{
|
||||
const orderResp = await MerchantPrivateApi.createOrder(
|
||||
merchant,
|
||||
"default",
|
||||
@ -86,34 +85,34 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
|
||||
preparePayResult.status === PreparePayResultType.PaymentPossible,
|
||||
);
|
||||
|
||||
const exc = await t.assertThrowsTalerErrorAsync(async () => {
|
||||
await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||
proposalId: preparePayResult.proposalId,
|
||||
});
|
||||
const confirmResp = await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||
proposalId: preparePayResult.proposalId,
|
||||
});
|
||||
|
||||
const tx = await wallet.client.call(WalletApiOperation.GetTransactionById, {
|
||||
transactionId: confirmResp.transactionId,
|
||||
});
|
||||
|
||||
t.assertTrue(
|
||||
exc.hasErrorCode(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED),
|
||||
tx.error?.code === TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR
|
||||
);
|
||||
|
||||
// FIXME: We might want a more specific error code here!
|
||||
t.assertDeepEqual(
|
||||
exc.errorDetail.innerError.code,
|
||||
TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR,
|
||||
);
|
||||
const merchantErrorCode = (exc.errorDetail.innerError.errorResponse as any)
|
||||
const merchantErrorCode = ((tx.error as any).errorResponse as any)
|
||||
.code;
|
||||
t.assertDeepEqual(
|
||||
merchantErrorCode,
|
||||
TalerErrorCode.MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
await wallet.client.call(WalletApiOperation.AddExchange, {
|
||||
exchangeBaseUrl: exchange.baseUrl,
|
||||
forceUpdate: true,
|
||||
});
|
||||
|
||||
await wallet.client.call(WalletApiOperation.DeleteTransaction, {
|
||||
transactionId: confirmResp.transactionId,
|
||||
});
|
||||
|
||||
// Now withdrawal should work again.
|
||||
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||
|
||||
|
@ -1625,28 +1625,11 @@ export async function runPayForConfirmPay(
|
||||
.runReadOnly(async (tx) =>
|
||||
tx.operationRetries.get(RetryTags.byPaymentProposalId(proposalId)),
|
||||
);
|
||||
const maxRetry = 3;
|
||||
const numRetry = opRetry?.retryInfo.retryCounter ?? 0;
|
||||
if (
|
||||
res.errorDetail.code ===
|
||||
TalerErrorCode.WALLET_PAY_MERCHANT_SERVER_ERROR &&
|
||||
numRetry < maxRetry
|
||||
) {
|
||||
logger.trace("hiding transient error from caller");
|
||||
// Pretend the operation is pending instead of reporting
|
||||
// an error, but only up to maxRetry attempts.
|
||||
await storeOperationPending(
|
||||
ws,
|
||||
RetryTags.byPaymentProposalId(proposalId),
|
||||
);
|
||||
return {
|
||||
type: ConfirmPayResultType.Pending,
|
||||
lastError: opRetry?.lastError,
|
||||
transactionId: makeTransactionId(TransactionType.Payment, proposalId),
|
||||
};
|
||||
} else {
|
||||
throw Error("payment failed");
|
||||
}
|
||||
return {
|
||||
type: ConfirmPayResultType.Pending,
|
||||
lastError: opRetry?.lastError,
|
||||
transactionId: makeTransactionId(TransactionType.Payment, proposalId),
|
||||
};
|
||||
}
|
||||
case OperationAttemptResultType.Pending:
|
||||
logger.trace("reporting pending as confirmPay response");
|
||||
|
Loading…
Reference in New Issue
Block a user