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