gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-docs] branch master updated: spec v1 of merchant protocol


From: gnunet
Subject: [taler-docs] branch master updated: spec v1 of merchant protocol
Date: Mon, 13 Apr 2020 16:27:12 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository docs.

The following commit(s) were added to refs/heads/master by this push:
     new 95f5214  spec v1 of merchant protocol
95f5214 is described below

commit 95f5214432d6f58ac374db481cc13e5542b2572c
Author: Christian Grothoff <address@hidden>
AuthorDate: Mon Apr 13 16:27:10 2020 +0200

    spec v1 of merchant protocol
---
 core/api-merchant.rst | 1862 +++++++++++++++++++++++++++----------------------
 1 file changed, 1016 insertions(+), 846 deletions(-)

diff --git a/core/api-merchant.rst b/core/api-merchant.rst
index 22c090f..43eed03 100644
--- a/core/api-merchant.rst
+++ b/core/api-merchant.rst
@@ -23,9 +23,74 @@
 Merchant Backend API
 ====================
 
+WARNING: This document describes the version 1 of the merchant backend
+API, which is NOT yet implemented at all!
+
+The ``*/public/*`` endpoints are publicly exposed on the Internet and accessed
+both by the user's browser and their wallet.
+
+Most endpoints given here can be prefixed by a base URL that includes the
+specific instance selected (BASE_URL/instances/$INSTANCE/).  If
+``/instances/`` is missing, the default instance is to be used.
+
 .. contents:: Table of Contents
 
 
+-------------------------
+Getting the configuration
+-------------------------
+
+.. http:get:: /public/config
+
+  Return the protocol version and currency supported by this merchant backend.
+
+  **Response:**
+
+  :status 200 OK:
+    The exchange accepted all of the coins. The body is a `VersionResponse`.
+
+  .. ts:def:: VersionResponse
+
+    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;
+
+      // Currency supported by this backend.
+      currency: string;
+
+      // optional array with information about the instances running at this 
backend
+      // FIXME: remove, use/provide http:get:: /instances instead!
+      instances: InstanceInformation[];
+    }
+
+  .. ts:def:: InstanceInformation
+
+    interface InstanceInformation {
+
+      // Human-readable legal business name served by this instance
+      name: string;
+
+      // Base URL of the instance. Can be of the form "/PizzaShop/" or
+      // a fully qualified URL (i.e. "https://backend.example.com/PizzaShop/";).
+      instance_baseurl: 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[];
+
+      // Base URL of the exchange this instance uses for tipping.
+      // Optional, only present if the instance supports tipping.
+      // FIXME: obsolete with current tipping API!
+      tipping_exchange_baseurl?: string;
+
+    }
+
 
 ------------------
 Receiving Payments
@@ -33,7 +98,7 @@ Receiving Payments
 
 .. _post-order:
 
-.. http:post:: /order
+.. http:post:: /create-order
 
   Create a new order that a customer can pay for.
 
@@ -41,10 +106,10 @@ Receiving Payments
 
   .. note::
 
-    This endpoint does not return a URL to redirect your user to confirm the 
payment.
-    In order to get this URL use :http:get:`/check-payment`.  The API is 
structured this way
-    since the payment redirect URL is not unique for every order, there might 
be varying parameters
-    such as the session id.
+    This endpoint does not return a URL to redirect your user to confirm the
+    payment.  In order to get this URL use :http:get:`/orders/$ORDER_ID`.  The
+    API is structured this way since the payment redirect URL is not unique
+    for every order, there might be varying parameters such as the session id.
 
   **Request:**
 
@@ -79,8 +144,8 @@ Receiving Payments
       summary: string;
 
       // URL that will show that the order was successful after
-      // it has been paid for.  The wallet will always automatically append
-      // the order_id as a query parameter.
+      // it has been paid for.  The wallet must always automatically append
+      // the order_id as a query parameter to this URL when using it.
       fulfillment_url: string;
     }
 
@@ -92,363 +157,291 @@ Receiving Payments
     }
 
 
-.. http:get:: /check-payment
 
-  Check the payment status of an order.  If the order exists but is not payed 
yet,
-  the response provides a redirect URL.
-  When the user goes to this URL, they will be prompted for payment.
+.. http:get:: /orders
 
-  **Request:**
-
-  :query order_id: order id that should be used for the payment
-  :query session_id: *Optional*. Session ID that the payment must be bound to. 
 If not specified, the payment is not session-bound.
-  :query timeout: *Optional*. Timeout in seconds to wait for a payment if the 
answer would otherwise be negative (long polling).
+  Returns known orders up to some point in the past
 
-  **Response:**
+  **Request**
 
-  Returns a `CheckPaymentResponse`, whose format can differ based on the 
status of the payment.
+  :query paid: *Optional*. If set to yes, only return paid orders, if no only 
unpaid orders. Do not give (or use "all") to see all orders regardless of 
payment status.
+  :query aborted: *Optional*. If set to yes, only return aborted orders, if no 
only unaborted orders. Do not give (or use "all")  to see all orders regardless 
of abort status.
+  :query refunded: *Optional*. If set to yes, only return refunded orders, if 
no only unrefunded orders. Do not give (or use "all") to see all orders 
regardless of refund status.
+  :query wired: *Optional*. If set to yes, only return wired orders, if no 
only orders with missing wire transfers. Do not give (or use "all") to see all 
orders regardless of wire transfer status.
+  :query date: *Optional.* Time threshold, see ``delta`` for its 
interpretation.  Defaults to the oldest or most recent entry, depending on 
``delta``.
+  :query start: *Optional*. Row number threshold, see ``delta`` for its 
interpretation.  Defaults to ``UINT64_MAX``, namely the biggest row id possible 
in the database.
+  :query delta: *Optional*. takes value of the form ``N (-N)``, so that at 
most ``N`` values strictly younger (older) than ``start`` and ``date`` are 
returned.  Defaults to ``-20``.
+  :query timeout_ms: *Optional*. Timeout in milli-seconds to wait for 
additional orders if the answer would otherwise be negative (long polling). 
Only useful if delta is positive. Note that the merchant MAY still return a 
response that contains fewer than delta orders.
 
-  .. ts:def:: CheckPaymentResponse
+  **Response**
 
-    type CheckPaymentResponse = CheckPaymentPaidResponse | 
CheckPaymentUnpaidResponse
+  :status 200 OK:
+    The response is a JSON ``array`` of  `OrderHistory`.  The array is
+    sorted such that entry ``i`` is younger than entry ``i+1``.
 
-  .. ts:def:: CheckPaymentPaidResponse
+  .. ts:def:: OrderHistory
 
-    interface CheckPaymentPaidResponse {
-      paid: true;
+    interface OrderHistory {
+      // The serial number this entry has in the merchant's DB.
+      row_id: number;
 
-      // Was the payment refunded (even partially)
-      refunded: boolean;
+      // order ID of the transaction related to this entry.
+      order_id: string;
 
-      // Amount that was refunded, only present if refunded is true.
-      refund_amount?: Amount;
+      // Transaction's timestamp
+      timestamp: Timestamp;
 
-      // Contract terms
-      contract_terms: ContractTerms;
-    }
+      // Total amount the customer should pay for this order.
+      total: Amount;
 
-  .. ts:def:: CheckPaymentUnpaidResponse
+      // Total amount the customer did pay for this order.
+      paid: Amount;
 
-    interface CheckPaymentUnpaidResponse {
-      paid: false;
+      // Total amount the customer was refunded for this order.
+      // (includes abort-refund and refunds, boolean flag
+      // below can help determine which case it is).
+      refunded: Amount;
 
-      // URI that the wallet must process to complete the payment.
-      taler_pay_uri: string;
+      // Was the order ever fully paid?
+      is_paid: boolean;
 
-      // 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;
     }
 
 
---------------
-Giving Refunds
---------------
 
 
-.. http:post:: /refund
+.. http:post:: /public/orders/$ORDER_ID/claim
 
-  Increase the refund amount associated with a given order.  The user should be
-  redirected to the ``taler_refund_url`` to trigger refund processing in the 
wallet.
+  Wallet claims ownership (via nonce) over an order.  By claiming
+  an order, the wallet obtains the full contract terms, and thereby
+  implicitly also the hash of the contract terms it needs for the
+  other ``/public/`` APIs to authenticate itself as the wallet that
+  is indeed eligible to inspect this particular order's status.
 
   **Request**
 
-  The request body is a `RefundRequest` object.
+  The request must be a `ClaimRequest`
+
+  .. ts:def:: ClaimRequest
+
+    interface ClaimRequest {
+      // Nonce to identify the wallet that claimed the order.
+      nonce: string;
+    }
 
   **Response**
 
   :status 200 OK:
-    The refund amount has been increased, the backend responds with a 
`MerchantRefundResponse`
+    The client has successfully claimed the order.
+    The response contains the :ref:`contract terms <ContractTerms>`.
   :status 404 Not found:
-    The order is unknown to the merchant
+    The backend is unaware of the instance or order.
   :status 409 Conflict:
-    The refund amount exceeds the amount originally paid
-
-  .. ts:def:: RefundRequest
+    The someone else claimed the same order ID with different nonce before.
 
-    interface RefundRequest {
-      // Order id of the transaction to be refunded
-      order_id: string;
 
-      // Amount to be refunded
-      refund: Amount;
+.. http:post:: /public/orders/$ORDER_ID/pay
 
-      // Human-readable refund justification
-      reason: string;
-    }
+  Pay for an order by giving a deposit permission for coins.  Typically used by
+  the customer's wallet.  Note that this request does not include the
+  usual ``h_contract`` argument to authenticate the wallet, as the hash of
+  the contract is implied by the signatures of the coins.  Furthermore, this
+  API doesn't really return useful information about the order.
 
-  .. ts:def:: MerchantRefundResponse
+  **Request:**
 
-    interface MerchantRefundResponse {
+  The request must be a `pay request <PayRequest>`.
 
-      // Hash of the contract terms of the contract that is being refunded.
-      h_contract_terms: HashCode;
+  **Response:**
 
-      // URL (handled by the backend) that the wallet should access to
-      // trigger refund processing.
-      taler_refund_url: string;
-    }
+  :status 200 OK:
+    The exchange accepted all of the coins.
+    The body is a `payment response <PaymentResponse>`.
+    The ``frontend`` should now fullfill the contract.
+  :status 400 Bad request:
+    Either the client request is malformed or some specific processing error
+    happened that may be the fault of the client as detailed in the JSON body
+    of the response.
+  :status 403 Forbidden:
+    One of the coin signatures was not valid.
+  :status 404 Not found:
+    The merchant backend could not find the order or the instance
+    and thus cannot process the payment.
+  :status 409 Conflict:
+    The exchange rejected the payment because a coin was already spent before.
+    The response will include the ``coin_pub`` for which the payment failed,
+    in addition to the response from the exchange to the ``/deposit`` request.
+  :status 412 Precondition Failed:
+    The given exchange is not acceptable for this merchant, as it is not in the
+    list of accepted exchanges and not audited by an approved auditor.
+  :status 424 Failed Dependency:
+    The merchant's interaction with the exchange failed in some way.
+    The client might want to try later again.
+    This includes failures like the denomination key of a coin not being
+    known to the exchange as far as the merchant can tell.
 
+  The backend will return verbatim the error codes received from the exchange's
+  :ref:`deposit <deposit>` API.  If the wallet made a mistake, like by
+  double-spending for example, the frontend should pass the reply verbatim to
+  the browser/wallet.  If the payment was successful, the frontend MAY use
+  this to trigger some business logic.
 
---------------------
-Giving Customer Tips
---------------------
+  .. ts:def:: PaymentResponse
 
+    interface PaymentResponse {
+      // Signature on ``TALER_PaymentResponsePS`` with the public
+      // key of the merchant instance.
+      sig: EddsaSignature;
 
-.. http:post:: /tip-authorize
+    }
 
-  Authorize a tip that can be picked up by the customer's wallet by POSTing to
-  ``/tip-pickup``.  Note that this is simply the authorization step the back
-  office has to trigger first.  The user should be navigated to the 
``tip_redirect_url``
-  to trigger tip processing in the wallet.
+  .. ts:def:: PayRequest
 
-  **Request**
+    interface PayRequest {
+      coins: CoinPaySig[];
+    }
 
-  The request body is a `TipCreateRequest` object.
+  .. ts:def:: CoinPaySig
 
-  **Response**
+    export interface CoinPaySig {
+      // Signature by the coin.
+      coin_sig: string;
 
-  :status 200 OK:
-    A tip has been created. The backend responds with a `TipCreateConfirmation`
-  :status 404 Not Found:
-    The instance is unknown to the backend.
-  :status 412 Precondition Failed:
-    The tip amount requested exceeds the available reserve balance for 
tipping, or
-    the instance was never configured for tipping.
-  :status 424 Failed Dependency:
-    We are unable to process the request because of a problem with the 
exchange.
-    Likely returned with an "exchange_code" in addition to a "code" and
-    an "exchange_http_status" in addition to our own HTTP status. Also may
-    include the full exchange reply to our request under "exchange_reply".
-    Naturally, those diagnostics may be omitted if the exchange did not reply
-    at all, or send a completely malformed response.
-  :status 503 Service Unavailable:
-    We are unable to process the request, possibly due to misconfiguration or
-    disagreement with the exchange (it is unclear which party is to blame).
-    Likely returned with an "exchange_code" in addition to a "code" and
-    an "exchange_http_status" in addition to our own HTTP status. Also may
-    include the full exchange reply to our request under "exchange_reply".
+      // Public key of the coin being spend.
+      coin_pub: string;
 
-  .. ts:def:: TipCreateRequest
+      // Signature made by the denomination public key.
+      ub_sig: string;
 
-    interface TipCreateRequest {
-      // Amount that the customer should be tipped
-      amount: Amount;
+      // The denomination public key associated with this coin.
+      denom_pub: string;
 
-      // Justification for giving the tip
-      justification: string;
+      // The amount that is subtracted from this coin with this payment.
+      contribution: Amount;
 
-      // URL that the user should be directed to after tipping,
-      // will be included in the tip_token.
-      next_url: string;
+      // URL of the exchange this coin was withdrawn from.
+      exchange_url: string;
     }
 
-  .. ts:def:: TipCreateConfirmation
 
-    interface TipCreateConfirmation {
-      // Token that will be handed to the wallet,
-      // contains all relevant information to accept
-      // a tip.
-      tip_token: string;
+.. http:post:: /public/orders/$ORDER_ID/abort
 
-      // URL that will directly trigger procesing
-      // the tip when the browser is redirected to it
-      tip_redirect_url: string;
-    }
+  Abort paying for an order and obtain a refund for coins that
+  were already deposited as part of a failed payment.
 
+  **Request:**
 
-.. http:post:: /tip-query
+  The request must be an `abort request <AbortRequest>`.
 
-  Query the status of a tipping reserve.
+  :query h_contract: hash of the order's contract terms (this is used to 
authenticate the wallet/customer in case $ORDER_ID is guessable). *Mandatory!*
 
-  **Response**
+  **Response:**
 
   :status 200 OK:
-    A tip has been created. The backend responds with a `TipQueryResponse`
-  :status 404 Not Found:
-    The instance is unknown to the backend.
+    The exchange accepted all of the coins. The body is a
+    a `merchant refund response <MerchantRefundResponse>`.
+  :status 400 Bad request:
+    Either the client request is malformed or some specific processing error
+    happened that may be the fault of the client as detailed in the JSON body
+    of the response.
+  :status 403 Forbidden:
+    The ``h_contract`` does not match the order.
+  :status 404 Not found:
+    The merchant backend could not find the order or the instance
+    and thus cannot process the abort request.
   :status 412 Precondition Failed:
-    The merchant backend instance does not have a tipping reserve configured.
+    Aborting the payment is not allowed, as the original payment did succeed.
   :status 424 Failed Dependency:
-    We are unable to process the request because of a problem with the 
exchange.
-    Likely returned with an "exchange_code" in addition to a "code" and
-    an "exchange_http_status" in addition to our own HTTP status. Also may
-    include the full exchange reply to our request under "exchange_reply".
-    Naturally, those diagnostics may be omitted if the exchange did not reply
-    at all, or send a completely malformed response.
-  :status 503 Service Unavailable:
-    We are unable to process the request, possibly due to misconfiguration or
-    disagreement with the exchange (it is unclear which party is to blame).
-    Likely returned with an "exchange_code" in addition to a "code" and
-    an "exchange_http_status" in addition to our own HTTP status. Also may
-    include the full exchange reply to our request under "exchange_reply".
-
-  .. ts:def:: TipQueryResponse
-
-    interface TipQueryResponse {
-      // Amount still available
-      amount_available: Amount;
+    The merchant's interaction with the exchange failed in some way.
+    The error from the exchange is included.
 
-      // Amount that we authorized for tips
-      amount_authorized: Amount;
+  The backend will return verbatim the error codes received from the exchange's
+  :ref:`refund <refund>` API.  The frontend should pass the replies verbatim to
+  the browser/wallet.
 
-      // Amount that was picked up by users already
-      amount_picked_up: Amount;
+  .. ts:def:: AbortRequest
 
-      // Timestamp indicating when the tipping reserve will expire
-      expiration: Timestamp;
+    interface AbortRequest {
+      // List of coins the wallet would like to see refunds for.
+      // (Should be limited to the coins for which the original
+      // payment succeeded, as far as the wallet knows.)
+      coins: AbortedCoin[];
+    }
 
-      // Reserve public key of the tipping reserve
-      reserve_pub: EddsaPublicKey;
+    interface AbortedCoin {
+      // Public key of a coin for which the wallet is requesting an 
abort-related refund.
+      coin_pub: EddsaPublicKey;
     }
 
 
-------------------------
-Tracking Wire Transfers
-------------------------
 
-.. http:get:: /track/transfer
+.. http:get:: /orders/$ORDER_ID/
 
-  Provides deposits associated with a given wire transfer.
+  Merchant checks the payment status of an order.  If the order exists but is 
not payed
+  yet, the response provides a redirect URL.  When the user goes to this URL,
+  they will be prompted for payment.  Differs from the ``/public/`` API both
+  in terms of what information is returned and in that the wallet must provide
+  the contract hash to authenticate, while for this API we assume that the
+  merchant is authenticated (as the endpoint is not ``/public/``).
 
-  **Request**
+  **Request:**
 
-  :query wtid: raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
-  :query wire_method: name of the wire transfer method used for the wire 
transfer
-  :query exchange: base URL of the exchange that made the wire transfer
+  :query session_id: *Optional*. Session ID that the payment must be bound to. 
 If not specified, the payment is not session-bound.
+  :query transfer: *Optional*. If set to "YES", try to obtain the wire 
transfer status for this order from the exchange. Otherwise, the wire transfer 
status MAY be returned if it is available.
+  :query timeout_ms: *Optional*. Timeout in milli-seconds to wait for a 
payment if the answer would otherwise be negative (long polling).
 
   **Response:**
 
   :status 200 OK:
-    The wire transfer is known to the exchange, details about it follow in the 
body.
-    The body of the response is a `TrackTransferResponse`.  Note that
-    the similarity to the response given by the exchange for a /track/transfer
-    is completely intended.
-
+    Returns a `MerchantOrderStatusResponse`, whose format can differ based on 
the status of the payment.
   :status 404 Not Found:
-    The wire transfer identifier is unknown to the exchange.
+    The order or instance is unknown to the backend.
+  :status 409 Conflict:
+    The exchange previously claimed that a deposit was not included in a wire
+    transfer, and now claims that it is.  This means that the exchange is
+    dishonest.  The response contains the cryptographic proof that the exchange
+    is misbehaving in the form of a `TransactionConflictProof`.
+  :status 424 Failed dependency:
+    We failed to obtain a response from the exchange about the
+    wire transfer status.
 
-  :status 424 Failed Dependency: The exchange provided conflicting information 
about the transfer. Namely,
-    there is at least one deposit among the deposits aggregated by ``wtid`` 
that accounts for a coin whose
-    details don't match the details stored in merchant's database about the 
same keyed coin.
-    The response body contains the `TrackTransferConflictDetails`.
+  .. ts:def:: MerchantOrderStatusResponse
 
-  .. ts:def:: TrackTransferResponse
+    type MerchantOrderStatusResponse = CheckPaymentPaidResponse | 
CheckPaymentUnpaidResponse
 
-    interface TrackTransferResponse {
-      // Total amount transferred
-      total: Amount;
+  .. ts:def:: CheckPaymentPaidResponse
 
-      // Applicable wire fee that was charged
-      wire_fee: Amount;
+    interface CheckPaymentPaidResponse {
+      paid: true;
 
-      // public key of the merchant (identical for all deposits)
-      merchant_pub: EddsaPublicKey;
+      // Was the payment refunded (even partially)
+      refunded: boolean;
 
-      // hash of the wire details (identical for all deposits)
-      h_wire: HashCode;
-
-      // Time of the execution of the wire transfer by the exchange
-      execution_time: Timestamp;
-
-      // details about the deposits
-      deposits_sums: TrackTransferDetail[];
-
-      // 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;
-    }
-
-  .. ts:def:: TrackTransferDetail
-
-    interface TrackTransferDetail {
-      // Business activity associated with the wire transferred amount
-      // ``deposit_value``.
-      order_id: string;
+      // Amount that was refunded, only present if refunded is true.
+      refund_amount?: Amount;
 
-      // The total amount the exchange paid back for ``order_id``.
-      deposit_value: Amount;
+      // Contract terms
+      contract_terms: ContractTerms;
 
-      // applicable fees for the deposit
-      deposit_fee: Amount;
+      // If available, the wire transfer status from the exchange for this 
order
+      wire_details?: TransactionWireTransfer;
     }
 
+  .. ts:def:: CheckPaymentUnpaidResponse
 
-  **Details:**
-
-  .. ts:def:: TrackTransferConflictDetails
-
-    interface TrackTransferConflictDetails {
-      // Numerical `error code <error-codes>`
-      code: number;
-
-      // Text describing the issue for humans.
-      hint: string;
-
-      // A /deposit response matching ``coin_pub`` showing that the
-      // exchange accepted ``coin_pub`` for ``amount_with_fee``.
-      exchange_deposit_proof: DepositSuccess;
-
-      // Offset in the ``exchange_transfer_proof`` 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.
-      exchange_transfer_proof: TrackTransferResponse;
-
-      // Public key of the coin for which we have conflicting information.
-      coin_pub: EddsaPublicKey;
-
-      // Merchant transaction in which ``coin_pub`` was involved for which
-      // we have conflicting information.
-      transaction_id: number;
+    interface CheckPaymentUnpaidResponse {
+      paid: false;
 
-      // Expected value of the coin.
-      amount_with_fee: Amount;
+      // URI that the wallet must process to complete the payment.
+      taler_pay_uri: string;
 
-      // Expected deposit fee of the coin.
-      deposit_fee: Amount;
+      // 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;
 
+      // FIXME: why do we NOT return the contract terms here?
     }
 
-
-.. http:get:: /track/transaction
-
-  Provide the wire transfer identifier associated with an (existing) deposit 
operation.
-
-  **Request:**
-
-  :query id: ID of the transaction we want to trace (an integer)
-
-  **Response:**
-
-  :status 200 OK:
-    The deposit has been executed by the exchange and we have a wire transfer 
identifier.
-    The response body is a JSON array of `TransactionWireTransfer` objects.
-  :status 202 Accepted:
-    The deposit request has been accepted for processing, but was not yet
-    executed.  Hence the exchange does not yet have a wire transfer identifier.
-    The merchant should come back later and ask again.
-    The response body is a `TrackTransactionAcceptedResponse 
<TrackTransactionAcceptedResponse>`.  Note that
-    the similarity to the response given by the exchange for a /track/order
-    is completely intended.
-  :status 404 Not Found: The transaction is unknown to the backend.
-  :status 424 Failed Dependency:
-    The exchange previously claimed that a deposit was not included in a wire
-    transfer, and now claims that it is.  This means that the exchange is
-    dishonest.  The response contains the cryptographic proof that the exchange
-    is misbehaving in the form of a `TransactionConflictProof`.
-
-  **Details:**
-
   .. ts:def:: TransactionWireTransfer
 
     interface TransactionWireTransfer {
@@ -467,19 +460,6 @@ Tracking Wire Transfers
       amount: Amount;
     }
 
-  .. ts:def:: CoinWireTransfer
-
-    interface CoinWireTransfer {
-      // public key of the coin that was deposited
-      coin_pub: EddsaPublicKey;
-
-      // Amount the coin was worth (including deposit fee)
-      amount_with_fee: Amount;
-
-      // Deposit fee retained by the exchange for the coin
-      deposit_fee: Amount;
-    }
-
   .. ts:def:: TransactionConflictProof
 
     interface TransactionConflictProof {
@@ -507,843 +487,1033 @@ Tracking Wire Transfers
     }
 
 
--------------------
-Transaction history
--------------------
+.. http:get:: /public/orders/$ORDER_ID/
 
-.. http:get:: /history
+  Query the payment status of an order. This endpoint is for the wallet.
+  When the wallet goes to this URL and it is unpaid,
+  they will be prompted for payment.
 
-  Returns transactions up to some point in the past
+  // FIXME: note that this combines the previous APIs
+  // to check-payment and to obtain refunds.
 
   **Request**
 
-  :query date: time threshold, see ``delta`` for its interpretation.
-  :query start: row number threshold, see ``delta`` for its interpretation.  
Defaults to ``UINT64_MAX``, namely the biggest row id possible in the database.
-  :query delta: takes value of the form ``N (-N)``, so that at most ``N`` 
values strictly younger (older) than ``start`` and ``date`` are returned.  
Defaults to ``-20``.
-  :query ordering: takes value ``"descending"`` or ``"ascending"`` according 
to the results wanted from younger to older or vice versa.  Defaults to 
``"descending"``.
+  :query h_contract: hash of the order's contract terms (this is used to 
authenticate the wallet/customer in case $ORDER_ID is guessable). *Mandatory!*
+  :query session_id: *Optional*. Session ID that the payment must be bound to. 
 If not specified, the payment is not session-bound.
+  :query timeout_ms: *Optional.*  If specified, the merchant backend will
+    wait up to ``timeout_ms`` milliseconds for completion of the payment before
+    sending the HTTP response.  A client must never rely on this behavior, as 
the
+    merchant backend may return a response immediately.
+  :query refund=AMOUNT: *Optional*. Indicates that we are polling for a refund 
above the given AMOUNT. Only useful in combination with timeout.
 
   **Response**
 
   :status 200 OK:
-    The response is a JSON ``array`` of  `TransactionHistory`.  The array is
-    sorted such that entry ``i`` is younger than entry ``i+1``.
-
-  .. ts:def:: TransactionHistory
+    The response is a `PublicPayStatusResponse`, with ``paid`` true.
+    FIXME: what about refunded?
+  :status 402 Payment required:
+    The response is a `PublicPayStatusResponse`, with ``paid`` false.
+    FIXME: what about refunded?
+  :status 403 Forbidden:
+    The ``h_contract`` does not match the order.
+  :status 404 Not found:
+    The merchant backend is unaware of the order.
 
-    interface TransactionHistory {
-      // The serial number this entry has in the merchant's DB.
-      row_id: number;
+  .. ts:def:: PublicPayStatusResponse
 
-      // order ID of the transaction related to this entry.
-      order_id: string;
+    interface PublicPayStatusResponse {
+      // Has the payment for this order (ever) been completed?
+      paid: boolean;
 
-      // Transaction's timestamp
-      timestamp: Timestamp;
+      // Was the payment refunded (even partially, via refund or abort)?
+      refunded: boolean;
 
-      // Total amount associated to this transaction.
-      amount: Amount;
-    }
+      // Amount that was refunded in total.
+      refund_amount: Amount;
 
-.. _proposal:
+      // Refunds for this payment, empty array for none.
+      refunds: RefundDetail[];
 
+      // URI that the wallet must process to complete the payment.
+      taler_pay_uri: string;
 
--------------------------
-Dynamic Merchant Instance
--------------------------
+      // 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;
 
-.. note::
+    }
 
-    The endpoints to dynamically manage merchant instances has not been
-    implemented yet. The bug id for this refernce is 5349.
 
-.. http:get:: /instances
+.. http:delete:: /orders/$ORDER_ID
 
-  This is used to return the list of all the merchant instances
+  Delete information about an order.  Fails if the order was paid in the
+  last 10 years (or whatever TAX_RECORD_EXPIRATION is set to) or was
+  claimed but is unpaid and thus still a valid offer.
 
   **Response**
 
-  :status 200 OK:
-    The backend has successfully returned the list of instances stored. Returns
-    a `InstancesResponse`.
-
-  .. ts:def:: InstancesResponse
-
-    interface InstancesResponse {
-      // List of instances that are present in the backend (see `Instance`)
-      instances: Instance[];
-    }
-
-  The `Instance` object describes the instance registered with the backend. It 
has the following structure:
-
-  .. ts:def:: Instance
-
-    interface Instance {
-      // Merchant name corresponding to this instance.
-      name: string;
-
-      // The URL where the wallet will send coins.
-      payto: string;
+  :status 204 No content:
+    The backend has successfully deleted the order.
+  :status 404 Not found:
+    The backend does not know the instance or the order.
+  :status 409 Conflict:
+    The backend refuses to delete the order.
 
-      // Merchant instance of the response to create
-      instance: string;
 
-      //unique key for each merchant
-      merchant_id: string;
-    }
+--------------
+Giving Refunds
+--------------
 
 
-.. http:put:: /instances/
+.. http:post:: /orders/$ORDER_ID/refund
 
-  This request will be used to create a new merchant instance in the backend.
+  Increase the refund amount associated with a given order.  The user should be
+  redirected to the ``taler_refund_url`` to trigger refund processing in the 
wallet.
 
   **Request**
 
-  The request must be a `CreateInstanceRequest`.
+  The request body is a `RefundRequest` object.
 
   **Response**
 
   :status 200 OK:
-    The backend has successfully created the instance.  The response is a
-    `CreateInstanceResponse`.
-
-  .. ts:def:: CreateInstanceRequest
-
-    interface CreateInstanceRequest {
-      // The URL where the wallet has to send coins.
-      // payto://-URL of the merchant's bank account. Required.
-      payto: string;
+    The refund amount has been increased, the backend responds with a 
`MerchantRefundResponse`
+  :status 404 Not found:
+    The order is unknown to the merchant
+  :status 409 Conflict:
+    The refund amount exceeds the amount originally paid
 
-      // Merchant instance of the response to create
-      // This field is optional. If it is not specified
-      // then it will automatically be created.
-      instance?: string;
+  .. ts:def:: RefundRequest
 
-      // Merchant name corresponding to this instance.
-      name: string;
+    interface RefundRequest {
+      // Amount to be refunded
+      refund: Amount;
 
+      // Human-readable refund justification
+      reason: string;
     }
 
-  .. ts:def:: CreateInstanceResponse
+  .. ts:def:: MerchantRefundResponse
 
-    interface CreateInstanceResponse {
-      // Merchant instance of the response that was created
-      instance: string;
+    interface MerchantRefundResponse {
 
-      //unique key for each merchant
-      merchant_id: string;
+      // Hash of the contract terms of the contract that is being refunded.
+      // FIXME: why do we return this?
+      h_contract_terms: HashCode;
+
+      // URL (handled by the backend) that the wallet should access to
+      // trigger refund processing.
+      // FIXME: isn't this basically now always ``/public/orders/$ORDER_ID/``?
+      // If so, why return this?
+      taler_refund_url: string;
     }
 
 
-.. http:get:: /instances/<instance-id>
 
-  This is used to query a specific merchant instance.
+------------------------
+Tracking Wire Transfers
+------------------------
+
+.. http:post:: /check-transfer
+
+  Inform the backend over an incoming wire transfer. The backend should 
inquire about the details with the exchange and mark the respective orders as 
wired.
 
   **Request:**
 
-  :query instance_id: instance id that should be used for the instance
+   The request must provide `transfer information <TransferInformation>`.
 
-  **Response**
+  **Response:**
 
   :status 200 OK:
-    The backend has successfully returned the list of instances stored. Returns
-    a `QueryInstancesResponse`.
-
-  .. ts:def:: QueryInstancesResponse
+    The wire transfer is known to the exchange, details about it follow in the 
body.
+    The body of the response is a `TrackTransferResponse`.  Note that
+    the similarity to the response given by the exchange for a /track/transfer
+    is completely intended.
 
-    interface QueryInstancesResponse {
-      // The URL where the wallet has to send coins.
-      // payto://-URL of the merchant's bank account. Required.
-      payto: string;
+  :status 404 Not Found:
+    The wire transfer identifier is unknown to the exchange.
 
-      // Merchant instance of the response to create
-      // This field is optional. If it is not specified
-      // then it will automatically be created.
-      instance?: string;
+  :status 424 Failed Dependency: The exchange provided conflicting information 
about the transfer. Namely,
+    there is at least one deposit among the deposits aggregated by ``wtid`` 
that accounts for a coin whose
+    details don't match the details stored in merchant's database about the 
same keyed coin.
+    The response body contains the `TrackTransferConflictDetails`.
 
-      // Merchant name corresponding to this instance.
-      name: string;
+  .. ts:def:: TransferInformation
 
-    }
+    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: FIXME;
 
-.. http:post:: /instances/<instance-id>
+      // name of the wire transfer method used for the wire transfer
+      // FIXME: why not a payto URI?
+      wire_method;
 
-  This request will be used to update merchant instance in the backend.
+      // base URL of the exchange that made the wire transfer
+      exchange: string;
+    }
 
+  .. ts:def:: TrackTransferResponse
 
-  **Request**
+    interface TrackTransferResponse {
+      // Total amount transferred
+      total: Amount;
 
-  The request must be a `PostInstanceUpdateRequest`.
+      // Applicable wire fee that was charged
+      wire_fee: Amount;
 
-  **Response**
+      // public key of the merchant (identical for all deposits)
+      // FIXME: why return this?
+      merchant_pub: EddsaPublicKey;
 
-  :status 200 OK:
-    The backend has successfully updated the instance.  The response is a
-    `PostInstanceUpdateResponse`.
+      // hash of the wire details (identical for all deposits)
+      // FIXME: why return this? Isn't this the WTID!?
+      h_wire: HashCode;
 
-  .. ts:def:: PostInstanceUpdateRequest
+      // Time of the execution of the wire transfer by the exchange, according 
to the exchange
+      execution_time: Timestamp;
 
-    interface PostInstanceUpdateRequest {
-      // Merchant instance that is to be updaated. Required.
-      instance: string;
+      // details about the deposits
+      deposits_sums: TrackTransferDetail[];
 
-      // New URL where the wallet has to send coins.
-      // payto://-URL of the merchant's bank account. Required.
-      payto: string;
+      // signature from the exchange made with purpose
+      // ``TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT``
+      // FIXME: why return this?
+      exchange_sig: EddsaSignature;
 
-      // Merchant name coreesponding to this instance.
-      name: string;
+      // 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.
+      // FIXME: why return this?
+      exchange_pub: EddsaSignature;
+    }
 
+  .. ts:def:: TrackTransferDetail
+
+    interface TrackTransferDetail {
+      // 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;
     }
 
-  .. ts:def:: PostInstanceUpdateResponse
 
-    interface PostInstanceUpdateResponse {
-      // Merchant instance of the response that was updated
-      instance: string;
+  **Details:**
+
+  .. ts:def:: TrackTransferConflictDetails
+
+    interface TrackTransferConflictDetails {
+      // Numerical `error code <error-codes>`
+      code: number;
+
+      // Text describing the issue for humans.
+      hint: string;
+
+      // A /deposit response matching ``coin_pub`` showing that the
+      // exchange accepted ``coin_pub`` for ``amount_with_fee``.
+      exchange_deposit_proof: DepositSuccess;
+
+      // Offset in the ``exchange_transfer_proof`` 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.
+      exchange_transfer_proof: TrackTransferResponse;
+
+      // Public key of the coin for which we have conflicting information.
+      coin_pub: EddsaPublicKey;
+
+      // Merchant transaction in which ``coin_pub`` was involved for which
+      // we have conflicting information.
+      transaction_id: number;
+
+      // Expected value of the coin.
+      amount_with_fee: Amount;
+
+      // Expected deposit fee of the coin.
+      deposit_fee: Amount;
 
-      //unique key for each merchant
-      merchant_id: string;
     }
 
 
-.. http:delete:: /instances/<instance-id>
+.. http:get:: /transfers
 
-  This request will be used to delete merchant instance in the backend.
+  Obtain a list of all wire transfers the backend has checked.
 
   **Request:**
 
-  :query instance_id: instance id that should be used for the instance
+   :query filter: FIXME: should have a way to filter, maybe even long-poll?
 
-  **Response**
+  **Response:**
+
+  FIXME: to be specified.
+
+
+
+--------------------
+Giving Customer Tips
+--------------------
+
+
+.. http:post:: /create-reserve
+
+  Create a reserve for tipping.
+
+  **Request:**
+
+  The request body is a `ReserveCreateRequest` object.
+
+  **Response:**
 
   :status 200 OK:
-    The backend has successfully removed the instance.  The response is a
-    `PostInstanceRemoveResponse`.
+    The backend is waiting for the reserve to be established. The merchant
+    must now perform the wire transfer indicated in the 
`ReserveCreateConfirmation`.
+  :status 424 Failed Depencency:
+    We could not obtain /wire details from the specified exchange base URL.
 
-  .. ts:def:: PostInstanceRemoveResponse
+  .. ts:def:: ReserveCreateRequest
+
+    interface ReserveCreateRequest {
+      // Amount that the merchant promises to put into the reserve
+      initial_amount: Amount;
+
+      // Exchange the merchant intends to use for tipping
+      exchange_base_url: string;
 
-    interface PostInstanceRemoveResponse {
-      deleted: true;
     }
 
+  .. ts:def:: ReserveCreateConfirmation
 
-------------------
-The Contract Terms
-------------------
+    interface ReserveCreateConfirmation {
+      // Public key identifying the reserve
+      reserve_pub: EddsaPublicKey;
 
-The contract terms must have the following structure:
+      // Wire account of the exchange where to transfer the funds
+      payto_url: string;
 
-  .. ts:def:: ContractTerms
+    }
 
-    interface ContractTerms {
-      // Human-readable description of the whole purchase
-      summary: string;
+.. http:get:: /reserves
 
-      // Map from IETF BCP 47 language tags to localized summaries
-      summary_i18n?: { [lang_tag: string]: string };
+   Obtain list of reserves that have been created for tipping.
 
-      // 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;
+   **Request:**
 
-      // Total price for the transaction.
-      // The exchange will subtract deposit fees from that amount
-      // before transferring it to the merchant.
+   :query after: *Optional*.  Only return reserves created after the given 
timestamp [FIXME: unit?]
+
+   **Response:**
+
+  :status 200 OK:
+    Returns a list of known tipping reserves.
+    The body is a `TippingReserveStatus`.
+
+  .. ts:def:: TippingReserveStatus
+
+    interface TippingReserveStatus {
+
+      // Array of all known reserves (possibly empty!)
+      reserves: ReserveStatusEntry[];
+
+    }
+
+  .. ts:def:: 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;
+
+    }
+
+
+.. http:get:: /reserves/$RESERVE_PUB
+
+   Obtain information about a specific reserve that have been created for 
tipping.
+
+   **Request:**
+
+   :query tips: *Optional*. If set to "yes", returns also information about 
all of the tips created
+
+   **Response:**
+
+  :status 200 OK:
+    Returns the `ReserveDetail`.
+  :status 404 Not found:
+    The tipping reserve is not known.
+  :status 424 Failed Dependency:
+    We are having trouble with the request because of a problem with the 
exchange.
+    Likely returned with an "exchange_code" in addition to a "code" and
+    an "exchange_http_status" in addition to our own HTTP status. Also usually
+    includes the full exchange reply to our request under "exchange_reply".
+    This is only returned if there was actual trouble with the exchange, not
+    if the exchange merely did not respond yet or if it responded that the
+    reserve was not yet filled.
+
+  .. ts:def:: ReserveDetail
+
+    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[];
+
+    }
+
+  .. ts:def:: TipStatusEntry
+
+    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;
+
+    }
+
+
+.. http:post:: /reserves/$RESERVE_PUB/authorize-tip
+
+  Authorize creation of a tip from the given reserve.
+
+  **Request:**
+
+  The request body is a `TipCreateRequest` object.
+
+  **Response**
+
+  :status 200 OK:
+    A tip has been created. The backend responds with a `TipCreateConfirmation`
+  :status 404 Not Found:
+    The instance or the reserve is unknown to the backend.
+  :status 412 Precondition Failed:
+    The tip amount requested exceeds the available reserve balance for tipping.
+
+  .. ts:def:: TipCreateRequest
+
+    interface TipCreateRequest {
+      // Amount that the customer should be tipped
       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;
+      // Justification for giving the tip
+      justification: string;
 
-      // Maximum total deposit fee accepted by the merchant for this contract
-      max_fee: Amount;
+      // URL that the user should be directed to after tipping,
+      // will be included in the tip_token.
+      next_url: string;
+    }
 
-      // 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;
+  .. ts:def:: TipCreateConfirmation
 
-      // 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;
+    interface TipCreateConfirmation {
+      // Unique tip identifier for the tip that was created.
+      tip_id: HashCode;
 
-      // List of products that are part of the purchase (see `Product`).
-      products: Product[];
+      // Token that will be handed to the wallet,
+      // contains all relevant information to accept
+      // a tip.
+      tip_token: string;
 
-      // Time when this contract was generated
-      timestamp: Timestamp;
+      // URL that will directly trigger processing
+      // the tip when the browser is redirected to it
+      tip_redirect_url: string;
 
-      // After this deadline has passed, no refunds will be accepted.
-      refund_deadline: Timestamp;
+    }
 
-      // After this deadline, the merchant won't accept payments for the 
contact
-      pay_deadline: Timestamp;
 
-      // Transfer deadline for the exchange.  Must be in the
-      // deposit permissions of coins used to pay for this order.
-      wire_transfer_deadline: Timestamp;
+.. http:delete:: /reserves/$RESERVE_PUB
 
-      // 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;
+  Delete information about a reserve.  Fails if the reserve still has
+  committed to tips that were not yet picked up and that have not yet
+  expired.
 
-      // Base URL of the (public!) merchant backend API.
-      // Must be an absolute URL that ends with a slash.
-      merchant_base_url: string;
+  **Response**
 
-      // More info about the merchant, see below
-      merchant: Merchant;
+  :status 204 No content:
+    The backend has successfully deleted the reserve.
+  :status 404 Not found:
+    The backend does not know the instance or the reserve.
+  :status 409 Conflict:
+    The backend refuses to delete the reserve (committed tips).
 
-      // 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[];
+.. http:get:: /tips/$TIP_ID
 
-      // Exchanges that the merchant accepts even if it does not accept any 
auditors that audit them.
-      exchanges: Exchange[];
+  Obtain information about a particular tip.
 
-      // Map from labels to locations
-      locations: { [label: string]: [location: Location], ... };
+   **Request:**
 
-      // Nonce generated by the wallet and echoed by the merchant
-      // in this field when the proposal is generated.
-      nonce: string;
+   :query pickups: if set to "yes", returns also information about all of the 
pickups
 
-      // 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;
+  **Response**
 
-      // 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;
+  :status 200 OK:
+    The tip is known. The backend responds with a `TipDetails` message
+  :status 404 Not Found:
+    The tip is unknown to the backend.
+
+  .. ts:def:: TipDetails
+
+    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: Timestamp;
+
+      // 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[];
     }
 
-  The wallet must select a exchange that either the merchant accepts directly 
by
-  listing it in the exchanges array, or for which the merchant accepts an 
auditor
-  that audits that exchange by listing it in the auditors array.
+  .. ts:def:: PickupDetail
 
-  The `Product` object describes the product being purchased from the 
merchant. It has the following structure:
+    interface PickupDetail {
 
-  .. ts:def:: Product
+      // Unique identifier for the pickup operation.
+      pickup_id: HashCode;
 
-    interface Product {
-      // Human-readable product description.
-      description: string;
+      // Number of planchets involved.
+      num_planchets: integer;
 
-      // Map from IETF BCP 47 language tags to localized descriptions
-      description_i18n?: { [lang_tag: string]: string };
+      // Total amount requested for this pickup_id.
+      requested_amount: Amount;
 
-      // The quantity of the product to deliver to the customer (optional, if 
applicable)
-      quantity?: string;
+      // Total amount processed by the exchange for this pickup.
+      exchange_amount: Amount;
 
-      // The price of the product; this is the total price for the amount 
specified by 'quantity'
-      price: Amount;
+    }
+
+
+.. http:post:: /public/tips/$TIP_ID/pickup
+
+  Handle request from wallet to pick up a tip.
+
+  **Request**
+
+  The request body is a `TipPickupRequest` object.
+
+  **Response**
 
-      // merchant-internal identifier for the product
-      product_id?: string;
+  :status 200 OK:
+    A tip is being returned. The backend responds with a `TipResponse`
+  :status 401 Unauthorized:
+    The tip amount requested exceeds the tip.
+  :status 404 Not Found:
+    The tip identifier is unknown.
+  :status 409 Conflict:
+    Some of the denomination key hashes of the request do not match those 
currently available from the exchange (hence there is a conflict between what 
the wallet requests and what the merchant believes the exchange can provide).
 
-      // An optional base64-encoded product image
-      image?: ImageDataUrl;
+  .. ts:def:: TipPickupRequest
 
-      // a list of objects indicating a 'taxname' and its amount. Again, 
italics denotes the object field's name.
-      taxes?: any[];
+    interface TipPickupRequest {
 
-      // time indicating when this product should be delivered
-      delivery_date: Timestamp;
+      // Identifier of the tip.
+      tip_id: HashCode;
 
-      // where to deliver this product. This may be an URL for online delivery
-      // (i.e. 'http://example.com/download' or 'mailto:address@hidden'),
-      // or a location label defined inside the proposition's 'locations'.
-      // The presence of a colon (':') indicates the use of an URL.
-      delivery_location: string;
+      // List of planches the wallet wants to use for the tip
+      planchets: PlanchetDetail[];
     }
 
-  .. ts:def:: Merchant
+  .. ts:def:: PlanchetDetail
 
-    interface Merchant {
-      // label for a location with the business address of the merchant
-      address: string;
+    interface PlanchetDetail {
+      // Hash of the denomination's public key (hashed to reduce
+      // bandwidth consumption)
+      denom_pub_hash: HashCode;
 
-      // the merchant's legal name of business
-      name: string;
+      // coin's blinded public key
+      coin_ev: CoinEnvelope;
 
-      // 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: string;
     }
 
+  .. ts:def:: TipResponse
 
-  .. ts:def:: Location
+    interface TipResponse {
 
-    interface Location {
-      country?: string;
-      city?: string;
-      state?: string;
-      region?: string;
-      province?: string;
-      zip_code?: string;
-      street?: string;
-      street_number?: string;
+      // Blind RSA signatures over the planchets.
+      // The order of the signatures matches the planchets list.
+      blind_sigs: BlindSignature[];
     }
 
-  .. ts:def:: Auditor
-
-    interface Auditor {
-      // official name
-      name: string;
-
-      // Auditor's public key
-      auditor_pub: EddsaPublicKey;
+    interface BlindSignature {
 
-      // Base URL of the auditor
-      url: string;
+      // The (blind) RSA signature. Still needs to be unblinded.
+      blind_sig: RsaSignature;
     }
 
-  .. ts:def:: Exchange
 
-    interface Exchange {
-      // the exchange's base URL
-      url: string;
 
-      // master public key of the exchange
-      master_pub: EddsaPublicKey;
-    }
 
 
--------------------
-Customer-facing API
--------------------
+-------------------------
+Dynamic Merchant Instance
+-------------------------
 
-The ``/public/*`` endpoints are publicly exposed on the internet and accessed
-both by the user's browser and their wallet.
+.. note::
 
+    The endpoints to dynamically manage merchant instances has not been
+    implemented yet. The bug id for this reference is #5349.
 
-.. http:get:: /public/config
+.. http:get:: /instances
 
-  Return the protocol version and currency supported by this merchant backend.
+  This is used to return the list of all the merchant instances
 
-  **Response:**
+  **Response**
 
   :status 200 OK:
-    The exchange accepted all of the coins. The body is a `VersionResponse`.
-
-  .. ts:def:: VersionResponse
-
-    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;
+    The backend has successfully returned the list of instances stored. Returns
+    a `InstancesResponse`.
 
-      // Currency supported by this backend.
-      currency: string;
+  .. ts:def:: InstancesResponse
 
-      // optional array with information about the instances running at this 
backend
-      instances: InstanceInformation[];
+    interface InstancesResponse {
+      // List of instances that are present in the backend (see `Instance`)
+      instances: Instance[];
     }
 
-  .. ts:def:: InstanceInformation
+  The `Instance` object describes the instance registered with the backend. It 
has the following structure:
 
-    interface InstanceInformation {
+  .. ts:def:: Instance
 
-      // Human-readable legal business name served by this instance
+    interface Instance {
+      // Merchant name corresponding to this instance.
       name: string;
 
-      // Base URL of the instance. Can be of the form "/PizzaShop/" or
-      // a fully qualified URL (i.e. "https://backend.example.com/PizzaShop/";).
-      instance_baseurl: 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[];
+      // The URL where the wallet will send coins.
+      payto: string;
 
-      // Base URL of the exchange this instance uses for tipping.
-      // Optional, only present if the instance supports tipping.
-      tipping_exchange_baseurl?: string;
+      // Merchant instance of the response to create
+      instance: string;
 
+      //unique key for each merchant
+      merchant_id: string;
     }
 
 
-.. http:post:: /public/pay
+.. http:put:: /instances/$INSTANCE
 
-  Pay for a proposal by giving a deposit permission for coins.  Typically used 
by
-  the customer's wallet.  Can also be used in ``abort-refund`` mode to refund 
coins
-  that were already deposited as part of a failed payment.
+  This request will be used to create a new merchant instance in the backend.
 
-  **Request:**
+  **Request**
 
-  The request must be a `pay request <PayRequest>`.
+  The request must be a `CreateInstanceRequest`.
 
-  **Response:**
+  **Response**
 
   :status 200 OK:
-    The exchange accepted all of the coins. The body is a `PaymentResponse` if
-    the request used the mode "pay", or a `MerchantRefundResponse` if the
-    request used was the mode "abort-refund".
-    The ``frontend`` should now fullfill the contract.
-  :status 400 Bad request:
-    Either the client request is malformed or some specific processing error
-    happened that may be the fault of the client as detailed in the JSON body
-    of the response.
-  :status 401 Unauthorized:
-    One of the coin signatures was not valid.
-  :status 403 Forbidden:
-    The exchange rejected the payment because a coin was already spent before.
-    The response will include the 'coin_pub' for which the payment failed,
-    in addition to the response from the exchange to the ``/deposit`` request.
-  :status 404 Not found:
-    The merchant backend could not find the proposal or the instance
-    and thus cannot process the payment.
-  :status 412 Precondition Failed:
-    The given exchange is not acceptable for this merchant, as it is not in the
-    list of accepted exchanges and not audited by an approved auditor.
-  :status 424 Failed Dependency:
-    The merchant's interaction with the exchange failed in some way.
-    The client might want to try later again.
-    This includes failures like the denomination key of a coin not being
-    known to the exchange as far as the merchant can tell.
+    The backend has successfully created the instance.  The response is a
+    `CreateInstanceResponse`.
 
-  The backend will return verbatim the error codes received from the exchange's
-  :ref:`deposit <deposit>` API.  If the wallet made a mistake, like by
-  double-spending for example, the frontend should pass the reply verbatim to
-  the browser/wallet. This should be the expected case, as the ``frontend``
-  cannot really make mistakes; the only reasonable exception is if the
-  ``backend`` is unavailable, in which case the customer might appreciate some
-  reassurance that the merchant is working on getting his systems back online.
+  .. ts:def:: CreateInstanceRequest
 
-  .. ts:def:: PaymentResponse
+    interface CreateInstanceRequest {
+      // The URL where the wallet has to send coins.
+      // payto://-URL of the merchant's bank account. Required.
+      // FIXME: need an array, and to distinguish between
+      // supported and active (see taler.conf options on accounts!)
+      payto: string;
 
-    interface PaymentResponse {
-      // Signature on `TALER_PaymentResponsePS` with the public
-      // key of the merchant instance.
-      sig: EddsaSignature;
+      // Merchant instance of the response to create
+      // This field is optional. If it is not specified
+      // then it will automatically be created.
+      // FIXME: I do not understand this argument. -CG
+      instance?: string;
+
+      // Merchant name corresponding to this instance.
+      name: string;
 
-      // Contract terms hash being signed over.
-      h_contract_terms: HashCode;
     }
 
-  .. ts:def:: PayRequest
+  .. ts:def:: CreateInstanceResponse
 
-    interface PayRequest {
-      coins: CoinPaySig[];
+    interface CreateInstanceResponse {
+      // Merchant instance of the response that was created
+      // FIXME: I do not understand this value, isn't it implied?
+      instance: string;
 
-      // The merchant public key, used to uniquely
-      // identify the merchant instance.
-      merchant_pub: string;
+      //unique key for each merchant
+      // FIXME: I do not understand this value.
+      merchant_id: string;
+    }
 
-      // Order ID that's being payed for.
-      order_id: string;
 
-      // Mode for /pay ("pay" or "abort-refund")
-      mode: "pay" | "abort-refund";
-    }
+.. http:get:: /instances/<instance-id>
 
-  .. ts:def:: CoinPaySig
+  This is used to query a specific merchant instance.
 
-    export interface CoinPaySig {
-      // Signature by the coin.
-      coin_sig: string;
+  **Request:**
 
-      // Public key of the coin being spend.
-      coin_pub: string;
+  :query instance_id: instance id that should be used for the instance
 
-      // Signature made by the denomination public key.
-      ub_sig: string;
+  **Response**
 
-      // The denomination public key associated with this coin.
-      denom_pub: string;
+  :status 200 OK:
+    The backend has successfully returned the list of instances stored. Returns
+    a `QueryInstancesResponse`.
 
-      // The amount that is subtracted from this coin with this payment.
-      contribution: Amount;
+  .. ts:def:: QueryInstancesResponse
 
-      // URL of the exchange this coin was withdrawn from.
-      exchange_url: string;
-    }
+    interface QueryInstancesResponse {
+      // The URL where the wallet has to send coins.
+      // payto://-URL of the merchant's bank account. Required.
+      payto: string;
 
+      // Merchant instance of the response to create
+      // This field is optional. If it is not specified
+      // then it will automatically be created.
+      instance?: string;
 
-.. http:get:: /public/pay
+      // Merchant name corresponding to this instance.
+      name: string;
 
-  Query the payment status of an order.
+      // Public key of the merchant/instance, in Crockford Base32 encoding.
+      merchant_pub: EddsaPublicKey;
 
-  **Request**
+      // 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[];
 
-  :query hc: hash of the order's contract terms
-  :query long_poll_ms: *Optional.*  If specified, the merchant backend will
-    wait up to ``long_poll_ms`` milliseconds for completion of the payment 
before
-    sending the HTTP response.  A client must never rely on this behavior, as 
the
-    merchant backend may return a response immediately.
+    }
 
-  **Response**
 
-  :status 200 OK:
-    The response is a `PublicPayStatusResponse`.
+.. http:post:: /instances/<instance-id>
 
-  .. ts:def:: PublicPayStatusResponse
+  This request will be used to update merchant instance in the backend.
 
-    interface PublicPayStatusResponse {
-      // Has the payment for this order been completed?
-      paid: boolean;
 
-      // Refunds for this payment, if any.
-      refunds: RefundInfo[];
-    }
+  **Request**
+
+  The request must be a `PostInstanceUpdateRequest`.
 
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully updated the instance.  The response is a
+    `PostInstanceUpdateResponse`.
 
-  .. ts:def:: RefundInfo
+  .. ts:def:: PostInstanceUpdateRequest
 
-    interface RefundInfo {
+    interface PostInstanceUpdateRequest {
+      // Merchant instance that is to be updaated. Required.
+      instance: string;
 
-      // Coin from which the refund is going to be taken
-      coin_pub: EddsaPublicKey;
+      // New URL where the wallet has to send coins.
+      // payto://-URL of the merchant's bank account. Required.
+      payto: string;
 
-      // Refund amount taken from coin_pub
-      refund_amount: Amount;
+      // Merchant name coreesponding to this instance.
+      name: string;
 
-      // Refund fee
-      refund_fee: Amount;
+    }
 
-      // Identificator of the refund
-      rtransaction_id: number;
+  .. ts:def:: PostInstanceUpdateResponse
 
-      // Merchant public key
-      merchant_pub: EddsaPublicKey
+    interface PostInstanceUpdateResponse {
+      // Merchant instance of the response that was updated
+      instance: string;
 
-      // Merchant signature of a TALER_RefundRequestPS object
-      merchant_sig: EddsaSignature;
+      //unique key for each merchant
+      merchant_id: string;
     }
 
 
-.. http:get:: /public/proposal
+.. http:delete:: /instances/<instance-id>
 
-  Retrieve and take ownership (via nonce) over a proposal.
+  This request will be used to delete merchant instance in the backend.
 
-  **Request**
+  **Request:**
 
-  :query order_id: the order id whose refund situation is being queried
-  :query nonce: the nonce for the proposal
+  :query instance_id: instance id that should be used for the instance
 
   **Response**
 
   :status 200 OK:
-    The backend has successfully retrieved the proposal.  It responds with a 
:ref:`proposal <proposal>`.
-
-  :status 403 Forbidden:
-    The frontend used the same order ID with different content in the order.
-
+    The backend has successfully removed the instance.  The response is a
+    `PostInstanceRemoveResponse`.
 
-.. http:get:: /public/[$INSTANCE]/$ORDER/refund
+  .. ts:def:: PostInstanceRemoveResponse
 
-  Obtain a refund issued by the merchant.
+    interface PostInstanceRemoveResponse {
+      deleted: true;
+    }
 
-  **Response:**
 
-  :status 200 OK:
-    The merchant processed the approved refund. The body is a `RefundResponse`.
-    Note that a successful response from the merchant does not imply that the
-    exchange successfully processed the refund. Clients must inspect the
-    body to check which coins were successfully refunded. It is possible for
-    only a subset of the refund request to have been processed successfully.
-    Re-issuing the request will cause the merchant to re-try such unsuccessful
-    sub-requests.
-
-  .. ts:def:: RefundResponse
-
-    interface RefundResponse {
-      // hash of the contract terms
-      h_contract_terms: HashCode;
+------------------
+The Contract Terms
+------------------
 
-      // merchant's public key
-      merchant_pub: EddsaPublicKey;
+The contract terms must have the following structure:
 
-      // array with information about the refunds obtained
-      refunds: RefundDetail[];
-    }
+  .. ts:def:: ContractTerms
 
-  .. ts:def:: RefundDetail
+    interface ContractTerms {
+      // Human-readable description of the whole purchase
+      summary: string;
 
-    interface RefundDetail {
+      // Map from IETF BCP 47 language tags to localized summaries
+      summary_i18n?: { [lang_tag: string]: string };
 
-      // public key of the coin to be refunded
-      coin_pub: EddsaPublicKey;
+      // 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;
 
-      // Amount approved for refund for this coin
-      refund_amount: Amount;
+      // Total price for the transaction.
+      // The exchange will subtract deposit fees from that amount
+      // before transferring it to the merchant.
+      amount: Amount;
 
-      // Refund fee the exchange will charge for the refund
-      refund_fee: 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;
 
-      // HTTP status from the exchange. 200 if successful.
-      exchange_http_status: integer;
+      // Maximum total deposit fee accepted by the merchant for this contract
+      max_fee: Amount;
 
-      // Refund transaction ID.
-      rtransaction_id: integer;
+      // 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;
 
-      // Taler error code from the exchange. Only given if the
-      // exchange_http_status is not 200.
-      exchange_code?: integer;
+      // 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;
 
-      // Full exchange response. Only given if the
-      // exchange_http_status is not 200 and the exchange
-      // did return JSON.
-      exchange_reply?: integer;
+      // List of products that are part of the purchase (see `Product`).
+      products: Product[];
 
-      // Public key of the exchange used for the exchange_sig.
-      // Only given if the exchange_http_status is 200.
-      exchange_pub?: EddsaPublicKey;
+      // Time when this contract was generated
+      timestamp: Timestamp;
 
-      // Signature the exchange confirming the refund.
-      // Only given if the exchange_http_status is 200.
-      exchange_sig?: EddsaSignature;
+      // After this deadline has passed, no refunds will be accepted.
+      refund_deadline: Timestamp;
 
-    }
+      // After this deadline, the merchant won't accept payments for the 
contact
+      pay_deadline: Timestamp;
 
-  :status 404 Not found:
-    The merchant is unaware of having granted a refund, or even of
-    the order specified.
+      // Transfer deadline for the exchange.  Must be in the
+      // deposit permissions of coins used to pay for this order.
+      wire_transfer_deadline: Timestamp;
 
+      // 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;
 
-.. http:post:: /public/tip-pickup
+      // Base URL of the (public!) merchant backend API.
+      // Must be an absolute URL that ends with a slash.
+      merchant_base_url: string;
 
-  Handle request from wallet to pick up a tip.
+      // More info about the merchant, see below
+      merchant: Merchant;
 
-  **Request**
+      // The hash of the merchant instance's wire details.
+      h_wire: HashCode;
 
-  The request body is a `TipPickupRequest` object.
+      // 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;
 
-  **Response**
+      // Any exchanges audited by these auditors are accepted by the merchant.
+      auditors: Auditor[];
 
-  :status 200 OK:
-    A tip is being returned. The backend responds with a `TipResponse`
-  :status 401 Unauthorized:
-    The tip amount requested exceeds the tip.
-  :status 404 Not Found:
-    The tip identifier is unknown.
-  :status 409 Conflict:
-    Some of the denomination key hashes of the request do not match those 
currently available from the exchange (hence there is a conflict between what 
the wallet requests and what the merchant believes the exchange can provide).
+      // Exchanges that the merchant accepts even if it does not accept any 
auditors that audit them.
+      exchanges: Exchange[];
 
-  .. ts:def:: TipPickupRequest
+      // Map from labels to locations
+      locations: { [label: string]: [location: Location], ... };
 
-    interface TipPickupRequest {
+      // Nonce generated by the wallet and echoed by the merchant
+      // in this field when the proposal is generated.
+      nonce: string;
 
-      // Identifier of the tip.
-      tip_id: HashCode;
+      // 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;
 
-      // List of planches the wallet wants to use for the tip
-      planchets: PlanchetDetail[];
+      // 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;
     }
 
-  .. ts:def:: PlanchetDetail
+  The wallet must select a exchange that either the merchant accepts directly 
by
+  listing it in the exchanges array, or for which the merchant accepts an 
auditor
+  that audits that exchange by listing it in the auditors array.
 
-    interface PlanchetDetail {
-      // Hash of the denomination's public key (hashed to reduce
-      // bandwidth consumption)
-      denom_pub_hash: HashCode;
+  The `Product` object describes the product being purchased from the 
merchant. It has the following structure:
 
-      // coin's blinded public key
-      coin_ev: CoinEnvelope;
+  .. ts:def:: Product
 
-    }
+    interface Product {
+      // Human-readable product description.
+      description: string;
 
-  .. ts:def:: TipResponse
+      // Map from IETF BCP 47 language tags to localized descriptions
+      description_i18n?: { [lang_tag: string]: string };
 
-    interface TipResponse {
+      // The quantity of the product to deliver to the customer (optional, if 
applicable)
+      quantity?: string;
 
-      // Blind RSA signatures over the planchets.
-      // The order of the signatures matches the planchets list.
-      blind_sigs: BlindSignature[];
-    }
+      // The price of the product; this is the total price for the amount 
specified by 'quantity'
+      price: Amount;
 
-    interface BlindSignature {
+      // merchant-internal identifier for the product
+      product_id?: string;
 
-      // The (blind) RSA signature. Still needs to be unblinded.
-      blind_sig: RsaSignature;
-    }
+      // An optional base64-encoded product image
+      image?: ImageDataUrl;
 
+      // a list of objects indicating a 'taxname' and its amount. Again, 
italics denotes the object field's name.
+      taxes?: any[];
 
-.. http:get:: /public/poll-payment
+      // time indicating when this product should be delivered
+      delivery_date: Timestamp;
 
-  Check the payment status of an order.
+      // where to deliver this product. This may be an URL for online delivery
+      // (i.e. 'http://example.com/download' or 'mailto:address@hidden'),
+      // or a location label defined inside the proposition's 'locations'.
+      // The presence of a colon (':') indicates the use of an URL.
+      delivery_location: string;
+    }
 
-  **Request:**
+  .. ts:def:: Merchant
 
-  :query order_id: order id that should be used for the payment
-  :query h_contract: hash of the contract (used to authenticate customer)
-  :query session_id: *Optional*. Session ID that the payment must be bound to. 
 If not specified, the payment is not session-bound.
-  :query timeout: *Optional*. Timeout in seconds to wait for a payment if the 
answer would otherwise be negative (long polling).
-  :query refund=AMOUNT: *Optional*. Indicates that we are polling for a refund 
above the given AMOUNT. Only useful in combination with timeout.
+    interface Merchant {
+      // label for a location with the business address of the merchant
+      address: string;
 
-  **Response:**
+      // the merchant's legal name of business
+      name: string;
 
-  Returns a `PollPaymentResponse`, whose format can differ based on the status 
of the payment.
+      // 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: string;
+    }
 
-  .. ts:def:: PollPaymentResponse
 
-    type CheckPaymentResponse = PollPaymentPaidResponse | 
PollPaymentUnpaidResponse
+  .. ts:def:: Location
 
-  .. ts:def:: PollPaymentPaidResponse
+    interface Location {
+      country?: string;
+      city?: string;
+      state?: string;
+      region?: string;
+      province?: string;
+      zip_code?: string;
+      street?: string;
+      street_number?: string;
+    }
 
-    interface PollPaymentPaidResponse {
-      // value is always true;
-      paid: boolean;
+  .. ts:def:: Auditor
 
-      // Was the payment refunded (even partially)
-      refunded: boolean;
+    interface Auditor {
+      // official name
+      name: string;
 
-      // Amount that was refunded, only present if refunded is true.
-      refund_amount?: Amount;
+      // Auditor's public key
+      auditor_pub: EddsaPublicKey;
 
+      // Base URL of the auditor
+      url: string;
     }
 
-  .. ts:def:: PollPaymentUnpaidResponse
-
-    interface PollPaymentUnpaidResponse {
-      // value is always false;
-      paid: boolean;
-
-      // URI that the wallet must process to complete the payment.
-      taler_pay_uri: string;
+  .. ts:def:: Exchange
 
-      // 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;
+    interface Exchange {
+      // the exchange's base URL
+      url: string;
 
+      // master public key of the exchange
+      master_pub: EddsaPublicKey;
     }

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]