Business, Chrome, JavaScript, webdev

In-App Payments On The Web

payment-with-penThere are many examples of applications that are free but let you add features with in-app payments. Think of a game that is free to play, but offers additional levels or virtual goods for a certain price (a low one in most cases). It’s very common to see applications that are free at the ‘trial period’ and later gives premium users the option to buy a specific level that match their needs. It’s a good practice to give users your product or service without any barriers (e.g credit card information). If they find it useful, they will pay for it with a smile.

Few examples

  • A designing web app that give the options to buy more projects (or more shapes, tools, features).
  • A Customer Relationship Management (CRM) application, that offer certain capabilities for a price.
    The basic options to collect and manage your contacts will be free, but if you wish to send emails they will charge you.
  • A game that let you advances more quickly if you buy certain improvements. For example a ‘magic’ power that give you the ability to pass a difficult stage (e.g. the mighty eagle in Angry Birds).the mighty eagle from angry birds


There are few options to create this ability: Stripe, PayPal and others. These services give the developer an SDK or a REST APIs that handle everything from authentication to payments and invoices.


We choose to show an in-app payment example with Mozilla experiment payment API.
Psst… This feature is not on a current W3C standards track, but it is supported on the Firefox OS platform. Although implementations may change in the future and it is not supported widely across browsers, it is suitable for use in code dedicated to Firefox OS apps.
If you wish a more generic solution that will work on many modern web browsers, check out: how to implement web payments.

Here are the steps:

  • 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 special window
    • The buyer logs in with Mozilla Persona (if not logged in.)
    • The buyer enters their PIN.
    • The buyer charges the purchase to her 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 successfully
  • You receive money directly deposited to your bank account.


// Typically you would attach this to the click handler on a Buy button.
purchaseSomething("Buy a new mountain bike! Something that is 29' in yellow - please!");
function purchaseSomething(productID) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
// Prepare to send a productID to your server and
// receive an array of JSON Web Token (=jwts) that describe your data'POST', '/create_jwts');
xhr.addEventListener('load', function () {
// Retrieve the JSON Web Token and a transactionID from a JSON response,
// Such as:
// {"jwts": ["jwt1...", "jwt2..."], "transactionID": "1234"}
var jwts = xhr.response.jwts;
var transactionID = xhr.response.transactionID;
// Pass the JSON Web Tokens to the payment provider
var request = navigator.mozPay(jwts);
// Set up the success/error handler for the payment window.
request.onsuccess = function () {
console.log('The user payment flow completed successfully! Go ride!');
// Although the payment flow completed, you need to poll your server and wait
// for a verified payment result to be sure the payment went through.
request.onerror = function () {
console.log(':( Sorry, the payment flow had an error:',;
// Initiate the payment request by sending information to
// get the signed JSON Web Tokens. In our example, productID
// is the ID of the product the user wants to puchase.
function waitForPaymentResult(transactionID) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
// Prepare to check if a postback/chargeback has been received for transactionID.'GET', '/payment_result/' + transactionID);
xhr.addEventListener('load', function () {
// Retrieve the result, such as:
// {"result": "postback received"} or {"result": "still waiting"}
if (xhr.response.result == 'postback received') {
// A postback notice was received and you verified the incoming JWT signature.
console.log('Success! The product has been purchased');
} else {
// No postback/chargeback has been sent to your server yet. Try again in 3 seconds.
window.setTimeout(function() { waitForPaymentResult(transactionID); }, 3000);
// Send the request to check the transactionID status.

For a list of the best practices for eCommerce, check this post at the bottom.

Happy payments!

#monetization on the web rock. 


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s