1# This is an example where we create a customized invoice with logos and attachments,
2# and a payment gateway, then send it by email to your address.
3
4from datetime import date
5from freshbooks import Client as FreshBooksClient
6from freshbooks import FreshBooksError
7
8FB_CLIENT_ID = "<your client id>"
9ACCESS_TOKEN = "<your access token>"
10ACCOUNT_ID = "<your account id>"
11DESTINATION_EMAIL = "<your email>" # Don't use the same email as the account owner.
12
13freshBooksClient = FreshBooksClient(client_id=FB_CLIENT_ID, access_token=ACCESS_TOKEN)
14
15# Create the client
16print("Creating client...")
17try:
18 client_data = {
19 "email": DESTINATION_EMAIL,
20 "organization": "Python SDK Test Client"
21 }
22 client = freshBooksClient.clients.create(ACCOUNT_ID, client_data)
23except FreshBooksError as e:
24 print(e)
25 print(e.status_code)
26 exit(1)
27
28print(f"Created client {client.id}")
29
30# Upload a logo and attachment with examples of file_path and file_stream.
31try:
32 print("Uploading invoice logo")
33 # We upload a file by providing the path to the file.
34 logo = freshBooksClient.images.upload(ACCOUNT_ID, file_path="./assets/sample_logo.png")
35
36 print("Uploading invoice attachment")
37 # We upload a file by opening it and providing the file stream.
38 attachment = freshBooksClient.attachments.upload(
39 ACCOUNT_ID, file_stream=open("./assets/sample_attachment.pdf", "rb")
40 )
41except FreshBooksError as e:
42 print(e)
43 print(e.status_code)
44 exit(1)
45
46# Create the invoice with taxed line items, a custom colour and logo, and an attachment.
47
48# Taxed line items
49line1 = {
50 "name": "A Taxed Item",
51 "description": "These things are taxed",
52 "qty": 2,
53 "taxAmount1": "13",
54 "taxName1": "HST",
55 "unit_cost": {
56 "amount": "27.00",
57 "code": "CAD"
58 }
59}
60line2 = {
61 "name": "Another Taxed ItemRegular Glasses",
62 "description": "With a different tax",
63 "qty": 4,
64 "taxAmount1": "5",
65 "taxName1": "GST",
66 "unit_cost": {
67 "amount": "6.95",
68 "code": "CAD"
69 }
70}
71
72presentation = {
73 "theme_primary_color": "#1fab13",
74 "theme_layout": "simple",
75 "theme_font_name": "modern",
76 "image_logo_src": f"/uploads/images/{logo.jwt}" # The logo upload response contains a jwt token
77}
78
79invoice_data = {
80 "customerid": client.id,
81 "create_date": date.today().isoformat(),
82 "due_offset_days": 5,
83 "lines": [line1, line2],
84 "attachments": [
85 {
86 "jwt": attachment.jwt,
87 "media_type": attachment.media_type
88 }
89 ],
90 "presentation": presentation
91}
92print("Creating invoice...")
93try:
94 invoice = freshBooksClient.invoices.create(ACCOUNT_ID, invoice_data)
95except FreshBooksError as e:
96 print(e)
97 print(e.status_code)
98 exit(1)
99
100print(f"Created invoice {invoice.invoice_number} (Id: {invoice.id})")
101print(f"Invoice total is {invoice.amount.amount} {invoice.amount.code}")
102
103# Once the invoice is created, a payment option can be added to it.
104print("Adding fbpay payment option...")
105payment_option_data = {
106 "gateway_name": "fbpay",
107 "entity_id": invoice.id,
108 "entity_type": "invoice",
109 "has_credit_card": True
110}
111try:
112 freshBooksClient.invoice_payment_options.create(ACCOUNT_ID, invoice.id, payment_option_data)
113except FreshBooksError as e:
114 print(e)
115 print(e.status_code)
116 exit(1)
117
118# Invoices are created in draft status, so we need to send it.
119print("Sending the invoice by email...")
120invoice_data = {
121 "action_email": True,
122 "email_recipients": [destination_email],
123 "email_include_pdf": False,
124 "invoice_customized_email": {
125 "subject": "Test Styled Invoice",
126 "body": "This was an example",
127 }
128}
129try:
130 invoice = freshBooksClient.invoices.update(ACCOUNT_ID, invoice.id, invoice_data)
131except FreshBooksError as e:
132 print(e)
133 print(e.status_code)
134 exit(1)