From c773474c481eac80b77555e3c0ea3375c5231e4a Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Thu, 13 Oct 2016 15:37:01 +0200 Subject: fix type name mismatch --- api-exchange.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-exchange.rst b/api-exchange.rst index c06d3862..e1439936 100644 --- a/api-exchange.rst +++ b/api-exchange.rst @@ -978,7 +978,7 @@ typically also view the balance.) .. _tsref-type-TrackTransferDetail: .. code-block:: tsref - interface WireDepositDetail { + interface TrackTransferDetail { // SHA-512 hash of the contact of the merchant with the customer. H_contract: HashCode; -- cgit v1.2.3 From f0cb91b02388972129fa701bb73624f213aa3589 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Thu, 13 Oct 2016 22:29:03 +0200 Subject: Integer->number --- api-exchange.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-exchange.rst b/api-exchange.rst index e1439936..9a8eb5ff 100644 --- a/api-exchange.rst +++ b/api-exchange.rst @@ -823,7 +823,7 @@ the API during normal operation. gamma_tp: EddsaPublicKey; // Specific `gamma` value chosen by the exchange. - gamma: Integer; + gamma: number; } -- cgit v1.2.3 From dd8eb50491d0fe1c5de88fa32975619f45b9938e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 15 Oct 2016 03:21:22 +0200 Subject: updating API documentation for error responses in transaction tracking --- api-merchant.rst | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index 749681d3..f5a83985 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -229,7 +229,33 @@ The following API are made available by the merchant's `backend` to the merchant is completely intended. :status 404 Not Found: - The wire transfer identifier is unknown to the exchange. + The wire transfer identifier is unknown to the exchange. + + :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`_. + + **Details:** + .. _tsref-type-TransactionConflictProof: + .. _TransactionConflictProof: + .. code-block:: tsref + + interface TransactionConflictProof { + // A claim by the exchange about the transfers associated + // with a given wire transfer; it does not list the + // transaction that `transaction_tracking_claim` says is part + // of the aggregate. This is + // a `/track/transfer` response from the exchange. + wtid_tracking_claim: TrackTransferResponse; + + // The current claim by the exchange that the given + // transaction is included in the above WTID. + // (A response from `/track/transaction`). + transaction_tracking_claim: TrackTransactionResponse; + + // Public key of the coin for which we got conflicting information. + coin_pub: CoinPublicKey; + + } .. http:get:: /track/transaction @@ -257,6 +283,9 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The transaction is unknown to the backend. + :status 409 Conflict: The exchange provided conflicting information about the transfer. + The response body contains the :ref:`TrackTransferConflictDetails`. + **Details:** @@ -290,6 +319,42 @@ The following API are made available by the merchant's `backend` to the merchant deposit_fee: Amount; } + .. _tsref-type-TrackTransferConflictDetails: + .. _TrackTransferConflictDetails: + .. code-block:: tsref + + interface TrackTransferConflictDetails { + // 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; + + } + .. http:get:: /history Returns transactions up to some point in the past @@ -311,7 +376,7 @@ The following API are made available by the merchant's `backend` to the merchant // Hashcode of the relevant contract h_contract: HashCode; - + // Exchange's base URL exchange: string; -- cgit v1.2.3 From a43b8e5f56b3f2cfa614265f26f4d345ffc087d8 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Sat, 15 Oct 2016 04:40:10 +0200 Subject: receiver token in /track/transfer --- api-merchant.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/api-merchant.rst b/api-merchant.rst index 8705069d..42fb830e 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -222,6 +222,7 @@ The following API are made available by the merchant's `backend` to the merchant :query wtid: raw wire transfer identifier identifying the wire transfer (a base32-encoded value) :query exchange: base URI of the exchange that made the wire transfer + :query receiver: identificative token of the merchant :ref:`instance ` which is being tracked. **Response:** -- cgit v1.2.3 From f761f3632785807fb6154e94dd6c5dee47b6a6a3 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Sat, 15 Oct 2016 22:00:36 +0200 Subject: fix link --- api-merchant.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index 42fb830e..dea931e4 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -239,8 +239,8 @@ The following API are made available by the merchant's `backend` to the merchant 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:** - .. _tsref-type-TransactionConflictProof: .. _TransactionConflictProof: + .. _tsref-type-TransactionConflictProof: .. code-block:: tsref interface TransactionConflictProof { @@ -288,7 +288,7 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The transaction is unknown to the backend. :status 409 Conflict: The exchange provided conflicting information about the transfer. - The response body contains the :ref:`TrackTransferConflictDetails`. + The response body contains the `TrackTransferConflictDetails`_. **Details:** -- cgit v1.2.3 From f0f8e4b873acf06cd7ac3dc5ef221bb3ab361fa1 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 18 Oct 2016 11:44:15 +0200 Subject: FIXME --- api-exchange.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-exchange.rst b/api-exchange.rst index 9a8eb5ff..15acf5ed 100644 --- a/api-exchange.rst +++ b/api-exchange.rst @@ -360,7 +360,7 @@ exchange. // `base32`_ encoding of `TALER_WithdrawRequestPS`_ with purpose TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW. This field appears only if `type` is "WITHDRAW". details?: string; - // Signature over the transaction `details`. + // Signature over the transaction `details` (FIXME: Which transaction, which details?). signature?: EddsaSignature; } -- cgit v1.2.3 From 5315da03acdef93934533497d781b47cc17134d9 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 18 Oct 2016 23:04:43 +0200 Subject: update specification to match current implementation --- api-common.rst | 4 ++-- api-exchange.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api-common.rst b/api-common.rst index 3bbc8722..d44e55ec 100644 --- a/api-common.rst +++ b/api-common.rst @@ -70,8 +70,8 @@ handle the error as if an internal error (500) had been returned. interface ErrorDetail { - // Numeric error code. See "taler_error_codes.h". - error_code: number; + // Numeric error code unique to the condition. See "taler_error_codes.h". + code: number; // Human-readable description of the error, i.e. "missing parameter", "commitment violation", ... // The other arguments are specific to the error value reported here. diff --git a/api-exchange.rst b/api-exchange.rst index 15acf5ed..d53056fb 100644 --- a/api-exchange.rst +++ b/api-exchange.rst @@ -392,7 +392,7 @@ exchange. not yet have completed and might be known to the exchange in the near future. In this case, the wallet should repeat the exact same request later again using exactly the same blinded coin. - :status 402 Payment Required: + :status 403 Forbidden: The balance of the reserve is not sufficient to withdraw a coin of the indicated denomination. The response is `WithdrawError`_ object. @@ -475,7 +475,7 @@ denomination. The operation succeeded, the exchange confirms that no double-spending took place. The response will include a `DepositSuccess`_ object. :status 401 Unauthorized: One of the signatures is invalid. - :status 403: + :status 403 Forbidden: The deposit operation has failed because the coin has insufficient residual value; the request should not be repeated again with this coin. In this case, the response is a `DepositDoubleSpendError`_. -- cgit v1.2.3 From 9cc3e04399ca7f223a61ebd515f4d8104be886e8 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Wed, 19 Oct 2016 12:37:22 +0200 Subject: still on #4251 --- api-merchant.rst | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index dea931e4..d89e0485 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -85,9 +85,14 @@ The Frontent HTTP API // a timestamp of this deposit permission. It equals just the contract's timestamp timestamp: Timestamp; - // same value held in the contract's `refund` field + // Deadline for the customer to be refunded for this purchase refund_deadline: Timestamp; + // Deadline for the customer to pay for this purchase. Note that is up to the frontend + // to make sure that this value matches the one the backend signed over when the contract + // was generated. + pay_deadline: Timestamp; + // the chosen exchange's base URL exchange: string; @@ -176,10 +181,10 @@ The following API are made available by the merchant's `backend` to the merchant **Request:** The `frontend` passes the :ref:`deposit permission ` - received from the wallet, and optionally adding a field named `pay_deadline`, + received from the wallet, and optionally adding a field named `wire_transfer_deadline`, indicating a deadline by which he would expect to receive the bank transfer - for this deal. Note that the `pay_deadline` must be after the `refund_deadline`. - The backend calculates the `pay_deadline` by adding the `wire_transfer_delay` + for this deal. Note that the `wire_transfer_deadline` must be after the `refund_deadline`. + The backend calculates the `wire_transfer_deadline` by adding the `wire_transfer_delay` value found in the configuration to the current time. **Response:** @@ -233,12 +238,13 @@ The following API are made available by the merchant's `backend` to the merchant is completely intended. :status 404 Not Found: - The wire transfer identifier is unknown to the exchange. + The wire transfer identifier is unknown to the exchange. :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`_. + 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:** - **Details:** .. _TransactionConflictProof: .. _tsref-type-TransactionConflictProof: .. code-block:: tsref -- cgit v1.2.3 From 835509f59bd11234b0181693396ad40b5ff8e5fc Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Wed, 19 Oct 2016 12:49:21 +0200 Subject: still on #4251 --- api-merchant.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api-merchant.rst b/api-merchant.rst index d89e0485..49d2d74a 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -90,7 +90,9 @@ The Frontent HTTP API // Deadline for the customer to pay for this purchase. Note that is up to the frontend // to make sure that this value matches the one the backend signed over when the contract - // was generated. + // was generated. The frontend should never verify if the payment is still on time, + // because when payments are replayed it is expxectable that this deadline is expired, + // and only the backend can detect if a payment is a reply or not. pay_deadline: Timestamp; // the chosen exchange's base URL -- cgit v1.2.3 From f46102c0bddc001769817046ae50e6e65b4769d1 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Fri, 21 Oct 2016 16:15:36 +0200 Subject: fix instance namespace --- operate-merchant.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operate-merchant.rst b/operate-merchant.rst index 418534be..a964b1d6 100644 --- a/operate-merchant.rst +++ b/operate-merchant.rst @@ -123,7 +123,7 @@ the chosen wireformat. In our demo, we have:: wireformat = test .. - [default-wireforma] + [merchant-instance-wireformat-default] test_response_file = ${TALER_CONFIG_HOME}/merchant/wire/test.json The file `test.json` obeys to the following specification -- cgit v1.2.3 From 0d417057eb1a20102dd3bd900278ddbc88df19fa Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Fri, 21 Oct 2016 17:30:12 +0200 Subject: still on instances namespace --- operate-merchant.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operate-merchant.rst b/operate-merchant.rst index a964b1d6..b5215955 100644 --- a/operate-merchant.rst +++ b/operate-merchant.rst @@ -177,7 +177,7 @@ instance `Tor` as follows:: .. - [Tor-wireformat] + [merchant-instance-wireformat-Tor] TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/tor.json Please note that :ref:`Taler messagging` is designed so that the merchant -- cgit v1.2.3 From a68e5da8188b2dd468d768395c458456d602f0f4 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Sat, 22 Oct 2016 18:04:13 +0200 Subject: #4749 --- api-merchant.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index 49d2d74a..967107ee 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -77,7 +77,7 @@ The Frontent HTTP API // The merchant instance which is going to receive the final wire transfer. // See `instances-lab`_ - receiver: string; + instance: string; // Signature of `TALER_ContractPS`_ merchant_sig: EddsaSignature; @@ -165,8 +165,8 @@ The following API are made available by the merchant's `backend` to the merchant * `H_wire` * `merchant_pub` - The frontend may or may not provide a `receiver` field in the proposition, depending on its logic. - The ``default`` instance will be used if no `receiver` field is found by the backend. + The frontend may or may not provide a `instance` field in the proposition, depending on its logic. + The ``default`` instance will be used if no `instance` field is found by the backend. **Response** @@ -229,7 +229,7 @@ The following API are made available by the merchant's `backend` to the merchant :query wtid: raw wire transfer identifier identifying the wire transfer (a base32-encoded value) :query exchange: base URI of the exchange that made the wire transfer - :query receiver: identificative token of the merchant :ref:`instance ` which is being tracked. + :query instance: identificative token of the merchant :ref:`instance ` which is being tracked. **Response:** @@ -276,7 +276,7 @@ The following API are made available by the merchant's `backend` to the merchant **Request:** :query id: ID of the transaction we want to trace (an integer) - :query receiver: identificative token for the merchant instance which is to be tracked (optional). See :ref:`instances-lab`. This information is needed because the request has to be signed by the merchant, thus we need to pick the instance's private key. + :query instance: identificative token for the merchant instance which is to be tracked (optional). See :ref:`instances-lab`. This information is needed because the request has to be signed by the merchant, thus we need to pick the instance's private key. **Response:** @@ -490,8 +490,8 @@ The `contract` must have the following structure: merchant: Merchant; // Which instance is participating in this contract. See the paragraph `Merchant Instances`. - // This field is optional, as the "default" instance is not forced to provide any `receiver` identificator. - receiver: string; + // This field is optional, as the "default" instance is not forced to provide any `instance` identificator. + instance: string; // The hash of the merchant instance's wire details. H_wire: HashCode; -- cgit v1.2.3 From 0308e3346eb6fdae5e5fba05164c372413e625fd Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Sat, 22 Oct 2016 19:52:44 +0200 Subject: fix unresolved link + installation chapter titles --- api-exchange.rst | 2 +- operate-exchange.rst | 6 ++++++ operate-merchant.rst | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/api-exchange.rst b/api-exchange.rst index d53056fb..b9d75dd1 100644 --- a/api-exchange.rst +++ b/api-exchange.rst @@ -549,7 +549,7 @@ denomination. // The string constant "DEPOSIT_OK" status: string; - // the EdDSA signature of `TALER_DepositConfirmation`_ using a current + // the EdDSA signature of `TALER_DepositConfirmationPS`_ using a current // `signing key of the exchange `_ affirming the successful // deposit and that the exchange will transfer the funds after the refund // deadline, or as soon as possible if the refund deadline is zero. diff --git a/operate-exchange.rst b/operate-exchange.rst index 64a8289e..fabb8083 100644 --- a/operate-exchange.rst +++ b/operate-exchange.rst @@ -167,6 +167,12 @@ Keys duration Both `signkeys` and `denom keys` have a :ref:`starting date `. The option `lookahead_provide`, under section `[exchange_keys]`, is such that only keys whose starting date is younger than `lookahead_provide` will be issued by the exchange. +++++++++++++ +Installation +++++++++++++ + +TBD + +++++ Other +++++ diff --git a/operate-merchant.rst b/operate-merchant.rst index b5215955..d5103115 100644 --- a/operate-merchant.rst +++ b/operate-merchant.rst @@ -183,3 +183,9 @@ instance `Tor` as follows:: Please note that :ref:`Taler messagging` is designed so that the merchant frontend can instruct the backend on which instance has to be used in the various operations. This information is optional, and if not given, the backend will act as the `default` instance. + +++++++++++++ +Installation +++++++++++++ + +TBD -- cgit v1.2.3 From 8f5d7e0f89183bc36d3c64046391eece6b1ee548 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Mon, 24 Oct 2016 17:39:20 +0200 Subject: fix link among types --- api-exchange.rst | 1 + api-merchant.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api-exchange.rst b/api-exchange.rst index b9d75dd1..1e828a4d 100644 --- a/api-exchange.rst +++ b/api-exchange.rst @@ -946,6 +946,7 @@ typically also view the balance.) The wire transfer identifier is unknown to the exchange. .. _TrackTransferResponse: + .. _tsref-type-TrackTransferResponse: .. code-block:: tsref interface TrackTransferResponse { diff --git a/api-merchant.rst b/api-merchant.rst index 967107ee..b44d52ca 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -235,7 +235,7 @@ The following API are made available by the merchant's `backend` to the merchant :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 :ref:`TrackTransactionResponse `. Note that + The body of the response is a :ref:`TrackTransferResponse `. Note that the similarity to the response given by the exchange for a /track/transfer is completely intended. -- cgit v1.2.3 From e1822eab7a8adb2318420b1a9daf289910a9278e Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Mon, 24 Oct 2016 17:42:27 +0200 Subject: fix comment --- api-merchant.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-merchant.rst b/api-merchant.rst index b44d52ca..d9488493 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -252,7 +252,7 @@ The following API are made available by the merchant's `backend` to the merchant .. code-block:: tsref interface TransactionConflictProof { - // A claim by the exchange about the transfers associated + // A claim by the exchange about the transactions associated // with a given wire transfer; it does not list the // transaction that `transaction_tracking_claim` says is part // of the aggregate. This is -- cgit v1.2.3 From fa87c12c0a8419b5a41e6b224d4d27f58681e460 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Mon, 24 Oct 2016 18:41:35 +0200 Subject: fix link --- api-merchant.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api-merchant.rst b/api-merchant.rst index d9488493..7e8ab25c 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -470,7 +470,7 @@ The `contract` must have the following structure: // 53-bit number chosen by the merchant to uniquely identify the contract. transaction_id: number; - // List of products that are part of the purchase (see `below) + // List of products that are part of the purchase (see `below `_) products: Product[]; // Time when this contract was generated @@ -510,6 +510,7 @@ The `contract` must have the following structure: The `product` object describes the product being purchased from the merchant. It has the following structure: + .. _Product: .. _tsref-type-Product: .. code-block:: tsref -- cgit v1.2.3 From cba780a60a6e63ef85ad10a6ffa6b74d37aaeb32 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 25 Oct 2016 11:07:19 +0200 Subject: fix link --- api-merchant.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-merchant.rst b/api-merchant.rst index 967107ee..18c6c4be 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -489,7 +489,7 @@ The `contract` must have the following structure: // More info about the merchant, see below merchant: Merchant; - // Which instance is participating in this contract. See the paragraph `Merchant Instances`. + // Which instance is participating in this contract. See `Merchant Instances `_. // This field is optional, as the "default" instance is not forced to provide any `instance` identificator. instance: string; -- cgit v1.2.3 From a6845fe1f13b3281c40d04864ecd958360bc7baa Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Thu, 27 Oct 2016 16:26:36 +0200 Subject: FIXME --- api-merchant.rst | 99 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index 1026c6b1..8cc2624f 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -242,33 +242,49 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The wire transfer identifier is unknown to the exchange. - :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 409 Conflict: The exchange provided conflicting information about the transfer. + The response body contains the `TrackTransferConflictDetails`_. + **Details:** - .. _TransactionConflictProof: - .. _tsref-type-TransactionConflictProof: + .. _tsref-type-TrackTransferConflictDetails: + .. _TrackTransferConflictDetails: .. code-block:: tsref - interface TransactionConflictProof { - // A claim by the exchange about the transactions associated - // with a given wire transfer; it does not list the - // transaction that `transaction_tracking_claim` says is part - // of the aggregate. This is - // a `/track/transfer` response from the exchange. - wtid_tracking_claim: TrackTransferResponse; + interface TrackTransferConflictDetails { + // Text describing the issue for humans. + hint: String; - // The current claim by the exchange that the given - // transaction is included in the above WTID. - // (A response from `/track/transaction`). - transaction_tracking_claim: TrackTransactionResponse; + // A /deposit response matching `coin_pub` showing that the + // exchange accepted `coin_pub` for `amount_with_fee`. + exchange_deposit_proof: DepositSuccess; // FIXME: define/link-to this object - // Public key of the coin for which we got conflicting information. - coin_pub: CoinPublicKey; + // 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; } + .. http:get:: /track/transaction Provide the wire transfer identifier associated with an (existing) deposit operation. @@ -295,9 +311,7 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The transaction is unknown to the backend. - :status 409 Conflict: The exchange provided conflicting information about the transfer. - The response body contains the `TrackTransferConflictDetails`_. - + :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`_. **Details:** @@ -331,42 +345,29 @@ The following API are made available by the merchant's `backend` to the merchant deposit_fee: Amount; } - .. _tsref-type-TrackTransferConflictDetails: - .. _TrackTransferConflictDetails: + .. _TransactionConflictProof: + .. _tsref-type-TransactionConflictProof: .. code-block:: tsref - interface TrackTransferConflictDetails { - // 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 TransactionConflictProof { + // A claim by the exchange about the transactions associated + // with a given wire transfer; it does not list the + // transaction that `transaction_tracking_claim` says is part + // of the aggregate. This is + // a `/track/transfer` response from the exchange. + wtid_tracking_claim: TrackTransferResponse; - // Expected value of the coin. - amount_with_fee: Amount; + // The current claim by the exchange that the given + // transaction is included in the above WTID. + // (A response from `/track/transaction`). + transaction_tracking_claim: TrackTransactionResponse; - // Expected deposit fee of the coin. - deposit_fee: Amount; + // Public key of the coin for which we got conflicting information. + coin_pub: CoinPublicKey; } + .. http:get:: /history Returns transactions up to some point in the past -- cgit v1.2.3 From dccf016e736e1a1f3fa004669c04c11bc8505cd0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 27 Oct 2016 19:54:43 +0200 Subject: update status codes to reflect actual current implementation --- api-merchant.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index 49d2d74a..b219e6c2 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -242,7 +242,7 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The wire transfer identifier is unknown to the exchange. - :status 409 Conflict: + :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:** @@ -295,7 +295,7 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The transaction is unknown to the backend. - :status 409 Conflict: The exchange provided conflicting information about the transfer. + :status 424 Failed Dependency: The exchange provided conflicting information about the transfer. The response body contains the `TrackTransferConflictDetails`_. -- cgit v1.2.3 From 4d249f029aba0179bfce197d23d66b0269b180d4 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 1 Nov 2016 15:06:24 +0100 Subject: moving paragraph --- api-merchant.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/api-merchant.rst b/api-merchant.rst index 2104080b..c0d5d447 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -242,8 +242,9 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The wire transfer identifier is unknown to the exchange. - :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`_. + :status 424 Failed Dependency: The exchange provided conflicting information about the transfer. + The response body contains the `TrackTransferConflictDetails`_. + **Details:** @@ -310,8 +311,8 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The transaction is unknown to the backend. - :status 424 Failed Dependency: The exchange provided conflicting information about the transfer. - The response body contains the `TrackTransferConflictDetails`_. + :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:** -- cgit v1.2.3 From ae2b92cbc36d690aed7a5371662322d0f7cce263 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 1 Nov 2016 15:23:27 +0100 Subject: more on tracks' conflicts --- api-merchant.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api-merchant.rst b/api-merchant.rst index c0d5d447..b137ffd2 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -242,7 +242,9 @@ The following API are made available by the merchant's `backend` to the merchant :status 404 Not Found: The wire transfer identifier is unknown to the exchange. - :status 424 Failed Dependency: The exchange provided conflicting information about the transfer. + :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`_. -- cgit v1.2.3 From 4e9ef310fbc9f39cc4ffb3c9079a117214448718 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Fri, 4 Nov 2016 14:31:18 +0100 Subject: adapting to #4755 --- api-merchant.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api-merchant.rst b/api-merchant.rst index c0d5d447..f088b443 100644 --- a/api-merchant.rst +++ b/api-merchant.rst @@ -253,6 +253,9 @@ The following API are made available by the merchant's `backend` to the merchant .. code-block:: tsref interface TrackTransferConflictDetails { + // Numerical error code + code: number; + // Text describing the issue for humans. hint: String; @@ -351,6 +354,12 @@ The following API are made available by the merchant's `backend` to the merchant .. code-block:: tsref interface TransactionConflictProof { + // Numerical error code + code: number; // FIXME Point to some error codes list + + // Human-readable error description + hint: string; + // A claim by the exchange about the transactions associated // with a given wire transfer; it does not list the // transaction that `transaction_tracking_claim` says is part -- cgit v1.2.3 From 82b1ba415bb735c9e9021d73b2fa1e4a08ac4d2b Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 8 Nov 2016 16:43:56 +0100 Subject: Still on #4645 --- dev-merchant.rst | 4 +-- example-essay-store.rst | 20 +++++------- integration-merchant.rst | 79 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 16 deletions(-) diff --git a/dev-merchant.rst b/dev-merchant.rst index cb834659..faa2a28c 100644 --- a/dev-merchant.rst +++ b/dev-merchant.rst @@ -29,13 +29,13 @@ Design TO REVIEW:: - The `frontend` is the existing shopping portal of the merchant. + The 'frontend' is the existing shopping portal of the merchant. The architecture tries to minimize the amount of modifications necessary to the `frontend` as well as the trust that needs to be placed into the `frontend` logic. Taler requires the frontend to facilitate two JSON-based interactions between the wallet and the `backend`, and one of those is trivial. - The `backend` is a standalone C application intended to implement all + The 'backend' is a standalone C application intended to implement all the cryptographic routines required to interact with the Taler wallet and a Taler exchange. diff --git a/example-essay-store.rst b/example-essay-store.rst index 2a240f86..ec22ff42 100644 --- a/example-essay-store.rst +++ b/example-essay-store.rst @@ -20,21 +20,17 @@ Example: Essay Store ================================== -To properly understand this example, the reader should be familiar with Taler's terminology; -in particular, definitions like `contract`, `fulfillment URL`, `offering URL`, and `deposit permission`, -are assumed to be known. Refer to :ref:`contract`, :ref:`payprot` and :ref:`deposit-par` in order to get -some general insight on terms and interactions between components. +This section shows how to set up a merchant :ref:`frontend `, and is +inspired by our demonstration shop running at `https://blog.demo.taler.net/`. -This section describes how the demonstrator essay store interacts with the Taler system. As for Taler's -terminology, the demonstrator essay store is an example of `frontend`. -This demonstrator's code is hosted at `git://taler.net/merchant-frontends/talerfrontends/blog/` and is -implemented in Python. +The code we are going to describe is available at +https://git.taler.net/merchant-frontends.git/tree/talerfrontends/blog +and is implemented in Python+Flask. -The essay store, available at https://blog.demo.taler.net, is such that its homepage -is a list of titles from buyable articles and each title links to an `offer URL`. -In particular, the offer URLs have the following format: +The desired effect is that the homepage has a list of buyable article, and once the +user clicks on one of them, they will either get the Taler :ref:`contract ` +or a credit card paywall if they have no Taler wallet installed. - `https://blog.demo.taler.net/essay/article_title` The offer URLs trigger the expected interaction with the wallet. In practical terms, the offer URL returns a HTML page that can either show a pay-form in case Taler is not installed diff --git a/integration-merchant.rst b/integration-merchant.rst index b07f1339..a119e87b 100644 --- a/integration-merchant.rst +++ b/integration-merchant.rst @@ -106,6 +106,8 @@ his wallet will not be able to replay the payment. Instead, his wallet will automatically redirect Bob to the offer URL and allow him to purchase the movie himself. +.. _offer: + --------------- Making an offer --------------- @@ -113,9 +115,11 @@ Making an offer When a user visits a offer URL, the merchant returns a page that can interact with the wallet either via JavaScript or by returning a "402 Payment Required". This page's main objective is to inform the wallet on where it should get the -contract. In case of JavaScript interaction, this is done by FIXME, whereas +contract. In case of JavaScript interaction, this is done by _FIXME_, whereas in case of "402 Payment Required", a `X-Taler-contract-url` HTTP header will -be set to the contract's location. (FIXME: is that right?). +be set to the contract's location. (_FIXME_: is that right?). + +.. _fulfillment: ------------------------------- Fulfillment interaction details @@ -151,3 +155,74 @@ By looking at `X-taler-contract-hash`, the wallet can face two situations: 2. This hashcode is unknown to the wallet, so the wallet can point the browser to `X-taler-offer-URL`, so the user will get the contract and decide to accept it or not. This happens when the user gets the fulfillment URL from someone else. FIXME: explain the JavaScript way + +-------------------- +Example: Essay Store +-------------------- + +This section is a high-level description of a merchant :ref:`frontend `, +and is inspired by our demonstration essay store running at `https://blog.demo.taler.net/`. +Basically, it tells how the frontend reacts to clients visiting `offer` and `fulfillment` +URLs. + +The website is implemented in Python+Flask, and is available at +https://git.taler.net/merchant-frontends.git/tree/talerfrontends/blog. + +The desired effect is that the homepage has a list of buyable articles, and once the +user clicks on one of them, they will either get the Taler :ref:`contract ` +or a credit card paywall if they have no Taler wallet installed. + +In particular, any buyable article on the homepage links to an `offer URL`: + +.. sourcecode:: html + + + ... +

How to write a frontend

+ ... + + +whence the offer URL design is as follows:: + + https:///essay/ + +`` is just a token that uniquely identifies the article within the shop. + +The server-side handler for the offer URL will return a special page to the client that +will either HTTP GET the contract from the frontend, or show the credit card paywall. +See `above `_ how this special page works. + +It is interesting to note that the fulfillment URL is just the offer URL plus +two additional parameters. It looks as follows:: + + https:///essay/?tid=×tamp= + +.. note:: + + Taler does not require that offer and fulfillment URL have this kind of relationship. + In fact, it is perfectly acceptable for the fulfillment URL to be hosted on a different + server under a different domain name. + +The fulfillment URL server-side handler implements the following logic: it checks the state +to see if `` has been payed, and if so, returns the article to the user. +If the user didn't pay, then it `executes` the contract by returning a special page to the +browser. The contract execution is the order to pay that the frontend gives to the wallet. + +Basically, the frontend points the wallet to the hashcode of the contract which is to be paid +and the wallet responds by giving coins to the frontend. Because the frontend doesn't perform +any cryptographic work by design, it forwards ``, `` and +`` to the frontend in order to get the contract's hashcode. + +See `above `_ for a detailed description of how the frontend triggers the +payment in the wallet. + +........ +Security +........ + +FIXME: + +* explain how the merchant prevents fake contracts reconstructions, AKA how it +trusts the parameters given in fulfillment URL. +* explain how the article shown is the original picked article, AKA how the wallet +cannot lie about article name at /pay-ing time. -- cgit v1.2.3 From 028c0629b5d2326f5b6cba5ba422bc5e3cd407a8 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Wed, 9 Nov 2016 10:50:54 +0100 Subject: #4169: state and security --- integration-merchant.rst | 56 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/integration-merchant.rst b/integration-merchant.rst index a119e87b..10a0c8f2 100644 --- a/integration-merchant.rst +++ b/integration-merchant.rst @@ -216,13 +216,53 @@ any cryptographic work by design, it forwards ``, ``_ for a detailed description of how the frontend triggers the payment in the wallet. -........ -Security -........ +.................. +State and security +.................. -FIXME: +The server-side state gets updated in two situations, (1) when an article is +"about" to be bought, which means when the user visits the fulfillment URL, +and (2) when the user actually pays. For (1), we use the contract hascode to +access the state, whereas in (2) we just define a list of payed articles. +For example: -* explain how the merchant prevents fake contracts reconstructions, AKA how it -trusts the parameters given in fulfillment URL. -* explain how the article shown is the original picked article, AKA how the wallet -cannot lie about article name at /pay-ing time. +.. sourcecode:: python + + session[] = {'article_name': 'How_to_write_a_frontend'} # (1) + session['payed_articles'] = ['How_to_write_a_frontend', 'How_to_install_a_backend'] # (2) + +The list of payed articles is used by the frontend to deliver the article to the user: +if the article name is among ``session['payed_articles']``, then the user gets what they +paid for. + +The reason for using `` as the key is to prevent the wallet to send bogus +parameters along the fulfillment URL. `` is the contract hashcode that +the fulfillment handler gets from the backend using the fulfillment URL parameters. + +In fact, when the wallet sends the payment to the frontend pay handler, it has to provide +both coins and contract hashcode. That hascode is (1) verified by the backend when it +receives the coins, (2) used by the frontend to update the list of payed articles. + +See below an example of pay handler: + +.. sourcecode:: python + + ... + + # 'deposit_permission' is the JSON object sent by the wallet + # which contains coins and the contract hashcode. + response = send_payment_to_backend(deposit_permission) + + # The backend accepted the payment + if 200 == response.status_code: + # Here we pick the article name from the state defined at + # fulfillment time. + # deposit_permission['H_contract'] is the contract hashcode + payed_article = session[deposit_permission['H_contract']]['article_name'] + session['payed_articles'].append(payed_article) + + +So the wallet is forced to send a valid contract hashcode along the payment, +and since that hashcode is then used to update the list of payed articles, +the wallet is forced to send fulfillment URL parameters that match that hashcode, +therefore being valid parameters. -- cgit v1.2.3 From 826dbaee28204b9c8ff2fa3f7218b0309c891b3c Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Wed, 9 Nov 2016 15:21:24 +0100 Subject: Working out #4118 --- integration-merchant.rst | 115 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/integration-merchant.rst b/integration-merchant.rst index 10a0c8f2..f3221617 100644 --- a/integration-merchant.rst +++ b/integration-merchant.rst @@ -31,26 +31,27 @@ Interaction with merchant websites The payment process +++++++++++++++++++ -By design, the Taler payment process ensures the following three properties: +By design, the Taler payment process ensures the following properties: 1. The user must see and accept a contract in a secure context before the payment happens. + That contract accounts for all the items which are supposed to be bought. + 2. The payment process must be idempotent, that is at any later time the customer must - be able to replay the payment and again retrieve the online resource he paid for. + be able to replay the payment and retrieve the resource he paid for. In case where a physical item was bought, this online resource is the merchant's order status page, which may contain tracking information for the customer. - Note that by `replay the payment` we mean reusing the `same coins` used to pay for + Note that by `replaying the payment` we mean reusing the `same coins` used to pay for the product the first time to get the `same product` the user got the first time. - So the replay will NOT subtract further credit from the user's total budget. + So the replay does NOT subtract further credit from the user's total budget. -3. The user must be able to *share* the link to both the page with the unpaid offer or - the order status page. If the links are shared with another user, they should - typically allow the other user to perform the same purchase (assuming the item - is still available). +3. Purchases are shareable: any purchase is given a URL that allows other users to + buy the same item(s). We call an *offer URL* any URL at the merchant's Web site that notifies the wallet that the user needs to pay for something. The offer URL must take into account that the user has no wallet installed, and manage the situation accordingly -(for example, by showing a credit card paywall). +(for example, by showing a credit card paywall). The notification can happen either +via JavaScript or via HTTP headers. The merchant needs to have a *contract URL* which generates the JSON contract for Taler. Alternatively, the contract may be embedded @@ -61,9 +62,17 @@ The merchant must also provide a *pay URL* to which the wallet can transmit the payment. Again, how this URL is made known from the merchant to the wallet, it is managed by the HTTP headers- or JavaScript-based protocol. -The merchant must have a *fulfillment URL* which is in charge of doing -two thigs: give to the user what he paid for, or redirect the user -to the offer URL in case he did not pay. +The merchant must also have a *fulfillment URL*, that addresses points 2 and 3 above. +In particular, fulfillment URL is responsible for: + +* Deliver the final product to the user after the payment +* Instruct the wallet to send the payment to the pay URL +* Redirect the user to the offer URL in case they hit a shared fulfillment URL. + +Again, Taler provides two ways of doing that: JavaScript- and HTTP headers-based. + +Taler helps merchants on the JavaScript-based interaction by providing the +``taler-wallet-lib``. See https://git.taler.net/web-common.git/tree/taler-wallet-lib.ts ------- Example @@ -115,9 +124,17 @@ Making an offer When a user visits a offer URL, the merchant returns a page that can interact with the wallet either via JavaScript or by returning a "402 Payment Required". This page's main objective is to inform the wallet on where it should get the -contract. In case of JavaScript interaction, this is done by _FIXME_, whereas -in case of "402 Payment Required", a `X-Taler-contract-url` HTTP header will -be set to the contract's location. (_FIXME_: is that right?). +contract. In case of JavaScript interaction, the merchant should just return +a page whose javascript contains an invocation to ``offerContractFrom()`` +from ``taler-wallet-lib``. This function will download the contract from +`` and hand it to the wallet. + +In case of HTTP headers-based protocol, the merchant needs to set the header +`X-Taler-contract-url` to the contract URL. Once this information reaches the +browser, the wallet will takes action by reading that header and downloading +the contract. + +Either way, the contract gets to the wallet which then renders it to the user. .. _fulfillment: @@ -127,34 +144,64 @@ Fulfillment interaction details A payment process is triggered whenever the user visits a fulfillment URL and he has no rights in the session state to get the items -accounted in the fulfillment URL. Note that when the user is not -visiting a fulfillment URL he got from someone else, it is the wallet -which points the browser to a fulfillment URL after the user accepts -the contract. +accounted in the fulfillment URL. Note that after the user accepts a +contract, the wallet will automatically point the browser to the +fulfillment URL. + +Becasue fulfillment URLs implements replayable and shareable payments +(see points 2,3 above), fulfillment URL parameter must encompass all the +details necessary to reconstruct a contract. -A fulfillment URL must carry all the details necessary to reconstruct -a contract. For simple contracts, a Web shop should encode the unique -contract details (in particular, the transaction identifier) in the -URL. This way, the Web shop can generate fulfillment URLs without -actually having to write the full contract proposal to its database. -This allows the merchant to delay disk (write) operations until -customers actually pay. +That saves the merchant from writing contracts to disk upon every contract +generation, and defer this operation until customers actually pay. + +.................. +HTTP headers based +.................. -Once the payment process has been started, the merchant will then -reconstruct the contract and re-hash it, sending back to the client -a "402 Payment required" status code and some HTTP headers which will -help the wallet to manage the payment, they are: +Once the fulfillment URL gets visited, deliver the final product if the user has +paid, otherwise: the merchant will reconstruct the contract and re-hash it, sending +back to the client a "402 Payment required" status code and some HTTP headers which +will help the wallet to manage the payment. Namely: * `X-taler-contract-hash` * `X-taler-pay-URL` * `X-taler-offer-URL` -By looking at `X-taler-contract-hash`, the wallet can face two situations: +The wallet then looks at `X-taler-contract-hash`, and can face two situations: + +1. This hashcode is already present in the wallet's database (meaning that the user did accept the related contract), so the wallet can send the payment to `X-taler-pay-URL`. During this operation, the wallet associates the coins it sent to `X-taler-pay-URL` with this hashcode, so that it can replay payments whenever it gets this hashcode again. + +2. This hashcode is unknown to the wallet (meaning that the user visited a shared fulfillment URL). The wallet then points the browser to `X-taler-offer-URL`, which is in charge of generating a contract referring to the same items accounted in the fulfillment URL. Of course, the user is then able to accept or not the contract. + +................ +JavaScript based +................ + +Once the fulfillment URL gets visited, deliver the final product if the user has paid, otherwise: +the merchant will reconstruct the contract and re-hash it. Then it will return a page whose JavaScript +needs to include a call to ``taler.executeContract(..)``. See the following example: + +.. sourcecode:: html + + + + + + + .. + + -1. This hashcode is already present in the wallet's database, so the wallet can send the payment to `X-taler-pay-URL`. During this operation, the wallet associates the data it sent to `X-taler-pay-URL` with the received hashcode, so that it can replay payments whenever it gets this hashcode again. -2. This hashcode is unknown to the wallet, so the wallet can point the browser to `X-taler-offer-URL`, so the user will get the contract and decide to accept it or not. This happens when the user gets the fulfillment URL from someone else. +The logic which will take place is the same as in the HTTP header based protocol. +Once ``executePayment(..)`` gets executed in the browser, it will hand its three +parameters to the wallet, which will: -FIXME: explain the JavaScript way +1. Send the payment to `` if `` is found in its database (meaning that the user accepted it). +2. Redirect the browser to ``, if `` is NOT found in its database, meaning that the user visited a shared fulfillment URL. -------------------- Example: Essay Store -- cgit v1.2.3