npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@elm-street-technology/recurring

v2.8.1

Published

a recurly v2 api client for node.js

Downloads

8

Readme

A node client for recurly's v2 api, with support for secure parameter signing for recurly.js embedded forms.

on npm Tests Dependencies io.js supported

This code is still in development. We do not have complete coverage of the API yet.

The recurly API has a number of different versions. In order to provide clarity as to which version of the recurly API this package supports, we aim to keep our release versions in sync with the recurly versioning scheme.

The following versions of the recurring package are currently supported:

| Recurly API version | NPM dist-tag | Git development branch | -------------------- | --------------------- | ----------------------- | 2.7 | recurly-v2.7 (latest) | 2.7 (master) | 2.3 | recurly-v2.3 | 2.3

Recurly API

An example of typical usage:

var Recurring = require('recurring');
var recurly = new Recurring();

recurly.setAPIKey('your-api-key');
recurly.setRateLimit(400);
recurly.setCache(false);

var account = recurly.Account();
account.id = 'account-uuid';
account.fetch(function(err) {
  account.fetchSubscriptions(function(err, subscriptions {
    subscriptions[0].cancel(function(err, updated) {
      console.log(updated.state); // will be 'canceled'
    });
  });
});

recurly.Account.all(function(err, accounts) {
  // accounts is an array containing all customer accounts
});

recurly.Plan.all(function(err, plans) {
  // plans is an array containing all plans set up for your account
});

Configuration

recurly.setAPIKey()
In order to access the Recurly API you must supply your API key which can be setterFunc by calling the setAPIKey() method.

var Recurring = require('recurring');
var recurly = new Recurring();
recurly.setAPIKey('your-api-key');

recurly.setRateLimit()
The recurly API has a rate limit policy in place that prevents excessive calls being made to the API. By default sandbox accounts have a limit of 400 requests per minute and live accounts have a limit of 1000 requests per minute. In order to help ensure that you do not exceed these limits Recurring provides a configurable rate limiter. The rate limiter can be configured by calling the setRateLimit() method.

var Recurring = require('recurring');
var recurly = new Recurring();
recurly.setRateLimit(400);

recurly.setCache()

Basic in memory result caching can be enabled by calling the setCache() method so that subsequent requests to fetch the same data does not result in additional API calls to Recurly.

var Recurring = require('recurring');
var recurly = new Recurring();
recurly.setCache(true);

recurly.clearCache()

The recurly result cache can be cleared by calling the clearCache() method.

var Recurring = require('recurring');
var recurly = new Recurring();
recurly.clearCache();

All data types

Recurly is not consistent about how it names the ID fields for each data type. For some it's uuid and for others foo_code. Recurring hides this away: every data type has an id property that sets the correct field name for Recurly.

instance.create()
Create an object of the given type by POSTing to Recurly.

DataType.create(optionsHash, function(err, object));

instance.fetch()
Fetch an item of a given type from Recurly. The item must have an id.

instance.fetch(function(err, instance))

instance.destroy()
Destroy, delete, close, cancel, or otherwise remove the specified object. Invokes http DELETE on the item's href. The item must have an id.

instance.destroy(function(err));

instance.update()
Most data types have an update() method that changes the stored data.

instance.update(options, function(err, updated));

Plan

Plan.all()
Fetch a list of plans. Responds with an array of all plans that match the passed-in (optional) filters.

Plan.all(filter, function(err, plans));

Plan.iterator()
Fetch a list of plans. Responds with an async iterator that lazy loads data from recurly in batches of 200.

var iterators = require('async-iterators');
var iterator = Plan.iterator();
iterators.forEachAsync(iterator, function (err, data, next) {
  ...
  next();
});

plan.fetchAddOns()
Fetch plan addons. Responds with a array of plan addons.

plan.fetchAddOns(function(err, addons));

Account

Account.all()
Fetch a list of accounts. Responds with an array of all accounts that match the passed-in (optional) filters.

Account.all(filter, function(err, accounts));

Account.iterator()
Fetch a list of accounts. Responds with an async iterator that lazy loads data from recurly in batches of 200.

var iterators = require('async-iterators');
var iterator = Account.iterator();
iterators.forEachAsync(iterator, function (err, data, next) {
  ...
  next();
});

account.close()
Close an account. Alias for delete.

account.close(function(err));

account.reopen()
Reopen a closed account:

account.reopen(function(err, updated));

account.fetchAdjustments() Fetch adjustment information for an account. Responds with an array of adjustments for this account.

account.fetchAdjustments(function(err, adjustments));

account.fetchBillingInfo()
Fetch billing information for an account. Responds with an BillingInfo object.

account.fetchBillingInfo(function(err, info));

account.fetchSubscriptions()
Fetch subscription information for an account. Responds with an array of subscriptions for this account.

account.fetchSubscriptions(function(err, subscriptions));

account.fetchTransactions()
Fetch transaction information for an account. Responds with an array of transactions for this account.

account.fetchTransactions(function(err, transactions));

account.fetchInvoices()
Fetch invoice information for an account. Responds with an array of invoices for this account.

account.fetchInvoices(function(err, invoices));

Billing Info

billingInfo.update()
Add/update billing information for an account.

binfo = recurly.BillingInfo();
binfo.account_code = '1234';
var billing_data = {
  first_name: 'Dummy',
  last_name: 'User',
  number: '4111-1111-1111-1111',
  month: 1,
  year: 2020,
  verification_value: '123',
  address1: '760 Market Street',
  address2: 'Suite 500',
  city: 'San Francisco',
  state: 'CA',
  country: 'USA',
  zip: '94102'
};

binfo.update(billing_data, function(err, binfo) {
  demand(err).not.exist();
  binfo.last_four.must.equal('1111');
});

Using a billing token

You can also update billing information using a recurly.js billing token in place of the raw billing information (recommended)

binfo = recurly.BillingInfo();
binfo.account_code = '1234';
var billing_data = {
  token_id: 'bunYTdIdjfJJY6Z87j5NtA' // <- recurly.js billing token.
};
binfo.update(billing_data);

skipAuthorization

When adding billing information to an account Recurly may ake an authorization attempt against the card which may incur charges depending on your payment gateway. In order to prevent Recurly from making this authorization attempt, a skipAuthorization paramater can be supplied along with the billing information.

binfo = recurly.BillingInfo();
binfo.account_code = '1234';
var billing_data = {
  number: '4111-1111-1111-1111',
  month: 1,
  year: 2020,
  skipAuthorization: true // <- do not make authorization request.
};
binfo.update(billing_data);

Subscription

Subscription.all()
Fetch a list of subscriptions. Responds with an array of all subscriptions that match the passed-in (optional) filters.

Subscription.all(filter, function(err, subscriptions));

Subscription.iterator()
Fetch a list of subscriptions. Responds with an async iterator that lazy loads data from recurly in batches of 200.

var iterators = require('async-iterators');
var iterator = Subscription.iterator();
iterators.forEachAsync(iterator, function (err, data, next) {
  ...
  next();
});

subscription.cancel()
Cancel a subscription.

subscription.cancel(function(err, updated));

subscription.reactivate()
Reactivate a cancelled subscription.

subscription.reactivate(function(err, updated));

subscription.postpone()
Postpone a subscription.

subscription.postpone(nextRenewalDate, function(err, updated));

subscription.terminate()
Terminate a subscription using the specific refund type. Valid refund types are 'partial', 'full', and 'none'.

subscription.terminate(refundType, function(err, updated));

Coupon

Coupon.all()
Fetch a list of coupons. Responds with an array of all coupons.

Coupon.all(function(err, coupons));

Coupon.iterator()
Fetch a list of coupons. Responds with an async iterator that lazy loads data from recurly in batches of 200.

var iterators = require('async-iterators');
var iterator = Coupon.iterator();
iterators.forEachAsync(iterator, function (err, data, next) {
  ...
  next();
});

coupon.redeem()
Redeem a coupon.

coupon.redeem(options, function(err, redemption));

Redemption

[TODO]

Transaction

Transaction.all()
Fetch a list of transactions. Responds with an array of all transactions that match the passed-in (optional) filters.

Transaction.all(filter, function(err, transactions));

Transaction.iterator()
Fetch a list of transactions. Responds with an async iterator that lazy loads data from recurly in batches of 200.

var iterators = require('async-iterators');
var iterator = Transaction.iterator();
iterators.forEachAsync(iterator, function (err, data, next) {
  ...
  next();
});

transaction.refund(amountInCents, function(err)) (DEPRECIATED)
If amountInCents is omitted, the transaction is refunded in full. Responds with any errors; the transaction object is updated.

Invoice

Invoice.all()
Fetch a list of invoices. Responds with an array of all invoices that match the passed-in (optional) filters.

Invoice.all(filter, function(err, invoices));

Invoice.iterator()
Fetch a list of invoices. Responds with an async iterator that lazy loads data from recurly in batches of 200.

var iterators = require('async-iterators');
var iterator = Invoice.iterator();
iterators.forEachAsync(iterator, function (err, data, next) {
  ...
  next();
});

invoice.refund(options, function(err))
If options.amount_in_cents is omitted, the invoice is refunded in full. Responds with any errors; the invoice object is updated.

options can include:

  • amount_in_cents (default: undefined) - The specific amount to be refunded from the original invoice. If left empty, the remaining refundable amount will be refunded.

  • refund_apply_order (default: 'credit') - If credit line items exist on the invoice, this parameter specifies which refund method to use first. Most relevant in a partial refunds, you can chose to refund credit back to the account first or a transaction giving money back to the customer first. Set as 'credit' or 'transaction'.

invoice.markSuccessful(function(err))
Mark an Invoice as Paid Successfully.

invoice.markFailed(function(err))
Mark an Invoice as Failed Collection.

Errors

All callbacks follow the node convention of reporting any error in the first parameter. If a transaction with Recurly succeeds but is rejected by Recurly for some reason-- inconsistent data, perhaps, or some other reason-- that err parameter is an instance of RecurlyError. The original transaction errors reported by Recurly are available as an array of structs in the errors parameter. For instance, here's the result of a billing info update with an invalid, expired CC:

{
	name: 'RecurlyError',
	message: '2 transaction errors',
	errors: [
		{
			field: 'billing_info.number',
			symbol: 'invalid',
			message: 'is not a valid credit card number'
		},
		{
			field: 'billing_info.number',
			symbol: 'expired',
			message: 'is expired or has an invalid expiration date'
		}
	]
}

SignedQuery

This provides the back-end support for signing parameters for forms embedded using recurly.js. See Recurly's signature documentation for details on which parameters must be signed for each form type.

var Recurring = require('recurring');
var recurly = new Recurring();

var signer = new recurly.SignedQuery('your-private-api-key');
signer.set('account', { account_code: 'account-id' });
var signedParameters = signer.toString();

The nonce & timestamp parameters are generated for you if you don't provide them. The nonce is created using node-uuid.

FormResponseToken

After Recurly handles a form submission, it posts to you a token pointing to the form results. Use a FormResponseToken object to fetch the results object represented by the token.

var Recurring = require('recurring');
var recurly = new Recurring();

var recurlyResponse = new recurly.FormResponseToken(token, 'subscription');
recurlyResponse.process(function(err, subscription) {
	if (err)
		return handleError(err);

	// subscription contains the new subscription data;
});

Having to hint about the type of the response is clunky; TODO fix.

Contributing

Unit tests for whatever you fix/implement/improve would be awesome. Recurring's are written with mocha and chai.

License

MIT. See accompanying LICENSE file.