Recurly

Invoices API

An invoice record relates charges, credits, and transactions together. When a subscription is first created or renewed, Recurly will create an invoice for the new subscription charges and include any outstanding credits and charges. Once the invoice is created, it attempts to collect payment on the outstanding balance (if there are more charges than credits).

List invoices

Returns a list of all invoices.

GET https://:subdomain.recurly.com/v2/invoices

Query Parameters

Parameter Default Description
state all The state of invoices to return: "open", "collected", "failed", or "past_due".
cursor Splits records across pages. Leave blank to return the first page. Follow the URI in the first page's Link header to fetch the next page.
per_page 50 Number of records to return per page, up to a maximum of 200.

Invoice States

open
Open, pending collection
collected
Collection completed successfully
failed
Failed to collect
past_due
Initial collection failed, still attempting collection

Please note: an invoice will only be in one state.

Example

Status: 200 OK
Content-Type: application/xml; charset=utf-8
X-Records: 123
Link: <https://your-subdomain.recurly.com/v2/invoices?cursor=1304958672>; rel="next"
ETag: "cd0faed6654f43768baf4282524f9782"
<?xml version="1.0" encoding="UTF-8"?>
<invoices type="array">
  <invoice href="https://your-subdomain.recurly.com/v2/invoices/e3f0a9e084a2468480d00ee61b090d4d">
    <account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
    <uuid>421f7b7d414e4c6792938e7c49d552e9</uuid>
    <state>open</state>
    <invoice_number type="integer">1005</invoice_number>
    <po_number nil="nil"></po_number>
    <vat_number nil="nil"></vat_number>
    <subtotal_in_cents type="integer">1200</subtotal_in_cents>
    <tax_in_cents type="integer">0</tax_in_cents>
    <total_in_cents type="integer">1200</total_in_cents>
    <currency>USD</currency>
    <created_at type="datetime">2011-08-25T12:00:00Z</created_at>
    <line_items type="array">
      <adjustment href="https://your-subdomain.recurly.com/v2/adjustments/05a4bbdeda2a47348185270021e6087b"/>
        <!-- Detail. -->
      </adjustment>
    </line_items>
    <transactions type="array">
    </transactions>
  </invoice>
  <!-- Continued... -->
</invoices>
$invoices = Recurly_InvoiceList::get();
foreach ($invoices as $invoice) {
  print "Invoice: $invoice\n";
}
The client library will automatically fetch the next page of the results. There may be a slight delay when fetching the next page.
Recurly::Invoice.find_each do |invoice|
  puts "Invoice: #{invoice.inspect}"
end
The client library will automatically fetch the next page of the results. There may be a slight delay when fetching the next page.
#client version <= 2.1.5
invoices = Invoice.all()
while invoices:
    for invoice in invoices:
        print 'Invoice: %s' % invoice
    try:
        invoices = invoices.next_page()
    except PageError:
        invoices = ()
# ...or...
past_due = Invoice.all_past_due()

#client version 2.1.6+
for invoice in Invoice.all():
    print 'Invoice: %s' % invoice

List an account's invoices

Returns a list of all the invoices.

GET https://:subdomain.recurly.com/v2/accounts/:account_code/invoices

Query Parameters

Parameter Default Description
cursor Splits records across pages. Leave blank to return the first page. Follow the URI in the first page's Link header to fetch the next page.
per_page 50 Number of records to return per page, up to a maximum of 200.

Example

Status: 200 OK
Content-Type: application/xml; charset=utf-8
X-Records: 92
Link: <https://your-subdomain.recurly.com/v2/accounts/1/invoices?cursor=1304958672>; rel="next"
ETag: "fab75c0e6cffe5bcf18442f8cbc4be3d"
<?xml version="1.0" encoding="UTF-8"?>
<invoices type="array">
  <invoice href="https://your-subdomain.recurly.com/v2/invoices/e3f0a9e084a2468480d00ee61b090d4d">
    <account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
    <uuid>421f7b7d414e4c6792938e7c49d552e9</uuid>
    <state>open</state>
    <invoice_number type="integer">1005</invoice_number>
    <po_number nil="nil"></po_number>
    <vat_number nil="nil"></vat_number>
    <subtotal_in_cents type="integer">1200</subtotal_in_cents>
    <tax_in_cents type="integer">0</tax_in_cents>
    <total_in_cents type="integer">1200</total_in_cents>
    <currency>USD</currency>
    <created_at type="datetime">2011-08-25T12:00:00Z</created_at>
    <line_items type="array">
      <adjustment href="https://your-subdomain.recurly.com/v2/adjustments/05a4bbdeda2a47348185270021e6087b"/>
        <!-- Detail. -->
      </adjustment>
    </line_items>
    <transactions type="array">
    </transactions>
  </invoice>
  <!-- Continued... -->
</invoices>
$invoices = Recurly_InvoiceList::getForAccount('account_code');
foreach ($invoices as $invoice) {
  print "Invoice: {$invoice}\n";
}
The client library will automatically fetch the next page of the results. There may be a slight delay when fetching the next page.
account = Recurly::Account.find('1')
account.invoices.find_each do |invoice|
  puts "Invoice: #{invoice.inspect}"
end
The client library will automatically fetch the next page of the results. There may be a slight delay when fetching the next page.
#client version <= 2.1.5
account = Account.get('1')
invoices = account.invoices()
while invoices:
    for invoice in invoices:
        print 'Invoice: %s' % invoice
    try:
        invoices = invoices.next_page()
    except PageError:
        invoices = ()

#client version 2.1.6+
account = Account.get('1')
for invoices in account.invoices():
    print 'Invoice: %s' % invoice

Lookup invoice details

Lookup an invoice to retrieve detailed information about its line items and payments.

GET https://:subdomain.recurly.com/v2/invoices/:invoice_number

Payments

Recurly returns an array of payments applied to an Invoice. At the moment, there is usually only one successful payment per invoice. The API only returns successful payments—it does not return failed payment attempts on an invoice nor does it return refunds on payments made to an invoice.

Example

Response

Status: 200 OK
Content-Type: application/xml; charset=utf-8
ETag: "66c8aa6c6b53123f99c43fe897e095ca"
<?xml version="1.0" encoding="UTF-8"?>
<invoice href="https://your-subdomain.recurly.com/v2/invoices/e3f0a9e084a2468480d00ee61b090d4d">
  <account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
  <uuid>421f7b7d414e4c6792938e7c49d552e9</uuid>
  <state>open</state>
  <invoice_number type="integer">1402</invoice_number>
  <po_number nil="nil"></po_number>
  <vat_number nil="nil"></vat_number>
  <subtotal_in_cents type="integer">9900</subtotal_in_cents>
  <tax_in_cents type="integer">0</tax_in_cents>
  <total_in_cents type="integer">9900</total_in_cents>
  <currency>USD</currency>
  <created_at type="datetime">2011-08-25T12:00:00Z</created_at>
  <line_items type="array">
    <adjustment href="https://your-subdomain.recurly.com/v2/adjustments/05a4bbdeda2a47348185270021e6087b" type="charge"/>
      <!-- Detail. -->
    </adjustment>
  </line_items>
  <transactions type="array">
  </transactions>
</invoice>
try {
  $invoice = Recurly_Invoice::get('1005');
  print "Invoice: $invoice\n";
} catch (Recurly_NotFoundError $e) {
  print "Invoice not found.\n";
}
invoice = Recurly::Invoice.find('1005')
invoice = Invoice.get('1005')

Retrieve a PDF invoice

To retrieve a PDF invoice, modify the headers to request the Accept as "application/pdf". You may also set the Accept-Language to the language and locale preferred for the invoice. This allows you to translate and/or localize the invoice.

GET https://:subdomain.recurly.com/v2/invoices/:invoice_number

Example

Request for English PDF

Accept: application/pdf
Accept-Language: en-US

Request for English PDF with UK date formats

Accept: application/pdf
Accept-Language: en-GB

Request for French PDF

Accept: application/pdf
Accept-Language: fr-FR
try {
  $pdf = Recurly_Invoice::getInvoicePdf('invoice_number', 'en-US');
} catch (Recurly_NotFoundError $e) {
  print "Invoice not found.\n";
}
begin
  pdf = Recurly::Invoice.find(
    'invoice_number', :format => 'pdf', :locale => 'en-US'
  )
rescue Recurly::Resource::NotFound => e
  puts 'Invoice not found.'
end
# TODO

Post an invoice: invoice pending charges on an account

When you post one-time charges to an account, these will remain pending until they are invoiced. An account is automatically invoiced when the subscription renews. However, there are times when it is appropriate to invoice an account before the renewal. If the subscriber has a yearly subscription, you might want to collect the one-time charges well before the renewal.

POST https://:subdomain.recurly.com/v2/accounts/:account_code/invoices

Example

Response

Status: 201 Created
Content-Type: application/xml; charset=utf-8
Location: https://your-subdomain.recurly.com/v2/invoices/421f7b7d414e4c6792938e7c49d552e9
<?xml version="1.0" encoding="UTF-8"?>
<invoice href="https://your-subdomain.recurly.com/v2/invoices/421f7b7d414e4c6792938e7c49d552e9">
  <account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
  <uuid>421f7b7d414e4c6792938e7c49d552e9</uuid>
  <state>open</state>
  <invoice_number type="integer">1005</invoice_number>
  <po_number nil="nil"></po_number>
  <vat_number nil="nil"></vat_number>
  <subtotal_in_cents type="integer">1200</subtotal_in_cents>
  <tax_in_cents type="integer">0</tax_in_cents>
  <total_in_cents type="integer">1200</total_in_cents>
  <currency>USD</currency>
  <created_at type="datetime">2011-08-25T12:00:00Z</created_at>
  <line_items type="array">
    <adjustment href="https://your-subdomain.recurly.com/v2/adjustments/05a4bbdeda2a47348185270021e6087b" type="charge"/>
      <!-- Detail. -->
    </adjustment>
  </line_items>
  <transactions type="array">
  </transactions>
</invoice>

This API call will return the new invoice's details on success. If there are no pending charges, it will return an HTTP status code of 422 Unprocessable Entity.

$invoice = Recurly_Invoice::invoicePendingCharges('1');
account = Recurly::Account.find('1')
invoice = account.invoice!
account = Account.get('1')
invoice = account.invoice()

Mark an invoice as paid successfully

PUT https://:subdomain.recurly.com/v2/invoices/:invoice_number/mark_successful

Example

$invoice = Recurly_Invoice::get('e3f0a9e084a2468480d00ee61b090d4d');
$invoice->markSuccessful();
invoice = Recurly::Invoice.find('e3f0a9e084a2468480d00ee61b090d4d')
invoice.mark_successful
invoice = Invoice.get('e3f0a9e084a2468480d00ee61b090d4d')
invoice.mark_successful()
// TODO

Mark an invoice as failed collection

PUT https://:subdomain.recurly.com/v2/invoices/:invoice_number/mark_failed

Example

$invoice = Recurly_Invoice::get('e3f0a9e084a2468480d00ee61b090d4d');
$invoice->markFailed();
invoice = Recurly::Invoice.find('e3f0a9e084a2468480d00ee61b090d4d')
invoice.mark_failed
invoice = Invoice.get('e3f0a9e084a2468480d00ee61b090d4d')
invoice.mark_failed()
// TODO