At first glance the Firefox Marketplace for Firefox OS may look similar to the Apple Store or Google Play Store but there is a key difference: it does not lock you into Mozilla or lock you into your Firefox OS phone. It enables you to sell a web app that will run on any open web device by way of the receipt protocol. Non-Mozilla marketplaces can participate in selling apps on Firefox OS out of the box by implementing the receipt format and users won’t notice anything different when running a paid app from either store.

When other devices support the receipt protocol then theoretically you could pay for an app once and run it everywhere. There is, of course, a chicken vs. egg problem here so Mozilla hopes to be the egg that helps prove out the decentralized receipt concept and iterate on the protocol. Mozilla invites other vendors to help us work on getting receipts right so that paid apps are as portable and “webby” as possible.

For Developers

It’s the responsibility of each paid app to validate its own receipt. If you’re a developer thinking about selling your app on Firefox OS, this post should give you a head start on implementing the receipt validation bits. This post may also be interesting for those who wish to build a compliant web runtime or a compliant marketplace.

The navigator.mozApps JavaScript API exposes device receipts to your application. The simplest way to validate a receipt is to include a client side library like receiptverifier.js and use the hosted verification service URL found in the receipt. The receiptverifer docs go into detail but it’s as easy as calling this JavaScript code when your app starts up:

That’s it! This is a high-level shortcut that also displays a prompt on the screen within your app if the receipt is missing or invalid. The docs for the verifier show how to do low-level validation.

For a more complete example, you can check out the code to the Private Yacht app which we’ve been using in testing. This app shows you how to do client side checking with the receiptverifier.js library as well as server side checking via Node.js. We also have a Python library (and one specifically for Django) that you can use on a server to check receipts.

How does it work? Each receipt is a mash up of JSON Web Tokens. One of the properties is a link to a hosted verification service that you can use to check the receipt. You also have the option of verifying receipts offline but this requires periodic key synchronization and some details like refund and reissue handling are not well supported yet for offline validation.

By default, a receipt is only allowed to originate from one of the store URLs in the installs_allowed_from parameter in your app’s manifest. As a developer you’ll create explicit payout relationships with each marketplace and will thus want to limit who can claim to sell your app. This acts as a whitelist for who can provide receipts for your app. Due to the loose nature of client side JavaScript, you can get tighter control over this whitelist by validating receipts server side (that is, on your own app server).

Paid apps for Firefox Marketplace aren’t fully live yet but they’re coming very soon. If you integrate a receipt checker into your app now, you’ll be ready when the submission flow supports payments.

Fraud Protection

Enabling any party on the web to sell apps is crucial to Mozilla’s vision of open web apps. However, making receipts decentralized while fully protecting app assets (without DRM) is challenging. There are currently attacks users can use in their clients, like a DNS proxy, to access paid apps but there is mitigation to this with CSP, CORS, and HSTS, just to name a few. The state of today’s paid iOS / Android apps is actually not much different. There is an open issue right now that will help make marketplace whitelists more effective and Mozilla expects to evolve the system further as more developers and more stores participate. Switching to a signed, packaged app may also offer another layer of asset protection but this was designed more to address permission issues.

As always, if you run into issues please file bugs! If it’s an Apps platform bug select Core (component: DOM: Apps) or select Marketplace (component: Payments/Refunds).