[Top][All Lists]

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

Re: [Taler] transaction history UX and fulfillment URL semantics

From: Florian Dold
Subject: Re: [Taler] transaction history UX and fulfillment URL semantics
Date: Sun, 24 Jan 2016 23:24:30 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1

On 01/24/2016 10:40 PM, Christian Grothoff wrote:
> On 01/24/2016 09:35 PM, Florian Dold wrote: 
> Again, I thought you argued nicely for cookie-state to be disallowed.
> Also, AFAIK /contract was never expected to do much on the session
> management side, it was just supposed to return the JSON-formatted
> signed contract.

I really *wish* we could eliminate session state, but then we would have
to ditch PHP session management, and cookie-based session management in
other common frameworks as well.

And yes, I always argued against session state, but your argument that
it makes it easier for merchant implementations was rather convincing ;-)

So, at this point we should make a definite decision to support session
state or not, because it influences the rest of the design a lot.

> I thought we decided cookies were bad.  If the UUID is OK as-is (refers
> to a paid contract, and if the payment is tied to an IP address, the
> client's IP is unchanged), then we execute. Now, cookies could
> optionally be used as well, but I'm not sure "in most cases" is the
> preferred formulation.

Okay, maybe I missed the point of our earlier discussion then.  I
thought you were arguing in favor of cookies that can be restored by
going to a special page?

I don't see why we would ever want to tie a contract UUID to an IP
address though.  This is really bad, today people are in environments
where their IP address changes all the time (if I move a bit to the
side, my phone / laptop might connect to a different WiFi hot spot).
I'm strongly against this ...

>> * otherwise asks the wallet to execute the contract that is associated
>> with the URL (i.e. serves as the execution page to inject the request in
>> the right domain context)
> I'd have described this differently: The merchant generates a page that
> interacts with the wallet to trigger the payment dialog.  For this, the
> merchant frontend may internally fetch /contract and inline that, or
> send JS to the browser where the JS then (as usual) fetches the
> /contract page. The page may set a cookie (see above). In either case,
> we directly interact with the wallet and effectively ask the wallet
> would still ask the wallet to issue a POST to /pay.  The wallet can use
> the contract-UUID to detect that it already paid on this very contract
> and just auto-replay an old /pay (resulting in the browser being
> redirected to a now valid fulfillment, see first case), or if this is a
> "first-time" contract, interactively prompt the user to approve it (same
> as after "checkout" in shopping cart).

Yes.  You're describing exactly what I meant to say :-)

>> * if this fails (the wallet does not have the contract) it redirects the
>> user agent to a page where the user can buy the product, since the user
>> must have gotten the link from somewhere without having bought the product.
> Your formulation is unclear here. In particular, you write "it
> redirects", but who is "it"?  "it" must not be the merchant's JS, as the
> merchant's JS must not be able to learn which contracts our wallet has
> executed already.  The merchant's JS is always doing just one thing: ask
> the wallet to pay for a contract. Thus, the wallet should be the "it"
> that makes a choice here.

This is a bit tricky, since if we go to a fulfillment page that we got
from a friend via email (where we didn't pay for it ourselves), the
merchant needs to let the wallet know where to get the contract to buy
e.g. the article.

This inherently allows the merchant to know whether the user paid for
THIS contract UUID from THIS merchant (the matching is done based on the
fulfillment URL including the UUID), which is reasonable enough.

> Also, your formulation is unclear as to what it means to "redirect the
> user agent".  The wallet may move the browser to a wallet-controlled
> backend-page showing the contract (where the user can accept/reject).
> The wallet should not redirect the user agent to some other "shopping"
> page generated by the merchant's frontend.

Why not?  If I send you the fulfillment link for an article I paid, you
should be redirected to the teaser page with the "buy this" link for the
article.  Again, the information the merchant can gain is negligible,
and the alternative would be to just say "oh, this is not yours, but we
won't tell you what it is either".

A super paranoid wallet could ask the question "do you want to go to the
checkout page for this contract, since it's not in your wallet", and
then the merchant can't distinguish between customers who already have
the article and those who just didn't bother buying it.

> What is your notion of equivalence here? And which URL? If we (still)
> have /contract, /pay (POST), and /fulfillment, the 'replay' may _look_
> the same for the customer for the /fulfillment in my interpretation of
> the design. The customer also never sees /contract and /pay URIs, but
> they still exist internally. Also, the replay is technically still very
> different, as in some cases (cookie/state OK) we immediately deliver the
> information, while in others (no cookie/state bad/payment failed
> earlier) we have like 3 additional round-trips with requests to /pay
> before the content is finally transmitted.  Now, again this may happen
> behind the scenes and thus (more or less) invisible to the customer, but
> it's not exactly "equivalent".

"Equivalent" in the sense that the browser makes the same request.

Why would "replay" from the wallet do anything different then just open
the fulfillment URL in a new tab, which then does the steps we discussed

This is not even a premature optimization; why should we have two
different implementations here when one is enough?

Why would I ever want to do a replay if the UUID-based fulfillment link
just gives me what I want?

> If this is about combining /exec and /pay, I'm fine with that. The
> result is nice in that there is only one visible URI to the customer
> (the /fulfillment URI). Still, having the POST /pay separate is IMO the
> right thing, as is having an (optional) GET /contract URI.

Yeah, I never wanted to eliminate /pay. And /contract is a merchant
implementation detail, it should not be in the HTTP API spec but in the
reference implementation docs.

- Florian

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

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