Skip to content
/ fxpay Public
forked from mozilla/fxpay

JavaScript library for Firefox Marketplace payments

License

Notifications You must be signed in to change notification settings

anitagao/fxpay

 
 

Repository files navigation

fxpay

A JavaScript library for Firefox Marketplace payments.

https://travis-ci.org/mozilla/fxpay.png?branch=master

This is a helper library for web apps to accept in-app payments on Firefox OS without hosting their own server. The in-app payments guide provides a deep dive into the underlying APIs and concepts. However, by using this library you can skip a lot of that. This is a wrapper around the in-app payment services offered by the Firefox Marketplace API which make it easier to do in-app payments.

Topics

This library is experimental.

Only consider using this library if you want to help us iron out bugs and if you don't mind dealing with API changes.

This tracker bug will keep you up to date on our progress: https://bugzilla.mozilla.org/show_bug.cgi?id=944480

To use fxpay to accept in-app payments, the following requirements must be met:

  • Your application must run in Firefox OS 1.1 or greater.

  • Your manifest must declare an origin for receipt validation.

  • You must declare the following permission in your manifest to talk to the Marketplace API:

    "permissions": {
      "systemXHR": {
        "description": "Required to access payment API"
      }
    }
    
  • Your application must be a privileged packaged app so it can be signed and granted proper permissions.

The example app, explained below, shows you how to set all this up.

If you'd like to see a working example of fxpay, you're in luck. We built one here: https://github.com/mozilla/fxpay/tree/master/example

The README on that page has instructions for how to install the example app on a Firefox OS device; the app can also be used to test fxpay and associated APIs.

Include this repository as a git submodule in your web app so you can load the script at lib/fxpay.js. When the lib is more stable we'll add support for script / package managers. See the Developers section below if you want to minimize it first.

Log into the Firefox Marketplace Developer Hub. There will be a page where you can enter the names and prices for each of your products. These docs will be updated with a link when the page is working :)

When you create a product on the Developer Hub you'll get a unique identifier, such as 543123. You'll use this ID number to reference the product when working with the fxpay library.

When your app starts up, you need to initialize fxpay so it can check for any existing product receipts. This is also your chance to register some callbacks for general error handling and other events.

Example:

fxpay.init({
  appId: 123,  // your app ID from the Developer Hub.
  onerror: function(error) {
    console.error('An error occurred:', error);
  },
  oninit: function() {
    console.log('fxpay initialized without errors');
  },
  onrestore: function(error, info) {
    // If error is null, info.productId has been restored from receipt.
  }
});

fxpay.init() will look for any receipts on device and validate them. If a receipt is valid then it means the user has already purchased the product so you should restore it.

The onrestore callback will be invoked for each product restored. The first argument is an error string which may be null. The second argument is a product info object which may also be null for certain errors.

You initialize the callback like this:

fxpay.init({
  onrestore: function(error, info) {
    if (error) {
      console.error('Error', error,
                    'while restoring receipt for', info.productId);
    } else {
      console.log('product', info.productId,
                  'was restored from receipt');
    }
  }
});

Upon initialization you must pass in your Firefox Marketplace Developer Hub application ID like this:

fxpay.init({
  appId: 123,
  // ...
});

This allows fxpay.init() to reject any valid receipts belonging to other apps, such as one that a user might have copied from another app.

To disable this check and allow any receipt belonging to any app, you can use configuration to set allowAnyAppReceipt = true.

You can call fxpay.purchase() to start the buy flow for an item. First, you'll probably want to make a screen in your app where you offer some product for purchase. Create a buy button that when tapped, calls fxpay.purchase() like this:

var productId = 543123;

fxpay.purchase(productId, function(error, info) {
  if (error) {
    throw error;
  }

  console.log('product', info.productId, 'was purchased and verified!');
  // ***************************************************
  // It is now safe to deliver the product to your user.
  // ***************************************************
});

The purchase callback will receive an error string which might be null and a product info object. The callback is invoked after the user completes the buy flow and the Marketplace server has verified the receipt so at this time it is safe to deliver the item.

How does this work? The fxpay.purchase() function automates the process of calling mozPay() then waiting for and verifying an incoming JWT signature. If you want to know the specifics, see the in-app payments guide but that's not mandatory for using the fxpay library.

The purchase and onrestore callbacks receive a product info object. This object has the following properties:

info.appId
The ID of the application that owns this product.
info.productId
The ID number of the product. This corresponds to the ID number you see in the Firefox Marketplace Developer Hub when managing your products.

Errors come back to you as the first argument to the onerror(error) callback that was passed to fxpay.init() or as the first argument to the fxpay.purchase() callback. The errors are strings and are meant to be treated like readable codes that you can map to localized text, etc. A detailed error explanation will be logged; read on for logging details.

Here are the possible error strings you might receive and what they mean:

API_REQUEST_ABORTED
An HTTP request to the API was aborted.
API_REQUEST_ERROR
An HTTP request to the API resulted in an error.
API_REQUEST_TIMEOUT
The API did not respond to a request before the timeout was reached.
BAD_API_RESPONSE
The API responded with a non-successful status code.
BAD_JSON_RESPONSE
The API unexpectedly responded with unparseable JSON.
DIALOG_CLOSED_BY_USER
The user closed their payment window before completing the purchase. You can probably ignore this error or maybe display a cancelled message. This error comes from mozPay().
INCORRECT_USAGE
An fxpay function was used incorrectly. Check the console for details.
INVALID_TRANSACTION_STATE
The transaction was in an invalid state and cannot be processed.
NOT_INITIALIZED
The library was not initialized correctly; no actions can be performed. This might mean you didn't call init() or it could mean there was an uncaught exception. Check the console for details.
NOT_INSTALLED_AS_APP
This platform supports apps but the app has not been installed on device. This could happen if it was accessed directly from the browser.
PAY_PLATFORM_UNAVAILABLE
This platform does not support payments. This could mean the navigator.mozApps namespace or the mozPay() function is unavailable or the Apps.addReceipt method doesn't exist.
TRANSACTION_TIMEOUT
The HTTP request to check the transaction state timed out.
USER_CANCELLED
The user cancelled the purchase. You can probably ignore this error or maybe display a cancelled message. This error comes from mozPay().

Additionally, your callback may receive one of the App error strings such as INVALID_MANIFEST.

By default, fxpay logs everything using window.console. If you want to replace console with your own logger, pass in an object as log that implements the same window.console methods:

fxpay.configure({
  log: myConsole
});

You can call fxpay.configure(overrides) to set some internal variables. If you call this repeatedly, the old keys will be preserved unless overidden.

Example:

fxpay.configure({log: myCustomLog});

Possible overrides:

allowAnyAppReceipt
If true, the receipt will not be marked invalid when it's for someone else's app. Default: false.
appId
Your Firefox Marketplace Developer Hub application ID.
apiUrlBase
The base URL of the internal fxpay API. Default: https://marketplace.firefox.com.
apiTimeoutMs
A length of time in milleseconds until any API request will time out. Default: 10000.
apiVersionPrefix
A Path that gets appended to apiUrlBase to access the right API version. Default: /api/v1.
log
A log object compatible with window.console to use internally. Default: window.console.
receiptCheckSites
Array of sites allowed to verify purchase receipts. These values are top level URLs to verifier services; they don't need to include URL paths. You would only need to adjust this if you want to work with something other than the production version of Firefox Marketplace. Default: ['https://receiptcheck.marketplace.firefox.com'].

To hack on this library you need NodeJS and npm installed. When you clone the source, all other dependencies are included for you. However, you need to build a few things. Run this:

npm rebuild

To execute scripts, you should add the local .bin directory to your $PATH:

PATH="./node_modules/.bin:${PATH}"
export PATH

This is pretty standard for any Node project so you you might already have it.

From a source checkout, run all tests and lint checks like this:

npm test

To run the JavaScript unit tests continuously while you are developing, type:

grunt karma:dev

This opens a web browser and will report test results to your console. As you edit a code file, it will re-run the tests.

To fire off a single test run with a browser and see the results, type:

grunt karma:run

To check for syntax errors (lint), run:

grunt jshint

To build yourself a compressed version of fxpay.js, run this:

grunt compress

The compressed source file will appear in the build directory.

About

JavaScript library for Firefox Marketplace payments

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published