upgradelabs / invoicexpress
Laravel package for InvoiceXpress API v2
Requires
- php: >=8.3
- illuminate/support: ^10.0
Requires (Dev)
- orchestra/testbench: ^7.0
- phpunit/phpunit: ^10.0
README
A first‑class Laravel wrapper around the InvoiceXpress API v2. Provides simple methods for all API endpoints, from Invoices and Estimates to SAF‑T exports and Treasury movements.
- Supports Laravel 10 & above
- Automatically registers a
InvoiceXpress
façade and service provider - Fully tested with PHPUnit and Orchestra Testbench
Installation
Install via Composer:
composer require upgradelabs/invoicexpress
Publish the configuration file:
php artisan vendor:publish \ --provider="Upgradelabs\InvoiceXpress\InvoiceXpressServiceProvider" \ --tag="config"
Configuration
In your .env
, set:
INVOICEXPRESS_ACCOUNT=your_account_name INVOICEXPRESS_API_KEY=your_api_key
The published config/invoicexpress.php
uses these to build:
return [ 'account_name' => env('INVOICEXPRESS_ACCOUNT'), 'api_key' => env('INVOICEXPRESS_API_KEY'), 'base_uri' => 'https://' . env('INVOICEXPRESS_ACCOUNT') . '.app.invoicexpress.com/', ];
Usage
Import the façade anywhere:
use Upgradelabs\InvoiceXpress\Facades\InvoiceXpress;
Or inject the client:
public function __construct(\Upgradelabs\InvoiceXpress\InvoiceXpressClient $ix) { … }
All methods return the decoded JSON response (as an array). HTTP errors throw an exception.
Invoices
// List invoices with optional filters $invoices = InvoiceXpress::listInvoices(['status' => 'final']); // Get a single invoice $invoice = InvoiceXpress::getInvoice(123); // Create a new invoice $new = InvoiceXpress::createInvoice([ 'client_id' => 5, 'items' => [ ['name' => 'Widget', 'quantity' => 2, 'unit_price' => 9.50], ], ]); // Update an existing invoice $updated = InvoiceXpress::updateInvoice(123, ['status' => 'draft']); // Change state (e.g. to “canceled”) InvoiceXpress::changeInvoiceState(123, ['state' => 'canceled']); // Send by email InvoiceXpress::sendInvoiceByEmail(123, [ 'to' => 'client@example.com', 'subject' => 'Your Invoice', ]); // Generate PDF (returns a URL) $pdfUrl = InvoiceXpress::generateInvoicePdf(123)['url']; // Fetch related documents $docs = InvoiceXpress::relatedDocuments(123); // Generate & cancel payment $payment = InvoiceXpress::generatePayment(123); InvoiceXpress::cancelPayment(123); // Get QR code data $qrcode = InvoiceXpress::getInvoiceQrCode(123)['qr_code'];
Estimates
InvoiceXpress::listEstimates(['status' => 'opened']); InvoiceXpress::getEstimate(10); InvoiceXpress::createEstimate([...]); InvoiceXpress::updateEstimate(10, [...]); InvoiceXpress::changeEstimateState(10, ['state' => 'accepted']); InvoiceXpress::sendEstimateByEmail(10, ['to' => 'a@b.com']); InvoiceXpress::generateEstimatePdf(10);
Guides
InvoiceXpress::listGuides(); InvoiceXpress::getGuide(7); InvoiceXpress::createGuide([...]); InvoiceXpress::updateGuide(7, [...]); InvoiceXpress::changeGuideState(7, ['state' => 'canceled']); InvoiceXpress::sendGuideByEmail(7, ['to' => 'x@y.com']); InvoiceXpress::generateGuidePdf(7); InvoiceXpress::getGuideQrCode(7);
Purchase Orders
InvoiceXpress::listPurchaseOrders(['status'=>'sent']); InvoiceXpress::getPurchaseOrder(5); InvoiceXpress::createPurchaseOrder([...]); InvoiceXpress::updatePurchaseOrder(5, [...]); InvoiceXpress::changePurchaseOrderState(5, ['state'=>'approved']); InvoiceXpress::sendPurchaseOrderByEmail(5, ['to'=>'z@z.com']); InvoiceXpress::generatePurchaseOrderPdf(5);
Clients
InvoiceXpress::listClients(['page'=>1]); InvoiceXpress::getClient(3); InvoiceXpress::createClient(['name'=>'Acme Corp']); InvoiceXpress::updateClient(3, ['email'=>'info@acme.com']); InvoiceXpress::findClientsByName('Acme'); InvoiceXpress::findClientsByCode('ACM123'); InvoiceXpress::listClientInvoices(3, ['status'=>'final']);
Items
InvoiceXpress::listItems(); InvoiceXpress::getItem(12); InvoiceXpress::createItem(['name'=>'Service','unit_price'=>50]); InvoiceXpress::updateItem(12, ['unit_price'=>60]); InvoiceXpress::deleteItem(12);
Sequences
InvoiceXpress::registerSequence(['prefix'=>'INV-', 'type'=>'invoice']); InvoiceXpress::listSequences(); InvoiceXpress::getSequence(2); InvoiceXpress::createSequence(['prefix'=>'QTE-']); InvoiceXpress::updateSequence(2, ['enabled'=>true]);
Taxes
InvoiceXpress::listTaxes(); InvoiceXpress::getTax(4); InvoiceXpress::createTax(['name'=>'VAT','rate'=>23]); InvoiceXpress::updateTax(4, ['rate'=>19]); InvoiceXpress::deleteTax(4);
Accounts
InvoiceXpress::getAccount(1); InvoiceXpress::updateAccount(1, ['name'=>'New']); InvoiceXpress::createAccount(['name'=>'Acct','email'=>'a@b.com']); InvoiceXpress::createAccountForExistingUser(['user_id'=>5]); InvoiceXpress::atCommunication(['event'=>'invoice_sent']);
SAF‑T Export
// Export your SAF‑T for auditing purposes $saftXml = InvoiceXpress::exportSaft([ 'year' => 2024, 'report' => 'complete', ]);
Treasury
// Client balances & movements $balance = InvoiceXpress::getClientBalance(3); InvoiceXpress::updateInitialBalance(3, ['amount'=>1000]); $regs = InvoiceXpress::getRegularizations(3); InvoiceXpress::createRegularization(3, ['date'=>'2025-05-01','amount'=>200]); InvoiceXpress::deleteRegularization(3, 7); InvoiceXpress::createTreasuryMovement(3, ['type'=>'receipt','amount'=>500]); InvoiceXpress::deleteTreasuryMovement(3, 8);
Running Tests
vendor/bin/phpunit
All HTTP interactions in tests are faked via Laravel’s Http::fake()
, so you can run the suite offline.
Contributing & Support
Feel free to open issues or pull requests—PRs should include tests. For commercial support or custom features, contact Upgradelabs.
License
MIT License. See the LICENSE file for details.