On Feb 27, 2013, at 12:39 PM, Fernando Jiménez <[email protected]> wrote:

>>> 
>>> 3. How would you manage refunds? I can't see how would you tell the web 
>>> service that your intention is to get a JWT for a refund request and not 
>>> for a payment one.
>> 
>> That's a good question! However, refunds are so hard for in-app payments 
>> that we've pretty much already ignored them. The current API also has no 
>> reliable way to do refunds. Take the example of ad-hoc JWTs (in the current 
>> API). Let's say a customer paid to "unlock level 10" then she beat level 10 
>> and decided to be sneaky and ask for a refund. How do we grant a refund? The 
>> current navigator.mozPay() has no memory of "the product." It cannot take 
>> away "Unlock level 10" after a refund because it doesn't know how. In this 
>> case, it would be impossible to take away Unlock level 10.
>> 
>> For now we are not supporting refunds for in-app payments. In the future, 
>> maybe developers could opt-in to refunds and then our app reviewers would 
>> have to be sure that they *can* grant refunds before we allow them to. 
>> 
>> For Marketplace app purchases, it's easier to implement refunds because we 
>> know what the app logic is inside the Firefox Marketplace. We know how to 
>> take away apps.
> 
> The current API does not *do* refunds but provides a way to *request* 
> refunds. The same way as it does for payments.

Oh, right, I forgot that we added refund requests to mozPay(). The dilemma I 
explained above is more for automated refunds where the user clicks some button 
to get a refund *without* the developer knowing about it. In the case you 
mention, the developer initiates the refund so that's fine; it's their refund 
request on behalf of the customer.

> 
> How is the Marketplace different to any other application using in-app 
> payments in terms of API usage?

Again, this only applied to automated refunds. My bad.

>>> 
>>> So my proposal, based on yours, would be extending the API this way:
>>> 
>>>     "DOMDOMRequest mozPay(DOMString signingService, jsval dataToBeSigned)"
>>> 
>>> where: 
>>> - "signingService" would be the URL of the Mozilla web service or any other 
>>> JWT signing web service.
>>> - "dataToBeSigned" would be a JSON object containing whatever is expected 
>>> by the signing service. It could be the identifier of the product being 
>>> sold or refunded and a flag for setting a payment or a refund, for example.
>> 
>> ok, let's say an app does this:
>> 
>> nav.mozPay('https://mkt/payments/signing-service', {
>>   request: {
>>     name: 'Rainbow Unicorn',
>>     pricePoint: 4  // USD $3.99
>>   }
>> })
>> 
>> What would that do? POST the raw JSON blob to the signing service and get 
>> backed a signed JWT? That would defeat the purpose of the signature because 
>> then anyone can sign anything. An attacker could just patch the app and 
>> change the JS to do this (note the price change):
>> 
>> nav.mozPay('https://mkt/payments/signing-service', {
>>   request: {
>>     name: 'Rainbow Unicorn',
>>     pricePoint: 1  // USD $0.99
>>   }
>> })
>> 
>> and they would get the product for whatever price they wanted. Am I missing 
>> something?
> 
> No.
> 
> Sorry if I didn't explained myself properly.
> 
> What an app should do depends on what the signing service expects and it is 
> very similar to what you are proposing.
> 
> Let's say that the signing service is the one exposed by the Firefox 
> Marketplace, which expects a "productId". Instead of doing:
> 
> var unicornId = 1234;
> payment.start(unicornId, function(jwt, transaction) {
>   var request = navigator.mozPay([jwt]);
>   request.onsuccess = function() {
>     transaction.whenDone(function(error) {
>       if (!error) {
>         alert('You bought a Rainbow Unicorn!');
>       }
>     });
>   };
> });
> 
> The developer could do something like:
> 
> var unicornId = 1234;
> var req = navigator.mozPay('https://mkt/payments/signing-service', {
>   productId: unicornId
> });
> req.onsuccess = function(evt) {
>   alert('Payment request done!);
>   // Use evt.target.result.transactionId to check that the product was paid 
> for, as you suggest, polling something like: GET 
> /payment/status/<transactionId>
> });
> req.onerror = function(evt) {
>   alert('Error');
> });


Ah, ok. I am following you now! I agree. Once we come up with a prototype for 
how it might work and we test it out then we could make it part of the mozPay() 
API and ship an update to clients. I think the details of the API calls will 
need some bikeshedding but there's no need for that on this thread.

Kumar

_______________________________________________
dev-webapps mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-webapps

Reply via email to