Go CLI application for processing Visa credit card transactions to Xero
2.6K
Automated processor for Visa credit card transactions that posts them to accounting systems (Xero and FinchKeep).
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:
# Build the application
just build
# Install to GOPATH/bin
just install
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 IDxero.bank_account_id - Bank account ID for transactionsxero.enabled - Enable/disable Xero processing (default: true)FinchKeep:
finchkeep.api_key - API key for authenticationfinchkeep.base_url - API base URL (default: https://finchkeep.guise.net.nz/api/v1)finchkeep.org_id - Organization IDfinchkeep.bank_account_id - Bank account ID for transactionsfinchkeep.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 URLntfy.topic - Notification topicntfy.auth_token - Authentication tokenFor 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.
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.
Process transactions from the queue:
./bin/xero-visa-loader run
The application will:
├── 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
mytypes.VisaTransactionBankTransaction via REST APIjust build # Build optimized binary
just build-docker # Build and push Docker image
just update # Update Go dependencies
Add new config fields in two steps:
internal/config/key/keys.go:const MyNewField = "section.field_name"
internal/config/default.go:{
Key: key.MyNewField,
DefaultValue: "default-value",
Description: "What this field does",
}
Access in code: viper.GetString(key.MyNewField)
The application runs as a non-root user in the container. See Dockerfile for details.
For detailed implementation notes and architecture decisions, see CLAUDE.md.
Proprietary - CyberCinch NZ
Content type
Image
Digest
sha256:36bd424ad…
Size
39.5 MB
Last updated
4 months ago
docker pull cybercinch/xero-visa-loader