From 3c03ac5de448880b428b61e8c4fba1d393caf054 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 18 Mar 2024 15:31:29 -0300 Subject: remove contract terms fields that has been deprecated --- packages/taler-util/src/http-client/merchant.ts | 25 +-- packages/taler-util/src/http-client/types.ts | 12 +- packages/taler-util/src/taler-types.ts | 236 +++++++++++++----------- 3 files changed, 151 insertions(+), 122 deletions(-) (limited to 'packages/taler-util/src') diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts index 1d498fb57..00efc5a71 100644 --- a/packages/taler-util/src/http-client/merchant.ts +++ b/packages/taler-util/src/http-client/merchant.ts @@ -18,7 +18,9 @@ import { HttpStatusCode, LibtoolVersion, TalerMerchantApi, - codecForMerchantConfig + codecForClaimResponse, + codecForMerchantConfig, + opKnownHttpFailure } from "@gnu-taler/taler-util"; import { HttpRequestLibrary, @@ -70,16 +72,17 @@ class TalerMerchantInstanceHttpClient { method: "POST", body, }); - // switch (resp.status) { - // case HttpStatusCode.Ok: - // return opSuccessFromHttp(resp, codecForClaimResponse()); - // case HttpStatusCode.Conflict: - // return opKnownHttpFailure(resp.status, resp) - // case HttpStatusCode.NotFound: - // return opKnownHttpFailure(resp.status, resp) - // default: - // return opUnknownFailure(resp, await resp.text()); - // } + + switch (resp.status) { + case HttpStatusCode.Ok: + return opSuccessFromHttp(resp, codecForClaimResponse()); + case HttpStatusCode.Conflict: + return opKnownHttpFailure(resp.status, resp) + case HttpStatusCode.NotFound: + return opKnownHttpFailure(resp.status, resp) + default: + return opUnknownFailure(resp, await resp.text()); + } } /** diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts index 97e37cf7d..67ac289d6 100644 --- a/packages/taler-util/src/http-client/types.ts +++ b/packages/taler-util/src/http-client/types.ts @@ -15,7 +15,7 @@ import { codecOptional, } from "../codec.js"; import { PaytoString, codecForPaytoString } from "../payto.js"; -import { AmountString } from "../taler-types.js"; +import { AmountString, MerchantContractTerms, codecForMerchantContractTerms } from "../taler-types.js"; import { TalerActionString, codecForTalerActionString } from "../taleruri.js"; import { AbsoluteTime, @@ -312,6 +312,13 @@ export const codecForMerchantConfig = .property("exchanges", codecForList(codecForExchangeConfigInfo())) .build("TalerMerchantApi.VersionResponse"); +export const codecForClaimResponse = + (): Codec => + buildCodecForObject() + .property("contract_terms", codecForMerchantContractTerms()) + .property("sig", codecForString()) + .build("TalerMerchantApi.ClaimResponse"); + export const codecForExchangeConfig = (): Codec => buildCodecForObject() @@ -2469,7 +2476,8 @@ export namespace TalerMerchantApi { export interface ClaimResponse { // Contract terms of the claimed order - contract_terms: ContractTerms; + contract_terms: MerchantContractTerms; + // Signature by the merchant over the contract terms. sig: EddsaSignature; diff --git a/packages/taler-util/src/taler-types.ts b/packages/taler-util/src/taler-types.ts index fe8f47e30..a0db25182 100644 --- a/packages/taler-util/src/taler-types.ts +++ b/packages/taler-util/src/taler-types.ts @@ -303,15 +303,23 @@ export interface CoinDepositPermission { * merchant's contract terms. */ export interface ExchangeHandle { - /** - * Master public signing key of the exchange. - */ - master_pub: string; - - /** - * Base URL of the exchange. - */ + // The exchange's base URL. url: string; + + // How much would the merchant like to use this exchange. + // The wallet should use a suitable exchange with high + // priority. The following priority values are used, but + // it should be noted that they are NOT in any way normative. + // + // 0: likely it will not work (recently seen with account + // restriction that would be bad for this merchant) + // 512: merchant does not know, might be down (merchant + // did not yet get /wire response). + // 1024: good choice (recently confirmed working) + priority: Integer; + + // Master public key of the exchange. + master_pub: EddsaPublicKeyString; } export interface AuditorHandle { @@ -323,7 +331,7 @@ export interface AuditorHandle { /** * Master public signing key of the auditor. */ - auditor_pub: string; + auditor_pub: EddsaPublicKeyString; /** * Base URL of the auditor. @@ -367,12 +375,24 @@ export interface Location { } export interface MerchantInfo { + // The merchant's legal name of business. name: string; - jurisdiction?: Location; - address?: Location; - logo?: string; - website?: string; + + // Label for a location with the business address of the merchant. email?: string; + + // Label for a location with the business address of the merchant. + website?: string; + + // An optional base64-encoded product image. + logo?: ImageDataUrl; + + // Label for a location with the business address of the merchant. + address?: Location; + + // 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; } export interface Tax { @@ -391,10 +411,10 @@ export interface Product { description: string; // Map from IETF BCP 47 language tags to localized descriptions - description_i18n?: { [lang_tag: string]: string }; + description_i18n?: InternationalizedString; // The number of units of the product to deliver to the customer. - quantity?: number; + quantity?: Integer; // The unit in which the product is measured (liters, kilograms, packages, etc.) unit?: string; @@ -403,7 +423,7 @@ export interface Product { price?: AmountString; // An optional base64-encoded product image - image?: string; + image?: ImageDataUrl; // a list of taxes paid by the merchant for this product. Can be empty. taxes?: Tax[]; @@ -421,141 +441,139 @@ export interface InternationalizedString { * FIXME: Add type field! */ export interface MerchantContractTerms { - /** - * Hash of the merchant's wire details. - */ + // The hash of the merchant instance's wire details. h_wire: string; - /** - * Hash of the merchant's wire details. - */ + // 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?: TalerProtocolDuration; - /** - * Wire method the merchant wants to use. - */ + // 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; - /** - * Human-readable short summary of the contract. - */ + // Human-readable description of the whole purchase. summary: string; + // Map from IETF BCP 47 language tags to localized summaries. summary_i18n?: InternationalizedString; - /** - * Nonce used to ensure freshness. - */ - nonce: 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 amount payable. - */ + // Total price for the transaction. + // The exchange will subtract deposit fees from that amount + // before transferring it to the merchant. amount: string; - /** - * Deadline to pay for the contract. - */ - pay_deadline: TalerProtocolTimestamp; + // Nonce generated by the wallet and echoed by the merchant + // in this field when the proposal is generated. + nonce: string; - /** - * Maximum deposit fee covered by the merchant. - */ - max_fee: string; + // After this deadline, the merchant won't accept payments for the contract. + pay_deadline: TalerProtocolTimestamp; - /** - * Information about the merchant. - */ + // More info about the merchant, see below. merchant: MerchantInfo; - /** - * Public key of the merchant. - */ + // 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: string; - /** - * Time indicating when the order should be delivered. - * May be overwritten by individual products. - */ + // Time indicating when the order should be delivered. + // May be overwritten by individual products. delivery_date?: TalerProtocolTimestamp; - /** - * Delivery location for (all!) products. - */ + // Delivery location for (all!) products. delivery_location?: Location; - /** - * List of accepted exchanges. - */ + // Exchanges that the merchant accepts even if it does not accept any auditors that audit them. exchanges: ExchangeHandle[]; - /** - * Products that are sold in this contract. - */ + // List of products that are part of the purchase (see Product). products?: Product[]; - /** - * Deadline for refunds. - */ + // After this deadline has passed, no refunds will be accepted. refund_deadline: TalerProtocolTimestamp; - /** - * Deadline for the wire transfer. - */ + // Transfer deadline for the exchange. Must be in the + // deposit permissions of coins used to pay for this order. wire_transfer_deadline: TalerProtocolTimestamp; - /** - * Time when the contract was generated by the merchant. - */ + // Time when this contract was generated. timestamp: TalerProtocolTimestamp; - /** - * Order id to uniquely identify the purchase within - * one merchant instance. - */ - order_id: string; - - /** - * Base URL of the merchant's backend. - */ + // Base URL of the (public!) merchant backend API. + // Must be an absolute URL that ends with a slash. merchant_base_url: string; - /** - * Fulfillment URL to view the product or - * delivery status. - */ + // URL that will show that the order was successful after + // it has been paid for. Optional, but either fulfillment_url + // or fulfillment_message must be specified in every + // contract terms. + // + // If a non-unique fulfillment URL is used, a customer can only + // buy the order once and will be redirected to a previous purchase + // when trying to buy an order with the same fulfillment URL a second + // time. This is useful for digital goods that a customer only needs + // to buy once but should be able to repeatedly download. + // + // For orders where the customer is expected to be able to make + // repeated purchases (for equivalent goods), the fulfillment URL + // should be made unique for every order. The easiest way to do + // this is to include a unique order ID in the fulfillment URL. + // + // When POSTing to the merchant, the placeholder text "${ORDER_ID}" + // is be replaced with the actual order ID (useful if the + // order ID is generated server-side and needs to be + // in the URL). Note that this placeholder can only be used once. + // Front-ends may use other means to generate a unique fulfillment URL. fulfillment_url?: string; - /** - * URL meant to share the shopping cart. - */ + // URL where the same contract could be ordered again (if + // available). Returned also at the public order endpoint + // for people other than the actual buyer (hence public, + // in case order IDs are guessable). public_reorder_url?: string; - /** - * Plain text fulfillment message in the merchant's default language. - */ + // Message shown to the customer after paying for the order. + // Either fulfillment_url or fulfillment_message must be specified. fulfillment_message?: string; - /** - * Internationalized fulfillment messages. - */ + // Map from IETF BCP 47 language tags to localized fulfillment + // messages. fulfillment_message_i18n?: InternationalizedString; - /** - * Share of the wire fee that must be settled with one payment. - */ - wire_fee_amortization?: number; - - /** - * Maximum wire fee that the merchant agrees to pay for. - */ - max_wire_fee?: string; - - minimum_age?: number; + // Maximum total deposit fee accepted by the merchant for this contract. + // Overrides defaults of the merchant instance. + max_fee: string; - /** - * Extra data, interpreted by the mechant only. - */ + // 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. + // Must really be an Object (not a string, integer, float or array). extra?: any; } @@ -831,6 +849,7 @@ export interface DenomCommon { export type RsaPublicKeySring = string; export type AgeMask = number; +export type ImageDataUrl = string; /** * 32-byte value representing a point on Curve25519. @@ -1375,6 +1394,7 @@ export const codecForAuditor = (): Codec => export const codecForExchangeHandle = (): Codec => buildCodecForObject() .property("master_pub", codecForString()) + .property("priority", codecForNumber()) .property("url", codecForString()) .build("ExchangeHandle"); @@ -1452,13 +1472,11 @@ export const codecForMerchantContractTerms = (): Codec => .property("delivery_location", codecOptional(codecForLocation())) .property("delivery_date", codecOptional(codecForTimestamp)) .property("max_fee", codecForString()) - .property("max_wire_fee", codecOptional(codecForString())) .property("merchant", codecForMerchantInfo()) .property("merchant_pub", codecForString()) .property("exchanges", codecForList(codecForExchangeHandle())) .property("products", codecOptional(codecForList(codecForProduct()))) .property("extra", codecForAny()) - .property("minimum_age", codecOptional(codecForNumber())) .build("MerchantContractTerms"); export const codecForPeerContractTerms = (): Codec => -- cgit v1.2.3