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