承接 3mad/fee-collection 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

3mad/fee-collection

Composer 安装命令:

composer require 3mad/fee-collection

包简介

Laravel package for fee collection with upcoming payments, invoices, receipts, wallet balance tracking, and optional PDF documents.

README 文档

README

FeeCollection logo

FeeCollection

Laravel fee workflow package for scheduled payments, invoices, receipts, credit notes, statement history, wallet balances, and optional PDF documents.

FeeCollection is a Laravel package for fee workflows:

  • register upcoming payments
  • create invoices and receipts
  • create manual credit notes
  • split payments
  • detect overdue payments and generate due invoices
  • keep account statements recalculated
  • track one wallet balance row per payable model
  • optionally generate/store invoice/receipt PDFs

See the documentation below, or browse the full documentation site:

https://3mad0o.github.io/fee-collection-documentation/

Table of Contents

Requirements

  • PHP 8.3+
  • Laravel 13+

Installation

Install package in your Laravel app:

composer require 3mad/fee-collection

If your app does not auto-discover providers, register:

Emad\FeeCollection\Providers\FeeCollectionServiceProvider::class

For PDF generation support (optional):

composer require barryvdh/laravel-dompdf

Publish Package Files

Publish config:

php artisan vendor:publish --provider="Emad\FeeCollection\Providers\FeeCollectionServiceProvider" --tag=config

Publish default PDF blade views:

php artisan vendor:publish --provider="Emad\FeeCollection\Providers\FeeCollectionServiceProvider" --tag=views

Published views path:

resources/views/vendor/fee-collection/pdf

Migrations

Run migrations:

php artisan migrate

This creates:

  • upcoming_payments
  • account_statements
  • account_statement_upcoming_payments
  • wallet_transactions (single row per walletable with current balance)

Getting Started

Setup Model

Add UseFeeable trait to any Eloquent model (for example User):

use Emad\FeeCollection\Traits\UseFeeable;

class User extends Model
{
    use UseFeeable;
}

After this, the model can register payments, create receipts, generate due invoices, query statements, and read its wallet balance.

Configuration

File: config/fee_collection.php

return [
    'invoice_prefix' => 'I-',
    'invoice_suffix' => '',
    'receipt_prefix' => 'R-',
    'receipt_suffix' => '',
    'credit_note_prefix' => 'CN-',
    'credit_note_suffix' => '',
    'auto_invoice_on_receipt' => true,
    'invoice_view' => 'fee-collection::pdf.invoice',
    'receipt_view' => 'fee-collection::pdf.receipt',
    'credit_note_view' => 'fee-collection::pdf.invoice',
    'pdf' => [
        'enabled' => env('FEE_COLLECTION_PDF_ENABLED', true),
        'paper' => 'a4',
        'orientation' => 'portrait',
        'disk' => env('FEE_COLLECTION_PDF_DISK', 'public'),
        'path' => env('FEE_COLLECTION_PDF_PATH', 'fee-collection/documents'),
    ],
];

Notes

  • account_statements.number stores numeric value only.
  • Prefix/suffix are added on retrieval via formatted_number.
  • If pdf.enabled = true, generated PDF path is saved in account_statements.document.
  • auto_invoice_on_receipt may be overridden per receipt call.
  • Credit notes are always manual. Splitting a payment never creates a credit note automatically.

Core Concepts

FeeCollection is built around payable models, upcoming payments, account statements, and wallet balances.

Payable Models

Any Eloquent model using UseFeeable can own fee workflows. Typical examples include User, Student, Customer, and Tenant.

The trait adds methods for payment registration, statement access, wallet balance checks, overdue detection, and due invoice generation.

Upcoming Payments

An upcoming payment represents a scheduled amount due on a future date.

Upcoming payments can be:

  • registered from a payable model
  • invoiced manually
  • receipted manually
  • split into child payments
  • detected as overdue
  • invoiced automatically when due

Account Statements

Account statements represent financial documents and history entries such as invoices, receipts, and credit notes.

Statements include a status field for reporting and filtering.

Wallet Balance

The package tracks one wallet balance row per payable model in wallet_transactions.

$balance = $user->balance();

Credit Notes

Credit notes are created from invoices. A credit note:

  • references the original invoice through reference_id
  • uses a negative amount
  • changes the original invoice status to credited

Credit notes are not created automatically during payment splitting.

Voided Invoices

A voided invoice is excluded from balance recalculation.

Use voiding only for invoices that should be killed internally before customer settlement.

Usage Examples

1) Create receipt, then register payments (wallet consumption flow)

$user = User::factory()->create();

$user->createReceipt(1000, 'Initial credit', now());

$user->registerPayment(100, now()->addDays(1));
$user->registerPayment(100, now()->addDays(2));
$user->registerPayment(100, now()->addDays(3));

If wallet balance is enough, registered payments can be invoiced automatically.

Disable receipt-driven invoice generation per call:

$user->createReceipt(1000, 'Initial credit', now(), autoInvoice: false);

2) Manual invoice and receipt on one upcoming payment

$payment = $user->registerPayment(100, now()->addDays(10));
$payment->createInvoice('Test Invoice', now());
$payment->createReceipt('Test Receipt', now());

3) Split an upcoming payment

$payment = $user->registerPayment(1000, now()->addDays(1));

$children = $payment->split([
    ['amount' => 100, 'due_date' => now()->addDays(2)],
    ['amount' => 100, 'due_date' => now()->addDays(3)],
    ['amount' => 800, 'due_date' => now()->addDays(4)],
]);

If the original payment already had an invoice, create the credit note manually:

$invoice = $payment->invoice;

$children = $payment->split([
    ['amount' => 500, 'due_date' => now()->addMonth()],
    ['amount' => 500, 'due_date' => now()->addMonths(2)],
]);

$invoice->createCreditNote('Customer requested installment split', now());

4) Create a credit note

$payment = $user->registerPayment(1000, now()->addDay());
$invoice = $payment->createInvoice('Original invoice', now());

$creditNote = $invoice->createCreditNote('Invoice cancelled', now());

Credit notes:

  • can only be created from invoices
  • reference the original invoice through reference_id
  • use a negative amount
  • move the original invoice status to credited

5) Void an invoice

$payment = $user->registerPayment(1000, now()->addDay());
$invoice = $payment->createInvoice('Draft invoice', now());

$invoice->void('Created by mistake');

Voided invoices are excluded from balance recalculation. Use this only for invoices that should be killed internally before customer settlement.

6) Detect overdue payments

if ($payment->isOverdue()) {
    // notify the customer
}

$overduePayments = $user->overduePayments();

An overdue payment has a due date before today, still has remaining amount, and has no linked receipt.

7) Generate invoices due today

$invoices = $user->generateDueInvoices();

Scheduler example:

use App\Models\User;

$schedule->call(function () {
    User::each(fn (User $user) => $user->generateDueInvoices());
})->daily();

8) Statement status

Statements include a status field for filtering/reporting:

  • issued
  • paid
  • overdue
  • credited
  • voided
$paidStatements = $user->accountStatements()->where('status', 'paid')->get();
$creditedStatements = $user->accountStatements()->where('status', 'credited')->get();

Status is a reporting helper. Balances are still calculated from statement debit/credit values, excluding voided invoices.

9) List statements and check wallet balance

$statements = $user->accountStatements()->orderByDesc('date')->get();
$balance = $user->balance();

Events

The package dispatches these events after successful changes:

  • Emad\FeeCollection\Events\InvoiceCreated
  • Emad\FeeCollection\Events\ReceiptCreated
  • Emad\FeeCollection\Events\CreditNoteCreated
  • Emad\FeeCollection\Events\PaymentOverdue
  • Emad\FeeCollection\Events\PaymentSplit
  • Emad\FeeCollection\Events\InvoiceVoided

Common uses include customer notifications, internal audit logs, reporting updates, accounting exports, and webhook dispatching.

PDF Documents

FeeCollection can generate and store PDF documents for invoices, receipts, and credit notes.

Install DomPDF support:

composer require barryvdh/laravel-dompdf

PDF generation is controlled by config/fee_collection.php:

'pdf' => [
    'enabled' => env('FEE_COLLECTION_PDF_ENABLED', true),
    'paper' => 'a4',
    'orientation' => 'portrait',
    'disk' => env('FEE_COLLECTION_PDF_DISK', 'public'),
    'path' => env('FEE_COLLECTION_PDF_PATH', 'fee-collection/documents'),
],

Useful environment variables:

FEE_COLLECTION_PDF_ENABLED=true
FEE_COLLECTION_PDF_DISK=public
FEE_COLLECTION_PDF_PATH=fee-collection/documents

Configure the Blade views used for generated documents:

'invoice_view' => 'fee-collection::pdf.invoice',
'receipt_view' => 'fee-collection::pdf.receipt',
'credit_note_view' => 'fee-collection::pdf.invoice',

Generate PDF manually

$statement = $user->accountStatements()->latest('id')->first();
$pdf = $statement->toPdf();

return $pdf->download($statement->formatted_number . '.pdf');

When PDF generation is enabled, the generated PDF path is saved in account_statements.document.

API Quick Reference

Payable model methods

$user->createReceipt(1000, 'Initial credit', now());
$user->createReceipt(1000, 'Initial credit', now(), autoInvoice: false);

$payment = $user->registerPayment(100, now()->addDays(10));

$overduePayments = $user->overduePayments();
$invoices = $user->generateDueInvoices();
$statements = $user->accountStatements()->orderByDesc('date')->get();
$balance = $user->balance();

Upcoming payment methods

$invoice = $payment->createInvoice('Original invoice', now());
$payment->createReceipt('Test Receipt', now());

$children = $payment->split([
    ['amount' => 500, 'due_date' => now()->addMonth()],
    ['amount' => 500, 'due_date' => now()->addMonths(2)],
]);

if ($payment->isOverdue()) {
    // notify the customer
}

Statement methods

$creditNote = $invoice->createCreditNote('Invoice cancelled', now());
$invoice->void('Created by mistake');
$pdf = $statement->toPdf();

What Gets Stored

  • account_statements.number: numeric sequence (no prefix/suffix)
  • account_statements.document: stored PDF relative path (when enabled)
  • account_statements.reference_id: original invoice for credit notes
  • account_statements.status: reporting status
  • account_statements.voided_at: timestamp for voided invoices
  • account_statements.void_reason: reason for voiding
  • wallet_transactions.balance: current wallet balance for the payable

License

MIT

3mad/fee-collection 适用场景与选型建议

3mad/fee-collection 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 05 月 06 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 3mad/fee-collection 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 3mad/fee-collection 我们能提供哪些服务?
定制开发 / 二次开发

基于 3mad/fee-collection 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 2
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 47
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-06