Sign inSign up

cybercinch/xero-visa-loader

By cybercinch

•Updated 4 months ago

Go CLI application for processing Visa credit card transactions to Xero

Image
0

2.6K

cybercinch/xero-visa-loader repository overview

⁠Xero Visa Loader

Automated processor for Visa credit card transactions that posts them to accounting systems (Xero and FinchKeep).

⁠Overview

This Go CLI application processes Visa credit card transactions from a Beanstalk message queue, matches them against vendor mappings, and automatically creates corresponding transactions in your accounting system.

Supported accounting systems:

  • Xero - Industry-standard cloud accounting platform
  • FinchKeep - Modern open-source accounting system

⁠Features

  • Queue-based processing - Consumes transactions from Beanstalk queue
  • Vendor matching - Automatic vendor identification via substring matching
  • Multiple upstreams - Route transactions to Xero, FinchKeep, or both
  • OAuth2 authentication - Secure PKCE flow for Xero API access
  • Notifications - NTFY alerts for unmatched transactions
  • Advanced config management - Self-documenting configuration with Viper⁠
  • Structured logging - JSON logging with zerolog⁠

⁠Quick Start

⁠Installation
# Build the application
just build

# Install to GOPATH/bin
just install
⁠Configuration

The application uses a TOML configuration file. View all available settings:

./bin/xero-visa-loader config info

Set configuration values:

./bin/xero-visa-loader config set -k xero.tenant_id -v "your-tenant-id"
./bin/xero-visa-loader config set -k xero.bank_account_id -v "your-bank-account-id"
./bin/xero-visa-loader config set -k finchkeep.org_id -v "your-org-id"
./bin/xero-visa-loader config set -k finchkeep.bank_account_id -v "your-bank-account-id"

Key configuration options:

Xero:

  • xero.tenant_id - Your Xero organization tenant ID
  • xero.bank_account_id - Bank account ID for transactions
  • xero.enabled - Enable/disable Xero processing (default: true)

FinchKeep:

  • finchkeep.api_key - API key for authentication
  • finchkeep.base_url - API base URL (default: https://finchkeep.guise.net.nz/api/v1⁠)
  • finchkeep.org_id - Organization ID
  • finchkeep.bank_account_id - Bank account ID for transactions
  • finchkeep.enabled - Enable/disable FinchKeep processing (default: false)

Beanstalk:

  • beanstalk.server - Beanstalk server address (default: localhost)
  • beanstalk.port - Server port (default: 11300)
  • beanstalk.tube - Queue tube name (default: visa-transactions)

NTFY (Notifications):

  • ntfy.url - NTFY server URL
  • ntfy.topic - Notification topic
  • ntfy.auth_token - Authentication token
⁠Authentication

For Xero API access, authenticate using OAuth2:

./bin/xero-visa-loader login

This opens your browser to complete the OAuth2 PKCE flow. Tokens are stored securely in the config file and refreshed automatically.

⁠Vendor Mapping

Edit the mapping files to configure vendor matching:

For Xero: account_mapping.json

[
  {
    "Name": "VENDOR NAME",
    "ContactID": "xero-contact-uuid",
    "PaymentCode": "xero-account-code"
  }
]

For FinchKeep: account_mapping_finchkeep.json

[
  {
    "Name": "VENDOR NAME",
    "ContactID": "vendor-contact-uuid",
    "PaymentCode": "expense-account-uuid"
  }
]

Transaction descriptions are matched using case-insensitive substring search against the Name field.

⁠Running

Process transactions from the queue:

./bin/xero-visa-loader run

The application will:

  1. Connect to Beanstalk and poll for transactions
  2. Match each transaction against vendor mappings
  3. Create transactions in enabled accounting systems
  4. Send NTFY notifications for unmatched transactions
  5. Exit when the queue is empty (60s timeout)

⁠Architecture

⁠Package Structure
├── cmd/                    # Cobra CLI commands
│   ├── run.go             # Main processing loop
│   ├── login.go           # OAuth2 authentication
│   └── config/            # Config management commands
├── internal/
│   ├── config/            # Advanced configuration system
│   │   ├── key/           # Config key constants
│   │   └── default.go     # Default values & descriptions
│   ├── xero/              # Xero API integration
│   │   ├── auth.go        # OAuth2 PKCE flow
│   │   └── client.go      # API client & atomic config writes
│   ├── finchkeep/         # FinchKeep API integration
│   │   ├── client.go      # API client
│   │   ├── accounting.go  # Transaction creation
│   │   └── types.go       # API data structures
│   ├── mytypes/           # Domain types
│   │   ├── visa.go        # VisaTransaction
│   │   └── dateonly.go    # Custom date type
│   └── upstream/          # Upstream routing system
└── account_mapping*.json  # Vendor mapping files
⁠Transaction Flow
  1. Queue Polling - Beanstalk job consumed as JSON
  2. Deserialization - Unmarshaled to mytypes.VisaTransaction
  3. Vendor Matching - Substring match against mapping files
  4. Upstream Routing - Create transactions in enabled systems:
    • Xero: Creates BankTransaction via REST API
    • FinchKeep: Creates expense transaction via Simple Mode API
  5. Notification - NTFY alert for unmatched transactions (buried in queue)

⁠Development

⁠Building
just build        # Build optimized binary
just build-docker # Build and push Docker image
just update       # Update Go dependencies
⁠Configuration Management

Add new config fields in two steps:

  1. Declare constant in internal/config/key/keys.go:
const MyNewField = "section.field_name"
  1. Add default value in internal/config/default.go:
{
    Key:          key.MyNewField,
    DefaultValue: "default-value",
    Description:  "What this field does",
}

Access in code: viper.GetString(key.MyNewField)

⁠Docker

The application runs as a non-root user in the container. See Dockerfile for details.

⁠Documentation

For detailed implementation notes and architecture decisions, see CLAUDE.md⁠.

⁠License

Proprietary - CyberCinch NZ

Tag summary

Content type

Image

Digest

sha256:36bd424ad…

Size

39.5 MB

Last updated

4 months ago

docker pull cybercinch/xero-visa-loader