Invoices

Listing all Invoices

A GET request to /api/invoices/ is used to list all invoices.

Using count and offset restricts the number of returned invoices.

Parameter Description
count Limit the number of results. This can improve performance.
offset The start position of results, used for paging result sets. Can be used with count parameter.
"""
List all invoices using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoices_url = 'https://%s:%d/api/invoices/?count=10&offset=0' % (ONSITE_HOST, ONSITE_PORT)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# Setup a session for the http request.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False
session.stream = True

# Send the request to list all invoices.
get_response = session.get(invoices_url)
assert get_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(get_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<invoices total_count="2">
    <invoice full_render="false" id="16" uri="https://localhost:9630/api/invoices/16/">
        <datetime_created>2017-07-11T14:46:11.497143</datetime_created>
        <invoice_id>I-16</invoice_id>
        <invoice_customer>
            <customer/>
            <mainname>Tigerlilly</mainname>
            <mainphone>333.444.5555</mainphone>
            <contact_info>555-777-9999 [email protected]</contact_info>
        </invoice_customer>
        <flags>
            <posted>false</posted>
        </flags>
        <totals>
            <total>45.48</total>
        </totals>
    </invoice>
    <invoice full_render="false" id="17" uri="https://localhost:9630/api/invoices/17/">
        <datetime_created>2017-07-11T14:46:13.014179</datetime_created>
        <invoice_id>I-17</invoice_id>
        <invoice_customer>
            <customer id="7" uri="https://localhost:9630/api/customers/7/">
                <merged_to>
                    <customer/>
                </merged_to>
            </customer>
            <mainname>Wendy Marvell-02:46PM</mainname>
            <mainphone>555-666-7777</mainphone>
            <contact_info>555-666-7777
555-666-7777
[email protected]</contact_info>
        </invoice_customer>
        <flags>
            <posted>false</posted>
        </flags>
        <totals>
            <total>107.43</total>
        </totals>
    </invoice>
</invoices>

Warning

This request can time-out if there are too many invoices to return. Use limit and offset parameters to mitigate this.

Note

It is recommended to search invoices rather than to list them all. See Searching Invoices.

Getting an Invoice

A GET request to /api/invoices/{id}/ is used to get a single invoice.

"""
Get an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoice_id = 17
invoice_url = 'https://%s:%d/api/invoices/%d/' % (ONSITE_HOST, ONSITE_PORT, invoice_id)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# Setup a session for the http request.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False
session.stream = True

# Send the request to get an invoice.
get_response = session.get(invoice_url)
assert get_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(get_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<invoice full_render="true" id="17" uri="https://localhost:9630/api/invoices/17/">
   <document_id>17</document_id>
   <date_created>2017-07-11</date_created>
   <datetime_created>2017-07-11T14:46:13.014179</datetime_created>
   <date_modified>2017-07-11</date_modified>
   <datetime_modified>2017-07-11T14:46:13.226122</datetime_modified>
   <invoice_id>I-17</invoice_id>
   <invoice_customer>
       <customer id="7" uri="https://localhost:9630/api/customers/7/">
           <merged_to>
               <customer/>
           </merged_to>
       </customer>
       <mainname>Wendy Marvell-02:46PM</mainname>
       <mainphone>555-666-7777</mainphone>
       <phone_email/>
       <contact>Wendy Marvell-02:46PM</contact>
       <contact_info>555-666-7777
555-666-7777
[email protected]</contact_info>
       <discount>0.000</discount>
       <pricing_level>0</pricing_level>
       <terms_tax/>
       <zip/>
       <po/>
   </invoice_customer>
   <margin>94.460</margin>
   <print_options>
       <localizable_language full_render="true" id="0" uri="https://localhost:9630/api/setup/localizable_languages/0/">
           <name>English</name>
           <list_order>0</list_order>
       </localizable_language>
       <images>0</images>
       <discounts>false</discounts>
   </print_options>
   <primary_user>
       <user id="2" uri="https://localhost:9630/api/users/2/"/>
   </primary_user>
   <secondary_user>
       <user/>
   </secondary_user>
   <printed_notes/>
   <internal_notes/>
   <shipping_method/>
   <currency full_render="true" id="1" uri="https://localhost:9630/api/setup/currencies/1/">
       <name>US</name>
       <rate>1.000000</rate>
       <symbol>$</symbol>
   </currency>
   <terms/>
   <due>2017-07-11</due>
   <import_id/>
   <status>Owing</status>
   <tax_code id="0" uri="https://localhost:9630/api/tax_codes/0/"/>
   <taxes inclusive="false">
       <tax_exempt>
           <tax id="1" rate="7.00" total="7.03">false</tax>
           <tax id="2" rate="0.00" total="0.00">false</tax>
           <tax id="3" rate="0.00" total="0.00">false</tax>
           <tax id="4" rate="0.00" total="0.00">false</tax>
           <tax id="5" rate="0.00" total="0.00">false</tax>
       </tax_exempt>
   </taxes>
   <pricing_level/>
   <c_discount_percentage>0.000</c_discount_percentage>
   <payments/>
   <billing>
       <address>
           <address1>123 Igneel Boulevard</address1>
           <address2/>
           <city>Fairy Tail City</city>
           <state>Fairy Tail Land</state>
           <country>Isle of Wizards</country>
           <zip>90210</zip>
       </address>
   </billing>
   <shipping>
       <address>
           <address1>123 Igneel Boulevard</address1>
           <address2>PO BOX 2</address2>
           <city>Fairy Tail City</city>
           <state>Fairy Tail Land</state>
           <country>Isle of Wizards</country>
           <zip>90210</zip>
       </address>
   </shipping>
   <lineitems>
       <lineitem full_render="false" id="18" uri="https://localhost:9630/api/invoices/17/lineitems/18/">
           <quantity>1.000</quantity>
           <sell_price>15.400</sell_price>
           <sells>
               <sell>15.400</sell>
               <base>15.400</base>
               <total>15.40</total>
               <sell_quantity_discount>15.400</sell_quantity_discount>
               <sell_tax_inclusive_quantity_discount>16.478</sell_tax_inclusive_quantity_discount>
               <sell_tax_inclusive>16.478</sell_tax_inclusive>
               <sell_tax_inclusive_total>16.48</sell_tax_inclusive_total>
               <sell_tax_inclusive_discounted>16.480</sell_tax_inclusive_discounted>
           </sells>
           <lineitem_product>
               <product id="31" uri="https://localhost:9630/api/products/31/"/>
               <code>333-001-02:46PM</code>
               <description>Flaming Torch-02:46PM</description>
           </lineitem_product>
       </lineitem>
       <lineitem full_render="false" id="19" uri="https://localhost:9630/api/invoices/17/lineitems/19/">
           <quantity>2.000</quantity>
           <sell_price>42.500</sell_price>
           <sells>
               <sell>42.500</sell>
               <base>42.500</base>
               <total>85.00</total>
               <sell_quantity_discount>42.500</sell_quantity_discount>
               <sell_tax_inclusive_quantity_discount>45.475</sell_tax_inclusive_quantity_discount>
               <sell_tax_inclusive>45.475</sell_tax_inclusive>
               <sell_tax_inclusive_total>90.96</sell_tax_inclusive_total>
               <sell_tax_inclusive_discounted>45.480</sell_tax_inclusive_discounted>
           </sells>
           <lineitem_product>
               <product id="32" uri="https://localhost:9630/api/products/32/"/>
               <code>333-002-02:46PM</code>
               <description>Celestial Whip-02:46PM</description>
           </lineitem_product>
       </lineitem>
   </lineitems>
   <flags>
       <drop_shipment>false</drop_shipment>
       <exported>false</exported>
       <pay_backorders>false</pay_backorders>
       <posted>false</posted>
       <voided>false</voided>
   </flags>
   <totals>
       <subtotal>100.40</subtotal>
       <tax>7.03</tax>
       <total>107.43</total>
       <owing>107.43</owing>
       <paid>0.00</paid>
   </totals>
   <source>
       <id>O-32</id>
       <order id="32" uri="https://localhost:9630/api/orders/32/"/>
   </source>
   <returned_invoice/>
   <cc_info/>
   <exported/>
   <posted/>
   <station/>
</invoice>

Creating an Invoice

A POST request to /api/invoices/ is used to create an invoice.

Create Invoice from an Order

Invoices created from an Order will have the contents of the Order copied over to the newly created Invoice.

The Order ID simply needs to be specified in the source element.

"""
Create an order using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoices_url = 'https://%s:%d/api/invoices/' % (ONSITE_HOST, ONSITE_PORT)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# This is the invoice that will be created.
invoice_xml = """
<invoice>
    <source>
        <order id="58"/>
    </source>
</invoice>
"""

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Send the request to create the invoice.
post_response = session.post(invoices_url, data=invoice_xml)
assert post_response.status_code == 201

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(post_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<invoice full_render="true" id="62" uri="https://localhost:9630/api/invoices/62/">
   <document_id>62</document_id>
   <date_created>2017-07-20</date_created>
   <datetime_created>2017-07-20T16:50:02.383887</datetime_created>
   <date_modified>2017-07-20</date_modified>
   <datetime_modified>2017-07-20T16:50:02.535684</datetime_modified>
   <invoice_id>I-62</invoice_id>
   <invoice_customer>
       <customer/>
       <mainname>Natsu Dragneel-09:10AM</mainname>
       <mainphone/>
       <phone_email/>
       <contact/>
       <contact_info/>
       <discount>0.000</discount>
       <pricing_level>0</pricing_level>
       <terms_tax/>
       <zip/>
       <po/>
   </invoice_customer>
   <margin>100.00</margin>
   <print_options>
       <localizable_language full_render="true" id="0" uri="https://localhost:9630/api/setup/localizable_languages/0/">
           <name>English</name>
           <list_order>0</list_order>
       </localizable_language>
       <images>0</images>
       <discounts>false</discounts>
   </print_options>
   <primary_user>
       <user id="2" uri="https://localhost:9630/api/users/2/"/>
   </primary_user>
   <secondary_user>
       <user/>
   </secondary_user>
   <printed_notes/>
   <internal_notes/>
   <shipping_method/>
   <currency full_render="true" id="1" uri="https://localhost:9630/api/setup/currencies/1/">
       <name>US</name>
       <rate>1.000000</rate>
       <symbol>$</symbol>
   </currency>
   <terms/>
   <due>2017-07-12</due>
   <import_id/>
   <status>Owing</status>
   <tax_code id="0" uri="https://localhost:9630/api/tax_codes/0/"/>
   <taxes inclusive="false">
       <tax_exempt>
           <tax id="1" rate="7.00" total="0.63">false</tax>
           <tax id="2" rate="0.00" total="0.00">false</tax>
           <tax id="3" rate="0.00" total="0.00">false</tax>
           <tax id="4" rate="0.00" total="0.00">false</tax>
           <tax id="5" rate="0.00" total="0.00">false</tax>
       </tax_exempt>
   </taxes>
   <pricing_level/>
   <c_discount_percentage>0.000</c_discount_percentage>
   <payments/>
   <billing/>
   <shipping/>
   <lineitems>
       <lineitem full_render="false" id="61" uri="https://localhost:9630/api/invoices/62/lineitems/61/">
           <quantity>1.000</quantity>
           <sell_price>9.00</sell_price>
           <sells>
               <sell>9.00</sell>
               <base>10.000</base>
               <total>9.00</total>
               <sell_quantity_discount>10.000</sell_quantity_discount>
               <sell_tax_inclusive_quantity_discount>10.700</sell_tax_inclusive_quantity_discount>
               <sell_tax_inclusive>10.700</sell_tax_inclusive>
               <sell_tax_inclusive_total>9.63</sell_tax_inclusive_total>
               <sell_tax_inclusive_discounted>9.63</sell_tax_inclusive_discounted>
           </sells>
           <lineitem_product>
               <product id="43" uri="https://localhost:9630/api/products/43/"/>
               <code>333-003-09:10AM</code>
               <description>Lucy's Bikini-09:10AM</description>
           </lineitem_product>
       </lineitem>
       <lineitem full_render="false" id="62" uri="https://localhost:9630/api/invoices/62/lineitems/62/">
           <quantity>2.000</quantity>
           <sell_price>0.00</sell_price>
           <sells>
               <sell>0.00</sell>
               <base>20.000</base>
               <total>0.00</total>
               <sell_quantity_discount>20.000</sell_quantity_discount>
               <sell_tax_inclusive_quantity_discount>21.400</sell_tax_inclusive_quantity_discount>
               <sell_tax_inclusive>21.400</sell_tax_inclusive>
               <sell_tax_inclusive_total>0.00</sell_tax_inclusive_total>
               <sell_tax_inclusive_discounted>0.00</sell_tax_inclusive_discounted>
           </sells>
           <lineitem_product>
               <product id="44" uri="https://localhost:9630/api/products/44/"/>
               <code>333-004-09:10AM</code>
               <description>Juvia's Hat-09:10AM</description>
           </lineitem_product>
       </lineitem>
   </lineitems>
   <flags>
       <drop_shipment>false</drop_shipment>
       <exported>false</exported>
       <pay_backorders>false</pay_backorders>
       <posted>false</posted>
       <voided>false</voided>
   </flags>
   <totals>
       <subtotal>9.00</subtotal>
       <tax>0.63</tax>
       <total>9.63</total>
       <owing>9.63</owing>
       <paid>0.00</paid>
   </totals>
   <source>
       <id>O-58</id>
       <order id="58" uri="https://localhost:9630/api/orders/58/"/>
   </source>
   <returned_invoice/>
   <cc_info/>
   <exported/>
   <posted/>
   <station/>
</invoice>

With a Walk-in Customer

Invoices can be created with walk-in customers, that is to say, there’s no customer entry made for them.

"""
Create an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoices_url = 'https://%s:%d/api/invoices/' % (ONSITE_HOST, ONSITE_PORT)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# This is the invoice that will be created.
invoice_xml = """
<invoice>
    <invoice_customer>
        <mainname>Jane Doe</mainname>
        <phone>555-123-4567</phone>
    </invoice_customer>
</invoice>
"""

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Send the request to create the invoice.
post_response = session.post(invoices_url, data=invoice_xml)
assert post_response.status_code == 201

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(post_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<invoice full_render="true" id="63" uri="https://localhost:9630/api/invoices/63/">
   <document_id>63</document_id>
   <date_created>2017-07-21</date_created>
   <datetime_created>2017-07-21T07:31:07.575932</datetime_created>
   <date_modified>2017-07-21</date_modified>
   <datetime_modified>2017-07-21T07:31:07.617372</datetime_modified>
   <invoice_id>I-63</invoice_id>
   <invoice_customer>
       <customer/>
       <mainname>Jane Doe</mainname>
       <mainphone/>
       <phone_email/>
       <contact/>
       <contact_info/>
       <discount>0.0</discount>
       <pricing_level>0</pricing_level>
       <terms_tax/>
       <zip/>
       <po/>
   </invoice_customer>
   <margin>0.00</margin>
   <print_options>
       <localizable_language full_render="true" id="0" uri="https://localhost:9630/api/setup/localizable_languages/0/">
           <name>English</name>
           <list_order>0</list_order>
       </localizable_language>
       <images>0</images>
       <discounts>false</discounts>
   </print_options>
   <primary_user>
       <user id="2" uri="https://localhost:9630/api/users/2/"/>
   </primary_user>
   <secondary_user>
       <user/>
   </secondary_user>
   <printed_notes/>
   <internal_notes/>
   <shipping_method/>
   <currency full_render="true" id="1" uri="https://localhost:9630/api/setup/currencies/1/">
       <name>US</name>
       <rate>1.000000</rate>
       <symbol>$</symbol>
   </currency>
   <terms/>
   <due>2017-07-21</due>
   <import_id/>
   <status>Paid</status>
   <tax_code id="0" uri="https://localhost:9630/api/tax_codes/0/"/>
   <taxes inclusive="false">
       <tax_exempt>
           <tax id="1" rate="7.00" total="0.00">false</tax>
           <tax id="2" rate="0.00" total="0.00">false</tax>
           <tax id="3" rate="0.00" total="0.00">false</tax>
           <tax id="4" rate="0.00" total="0.00">false</tax>
           <tax id="5" rate="0.00" total="0.00">false</tax>
       </tax_exempt>
   </taxes>
   <pricing_level/>
   <c_discount_percentage>0.0</c_discount_percentage>
   <payments/>
   <billing/>
   <shipping/>
   <lineitems/>
   <flags>
       <drop_shipment>false</drop_shipment>
       <exported>false</exported>
       <pay_backorders>false</pay_backorders>
       <posted>false</posted>
       <voided>false</voided>
   </flags>
   <totals>
       <subtotal>0.00</subtotal>
       <tax>0.00</tax>
       <total>0.00</total>
       <owing>0.00</owing>
       <paid>0.00</paid>
   </totals>
   <source/>
   <returned_invoice/>
   <cc_info/>
   <exported/>
   <posted/>
   <station/>
</invoice>

With an Existing Customer

Invoices can be created with existing customers. How to create customers is explained in Customers.

"""
Create an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoices_url = 'https://%s:%d/api/invoices/' % (ONSITE_HOST, ONSITE_PORT)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# This is the invoice that will be created.
invoice_xml = """
<invoice>
    <invoice_customer>
        <customer id="2"/>
    </invoice_customer>
</invoice>
"""

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Send the request to create the invoice.
post_response = session.post(invoices_url, data=invoice_xml)
assert post_response.status_code == 201

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(post_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<invoice full_render="true" id="64" uri="https://localhost:9630/api/invoices/64/">
   <document_id>64</document_id>
   <date_created>2017-07-21</date_created>
   <datetime_created>2017-07-21T07:33:22.583078</datetime_created>
   <date_modified>2017-07-21</date_modified>
   <datetime_modified>2017-07-21T07:33:22.623851</datetime_modified>
   <invoice_id>I-64</invoice_id>
   <invoice_customer>
       <customer id="15" uri="https://localhost:9630/api/customers/15/">
           <merged_to>
               <customer/>
           </merged_to>
       </customer>
       <mainname>Jane Smith</mainname>
       <mainphone>613-555-5555</mainphone>
       <phone_email/>
       <contact>Jane Smith</contact>
       <contact_info>613-555-5555
613-555-5555
[email protected]</contact_info>
       <discount>0.0</discount>
       <pricing_level>0</pricing_level>
       <terms_tax/>
       <zip/>
       <po/>
   </invoice_customer>
   <margin>0.00</margin>
   <print_options>
       <localizable_language full_render="true" id="0" uri="https://localhost:9630/api/setup/localizable_languages/0/">
           <name>English</name>
           <list_order>0</list_order>
       </localizable_language>
       <images>0</images>
       <discounts>false</discounts>
   </print_options>
   <primary_user>
       <user id="2" uri="https://localhost:9630/api/users/2/"/>
   </primary_user>
   <secondary_user>
       <user/>
   </secondary_user>
   <printed_notes/>
   <internal_notes/>
   <shipping_method/>
   <currency full_render="true" id="1" uri="https://localhost:9630/api/setup/currencies/1/">
       <name>US</name>
       <rate>1.000000</rate>
       <symbol>$</symbol>
   </currency>
   <terms/>
   <due>2017-07-21</due>
   <import_id/>
   <status>Paid</status>
   <tax_code id="0" uri="https://localhost:9630/api/tax_codes/0/"/>
   <taxes inclusive="false">
       <tax_exempt>
           <tax id="1" rate="7.00" total="0.00">false</tax>
           <tax id="2" rate="0.00" total="0.00">false</tax>
           <tax id="3" rate="0.00" total="0.00">false</tax>
           <tax id="4" rate="0.00" total="0.00">false</tax>
           <tax id="5" rate="0.00" total="0.00">false</tax>
       </tax_exempt>
   </taxes>
   <pricing_level/>
   <c_discount_percentage>0.0</c_discount_percentage>
   <payments/>
   <billing/>
   <shipping/>
   <lineitems/>
   <flags>
       <drop_shipment>false</drop_shipment>
       <exported>false</exported>
       <pay_backorders>false</pay_backorders>
       <posted>false</posted>
       <voided>false</voided>
   </flags>
   <totals>
       <subtotal>0.00</subtotal>
       <tax>0.00</tax>
       <total>0.00</total>
       <owing>0.00</owing>
       <paid>0.00</paid>
   </totals>
   <source/>
   <returned_invoice/>
   <cc_info/>
   <exported/>
   <posted/>
   <station/>
</invoice>

Adding Products to an Invoice

A POST request to /api/invoices/{id}/lineitems/ is used to add a product to an invoice.

This must be preceded by a LOCK request to the same endpoint, and followed by an UNLOCK request. See Locking & Unlocking Resources.

"""
Add products to an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoice_id = 17
invoice_url = 'https://%s:%d/api/invoices/%d/' % (ONSITE_HOST, ONSITE_PORT, invoice_id)

# This is the product being added to the invoice.
line_items_xml = """
<lineitem>
    <quantity>1</quantity>
    <lineitem_product>
        <product id="3"/>
    </lineitem_product>
</lineitem>
"""

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Lock the order before making the change.
lock_response = session.request('LOCK', invoice_url)
assert lock_response.status_code == 200

# Send the request to update the invoice.
post_response = session.post(invoice_url + 'lineitems/', data=line_items_xml)
assert post_response.status_code == 201

# Unlock the order after the change is complete.
unlock_response = session.request('UNLOCK', invoice_url)
assert unlock_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Print the revised product.
response_xml = minidom.parseString(post_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<response>
   <lineitem full_render="true" id="63" uri="https://localhost:9630/api/invoices/17/lineitems/63/">
       <cost edited="false" total="0.00">0</cost>
       <discount/>
       <pricing_level/>
       <profit_margin minimum="0.000"/>
       <quantity>1</quantity>
       <quantity_discount>false</quantity_discount>
       <sell_price>50.00</sell_price>
       <sells>
           <sell>50.00</sell>
           <base>50.000</base>
           <total>50.00</total>
           <sell_quantity_discount>50.00</sell_quantity_discount>
           <sell_tax_inclusive_quantity_discount>50.000</sell_tax_inclusive_quantity_discount>
           <sell_tax_inclusive>50.000</sell_tax_inclusive>
           <sell_tax_inclusive_total>50.00</sell_tax_inclusive_total>
           <sell_tax_inclusive_discounted>50.00</sell_tax_inclusive_discounted>
       </sells>
       <editable>true</editable>
       <manual>false</manual>
       <lineitem_product>
           <product full_render="true" id="3" uri="https://localhost:9630/api/products/3/">
               <class id="9" uri="https://localhost:9630/api/setup/classes/9/"/>
               <currency id="1" uri="https://localhost:9630/api/setup/currencies/1/"/>
               <code>CORGIFT</code>
               <costs>
                   <cost/>
                   <average>0.000</average>
                   <raw/>
               </costs>
               <supplier_costs/>
               <flags>
                   <current>true</current>
                   <editable>true</editable>
                   <gift_card>true</gift_card>
                   <inventoried>false</inventoried>
                   <new_cost>false</new_cost>
                   <new_import>false</new_import>
                   <new_update>false</new_update>
                   <no_live_rules>false</no_live_rules>
                   <no_profit>false</no_profit>
                   <serialized>false</serialized>
                   <web>false</web>
                   <editable_sell>false</editable_sell>
                   <master_model>false</master_model>
               </flags>
               <sell_price>50.000</sell_price>
               <pricing_levels/>
               <created>2017-07-07T13:00:18.501813</created>
               <modified>2017-07-07T13:03:35.764628</modified>
               <description/>
               <long_web_description/>
               <family/>
               <gl_product>
                   <asset/>
                   <cogs_expense/>
                   <income/>
                   <payable_expense/>
               </gl_product>
               <product_id>P-1002</product_id>
               <import_id/>
               <inventory>
                   <available>-12.000</available>
                   <reserved>0.000</reserved>
                   <coming_for_stock>0</coming_for_stock>
                   <coming_for_customer>0</coming_for_customer>
                   <warehouses>0.000</warehouses>
                   <in_transit>0.000</in_transit>
                   <total>-12.000</total>
               </inventory>
               <margin/>
               <minimum_margin>0.000</minimum_margin>
               <notes/>
               <product_info>
                   <color/>
                   <height>0.000</height>
                   <length>0.000</length>
                   <size/>
                   <weight>0.000</weight>
                   <width>0.000</width>
               </product_info>
               <reorder>
                   <amount>0.000</amount>
                   <calc>0.000</calc>
                   <point>0.000</point>
                   <type>0</type>
               </reorder>
               <sells>
                   <sell>50.000</sell>
                   <sell_tax_inclusive/>
                   <sell_web/>
               </sells>
               <supplier id="1" uri="https://localhost:9630/api/suppliers/1/"/>
               <supplier_code/>
               <upc/>
               <web>
                   <inventory/>
               </web>
               <keywords>
                   <keyword/>
                   <keyword/>
                   <keyword/>
               </keywords>
               <multi_store_label>3</multi_store_label>
               <multi_store_master_label/>
               <categories>
                   <pos/>
                   <web/>
               </categories>
               <related_products/>
               <serial_numbers/>
               <product_photos/>
               <tax_exemption id="38" uri="https://localhost:9630/api/setup/tax_exemptions/38/">
                   <name>No Tax</name>
                   <taxes>
                       <tax id="1">
                           <exempt>true</exempt>
                       </tax>
                       <tax id="2">
                           <exempt>false</exempt>
                       </tax>
                       <tax id="3">
                           <exempt>false</exempt>
                       </tax>
                       <tax id="4">
                           <exempt>false</exempt>
                       </tax>
                       <tax id="5">
                           <exempt>false</exempt>
                       </tax>
                   </taxes>
                   <active>true</active>
               </tax_exemption>
               <master_product/>
           </product>
           <code>CORGIFT</code>
           <family/>
           <description/>
           <class_name/>
           <current>true</current>
           <editable>true</editable>
           <editable_sell>false</editable_sell>
           <gift_card>true</gift_card>
           <inventoried>false</inventoried>
           <no_profit>false</no_profit>
           <serialized>false</serialized>
       </lineitem_product>
       <tax_exemption id="38" uri="https://localhost:9630/api/setup/tax_exemptions/38/"/>
       <taxes>
           <tax id="1">
               <exempt>true</exempt>
               <total>0.00</total>
           </tax>
           <tax id="2">
               <exempt>true</exempt>
               <total>0.00</total>
           </tax>
           <tax id="3">
               <exempt>true</exempt>
               <total>0.00</total>
           </tax>
           <tax id="4">
               <exempt>true</exempt>
               <total>0.00</total>
           </tax>
           <tax id="5">
               <exempt>true</exempt>
               <total>0.00</total>
           </tax>
       </taxes>
       <quantity_backordered/>
       <ext_status/>
       <gift_card>2</gift_card>
       <serial_numbers>
           <serial_number>G-1EB0-2E8</serial_number>
       </serial_numbers>
   </lineitem>
   <invoice full_render="true" id="17" uri="https://localhost:9630/api/invoices/17/">
       <document_id>17</document_id>
       <date_created>2017-07-11</date_created>
       <datetime_created>2017-07-11T14:46:13.014179</datetime_created>
       <date_modified>2017-07-21</date_modified>
       <datetime_modified>2017-07-21T07:36:38.727530</datetime_modified>
       <invoice_id>I-17</invoice_id>
       <invoice_customer>
           <customer id="7" uri="https://localhost:9630/api/customers/7/">
               <merged_to>
                   <customer/>
               </merged_to>
           </customer>
           <mainname>Wendy Marvell-02:46PM</mainname>
           <mainphone>555-666-7777</mainphone>
           <phone_email/>
           <contact>Wendy Marvell-02:46PM</contact>
           <contact_info>555-666-7777
555-666-7777
[email protected]</contact_info>
           <discount>0.000</discount>
           <pricing_level>0</pricing_level>
           <terms_tax/>
           <zip/>
           <po/>
       </invoice_customer>
       <margin>96.30</margin>
       <print_options>
           <localizable_language full_render="true" id="0" uri="https://localhost:9630/api/setup/localizable_languages/0/">
               <name>English</name>
               <list_order>0</list_order>
           </localizable_language>
           <images>0</images>
           <discounts>false</discounts>
       </print_options>
       <primary_user>
           <user id="2" uri="https://localhost:9630/api/users/2/"/>
       </primary_user>
       <secondary_user>
           <user/>
       </secondary_user>
       <printed_notes/>
       <internal_notes/>
       <shipping_method/>
       <currency full_render="true" id="1" uri="https://localhost:9630/api/setup/currencies/1/">
           <name>US</name>
           <rate>1.000000</rate>
           <symbol>$</symbol>
       </currency>
       <terms/>
       <due>2017-07-11</due>
       <import_id/>
       <status>Owing</status>
       <tax_code id="0" uri="https://localhost:9630/api/tax_codes/0/"/>
       <taxes inclusive="false">
           <tax_exempt>
               <tax id="1" rate="7.00" total="7.03">false</tax>
               <tax id="2" rate="0.00" total="0.00">false</tax>
               <tax id="3" rate="0.00" total="0.00">false</tax>
               <tax id="4" rate="0.00" total="0.00">false</tax>
               <tax id="5" rate="0.00" total="0.00">false</tax>
           </tax_exempt>
       </taxes>
       <pricing_level/>
       <c_discount_percentage>0.000</c_discount_percentage>
       <payments/>
       <billing>
           <address>
               <address1>123 Igneel Boulevard</address1>
               <address2/>
               <city>Fairy Tail City</city>
               <state>Fairy Tail Land</state>
               <country>Isle of Wizards</country>
               <zip>90210</zip>
           </address>
       </billing>
       <shipping>
           <address>
               <address1>123 Igneel Boulevard</address1>
               <address2>PO BOX 2</address2>
               <city>Fairy Tail City</city>
               <state>Fairy Tail Land</state>
               <country>Isle of Wizards</country>
               <zip>90210</zip>
           </address>
       </shipping>
       <lineitems>
           <lineitem full_render="false" id="18" uri="https://localhost:9630/api/invoices/17/lineitems/18/">
               <quantity>1.000</quantity>
               <sell_price>15.400</sell_price>
               <sells>
                   <sell>15.400</sell>
                   <base>15.400</base>
                   <total>15.40</total>
                   <sell_quantity_discount>15.400</sell_quantity_discount>
                   <sell_tax_inclusive_quantity_discount>16.478</sell_tax_inclusive_quantity_discount>
                   <sell_tax_inclusive>16.478</sell_tax_inclusive>
                   <sell_tax_inclusive_total>16.48</sell_tax_inclusive_total>
                   <sell_tax_inclusive_discounted>16.48</sell_tax_inclusive_discounted>
               </sells>
               <lineitem_product>
                   <product id="31" uri="https://localhost:9630/api/products/31/"/>
                   <code>333-001-02:46PM</code>
                   <description>Flaming Torch-02:46PM</description>
               </lineitem_product>
           </lineitem>
           <lineitem full_render="false" id="19" uri="https://localhost:9630/api/invoices/17/lineitems/19/">
               <quantity>2.000</quantity>
               <sell_price>42.500</sell_price>
               <sells>
                   <sell>42.500</sell>
                   <base>42.500</base>
                   <total>85.00</total>
                   <sell_quantity_discount>42.500</sell_quantity_discount>
                   <sell_tax_inclusive_quantity_discount>45.475</sell_tax_inclusive_quantity_discount>
                   <sell_tax_inclusive>45.475</sell_tax_inclusive>
                   <sell_tax_inclusive_total>90.96</sell_tax_inclusive_total>
                   <sell_tax_inclusive_discounted>45.48</sell_tax_inclusive_discounted>
               </sells>
               <lineitem_product>
                   <product id="32" uri="https://localhost:9630/api/products/32/"/>
                   <code>333-002-02:46PM</code>
                   <description>Celestial Whip-02:46PM</description>
               </lineitem_product>
           </lineitem>
           <lineitem full_render="false" id="63" uri="https://localhost:9630/api/invoices/17/lineitems/63/">
               <quantity>1</quantity>
               <sell_price>50.00</sell_price>
               <sells>
                   <sell>50.00</sell>
                   <base>50.000</base>
                   <total>50.00</total>
                   <sell_quantity_discount>50.00</sell_quantity_discount>
                   <sell_tax_inclusive_quantity_discount>50.000</sell_tax_inclusive_quantity_discount>
                   <sell_tax_inclusive>50.000</sell_tax_inclusive>
                   <sell_tax_inclusive_total>50.00</sell_tax_inclusive_total>
                   <sell_tax_inclusive_discounted>50.00</sell_tax_inclusive_discounted>
               </sells>
               <lineitem_product>
                   <product id="3" uri="https://localhost:9630/api/products/3/"/>
                   <code>CORGIFT</code>
                   <description/>
               </lineitem_product>
           </lineitem>
       </lineitems>
       <flags>
           <drop_shipment>false</drop_shipment>
           <exported>false</exported>
           <pay_backorders>false</pay_backorders>
           <posted>false</posted>
           <voided>false</voided>
       </flags>
       <totals>
           <subtotal>150.40</subtotal>
           <tax>7.03</tax>
           <total>157.43</total>
           <owing>157.43</owing>
           <paid>0.00</paid>
       </totals>
       <source>
           <id>O-32</id>
           <order id="32" uri="https://localhost:9630/api/orders/32/"/>
       </source>
       <returned_invoice/>
       <cc_info/>
       <exported/>
       <posted/>
       <station/>
   </invoice>
   <gift_cards>
       <gift_card id="28" uri="https://localhost:9630/api/gift_cards/28/"/>
   </gift_cards>
</response>

Updating an Invoice

A PUT request to /api/invoices/{id}/ is used to update an invoice.

This must be preceded by a LOCK request to the same endpoint, and followed by an UNLOCK request. See Locking & Unlocking Resources.

"""
Update an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoice_id = 17
invoice_url = 'https://%s:%d/api/invoices/%d/' % (ONSITE_HOST, ONSITE_PORT, invoice_id)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# This is the updated information for the invoice.
invoice_xml = """
<invoice>
    <internal_notes>This customer requested that the items be gift-wrapped.</internal_notes>
</invoice>
"""

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Lock the invoice before making the change.
lock_response = session.request('LOCK', invoice_url)
assert lock_response.status_code == 200

# Send the request to update the invoice.
put_response = session.put(invoice_url, data=invoice_xml)
assert put_response.status_code == 200

# Unlock the invoice after the change is complete.
unlock_response = session.request('UNLOCK', invoice_url)
assert unlock_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Print the revised invoice.
response_xml = minidom.parseString(put_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<invoice full_render="true" id="17" uri="https://localhost:9630/api/invoices/17/">
    <document_id>17</document_id>
    <date_created>2017-07-11</date_created>
    <datetime_created>2017-07-11T14:46:13.014179</datetime_created>
    <date_modified>2017-07-21</date_modified>
    <datetime_modified>2017-07-21T07:40:59.282275</datetime_modified>
    <invoice_id>I-17</invoice_id>
    <invoice_customer>
        <customer id="7" uri="https://localhost:9630/api/customers/7/">
            <merged_to>
                <customer/>
            </merged_to>
        </customer>
        <mainname>Wendy Marvell-02:46PM</mainname>
        <mainphone>555-666-7777</mainphone>
        <phone_email/>
        <contact>Wendy Marvell-02:46PM</contact>
        <contact_info>555-666-7777
555-666-7777
[email protected]</contact_info>
        <discount>0.000</discount>
        <pricing_level>0</pricing_level>
        <terms_tax/>
        <zip/>
        <po/>
    </invoice_customer>
    <margin>96.30</margin>
    <print_options>
        <localizable_language full_render="true" id="0" uri="https://localhost:9630/api/setup/localizable_languages/0/">
            <name>English</name>
            <list_order>0</list_order>
        </localizable_language>
        <images>0</images>
        <discounts>false</discounts>
    </print_options>
    <primary_user>
        <user id="2" uri="https://localhost:9630/api/users/2/"/>
    </primary_user>
    <secondary_user>
        <user/>
    </secondary_user>
    <printed_notes/>
    <internal_notes>This customer requested that the items be gift-wrapped.</internal_notes>
    <shipping_method/>
    <currency full_render="true" id="1" uri="https://localhost:9630/api/setup/currencies/1/">
        <name>US</name>
        <rate>1.000000</rate>
        <symbol>$</symbol>
    </currency>
    <terms/>
    <due>2017-07-11</due>
    <import_id/>
    <status>Owing</status>
    <tax_code id="0" uri="https://localhost:9630/api/tax_codes/0/"/>
    <taxes inclusive="false">
        <tax_exempt>
            <tax id="1" rate="7.00" total="7.03">false</tax>
            <tax id="2" rate="0.00" total="0.00">false</tax>
            <tax id="3" rate="0.00" total="0.00">false</tax>
            <tax id="4" rate="0.00" total="0.00">false</tax>
            <tax id="5" rate="0.00" total="0.00">false</tax>
        </tax_exempt>
    </taxes>
    <pricing_level/>
    <c_discount_percentage>0.000</c_discount_percentage>
    <payments/>
    <billing>
        <address>
            <address1>123 Igneel Boulevard</address1>
            <address2/>
            <city>Fairy Tail City</city>
            <state>Fairy Tail Land</state>
            <country>Isle of Wizards</country>
            <zip>90210</zip>
        </address>
    </billing>
    <shipping>
        <address>
            <address1>123 Igneel Boulevard</address1>
            <address2>PO BOX 2</address2>
            <city>Fairy Tail City</city>
            <state>Fairy Tail Land</state>
            <country>Isle of Wizards</country>
            <zip>90210</zip>
        </address>
    </shipping>
    <lineitems>
        <lineitem full_render="false" id="18" uri="https://localhost:9630/api/invoices/17/lineitems/18/">
            <quantity>1.000</quantity>
            <sell_price>15.400</sell_price>
            <sells>
                <sell>15.400</sell>
                <base>15.400</base>
                <total>15.40</total>
                <sell_quantity_discount>15.400</sell_quantity_discount>
                <sell_tax_inclusive_quantity_discount>16.478</sell_tax_inclusive_quantity_discount>
                <sell_tax_inclusive>16.478</sell_tax_inclusive>
                <sell_tax_inclusive_total>16.48</sell_tax_inclusive_total>
                <sell_tax_inclusive_discounted>16.48</sell_tax_inclusive_discounted>
            </sells>
            <lineitem_product>
                <product id="31" uri="https://localhost:9630/api/products/31/"/>
                <code>333-001-02:46PM</code>
                <description>Flaming Torch-02:46PM</description>
            </lineitem_product>
        </lineitem>
        <lineitem full_render="false" id="19" uri="https://localhost:9630/api/invoices/17/lineitems/19/">
            <quantity>2.000</quantity>
            <sell_price>42.500</sell_price>
            <sells>
                <sell>42.500</sell>
                <base>42.500</base>
                <total>85.00</total>
                <sell_quantity_discount>42.500</sell_quantity_discount>
                <sell_tax_inclusive_quantity_discount>45.475</sell_tax_inclusive_quantity_discount>
                <sell_tax_inclusive>45.475</sell_tax_inclusive>
                <sell_tax_inclusive_total>90.96</sell_tax_inclusive_total>
                <sell_tax_inclusive_discounted>45.48</sell_tax_inclusive_discounted>
            </sells>
            <lineitem_product>
                <product id="32" uri="https://localhost:9630/api/products/32/"/>
                <code>333-002-02:46PM</code>
                <description>Celestial Whip-02:46PM</description>
            </lineitem_product>
        </lineitem>
        <lineitem full_render="false" id="63" uri="https://localhost:9630/api/invoices/17/lineitems/63/">
            <quantity>1.000</quantity>
            <sell_price>50.000</sell_price>
            <sells>
                <sell>50.000</sell>
                <base>50.000</base>
                <total>50.00</total>
                <sell_quantity_discount>50.000</sell_quantity_discount>
                <sell_tax_inclusive_quantity_discount>50.000</sell_tax_inclusive_quantity_discount>
                <sell_tax_inclusive>50.000</sell_tax_inclusive>
                <sell_tax_inclusive_total>50.00</sell_tax_inclusive_total>
                <sell_tax_inclusive_discounted>50.00</sell_tax_inclusive_discounted>
            </sells>
            <lineitem_product>
                <product id="3" uri="https://localhost:9630/api/products/3/"/>
                <code>CORGIFT</code>
                <description/>
            </lineitem_product>
        </lineitem>
    </lineitems>
    <flags>
        <drop_shipment>false</drop_shipment>
        <exported>false</exported>
        <pay_backorders>false</pay_backorders>
        <posted>false</posted>
        <voided>false</voided>
    </flags>
    <totals>
        <subtotal>150.40</subtotal>
        <tax>7.03</tax>
        <total>157.43</total>
        <owing>157.43</owing>
        <paid>0.00</paid>
    </totals>
    <source>
        <id>O-32</id>
        <order id="32" uri="https://localhost:9630/api/orders/32/"/>
    </source>
    <returned_invoice/>
    <cc_info/>
    <exported/>
    <posted/>
    <station/>
</invoice>

List Payments on an Invoice

A GET request to /api/invoices/{id}/payments/ is used to list payments on an invoice.

"""
Get payments on an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoice_id = 18
invoice_payments_url = 'https://%s:%d/api/invoices/%d/payments/' % (ONSITE_HOST, ONSITE_PORT, invoice_id)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# Setup a session for the http request.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False
session.stream = True

# Send the request to list all payments.
get_response = session.get(invoice_payments_url)
assert get_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(get_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<payments>
    <payment id="4" uri="https://localhost:9630/api/invoices/18/payments/4/"/>
</payments>

Get a Payment on an Invoice

A GET request to /api/invoices/{invoice id}/payments/{payment id}/ is used to get a payment on an invoice.

"""
Get a payment on an invoice using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoice_id = 18
payment_id = 4
invoice_payment_url = 'https://%s:%d/api/invoices/%d/payments/%d/' % (
    ONSITE_HOST, ONSITE_PORT, invoice_id, payment_id)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# Setup a session for the http request.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False
session.stream = True

# Send the request to get an invoice payment.
get_response = session.get(invoice_payment_url)
assert get_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Get the response and print it.
response_xml = minidom.parseString(get_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<payment id="4" uri="https://localhost:9630/api/invoices/18/payments/4/">
    <type>Cash</type>
    <payment_method>Cash</payment_method>
    <datetime_created>2017-07-11T14:46:14.655718</datetime_created>
    <datetime_modified>2017-07-11T14:46:14.655155</datetime_modified>
    <exported/>
    <posted/>
    <flags>
        <exported>false</exported>
        <posted>false</posted>
        <voided>false</voided>
    </flags>
    <number/>
    <source id="I-18">Happy</source>
    <amount>15.00</amount>
    <tendered>15.00</tendered>
    <authcode/>
    <avs_result/>
    <till/>
    <signature_photo/>
</payment>

Searching Invoices

A POST request to /api/invoices/search/ is used to search invoices. The POST request payload specifies what invoice information to return (columns) and what to search by (filters). Pagination is supported with the search query.

A GET request to /api/invoices/search/ is used to obtain the list of columns and filters.

Listing Search Columns and Filters

A GET request to /api/invoices/search/ is used to obtain the list of columns and filters.

These results can be cached if desired.

"""
Get the list of search filters and columns for invoices using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

customer_search_url = 'https://%s:%d/api/invoices/search/' % (ONSITE_HOST, ONSITE_PORT)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Send the request to get the list of columns/filters.
get_response = session.get(customer_search_url)
assert get_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Print the list of columns/filters.
response_xml = minidom.parseString(get_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<search_criteria uri="https://localhost:9630/api/invoices/search/">
	<columns>
		<column id="lsserver.search.column.id">
			<name>
				<localizable_message type="lsserver.search.column.id">
					<fields/>
					<plain_message>ID</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>true</default>
			<sort_default>true</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.date">
			<name>
				<localizable_message type="lsserver.search.column.date">
					<fields/>
					<plain_message>Date</plain_message>
				</localizable_message>
			</name>
			<type>DATE</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.customer">
			<name>
				<localizable_message type="lsserver.search.column.customer">
					<fields/>
					<plain_message>Customer</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.phone">
			<name>
				<localizable_message type="lsserver.search.column.phone">
					<fields/>
					<plain_message>Phone</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.po">
			<name>
				<localizable_message type="lsserver.search.column.po">
					<fields/>
					<plain_message>PO</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.user">
			<name>
				<localizable_message type="lsserver.search.column.user">
					<fields/>
					<plain_message>User</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.status">
			<name>
				<localizable_message type="lsserver.search.column.status">
					<fields/>
					<plain_message>Status</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.total">
			<name>
				<localizable_message type="lsserver.search.column.total">
					<fields/>
					<plain_message>Total</plain_message>
				</localizable_message>
			</name>
			<type>MONEY</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>true</can_summarize>
		</column>
		<column id="lsserver.search.column.exported">
			<name>
				<localizable_message type="lsserver.search.column.exported">
					<fields/>
					<plain_message>Exported</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.posted">
			<name>
				<localizable_message type="lsserver.search.column.posted">
					<fields/>
					<plain_message>Posted</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.total_owing">
			<name>
				<localizable_message type="lsserver.search.column.total_owing">
					<fields/>
					<plain_message>Total Owing</plain_message>
				</localizable_message>
			</name>
			<type>MONEY</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.total_paid">
			<name>
				<localizable_message type="lsserver.search.column.total_paid">
					<fields/>
					<plain_message>Total Paid</plain_message>
				</localizable_message>
			</name>
			<type>MONEY</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.voided">
			<name>
				<localizable_message type="lsserver.search.column.voided">
					<fields/>
					<plain_message>Voided</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
			<required>false</required>
			<default>true</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.modified_date">
			<name>
				<localizable_message type="lsserver.search.column.modified_date">
					<fields/>
					<plain_message>Modified Date</plain_message>
				</localizable_message>
			</name>
			<type>DATETIME</type>
			<required>false</required>
			<default>false</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.drop_shipment">
			<name>
				<localizable_message type="lsserver.search.column.drop_shipment">
					<fields/>
					<plain_message>Drop Shipment</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
			<required>false</required>
			<default>false</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.shipping_method">
			<name>
				<localizable_message type="lsserver.search.column.shipping_method">
					<fields/>
					<plain_message>Shipping Method</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>false</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.terms">
			<name>
				<localizable_message type="lsserver.search.column.terms">
					<fields/>
					<plain_message>Terms</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>false</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.currency">
			<name>
				<localizable_message type="lsserver.search.column.currency">
					<fields/>
					<plain_message>Currency</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
			<required>false</required>
			<default>false</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
		<column id="lsserver.search.column.created">
			<name>
				<localizable_message type="lsserver.search.column.created">
					<fields/>
					<plain_message>Created</plain_message>
				</localizable_message>
			</name>
			<type>DATETIME</type>
			<required>false</required>
			<default>false</default>
			<sort_default>false</sort_default>
			<sort_default_order_by>ASC</sort_default_order_by>
			<can_summarize>false</can_summarize>
		</column>
	</columns>
	<filters>
		<filter id="lsserver.search.filters.invoice_id">
			<name>
				<localizable_message type="lsserver.search.filters.invoice_id">
					<fields/>
					<plain_message>Invoice ID</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.customer_id">
			<name>
				<localizable_message type="lsserver.search.filters.customer_id">
					<fields/>
					<plain_message>Customer ID</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.customer_name">
			<name>
				<localizable_message type="lsserver.search.filters.customer_name">
					<fields/>
					<plain_message>Customer Name</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.customer_phone">
			<name>
				<localizable_message type="lsserver.search.filters.customer_phone">
					<fields/>
					<plain_message>Customer Phone</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.customer_po">
			<name>
				<localizable_message type="lsserver.search.filters.customer_po">
					<fields/>
					<plain_message>Customer PO</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_id">
			<name>
				<localizable_message type="lsserver.search.filters.product_id">
					<fields/>
					<plain_message>Product ID</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.upc">
			<name>
				<localizable_message type="lsserver.search.filters.upc">
					<fields/>
					<plain_message>UPC</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_code">
			<name>
				<localizable_message type="lsserver.search.filters.product_code">
					<fields/>
					<plain_message>Product Code</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_description">
			<name>
				<localizable_message type="lsserver.search.filters.product_description">
					<fields/>
					<plain_message>Product Description</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_class">
			<name>
				<localizable_message type="lsserver.search.filters.product_class">
					<fields/>
					<plain_message>Product Class</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_family">
			<name>
				<localizable_message type="lsserver.search.filters.product_family">
					<fields/>
					<plain_message>Product Family</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_size">
			<name>
				<localizable_message type="lsserver.search.filters.product_size">
					<fields/>
					<plain_message>Product Size</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.product_color">
			<name>
				<localizable_message type="lsserver.search.filters.product_color">
					<fields/>
					<plain_message>Product Color</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.serial_number">
			<name>
				<localizable_message type="lsserver.search.filters.serial_number">
					<fields/>
					<plain_message>Serial Number</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.total_owing">
			<name>
				<localizable_message type="lsserver.search.filters.total_owing">
					<fields/>
					<plain_message>Total Owing</plain_message>
				</localizable_message>
			</name>
			<type>MONEY</type>
		</filter>
		<filter id="lsserver.search.filters.posted">
			<name>
				<localizable_message type="lsserver.search.filters.posted">
					<fields/>
					<plain_message>Posted</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
		</filter>
		<filter id="lsserver.search.filters.exported">
			<name>
				<localizable_message type="lsserver.search.filters.exported">
					<fields/>
					<plain_message>Exported</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
		</filter>
		<filter id="lsserver.search.filters.user">
			<name>
				<localizable_message type="lsserver.search.filters.user">
					<fields/>
					<plain_message>User</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.drop_shipment">
			<name>
				<localizable_message type="lsserver.search.filters.drop_shipment">
					<fields/>
					<plain_message>Drop Shipment</plain_message>
				</localizable_message>
			</name>
			<type>BOOLEAN</type>
		</filter>
		<filter id="lsserver.search.filters.station">
			<name>
				<localizable_message type="lsserver.search.filters.station">
					<fields/>
					<plain_message>Station</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.printed_notes">
			<name>
				<localizable_message type="lsserver.search.filters.printed_notes">
					<fields/>
					<plain_message>Printed Notes</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.internal_notes">
			<name>
				<localizable_message type="lsserver.search.filters.internal_notes">
					<fields/>
					<plain_message>Internal Notes</plain_message>
				</localizable_message>
			</name>
			<type>STRING</type>
		</filter>
		<filter id="lsserver.search.filters.created_date">
			<name>
				<localizable_message type="lsserver.search.filters.created_date">
					<fields/>
					<plain_message>Created Date</plain_message>
				</localizable_message>
			</name>
			<type>DATE</type>
		</filter>
		<filter id="lsserver.search.filters.modified_date">
			<name>
				<localizable_message type="lsserver.search.filters.modified_date">
					<fields/>
					<plain_message>Modified Date</plain_message>
				</localizable_message>
			</name>
			<type>DATE</type>
		</filter>
	</filters>
</search_criteria>

Search by Date

A POST request to /api/invoices/search/ is used to search invoices.

"""
Search invoices using the OnSite API.
"""
import requests
from xml.dom import minidom

# Customize these to your install.
ONSITE_HOST = 'localhost'
ONSITE_PORT = 9630
ONSITE_USERNAME = 'lightspeed'
ONSITE_PASSWORD = 'admin'
APP_ID = 'com.lightspeed.onsite.demo'
APP_VERSION = '1.0'
APP_PRIVATE_ID = '12345678-90ab-cdef-1234-567890abcdef'

invoice_search_url = 'https://%s:%d/api/invoices/search/' % (ONSITE_HOST, ONSITE_PORT)
logout_url = 'https://%s:%d/api/sessions/current/logout/' % (ONSITE_HOST, ONSITE_PORT)

# This is the search information.
search_xml = """
<search>
    <page>
        <offset>0</offset>
        <count>5</count>
    </page>
    <search_query>
        <columns>
            <column id="lsserver.search.column.id"/>
            <column id="lsserver.search.column.created"/>
            <column id="lsserver.search.column.total"/>
            <column id="lsserver.search.column.status"/>
        </columns>
        <sort_by_column>
            <column id="lsserver.search.column.created"/>
            <order_by>ASC</order_by>
        </sort_by_column>
        <filters>lsserver.search.filters.created_date > '2017-07-05'</filters>
    </search_query>
</search>
"""

# Create a session. This will persist cookies across all requests.
session = requests.Session()
session.auth = (ONSITE_USERNAME, ONSITE_PASSWORD)
session.headers.update({
    'user-agent': '%s/%s' % (APP_ID, APP_VERSION),
    'x-pappid': APP_PRIVATE_ID})
session.verify = False

# Send the request to search the invoices.
post_response = session.post(invoice_search_url, data=search_xml)
assert post_response.status_code == 200

# Log out.
logout_response = session.post(logout_url)
assert logout_response.status_code == 204

# Print the search results.
response_xml = minidom.parseString(post_response.text)
print(response_xml.toprettyxml())
<!-- Response -->

<?xml version="1.0" ?>
<data>
    <info>
        <total_count>63</total_count>
    </info>
    <columns>
        <column>
            <name>
                <localizable_message type="lsserver.search.column.id">
                    <fields/>
                    <plain_message>ID</plain_message>
                </localizable_message>
            </name>
            <type>STRING</type>
        </column>
        <column>
            <name>
                <localizable_message type="lsserver.search.column.created">
                    <fields/>
                    <plain_message>Created</plain_message>
                </localizable_message>
            </name>
            <type>DATETIME</type>
        </column>
        <column>
            <name>
                <localizable_message type="lsserver.search.column.total">
                    <fields/>
                    <plain_message>Total</plain_message>
                </localizable_message>
            </name>
            <type>MONEY</type>
        </column>
        <column>
            <name>
                <localizable_message type="lsserver.search.column.status">
                    <fields/>
                    <plain_message>Status</plain_message>
                </localizable_message>
            </name>
            <type>STRING</type>
        </column>
    </columns>
    <rows>
        <row>
            <links>
                <link>
                    <invoice id="1" uri="https://localhost:9630/api/invoices/1/"/>
                </link>
            </links>
            <cell>
                <type>STRING</type>
                <value>I-1</value>
            </cell>
            <cell>
                <type>DATETIME</type>
                <value>2017-07-07 13:02:56.764721</value>
            </cell>
            <cell>
                <type>MONEY</type>
                <value>0.00</value>
            </cell>
            <cell>
                <type>STRING</type>
                <value>Paid</value>
            </cell>
        </row>
        <row>
            <links>
                <link>
                    <invoice id="2" uri="https://localhost:9630/api/invoices/2/"/>
                </link>
            </links>
            <cell>
                <type>STRING</type>
                <value>I-2</value>
            </cell>
            <cell>
                <type>DATETIME</type>
                <value>2017-07-07 13:03:53.450728</value>
            </cell>
            <cell>
                <type>MONEY</type>
                <value>50.00</value>
            </cell>
            <cell>
                <type>STRING</type>
                <value>Owing</value>
            </cell>
        </row>
        <row>
            <links>
                <link>
                    <invoice id="3" uri="https://localhost:9630/api/invoices/3/"/>
                </link>
            </links>
            <cell>
                <type>STRING</type>
                <value>I-3</value>
            </cell>
            <cell>
                <type>DATETIME</type>
                <value>2017-07-07 13:15:46.143926</value>
            </cell>
            <cell>
                <type>MONEY</type>
                <value>0.00</value>
            </cell>
            <cell>
                <type>STRING</type>
                <value>Paid</value>
            </cell>
        </row>
        <row>
            <links>
                <link>
                    <invoice id="4" uri="https://localhost:9630/api/invoices/4/"/>
                </link>
            </links>
            <cell>
                <type>STRING</type>
                <value>I-4</value>
            </cell>
            <cell>
                <type>DATETIME</type>
                <value>2017-07-07 13:17:28.869141</value>
            </cell>
            <cell>
                <type>MONEY</type>
                <value>0.00</value>
            </cell>
            <cell>
                <type>STRING</type>
                <value>Paid</value>
            </cell>
        </row>
        <row>
            <links>
                <link>
                    <invoice id="5" uri="https://localhost:9630/api/invoices/5/"/>
                </link>
            </links>
            <cell>
                <type>STRING</type>
                <value>I-5</value>
            </cell>
            <cell>
                <type>DATETIME</type>
                <value>2017-07-07 13:33:53.446989</value>
            </cell>
            <cell>
                <type>MONEY</type>
                <value>60.70</value>
            </cell>
            <cell>
                <type>STRING</type>
                <value>Paid</value>
            </cell>
        </row>
    </rows>
</data>