Contents

getTransactionByIdread-only#

Get a single transaction by its identifier.

Request:

The request args must be a TransactionByIdRequest object.

Response:

On success, the result is a Transaction object.

Expected errors:

The caller can handle the following errors inline: WALLET_TRANSACTION_NOT_FOUND, WALLET_CORE_API_BAD_REQUEST.

Details:

The transactionId must have the form of a TransactionIdStr; malformed identifiers fail with WALLET_CORE_API_BAD_REQUEST, well-formed but unknown identifiers with WALLET_TRANSACTION_NOT_FOUND.

The full contract terms (contractTerms) are only reported for payment transactions and only when includeContractTerms is set.

// A transaction in the wallet's transaction history.  The
// type field discriminates the union; all members share the
// fields of TransactionCommon.
type Transaction =
  | TransactionWithdrawal
  | TransactionPayment
  | TransactionRefund
  | TransactionRefresh
  | TransactionDeposit
  | TransactionPeerPullCredit
  | TransactionPeerPullDebit
  | TransactionPeerPushCredit
  | TransactionPeerPushDebit
  | TransactionInternalWithdrawal
  | TransactionRecoup
  | TransactionDenomLoss;
// Opaque, stable identifier of a transaction, of the form
// txn:<type>:<id> where <type> is a TransactionType.
// (The TypeScript source additionally brands this string type;
// the brand only exists at compile time.)
type TransactionIdStr = `txn:${string}:${string}`;
type TransactionType =
  | "withdrawal"
  | "internal-withdrawal"
  | "payment"
  | "refund"
  | "refresh"
  | "deposit"
  | "peer-push-debit"
  | "peer-push-credit"
  | "peer-pull-debit"
  | "peer-pull-credit"
  | "recoup"
  | "denom-loss";
interface TransactionCommon {
  // Opaque unique ID for the transaction, used as a starting
  // point for paginating queries and for invoking actions on the
  // transaction (e.g. deleting it from the history).
  transactionId: TransactionIdStr;

  // The transaction produced funds under an exchange key set that
  // the user subsequently purged from the wallet.
  legacy?: boolean;

  // Short identifier assigned by this wallet for local,
  // human-facing use, of the form #<type>:<localIdent>.
  // Intentionally not portable: importing or merging a wallet can
  // assign different local identifiers.  Clients must use
  // transactionId when they need a stable ID.  Undefined when
  // the wallet backend does not support local IDs.
  localTransactionId?: string;

  // Type of the transaction; discriminates the Transaction
  // union.
  type: TransactionType;

  // Main timestamp of the transaction.
  timestamp: TalerPreciseTimestamp;

  // Scopes of this transaction.
  scopes: ScopeInfo[];

  // Transaction state, as per DD37.
  txState: TransactionState;

  // Wallet-internal state ID, only used for debugging and
  // testing.
  stId: number;

  // Possible transitions based on the current state.
  txActions: TransactionAction[];

  // Raw amount of the transaction (exclusive of fees or other
  // extra costs).
  amountRaw: AmountString;

  // Amount shown when the transaction was confirmed, including
  // estimated fees.  Preserved when execution fails, expires or
  // is aborted.
  amountEffective: AmountString;

  // Settled wallet balance effect, including fees and abort
  // recovery.  Nonnegative; the transaction type determines
  // whether this is a debit or a credit.  Absent until the
  // transaction and its recovery have settled, or when the amount
  // cannot be established for historical records.  Ordinary
  // merchant refunds remain separate credits.  Associated
  // refreshes have zero effect.
  amountEffectiveFinal?: AmountString;

  error?: TalerErrorDetail;

  abortReason?: TalerErrorDetail;

  failReason?: TalerErrorDetail;

  // Location where the user must go to complete KYC; present
  // when the transaction's minor state is kyc.
  kycUrl?: string;

  // KYC payto hash.  Useful for testing, not so useful for UIs.
  kycPaytoHash?: string;

  // KYC access token.  Useful for testing, not so useful for UIs.
  kycAccessToken?: string;

  kycAuthTransferInfo?: KycAuthTransferInfo;
}
interface TransactionState {
  // Major state component of the transaction state.
  major: TransactionMajorState;

  // Minor state component of the transaction.
  minor?: TransactionMinorState;

  // Whether the wallet is currently actively processing the
  // transaction or waiting for a counterparty.  Will eventually
  // be folded into a new major state.
  working?: boolean;
}
type TransactionMajorState =
  // No state, only used when reporting transitions into the
  // initial state.
  | "none"
  | "pending"
  | "done"
  | "aborting"
  | "aborted"
  | "dialog"
  | "finalizing"
  // A suspended pending state.
  | "suspended"
  | "suspended-finalizing"
  | "suspended-aborting"
  | "failed"
  | "expired"
  // Only used for notifications, never in the transaction
  // history.
  | "deleted";
type TransactionMinorState =
  | "aborting-bank"
  | "accept-refund"
  | "auto-refund"
  | "balance-kyc"
  | "bank"
  | "bank-confirm-transfer"
  | "bank-register-reserve"
  | "check-refund"
  | "claim-proposal"
  | "completed-by-other-wallet"
  | "continued-with-other-wallet"
  | "create-purse"
  | "delete-purse"
  | "deposit"
  | "deposit-abort-partial"
  | "deposit-abort-recovered"
  | "deposit-abort-recovery-failed"
  | "deposit-abort-refund-failed"
  | "deposit-abort-too-late"
  | "exchange"
  | "exchange-wait-reserve"
  | "kyc-auth"
  | "kyc-hard-limit"
  | "kyc-init"
  | "kyc"
  | "merge"
  | "paid-by-other"
  | "proposed"
  | "ready"
  | "rebind-session"
  | "refresh"
  | "refused"
  | "repurchase"
  | "submit-payment"
  | "track"
  | "unknown"
  | "withdraw"
  | "waiting-for-other-wallet"
  | "abort";
// Actions the user can request on a transaction in its current
// state; each action corresponds to one of the transaction
// operations.
type TransactionAction =
  | "delete"
  | "suspend"
  | "resume"
  | "abort"
  | "fail"
  | "retry";
interface KycAuthTransferInfo {
  // Payto URI of the account that must make the transfer.  The
  // KYC auth transfer will *not* work if it originates from a
  // different account.
  debitPaytoUri: string;

  // Account public key.  Included in the transfer subject for
  // some of the transfer options.
  accountPub: string;

  // Options for making the KYC auth transfer, grouped by exchange
  // credit account in the same format used for withdrawals.
  transferOptionsExt: WithdrawalExchangeAccountDetails[];

  // Options for making the KYC auth transfer payment to the
  // exchange.  Deprecated: use transferOptionsExt instead.
  transferOptions: TransferOption[];

  // Validity of the transferOptions, or undefined if they do not
  // expire.  Deprecated: use the per-account expiry in
  // transferOptionsExt instead.
  transferExpiry: TalerProtocolTimestamp | undefined;

  // Amount that the exchange expects to be deposited.  Usually
  // the smallest amount that can be transferred via a bank
  // transfer.  Deprecated: use transferOptions instead.
  amount: AmountString;

  // Possible target payto URIs.  Deprecated: use
  // transferOptions instead.
  creditPaytoUris: string[];
}
// A withdrawal transaction (either bank-integrated or manual).
interface TransactionWithdrawal extends TransactionCommon {
  type: "withdrawal";

  // Exchange of the withdrawal.
  exchangeBaseUrl: string | undefined;

  // Amount that got subtracted from the reserve balance.
  amountRaw: AmountString;

  // Amount that actually was (or will be) added to the wallet's
  // balance.
  amountEffective: AmountString;

  withdrawalDetails: WithdrawalDetails;
}
// Internal withdrawal operation, only reported on request.  Some
// transactions (peer-*-credit) internally do a withdrawal, but
// only the peer-*-credit transaction is reported.  The internal
// withdrawal transaction gives access to the details of the
// underlying withdrawal for testing/debugging.  It is usually not
// reported, so that the amounts of transactions properly add up.
interface TransactionInternalWithdrawal extends TransactionCommon {
  type: "internal-withdrawal";

  // Exchange of the withdrawal.
  exchangeBaseUrl: string;

  // Amount that got subtracted from the reserve balance.
  amountRaw: AmountString;

  // Amount that actually was (or will be) added to the wallet's
  // balance.
  amountEffective: AmountString;

  withdrawalDetails: WithdrawalDetails;
}
interface WithdrawalDetailsForManualTransfer {
  type: "manual-transfer";

  // Payto URIs that the exchange supports.  Already contains the
  // amount and message.  Deprecated: in favor of
  // exchangeCreditAccountDetails.
  exchangePaytoUris: string[];

  exchangeCreditAccountDetails?: WithdrawalExchangeAccountDetails[];

  // Public key of the reserve.
  reservePub: string;

  // Is the reserve ready for withdrawal?
  reserveIsReady: boolean;

  // How long the exchange waits to transfer back funds from a
  // reserve.
  reserveClosingDelay: TalerProtocolDuration;
}
interface WithdrawalDetailsForTalerBankIntegrationApi {
  type: "taler-bank-integration-api";

  // True if the bank has confirmed the withdrawal.  An
  // unconfirmed withdrawal usually requires user input and should
  // be highlighted in the UI; see bankConfirmationUrl.
  confirmed: boolean;

  // If the withdrawal is unconfirmed, this can include a URL for
  // user-initiated confirmation.
  bankConfirmationUrl?: string;

  // Public key of the reserve.
  reservePub: string;

  // Is the reserve ready for withdrawal?
  reserveIsReady: boolean;

  // Is the bank transfer for the withdrawal externally
  // confirmed?
  externalConfirmation?: boolean;

  exchangeCreditAccountDetails?: WithdrawalExchangeAccountDetails[];
}
interface TransactionPayment extends TransactionCommon {
  type: "payment";

  // Merchant instance base URL used to claim the order.
  // Available even before the contract terms have been
  // downloaded.
  merchantBaseUrl: string;

  // Public payment URI shown while this wallet waits for another
  // wallet to claim an order that it released.
  unclaimedPayUri?: TalerUriString;

  // Additional information about the payment.  Only present if
  // the information about the order is already available.
  info: OrderShortInfo | undefined;

  // Full contract terms.  Only included if explicitly requested
  // via the includeContractTerms flag of
  // getTransactionById.
  contractTerms?: MerchantContractTerms;

  // Amount that must be paid for the contract.
  amountRaw: AmountString;

  // Amount that was paid, including deposit, wire and refresh
  // fees.
  amountEffective: AmountString;

  // Amount that has been refunded by the merchant.
  totalRefundRaw: AmountString;

  // Amount that will be added to the wallet's balance after fees
  // and refreshing.
  totalRefundEffective: AmountString;

  // Amount pending to be picked up.
  refundPending: AmountString | undefined;

  // Reference to applied refunds.
  refunds: RefundInfoShort[];

  // Is the wallet currently checking for a refund?
  refundQueryActive: boolean;

  // PoS confirmation codes, separated by newlines.  Only present
  // for purchases that support PoS confirmation.
  posConfirmation: string | undefined;

  // Until when the posConfirmation is valid.
  posConfirmationDeadline?: TalerProtocolTimestamp;

  // Did we receive the payment via a taler://pay-template/ URI
  // and did the URI contain a nfc=1 flag?
  posConfirmationViaNfc?: boolean;

  // In case this payment transaction was detected as a
  // repurchase, the transaction ID of the original payment.
  repurchaseTransactionId?: TransactionIdStr;

  // If applicable, the choice that the user selected.
  choiceIndex?: number;
}
interface OrderShortInfo {
  // Order ID, uniquely identifies the order within a merchant
  // instance.
  orderId: string;

  // Hash of the contract terms.
  contractTermsHash: string;

  // More information about the merchant.
  merchant: MerchantInfo;

  // Summary of the order, given by the merchant.
  summary: string;

  // Map from IETF BCP 47 language tags to localized summaries.
  summary_i18n?: InternationalizedString;

  // URL of the fulfillment, given by the merchant.
  fulfillmentUrl?: string;

  // Plain text message that should be shown to the user when the
  // payment is complete.
  fulfillmentMessage?: string;

  // Translations of fulfillmentMessage.
  fulfillmentMessage_i18n?: InternationalizedString;
}
interface RefundInfoShort {
  transactionId: string;

  timestamp: TalerProtocolTimestamp;

  amountEffective: AmountString;

  amountRaw: AmountString;
}
interface TransactionRefund extends TransactionCommon {
  // Recovery already included in the unsuccessful payment's
  // final cost.
  isAbortRecovery?: boolean;

  type: "refund";

  // Amount that has been refunded by the merchant.
  amountRaw: AmountString;

  // Amount that will be added to the wallet's balance after fees
  // and refreshing.
  amountEffective: AmountString;

  // ID of the transaction that is refunded.
  refundedTransactionId: string;

  paymentInfo: RefundPaymentInfo | undefined;
}
// Summary information about the payment that we got a refund
// for.
interface RefundPaymentInfo {
  summary: string;

  summary_i18n?: InternationalizedString;

  // More information about the merchant.
  merchant: MerchantInfo;
}
// A transaction shown for refreshes.  Only shown for (1)
// refreshes not associated with other transactions and (2)
// refreshes in an error state.
interface TransactionRefresh extends TransactionCommon {
  type: "refresh";

  refreshReason: RefreshReason;

  // Transaction ID that caused this refresh.
  originatingTransactionId?: string;

  // Always zero for refreshes.
  amountRaw: AmountString;

  // Fees, i.e. the effective, negative effect of the refresh on
  // the balance.  Only applicable for stand-alone refreshes, and
  // zero for other refreshes where the transaction itself
  // accounts for the refresh fee.
  amountEffective: AmountString;

  refreshInputAmount: AmountString;

  refreshOutputAmount: AmountString;
}
// Reason why a coin is being refreshed.
type RefreshReason =
  | "manual"
  | "pay-merchant"
  | "pay-deposit"
  | "pay-peer-push"
  | "pay-peer-pull"
  | "refund"
  | "abort-pay"
  | "abort-deposit"
  | "abort-peer-push-debit"
  | "abort-peer-pull-debit"
  | "recoup"
  | "backup-restored"
  | "scheduled";
// Deposit transaction, which effectively sends money from this
// wallet somewhere else.
interface TransactionDeposit extends TransactionCommon {
  type: "deposit";

  depositGroupId: string;

  // Target for the deposit.
  targetPaytoUri: string;

  // Raw amount that is being deposited.
  amountRaw: AmountString;

  // Deposit account public key.
  accountPub: string;

  // Effective amount that is being deposited.
  amountEffective: AmountString;

  wireTransferDeadline: TalerProtocolTimestamp;

  wireTransferProgress: number;

  // Did all the deposit requests succeed?
  deposited: boolean;

  trackingState: Array<DepositTransactionTrackingState>;
}
interface DepositTransactionTrackingState {
  // Raw wire transfer identifier of the deposit.
  wireTransferId: string;

  // When the wire transfer was given to the bank.
  timestampExecuted: TalerProtocolTimestamp;

  // Total amount transferred for this wtid (including fees).
  amountRaw: AmountString;

  // Wire fee amount for this exchange.
  wireFee: AmountString;
}
// Credit because we were paid for a P2P invoice we created.
interface TransactionPeerPullCredit extends TransactionCommon {
  type: "peer-pull-credit";

  info: PeerInfoShort;

  // Exchange used.
  exchangeBaseUrl: string;

  // Amount that got subtracted from the reserve balance.
  amountRaw: AmountString;

  // Amount that actually was (or will be) added to the wallet's
  // balance.
  amountEffective: AmountString;

  // URI to send to the other party.  Only available in the right
  // state.
  talerUri: string | undefined;
}
// Debit because we paid someone's invoice.
interface TransactionPeerPullDebit extends TransactionCommon {
  type: "peer-pull-debit";

  info: PeerInfoShort;

  // Exchange used.
  exchangeBaseUrl: string;

  amountRaw: AmountString;

  amountEffective: AmountString;
}
// We sent money via a P2P payment.
interface TransactionPeerPushDebit extends TransactionCommon {
  type: "peer-push-debit";

  info: PeerInfoShort;

  // Exchange used.
  exchangeBaseUrl: string;

  // Amount that got subtracted from the reserve balance.
  amountRaw: AmountString;

  // Amount that actually was (or will be) added to the wallet's
  // balance.
  amountEffective: AmountString;

  // URI to accept the payment.  Only present if the transaction
  // is in a state where the other party can accept the payment.
  talerUri?: string;
}
// We received money via a P2P payment.
interface TransactionPeerPushCredit extends TransactionCommon {
  type: "peer-push-credit";

  info: PeerInfoShort;

  // Exchange used.
  exchangeBaseUrl: string;

  // Amount that got subtracted from the reserve balance.
  amountRaw: AmountString;

  // Amount that actually was (or will be) added to the wallet's
  // balance.
  amountEffective: AmountString;
}
interface PeerInfoShort {
  expiration: TalerProtocolTimestamp | undefined;

  summary: string | undefined;

  iconId: string | undefined;
}
// The exchange revoked a key and the wallet recoups funds.
interface TransactionRecoup extends TransactionCommon {
  type: "recoup";
}
// A transaction to indicate financial loss due to denominations
// that became unusable for deposits.
interface TransactionDenomLoss extends TransactionCommon {
  type: "denom-loss";

  lossEventType: DenomLossEventType;

  exchangeBaseUrl: string;
}
type DenomLossEventType =
  | "denom-expired"
  | "denom-vanished"
  | "denom-unoffered"
  // The exchange revoked the denomination.  A revoked
  // denomination also stops being offered, so this must be
  // checked before "denom-unoffered" to say what actually
  // happened.
  | "denom-revoked";
interface TransactionByIdRequest {
  transactionId: string;

  // If set to true, report the full contract terms in the
  // response if the transaction has them.
  includeContractTerms?: boolean;
}