• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Archive of obsolete content
  1. MDN
  2. Archive of obsolete content
  3. Marketplace
  4. Monetization
  5. In-app Payments
  6. In-app payments with mozPay

In-app payments with mozPay

In This Article
  1. Overview
  2. Process an in-app payment: step by step
    1. Obtain a payment key for testing
    2. Obtain a real payment key
    3. Set up an application
    4. Set up your server to sign JWTs
    5. Set up a purchase button
    6. Processing postbacks on the server
    7. Responding to postbacks
    8. Processing chargebacks on the server
    9. Postback/chargeback errors
    10. Use HTTPS postback/chargeback URLs
    11. Postback/chargeback IPs
    12. Simulating payments
  3. Debugging errors
  4. Protect the application secret
    1. Revoking a compromised application secret
  5. Code libraries
  6. Sample code
  7. Getting help
  8. Similar payment systems

Marketplace feature removal
The functionality described on this page no longer works — Firefox Marketplace has discontinued support for Android, Desktop, Tablets, and payments (and other related functionality). For more information, read the Future of Marketplace FAQ.

The navigator.mozPay API enables web pages to take payment for digital goods. This article explains how to use the navigator.mozPay API and Web Payment Provider services to process in-app payments.

The fxPay library offers a complete abstraction around mozPay with a more concise, developer friendly API. Consider using fxPay before mozPay.

Overview

Here is an overview of how you add in-app payments to your app and process a transaction:

  • Log in to the Firefox Marketplace Developer Hub.
  • Upload an app, set it up as paid/in-app, and generate an Application Key and an Application Secret.
  • From your app, initiate a payment by signing a JWT request with your secret and calling navigator.mozPay(...).
  • This starts a payment flow in a new window
    • The buyer logs in with their email address.
    • The buyer enters their PIN.
    • The buyer charges the purchase to their phone bill or credit card.
  • Your app receives a JavaScript callback when the buyer closes the window.
  • Your app server receives a signed POST request with a Mozilla transaction ID indicating that the purchase was completed.
  • If the transaction succeeded, you receive money directly deposited to your bank account

The navigator.mozPay API is currently only available on Firefox OS. You can test it with the Firefox OS Simulator.

Process an in-app payment: step by step

This section explains how set up an in-app payment for testing and production.

Obtain a payment key for testing

When you log into the Firefox Marketplace Developer Hub you can visit the In-App Payment Keys page to generate an Application Key and Application Secret for testing. This key will only allow you to simulate in-app payments but this is suitable for testing. You should try out some simulations before you submit your app for review to the Marketplace. Read on for instructions on how to simulate a payment.

Obtain a real payment key

When you submit your working app to the Firefox Marketplace Developer Hub you will be prompted to configure payments. Select the cost of your app (typically free in this case) then mark the option to accept in-app payments. After setting up your bank account details, visit the In-App Payments page to obtain an Application Key and Application Secret for making real payments.

Store the Application Secret securely on your app server in a private settings file or something like that.

Important: Ensure that no one else can read your application secret. Never expose it to the client.

Set up an application

Let's say you are building an adventure game web app and you want to offer a Magical Unicorn for purchase so that players can excel in the game. You want to charge $1.99 or €1.89 or whatever the user's preferred currency is. In the following sections you'll see how to set up a backend server and write frontend code to use navigator.mozPay to sell products.

Set up your server to sign JWTs

A payment is initiated with a JSON Web Token (JWT) and it must be created server side, not client side. This is because the secret key used for signing should never be publicly accessible. Continuing with the example of selling a Magical Unicorn for an adventure game, create a URL on your server like /sign-jwt. This should create a JSON object that defines the product name, the price point, etc. Consult the Web Payment API spec for complete documentation on the JWT format. Here is an example:

{
  "iss": APPLICATION_KEY,
  "aud": "marketplace.firefox.com",
  "typ": "mozilla/payments/pay/v1",
  "iat": 1337357297,
  "exp": 1337360897,
  "request": {
    "id": "915c07fc-87df-46e5-9513-45cb6e504e39",
    "pricePoint": 10,
    "name": "Magical Unicorn",
    "description": "Adventure Game item",
    "icons": {
      "64": "https://yourapp.com/img/icon-64.png",
      "128": "https://yourapp.com/img/icon-128.png"
    },
    "productData": "user_id=1234&my_session_id=XYZ",
    "postbackURL": "https://yourapp.com/payments/postback",
    "chargebackURL": "https://yourapp.com/payments/chargeback",
    "defaultLocale": "en",
    "locales": {
      "de": {
        "name": "Magisches Einhorn",
        "description": "Adventure Game Artikel"
      }
    }
  }
}

Here is an overview of each field:

JWT attribute description
iss (issuer) Application Key that you obtained from the Firefox Marketplace Developer Hub.
aud (audience) The payment provider you want to connect to. To use the production server, always set this to marketplace.firefox.com.
iat (issued at time) A UTC Unix timestamp of when the JWT was issued.
exp (expiration) A UTC Unix timestamp of when the JWT should expire.
nbf (not before time) A UTC Unix timestamp of the earliest time the JWT can be processed.
request.id A unique ID for the product you are selling.
request.pricePoint A valid price point. This will be expanded to a price and currency at the time of purchase.
request.productData Any optional string up to 255 characters. This allows you to reconcile application state when you receive a postback.
request.postbackURL An absolute URL on your server that will receive postbacks. In a production environment, always use HTTPS URLs if possible.
request.chargebackURL An absolute URL on your server that will receive chargebacks. In a production environment, always use HTTPS URLs if possible.
request.icons

An optional object describing icon URLs for the product you are selling. The keys are width/height pixel values (images must be square). Mozilla's Payment Provider will use your 64 pixel image on the payment confirmation page. If you don't specify a 64 pixel image, it will take the largest icon and resize it. The first time someone makes a payment they won't see the icon immediately because the Payment Provider is fetching it in the background; you should see it soon after. If you make changes to the icon, they could take up to 24 hours to appear.

request.defaultLocale A language tag (RFC 4646) to describe the default localization of your in-app product name and description. It is optional unless locales is also defined, in which case it is required.
request.locales An optional object containing one or more localized fields to describe your in-app product. Each locale entry is keyed on a language tag (RFC 4646) and contains the attributes you want to replace. You can only override name and description. If locales is defined then defaultLocale must also be defined.

In Python code (using PyJWT), you could sign and encode the request dictionary shown above like this:

import jwt
signed_request = jwt.encode(request_dict, application_secret, algorithm='HS256')

This code signs a JWT using the application secret and uses the HMAC SHA 256 algorithm. Currently, this is the only supported algorithm. When encoded, it will look something like this:

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.IntcImF1ZFwiOiBcIm1hcmtldHBsYWNlLm1vemlsbGEub3JnXCIsIFwiaXNzXCI6IFwiQVBQLTEyM1wiLCBcInJlcXVlc3RcIjoge1wiY3VycmVuY3lcIjogXCJVU0RcIiwgXCJwcmljZVwiOiBcIjAuOTlcIiwgXCJuYW1lXCI6IFwiVmlydHVhbCAzRCBHbGFzc2VzXCIsIFwicHJvZHVjdGRhdGFcIjogXCJBQkMxMjNfREVGNDU2X0dISV83ODkuWFlaXCIsIFwiZGVzY3JpcHRpb25cIjogXCJWaXJ0dWFsIDNEIEdsYXNzZXNcIn0sIFwiZXhwXCI6IFwiMjAxMi0wMy0yMVQxMTowOTo1Ni43NTMxNDFcIiwgXCJpYXRcIjogXCIyMDEyLTAzLTIxVDEwOjA5OjU2LjgxMDQyMFwiLCBcInR5cFwiOiBcIm1vemlsbGEvcGF5bWVudHMvcGF5L3YxXCJ9Ig.vl4E31_5H3t5H_mM8XA69DqypCqdACVKFy3kXz9EmTI

The encoded/signed JWT can now be used by your app in its client code.

Set up a purchase button

Now that you have a backend to produce a JWT for your product, here's an example of writing frontend code with navigator.mozPay. You would make a button somewhere in your app that lets players purchase the product. For example:

<button id="purchase">Purchase Magical Unicorn</button>

When the purchase button is clicked, your app should sign a JSON Web Token (JWT) and call navigator.mozPay. Here is an example using jQuery:

$('#purchase button').click(function() {
  // The purchase is now pending...
  $.post('/sign-jwt', {})
    .done(function(signedJWT) {
      var request = navigator.mozPay([signedJWT]);
      request.onsuccess = function() {
        waitForPostback();
      };
      request.onerror = function() {
        console.log('navigator.mozPay() error: ' + this.error.name);
      }
    })
    .fail(function() {
      console.error('Ajax post to /sign-jwt failed');
    });
});
function waitForPostback() {
  // Poll your server until you receive a postback with a JWT.
  // If the JWT signature is valid then you can dispurse the Magical Unicorn
  // product to your customer.
  // For bonus points, use Web Sockets :)
}

This code would make an Ajax request to a /sign-jwt URL on your own server. That URL would sign a JSON blob with product/price info and return a JWT in plain text. The Ajax handler would pass that JWT into navigator.mozPay and then wait until the Payment Provider POSTs a purchase confirmation to your server. If the signature on the posted JWT is valid you can deliver the virtual goods to your customer.

Processing postbacks on the server

Before delivering your product, you need to wait for a purchase confirmation from the Marketplace; this is called a postback. The marketplace.firefox.com site sends a POST confirmation notice (a JWT) to the request.postbackURL specified in the original payment request.  The postbackURL must be the URL for a server listening on either port 80 or port 443.

The POST has a Content-Type of application/x-www-form-urlencoded and the JWT can be found in the notice parameter. In your server framework you'll probably access this with something like request.POST['notice'].

This JWT notice contains all the payment request fields plus a transaction ID, and is signed with your application secret that was obtained from the Firefox Marketplace Developer Hub. You can fulfill the purchase when you receive a postback and validate the signature. If you get a JWT whose signature you cannot verify you should ignore it since it probably wasn't sent by the marketplace.

The Web Payment API spec explains what postbacks look like in detail. The postback contains the original request and adds a new response parameter that contains a Mozilla specific transaction ID. Here is an example:

{
  "iss": "marketplace.firefox.com",
  "aud": APPLICATION_KEY,
  "typ": "mozilla/payments/pay/postback/v1",
  "exp": 1337370900,
  "iat": 1337360900,
  "request": {
    "id": "915c07fc-87df-46e5-9513-45cb6e504e39",
    "pricePoint": 10,
    "name": "Magical Unicorn",
    "description": "Adventure Game item",
    "icons": {
      "64": "https://yourapp.com/img/icon-64.png",
      "128": "https://yourapp.com/img/icon-128.png"
    },
    "productData": "user_id=1234&my_session_id=XYZ",
    "postbackURL": "https://yourapp.com/payments/postback",
    "chargebackURL": "https://yourapp.com/payments/chargeback",
    "defaultLocale": "en",
    "locales": {
      "de": {
        "name": "Magisches Einhorn",
        "description": "Adventure Game Artikel"
      }
    }
  },
  "response": {
    "transactionID": "ABCD84294ec6-7352-4dc7-90fd-3d3dd36377e9",
    "price": {"amount": "0.99", "currency": "CAD"}
  }
}

Description of the postback object:

JWT attribute description
iss (issuer) Marketplace notices are issued by marketplace.firefox.com.
aud (audience) Your application is the audience for the notice so this value will be your Application Key.
iat (issued at time) A UTC Unix timestamp of when the JWT was issued.
exp (expiration) A UTC Unix timestamp of when the JWT should expire.
nbf (not before time) A UTC Unix timestamp of the earliest time the JWT can be processed.
request The request object is exactly the same as the one you defined when creating the purchase JWT.
response.transactionID A transaction identifier specific to Mozilla's Web Payment Provider.
response.price An object describing the amount and currency that the customer actually used to make the purchase.

Here are some important notes about the postback:

  • The JWT is signed with your Application Secret
  • Your postback/chargeback URLs must be located either on port 80 or port 443 of your web server. No other ports can be used. This is due to how Mozilla's firewall is configured.

Responding to postbacks

Your application must respond to the postback with a plain text HTTP response including just the transaction ID. For example:

HTTP/1.1 200 OK
Content-Type: text/plain
ABCD84294ec6-7352-4dc7-90fd-3d3dd36377e9

Processing chargebacks on the server

Marketplace will send you a chargeback notice (a POSTed JWT) if something goes wrong while processing the transaction, such as insufficient funds in the buyer's account. Chargebacks will be delivered to the app just like postbacks but they might arrive later on. The POST has a Content-Type of application/x-www-form-urlencoded and the JWT can be found in the notice parameter.  The chargeback must be the URL for a server listening on either port 80 or port 443.

Here is an example of what a decoded chargeback notice might look like:

{
  "iss": "marketplace.firefox.com",
  "aud": APPLICATION_KEY,
  "typ": "mozilla/payments/pay/chargeback/v1",
  "exp": 1337370900,
  "iat": 1337360900,
  "request": {
    "id": "915c07fc-87df-46e5-9513-45cb6e504e39",
    "pricePoint": 10,
    "name": "Magical Unicorn",
    "description": "Adventure Game item",
    "icons": {
      "64": "https://yourapp.com/img/icon-64.png",
      "128": "https://yourapp.com/img/icon-128.png"
    },
    "productData": "user_id=1234&my_session_id=XYZ",
    "postbackURL": "https://yourapp.com/payments/postback",
    "chargebackURL": "https://yourapp.com/payments/chargeback",
    "defaultLocale": "en",
    "locales": {
      "de": {
        "name": "Magisches Einhorn",
        "description": "Adventure Game Artikel"
      }
    }
  },
  "response": {
    "transactionID": "ABCD84294ec6-7352-4dc7-90fd-3d3dd36377e9",
    "reason": "refund"
  }
}

Description of the chargeback object:

JWT attribute description
iss (issuer) Marketplace notices are issued by marketplace.firefox.com.
aud (audience) Your application is the audience for the notice so this value will be your Application Key.
iat (issued at time) A UTC Unix timestamp of when the JWT was issued.
exp (expiration) A UTC Unix timestamp of when the JWT should expire.
nbf (not before time) A UTC Unix timestamp of the earliest time the JWT can be processed.
request The request object is exactly the same as the one you defined when creating the purchase JWT.
response.transactionID A transaction identifier specific to Mozilla's Web Payment Provider.
response.reason An object that describes the chargeback reason. This value will either be set to refund or reversal.
  • A refund means the payment was refunded either upon request of the customer or by an administrator.
  • A reversal is when a buyer asks the credit card issuer to reverse a transaction after it has been completed. The buyer might do this through the credit card company as part of a dispute.

 

NOTE: Refunds are not yet supported for in-app payments.

 

Your application must respond to the chargeback with a plain text HTTP response containing just the transaction ID. For example:

HTTP/1.1 200 OK
Content-Type: text/plain
ABCD84294ec6-7352-4dc7-90fd-3d3dd36377e9

Postback/chargeback errors

If an application server responds to the HTTP request with a non-successful status code then Mozilla's Web Payment Provider will retry the URL several times. If it still doesn't receive a successful response, the app developer will be notified and the app may be temporarily disabled. If the application server does not respond to the postback or chargeback with the transaction ID then it is handled like an error and will be retried, etc.  If you are not seeing requests to your chargeback or postback URL's, make sure that your serve is listening on port 80 or 443.  Mozilla's IAP server will not contact you otherwise.

Use HTTPS postback/chargeback URLs

When running your app in a production environment try to use secure HTTPS URLs if you have the means to do so. This will protect the postback data from being read by a third party when it transits from a Mozilla server to your app server. Using HTTPS is not mandatory to protect the integrity of the payment request, a JWT signature accomplishes that.

Warning: If you do not use secure HTTPS postback URLs, ensure your payment request does not contain personally identifiable information in case it is intercepted by a third party. For example, make sure your productData value does not reveal any sensitive user data. Mozilla never includes personally identifiable information in a payment request by default.

Postback/chargeback IPs

If you are correctly checking the JWT signature as decribed above then there is no need to whitelist IPs of the Firefox Marketplace servers that will send you postback/chargeback notices. However, if you wish to add an extra layer of protection (e.g. against key theft), the Marketplace will send you postback/chargeback notices from the following IP address(es). Any changes to these IP addresses will be announced on the dev-marketplace mailing list.

63.245.216.100

Simulating payments

The intro mentioned how you can obtain a special application key and application secret from the Firefox Marketplace Developer Hub to simulate in-app payments while you are developing and testing your app. Use this secret to sign a custom JWT that looks like this:

{
  "iss": APPLICATION_KEY,
  "aud": "marketplace.firefox.com",
  "typ": "mozilla/payments/pay/v1",
  "iat": 1337357297,
  "exp": 1337360897,
  "request": {
    "id": "915c07fc-87df-46e5-9513-45cb6e504e39",
    "pricePoint": 10,
    "name": "Magical Unicorn",
    "description": "Adventure Game item",
    "icons": {
      "64": "https://yourapp.com/img/icon-64.png",
      "128": "https://yourapp.com/img/icon-128.png"
    },
    "productData": "user_id=1234&my_session_id=XYZ",
    "postbackURL": "https://yourapp.com/payments/postback",
    "chargebackURL": "https://yourapp.com/payments/chargeback",
    "simulate": {
      "result": "postback"
    }
  }
}
JWT attribute description
request.simulate

An object to describe what to simulate. Possible results:

  • postback: simulate a successful purchase
  • chargeback: simulate a chargeback refund

The additional request.simulate attribute tells the payment provider to simulate some result without charging any money. The user interface will not ask for a login or a PIN number either. You can use this while developing your app to make sure your buy button is hooked up correctly to navigator.mozPay and your server postback and chargeback URLs are functioning correctly.

Here is an example that will simulate a successful purchase and send a signed notification to your postback URL:

{
  ...
  "request": {
    ...
    "simulate": {
      "result": "postback"
    }
  }
}

Here is how to simulate a chargeback refund:

{
  ...
  "request": {
    ...
    "simulate": {
      "result": "chargeback",
      "reason": "refund"
    }
  }
}

A JWT notice is posted to your handler just like for a real purchase except you'll receive a randomly generated transactionID. It is okay to use non-HTTPS URLs for simulations.

When you simulate a chargeback, keep in mind that the mozPay onsuccess() callback will be invoked since a chargeback is not an operational error.

Note: Simulated payment JWTs should not be used in production because your customers would be able to obtain free products.

Debugging errors

If you don't use the in-app payment API correctly, the payment screen will show an error that aims to help the user figure out what to do. The payment screen will also include an error code which aims to help you as the developer figure out what to do. You can use Mozilla's Error Legend API to decipher error codes in your own language. For example, the error code INVALID_JWT means the JWT signature is invalid or the JWT is malformed.

Protect the application secret

Warning: Ensure that no one else can read your Application Secret. Never expose it to the client.

Revoking a compromised application secret

In the rare chance that your application secret leaks out or becomes compromised, you need to revoke it as soon as possible. Here's how:

  1. Log in to the Firefox Marketplace.
  2. Navigate to My Submissions and locate your app.
  3. Navigate to the Manage In-App Payments page, which is the same place where you generated your credentials.
  4. Click the Reset Credentials button.

After resetting your credentials, no one will be able to process payments with the old credentials. You will see a new application key and application secret that you can begin using immediately to continue processing payments in your app.

If you need to report any other security issues, please file a bug in the Payments/Refunds component.

Code libraries

Here are libraries specific to Mozilla's navigator.mozPay:

  • Python: mozpay module
  • node.js: mozpay module

To find a secure, up to date JSON Web Token (JWT) library for your favorite language, see jwt.io.

Sample code

  • Here is the source to Web Fighter, a game that implements in-app payments in NodeJS. You can install it from the Marketplace here.
  • Here is a diagnostics and testing app that shows how to sign JWT requests and write postback and chargeback verifier code in Python: In-app Payment Tester

Getting help

  • You can discuss in-app payment related issues on the dev-webapps mailing list or in the #payments channel on irc.mozilla.org.
  • You can file a Marketplace bug in the Payments/Refunds component if you find a bug

Similar payment systems

  • Google's In-App Payments API
  • iOS in-app purchases
  • Android in-App billing API

Document Tags and Contributors

Tags: 
  • Apps
  • Firefox OS
  • In-app
  • Marketplace
  • Web Payment
 Contributors to this page: chrisdavidmills, kumar303, WhyDoINeedAnMDNProfile, teoli, kabirrubel31, .vimrc, rebloor, andymckay, markg, Wraithan, kohei.yoshino, Sheppy, Jeremie, jswisher, mcoates, krupakrupa
 Last updated by: chrisdavidmills, Mar 29, 2016, 2:33:30 AM

  1. .htaccess ( hypertext access )
  2. <input> archive
  3. Add-ons
    1. Add-ons
    2. Firefox addons developer guide
    3. Interaction between privileged and non-privileged pages
    4. Tabbed browser
    5. bookmarks.export()
    6. bookmarks.import()
  4. Adding preferences to an extension
  5. An Interview With Douglas Bowman of Wired News
  6. Apps
    1. Apps
    2. App Development API Reference
    3. Designing Open Web Apps
    4. Graphics and UX
    5. Open web app architecture
    6. Tools and frameworks
    7. Validating web apps with the App Validator
  7. Archived Mozilla and build documentation
    1. Archived Mozilla and build documentation
    2. ActiveX Control for Hosting Netscape Plug-ins in IE
    3. Archived SpiderMonkey docs
    4. Autodial for Windows NT
    5. Automated testing tips and tricks
    6. Automatic Mozilla Configurator
    7. Automatically Handle Failed Asserts in Debug Builds
    8. BlackConnect
    9. Blackwood
    10. Bonsai
    11. Bookmark Keywords
    12. Building TransforMiiX standalone
    13. Chromeless
    14. Creating a Firefox sidebar extension
    15. Creating a Microsummary
    16. Creating a Mozilla Extension
    17. Creating a Release Tag
    18. Creating a Skin for Firefox/Getting Started
    19. Creating a Skin for Mozilla
    20. Creating a Skin for SeaMonkey 2.x
    21. Creating a hybrid CD
    22. Creating regular expressions for a microsummary generator
    23. DTrace
    24. Dehydra
    25. Developing New Mozilla Features
    26. Devmo 1.0 Launch Roadmap
    27. Download Manager improvements in Firefox 3
    28. Download Manager preferences
    29. Drag and Drop
    30. Embedding FAQ
    31. Embedding Mozilla in a Java Application using JavaXPCOM
    32. Error Console
    33. Exception logging in JavaScript
    34. Existing Content
    35. Extension Frequently Asked Questions
    36. Fighting Junk Mail with Netscape 7.1
    37. Firefox Sync
    38. Force RTL
    39. GRE
    40. Gecko Coding Help Wanted
    41. HTTP Class Overview
    42. Hacking wiki
    43. Help Viewer
    44. Helper Apps (and a bit of Save As)
    45. Hidden prefs
    46. How to Write and Land Nanojit Patches
    47. Introducing the Audio API extension
    48. Java in Firefox Extensions
    49. JavaScript crypto
    50. Jetpack
    51. Litmus tests
    52. Makefile.mozextension.2
    53. Microsummary topics
    54. Migrate apps from Internet Explorer to Mozilla
    55. Monitoring downloads
    56. Mozilla Application Framework
    57. Mozilla Crypto FAQ
    58. Mozilla Modules and Module Ownership
    59. Mozprocess
    60. Mozprofile
    61. Mozrunner
    62. Nanojit
    63. New Skin Notes
    64. Persona
    65. Plug-n-Hack
    66. Plugin Architecture
    67. Porting NSPR to Unix Platforms
    68. Priority Content
    69. Prism
    70. Proxy UI
    71. Remote XUL
    72. SXSW 2007 presentations
    73. Space Manager Detailed Design
    74. Space Manager High Level Design
    75. Standalone XPCOM
    76. Stress testing
    77. Structure of an installable bundle
    78. Supporting private browsing mode
    79. Table Cellmap
    80. Table Cellmap - Border Collapse
    81. Table Layout Regression Tests
    82. Table Layout Strategy
    83. Tamarin
    84. The Download Manager schema
    85. The life of an HTML HTTP request
    86. The new nsString class implementation (1999)
    87. TraceVis
    88. Treehydra
    89. URIScheme
    90. URIs and URLs
    91. Using Monotone With Mozilla CVS
    92. Using SVK With Mozilla CVS
    93. Using addresses of stack variables with NSPR threads on win16
    94. Venkman
    95. Video presentations
    96. Why Embed Gecko
    97. XML in Mozilla
    98. XPInstall
    99. XPJS Components Proposal
    100. XRE
    101. XTech 2005 Presentations
    102. XTech 2006 Presentations
    103. XUL Explorer
    104. XULRunner
    105. ant script to assemble an extension
    106. calICalendarView
    107. calICalendarViewController
    108. calIFileType
    109. xbDesignMode.js
  8. Archived open Web documentation
    1. Archived open Web documentation
    2. Browser Detection and Cross Browser Support
    3. Browser Feature Detection
    4. Displaying notifications (deprecated)
    5. E4X
    6. E4X Tutorial
    7. LiveConnect
    8. MSX Emulator (jsMSX)
    9. Old Proxy API
    10. Properly Using CSS and JavaScript in XHTML Documents
    11. Reference
    12. Scope Cheatsheet
    13. Server-Side JavaScript
    14. Sharp variables in JavaScript
    15. Standards-Compliant Authoring Tools
    16. Using JavaScript Generators in Firefox
    17. Window.importDialog()
    18. Writing JavaScript for XHTML
    19. XForms
    20. background-size
    21. forEach
  9. B2G OS
    1. B2G OS
    2. Automated Testing of B2G OS
    3. B2G OS APIs
    4. B2G OS add-ons
    5. B2G OS architecture
    6. B2G OS build prerequisites
    7. B2G OS phone guide
    8. Building B2G OS
    9. Building and installing B2G OS
    10. Building the B2G OS Simulator
    11. Choosing how to run Gaia or B2G
    12. Customization with the .userconfig file
    13. Debugging on Firefox OS
    14. Developer Mode
    15. Developing Firefox OS
    16. Firefox OS Simulator
    17. Firefox OS apps
    18. Firefox OS board guide
    19. Firefox OS developer release notes
    20. Firefox OS security
    21. Firefox OS usage tips
    22. Gaia
    23. Installing B2G OS on a mobile device
    24. Introduction to Firefox OS
    25. Mulet
    26. Open web apps quickstart
    27. Pandaboard
    28. PasscodeHelper Internals
    29. Porting B2G OS
    30. Preparing for your first B2G build
    31. Resources
    32. Running tests on Firefox OS: A guide for developers
    33. The B2G OS platform
    34. Troubleshooting B2G OS
    35. Using the App Manager
    36. Using the B2G emulators
    37. Web Bluetooth API (Firefox OS)
    38. Web Telephony API
    39. Web applications
  10. Beginner tutorials
    1. Beginner tutorials
    2. Creating reusable content with CSS and XBL
    3. Underscores in class and ID Names
    4. XML data
    5. XUL user interfaces
  11. Case Sensitivity in class and id Names
  12. Creating a dynamic status bar extension
  13. Creating a status bar extension
  14. Gecko Compatibility Handbook
  15. Getting the page URL in NPAPI plugin
  16. Index
  17. Inner-browsing extending the browser navigation paradigm
  18. Install.js
  19. JXON
  20. List of Former Mozilla-Based Applications
  21. List of Mozilla-Based Applications
  22. Localizing an extension
  23. MDN
    1. MDN
    2. Content kits
  24. MDN "meta-documentation" archive
    1. MDN "meta-documentation" archive
    2. Article page layout guide
    3. Blog posts to integrate into documentation
    4. Current events
    5. Custom CSS classes for MDN
    6. Design Document
    7. DevEdge
    8. Developer documentation process
    9. Disambiguation
    10. Documentation Wishlist
    11. Documentation planning and tracking
    12. Editing MDN pages
    13. Examples
    14. Existing Content/DOM in Mozilla
    15. External Redirects
    16. Finding the right place to document bugs
    17. Getting started as a new MDN contributor
    18. Landing page layout guide
    19. MDN content on WebPlatform.org
    20. MDN page layout guide
    21. MDN subproject list
    22. Needs Redirect
    23. Page types
    24. RecRoom documentation plan
    25. Remove in-content iframes
    26. Team status board
    27. Trello
    28. Using the Mozilla Developer Center
    29. Welcome to the Mozilla Developer Network
    30. Writing chrome code documentation plan
    31. Writing content
  25. MMgc
  26. Makefile - .mk files
  27. Marketplace
    1. Marketplace
    2. API
    3. Monetization
    4. Options
    5. Publishing
  28. Mozilla release FAQ
  29. Newsgroup summaries
    1. Newsgroup summaries
    2. Format
    3. Mozilla.dev.apps.firefox-2006-09-29
    4. Mozilla.dev.apps.firefox-2006-10-06
    5. mozilla-dev-accessibility
    6. mozilla-dev-apps-calendar
    7. mozilla-dev-apps-firefox
    8. mozilla-dev-apps-thunderbird
    9. mozilla-dev-builds
    10. mozilla-dev-embedding
    11. mozilla-dev-extensions
    12. mozilla-dev-i18n
    13. mozilla-dev-l10n
    14. mozilla-dev-planning
    15. mozilla-dev-platform
    16. mozilla-dev-quality
    17. mozilla-dev-security
    18. mozilla-dev-tech-js-engine
    19. mozilla-dev-tech-layout
    20. mozilla-dev-tech-xpcom
    21. mozilla-dev-tech-xul
    22. mozilla.dev.apps.calendar
    23. mozilla.dev.tech.js-engine
  30. Obsolete: XPCOM-based scripting for NPAPI plugins
  31. Plugins
    1. Plugins
    2. Adobe Flash
    3. External resources for plugin creation
    4. Logging Multi-Process Plugins
    5. Monitoring plugins
    6. Multi-process plugin architecture
    7. NPAPI plugin developer guide
    8. NPAPI plugin reference
    9. Samples and Test Cases
    10. Shipping a plugin as a Toolkit bundle
    11. Supporting private browsing in plugins
    12. The First Install Problem
    13. Writing a plugin for Mac OS X
    14. XEmbed Extension for Mozilla Plugins
  32. SAX
  33. Security
    1. Security
    2. Digital Signatures
    3. Encryption and Decryption
    4. Introduction to Public-Key Cryptography
    5. Introduction to SSL
    6. NSPR Release Engineering Guide
    7. SSL and TLS
  34. Solaris 10 Build Prerequisites
  35. Sunbird Theme Tutorial
  36. Table Reflow Internals
  37. Tamarin Tracing Build Documentation
  38. The Basics of Web Services
  39. Themes
    1. Themes
    2. Building a Theme
    3. Common Firefox theme issues and solutions
    4. Creating a Skin for Firefox
    5. Making sure your theme works with RTL locales
    6. Theme changes in Firefox 2
    7. Theme changes in Firefox 3
    8. Theme changes in Firefox 3.5
    9. Theme changes in Firefox 4
  40. Updating an extension to support multiple Mozilla applications
  41. Using IO Timeout And Interrupt On NT
  42. Using SSH to connect to CVS
  43. Using workers in extensions
  44. WebVR
    1. WebVR
    2. WebVR environment setup
  45. XQuery
  46. XUL Booster
  47. XUL Parser in Python