Overview
TheReceiptsAPI
provides methods to add detailed receipt information to transactions, including itemized purchases, tax details, and merchant information. This enables rich transaction data for expense tracking and reporting.
Methods
create()
Add detailed receipt information to a transaction.Copy
def create(
self,
transaction_id: str,
total: int,
currency: str = "GBP",
merchant_name: str = "",
merchant_address: Optional[str] = None,
merchant_phone: Optional[str] = None,
merchant_email: Optional[str] = None,
items: Optional[list] = None,
taxes: Optional[list] = None,
**kwargs
) -> Receipt:
"""Create a detailed receipt for a transaction."""
transaction_id
: The unique transaction identifiertotal
: Total receipt amount in poundscurrency
: Currency code (default “GBP”)merchant_name
: Name of the merchantmerchant_address
: Merchant address (optional)merchant_phone
: Merchant phone number (optional)merchant_email
: Merchant email (optional)items
: List of receipt items (optional)taxes
: List of tax details (optional)
Receipt
- The created receipt object
Receipt Creation Examples
Basic Receipt
Create a simple receipt with basic information:Copy
from monzoh import MonzoClient
client = MonzoClient()
# Get a transaction to add receipt to
accounts = client.accounts.list()
transactions = client.transactions.list(
account_id=accounts[0].id,
limit=1
)
transaction_id = transactions[0].id
# Create basic receipt
receipt = client.receipts.create(
transaction_id=transaction_id,
total=1250, # £12.50 in pence
currency="GBP",
merchant_name="Corner Coffee Shop",
merchant_address="123 High Street, London SW1A 1AA",
merchant_phone="+44 20 7946 0958"
)
print(f"✅ Receipt created: {receipt.id}")
print(f"📄 Merchant: {receipt.merchant_name}")
print(f"💰 Total: £{receipt.total / 100:.2f}")
Detailed Receipt with Items
Create a comprehensive receipt with itemized purchases:Copy
# Detailed receipt with line items
receipt_items = [
{
"description": "Large Cappuccino",
"unit_price": 350, # £3.50 in pence
"quantity": 1,
"total_price": 350,
"currency": "GBP",
"category": "beverages"
},
{
"description": "Blueberry Muffin",
"unit_price": 280, # £2.80 in pence
"quantity": 1,
"total_price": 280,
"currency": "GBP",
"category": "food"
},
{
"description": "Extra Shot",
"unit_price": 50, # £0.50 in pence
"quantity": 2,
"total_price": 100,
"currency": "GBP",
"category": "extras"
}
]
# Tax information
tax_details = [
{
"description": "VAT",
"amount": 146, # £1.46 in pence (20% VAT)
"currency": "GBP",
"tax_number": "GB123456789"
}
]
# Create detailed receipt
receipt = client.receipts.create(
transaction_id=transaction_id,
total=876, # £8.76 total (£7.30 + £1.46 VAT)
currency="GBP",
merchant_name="Corner Coffee Shop",
merchant_address="123 High Street, London SW1A 1AA",
merchant_phone="+44 20 7946 0958",
merchant_email="orders@cornercoffee.com",
items=receipt_items,
taxes=tax_details
)
print(f"✅ Detailed receipt created")
print(f"📋 Items: {len(receipt_items)}")
print(f"💷 Subtotal: £{sum(item['total_price'] for item in receipt_items) / 100:.2f}")
print(f"🏛️ VAT: £{tax_details[0]['amount'] / 100:.2f}")
print(f"💰 Total: £{receipt.total / 100:.2f}")
Advanced Receipt Management
Grocery Receipt Parser
Parse grocery receipts and create detailed receipt records:Copy
from datetime import datetime
from typing import List, Dict, Any
import re
class GroceryReceiptManager:
def __init__(self):
self.client = MonzoClient()
def create_grocery_receipt(
self,
transaction_id: str,
store_name: str,
items_text: str,
store_info: Dict[str, str] = None
):
"""Create a grocery receipt from text input."""
# Parse items from text
items = self._parse_grocery_items(items_text)
# Calculate totals
subtotal = sum(item['total_price'] for item in items)
vat_rate = 0.20 # 20% VAT on applicable items
vat_amount = int(subtotal * vat_rate)
total = subtotal + vat_amount
# Default store info
default_store_info = store_info or {}
# Tax details
taxes = [{
"description": "VAT",
"amount": vat_amount,
"currency": "GBP"
}] if vat_amount > 0 else []
# Create receipt
receipt = self.client.receipts.create(
transaction_id=transaction_id,
total=total,
currency="GBP",
merchant_name=store_name,
merchant_address=default_store_info.get('address'),
merchant_phone=default_store_info.get('phone'),
items=items,
taxes=taxes
)
return receipt
def _parse_grocery_items(self, items_text: str) -> List[Dict[str, Any]]:
"""Parse grocery items from text input."""
items = []
lines = items_text.strip().split('\n')
for line in lines:
line = line.strip()
if not line:
continue
# Try to parse: "Item Name x2 @ £1.50 = £3.00"
pattern = r'(.+?)\s*x?(\d+)?\s*@?\s*£(\d+\.?\d*)\s*=?\s*£?(\d+\.?\d*)?'
match = re.match(pattern, line)
if match:
description = match.group(1).strip()
quantity = int(match.group(2)) if match.group(2) else 1
unit_price = float(match.group(3))
total_price = float(match.group(4)) if match.group(4) else unit_price * quantity
items.append({
"description": description,
"unit_price": int(unit_price * 100), # Convert to pence
"quantity": quantity,
"total_price": int(total_price * 100), # Convert to pence
"currency": "GBP",
"category": self._categorize_item(description)
})
else:
# Fallback: simple "Item Name £2.50"
simple_pattern = r'(.+?)\s+£(\d+\.?\d*)'
simple_match = re.match(simple_pattern, line)
if simple_match:
description = simple_match.group(1).strip()
price = float(simple_match.group(2))
items.append({
"description": description,
"unit_price": int(price * 100),
"quantity": 1,
"total_price": int(price * 100),
"currency": "GBP",
"category": self._categorize_item(description)
})
return items
def _categorize_item(self, description: str) -> str:
"""Categorize grocery items."""
description_lower = description.lower()
categories = {
'dairy': ['milk', 'cheese', 'butter', 'yogurt', 'cream'],
'meat': ['chicken', 'beef', 'pork', 'fish', 'salmon', 'turkey'],
'vegetables': ['carrot', 'potato', 'onion', 'tomato', 'lettuce', 'pepper'],
'fruits': ['apple', 'banana', 'orange', 'grape', 'berry'],
'bakery': ['bread', 'rolls', 'cake', 'pastry', 'croissant'],
'beverages': ['juice', 'water', 'coffee', 'tea', 'soda'],
'frozen': ['frozen', 'ice cream'],
'household': ['detergent', 'soap', 'shampoo', 'toilet paper']
}
for category, keywords in categories.items():
if any(keyword in description_lower for keyword in keywords):
return category
return 'other'
# Usage example
def create_sample_grocery_receipt():
manager = GroceryReceiptManager()
# Get a recent transaction
accounts = manager.client.accounts.list()
transactions = manager.client.transactions.list(
account_id=accounts[0].id,
limit=5
)
# Find a transaction that looks like grocery shopping
grocery_transaction = None
for txn in transactions:
if txn.amount < 0 and any(word in txn.description.lower()
for word in ['tesco', 'sainsbury', 'asda', 'grocery']):
grocery_transaction = txn
break
if not grocery_transaction:
print("No grocery transaction found")
return
# Sample grocery items
items_text = """
Organic Bananas x3 @ £0.90 = £2.70
Semi-Skimmed Milk 2L £1.25
Sourdough Bread £2.50
Free Range Eggs x12 £3.20
Cheddar Cheese 200g £2.80
Fresh Salmon Fillet 400g £6.50
Baby Spinach 100g £1.50
Cherry Tomatoes 250g £2.25
"""
store_info = {
'address': '456 Shopping Street, London E1 6AN',
'phone': '+44 20 7946 0123'
}
print(f"📄 Creating receipt for transaction: {grocery_transaction.description}")
print(f"💰 Transaction amount: £{abs(grocery_transaction.amount) / 100:.2f}")
receipt = manager.create_grocery_receipt(
transaction_id=grocery_transaction.id,
store_name="Tesco Express",
items_text=items_text,
store_info=store_info
)
if receipt:
print(f"✅ Grocery receipt created successfully")
print(f"📋 Receipt ID: {receipt.id}")
print(f"🛒 Items: {len(receipt.items) if receipt.items else 0}")
if __name__ == "__main__":
create_sample_grocery_receipt()
Restaurant Receipt Builder
Create detailed restaurant receipts with tip calculations:Copy
class RestaurantReceiptBuilder:
def __init__(self):
self.client = MonzoClient()
def create_restaurant_receipt(
self,
transaction_id: str,
restaurant_name: str,
menu_items: List[Dict],
service_charge: float = 0.125, # 12.5% service charge
restaurant_info: Dict[str, str] = None
):
"""Create a detailed restaurant receipt."""
# Calculate subtotal
food_subtotal = sum(item['price'] * item['quantity'] for item in menu_items)
# Convert menu items to receipt format
receipt_items = []
for item in menu_items:
unit_price = int(item['price'] * 100) # Convert to pence
quantity = item['quantity']
total_price = int(item['price'] * quantity * 100)
receipt_items.append({
"description": item['name'],
"unit_price": unit_price,
"quantity": quantity,
"total_price": total_price,
"currency": "GBP",
"category": item.get('category', 'food')
})
# Add service charge if applicable
if service_charge > 0:
service_amount = food_subtotal * service_charge
receipt_items.append({
"description": f"Service Charge ({service_charge*100:.1f}%)",
"unit_price": int(service_amount * 100),
"quantity": 1,
"total_price": int(service_amount * 100),
"currency": "GBP",
"category": "service"
})
# Calculate total
subtotal = food_subtotal + (food_subtotal * service_charge if service_charge else 0)
vat_amount = subtotal * 0.20 # 20% VAT
total = subtotal + vat_amount
# Tax information
taxes = [{
"description": "VAT",
"amount": int(vat_amount * 100),
"currency": "GBP"
}]
# Restaurant info
info = restaurant_info or {}
# Create receipt
receipt = self.client.receipts.create(
transaction_id=transaction_id,
total=int(total * 100),
currency="GBP",
merchant_name=restaurant_name,
merchant_address=info.get('address'),
merchant_phone=info.get('phone'),
merchant_email=info.get('email'),
items=receipt_items,
taxes=taxes
)
return receipt
def create_receipt_from_bill_photo(self, transaction_id: str, bill_text: str):
"""Create receipt from OCR'd bill text."""
# This would integrate with OCR service to extract text from bill photos
# Then parse the text to extract items, prices, etc.
lines = bill_text.split('\n')
items = []
restaurant_name = "Unknown Restaurant"
for line in lines:
line = line.strip()
# Try to extract restaurant name from first line
if not items and len(line) > 5 and not any(c.isdigit() for c in line):
restaurant_name = line
continue
# Parse menu items: "Margherita Pizza £12.50"
item_pattern = r'(.+?)\s+£(\d+\.?\d*)'
match = re.match(item_pattern, line)
if match:
item_name = match.group(1).strip()
price = float(match.group(2))
# Skip service charges, VAT, etc.
if any(word in item_name.lower()
for word in ['service', 'vat', 'tax', 'total', 'subtotal']):
continue
items.append({
'name': item_name,
'price': price,
'quantity': 1,
'category': 'food'
})
if items:
return self.create_restaurant_receipt(
transaction_id=transaction_id,
restaurant_name=restaurant_name,
menu_items=items
)
return None
# Usage
def create_sample_restaurant_receipt():
builder = RestaurantReceiptBuilder()
# Sample restaurant order
menu_items = [
{'name': 'Caesar Salad (Starter)', 'price': 8.50, 'quantity': 1, 'category': 'starter'},
{'name': 'Grilled Salmon', 'price': 18.95, 'quantity': 1, 'category': 'main'},
{'name': 'Ribeye Steak', 'price': 24.50, 'quantity': 1, 'category': 'main'},
{'name': 'Chocolate Brownie', 'price': 7.25, 'quantity': 1, 'category': 'dessert'},
{'name': 'Glass of House Red', 'price': 6.50, 'quantity': 2, 'category': 'beverage'},
]
restaurant_info = {
'address': '789 Fine Dining Street, London W1K 3AB',
'phone': '+44 20 7946 0456',
'email': 'reservations@finedining.co.uk'
}
# Get a recent transaction
client = MonzoClient()
accounts = client.accounts.list()
transactions = client.transactions.list(
account_id=accounts[0].id,
limit=5
)
# Find a restaurant-like transaction
restaurant_transaction = None
for txn in transactions:
if txn.amount < 0:
restaurant_transaction = txn
break
if restaurant_transaction:
receipt = builder.create_restaurant_receipt(
transaction_id=restaurant_transaction.id,
restaurant_name="The Fine Dining Co.",
menu_items=menu_items,
service_charge=0.125, # 12.5%
restaurant_info=restaurant_info
)
print(f"🍽️ Restaurant receipt created")
print(f"📄 Receipt ID: {receipt.id}")
# Calculate and display breakdown
food_total = sum(item['price'] * item['quantity'] for item in menu_items)
service = food_total * 0.125
subtotal = food_total + service
vat = subtotal * 0.20
total = subtotal + vat
print(f"💰 Breakdown:")
print(f" Food & Drink: £{food_total:.2f}")
print(f" Service (12.5%): £{service:.2f}")
print(f" Subtotal: £{subtotal:.2f}")
print(f" VAT (20%): £{vat:.2f}")
print(f" Total: £{total:.2f}")
if __name__ == "__main__":
create_sample_restaurant_receipt()
Receipt Analytics
Analyze receipt data for insights:Copy
def analyze_receipt_data():
"""Analyze receipt data across transactions."""
client = MonzoClient()
accounts = client.accounts.list()
current_account = accounts[0]
# Get transactions with receipts
since = datetime.now(tz=datetime.timezone.utc) - timedelta(days=60)
transactions = client.transactions.list(
account_id=current_account.id,
since=since,
limit=200
)
# This is a simplified example - in reality you'd need to fetch
# receipt data separately using transaction IDs
transactions_with_receipts = [
t for t in transactions
if t.amount < 0 and hasattr(t, 'receipt') and t.receipt
]
print(f"📊 Receipt Analytics (60 days)")
print("=" * 35)
print(f"Total transactions analyzed: {len(transactions)}")
print(f"Transactions with receipts: {len(transactions_with_receipts)}")
# Category spending from receipts
from collections import defaultdict
category_spending = defaultdict(float)
# This would require fetching actual receipt data
# For demo purposes, we'll use transaction categories
for txn in transactions:
if txn.amount < 0 and txn.category:
category_spending[txn.category] += abs(txn.amount) / 100
print(f"\n💰 Spending by Category:")
for category, amount in sorted(category_spending.items(),
key=lambda x: x[1], reverse=True):
print(f" {category.title()}: £{amount:.2f}")
# Average transaction size
spending_amounts = [abs(t.amount) / 100 for t in transactions if t.amount < 0]
if spending_amounts:
avg_spending = sum(spending_amounts) / len(spending_amounts)
print(f"\n📈 Average transaction: £{avg_spending:.2f}")
if __name__ == "__main__":
analyze_receipt_data()
Best Practices
- Accurate totals: Ensure receipt totals match transaction amounts
- Detailed items: Include as much item detail as possible for better expense tracking
- Tax information: Always include VAT/tax details where applicable
- Merchant info: Provide complete merchant information for record keeping
- Currency consistency: Use consistent currency codes throughout
- Validation: Validate calculated totals against actual transaction amounts