Skip to content

Instantly share code, notes, and snippets.

@ssaunier
Last active November 3, 2017 16:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ssaunier/5237025 to your computer and use it in GitHub Desktop.
Save ssaunier/5237025 to your computer and use it in GitHub Desktop.
Simple REST Client for the Zoho Invoice API, using HTTParty. You can search for customers, create a new one, create a new invoice, add a payment and send it.
# Copyright Applidget - 2013
# Author : Sébastien Saunier (@ssaunier)
# Released under MIT License
require "httparty"
class Zoho
include HTTParty
base_uri 'invoice.zoho.com:443/api'
PAYMENT_METHODS = {
1 => "Check",
2 => "Cash",
3 => "Bank Transfer",
4 => "Paypal",
5 => "Credit Card",
6 => "Google Checkout",
8 => "Authorize.Net",
9 => "Bank Remittance",
10 => "Payflow Pro",
11 => "Stripe",
12 => "2Checkout"
}
# Zoho constructor
#
# api_key: One time process. A customer must request the API key by registering at https://zapi.zoho.com/apigen.do
# auth_token: Customer must go to https://accounts.zoho.com/apiauthtoken/create?SCOPE=ZohoInvoice/invoiceapi to generate it.
#
def initialize(api_key, auth_token)
@auth = {
:authtoken => auth_token,
:apikey => api_key,
:scope => :invoiceapi
}
end
# http://www.zoho.com/invoice/api/customers/customers.html#how-do-i-find-a-customer?
#
# Will return an array of hashes containing a customer.
def customers(search)
raise ArgumentError.new("You must provided a non empty search token") if search.blank?
result = self.class.get '/view/search/customers', :query => @auth.merge(:searchtext => search)
result["Response"]["Customers"]["Customer"] || []
end
# http://www.zoho.com/invoice/api/customers/customers.html#how-do-i-add-a-customer?
#
# Options to provide:
# - Name (mandatory)
# - PaymentsDue (e.g. "0")
# - CurrencyCode (e.g. "EUR")
# - BillingAddress, BillingCity, BillingZip, BillingCountry, BillingFax
# - Contacts => Array of Contact:
# - Salutation, FirstName, LastName, EMail, Phone, Mobile
#
# Will return a couple:
# 1. Hash containing the created customer, with id at key "CustomerID"
# 2. Error message if first element is nil because it could not be created.
def create_customer(options)
create(:customer, nil, nil, options)
end
# http://www.zoho.com/invoice/api/invoices/invoices.html#how-do-i-add-an-Invoice?
#
# Options to provide:
# - InvoiceItems => Array of InvoiceItem
# - ItemName
# - ItemDescription
# - Price
# - Quantity
# - Discount
# - Tax1Name
# - Tax2Name
# - Comments => Array of Comment:
# - Description
# - Notes
# - Terms
#
# Will return a couple:
# 1. Hash containing the created invoice, with id at key "InvoiceID"
# 2. Error message if first element is nil because it could not be created.
def create_invoice(customer_id, options)
create(:invoice, :customer, customer_id, options)
end
# http://www.zoho.com/invoice/api/payments.html#how-do-i-add-a-payment-to-an-invoice?
#
# Adding a payment to a method will automatically change its status from "Draft" to "Open".
#
# Options to provide:
# - Mode (1->Cheque, 2->Cash, 3->Bank Transfer, 4->PayPal, 5->CreditCard, 6->GoogleCheckOut, 7->Applied from Credit, 8->Authorize.Net, 9->Bank Remittance)
# - Description
# - Date (format: "yyyy-mm-dd". If not given, today's taken)
# - Amount (float)
#
# Will return a couple:
# 1. Hash containing the created payment, with id at key "PaymentID"
# 2. Error message if first element is nil because it could not be created.
def create_payment(invoice_id, options)
create(:payment, :invoice, invoice_id, options)
end
# http://www.zoho.com/invoice/api/invoices/invoices.html#how-do-i-send-an-invoice?
#
# Options to provide
# - Custom.Subject
# - Custom.Body
# - ToEMailIDs (emails, comma separated)
# - CCEMailIDs
def send_invoice(invoice_id, options)
options.merge! :InvoiceID => invoice_id
self.class.post '/invoices/send', :body => @auth.merge(options)
end
def get_invoice(invoice_id)
result = self.class.get "/invoices/#{invoice_id}", :query => @auth
result["Response"]["Invoice"]
end
private
def create(type, parent_type, parent_id, options)
object = parent_type.nil? ? {} : { "#{parent_type.capitalize}ID" => parent_id }
options.each do |key, value|
object[key] = value unless value.blank?
end
body = @auth.merge :XMLString => object.to_xml(:root => type.capitalize)
result = self.class.post "/#{type}s/create", :body => body
# Zoho API is really poor at handling HTTP status codes. 200 is returned
# when the object was not created because of an error.
return result["Response"][type.capitalize.to_s], result["Response"]["Message"]
end
end
@ganeshprabhu
Copy link

This is latest api documentation:
https://www.zoho.com/invoice/api/v3/#introduction
and no need to create apikey from zapi.zoho.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment