Skip to main content

Listing and Searching Invoices

Learn how to list, filter, and search PayPal invoices using various criteria.

Basic Invoice Listing​

List All Invoices​

The simplest way to get invoices is to retrieve all of them:

from abstra.connectors import run_connection_action

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]
print(f"Total invoices: {len(invoices)}")

for invoice in invoices:
print(f"Invoice: {invoice['detail']['invoice_number']}")
print(f"Status: {invoice['status']}")
print(f"Amount: ${invoice['amount']['value']} {invoice['amount']['currency_code']}")
print("---")

Expected Output:

Total invoices: 20
Invoice: SCRANTON-2024-001
Status: PAID
Amount: $1,234.56 USD
---
Invoice: SCRANTON-2024-002
Status: SENT
Amount: $567.89 USD
---

Filtering Invoices​

Filter by Status​

Find invoices with specific status (PAID, SENT, DRAFT, etc.):

from abstra.connectors import run_connection_action

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Filter paid invoices
paid_invoices = [inv for inv in invoices if inv["status"] == "PAID"]
print(f"Paid invoices: {len(paid_invoices)}")

# Filter sent (unpaid) invoices
sent_invoices = [inv for inv in invoices if inv["status"] == "SENT"]
print(f"Sent invoices: {len(sent_invoices)}")

# Show sent invoices details
for invoice in sent_invoices:
customer_email = invoice["primary_recipients"][0]["billing_info"]["email_address"]
print(f"\nOverdue: {invoice['detail']['invoice_number']}")
print(f"Customer: {customer_email}")
print(f"Amount Due: ${invoice['due_amount']['value']}")

Expected Output:

Paid invoices: 18
Sent invoices: 2

Overdue: SCRANTON-2024-002
Customer: dwight.schrute@dundermifflin.com
Amount Due: $192.16

Filter Multiple Statuses​

from abstra.connectors import run_connection_action

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Filter invoices that need attention
statuses_to_check = ["SENT", "PARTIALLY_PAID"]
needs_attention = [
inv for inv in invoices
if inv["status"] in statuses_to_check
]

print(f"Invoices needing attention: {len(needs_attention)}")

for invoice in needs_attention:
print(f"\nInvoice: {invoice['detail']['invoice_number']}")
print(f"Status: {invoice['status']}")
print(f"Due: ${invoice['due_amount']['value']}")

Filter by Customer​

Find all invoices for a specific customer:

from abstra.connectors import run_connection_action

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Filter by customer email
customer_email = "michael.scott@dundermifflin.com"

customer_invoices = [
inv for inv in invoices
if inv["primary_recipients"][0]["billing_info"]["email_address"] == customer_email
]

print(f"Invoices for {customer_email}: {len(customer_invoices)}")

total = sum(float(inv["amount"]["value"]) for inv in customer_invoices)
paid = sum(
float(inv["amount"]["value"])
for inv in customer_invoices
if inv["status"] == "PAID"
)
due = total - paid

print(f"Total invoiced: ${total:.2f}")
print(f"Total paid: ${paid:.2f}")
print(f"Amount due: ${due:.2f}")

Expected Output:

Invoices for michael.scott@dundermifflin.com: 5
Total invoiced: $5,432.10
Total paid: $4,500.00
Amount due: $932.10

Filter by Date Range​

Find invoices within a date range:

from abstra.connectors import run_connection_action
from datetime import datetime

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Define date range
start_date = datetime(2024, 10, 1).date()
end_date = datetime(2024, 10, 31).date()

invoices_in_range = []

for invoice in invoices:
invoice_date_str = invoice["detail"]["invoice_date"]
invoice_date = datetime.strptime(invoice_date_str, "%Y-%m-%d").date()

if start_date <= invoice_date <= end_date:
invoices_in_range.append(invoice)

print(f"Invoices in October 2024: {len(invoices_in_range)}")

for invoice in invoices_in_range:
print(f" {invoice['detail']['invoice_date']}: {invoice['detail']['invoice_number']}")

Expected Output:

Invoices in October 2024: 8
2024-10-05: SCRANTON-2024-015
2024-10-10: SCRANTON-2024-016
2024-10-12: SCRANTON-2024-017
...

Filter by Amount Range​

Find invoices within a specific amount range:

from abstra.connectors import run_connection_action

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Find invoices between $100 and $500
min_amount = 100.00
max_amount = 500.00

invoices_in_range = [
inv for inv in invoices
if min_amount <= float(inv["amount"]["value"]) <= max_amount
]

print(f"Invoices between ${min_amount} and ${max_amount}: {len(invoices_in_range)}")

for invoice in invoices_in_range:
print(f" ${invoice['amount']['value']}: {invoice['detail']['invoice_number']}")

Expected Output:

Invoices between $100.0 and $500.0: 12
$234.56: SCRANTON-2024-003
$456.78: SCRANTON-2024-007
$123.45: SCRANTON-2024-011
...

Advanced Filtering​

Combine Multiple Filters​

Create complex filters by combining multiple criteria:

from abstra.connectors import run_connection_action
from datetime import datetime, timedelta

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Find high-value unpaid invoices from last 30 days
thirty_days_ago = (datetime.now() - timedelta(days=30)).date()

filtered_invoices = []

for invoice in invoices:
# Check status
if invoice["status"] != "SENT":
continue

# Check amount
if float(invoice["amount"]["value"]) < 500:
continue

# Check date
invoice_date = datetime.strptime(
invoice["detail"]["invoice_date"],
"%Y-%m-%d"
).date()

if invoice_date < thirty_days_ago:
continue

filtered_invoices.append(invoice)

print(f"High-value unpaid invoices (last 30 days): {len(filtered_invoices)}")

for invoice in filtered_invoices:
customer_email = invoice["primary_recipients"][0]["billing_info"]["email_address"]
print(f"\n${invoice['amount']['value']}: {invoice['detail']['invoice_number']}")
print(f"Customer: {customer_email}")
print(f"Date: {invoice['detail']['invoice_date']}")

Reusable Filter Function​

Create a reusable function for common filters:

from abstra.connectors import run_connection_action
from typing import List, Dict, Optional
from datetime import datetime

def filter_invoices(
invoices: List[Dict],
status: Optional[str] = None,
customer_email: Optional[str] = None,
min_amount: Optional[float] = None,
max_amount: Optional[float] = None,
start_date: Optional[datetime] = None,
end_date: Optional[datetime] = None
) -> List[Dict]:
"""
Filter invoices by multiple criteria.
"""
filtered = invoices

# Filter by status
if status:
filtered = [inv for inv in filtered if inv["status"] == status]

# Filter by customer
if customer_email:
filtered = [
inv for inv in filtered
if inv["primary_recipients"][0]["billing_info"]["email_address"] == customer_email
]

# Filter by amount
if min_amount is not None:
filtered = [inv for inv in filtered if float(inv["amount"]["value"]) >= min_amount]

if max_amount is not None:
filtered = [inv for inv in filtered if float(inv["amount"]["value"]) <= max_amount]

# Filter by date
if start_date or end_date:
date_filtered = []
for inv in filtered:
inv_date = datetime.strptime(inv["detail"]["invoice_date"], "%Y-%m-%d").date()

if start_date and inv_date < start_date.date():
continue
if end_date and inv_date > end_date.date():
continue

date_filtered.append(inv)

filtered = date_filtered

return filtered

# Usage example
connection_name = "paypal"
result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Find paid invoices over $200 in October
filtered = filter_invoices(
invoices,
status="PAID",
min_amount=200.00,
start_date=datetime(2024, 10, 1),
end_date=datetime(2024, 10, 31)
)

print(f"Matching invoices: {len(filtered)}")

Pagination​

Handle large numbers of invoices with pagination:

from abstra.connectors import run_connection_action

def get_all_invoices(paypal_connector, max_pages=10):
"""
Retrieve all invoices with pagination support.
"""
all_invoices = []
page = 1

while page <= max_pages:
result = paypal_connector.run(
"invoicing/get_v2_invoicing_invoices",
params={
"page": page,
"page_size": 100
}
)

if result["status"] != "success":
print(f"Error on page {page}: {result.get('message')}")
break

items = result["items"]
all_invoices.extend(items)

print(f"Page {page}: {len(items)} invoices")

# Stop if we got less than a full page
if len(items) < 100:
break

page += 1

return all_invoices

# Usage
connection_name = "paypal"
all_invoices = get_all_invoices(paypal)
print(f"\nTotal invoices retrieved: {len(all_invoices)}")

Summary Statistics​

Generate summary statistics from invoice list:

from abstra.connectors import run_connection_action
from collections import defaultdict

connection_name = "paypal"

result = run_connection_action(connection_name, "invoicing/get_v2_invoicing_invoices")

if result["status"] == "success":
invoices = result["items"]

# Count by status
status_counts = defaultdict(int)
for invoice in invoices:
status_counts[invoice["status"]] += 1

print("Invoices by Status:")
for status, count in status_counts.items():
print(f" {status}: {count}")

# Calculate totals
total_invoiced = sum(float(inv["amount"]["value"]) for inv in invoices)
total_paid = sum(
float(inv["amount"]["value"])
for inv in invoices
if inv["status"] == "PAID"
)
total_due = sum(float(inv["due_amount"]["value"]) for inv in invoices)

print(f"\nFinancial Summary:")
print(f" Total Invoiced: ${total_invoiced:.2f}")
print(f" Total Paid: ${total_paid:.2f}")
print(f" Total Due: ${total_due:.2f}")

Expected Output:

Invoices by Status:
PAID: 18
SENT: 2

Financial Summary:
Total Invoiced: $8,456.78
Total Paid: $7,865.12
Total Due: $591.66

Best Practices​

  1. Always Check Status: Verify API response status before processing data
  2. Handle Missing Fields: Use .get() or try/except for optional fields
  3. Implement Pagination: Don't assume all invoices fit in one request
  4. Cache Results: Store invoice lists locally if querying multiple times
  5. Filter Locally: Get all invoices once, then filter in Python for better performance

Next Steps​