Hi all.
We're rapidly approaching the day when third party app developers can begin 
testing web payments using navigator.mozPay() [1] against Mozilla's Web Payment 
Provider [2]. I'd like to get some feedback on ideas for how developers can 
*test* their use of the API.

[1] https://wiki.mozilla.org/WebAPI/WebPayment
[2] https://wiki.mozilla.org/WebAPI/WebPaymentProvider

Some info on those wiki pages is outdated already (fixes are coming). Here is a 
summary of how developers will set up payments:

The developer...
- submits app to Firefox Marketplace
- activates in-app payments
- enters bank details to receive money
- clicks a button to generate a secret key
- hosts an app on a server
- writes server code to sign JWTs (JSON Web Tokens) with the secret key
- hosts two URLs, a postback and a chargeback
- creates purchase button in app that calls nav.mozPay([signedJWT])

How does a developer test this? She will want to know:

1. Did I sign my JWT correctly, is the format OK, etc?
2.  Are my postbacks and chargebacks hooked up correctly to my client code?

The second question is the most important because this is how the app developer 
protects against malicious attackers stealing digital goods. The postback needs 
to reconcile the product and probably also the user identity which would all be 
managed internally by the app.

Here is an example of constructing and signing a JWT request:

token = jwt.encode({
  "iss" : appIdFromMarketplace,
  "aud" : "marketplace.firefox.com",
  "typ" : "mozilla/payments/v1/pay",
  "exp" : 1337357297,
  "iat" : 1337360897,
  "request" : {
    "name" : "Unlock Level 10",
    "description" : "The most exciting level in the game! Dungeons! Fire!",
    "id": "unique-id-for-product",
    "pricePoint": 1,  // This might convert to USD 0.99, EUR 0.89, BRL 1.20
    "productData" : "my_product_id=1234&my_user_id=345",
    "postbackURL" : "http://castlgame.com/payments/postback";,
    "chargebackURL" : "http://castlegame.com/payments/chargeback";
  }
}, secretKeyFromMarketplace)

The app fetches this JWT from the server and runs this JS code on the client 
when the user clicks buy:

var request = navigator.mozPay([signedJWT]);
request.onsuccess = function() {
  // Poll the server, waiting for a successful postback...
};
request.onerror = function() {
  console.log('Payment failed:', this.error.name);
  // more DOMRequest checking...
};

Note that these success/error handlers on the client are not as useful as the 
server side postback/chargeback handlers. The former is more for UI errors like 
the user clicking the Cancel button. In order to fulfill payment, the developer 
must use a postback handler so she can verify the JWT signature.


TEST PROPOSAL

The developer could test successful payments by amending a JWT like this:

{
  ...
  "request" : {
    "name" : "Unlock Level 10",
    ...
    "simulate": {
      "result": "postback"
    },
  }
}

That is, add a simulate option to the request that describes what to simulate. 
The above code would run against the same production server configured in 
shipping devices (and Firefox OS Simulator). When the server sees the simulate 
option it would never process any payment, it would simply say "Click this 
button to continue the simulation". In this case, that button would do a real 
postback to the app developer's server as if a real payment went through 
successfully. The developer could then test their product delivery mechanism 
without sending a real payment through. Since postbacks receive a copy of the 
original JWT then the dev could detect if it were a test via the simulate 
option.

To simulate an error, the option would be:

{
  "request" : {
    ...
    "simulate": {
      "result": "chargeback",
      "reason": "Insufficient funds"
    },
  }
}

Chargeback reasons aren't very well defined yet but this object model would 
allow us to add properties as needed in the future.

What are your thoughts on this? Either from the developer perspective, the 
server perspective, security-wise, etc. Would there be an easier or alternate 
way for developers to test payments?

One optimization is that we can require developers to generate a special secret 
key just for testing purposes. Thus the developer would not have to store a 
production key on their development/test server. The test key would only allow 
the simulate option and could never be used to process real payments.


thanks, Kumar

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

Reply via email to