mozpay

fulfill web payments with navigator.mozPay()

npm install mozpay
14 downloads in the last month
<h1>mozpay</h1>

<p>This is a NodeJS module for processing
<a href="https://wiki.mozilla.org/WebAPI/WebPayment">navigator.mozPay()</a> payments on a
server.</p>

<p>You'll need to obtain a secret key from a provider such as the
<a href="https://marketplace.firefox.com/">Firefox Marketplace</a>
but this module should work with any compliant
<a href="https://wiki.mozilla.org/WebAPI/WebPaymentProvider">provider</a>.
Here is a guide to
<a href="https://developer.mozilla.org/en-US/docs/Apps/Publishing/In-app_payments">setting up payments</a>
with Firefox Marketplace.</p>

<p>The basic payment flow goes like this:</p>

<ul>
<li>A user clicks a buy button on your app</li>
<li>Your app signs a <a href="http://openid.net/specs/draft-jones-json-web-token-07.html">JSON Web Token (JWT)</a>
describing the product, the price, and postback/chargeback URLs.</li>
<li>Your app client fetches the JWT from the server and calls <code>navigator.mozPay()</code></li>
<li>Your server receives a JWT at its postback or chargeback URL</li>
<li>If the postback was received and the JWT signature validates against your secret
key then you can disburse your product.</li>
</ul>

<h2>Install</h2>

<pre><code>npm install mozpay
</code></pre>

<h2>Configuration</h2>

<p>The module is intended to be used server side only because you can't expose
your secret key to the client. There are helpers to hook into an
<a href="http://expressjs.com/">express</a> app but you could probably use other web frameworks too.</p>

<p>Load the module:</p>

<pre><code>var pay = require('mozpay');
</code></pre>

<p>Configure it when your app starts up:</p>

<pre><code>pay.configure({
  // This is your Application Key from the Firefox Marketplace Devhub.
  mozPayKey: '52ee5d47-9981-40ad-bf6e-bca957f65385',
  // This is your Application Secret from the Firefox Marketplace Devhub.
  mozPaySecret: 'd6338705419ea14328084e0c182603ebec4e52c1c6cbceda4d61ee125f10c0f728c4451a4637e4e960b3293df8bb6ac5',
  // This is the aud (audience) in the JWT. You only need to override this if you want to use a dev server.
  mozPayAudience: 'marketplace.firefox.com',
  // This is an optional prefix to your postback/chargeback URLs.
  // For example, a postback would be available at https://yourapp/mozpay/postback with the default prefix.
  mozPayRoutePrefix: '/mozpay',
  // Set a custom payment type for JWTs. You only need to override this if
  // you're working with a non-default payment provider.
  mozPayType: 'mozilla/payments/pay/v1'
});
</code></pre>

<p>With an <a href="http://expressjs.com/api.html#express">express app object</a>, add your routes:</p>

<pre><code>var express = require('express');
var pay = require('mozpay');
var app = express();

app.configure(function(){
  // Make sure you turn on the body parser for POST params.
  app.use(express.bodyParser());
});

pay.routes(app);
</code></pre>

<p>You can test your postback/chargeback URLs with something like this:</p>

<pre><code>curl -X POST -d notice=JWT http://localhost:3000/mozpay/postback
curl -X POST -d notice=JWT http://localhost:3000/mozpay/chargeback
</code></pre>

<p>If you see a 400 Bad Request response then your app is configured to receive
real JWT requests.</p>

<p>You can combine the configuration and routes setup like this:</p>

<pre><code>pay.routes(app, {
  mozPayKey: '52ee5d47-9981-40ad-bf6e-bca957f65385',
  mozPaySecret: 'd6338705419ea14328084e0c182603ebec4e52c1c6cbceda4d61ee125f10c0f728c4451a4637e4e960b3293df8bb6ac5',
  // ...
});
</code></pre>

<h2>Events</h2>

<p>Here's how to take action when the postback notices are
received. The <code>data</code> argument to these event handlers are only for valid JWT
notices that pass the signature verification.</p>

<pre><code>pay.on('postback', function(data) {
  console.log('product ID ' + data.request.id + ' has been purchased');
  console.log('Transaction ID: ' + data.response.transactionID);
});

pay.on('chargeback', function(data) {
  console.log('product ID ' + data.request.id + ' failed');
  console.log('reason: ' + data.response.reason);
  console.log('Transaction ID: ' + data.response.transactionID);
});
</code></pre>

<p>The <code>data.request</code> object is a copy of what you initiated the payment request
with.</p>

<h2>Issuing Payment Requests</h2>

<p>When a user clicks the buy button you should fetch a JWT from the server via
Ajax. You can't cache JWTs for too long because they have a short expiration
(generally about an hour).</p>

<p>There is a helper to created a JWT to begin a payment.
On your server create a URL that does something like this:</p>

<pre><code>var jwt = pay.request({
  id: 'your-unique-product-id',
  name: 'Your Product',
  description: 'A little bit more about the product...',
  pricePoint: 1,  // Consult the Firefox Marketplace price points for details.
                  // This expands to a price/currency at the time of payment.
  productData: 'session_id=xyz',  // You can track whatever you like here.
  // These must be absolute URLs like what you configured above.
  postbackURL: 'http://localhost:3000/mozpay/postback',
  chargebackURL: 'http://localhost:3000/mozpay/chargeback'
});
</code></pre>

<p>In your client-side JavaScript, you can initiate a payment with the JWT like
this:</p>

<pre><code>var request = navigator.mozPay([jwtFromServer]);
request.onsuccess = function() {
  console.log('navigator.mozPay() finished');
  // The product has not yet been bought!
  // Poll your server until a valid postback has been received.
  waitForPostback();
}
request.onerror = function() {
  console.log('navigator.mozPay() error: ' + this.error.name);
};
</code></pre>

<h2>Developers</h2>

<p>Grab the <a href="https://github.com/mozilla/mozpay-js">source</a>:</p>

<pre><code>git clone git://github.com/mozilla/mozpay-js.git
</code></pre>

<p>Install the dependencies:</p>

<pre><code>cd mozpay-js
npm install
</code></pre>

<p>Here's how to run the tests:</p>

<pre><code>npm test
</code></pre>
npm loves you