summaryrefslogtreecommitdiff
path: root/df/07c2c81e1e9a508d7d9716b63b76f8d95325a0
blob: a9c2b166abc37f0cbe0fcbaea40aab84acc1990b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191]
	helo=mx.sourceforge.net)
	by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76)
	(envelope-from <stephane@kill-bill.org>) id 1WIVYd-0008Tl-LB
	for bitcoin-development@lists.sourceforge.net;
	Wed, 26 Feb 2014 03:53:19 +0000
Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of kill-bill.org
	designates 209.85.160.46 as permitted sender)
	client-ip=209.85.160.46; envelope-from=stephane@kill-bill.org;
	helo=mail-pb0-f46.google.com; 
Received: from mail-pb0-f46.google.com ([209.85.160.46])
	by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128)
	(Exim 4.76) id 1WIVYb-0002KV-F9
	for bitcoin-development@lists.sourceforge.net;
	Wed, 26 Feb 2014 03:53:19 +0000
Received: by mail-pb0-f46.google.com with SMTP id um1so391536pbc.5
	for <bitcoin-development@lists.sourceforge.net>;
	Tue, 25 Feb 2014 19:53:11 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
	d=1e100.net; s=20130820;
	h=x-gm-message-state:content-type:mime-version:subject:from
	:in-reply-to:date:cc:message-id:references:to;
	bh=Go9SX7rLPg9GTGqTc6W3tyIdo3a6QxZwGJYtsul8ddM=;
	b=jqKVC3XVImfkSZFvfG2iHsmtoudK/FEcLcwf07h6igwAAX4ozAoIWEzwlwgwd7ZgI0
	fuZGaCy0Qh1ye7GUoTtUDjUak9DQZM4COowQXvnlbzx7XWWvXVH6IBr9HE3c3dPOWhhy
	hFRbdY/eX7XAaCl0+1ofGzGiSl38CBSZ/Uwgrd9EXYeYBuixvr5VWcbCT7n9JIL0huMU
	lv8W9ZVgQK7bNlzGBqislijtKHyPedO+adOLVlvV6L2Bf+pFUcskMwQVv3peyaZT8bCf
	THLHD0/w8Jryzehc/ywIK+xEyEE9EDm2ojXvJuqrSLUkI4ZgKlO/Pjf9lI3OYFM+2UX5
	2sOQ==
X-Gm-Message-State: ALoCoQk879B7jk+tpKoDoetD/KuEeTEgZoZtS3Prq4c+x9hP0UEKRSJrAtsE2idnX4/JcDZyr6yn
X-Received: by 10.66.148.230 with SMTP id tv6mr5774664pab.155.1393386791528;
	Tue, 25 Feb 2014 19:53:11 -0800 (PST)
Received: from [192.168.1.107] (adsl-71-146-11-193.dsl.pltn13.sbcglobal.net.
	[71.146.11.193])
	by mx.google.com with ESMTPSA id bc4sm15896882pbb.2.2014.02.25.19.53.09
	for <multiple recipients>
	(version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
	Tue, 25 Feb 2014 19:53:10 -0800 (PST)
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_95094412-BF43-4F67-807D-5F2DC2CB942C"
Mime-Version: 1.0 (Mac OS X Mail 6.6 \(1510\))
From: Stephane Brossier <stephane@kill-bill.org>
In-Reply-To: <CANEZrP0-LqFC8N500=mnKbKE+=UtFw_Y5cHR8JRC-zmmGsSAjA@mail.gmail.com>
Date: Tue, 25 Feb 2014 19:53:08 -0800
Message-Id: <BFA4F8CD-529B-418D-B3B9-599C89914CD1@kill-bill.org>
References: <E1FDB3F2-25ED-4B99-979E-12CE943CBD66@kill-bill.org>
	<CANEZrP10z6_UAHD97mj22kVEGyXgHPQ2PdP_8RxHT5Py+xRP_A@mail.gmail.com>
	<D6BCC0C4-EF22-4DE8-868E-825D19C387E3@kill-bill.org>
	<CANEZrP0FzTGmp1zbaW1VHJLk5117ZnTSehfF4uMX=+UFS+R_Dw@mail.gmail.com>
	<0CC0BE1D-1DAA-4994-B034-EB7712F845CF@kill-bill.org>
	<DBA255DB-4839-4C3A-BA62-BD3926995C12@kill-bill.org>
	<CAEY8wq6F33814d2+97AqDoAicvh=0PigHZ03wHadMq6JqtQMLg@mail.gmail.com>
	<EAEC76DA-A490-4A61-BFB7-611D4ADF1680@kill-bill.org>
	<CAEY8wq5=pAMTqDPM8yeCF+Z2=1GWmD0UDQdgacN1o3jAUh_BYA@mail.gmail.com>
	<CAEY8wq40RxeUYYJS2m=xq26iTd2NE64WR7QOUO0+yR-MJQCoxQ@mail.gmail.com>
	<5F91BEBF-ECDD-4CBD-A85E-FD7E7DB3F01F@kill-bill.org>
	<81FBEA67-45A9-4531-BEA0-071CE9FAEF7E@kill-bill.org>
	<CANEZrP0-LqFC8N500=mnKbKE+=UtFw_Y5cHR8JRC-zmmGsSAjA@mail.gmail.com>
To: Mike Hearn <mike@plan99.net>
X-Mailer: Apple Mail (2.1510)
X-Spam-Score: -0.5 (/)
X-Spam-Report: Spam Filtering performed by mx.sourceforge.net.
	See http://spamassassin.org/tag/ for more details.
	-1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for
	sender-domain
	-0.0 SPF_PASS               SPF: sender matches SPF record
	1.0 HTML_MESSAGE           BODY: HTML included in message
X-Headers-End: 1WIVYb-0002KV-F9
Cc: Bitcoin Dev <bitcoin-development@lists.sourceforge.net>,
	Pierre-Alexandre Meyer <pierre@kill-bill.org>
Subject: Re: [Bitcoin-development] Extension for BIP-0070 to support
	recurring payments
X-BeenThere: bitcoin-development@lists.sourceforge.net
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: <bitcoin-development.lists.sourceforge.net>
List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>,
	<mailto:bitcoin-development-request@lists.sourceforge.net?subject=unsubscribe>
List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development>
List-Post: <mailto:bitcoin-development@lists.sourceforge.net>
List-Help: <mailto:bitcoin-development-request@lists.sourceforge.net?subject=help>
List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>,
	<mailto:bitcoin-development-request@lists.sourceforge.net?subject=subscribe>
X-List-Received-Date: Wed, 26 Feb 2014 03:53:19 -0000


--Apple-Mail=_95094412-BF43-4F67-807D-5F2DC2CB942C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=windows-1252

Hi Mike, Jeremy, Drak,

Before going through your questions, I would like to bring some clarity =
on a few key elements in that protocol. There are really two aspects to =
it:
The contract negotiation; when the user first subscribes, it is prompted =
by a contract that will define the payment bounds associated with that =
subscription.=20
Once accepted, the wallet is in charge and the user does not have to =
interact anymore -- this is the point of the recurring payment protocol. =
The wallet will poll the merchant and issue payments as they are =
requested by the merchant as long as they stay within the bounds of what =
was specified by the contract (and accepted by the customer).

I think it would help to explain how we ended up with the type of =
contract we introduced in that protocol. In an ideal world and in a NON =
recurring scheme, the contract should simply be the exact amount to be =
paid. In our case the exact amount may not be completely known in =
advance -- for e.g taxes, shipping, pro-rations, =85 and so we decided =
to introduce first a max amount per payment, and also a max amount per =
period. It is up to the merchant to decide whether to specify none, any =
or both bounds (max amount per payment and max amount per period). By =
specifying both, the contract is tighter and the client would feel safer =
to accept it. In the extreme case, by specifying none, the client would =
be presented with a contract to pay whatever is requested -- probably =
not a good option in the Bitcoin world unless there is a high sense of =
trust with the merchant.  =20

=46rom reading your comments, it appears we have not been clear on how =
that frequency (PaymentFrequencyType) is being used. Its sole purpose is =
to define the max amount per period in the contract. The frequency of =
the payment is implicitly dictated by the merchant but not specified in =
the protocol by design: the wallet has to poll with a fine granularity =
(ideally each day when it is up) to understand if there is something =
pending. In the same way, a specified amount was not enough in the =
contract, we feel it would be restrictive to specify in advance when =
payments are due. There are a lot of complex scenarios in the billing =
space, and having the wallet poll the merchant to inquire for pending =
payments is the most flexible option and the contract is there to ensure =
the client will not be abused. To give a concrete example, imagine a =
data plan where you pay a base recurring price of $70 per month, but you =
are charged $10 per GB of data used beyond your included limit. If you =
exceed your limit on the 15th and the 23rd of a given month, two extra =
payment attempts will be requested by the merchant, that you couldn=92t =
predict (this scenario is often referred to as usage billing with Prepay =
Credits and Top-up, where the customer pays in advance for blocks of N =
units, and once they are consumed another N are purchased).


See answers in your questions inlined below:

>=20
> I have the following comments:
> There's no need to serialize RecurringPaymentDetails as bytes here. =
It's done that way outside of PaymentDetails in order to support digital =
signatures over protobufs that may have extensions the wallet app isn't =
aware of, but it's a pain and inside PaymentDetails (and therefore for =
most extensions) it shouldn't be necessary. So you can just use =
"optional RecurringPamentDetails recurring_payments =3D 8;"
>=20

OK, we'll fix it.


> There's only 4 possibilities here for recurrences. That seems rather =
restrictive. Is the cost of being more expressive really so high? Why =
not allow more flexible specification of periods?
> If there's no payment_frequency_type field then what happens? A quirk =
of protobufs to be aware of is that making an enum field "required" can =
hurt backwards compatibility. Because it will be expressed using a =
languages underlying enum type, if there's a new enum member added later =
old software that attempts to deserialize this will throw exceptions =
because the new "unknown" member would be unrepresentable in the old =
model. Making the field optional avoids this problem (it will be treated =
as missing instead) but means software needs to be written to know what =
to do when it can't read the enum value / sees enum values from the =
future.
>=20

I hope the explanation above answers the questions.

> I assume the amounts are specified in terms of satoshi, and timestamps =
are UNIX time, but better to make that explicit.
>=20

Yes.

> Seems there's an implicit value constraint that max_payment_amount <=3D =
max_payment_per_period. What happens if that constraint is violated? =
Best to document that.
>=20

As explained above, contract would define none, 1 or both conditions.  =
First the merchant should not return such 'conditions' but if it does =
the client should not accept the contract. If the client decides to =
accept it anyway, then the wallet just verifies both conditions are met =
separately regardless of whether there is such violation and if so, =
makes the payment.

> What's the "merchant ID" namespace thing about? What's it for? What =
happens if I set my competitors merchant ID there?

I agree, we can easily get rid of it.

> What's the "subscription ID"? Is this stuff not duplicative/redundant =
with the existing merchant_data field?

In an ideal world the merchant should return unique subscriptionId (UUID =
for instance). That subscriptionId is used in the code to identify the =
contracts associated with the subscription. The merchant_data if i =
understand correctly the payment protocol is opaque from the client =
point of view, so it cannot be used by the client for that purpose.=20
> In what situations would you have >1 contract per payment request? I'm =
not sure I understand why it's repeated. Presumably if there are zero =
contracts included the data should be ignored, or an error thrown and =
the entire payment request rejected? Which should it be?
>=20


There are many example where that could  happen; for instance if you =
subscribe to a service,  then later decide to downgrade to a lower =
product. The merchant may decide to only let you downgrade at the end of =
your paid period-- to avoid generating extra credit-- and in that =
situation you end up with two contracts: One for the current product you =
are in and one for the future product you will end up on when the =
downgrade becomes effective.


> It's unclear to me given such a contract when the payment should =
actually occur. For instance if it's "monthly" then what day in the =
month would the payment occur?
>=20

As outlined above in the introduction, the protocol is designed in such =
a way that the wallet does not have to know what is the exact date when =
payment should occur, but instead polls the merchant for pending =
payments. There are many situations when specifying an exact payment =
date is not an option so that flexibility is essential. A simple example =
would be for a customer who started subscribing on the 31th of a month. =
Since there will be months with 28/29/30 days, the payment date would =
change depending on the month.




> You'll notice I moved the comments to be above the field definitions. =
I know the current proto isn't done that way, but let's change it - long =
comments are good and putting them above the field definitions =
encourages people to write enough detail without being put off by line =
length constraints
>=20

Fine.


> I think the next step would be to talk to BitPay/get Jeff+Stephen =
involved because I know they have customers that really want recurring =
payments, and those guys will have a clearer idea of customer =
requirements than we do. I feel uncomfortable with designing or =
reviewing in a vacuum without some actual people who would use it =
chiming in, as I don't really know much about the underlying business =
processes.


We are totally open to receive feedbacks from them.. How do we bring =
them in the discussion?

>=20
> I have some other comments about the bitcoinj implementation =
specifically - for instance, we don't have a "wallet directory" concept: =
everything goes into the wallet file. So we'll need to think about how =
to structure the code to allow that. Also, just using a background =
polling thread is likely not flexible enough, as on some platforms you =
can't stay running all the time (e.g. Android) without upsetting people, =
but the underlying OS can wake you up at the right times, so wallet apps =
should have an ability to control wakeup tasks. But we can discuss that =
over on the bitcoinj list specifically. Let's keep this thread for the =
general protocol design.

Ok that makes sense.

>=20
> BIP 70 is indeed implemented in Bitcoin Core on the C++ side, so that =
isn't a concern. It could be done there too.
>=20

Great to know.




--Apple-Mail=_95094412-BF43-4F67-807D-5F2DC2CB942C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=windows-1252

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html =
charset=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space; =
"><div><b =
id=3D"docs-internal-guid-4a9a06ba-6c39-ff6f-7d06-7ec212a688dc"><div =
style=3D"line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt; "><span =
style=3D"font-size: 15px; font-family: Arial; font-weight: normal; =
vertical-align: baseline; white-space: pre-wrap; ">Hi Mike, Jeremy, =
Drak,</span></div><br><span style=3D"font-size: 15px; font-family: =
Arial; font-weight: normal; vertical-align: baseline; white-space: =
pre-wrap; "></span><div style=3D"line-height: 1.15; margin-top: 0pt; =
margin-bottom: 0pt; "><span style=3D"font-size: 15px; font-family: =
Arial; font-weight: normal; vertical-align: baseline; white-space: =
pre-wrap; ">Before going through your questions, I would like to bring =
some clarity on a few key elements in that protocol. There are really =
two aspects to it:</span></div><ol =
style=3D"margin-top:0pt;margin-bottom:0pt;"><li dir=3D"ltr" =
style=3D"list-style-type: decimal; font-size: 15px; font-family: Arial; =
font-weight: normal; vertical-align: baseline; "><div =
style=3D"line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt; "><span =
style=3D"vertical-align: baseline; white-space: pre-wrap; ">The contract =
negotiation; when the user first subscribes, it is prompted by a =
contract that will define the payment bounds associated with that =
subscription. </span></div></li><li dir=3D"ltr" style=3D"list-style-type: =
decimal; font-size: 15px; font-family: Arial; font-weight: normal; =
vertical-align: baseline; "><div style=3D"line-height: 1.15; margin-top: =
0pt; margin-bottom: 0pt; "><span style=3D"vertical-align: baseline; =
white-space: pre-wrap; ">Once accepted, the wallet is in charge and the =
user does not have to interact anymore -- this is the point of the =
recurring payment protocol. The wallet will poll the merchant and issue =
payments as they are requested by the merchant as long as they stay =
within the bounds of what was specified by the contract (and accepted by =
the customer).</span></div></li></ol><br><span style=3D"font-size: 15px; =
font-family: Arial; font-weight: normal; vertical-align: baseline; =
white-space: pre-wrap; "></span><div style=3D"line-height: 1.15; =
margin-top: 0pt; margin-bottom: 0pt; "><span style=3D"font-size: 15px; =
font-family: Arial; font-weight: normal; vertical-align: baseline; =
white-space: pre-wrap; ">I think it would help to explain how we ended =
up with the type of contract we introduced in that protocol. In an ideal =
world and in a NON recurring scheme, the contract should simply be the =
exact amount to be paid. In our case the exact amount may not be =
completely known in advance -- for e.g taxes, shipping, pro-rations, =85 =
and so we decided to introduce first a max amount per payment, and also =
a max amount per period. It is up to the merchant to decide whether to =
specify none, any or both bounds (max amount per payment and max amount =
per period). By specifying both, the contract is tighter and the client =
would feel safer to accept it. In the extreme case, by specifying none, =
the client would be presented with a contract to pay whatever is =
requested -- probably not a good option in the Bitcoin world unless =
there is a high sense of trust with the merchant. =
&nbsp;&nbsp;</span></div><br><span style=3D"font-size: 15px; =
font-family: Arial; font-weight: normal; vertical-align: baseline; =
white-space: pre-wrap; "></span><div style=3D"line-height: 1.15; =
margin-top: 0pt; margin-bottom: 0pt; "><span style=3D"font-size: 15px; =
font-family: Arial; font-weight: normal; vertical-align: baseline; =
white-space: pre-wrap; ">=46rom reading your comments, it appears we =
have not been clear on how that frequency (PaymentFrequencyType) is =
being used. Its sole purpose is to define the max amount per period in =
the contract. The frequency of the payment is implicitly dictated by the =
merchant but not specified in the protocol by design: the wallet has to =
poll with a fine granularity (ideally each day when it is up) to =
understand if there is something pending. In the same way, a specified =
amount was not enough in the contract, we feel it would be restrictive =
to specify in advance when payments are due. There are a lot of complex =
scenarios in the billing space, and having the wallet poll the merchant =
to inquire for pending payments is the most flexible option and the =
contract is there to ensure the client will not be abused. To give a =
concrete example, imagine a data plan where you pay a base recurring =
price of $70 per month, but you are charged $10 per GB of data used =
beyond your included limit. If you exceed your limit on the 15th and the =
23rd of a given month, two extra payment attempts will be requested by =
the merchant, that you couldn=92t predict (this scenario is often =
referred to as usage billing with Prepay Credits and Top-up, where the =
customer pays in advance for blocks of N units, and once they are =
consumed another N are purchased).</span></div><br><span =
style=3D"font-size: 15px; font-family: Arial; font-weight: normal; =
vertical-align: baseline; white-space: pre-wrap; =
"></span></b></div><div><br></div><div><b =
id=3D"docs-internal-guid-4a9a06ba-6c39-ff6f-7d06-7ec212a688dc"><div =
style=3D"line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt; "><span =
style=3D"font-size: 15px; font-family: Arial; font-weight: normal; =
vertical-align: baseline; white-space: pre-wrap; ">See answers in your =
questions inlined below:</span></div><div style=3D"line-height: 1.15; =
margin-top: 0pt; margin-bottom: 0pt; "><span style=3D"font-size: 15px; =
font-family: Arial; font-weight: normal; vertical-align: baseline; =
white-space: pre-wrap; "><br></span></div></b></div><div><blockquote =
type=3D"cite"><div dir=3D"ltr"><div><pre =
style=3D"font-family:Consolas,'Liberation =
Mono',Courier,monospace;font-size:12px;margin-top:0px;margin-bottom:0px;co=
lor:rgb(51,51,51);line-height:18px"><div><span class=3D"" =
style=3D"color:rgb(153,153,136);font-style:italic"><br></span></div></pre>=
</div><div>I have the following comments:</div>
<div><ol><li>There's no need to serialize RecurringPaymentDetails as =
bytes here. It's done that way outside of PaymentDetails in order to =
support digital signatures over protobufs that may have extensions the =
wallet app isn't aware of, but it's a pain and inside PaymentDetails =
(and therefore for most extensions) it shouldn't be necessary. So you =
can just use "optional RecurringPamentDetails recurring_payments =3D =
8;"<br>
<br></li></ol></div></div></blockquote><div><br></div><div>OK, we'll fix =
it.</div><div><br></div><br><blockquote type=3D"cite"><div =
dir=3D"ltr"><div><ol start=3D"2"><li>There's only 4 possibilities here =
for recurrences. That seems rather restrictive. Is the cost of being =
more expressive really so high? Why not allow more flexible =
specification of periods?</li></ol></div></div></blockquote><blockquote =
type=3D"cite"><div dir=3D"ltr"><div><ol start=3D"3"><li>
If there's no payment_frequency_type field then what happens? A quirk of =
protobufs to be aware of is that making an enum field "required" can =
hurt backwards compatibility. Because it will be expressed using a =
languages underlying enum type, if there's a new enum member added later =
old software that attempts to deserialize this will throw exceptions =
because the new "unknown" member would be unrepresentable in the old =
model. Making the field optional avoids this problem (it will be treated =
as missing instead) but means software needs to be written to know what =
to do when it can't read the enum value / sees enum values from the =
future.<br>
<br></li></ol></div></div></blockquote><div><br></div><div>I hope the =
explanation above answers the questions.</div><br><blockquote =
type=3D"cite"><div dir=3D"ltr"><div><ol start=3D"4"><li>I assume the =
amounts are specified in terms of satoshi, and timestamps are UNIX time, =
but better to make that =
explicit.<br><br></li></ol></div></div></blockquote><div><br></div>Yes.</d=
iv><div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div><ol =
start=3D"5"><li>Seems there's an implicit value constraint that =
max_payment_amount &lt;=3D max_payment_per_period. What happens if that =
constraint is violated? Best to document that.<br>
<br></li></ol></div></div></blockquote><div><br></div>As explained =
above, contract would define none, 1 or both conditions. &nbsp;First the =
merchant should not return such 'conditions' but if it does the client =
should not accept the contract. If the client decides to accept it =
anyway, then the wallet just verifies both conditions are met separately =
regardless of whether there is such violation and if so, makes the =
payment.</div><div><br></div><div><blockquote type=3D"cite"><div =
dir=3D"ltr"><div><ol start=3D"6"><li>What's the "merchant ID" namespace =
thing about? What's it for? What happens if I set my competitors =
merchant ID there?</li></ol></div></div></blockquote><div><br></div>I =
agree, we can easily get rid of it.</div><div><br><blockquote =
type=3D"cite"><div dir=3D"ltr"><div><ol start=3D"6"><li>What's the =
"subscription ID"? Is this stuff not duplicative/redundant with the =
existing merchant_data =
field?<br></li></ol></div></div></blockquote><div><br></div><div>In an =
ideal world the merchant should return unique subscriptionId (UUID for =
instance). That subscriptionId is used in the code to identify the =
contracts associated with the subscription. The merchant_data if i =
understand correctly the payment protocol is opaque from the client =
point of view, so it cannot be used by the client for that =
purpose.&nbsp;</div><blockquote type=3D"cite"><div dir=3D"ltr"><div><ol =
start=3D"6"><li>In what situations would you have &gt;1 contract per =
payment request? I'm not sure I understand why it's repeated. Presumably =
if there are zero contracts included the data should be ignored, or an =
error thrown and the entire payment request rejected? Which should it =
be?<br>
=
<br></li></ol></div></div></blockquote><div><br></div><div><br></div><div>=
There are many example where that could &nbsp;happen; for instance if =
you subscribe to a service, &nbsp;then later decide to downgrade to a =
lower product. The merchant may decide to only let you downgrade at the =
end of your paid period-- to avoid generating extra credit-- and in that =
situation you end up with two contracts: One for the current product you =
are in and one for the future product you will end up on when the =
downgrade becomes effective.</div><div><br></div><br><blockquote =
type=3D"cite"><div dir=3D"ltr"><div><ol start=3D"8"><li>It's unclear to =
me given such a contract when the payment should actually occur. For =
instance if it's "monthly" then what day in the month would the payment =
occur?<br><br></li></ol></div></div></blockquote><div><br></div><div>As =
outlined above in the introduction, the protocol is designed in such a =
way that the wallet does not have to know what is the exact date when =
payment should occur, but instead polls the merchant for pending =
payments. There are many situations when specifying an exact payment =
date is not an option so that flexibility is essential. A simple example =
would be for a customer who started subscribing on the 31th of a month. =
Since there will be months with 28/29/30 days, the payment date would =
change depending on the =
month.</div><div><br></div><div><br></div><div><br></div><br><blockquote =
type=3D"cite"><div dir=3D"ltr"><div><ol start=3D"9"><li>You'll notice I =
moved the comments to be above the field definitions. I know the current =
proto isn't done that way, but let's change it - long comments are good =
and putting them above the field definitions encourages people to write =
enough detail without being put off by line length constraints</li>
=
</ol></div><div><br></div></div></blockquote><div><br></div><div>Fine.</di=
v><div><br></div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div>I =
think the next step would be to talk to BitPay/get Jeff+Stephen involved =
because I know they have customers that really want recurring payments, =
and those guys will have a clearer idea of customer requirements than we =
do. I feel uncomfortable with designing or reviewing in a vacuum without =
some actual people who would use it chiming in, as I don't really know =
much about the underlying business =
processes.</div></div></blockquote><div><br></div><div><br></div><div>We =
are totally open to receive feedbacks from them.. How do we bring them =
in the discussion?</div><br><blockquote type=3D"cite"><div dir=3D"ltr">
<div><br></div><div>I have some other comments about the bitcoinj =
implementation specifically - for instance, we don't have a "wallet =
directory" concept: everything goes into the wallet file. So we'll need =
to think about how to structure the code to allow that. Also, just using =
a background polling thread is likely not flexible enough, as on some =
platforms you can't stay running all the time (e.g. Android) without =
upsetting people, but the underlying OS can wake you up at the right =
times, so wallet apps should have an ability to control wakeup tasks. =
But we can discuss that over on the bitcoinj list specifically. Let's =
keep this thread for the general protocol =
design.</div></div></blockquote><div><br></div>Ok that makes =
sense.</div><div><br><blockquote type=3D"cite"><div dir=3D"ltr">
<div><br></div><div class=3D"gmail_extra">BIP 70 is indeed implemented =
in Bitcoin Core on the C++ side, so that isn't a concern. It could be =
done there too.<br><br></div></div>
</blockquote><br></div><div>Great to =
know.</div><div><br></div><div><br></div><br></body></html>=

--Apple-Mail=_95094412-BF43-4F67-807D-5F2DC2CB942C--