summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-05-15 16:03:52 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-05-15 16:03:52 +0530
commit3eb88574bcf327672c34120becfb511eac4e06cd (patch)
tree9d54748adef52dc9a21c8ea97c7d034cd773277a
parent35c83414f9e0af11012c1a2e00672d2a7c1856ae (diff)
downloadwallet-core-3eb88574bcf327672c34120becfb511eac4e06cd.tar.gz
wallet-core-3eb88574bcf327672c34120becfb511eac4e06cd.tar.bz2
wallet-core-3eb88574bcf327672c34120becfb511eac4e06cd.zip
address first batch of transaction list issues
-rw-r--r--src/db.ts2
-rw-r--r--src/operations/pay.ts10
-rw-r--r--src/operations/reserves.ts51
-rw-r--r--src/operations/tip.ts16
-rw-r--r--src/operations/transactions.ts55
-rw-r--r--src/operations/withdraw.ts20
-rw-r--r--src/types/dbTypes.ts22
-rw-r--r--src/types/talerTypes.ts94
-rw-r--r--src/types/transactions.ts128
9 files changed, 257 insertions, 141 deletions
diff --git a/src/db.ts b/src/db.ts
index 098767b5..19737202 100644
--- a/src/db.ts
+++ b/src/db.ts
@@ -7,7 +7,7 @@ import { openDatabase, Database, Store, Index } from "./util/query";
* with each major change. When incrementing the major version,
* the wallet should import data from the previous version.
*/
-const TALER_DB_NAME = "taler-walletdb-v3";
+const TALER_DB_NAME = "taler-walletdb-v4";
/**
* Current database minor version, should be incremented
diff --git a/src/operations/pay.ts b/src/operations/pay.ts
index 45caa958..20d62dea 100644
--- a/src/operations/pay.ts
+++ b/src/operations/pay.ts
@@ -137,11 +137,7 @@ export async function getTotalPaymentCost(
ws: InternalWalletState,
pcs: PayCoinSelection,
): Promise<PayCostInfo> {
- const costs = [
- pcs.paymentAmount,
- pcs.customerDepositFees,
- pcs.customerWireFees,
- ];
+ const costs = [];
for (let i = 0; i < pcs.coinPubs.length; i++) {
const coin = await ws.db.get(Stores.coins, pcs.coinPubs[i]);
if (!coin) {
@@ -165,6 +161,7 @@ export async function getTotalPaymentCost(
const amountLeft = Amounts.sub(denom.value, pcs.coinContributions[i])
.amount;
const refreshCost = getTotalRefreshCost(allDenoms, denom, amountLeft);
+ costs.push(pcs.coinContributions[i]);
costs.push(refreshCost);
}
return {
@@ -670,6 +667,9 @@ async function processDownloadProposalImpl(
wireMethod: parsedContractTerms.wire_method,
wireInfoHash: parsedContractTerms.h_wire,
maxDepositFee: Amounts.parseOrThrow(parsedContractTerms.max_fee),
+ merchant: parsedContractTerms.merchant,
+ products: parsedContractTerms.products,
+ summaryI18n: parsedContractTerms.summary_i18n,
},
contractTermsRaw: JSON.stringify(proposalResp.contract_terms),
};
diff --git a/src/operations/reserves.ts b/src/operations/reserves.ts
index 347f6e89..3d45d8d5 100644
--- a/src/operations/reserves.ts
+++ b/src/operations/reserves.ts
@@ -35,6 +35,7 @@ import {
WalletReserveHistoryItemType,
WithdrawalSourceType,
ReserveHistoryRecord,
+ ReserveBankInfo,
} from "../types/dbTypes";
import { Logger } from "../util/logging";
import { Amounts } from "../util/amounts";
@@ -48,9 +49,11 @@ import { assertUnreachable } from "../util/assertUnreachable";
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto";
import { randomBytes } from "../crypto/primitives/nacl-fast";
import {
- getVerifiedWithdrawDenomList,
+ selectWithdrawalDenoms,
processWithdrawGroup,
getBankWithdrawalInfo,
+ denomSelectionInfoToState,
+ getWithdrawDenomList,
} from "./withdraw";
import {
guardOperationException,
@@ -100,6 +103,20 @@ export async function createReserve(
reserveStatus = ReserveRecordStatus.UNCONFIRMED;
}
+ let bankInfo: ReserveBankInfo | undefined;
+
+ if (req.bankWithdrawStatusUrl) {
+ const denomSelInfo = await selectWithdrawalDenoms(ws, canonExchange, req.amount);
+ const denomSel = denomSelectionInfoToState(denomSelInfo);
+ bankInfo = {
+ statusUrl: req.bankWithdrawStatusUrl,
+ amount: req.amount,
+ bankWithdrawalGroupId: encodeCrock(getRandomBytes(32)),
+ withdrawalStarted: false,
+ denomSel,
+ };
+ }
+
const reserveRecord: ReserveRecord = {
timestampCreated: now,
exchangeBaseUrl: canonExchange,
@@ -108,14 +125,7 @@ export async function createReserve(
senderWire: req.senderWire,
timestampConfirmed: undefined,
timestampReserveInfoPosted: undefined,
- bankInfo: req.bankWithdrawStatusUrl
- ? {
- statusUrl: req.bankWithdrawStatusUrl,
- amount: req.amount,
- bankWithdrawalGroupId: encodeCrock(getRandomBytes(32)),
- withdrawalStarted: false,
- }
- : undefined,
+ bankInfo,
exchangeWire: req.exchangeWire,
reserveStatus,
lastSuccessfulStatusQuery: undefined,
@@ -286,10 +296,11 @@ async function registerReserveWithBank(
default:
return;
}
- const bankStatusUrl = reserve.bankInfo?.statusUrl;
- if (!bankStatusUrl) {
+ const bankInfo = reserve.bankInfo;
+ if (!bankInfo) {
return;
}
+ const bankStatusUrl = bankInfo.statusUrl;
console.log("making selection");
if (reserve.timestampReserveInfoPosted) {
throw Error("bank claims that reserve info selection is not done");
@@ -309,6 +320,9 @@ async function registerReserveWithBank(
}
r.timestampReserveInfoPosted = getTimestampNow();
r.reserveStatus = ReserveRecordStatus.WAIT_CONFIRM_BANK;
+ if (!r.bankInfo) {
+ throw Error("invariant failed");
+ }
r.retryInfo = initRetryInfo();
return r;
});
@@ -657,7 +671,7 @@ async function depleteReserve(
logger.trace(`getting denom list`);
- const denomsForWithdraw = await getVerifiedWithdrawDenomList(
+ const denomsForWithdraw = await selectWithdrawalDenoms(
ws,
reserve.exchangeBaseUrl,
withdrawAmount,
@@ -752,17 +766,8 @@ async function depleteReserve(
retryInfo: initRetryInfo(),
lastErrorPerCoin: {},
lastError: undefined,
- denomsSel: {
- totalCoinValue: denomsForWithdraw.totalCoinValue,
- totalWithdrawCost: denomsForWithdraw.totalWithdrawCost,
- selectedDenoms: denomsForWithdraw.selectedDenoms.map((x) => {
- return {
- count: x.count,
- denomPubHash: x.denom.denomPubHash,
- };
- }),
- },
- };
+ denomsSel: denomSelectionInfoToState(denomsForWithdraw),
+ };
await tx.put(Stores.reserves, newReserve);
await tx.put(Stores.reserveHistory, newHist);
diff --git a/src/operations/tip.ts b/src/operations/tip.ts
index f584fc50..15d2339b 100644
--- a/src/operations/tip.ts
+++ b/src/operations/tip.ts
@@ -34,8 +34,9 @@ import {
} from "../types/dbTypes";
import {
getExchangeWithdrawalInfo,
- getVerifiedWithdrawDenomList,
+ selectWithdrawalDenoms,
processWithdrawGroup,
+ denomSelectionInfoToState,
} from "./withdraw";
import { updateExchangeFromUrl } from "./exchanges";
import { getRandomBytes, encodeCrock } from "../crypto/talerCrypto";
@@ -81,7 +82,7 @@ export async function getTipStatus(
);
const tipId = encodeCrock(getRandomBytes(32));
- const selectedDenoms = await getVerifiedWithdrawDenomList(
+ const selectedDenoms = await selectWithdrawalDenoms(
ws,
tipPickupStatus.exchange_url,
amount,
@@ -107,16 +108,7 @@ export async function getTipStatus(
).amount,
retryInfo: initRetryInfo(),
lastError: undefined,
- denomsSel: {
- totalCoinValue: selectedDenoms.totalCoinValue,
- totalWithdrawCost: selectedDenoms.totalWithdrawCost,
- selectedDenoms: selectedDenoms.selectedDenoms.map((x) => {
- return {
- count: x.count,
- denomPubHash: x.denom.denomPubHash,
- };
- }),
- },
+ denomsSel: denomSelectionInfoToState(selectedDenoms),
};
await ws.db.put(Stores.tips, tipRecord);
}
diff --git a/src/operations/transactions.ts b/src/operations/transactions.ts
index 4cc6154b..fd767962 100644
--- a/src/operations/transactions.ts
+++ b/src/operations/transactions.ts
@@ -18,7 +18,7 @@
* Imports.
*/
import { InternalWalletState } from "./state";
-import { Stores, ReserveRecordStatus, PurchaseRecord, ProposalStatus } from "../types/dbTypes";
+import { Stores, ReserveRecordStatus, PurchaseRecord } from "../types/dbTypes";
import { Amounts, AmountJson } from "../util/amounts";
import { timestampCmp } from "../util/time";
import {
@@ -131,10 +131,8 @@ export async function getTransactions(
if (wsr.timestampFinish) {
transactions.push({
type: TransactionType.Withdrawal,
- amountEffective: Amounts.stringify(
- wsr.denomsSel.totalWithdrawCost,
- ),
- amountRaw: Amounts.stringify(wsr.denomsSel.totalCoinValue),
+ amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
+ amountRaw: Amounts.stringify(wsr.denomsSel.totalWithdrawCost),
confirmed: true,
exchangeBaseUrl: wsr.exchangeBaseUrl,
pending: !wsr.timestampFinish,
@@ -163,9 +161,9 @@ export async function getTransactions(
transactions.push({
type: TransactionType.Withdrawal,
confirmed: false,
- amountRaw: Amounts.stringify(r.bankInfo.amount),
- amountEffective: undefined,
- exchangeBaseUrl: undefined,
+ amountRaw: Amounts.stringify(r.bankInfo.denomSel.totalWithdrawCost),
+ amountEffective: Amounts.stringify(r.bankInfo.denomSel.totalCoinValue),
+ exchangeBaseUrl: r.exchangeBaseUrl,
pending: true,
timestamp: r.timestampCreated,
bankConfirmationUrl: r.bankInfo.confirmUrl,
@@ -176,38 +174,6 @@ export async function getTransactions(
});
});
- tx.iter(Stores.proposals).forEachAsync(async (proposal) => {
- if (!proposal.download) {
- return;
- }
- if (proposal.proposalStatus !== ProposalStatus.PROPOSED) {
- return;
- }
- const dl = proposal.download;
- const purchase = await tx.get(Stores.purchases, proposal.proposalId);
- if (purchase) {
- return;
- }
-
- transactions.push({
- type: TransactionType.Payment,
- amountRaw: Amounts.stringify(dl.contractData.amount),
- amountEffective: undefined,
- status: PaymentStatus.Offered,
- pending: true,
- timestamp: proposal.timestamp,
- transactionId: makeEventId(TransactionType.Payment, proposal.proposalId),
- info: {
- fulfillmentUrl: dl.contractData.fulfillmentUrl,
- merchant: {},
- orderId: dl.contractData.orderId,
- products: [],
- summary: dl.contractData.summary,
- summary_i18n: {},
- },
- });
- });
-
tx.iter(Stores.purchases).forEachAsync(async (pr) => {
if (
transactionsRequest?.currency &&
@@ -231,11 +197,11 @@ export async function getTransactions(
transactionId: makeEventId(TransactionType.Payment, pr.proposalId),
info: {
fulfillmentUrl: pr.contractData.fulfillmentUrl,
- merchant: {},
+ merchant: pr.contractData.merchant,
orderId: pr.contractData.orderId,
- products: [],
+ products: pr.contractData.products,
summary: pr.contractData.summary,
- summary_i18n: {},
+ summary_i18n: pr.contractData.summaryI18n,
},
});
@@ -258,7 +224,8 @@ export async function getTransactions(
timestamp: rg.timestampQueried,
transactionId: makeEventId(
TransactionType.Refund,
- `{rg.timestampQueried.t_ms}`,
+ pr.proposalId,
+ `${rg.timestampQueried.t_ms}`,
),
refundedTransactionId: makeEventId(
TransactionType.Payment,
diff --git a/src/operations/withdraw.ts b/src/operations/withdraw.ts
index 21c30d7a..14071be7 100644
--- a/src/operations/withdraw.ts
+++ b/src/operations/withdraw.ts
@@ -1,6 +1,6 @@
/*
This file is part of GNU Taler
- (C) 2019-2029 Taler Systems SA
+ (C) 2019-2020 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -27,6 +27,7 @@ import {
DenominationSelectionInfo,
PlanchetRecord,
WithdrawalSourceType,
+ DenomSelectionState,
} from "../types/dbTypes";
import {
BankWithdrawDetails,
@@ -419,6 +420,19 @@ async function processPlanchet(
}
}
+export function denomSelectionInfoToState(dsi: DenominationSelectionInfo): DenomSelectionState {
+ return {
+ selectedDenoms: dsi.selectedDenoms.map((x) => {
+ return {
+ count: x.count,
+ denomPubHash: x.denom.denomPubHash
+ };
+ }),
+ totalCoinValue: dsi.totalCoinValue,
+ totalWithdrawCost: dsi.totalWithdrawCost,
+ }
+}
+
/**
* Get a list of denominations to withdraw from the given exchange for the
* given amount, making sure that all denominations' signatures are verified.
@@ -426,7 +440,7 @@ async function processPlanchet(
* Writes to the DB in order to record the result from verifying
* denominations.
*/
-export async function getVerifiedWithdrawDenomList(
+export async function selectWithdrawalDenoms(
ws: InternalWalletState,
exchangeBaseUrl: string,
amount: AmountJson,
@@ -603,7 +617,7 @@ export async function getExchangeWithdrawalInfo(
throw Error(`exchange ${exchangeInfo.baseUrl} wire details not available`);
}
- const selectedDenoms = await getVerifiedWithdrawDenomList(
+ const selectedDenoms = await selectWithdrawalDenoms(
ws,
baseUrl,
amount,
diff --git a/src/types/dbTypes.ts b/src/types/dbTypes.ts
index 37a66251..79966eb3 100644
--- a/src/types/dbTypes.ts
+++ b/src/types/dbTypes.ts
@@ -31,6 +31,8 @@ import {
PayReq,
TipResponse,
ExchangeSignKeyJson,
+ MerchantInfo,
+ Product,
} from "./talerTypes";
import { Index, Store } from "../util/query";
@@ -216,6 +218,15 @@ export interface ReserveHistoryRecord {
reserveTransactions: WalletReserveHistoryItem[];
}
+export interface ReserveBankInfo {
+ statusUrl: string;
+ confirmUrl?: string;
+ amount: AmountJson;
+ bankWithdrawalGroupId: string;
+ withdrawalStarted: boolean;
+ denomSel: DenomSelectionState;
+}
+
/**
* A reserve record as stored in the wallet's database.
*/
@@ -278,13 +289,7 @@ export interface ReserveRecord {
* Extra state for when this is a withdrawal involving
* a Taler-integrated bank.
*/
- bankInfo?: {
- statusUrl: string;
- confirmUrl?: string;
- amount: AmountJson;
- bankWithdrawalGroupId: string;
- withdrawalStarted: boolean;
- };
+ bankInfo?: ReserveBankInfo;
reserveStatus: ReserveRecordStatus;
@@ -1179,10 +1184,13 @@ export interface AllowedExchangeInfo {
* processing in the wallet.
*/
export interface WalletContractData {
+ products?: Product[];
+ summaryI18n: { [lang_tag: string]: string } | undefined;
fulfillmentUrl: string;
contractTermsHash: string;
merchantSig: string;
merchantPub: string;
+ merchant: MerchantInfo;
amount: AmountJson;
orderId: string;
merchantBaseUrl: string;
diff --git a/src/types/talerTypes.ts b/src/types/talerTypes.ts
index 17d11eea..eb10d6e1 100644
--- a/src/types/talerTypes.ts
+++ b/src/types/talerTypes.ts
@@ -260,6 +260,55 @@ export class AuditorHandle {
url: string;
}
+export interface MerchantInfo {
+ name: string;
+ jurisdiction: string | undefined;
+ address: string | undefined;
+}
+
+export interface Tax {
+ // the name of the tax
+ name: string;
+
+ // amount paid in tax
+ tax: AmountString;
+}
+
+export interface Product {
+ // merchant-internal identifier for the product.
+ product_id?: string;
+
+ // Human-readable product description.
+ description: string;
+
+ // Map from IETF BCP 47 language tags to localized descriptions
+ description_i18n?: { [lang_tag: string]: string };
+
+ // The number of units of the product to deliver to the customer.
+ quantity?: number;
+
+ // The unit in which the product is measured (liters, kilograms, packages, etc.)
+ unit?: string;
+
+ // The price of the product; this is the total price for quantity times unit of this product.
+ price?: AmountString;
+
+ // An optional base64-encoded product image
+ image?: string;
+
+ // a list of taxes paid by the merchant for this product. Can be empty.
+ taxes?: Tax[];
+
+ // time indicating when this product should be delivered
+ delivery_date?: Timestamp;
+
+ // where to deliver this product. This may be an URL for online delivery
+ // (i.e. 'http://example.com/download' or 'mailto:customer@example.com'),
+ // or a location label defined inside the proposition's 'locations'.
+ // The presence of a colon (':') indicates the use of an URL.
+ delivery_location?: string;
+}
+
/**
* Contract terms from a merchant.
*/
@@ -284,6 +333,8 @@ export class ContractTerms {
*/
summary: string;
+ summary_i18n?: { [lang_tag: string]: string };
+
/**
* Nonce used to ensure freshness.
*/
@@ -317,7 +368,7 @@ export class ContractTerms {
/**
* Information about the merchant.
*/
- merchant: any;
+ merchant: MerchantInfo;
/**
* Public key of the merchant.
@@ -332,7 +383,7 @@ export class ContractTerms {
/**
* Products that are sold in this contract.
*/
- products?: any[];
+ products?: Product[];
/**
* Deadline for refunds.
@@ -805,6 +856,35 @@ export const codecForAuditorHandle = (): Codec<AuditorHandle> =>
.property("url", codecForString)
.build("AuditorHandle");
+export const codecForMerchantInfo = (): Codec<MerchantInfo> =>
+ makeCodecForObject<MerchantInfo>()
+ .property("name", codecForString)
+ .property("address", makeCodecOptional(codecForString))
+ .property("jurisdiction", makeCodecOptional(codecForString))
+ .build("MerchantInfo");
+
+export const codecForTax = (): Codec<Tax> =>
+ makeCodecForObject<Tax>()
+ .property("name", codecForString)
+ .property("tax", codecForString)
+ .build("Tax");
+
+
+export const codecForI18n = (): Codec<{ [lang_tag: string]: string }> =>
+ makeCodecForMap(codecForString)
+
+export const codecForProduct = (): Codec<Product> =>
+ makeCodecForObject<Product>()
+ .property("product_id", makeCodecOptional(codecForString))
+ .property("description", codecForString)
+ .property("description_i18n", makeCodecOptional(codecForI18n()))
+ .property("quantity", makeCodecOptional(codecForNumber))
+ .property("unit", makeCodecOptional(codecForString))
+ .property("price", makeCodecOptional(codecForString))
+ .property("delivery_date", makeCodecOptional(codecForTimestamp))
+ .property("delivery_location", makeCodecOptional(codecForString))
+ .build("Tax");
+
export const codecForContractTerms = (): Codec<ContractTerms> =>
makeCodecForObject<ContractTerms>()
.property("order_id", codecForString)
@@ -814,6 +894,7 @@ export const codecForContractTerms = (): Codec<ContractTerms> =>
.property("auto_refund", makeCodecOptional(codecForDuration))
.property("wire_method", codecForString)
.property("summary", codecForString)
+ .property("summary_i18n", makeCodecOptional(codecForI18n()))
.property("nonce", codecForString)
.property("amount", codecForString)
.property("auditors", makeCodecForList(codecForAuditorHandle()))
@@ -824,10 +905,10 @@ export const codecForContractTerms = (): Codec<ContractTerms> =>
.property("locations", codecForAny)
.property("max_fee", codecForString)
.property("max_wire_fee", makeCodecOptional(codecForString))
- .property("merchant", codecForAny)
+ .property("merchant", codecForMerchantInfo())
.property("merchant_pub", codecForString)
.property("exchanges", makeCodecForList(codecForExchangeHandle()))
- .property("products", makeCodecOptional(makeCodecForList(codecForAny)))
+ .property("products", makeCodecOptional(makeCodecForList(codecForProduct())))
.property("extra", codecForAny)
.build("ContractTerms");
@@ -852,10 +933,7 @@ export const codecForMerchantRefundResponse = (): Codec<
makeCodecForObject<MerchantRefundResponse>()
.property("merchant_pub", codecForString)
.property("h_contract_terms", codecForString)
- .property(
- "refunds",
- makeCodecForList(codecForMerchantRefundPermission()),
- )
+ .property("refunds", makeCodecForList(codecForMerchantRefundPermission()))
.build("MerchantRefundResponse");
export const codecForReserveSigSingleton = (): Codec<ReserveSigSingleton> =>
diff --git a/src/types/transactions.ts b/src/types/transactions.ts
index 263e08a4..b1d033c0 100644
--- a/src/types/transactions.ts
+++ b/src/types/transactions.ts
@@ -16,13 +16,16 @@
/**
* Type and schema definitions for the wallet's transaction list.
+ *
+ * @author Florian Dold
+ * @author Torsten Grote
*/
/**
* Imports.
*/
import { Timestamp } from "../util/time";
-import { AmountString } from "./talerTypes";
+import { AmountString, Product } from "./talerTypes";
export interface TransactionsRequest {
/**
@@ -44,6 +47,24 @@ export interface TransactionsResponse {
transactions: Transaction[];
}
+interface TransactionError {
+ /**
+ * TALER_EC_* unique error code.
+ * The action(s) offered and message displayed on the transaction item depend on this code.
+ */
+ ec: number;
+
+ /**
+ * English-only error hint, if available.
+ */
+ hint?: string;
+
+ /**
+ * Error details specific to "ec", if applicable/available
+ */
+ details?: any;
+}
+
export 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/hiding it from the history)
@@ -64,16 +85,17 @@ export interface TransactionCommon {
amountRaw: AmountString;
// Amount added or removed from the wallet's balance (including all fees and other costs)
- amountEffective?: AmountString;
+ amountEffective: AmountString;
+
+ error?: TransactionError;
}
-export type Transaction = (
- TransactionWithdrawal |
- TransactionPayment |
- TransactionRefund |
- TransactionTip |
- TransactionRefresh
-)
+export type Transaction =
+ | TransactionWithdrawal
+ | TransactionPayment
+ | TransactionRefund
+ | TransactionTip
+ | TransactionRefresh;
export const enum TransactionType {
Withdrawal = "withdrawal",
@@ -93,79 +115,109 @@ interface TransactionWithdrawal extends TransactionCommon {
*/
exchangeBaseUrl?: string;
- // true if the bank has confirmed the withdrawal, false if not.
- // An unconfirmed withdrawal usually requires user-input and should be highlighted in the UI.
- // See also bankConfirmationUrl below.
+ /**
+ * true if the bank has confirmed the withdrawal, false if not.
+ * An unconfirmed withdrawal usually requires user-input and should be highlighted in the UI.
+ * See also bankConfirmationUrl below.
+ */
confirmed: boolean;
- // If the withdrawal is unconfirmed, this can include a URL for user initiated confirmation.
+ /**
+ * If the withdrawal is unconfirmed, this can include a URL for user
+ * initiated confirmation.
+ */
bankConfirmationUrl?: string;
- // Amount that has been subtracted from the reserve's balance for this withdrawal.
+ /**
+ * Amount that got subtracted from the reserve balance.
+ */
amountRaw: AmountString;
/**
* Amount that actually was (or will be) added to the wallet's balance.
- * Only present if an exchange has already been selected.
*/
- amountEffective?: AmountString;
+ amountEffective: AmountString;
}
export const enum PaymentStatus {
- // Explicitly aborted after timeout / failure
+ /**
+ * Explicitly aborted after timeout / failure
+ */
Aborted = "aborted",
- // Payment failed, wallet will auto-retry.
- // User should be given the option to retry now / abort.
+ /**
+ * Payment failed, wallet will auto-retry.
+ * User should be given the option to retry now / abort.
+ */
Failed = "failed",
- // Paid successfully
+ /**
+ * Paid successfully
+ */
Paid = "paid",
- // Only offered, user must accept / decline
- Offered = "offered",
-
- // User accepted, payment is processing.
+ /**
+ * User accepted, payment is processing.
+ */
Accepted = "accepted",
}
export interface TransactionPayment extends TransactionCommon {
type: TransactionType.Payment;
- // Additional information about the payment.
+ /**
+ * Additional information about the payment.
+ */
info: PaymentShortInfo;
+ /**
+ * How far did the wallet get with processing the payment?
+ */
status: PaymentStatus;
- // Amount that must be paid for the contract
+ /**
+ * Amount that must be paid for the contract
+ */
amountRaw: AmountString;
- // Amount that was paid, including deposit, wire and refresh fees.
- amountEffective?: AmountString;
+ /**
+ * Amount that was paid, including deposit, wire and refresh fees.
+ */
+ amountEffective: AmountString;
}
-
interface PaymentShortInfo {
- // Order ID, uniquely identifies the order within a merchant instance
+ /**
+ * Order ID, uniquely identifies the order within a merchant instance
+ */
orderId: string;
- // More information about the merchant
+ /**
+ * More information about the merchant
+ */
merchant: any;
- // Summary of the order, given by the merchant
+ /**
+ * Summary of the order, given by the merchant
+ */
summary: string;
- // Map from IETF BCP 47 language tags to localized summaries
+ /**
+ * Map from IETF BCP 47 language tags to localized summaries
+ */
summary_i18n?: { [lang_tag: string]: string };
- // List of products that are part of the order
- products: any[];
+ /**
+ * List of products that are part of the order
+ */
+ products: Product[] | undefined;
- // URL of the fulfillment, given by the merchant
+ /**
+ * URL of the fulfillment, given by the merchant
+ */
fulfillmentUrl: string;
}
-
interface TransactionRefund extends TransactionCommon {
type: TransactionType.Refund;
@@ -221,4 +273,4 @@ interface TransactionRefresh extends TransactionCommon {
// Amount that will be paid as fees for the refresh
amountEffective: AmountString;
-} \ No newline at end of file
+}