PHP code example of derrickob / pricer
1. Go to this page and download the library: Download derrickob/pricer library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
derrickob / pricer example snippets
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
$price = Pricer::base(100, 'USD')
->tax(10, AmountType::PERCENT)
->calculate();
echo $price->getTotal()->format(); // $110.00
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
$price = Pricer::base(150, 'USD')
->discount(10, AmountType::PERCENT, 'SAVE10')
->shipping(12, 'standard')
->tax(8, AmountType::PERCENT, 'sales_tax')
->fee(2.9, AmountType::PERCENT, 'stripe_percentage')
->fee(0.30, AmountType::FIXED, 'stripe_fixed')
->calculate();
echo $price->getSubtotal()->format(); // $150.00
echo $price->getDiscount()->format(); // $15.00
echo $price->getShipping()->format(); // $12.00
echo $price->getTax()->format(); // $11.76 (tax on $147 after discount)
echo $price->getFees()->format(); // $4.90 (Stripe fees)
echo $price->getTotal()->format(); // $163.66
echo $price->getBreakdown()->format();
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
use DerrickOb\Pricer\Enums\TipCalculation;
$bill = Pricer::base(85.50, 'USD')
->tax(8, AmountType::PERCENT, 'sales_tax')
->tip(20, TipCalculation::PRE_TAX)
->calculate();
echo $bill->getTotal()->format(); // $109.44
// Breakdown:
// Base: $85.50
// Tax (8%): $6.84
// Tip (20% of $85.50): $17.10
// Total: $109.44
$bill = Pricer::base(85.50, 'USD')
->tax(8, AmountType::PERCENT)
->tip(20, TipCalculation::POST_TAX)
->calculate();
echo $bill->getTotal()->format(); // $110.81
// Tip is 20% of $92.34 (base + tax) = $18.47
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
use DerrickOb\Pricer\Enums\BillingCycle;
$startDate = new DateTime('2025-01-15');
$endDate = new DateTime('2025-02-01'); // 17 days
$price = Pricer::base(0, 'USD')
->prorateSubscription(
30, // Monthly price
BillingCycle::MONTHLY, // 30-day cycle
$startDate,
$endDate,
'prorated_period'
)
->tax(10, AmountType::PERCENT)
->calculate();
echo $price->getTotal()->format(); // $18.70
// Calculation:
// Daily rate: $30 / 30 days = $1.00/day
// 17 days: $1.00 × 17 = $17.00
// Tax: $17.00 × 1.10 = $18.70
$firstMonth = Pricer::base(0, 'USD')
->prorateSubscription(30, BillingCycle::MONTHLY, $startDate, $endDate, 'initial')
->subscription(30, BillingCycle::MONTHLY, 'regular')
->setupFee(50, 'onboarding')
->tax(10, AmountType::PERCENT)
->calculate();
echo $firstMonth->getTotal()->format(); // $106.70
// Prorated ($17) + Regular ($30) + Setup ($50) = $97 + tax ($9.70) = $106.70
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
$price = Pricer::base(100, 'USD')
->tax(8, AmountType::PERCENT)
->fee(2.9, AmountType::PERCENT, 'stripe_percentage')
->fee(0.30, AmountType::FIXED, 'stripe_fixed')
->calculate();
echo $price->getTotal()->format(); // $111.43
// Breakdown:
// Base: $100.00
// Tax: $8.00 = $108.00
// Stripe fee (2.9%): $3.13 (on $108)
// Stripe fee (fixed): $0.30
// Total: $111.43
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
use DerrickOb\Pricer\Enums\CreditApplication;
$price = Pricer::base(150, 'USD')
->discount(10, AmountType::PERCENT, 'SAVE10')
->tax(8, AmountType::PERCENT)
->applyCredit(50, 'gift_card', CreditApplication::AFTER_TAX)
->calculate();
echo $price->getTotal()->format(); // $95.80
// Breakdown:
// Base: $150.00
// Discount (10%): -$15.00 = $135.00
// Tax (8%): +$10.80 = $145.80
// Gift card: -$50.00 = $95.80
$price = Pricer::base(150, 'USD')
->applyCredit(50, 'gift_card', CreditApplication::BEFORE_TAX)
->tax(8, AmountType::PERCENT)
->calculate();
echo $price->getTotal()->format(); // $108.00
// Breakdown:
// Base: $150.00
// Gift card: -$50.00 = $100.00
// Tax (8%): +$8.00 = $108.00
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
use DerrickOb\Pricer\ValueObjects\PriceTier;
// Define pricing tiers:
// 1-10 units: 0% discount
// 11-50 units: 5% discount
// 51-100 units: 10% discount
// 101+ units: 15% discount
$tiers = [
PriceTier::percent(1, 10, 0),
PriceTier::percent(11, 50, 5),
PriceTier::percent(51, 100, 10),
PriceTier::percent(101, null, 15), // null = no upper limit
];
// Customer buys 75 units at $10 each = $750
$price = Pricer::base(750, 'USD')
->bulkDiscount($tiers, 75, 'wholesale_discount')
->tax(8, AmountType::PERCENT)
->calculate();
echo $price->getDiscount()->format(); // $75.00 (10% discount)
echo $price->getTotal()->format(); // $729.00
$tiers = [
PriceTier::fixed(1, 50, 0),
PriceTier::fixed(51, 100, 2), // $2 off per unit
PriceTier::fixed(101, null, 5), // $5 off per unit
];
$price = Pricer::base(750, 'USD')
->bulkDiscount($tiers, 75, 'volume_discount')
->calculate();
echo $price->getDiscount()->format(); // $150.00 (75 units × $2)
echo $price->getTotal()->format(); // $600.00
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
$price = Pricer::base(100, 'USD')
->tax(6, AmountType::PERCENT, 'state_tax')
->tax(2, AmountType::PERCENT, 'city_tax')
->tax(1, AmountType::PERCENT, 'county_tax')
->calculate();
echo $price->getTax()->format(); // $9.00
echo $price->getTotal()->format(); // $109.00
// Breakdown:
// Base: $100.00
// State tax (6%): $6.00
// City tax (2%): $2.00
// County tax (1%): $1.00
// Total tax: $9.00
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
// US state + city taxes (both on $100)
$price = Pricer::base(100, 'USD')
->taxOnSubtotal(6, AmountType::PERCENT, 'state_tax')
->taxOnSubtotal(2, AmountType::PERCENT, 'city_tax')
->calculate();
echo $price->getTax()->format(); // $8.00
echo $price->getTotal()->format(); // $108.00
// Breakdown:
// Base: $100.00
// State tax (6% of $100): $6.00
// City tax (2% of $100): $2.00
// Total: $108.00
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
// Quebec: GST on subtotal, QST compounds on (subtotal + GST)
$price = Pricer::base(100, 'CAD')
->taxOnSubtotal(5, AmountType::PERCENT, 'GST')
->compoundingTax(9.975, AmountType::PERCENT, 'QST')
->calculate();
echo $price->getTax()->format(); // $15.47
echo $price->getTotal()->format(); // $115.47
// Breakdown:
// Base: $100.00
// GST (5% of $100): $5.00 → Running total: $105.00
// QST (9.975% of $105): $10.47 → Running total: $115.47
// Total tax: $15.47
$price = Pricer::base(100, 'USD')
->taxOnSubtotal(6, AmountType::PERCENT, 'state_tax') // $6 on $100
->taxOnSubtotal(2, AmountType::PERCENT, 'city_tax') // $2 on $100
->compoundingTax(5, AmountType::PERCENT, 'luxury_tax') // $5.40 on $108
->calculate();
echo $price->getTax()->format(); // $13.40
echo $price->getTotal()->format(); // $113.40
// Breakdown:
// Base: $100.00
// State tax: $6.00
// City tax: $2.00
// Running subtotal: $108.00
// Luxury tax (5% of $108): $5.40
// Total: $113.40
use DerrickOb\Pricer\Enums\AmountType;
// Percentage
AmountType::PERCENT // Use for rates like 10% tax
// Fixed amount
AmountType::FIXED // Use for flat amounts like $15 shipping
->discount(10, AmountType::PERCENT) // 10% off
->discount(15, AmountType::FIXED) // $15 off
->tax(8, AmountType::PERCENT) // 8% tax
->tax(5, AmountType::FIXED) // $5 environmental fee
->fee(2.9, AmountType::PERCENT) // 2.9% processing fee
->fee(0.30, AmountType::FIXED) // $0.30 fixed fee
// Discount BEFORE tax (reduces taxable amount)
Pricer::base(100, 'USD')
->discount(20, AmountType::PERCENT) // Priority 10
->tax(10, AmountType::PERCENT) // Priority 30
->calculate()
->getTotal()->format(); // $88.00
// Tax is 10% of $80 = $8.00
// If tax came first (wrong order):
// Tax would be 10% of $100 = $10.00
// Then discount 20% of $110 = $22.00
// Total: $88.00 (same) but breakdown is wrong
use DerrickOb\Pricer\Components\Tax;
use DerrickOb\Pricer\Enums\AmountType;
$tax = new Tax(10, AmountType::PERCENT, 'vat');
$tax = $tax->setPriority(15); // Apply earlier than default (30)
use DerrickOb\Pricer\Core\Money;
$money = Money::of(10, 'USD');
$result = $money->divide(3);
echo $result->format(); // $3.33 (not 3.333333...)
Pricer::configure([
'precision' => 2, // Default: 2 decimal places
]);
use DerrickOb\Pricer\Core\Money;
$money = Money::of(100, 'USD');
// Arithmetic operations (all return new Money instances)
$money->add(50); // $150.00
$money->subtract(20); // $80.00
$money->multiply(2); // $200.00
$money->divide(3); // $33.33
$money->percentage(10); // $10.00 (10% of $100)
// Comparisons
$money1 = Money::of(100, 'USD');
$money2 = Money::of(50, 'USD');
$money1->greaterThan($money2); // true
$money1->lessThan($money2); // false
$money1->equals($money2); // false
// State checks
$money->isPositive(); // true
$money->isNegative(); // false
$money->isZero(); // false
// Formatting
$money->format('USD', 'en_US'); // "$100.00"
$money->format('EUR', 'de_DE'); // "100,00 €"
$money->format('GBP', 'en_GB'); // "£100.00"
use DerrickOb\Pricer\Pricer;
// Vanilla PHP
Pricer::base(100, 'USD')
// Laravel (using helper)
price(100, 'USD')
// Laravel (using facade)
use DerrickOb\Pricer\Laravel\Facades\Pricer;
Pricer::base(100, 'USD')
use DerrickOb\Pricer\Enums\AmountType;
// Basic discount
->discount(20, AmountType::PERCENT, 'SAVE20')
->discount(15, AmountType::FIXED, 'WELCOME15')
// Conditional discount
->discountIf($isVip, 10, AmountType::PERCENT, 'VIP10')
use DerrickOb\Pricer\Enums\TaxMode;
// Single tax (default: non-compounding)
->tax(8, AmountType::PERCENT, 'sales_tax')
// Multiple non-compounding taxes (all calculate on subtotal)
->taxOnSubtotal(6, AmountType::PERCENT, 'state_tax')
->taxOnSubtotal(2, AmountType::PERCENT, 'city_tax')
// Compounding tax (calculates on running total including previous taxes)
->compoundingTax(9.975, AmountType::PERCENT, 'QST')
// Mix both modes
->taxOnSubtotal(6, AmountType::PERCENT, 'state')
->compoundingTax(5, AmountType::PERCENT, 'luxury')
// Or specify mode explicitly
->tax(8, AmountType::PERCENT, 'tax', TaxMode::ON_SUBTOTAL)
->tax(5, AmountType::PERCENT, 'tax', TaxMode::COMPOUNDING)
// Fixed tax (rare, but supported)
->tax(5, AmountType::FIXED, 'environmental_fee')
// Processing fees
->fee(2.9, AmountType::PERCENT, 'stripe_fee')
->fee(0.30, AmountType::FIXED, 'stripe_fixed')
// Conditional fee
->feeIf($expressShipping, 25, AmountType::FIXED, 'express_fee')
// Basic shipping
->shipping(10)
->shipping(15, 'priority_shipping')
// Conditional shipping
->shippingIf($hasPhysicalItems, 12, 'standard')
// Free shipping threshold
->freeShippingOver(100) // Free if subtotal >= $100
use DerrickOb\Pricer\Enums\BillingCycle;
// Regular subscription
->subscription(29.99, BillingCycle::MONTHLY)
->subscription(99, BillingCycle::QUARTERLY)
->subscription(299, BillingCycle::YEARLY)
// With setup fee
->subscription(30, BillingCycle::MONTHLY)
->setupFee(50, 'onboarding')
// Prorated subscription
->prorateSubscription(
30, // Amount
BillingCycle::MONTHLY, // Cycle
new DateTime('2025-01-15'), // Start
new DateTime('2025-02-01'), // End
'prorated_period' // Name
)
use DerrickOb\Pricer\Enums\CreditApplication;
// Apply after tax (default, most common)
->applyCredit(50, 'gift_card', CreditApplication::AFTER_TAX)
// Apply before tax (reduces taxable amount)
->applyCredit(50, 'store_credit', CreditApplication::BEFORE_TAX)
use DerrickOb\Pricer\Enums\TipCalculation;
// Tip on pre-tax amount (default)
->tip(20, TipCalculation::PRE_TAX)
// Tip on post-tax amount
->tip(20, TipCalculation::POST_TAX)
use DerrickOb\Pricer\ValueObjects\PriceTier;
// Define tiers
$tiers = [
PriceTier::percent(1, 50, 0), // 0% for 1-50 units
PriceTier::percent(51, 100, 5), // 5% for 51-100 units
PriceTier::percent(101, null, 10), // 10% for 101+ units
];
// Apply bulk discount
->bulkDiscount($tiers, $quantity, 'wholesale')
// Or tiered fees (instead of discounts)
->tieredFee($tiers, $quantity, 'volume_fee')
// Execute callback if condition is true
->when($condition, function($builder) {
$builder->discount(10, AmountType::PERCENT);
})
// Execute callback if condition is false
->unless($condition, function($builder) {
$builder->fee(20, AmountType::FIXED);
})
// Simple conditionals
->discountIf($isVip, 10, AmountType::PERCENT, 'VIP10')
->feeIf($rushDelivery, 25, AmountType::FIXED, 'rush')
->shippingIf($hasPhysicalItems, 12, 'standard')
->freeShippingOver(100)
// Perform calculation
$price = ->calculate(); // Returns Price object
// Get individual amounts
$price->getSubtotal() // Money object
$price->getDiscount() // Money object
$price->getShipping() // Money object
$price->getTax() // Money object
$price->getFees() // Money object
$price->getCredit() // Money object
$price->getTotal() // Money object
// Format for display
$price->getTotal()->format(); // "$123.45"
$price->getTotal()->format('EUR', 'de_DE'); // "123,45 €"
// Get raw numbers
$price->getTotal()->getAmountFloat(); // 123.45
// Convert to array/JSON
$price->toArray()
$price->toJson()
// Get detailed breakdown
$price->getBreakdown()->format()
$price->explain()
$price->breakdown()
// config/pricer.php
return [
'default_currency' => env('PRICER_CURRENCY', 'USD'),
'default_locale' => env('PRICER_LOCALE', 'en_US'),
'precision' => 2,
'rounding_strategy' => 'nearest',
'tax_behavior' => 'exclusive',
'discount_stacking' => true,
'max_discount_percent' => 100,
];
use DerrickOb\Pricer\Laravel\Facades\Pricer;
$price = Pricer::base(100, 'USD')
->tax(8, AmountType::PERCENT)
->calculate();
// Create a price calculation
$price = price(100, 'USD')
->tax(10, AmountType::PERCENT)
->calculate();
// Create a Money object
$money = money(100, 'USD');
// Quick format an amount
echo format_price(1234.56, 'USD'); // "$1,234.56"
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
$price = Pricer::base(150, 'USD')
->freeShippingOver(100) // Adds $0 shipping if subtotal >= $100
->tax(8, AmountType::PERCENT)
->calculate();
$isVip = true;
$orderTotal = 150;
$price = Pricer::base($orderTotal, 'USD')
->discountIf($isVip, 10, AmountType::PERCENT, 'VIP10')
->when(
fn() => $orderTotal >= 100,
fn($builder) => $builder->shipping(0, 'free')
)
->unless(
fn() => $orderTotal >= 100,
fn($builder) => $builder->shipping(12, 'standard')
)
->tax(8, AmountType::PERCENT)
->calculate();
use DerrickOb\Pricer\Pricer;
// US Dollars
$usd = Pricer::base(100, 'USD')->calculate();
echo $usd->getTotal()->format(); // "$100.00"
// Euros
$eur = Pricer::base(100, 'EUR')->calculate();
echo $eur->getTotal()->format('EUR', 'de_DE'); // "100,00 €"
// British Pounds
$gbp = Pricer::base(100, 'GBP')->calculate();
echo $gbp->getTotal()->format('GBP', 'en_GB'); // "£100.00"
use DerrickOb\Pricer\Support\Validator;
use DerrickOb\Pricer\Core\Money;
$baseAmount = Money::of(100, 'USD');
$components = [...]; // Your components
$result = Validator::validateAll($baseAmount, $components);
if (!$result['valid']) {
foreach ($result['errors'] as $error) {
echo "Error: $error\n";
}
}
foreach ($result['warnings'] as $warning) {
echo "Warning: $warning\n";
}
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
function generateInvoice($customer, $items, $taxRate)
{
$subtotal = array_sum(array_column($items, 'price'));
$invoice = Pricer::base($subtotal, 'USD');
if ($customer->hasDiscount()) {
$invoice->discount($customer->discount, AmountType::PERCENT);
}
if ($customer->needsShipping()) {
$invoice->shipping(calculateShipping($items));
}
$invoice->tax($taxRate, AmountType::PERCENT);
$price = $invoice->calculate();
// Store invoice in database
Invoice::create([
'customer_id' => $customer->id,
'subtotal' => $price->getSubtotal()->getAmountFloat(),
'discount' => $price->getDiscount()->getAmountFloat(),
'tax' => $price->getTax()->getAmountFloat(),
'total' => $price->getTotal()->getAmountFloat(),
'breakdown' => $price->toJson(),
]);
return $price;
}
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
use DerrickOb\Pricer\Enums\BillingCycle;
function chargeNewSubscriber($customer, $plan, $signupDate)
{
$nextBilling = $signupDate->modify('first day of next month');
// First invoice: prorated
$firstCharge = Pricer::base(0, 'USD')
->prorateSubscription(
$plan->price,
BillingCycle::MONTHLY,
$signupDate,
$nextBilling
)
->setupFee($plan->setupFee)
->tax($customer->taxRate, AmountType::PERCENT)
->calculate();
charge($customer, $firstCharge->getTotal());
// Schedule recurring charges
$recurringCharge = Pricer::base(0, 'USD')
->subscription($plan->price, BillingCycle::MONTHLY)
->tax($customer->taxRate, AmountType::PERCENT)
->calculate();
scheduleRecurring($customer, $recurringCharge->getTotal(), $nextBilling);
}
use DerrickOb\Pricer\Exceptions\InvalidAmountException;
use DerrickOb\Pricer\Exceptions\InvalidCurrencyException;
use DerrickOb\Pricer\Exceptions\CalculationException;
try {
$price = Pricer::base(-100, 'USD')->calculate();
} catch (InvalidAmountException $e) {
echo "Invalid amount: " . $e->getMessage();
}
try {
$money1 = Money::of(100, 'USD');
$money2 = Money::of(100, 'EUR');
$money1->add($money2); // Currency mismatch
} catch (InvalidCurrencyException $e) {
echo "Currency error: " . $e->getMessage();
}
try {
$price = Pricer::base(100, 'USD')
->discount(200, AmountType::FIXED) // Discount > base
->calculate();
} catch (CalculationException $e) {
echo "Calculation error: " . $e->getMessage();
}
use DerrickOb\Pricer\Pricer;
use DerrickOb\Pricer\Enums\AmountType;
public function test_checkout_calculation()
{
$price = Pricer::base(100, 'USD')
->discount(10, AmountType::PERCENT)
->tax(8, AmountType::PERCENT)
->calculate();
$this->assertEquals(97.20, $price->getTotal()->getAmountFloat());
$this->assertEquals(10.00, $price->getDiscount()->getAmountFloat());
$this->assertEquals(7.20, $price->getTax()->getAmountFloat());
}
bash
php artisan pricer:install