Python script to convert an Etsy sales export CSV into a Xero import CSV

We handle the accounting for our pop out cards shop using Xero. There are convenient pre-built integrations that handle Stripe and PayPal data in Xero, but nothing for Etsy, so I had to do a little Python script to generate a Xero import CSV file from the Etsy orders export CSV.

Here’s the script for future reference:


# Sold Orders
# e.g. EtsySoldOrders2020.csv

import argparse
import csv
from datetime import datetime
from io import TextIOWrapper
from typing import Dict


def convert_etsy_to_xero(etsy_file: TextIOWrapper):
    output_file = f"etsy_xero_orders_{}"
    with open(output_file, "w", newline="") as output_file:
        etsy_reader = csv.DictReader(etsy_file, delimiter=",", quotechar='"')
        xero_writer = csv.DictWriter(output_file, XERO_FIELDS,
                                     delimiter=",", quotechar='"')
        for etsy_order in etsy_reader:

def etsy_order_to_xero_row(etsy_order: Dict[str, str]) -> Dict[str, str]:
    return {
        "*ContactName": etsy_order.get("Full Name"),
        "EmailAddress": "",
        "POAddressLine1": etsy_order.get("Street 1"),
        "POAddressLine2": etsy_order.get("Street 2"),
        "POAddressLine3": etsy_order.get(""),
        "POAddressLine4": etsy_order.get(""),
        "POCity": etsy_order.get("Delivery City"),
        "PORegion": etsy_order.get("Delivery State"),
        "POPostalCode": etsy_order.get("Delivery Zipcode"),
        "POCountry": etsy_order.get("Delivery Country"),
        "*InvoiceNumber": etsy_order.get("Order ID"),
        "Reference": etsy_order.get(""),
        "*InvoiceDate": etsy_date_to_xero_date(etsy_order.get("Sale Date")),
        "*DueDate": etsy_date_to_xero_date(etsy_order.get("Sale Date")),
        "Total": etsy_order.get("Order total"),
        "InventoryItemCode": "",
        "*Description": f"Etsy Order {etsy_order.get('Order ID')}",
        "*Quantity": "1",
        "*UnitAmount": etsy_order.get("Order total"),
        "Discount": "",
        "*AccountCode": SALES_ACCOUNT_CODE,
        "*TaxType": etsy_order.get("Sales"),
        "TaxAmount": "",
        "TrackingName1": "",
        "TrackingOption1": "",
        "TrackingName2": "",
        "TrackingOption2": "",
        "Currency": etsy_order.get("Currency"),
        "BrandingTheme": "",

def etsy_date_to_xero_date(etsy_date: str) -> str:
    return datetime.strptime(etsy_date, "%m/%d/%y").strftime("%d %b %Y")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Convert an Etsy sales export CSV into a xero invoices CSV")
    parser.add_argument("etsy_file", default=f"EtsySoldOrders{NOW.year}.csv",
                        type=argparse.FileType("r", encoding="UTF-8"),
                        help="Path to Etsy sales export CSV file")
    args = parser.parse_args()


Tech mentioned