Giter Club home page Giter Club logo

fxpay's Introduction

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.

fxpay's People

Contributors

kumar303 avatar

Watchers

anita avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.