Skip to main content

PayPal

Learn how to automate PayPal operations using Abstra connectors through practical, focused tutorials.

API Behavior

run_connection_action() returns the data directly and automatically raises an exception if an error occurs. You don't need to check for status == "success" - just use try/except for error handling.

Getting Startedโ€‹

Prerequisitesโ€‹

  • PayPal Business account
  • PayPal Developer account access
  • API credentials (Client ID and Secret)
  • Abstra project

Quick Setupโ€‹

  1. Go to PayPal Developer Dashboard
  2. Create an app (e.g., "Abstra Integration")
  3. Get your credentials (Client ID and Secret)
  4. Add PayPal connector in Abstra Console
  5. Enter your credentials and select environment:
    • Sandbox: For testing (fake money)
    • Production: For live transactions (real money)

Test your connection:

from abstra.connectors import run_connection_action

# List invoices
result = run_connection_action(
"paypal",
"invoicing/get_v2_invoicing_invoices"
)
print(f"โœ“ Connection works! Found {len(result['items'])} invoices")

๐Ÿงพ Invoice Tutorialsโ€‹

Learn how to manage invoices in PayPal:

1. Listing and Searching Invoicesโ€‹

Find and filter invoices using various criteria.

You'll learn:

  • List all invoices
  • Filter by status (PAID, SENT, DRAFT)
  • Search by date range
  • Filter by customer email
  • Pagination for large datasets
# Quick example
result = run_connection_action("paypal", "invoicing/get_v2_invoicing_invoices")
invoices = result["items"]

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

2. Getting Invoice Details and Transactionsโ€‹

Retrieve complete invoice information including payment transactions.

You'll learn:

  • Get invoice by ID
  • View transaction details (payment ID, date, method)
  • Check payment status
  • Extract customer information
  • Get invoice items and amounts
# Quick example
invoice_id = "INV2-XXXX-XXXX-XXXX-XXXX"
result = run_connection_action("paypal",
"invoicing/get_v2_invoicing_invoices_by_invoice_id",
params={"invoice_id": invoice_id}
)

invoice = result
print(f"Invoice: {invoice['detail']['invoice_number']}")
print(f"Amount: ${invoice['amount']['value']}")

Common Patternsโ€‹

List and Process Patternโ€‹

from abstra.connectors import run_connection_action

# 1. List all invoices
result = run_connection_action("paypal", "invoicing/get_v2_invoicing_invoices")
invoices = result["items"]

# 2. Process each invoice
for invoice in invoices:
if invoice["status"] == "PAID":
# Get detailed information
detail = run_connection_action(
"paypal",
"invoicing/get_v2_invoicing_invoices_by_invoice_id",
{"invoice_id": invoice["id"]}
)
# ... process invoice details

Filter and Aggregate Patternโ€‹

from abstra.connectors import run_connection_action
from collections import defaultdict

# Get all invoices
result = run_connection_action("paypal", "invoicing/get_v2_invoicing_invoices")
invoices = result["items"]

# Group by customer
customers = defaultdict(lambda: {"count": 0, "total": 0.0})

for inv in invoices:
if inv["status"] == "PAID":
email = inv["primary_recipients"][0]["billing_info"]["email_address"]
customers[email]["count"] += 1
customers[email]["total"] += float(inv["amount"]["value"])

# Display results
for email, data in customers.items():
print(f"{email}: {data['count']} invoices, ${data['total']:.2f}")

Search and Export Patternโ€‹

import csv
from abstra.connectors import run_connection_action

# Get invoices
result = run_connection_action("paypal", "invoicing/get_v2_invoicing_invoices")
invoices = result["items"]

# Export to CSV
with open("invoices.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Invoice Number", "Status", "Amount", "Customer"])

for inv in invoices:
writer.writerow([
inv["detail"]["invoice_number"],
inv["status"],
inv["amount"]["value"],
inv["primary_recipients"][0]["billing_info"]["email_address"]
])

Quick Referenceโ€‹

Invoice Operationsโ€‹

ActionPurposeKey Parameters
invoicing/get_v2_invoicing_invoicesList all invoicesNone (optional: pagination)
invoicing/get_v2_invoicing_invoices_by_invoice_idGet invoice detailsinvoice_id
invoicing/get_v2_invoicing_templatesList invoice templatesNone

Order Operationsโ€‹

ActionPurposeKey Parameters
checkout_orders/get_v2_checkout_orders_by_idGet order detailsid

Subscription Operationsโ€‹

ActionPurposeKey Parameters
billing_subscriptions/get_v1_billing_plansList billing plansNone
billing_subscriptions/get_v1_billing_plans_by_idGet plan detailsid
billing_subscriptions/get_v1_billing_subscriptions_by_idGet subscription detailsid

Payment Operationsโ€‹

ActionPurposeKey Parameters
payments_payment/get_v2_payments_captures_by_capture_idGet capture detailscapture_id
payments_payment/get_v2_payments_refunds_by_refund_idGet refund detailsrefund_id

Invoice Status Valuesโ€‹

StatusDescription
DRAFTInvoice created but not sent
SENTInvoice sent to customer
PAIDInvoice fully paid
MARKED_AS_PAIDManually marked as paid
CANCELLEDInvoice cancelled
REFUNDEDInvoice refunded
PARTIALLY_PAIDInvoice partially paid

Order Status Valuesโ€‹

StatusDescription
CREATEDOrder created
SAVEDOrder saved (not completed)
APPROVEDOrder approved by customer
VOIDEDOrder voided
COMPLETEDOrder completed

Best Practicesโ€‹

Environment Managementโ€‹

# โœ… Always specify environment in connector config (in Abstra Console)
# Sandbox for testing, Production for live data

# โœ… Test with Sandbox connection first
result = run_connection_action("paypal-sandbox", "invoicing/get_v2_invoicing_invoices")

# Production only for read operations
result = run_connection_action("paypal-production", "invoicing/get_v2_invoicing_invoices")

Error Handlingโ€‹

# โœ… Use try/except - run_connection_action raises exception on error
try:
invoices = run_connection_action("paypal", "invoicing/get_v2_invoicing_invoices")
# invoices is the data object with {"items": [...], "links": [...]}
for invoice in invoices["items"]:
print(invoice["detail"]["invoice_number"])
except Exception as e:
print(f"Error: {str(e)}")

Data Validationโ€‹

# โœ… Validate invoice has required fields
def safe_get_email(invoice):
try:
return invoice["primary_recipients"][0]["billing_info"]["email_address"]
except (KeyError, IndexError):
return "Unknown"

Paginationโ€‹

# โœ… Handle pagination for large datasets
def get_all_invoices(connection_name="paypal"):
all_invoices = []
page = 1

while True:
result = run_connection_action(
connection_name,
"invoicing/get_v2_invoicing_invoices",
{"page": page, "page_size": 100}
)

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

if len(items) < 100:
break
page += 1

return all_invoices

Troubleshootingโ€‹

"NOT_AUTHORIZED" Errorโ€‹

  • Cause: Missing API permissions
  • Solution: Enable required features in PayPal Developer Dashboard
    • Go to your app settings
    • Enable: Invoicing, Payments, Subscriptions, Transaction Search

Invalid Invoice IDโ€‹

  • Cause: Invoice ID format incorrect or invoice doesn't exist
  • Solution: Use the exact ID returned from get_v2_invoicing_invoices
    • Format: INV2-XXXX-XXXX-XXXX-XXXX

Empty Transaction Listโ€‹

  • Cause: Invoice not paid yet or payments not recorded
  • Solution: Check invoice status first
    • Only PAID or PARTIALLY_PAID invoices have transactions

Sandbox vs Production Confusionโ€‹

  • Cause: Using production credentials in sandbox or vice versa
  • Solution: Verify environment matches credentials
    • Sandbox URLs: api-m.sandbox.paypal.com
    • Production URLs: api-m.paypal.com

Rate Limitingโ€‹

  • Cause: Too many requests in short time
  • Solution: Implement exponential backoff
    import time

    def retry_with_backoff(func, max_retries=3):
    for i in range(max_retries):
    try:
    return func()
    except Exception as e:
    if i == max_retries - 1:
    raise
    time.sleep(2 ** i)

Resourcesโ€‹

Need Help?โ€‹

  • Check the specific tutorial for detailed examples
  • Review error messages in troubleshooting sections
  • Test with Sandbox environment first
  • Verify credentials and permissions
  • Check PayPal API status page for outages