Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Money Laravel Package

mathiasverraes/money

Small PHP money library that treats monetary values as immutable value objects to avoid floating-point errors. Includes currency support, arithmetic and comparisons, and formatting helpers—useful for modeling prices, totals, and discounts in a robust, domain-driven way.

View on GitHub
Deep Wiki
Context7
## Technical Evaluation

### **Architecture Fit**
- **Monetary Calculations**: Perfect fit for any system handling financial transactions, pricing, billing, or currency conversions (e.g., e-commerce, SaaS, fintech).
- **Domain-Driven Design (DDD)**: Aligns with DDD principles by encapsulating money as a first-class entity, reducing primitive obsession.
- **Immutable Value Objects**: Enforces immutability, preventing accidental state corruption in financial logic.
- **Contextual Boundaries**: Supports multi-currency applications with clear separation of concerns (e.g., `Money` vs. `Currency`).
- **Potential Overhead**: May introduce slight complexity for non-financial use cases (e.g., logging, analytics).
- **New Feature (v4.9.0)**:
  - **`Currency::zero()`**: Adds convenience for creating zero-valued `Money` objects (e.g., `Money::zero('EUR')`), reducing boilerplate and improving readability. Aligns with common patterns in financial libraries (e.g., `Money::zero()` in other ecosystems).

### **Integration Feasibility**
- **PHP/Laravel Compatibility**: Seamless integration with Laravel’s dependency injection (DI) container and service providers.
- **Database Agnostic**: Works with any ORM (Eloquent, Doctrine) or raw SQL, but requires manual serialization for storage (e.g., `amount`, `currency` fields).
- **API/CLI-Friendly**: Can be used in API layers (e.g., validating payments) or CLI scripts (e.g., batch currency conversions).
- **Testing**: Enhances testability by isolating monetary logic from business rules.
- **New Feature (v4.9.0)**:
  - **`Currency::zero()`**: Simplifies initialization of zero-amount `Money` objects, particularly useful in:
    - Default value assignments (e.g., `Order::fill(['subtotal' => Money::zero('USD')])`).
    - Edge-case handling (e.g., refunds, cancellations).
    - Factory methods for Eloquent models (e.g., `protected $defaults = ['total' => Money::zero('USD')]`).

### **Technical Risk**
- **Currency Data Management**: Requires external service (e.g., [ExchangeRate-API](https://www.exchangerate-api.com/)) for real-time conversions; caching strategies needed.
- **Precision Handling**: Floating-point arithmetic risks; consider using `bcmath` or `gmp` for high-precision calculations.
- **Legacy Code**: May conflict with existing "primitive money" implementations (e.g., `float` amounts in DB).
- **Performance**: Minimal runtime overhead, but serialization/deserialization could impact bulk operations.
- **New Feature (v4.9.0)**:
  - **No Risks**: `Currency::zero()` is a non-breaking convenience method with no impact on existing functionality or performance.

### **Key Questions**
1. **Currency Strategy**:
   - How will exchange rates be sourced/fetched? (API, cached DB, manual updates?)
   - Will the system support dynamic currency switching (e.g., user-selected checkout currency)?
2. **Storage**:
   - How will `Money` objects be persisted? (JSON column? Separate `amount`/`currency` fields?)
   - Will historical exchange rates need to be tracked for auditing?
3. **Precision**:
   - Are there requirements for sub-unit precision (e.g., cents vs. fractions of a cent)?
   - Will rounding rules (e.g., banker’s rounding) be enforced?
4. **Validation**:
   - Should invalid operations (e.g., adding `USD` and `EUR`) throw exceptions or return `null`?
5. **Testing**:
   - How will currency conversion tests be isolated from external API dependencies?
6. **New Feature (v4.9.0)**:
   - **Usage Patterns**:
     - Should `Money::zero()` be the primary way to create zero-amount objects, or will explicit `new Money(0, 'USD')` still be preferred for clarity?
     - Are there cases where zero-amount objects should *not* be allowed (e.g., mandatory fields)? If so, how will this be enforced?

---

## Integration Approach

### **Stack Fit**
- **Laravel Ecosystem**:
  - **Service Provider**: Register `Money` as a singleton or bind interfaces (e.g., `MoneyService`) for dependency injection.
  - **Eloquent Models**: Use accessors/mutators to convert between `Money` objects and DB fields.
  - **API Resources**: Serialize `Money` objects in JSON responses (e.g., `amount: "100.00", currency: "USD"`).
  - **Form Requests**: Validate monetary inputs using Laravel’s validation rules (e.g., `numeric|min:0`).
  - **New Feature (v4.9.0)**:
    - **Default Values**: Leverage `Currency::zero()` in Eloquent model defaults or factory methods:
      ```php
      // Before:
      protected $attributes = ['total' => new Money(0, 'USD')];

      // After:
      protected $attributes = ['total' => Money::zero('USD')];
      ```
    - **API Responses**: Use `Money::zero()` for default responses (e.g., empty carts, unprocessed orders).
- **Microservices**:
  - Ideal for decoupling monetary logic into a shared library or service (e.g., `currency-conversion-service`).
- **Non-Laravel PHP**:
  - Works in any PHP 8.1+ app, but Laravel’s tooling (e.g., Artisan commands) will simplify adoption.

### **Migration Path**
1. **Pilot Phase**:
   - Start with a single feature (e.g., order pricing) to validate the pattern.
   - Replace primitive `float` amounts with `Money` in domain models.
   - **New Feature (v4.9.0)**: Introduce `Money::zero()` in the pilot phase for zero-amount use cases (e.g., cancellations, refunds).
2. **Incremental Replacement**:
   - Use adapter classes to bridge old and new implementations (e.g., `LegacyMoneyAdapter`).
   - Gradually migrate high-risk areas (e.g., payment processing) last.
3. **Database Schema**:
   - Add `currency` column to existing tables; backfill with default currency (e.g., `USD`).
   - Example:
     ```php
     // Before: $order->total = 99.99;
     // After: $order->total = new Money(9999, 'USD'); // Stored as 9999 in cents
     // With v4.9.0: $order->total = Money::zero('USD'); // For defaults
     ```
4. **API Contracts**:
   - Update OpenAPI/Swagger specs to reflect `Money` objects in requests/responses.
   - **New Feature (v4.9.0)**: Document `Money::zero()` in API schemas for cases where zero-amount responses are valid.

### **Compatibility**
- **PHP Version**: Requires PHP 8.1+ (for named arguments, enums).
- **Laravel Version**: Compatible with Laravel 9+ (test for 10+ if using newer features like enums).
- **Dependencies**:
  - No hard dependencies; works alongside existing libraries (e.g., `moneyphp/money` if needed for backward compatibility).
  - Avoid conflicts with other "money" libraries by using namespaced classes.
- **New Feature (v4.9.0)**:
  - **Backward Compatibility**: `Currency::zero()` is additive and does not affect existing code. No version pinning required unless using strict dependency resolution.

### **Sequencing**
1. **Design Phase**:
   - Define currency strategy (fixed vs. dynamic rates).
   - Document rounding/precision rules.
   - **New Feature (v4.9.0)**: Clarify where `Money::zero()` will be used (e.g., defaults, edge cases) vs. explicit `new Money(0, 'USD')`.
2. **Implementation**:
   - Create a `MoneyService` facade for centralized logic.
   - Implement a `Money` trait or abstract class for Eloquent models.
   - **New Feature (v4.9.0)**: Update factories and defaults to use `Money::zero()` where appropriate.
3. **Testing**:
   - Write unit tests for edge cases (e.g., division by zero, negative amounts).
   - Mock external currency APIs.
   - **New Feature (v4.9.0)**: Add tests for `Money::zero()` behavior (e.g., serialization, arithmetic operations).
4. **Deployment**:
   - Roll out in feature flags for critical paths (e.g., checkout).
   - Monitor for serialization/deserialization errors.
   - **New Feature (v4.9.0)**: Log usage of `Money::zero()` to identify adoption patterns or edge cases.

---

## Operational Impact

### **Maintenance**
- **Pros**:
  - Reduces bugs from manual currency conversions (e.g., `100 * 0.99` vs. `Money::USD(100)->multiply(0.99)`).
  - Centralized logic for future changes (e.g., adding a new currency).
  - **New Feature (v4.9.0)**: `Currency::zero()` reduces boilerplate, making maintenance easier for zero-amount logic.
- **Cons**:
  - Requires
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor