wallet-core/packages/merchant-backend-ui/src/declaration.d.ts

1386 lines
50 KiB
TypeScript

/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
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
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Sebastian Javier Marchano (sebasjm)
*/
type HashCode = string;
type EddsaPublicKey = string;
type EddsaSignature = string;
type WireTransferIdentifierRawP = string;
type RelativeTime = Duration;
type ImageDataUrl = string;
export interface WithId {
id: string
}
interface Timestamp {
// Milliseconds since epoch, or the special
// value "forever" to represent an event that will
// never happen.
t_s: number | "never";
}
interface Duration {
// Duration in milliseconds or "forever"
// to represent an infinite duration.
d_us: number | "forever";
}
interface WithId {
id: string;
}
type Amount = string;
type UUID = string;
type Integer = number;
export namespace ExchangeBackend {
interface WireResponse {
// Master public key of the exchange, must match the key returned in /keys.
master_public_key: EddsaPublicKey;
// Array of wire accounts operated by the exchange for
// incoming wire transfers.
accounts: WireAccount[];
// Object mapping names of wire methods (i.e. "sepa" or "x-taler-bank")
// to wire fees.
fees: { method: AggregateTransferFee };
}
interface WireAccount {
// payto:// URI identifying the account and wire method
payto_uri: string;
// Signature using the exchange's offline key
// with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
master_sig: EddsaSignature;
}
interface AggregateTransferFee {
// Per transfer wire transfer fee.
wire_fee: Amount;
// Per transfer closing fee.
closing_fee: Amount;
// What date (inclusive) does this fee go into effect?
// The different fees must cover the full time period in which
// any of the denomination keys are valid without overlap.
start_date: TalerProtocolTimestamp;
// What date (exclusive) does this fee stop going into effect?
// The different fees must cover the full time period in which
// any of the denomination keys are valid without overlap.
end_date: TalerProtocolTimestamp;
// Signature of TALER_MasterWireFeePS with
// purpose TALER_SIGNATURE_MASTER_WIRE_FEES.
sig: EddsaSignature;
}
}
export namespace MerchantBackend {
interface ErrorDetail {
// Numeric error code unique to the condition.
// The other arguments are specific to the error value reported here.
code: number;
// Human-readable description of the error, i.e. "missing parameter", "commitment violation", ...
// Should give a human-readable hint about the error's nature. Optional, may change without notice!
hint?: string;
// Optional detail about the specific input value that failed. May change without notice!
detail?: string;
// Name of the parameter that was bogus (if applicable).
parameter?: string;
// Path to the argument that was bogus (if applicable).
path?: string;
// Offset of the argument that was bogus (if applicable).
offset?: string;
// Index of the argument that was bogus (if applicable).
index?: string;
// Name of the object that was bogus (if applicable).
object?: string;
// Name of the currency than was problematic (if applicable).
currency?: string;
// Expected type (if applicable).
type_expected?: string;
// Type that was provided instead (if applicable).
type_actual?: string;
}
// Delivery location, loosely modeled as a subset of
// ISO20022's PostalAddress25.
interface Tax {
// the name of the tax
name: string;
// amount paid in tax
tax: Amount;
}
interface Auditor {
// official name
name: string;
// Auditor's public key
auditor_pub: EddsaPublicKey;
// Base URL of the auditor
url: string;
}
interface Exchange {
// the exchange's base URL
url: string;
// master public key of the exchange
master_pub: EddsaPublicKey;
}
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: Integer;
// 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: Amount;
// An optional base64-encoded product image
image: ImageDataUrl;
// 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;
}
interface Merchant {
// label for a location with the business address of the merchant
address: Location;
// the merchant's legal name of business
name: string;
// label for a location that denotes the jurisdiction for disputes.
// Some of the typical fields for a location (such as a street address) may be absent.
jurisdiction: Location;
}
interface VersionResponse {
// libtool-style representation of the Merchant protocol version, see
// https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
// The format is "current:revision:age".
version: string;
// Name of the protocol.
name: "taler-merchant";
// Currency supported by this backend.
currency: string;
}
interface Location {
// Nation with its own government.
country?: string;
// Identifies a subdivision of a country such as state, region, county.
country_subdivision?: string;
// Identifies a subdivision within a country sub-division.
district?: string;
// Name of a built-up area, with defined boundaries, and a local government.
town?: string;
// Specific location name within the town.
town_location?: string;
// Identifier consisting of a group of letters and/or numbers that
// is added to a postal address to assist the sorting of mail.
post_code?: string;
// Name of a street or thoroughfare.
street?: string;
// Name of the building or house.
building_name?: string;
// Number that identifies the position of a building on a street.
building_number?: string;
// Free-form address lines, should not exceed 7 elements.
address_lines?: string[];
}
namespace Instances {
//POST /private/instances/$INSTANCE/auth
interface InstanceAuthConfigurationMessage {
// Type of authentication.
// "external": The mechant backend does not do
// any authentication checks. Instead an API
// gateway must do the authentication.
// "token": The merchant checks an auth token.
// See "token" for details.
method: "external" | "token";
// For method "external", this field is mandatory.
// The token MUST begin with the string "secret-token:".
// After the auth token has been set (with method "token"),
// the value must be provided in a "Authorization: Bearer $token"
// header.
token?: string;
}
//POST /private/instances
interface InstanceConfigurationMessage {
// The URI where the wallet will send coins. A merchant may have
// multiple accounts, thus this is an array. Note that by
// removing URIs from this list the respective account is set to
// inactive and thus unavailable for new contracts, but preserved
// in the database as existing offers and contracts may still refer
// to it.
payto_uris: string[];
// Name of the merchant instance to create (will become $INSTANCE).
id: string;
// Merchant name corresponding to this instance.
name: string;
// "Authentication" header required to authorize management access the instance.
// Optional, if not given authentication will be disabled for
// this instance (hopefully authentication checks are still
// done by some reverse proxy).
auth: InstanceAuthConfigurationMessage;
// The merchant's physical address (to be put into contracts).
address: Location;
// The jurisdiction under which the merchant conducts its business
// (to be put into contracts).
jurisdiction: Location;
// Maximum wire fee this instance is willing to pay.
// Can be overridden by the frontend on a per-order basis.
default_max_wire_fee: Amount;
// Default factor for wire fee amortization calculations.
// Can be overridden by the frontend on a per-order basis.
default_wire_fee_amortization: Integer;
// Maximum deposit fee (sum over all coins) this instance is willing to pay.
// Can be overridden by the frontend on a per-order basis.
default_max_deposit_fee: Amount;
// If the frontend does NOT specify an execution date, how long should
// we tell the exchange to wait to aggregate transactions before
// executing the wire transfer? This delay is added to the current
// time when we generate the advisory execution time for the exchange.
default_wire_transfer_delay: RelativeTime;
// If the frontend does NOT specify a payment deadline, how long should
// offers we make be valid by default?
default_pay_delay: RelativeTime;
}
// PATCH /private/instances/$INSTANCE
interface InstanceReconfigurationMessage {
// The URI where the wallet will send coins. A merchant may have
// multiple accounts, thus this is an array. Note that by
// removing URIs from this list
payto_uris: string[];
// Merchant name corresponding to this instance.
name: string;
// The merchant's physical address (to be put into contracts).
address: Location;
// The jurisdiction under which the merchant conducts its business
// (to be put into contracts).
jurisdiction: Location;
// Maximum wire fee this instance is willing to pay.
// Can be overridden by the frontend on a per-order basis.
default_max_wire_fee: Amount;
// Default factor for wire fee amortization calculations.
// Can be overridden by the frontend on a per-order basis.
default_wire_fee_amortization: Integer;
// Maximum deposit fee (sum over all coins) this instance is willing to pay.
// Can be overridden by the frontend on a per-order basis.
default_max_deposit_fee: Amount;
// If the frontend does NOT specify an execution date, how long should
// we tell the exchange to wait to aggregate transactions before
// executing the wire transfer? This delay is added to the current
// time when we generate the advisory execution time for the exchange.
default_wire_transfer_delay: RelativeTime;
// If the frontend does NOT specify a payment deadline, how long should
// offers we make be valid by default?
default_pay_delay: RelativeTime;
}
// GET /private/instances
interface InstancesResponse {
// List of instances that are present in the backend (see Instance)
instances: Instance[];
}
interface Instance {
// Merchant name corresponding to this instance.
name: string;
deleted?: boolean;
// Merchant instance this response is about ($INSTANCE)
id: string;
// Public key of the merchant/instance, in Crockford Base32 encoding.
merchant_pub: EddsaPublicKey;
// List of the payment targets supported by this instance. Clients can
// specify the desired payment target in /order requests. Note that
// front-ends do not have to support wallets selecting payment targets.
payment_targets: string[];
}
//GET /private/instances/$INSTANCE
interface QueryInstancesResponse {
// The URI where the wallet will send coins. A merchant may have
// multiple accounts, thus this is an array.
accounts: MerchantAccount[];
// Merchant name corresponding to this instance.
name: string;
// Public key of the merchant/instance, in Crockford Base32 encoding.
merchant_pub: EddsaPublicKey;
// The merchant's physical address (to be put into contracts).
address: Location;
// The jurisdiction under which the merchant conducts its business
// (to be put into contracts).
jurisdiction: Location;
// Maximum wire fee this instance is willing to pay.
// Can be overridden by the frontend on a per-order basis.
default_max_wire_fee: Amount;
// Default factor for wire fee amortization calculations.
// Can be overridden by the frontend on a per-order basis.
default_wire_fee_amortization: Integer;
// Maximum deposit fee (sum over all coins) this instance is willing to pay.
// Can be overridden by the frontend on a per-order basis.
default_max_deposit_fee: Amount;
// If the frontend does NOT specify an execution date, how long should
// we tell the exchange to wait to aggregate transactions before
// executing the wire transfer? This delay is added to the current
// time when we generate the advisory execution time for the exchange.
default_wire_transfer_delay: RelativeTime;
// If the frontend does NOT specify a payment deadline, how long should
// offers we make be valid by default?
default_pay_delay: RelativeTime;
// Authentication configuration.
// Does not contain the token when token auth is configured.
auth: {
method: "external" | "token";
};
}
interface MerchantAccount {
// payto:// URI of the account.
payto_uri: string;
// Hash over the wire details (including over the salt)
h_wire: HashCode;
// salt used to compute h_wire
salt: HashCode;
// true if this account is active,
// false if it is historic.
active: boolean;
}
// DELETE /private/instances/$INSTANCE
}
namespace Products {
// POST /private/products
interface ProductAddDetail {
// product ID to use.
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 };
// unit in which the product is measured (liters, kilograms, packages, etc.)
unit: string;
// The price for one unit of the product. Zero is used
// to imply that this product is not sold separately, or
// that the price is not fixed, and must be supplied by the
// front-end. If non-zero, this price MUST include applicable
// taxes.
price: Amount;
// An optional base64-encoded product image
image: ImageDataUrl;
// a list of taxes paid by the merchant for one unit of this product
taxes: Tax[];
// Number of units of the product in stock in sum in total,
// including all existing sales ever. Given in product-specific
// units.
// A value of -1 indicates "infinite" (i.e. for "electronic" books).
total_stock: Integer;
// Identifies where the product is in stock.
address: Location;
// Identifies when we expect the next restocking to happen.
next_restock?: Timestamp;
}
// PATCH /private/products/$PRODUCT_ID
interface ProductPatchDetail {
// Human-readable product description.
description: string;
// Map from IETF BCP 47 language tags to localized descriptions
description_i18n: { [lang_tag: string]: string };
// unit in which the product is measured (liters, kilograms, packages, etc.)
unit: string;
// The price for one unit of the product. Zero is used
// to imply that this product is not sold separately, or
// that the price is not fixed, and must be supplied by the
// front-end. If non-zero, this price MUST include applicable
// taxes.
price: Amount;
// An optional base64-encoded product image
image: ImageDataUrl;
// a list of taxes paid by the merchant for one unit of this product
taxes: Tax[];
// Number of units of the product in stock in sum in total,
// including all existing sales ever. Given in product-specific
// units.
// A value of -1 indicates "infinite" (i.e. for "electronic" books).
total_stock: Integer;
// Number of units of the product that were lost (spoiled, stolen, etc.)
total_lost: Integer;
// Identifies where the product is in stock.
address: Location;
// Identifies when we expect the next restocking to happen.
next_restock?: Timestamp;
}
// GET /private/products
interface InventorySummaryResponse {
// List of products that are present in the inventory
products: InventoryEntry[];
}
interface InventoryEntry {
// Product identifier, as found in the product.
product_id: string;
}
// GET /private/products/$PRODUCT_ID
interface ProductDetail {
// Human-readable product description.
description: string;
// Map from IETF BCP 47 language tags to localized descriptions
description_i18n: { [lang_tag: string]: string };
// unit in which the product is measured (liters, kilograms, packages, etc.)
unit: string;
// The price for one unit of the product. Zero is used
// to imply that this product is not sold separately, or
// that the price is not fixed, and must be supplied by the
// front-end. If non-zero, this price MUST include applicable
// taxes.
price: Amount;
// An optional base64-encoded product image
image: ImageDataUrl;
// a list of taxes paid by the merchant for one unit of this product
taxes: Tax[];
// Number of units of the product in stock in sum in total,
// including all existing sales ever. Given in product-specific
// units.
// A value of -1 indicates "infinite" (i.e. for "electronic" books).
total_stock: Integer;
// Number of units of the product that have already been sold.
total_sold: Integer;
// Number of units of the product that were lost (spoiled, stolen, etc.)
total_lost: Integer;
// Identifies where the product is in stock.
address: Location;
// Identifies when we expect the next restocking to happen.
next_restock?: Timestamp;
}
// POST /private/products/$PRODUCT_ID/lock
interface LockRequest {
// UUID that identifies the frontend performing the lock
// It is suggested that clients use a timeflake for this,
// see https://github.com/anthonynsimon/timeflake
lock_uuid: UUID;
// How long does the frontend intend to hold the lock
duration: RelativeTime;
// How many units should be locked?
quantity: Integer;
}
// DELETE /private/products/$PRODUCT_ID
}
namespace Orders {
type MerchantOrderStatusResponse = CheckPaymentPaidResponse |
CheckPaymentClaimedResponse |
CheckPaymentUnpaidResponse;
interface CheckPaymentPaidResponse {
// The customer paid for this contract.
order_status: "paid";
// Was the payment refunded (even partially)?
refunded: boolean;
// True if there are any approved refunds that the wallet has
// not yet obtained.
refund_pending: boolean;
// Did the exchange wire us the funds?
wired: boolean;
// Total amount the exchange deposited into our bank account
// for this contract, excluding fees.
deposit_total: Amount;
// Numeric error code indicating errors the exchange
// encountered tracking the wire transfer for this purchase (before
// we even got to specific coin issues).
// 0 if there were no issues.
exchange_ec: number;
// HTTP status code returned by the exchange when we asked for
// information to track the wire transfer for this purchase.
// 0 if there were no issues.
exchange_hc: number;
// Total amount that was refunded, 0 if refunded is false.
refund_amount: Amount;
// Contract terms.
contract_terms: ContractTerms;
// The wire transfer status from the exchange for this order if
// available, otherwise empty array.
wire_details: TransactionWireTransfer[];
// Reports about trouble obtaining wire transfer details,
// empty array if no trouble were encountered.
wire_reports: TransactionWireReport[];
// The refund details for this order. One entry per
// refunded coin; empty array if there are no refunds.
refund_details: RefundDetails[];
// Status URL, can be used as a redirect target for the browser
// to show the order QR code / trigger the wallet.
order_status_url: string;
}
interface CheckPaymentClaimedResponse {
// A wallet claimed the order, but did not yet pay for the contract.
order_status: "claimed";
// Contract terms.
contract_terms: ContractTerms;
}
interface CheckPaymentUnpaidResponse {
// The order was neither claimed nor paid.
order_status: "unpaid";
// when was the order created
creation_time: Timestamp;
// Order summary text.
summary: string;
// Total amount of the order (to be paid by the customer).
total_amount: Amount;
// URI that the wallet must process to complete the payment.
taler_pay_uri: string;
// Alternative order ID which was paid for already in the same session.
// Only given if the same product was purchased before in the same session.
already_paid_order_id?: string;
// Fulfillment URL of an already paid order. Only given if under this
// session an already paid order with a fulfillment URL exists.
already_paid_fulfillment_url?: string;
// Status URL, can be used as a redirect target for the browser
// to show the order QR code / trigger the wallet.
order_status_url: string;
// We do we NOT return the contract terms here because they may not
// exist in case the wallet did not yet claim them.
}
interface RefundDetails {
// Reason given for the refund.
reason: string;
// When was the refund approved.
timestamp: Timestamp;
// Total amount that was refunded (minus a refund fee).
amount: Amount;
}
interface TransactionWireTransfer {
// Responsible exchange.
exchange_url: string;
// 32-byte wire transfer identifier.
wtid: Base32;
// Execution time of the wire transfer.
execution_time: Timestamp;
// Total amount that has been wire transferred
// to the merchant.
amount: Amount;
// Was this transfer confirmed by the merchant via the
// POST /transfers API, or is it merely claimed by the exchange?
confirmed: boolean;
}
interface TransactionWireReport {
// Numerical error code.
code: number;
// Human-readable error description.
hint: string;
// Numerical error code from the exchange.
exchange_ec: number;
// HTTP status code received from the exchange.
exchange_hc: number;
// Public key of the coin for which we got the exchange error.
coin_pub: CoinPublicKey;
}
interface OrderHistory {
// timestamp-sorted array of all orders matching the query.
// The order of the sorting depends on the sign of delta.
orders: OrderHistoryEntry[];
}
interface OrderHistoryEntry {
// order ID of the transaction related to this entry.
order_id: string;
// row ID of the order in the database
row_id: number;
// when the order was created
timestamp: Timestamp;
// the amount of money the order is for
amount: Amount;
// the summary of the order
summary: string;
// whether some part of the order is refundable,
// that is the refund deadline has not yet expired
// and the total amount refunded so far is below
// the value of the original transaction.
refundable: boolean;
// whether the order has been paid or not
paid: boolean;
}
interface PostOrderRequest {
// The order must at least contain the minimal
// order detail, but can override all
order: Order;
// if set, the backend will then set the refund deadline to the current
// time plus the specified delay. If it's not set, refunds will not be
// possible.
refund_delay?: RelativeTime;
// specifies the payment target preferred by the client. Can be used
// to select among the various (active) wire methods supported by the instance.
payment_target?: string;
// specifies that some products are to be included in the
// order from the inventory. For these inventory management
// is performed (so the products must be in stock) and
// details are completed from the product data of the backend.
inventory_products?: MinimalInventoryProduct[];
// Specifies a lock identifier that was used to
// lock a product in the inventory. Only useful if
// manage_inventory is set. Used in case a frontend
// reserved quantities of the individual products while
// the shopping card was being built. Multiple UUIDs can
// be used in case different UUIDs were used for different
// products (i.e. in case the user started with multiple
// shopping sessions that were combined during checkout).
lock_uuids?: UUID[];
// Should a token for claiming the order be generated?
// False can make sense if the ORDER_ID is sufficiently
// high entropy to prevent adversarial claims (like it is
// if the backend auto-generates one). Default is 'true'.
create_token?: boolean;
}
type Order = MinimalOrderDetail | ContractTerms;
interface MinimalOrderDetail {
// Amount to be paid by the customer
amount: Amount;
// Short summary of the order
summary: string;
// URL that will show that the order was successful after
// it has been paid for. Optional. When POSTing to the
// merchant, the placeholder "${ORDER_ID}" will be
// replaced with the actual order ID (useful if the
// order ID is generated server-side and needs to be
// in the URL).
fulfillment_url?: string;
}
interface MinimalInventoryProduct {
// Which product is requested (here mandatory!)
product_id: string;
// How many units of the product are requested
quantity: Integer;
}
interface PostOrderResponse {
// Order ID of the response that was just created
order_id: string;
// Token that authorizes the wallet to claim the order.
// Provided only if "create_token" was set to 'true'
// in the request.
token?: ClaimToken;
}
interface OutOfStockResponse {
// Product ID of an out-of-stock item
product_id: string;
// Requested quantity
requested_quantity: Integer;
// Available quantity (must be below requested_quanitity)
available_quantity: Integer;
// When do we expect the product to be again in stock?
// Optional, not given if unknown.
restock_expected?: Timestamp;
}
interface ForgetRequest {
// Array of valid JSON paths to forgettable fields in the order's
// contract terms.
fields: string[];
}
interface RefundRequest {
// Amount to be refunded
refund: Amount;
// Human-readable refund justification
reason: string;
}
interface MerchantRefundResponse {
// URL (handled by the backend) that the wallet should access to
// trigger refund processing.
// taler://refund/...
taler_refund_uri: string;
// Contract hash that a client may need to authenticate an
// HTTP request to obtain the above URI in a wallet-friendly way.
h_contract: HashCode;
}
}
namespace Tips {
// GET /private/reserves
interface TippingReserveStatus {
// Array of all known reserves (possibly empty!)
reserves: ReserveStatusEntry[];
}
interface ReserveStatusEntry {
// Public key of the reserve
reserve_pub: EddsaPublicKey;
// Timestamp when it was established
creation_time: Timestamp;
// Timestamp when it expires
expiration_time: Timestamp;
// Initial amount as per reserve creation call
merchant_initial_amount: Amount;
// Initial amount as per exchange, 0 if exchange did
// not confirm reserve creation yet.
exchange_initial_amount: Amount;
// Amount picked up so far.
pickup_amount: Amount;
// Amount approved for tips that exceeds the pickup_amount.
committed_amount: Amount;
// Is this reserve active (false if it was deleted but not purged)
active: boolean;
}
interface ReserveCreateRequest {
// Amount that the merchant promises to put into the reserve
initial_balance: Amount;
// Exchange the merchant intends to use for tipping
exchange_url: string;
// Desired wire method, for example "iban" or "x-taler-bank"
wire_method: string;
}
interface ReserveCreateConfirmation {
// Public key identifying the reserve
reserve_pub: EddsaPublicKey;
// Wire account of the exchange where to transfer the funds
payto_uri: string;
}
interface TipCreateRequest {
// Amount that the customer should be tipped
amount: Amount;
// Justification for giving the tip
justification: string;
// URL that the user should be directed to after tipping,
// will be included in the tip_token.
next_url: string;
}
interface TipCreateConfirmation {
// Unique tip identifier for the tip that was created.
tip_id: HashCode;
// taler://tip URI for the tip
taler_tip_uri: string;
// URL that will directly trigger processing
// the tip when the browser is redirected to it
tip_status_url: string;
// when does the tip expire
tip_expiration: Timestamp;
}
interface ReserveDetail {
// Timestamp when it was established.
creation_time: Timestamp;
// Timestamp when it expires.
expiration_time: Timestamp;
// Initial amount as per reserve creation call.
merchant_initial_amount: Amount;
// Initial amount as per exchange, 0 if exchange did
// not confirm reserve creation yet.
exchange_initial_amount: Amount;
// Amount picked up so far.
pickup_amount: Amount;
// Amount approved for tips that exceeds the pickup_amount.
committed_amount: Amount;
// Array of all tips created by this reserves (possibly empty!).
// Only present if asked for explicitly.
tips?: TipStatusEntry[];
// Is this reserve active (false if it was deleted but not purged)?
active: boolean;
// URI to use to fill the reserve, can be NULL
// if the reserve is inactive or was already filled
payto_uri: string;
// URL of the exchange hosting the reserve,
// NULL if the reserve is inactive
exchange_url: string;
}
interface TipStatusEntry {
// Unique identifier for the tip.
tip_id: HashCode;
// Total amount of the tip that can be withdrawn.
total_amount: Amount;
// Human-readable reason for why the tip was granted.
reason: string;
}
interface TipDetails {
// Amount that we authorized for this tip.
total_authorized: Amount;
// Amount that was picked up by the user already.
total_picked_up: Amount;
// Human-readable reason given when authorizing the tip.
reason: string;
// Timestamp indicating when the tip is set to expire (may be in the past).
expiration: TalerProtocolTimestamp;
// Reserve public key from which the tip is funded.
reserve_pub: EddsaPublicKey;
// Array showing the pickup operations of the wallet (possibly empty!).
// Only present if asked for explicitly.
pickups?: PickupDetail[];
}
interface PickupDetail {
// Unique identifier for the pickup operation.
pickup_id: HashCode;
// Number of planchets involved.
num_planchets: Integer;
// Total amount requested for this pickup_id.
requested_amount: Amount;
}
}
namespace Transfers {
interface TransferList {
// list of all the transfers that fit the filter that we know
transfers: TransferDetails[];
}
interface TransferDetails {
// how much was wired to the merchant (minus fees)
credit_amount: Amount;
// raw wire transfer identifier identifying the wire transfer (a base32-encoded value)
wtid: string;
// target account that received the wire transfer
payto_uri: string;
// base URL of the exchange that made the wire transfer
exchange_url: string;
// Serial number identifying the transfer in the merchant backend.
// Used for filgering via offset.
transfer_serial_id: number;
// Time of the execution of the wire transfer by the exchange, according to the exchange
// Only provided if we did get an answer from the exchange.
execution_time?: Timestamp;
// True if we checked the exchange's answer and are happy with it.
// False if we have an answer and are unhappy, missing if we
// do not have an answer from the exchange.
verified?: boolean;
// True if the merchant uses the POST /transfers API to confirm
// that this wire transfer took place (and it is thus not
// something merely claimed by the exchange).
confirmed?: boolean;
}
interface TransferInformation {
// how much was wired to the merchant (minus fees)
credit_amount: Amount;
// raw wire transfer identifier identifying the wire transfer (a base32-encoded value)
wtid: WireTransferIdentifierRawP;
// target account that received the wire transfer
payto_uri: string;
// base URL of the exchange that made the wire transfer
exchange_url: string;
}
interface MerchantTrackTransferResponse {
// Total amount transferred
total: Amount;
// Applicable wire fee that was charged
wire_fee: Amount;
// Time of the execution of the wire transfer by the exchange, according to the exchange
execution_time: Timestamp;
// details about the deposits
deposits_sums: MerchantTrackTransferDetail[];
}
interface MerchantTrackTransferDetail {
// Business activity associated with the wire transferred amount
// deposit_value.
order_id: string;
// The total amount the exchange paid back for order_id.
deposit_value: Amount;
// applicable fees for the deposit
deposit_fee: Amount;
}
type ExchangeConflictDetails = WireFeeConflictDetails | TrackTransferConflictDetails
// Note: this is not the full 'proof' of missbehavior, as
// the bogus message from the exchange with a signature
// over the 'different' wire fee is missing.
//
// This information is NOT provided by the current implementation,
// because this would be quite expensive to generate and is
// hardly needed _here_. Once we add automated reports for
// the Taler auditor, we need to generate this data anyway
// and should probably return it here as well.
interface WireFeeConflictDetails {
// Numerical error code:
code: "TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE";
// Text describing the issue for humans.
hint: string;
// Wire fee (wrongly) charged by the exchange, breaking the
// contract affirmed by the exchange_sig.
wire_fee: Amount;
// Timestamp of the wire transfer
execution_time: Timestamp;
// The expected wire fee (as signed by the exchange)
expected_wire_fee: Amount;
// Expected closing fee (needed to verify signature)
expected_closing_fee: Amount;
// Start date of the expected fee structure
start_date: Timestamp;
// End date of the expected fee structure
end_date: Timestamp;
// Signature of the exchange affirming the expected fee structure
master_sig: EddsaSignature;
// Master public key of the exchange
master_pub: EddsaPublicKey;
}
interface TrackTransferConflictDetails {
// Numerical error code
code: "TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS";
// Text describing the issue for humans.
hint: string;
// Offset in the exchange_transfer where the
// exchange's response fails to match the exchange_deposit_proof.
conflict_offset: number;
// The response from the exchange which tells us when the
// coin was returned to us, except that it does not match
// the expected value of the coin.
//
// This field is NOT provided by the current implementation,
// because this would be quite expensive to generate and is
// hardly needed _here_. Once we add automated reports for
// the Taler auditor, we need to generate this data anyway
// and should probably return it here as well.
// exchange_transfer?: TrackTransferResponse;
// Public key of the exchange used to sign the response to
// our deposit request.
deposit_exchange_pub: EddsaPublicKey;
// Signature of the exchange signing the (conflicting) response.
// Signs over a struct TALER_DepositConfirmationPS.
deposit_exchange_sig: EddsaSignature;
// Hash of the merchant's bank account the wire transfer went to
h_wire: HashCode;
// Hash of the contract terms with the conflicting deposit.
h_contract_terms: HashCode;
// At what time the exchange received the deposit. Needed
// to verify the \exchange_sig\.
deposit_timestamp: Timestamp;
// At what time the refund possibility expired (needed to verify exchange_sig).
refund_deadline: Timestamp;
// Public key of the coin for which we have conflicting information.
coin_pub: EddsaPublicKey;
// Amount the exchange counted the coin for in the transfer.
amount_with_fee: Amount;
// Expected value of the coin.
coin_value: Amount;
// Expected deposit fee of the coin.
coin_fee: Amount;
// Expected deposit fee of the coin.
deposit_fee: Amount;
}
// interface TrackTransferProof {
// // signature from the exchange made with purpose
// // TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT
// exchange_sig: EddsaSignature;
// // public EdDSA key of the exchange that was used to generate the signature.
// // Should match one of the exchange's signing keys from /keys. Again given
// // explicitly as the client might otherwise be confused by clock skew as to
// // which signing key was used.
// exchange_pub: EddsaSignature;
// // hash of the wire details (identical for all deposits)
// // Needed to check the exchange_sig
// h_wire: HashCode;
// }
}
interface ContractTerms {
// Human-readable description of the whole purchase
summary: string;
// Map from IETF BCP 47 language tags to localized summaries
summary_i18n?: { [lang_tag: string]: string };
// Unique, free-form identifier for the proposal.
// Must be unique within a merchant instance.
// For merchants that do not store proposals in their DB
// before the customer paid for them, the order_id can be used
// by the frontend to restore a proposal from the information
// encoded in it (such as a short product identifier and timestamp).
order_id: string;
// Total price for the transaction.
// The exchange will subtract deposit fees from that amount
// before transferring it to the merchant.
amount: Amount;
// The URL for this purchase. Every time is is visited, the merchant
// will send back to the customer the same proposal. Clearly, this URL
// can be bookmarked and shared by users.
fulfillment_url?: string;
fulfillment_message?: string;
// Maximum total deposit fee accepted by the merchant for this contract
max_fee: Amount;
// Maximum wire fee accepted by the merchant (customer share to be
// divided by the 'wire_fee_amortization' factor, and further reduced
// if deposit fees are below 'max_fee'). Default if missing is zero.
max_wire_fee: Amount;
// Over how many customer transactions does the merchant expect to
// amortize wire fees on average? If the exchange's wire fee is
// above 'max_wire_fee', the difference is divided by this number
// to compute the expected customer's contribution to the wire fee.
// The customer's contribution may further be reduced by the difference
// between the 'max_fee' and the sum of the actual deposit fees.
// Optional, default value if missing is 1. 0 and negative values are
// invalid and also interpreted as 1.
wire_fee_amortization: number;
// List of products that are part of the purchase (see Product).
products: Product[];
// Time when this contract was generated
timestamp: TalerProtocolTimestamp;
// After this deadline has passed, no refunds will be accepted.
refund_deadline: TalerProtocolTimestamp;
// After this deadline, the merchant won't accept payments for the contact
pay_deadline: TalerProtocolTimestamp;
// Transfer deadline for the exchange. Must be in the
// deposit permissions of coins used to pay for this order.
wire_transfer_deadline: TalerProtocolTimestamp;
// Merchant's public key used to sign this proposal; this information
// is typically added by the backend Note that this can be an ephemeral key.
merchant_pub: EddsaPublicKey;
// Base URL of the (public!) merchant backend API.
// Must be an absolute URL that ends with a slash.
merchant_base_url: string;
// More info about the merchant, see below
merchant: Merchant;
// The hash of the merchant instance's wire details.
h_wire: HashCode;
// Wire transfer method identifier for the wire method associated with h_wire.
// The wallet may only select exchanges via a matching auditor if the
// exchange also supports this wire method.
// The wire transfer fees must be added based on this wire transfer method.
wire_method: string;
// Any exchanges audited by these auditors are accepted by the merchant.
auditors: Auditor[];
// Exchanges that the merchant accepts even if it does not accept any auditors that audit them.
exchanges: Exchange[];
// Delivery location for (all!) products.
delivery_location?: Location;
// Time indicating when the order should be delivered.
// May be overwritten by individual products.
delivery_date?: TalerProtocolTimestamp;
// Nonce generated by the wallet and echoed by the merchant
// in this field when the proposal is generated.
nonce: string;
// Specifies for how long the wallet should try to get an
// automatic refund for the purchase. If this field is
// present, the wallet should wait for a few seconds after
// the purchase and then automatically attempt to obtain
// a refund. The wallet should probe until "delay"
// after the payment was successful (i.e. via long polling
// or via explicit requests with exponential back-off).
//
// In particular, if the wallet is offline
// at that time, it MUST repeat the request until it gets
// one response from the merchant after the delay has expired.
// If the refund is granted, the wallet MUST automatically
// recover the payment. This is used in case a merchant
// knows that it might be unable to satisfy the contract and
// desires for the wallet to attempt to get the refund without any
// customer interaction. Note that it is NOT an error if the
// merchant does not grant a refund.
auto_refund?: RelativeTime;
// Extra data that is only interpreted by the merchant frontend.
// Useful when the merchant needs to store extra information on a
// contract without storing it separately in their database.
extra?: any;
}
}