PHP code example of ideacrafters / eloquent-payable

1. Go to this page and download the library: Download ideacrafters/eloquent-payable 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/ */

    

ideacrafters / eloquent-payable example snippets




namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Ideacrafters\EloquentPayable\Traits\Payable;
use Ideacrafters\EloquentPayable\Contracts\Payable as PayableContract;
use Ideacrafters\EloquentPayable\Contracts\Payer;

class Invoice extends Model implements PayableContract
{
    use Payable;

    protected $fillable = ['total_amount', 'client_id', 'title', 'description', 'currency', 'status'];

    public function getPayableAmount(?Payer $payer = null): float
    {
        return $this->total_amount;
    }

    public function isPayableBy(Payer $payer): bool
    {
        return $this->client_id === $payer->getKey();
    }

    public function getPayableTitle(): string
    {
        return $this->title ?: "Invoice #{$this->id}";
    }

    public function getPayableDescription(): ?string
    {
        return $this->description;
    }

    public function getPayableCurrency(): string
    {
        return $this->currency ?: 'USD';
    }

    public function getPayableMetadata(): array
    {
        return [
            'invoice_id' => $this->id,
            'client_id' => $this->client_id,
            'status' => $this->status,
        ];
    }

    public function 



namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Ideacrafters\EloquentPayable\Traits\HasPayments;
use Ideacrafters\EloquentPayable\Contracts\Payer;

class User extends Authenticatable implements Payer
{
    use HasPayments;

    public function getKey()
    {
        return $this->getKey();
    }

    public function getMorphClass()
    {
        return static::class;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function canMakePayments(): bool
    {
        return $this->email_verified_at !== null;
    }

    public function getPreferredCurrency(): ?string
    {
        return $this->preferred_currency ?? 'USD';
    }

    public function getBillingAddress(): ?array
    {
        return $this->billing_address;
    }

    public function getShippingAddress(): ?array
    {
        return $this->shipping_address;
    }

    public function getTaxId(): ?string
    {
        return $this->tax_id;
    }

    public function getPhoneNumber(): ?string
    {
        return $this->phone;
    }

    public function getLocale(): ?string
    {
        return $this->locale ?? 'en';
    }

    public function getTimezone(): ?string
    {
        return $this->timezone ?? 'UTC';
    }

    public function getMetadata(): array
    {
        return [
            'user_id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}

// Process a payment
$invoice->pay($client, $invoice->total_amount);

// Process with Stripe
$invoice->pay($client, $invoice->total_amount, [
    'processor' => 'stripe',
    'payment_method_id' => 'pm_card_visa'
]);

// Create offline payment
$invoice->payOffline($client, $invoice->total_amount, [
    'type' => 'bank_transfer',
    'reference' => 'INV-2024-001'
]);

// Mark offline payment as paid
$payment = $invoice->payments()->pending()->first();
$payment->markAsPaid();

// Refund a payment
$payment->refund(50.00); // Partial refund
$payment->refund(); // Full refund

use Ideacrafters\EloquentPayable\Facades\Payable;

// Process payments
$payment = Payable::process($invoice, $client, 100.00);
$offlinePayment = Payable::processOffline($invoice, $client, 100.00);

// Payment management
$payment = Payable::find(1);
Payable::markAsPaid($payment);
Payable::markAsFailed($payment, 'Card declined');
Payable::refund($payment, 50.00);

// Payment queries
$payments = Payable::getPaymentsFor($invoice);
$userPayments = Payable::getPaymentsBy($user);
$totalPaid = Payable::getTotalPaidBy($user);
$hasPaid = Payable::hasPaidFor($invoice, $user);

// Statistics
$stats = Payable::getPaymentStats();
$processorStats = Payable::getProcessorStats();

// Health check
$health = Payable::getHealthCheck();

// Configuration
$config = Payable::getConfiguration();
$currencies = Payable::getSupportedCurrencies();
$processors = Payable::getProcessorNames();

// Logging
Payable::info('Payment processed', ['payment_id' => $payment->id]);
Payable::error('Payment failed', ['error' => $exception->getMessage()]);

return [
    'default_processor' => env('PAYABLE_PROCESSOR', 'stripe'),
    
    'processors' => [
        'stripe' => \Ideacrafters\EloquentPayable\Processors\StripeProcessor::class,
        'offline' => \Ideacrafters\EloquentPayable\Processors\OfflineProcessor::class,
        'none' => \Ideacrafters\EloquentPayable\Processors\NoProcessor::class,
    ],
    
    'tables' => [
        'payments' => 'payments',
    ],
    
    'currency' => 'USD',
    'decimal_precision' => 2,
    
    'routes' => [
        'enabled' => true,
        'prefix' => 'payable',
        'middleware' => ['web'],
    ],
    
    'stripe' => [
        'key' => env('STRIPE_KEY'),
        'secret' => env('STRIPE_SECRET'),
        'webhook_secret' => env('STRIPE_WEBHOOK_SECRET'),
    ],
];

// Create a redirect payment
$redirect = $invoice->payRedirect($client, $invoice->total_amount, [
    'processor' => 'stripe',
    'success_url' => 'https://yourapp.com/success',
    'cancel_url' => 'https://yourapp.com/cancel',
    'failure_url' => 'https://yourapp.com/failed'
]);

// Redirect user to payment page
return redirect($redirect->getRedirectUrl());

// Or use the Facade
$redirect = Payable::createRedirect($invoice, $client, $invoice->total_amount, [
    'processor' => 'stripe',
    'success_url' => 'https://yourapp.com/success'
]);

// Process immediate payment
$invoice->pay($client, 100.00, [
    'processor' => 'stripe',
    'payment_method_id' => 'pm_card_visa'
]);

// Create payment intent for later confirmation
$invoice->pay($client, 100.00, [
    'processor' => 'stripe'
]);

$invoice->payOffline($client, 100.00, [
    'type' => 'bank_transfer',
    'reference' => 'TXN-123456',
    'notes' => 'Payment via bank transfer'
]);

// Later, mark as paid
$payment->markAsPaid();

$freeItem->pay($user, 0.00, ['processor' => 'none']);
// Automatically marked as completed

class Product extends Model implements PayableContract
{
    use Payable;

    public function getPayableAmount($payer = null): float
    {
        // Dynamic pricing based on user
        if ($payer && $payer->is_premium) {
            return $this->price * 0.9; // 10% discount
        }
        return $this->price;
    }
}

// Usage
$product->pay($customer, $product->price * $quantity);

class ServiceInvoice extends Model implements PayableContract
{
    use Payable;

    public function getPayableAmount($payer = null): float
    {
        return $this->calculateTotal();
    }

    public function isPayableBy($payer): bool
    {
        return $this->client_id === $payer->id && $this->status === 'pending';
    }
}

class Campaign extends Model implements PayableContract
{
    use Payable;

    public function getPayableAmount($payer = null): float
    {
        return $payer ? $payer->donation_amount : 0;
    }
}

// Usage
$campaign->pay($donor, 100.00);

class Subscription extends Model implements PayableContract
{
    use Payable;

    public function getPayableAmount($payer = null): float
    {
        return $this->monthly_fee;
    }
}

$invoice->payments; // All payments for this invoice
$invoice->completedPayments; // Only completed payments
$invoice->pendingPayments; // Only pending payments
$invoice->failedPayments; // Only failed payments

$user->payments; // All payments made by user
$user->completedPayments; // Only completed payments
$user->pendingPayments; // Only pending payments
$user->paymentsToday(); // Today's payments
$user->paymentsThisMonth(); // This month's payments
$user->paymentFor($invoice); // Specific payment for an item
$user->hasPaidFor($invoice); // Check if user paid for item
$user->getTotalPaid(); // Total amount paid

use Ideacrafters\EloquentPayable\Events\PaymentCreated;
use Ideacrafters\EloquentPayable\Events\PaymentCompleted;
use Ideacrafters\EloquentPayable\Events\PaymentFailed;
use Ideacrafters\EloquentPayable\Events\PaymentRefunded;

// Listen to events
Event::listen(PaymentCompleted::class, function ($event) {
    // Send confirmation email
    Mail::to($event->payment->payer)->send(new PaymentConfirmation($event->payment));
});

// For offline payments, check the isOffline flag
Event::listen(PaymentCreated::class, function ($event) {
    if ($event->isOffline) {
        // Handle offline payment creation
    }
});

// In your Stripe dashboard, set webhook URL to:
// https://yourdomain.com/payable/webhooks/stripe

// Handle other processors
Route::post('/payable/webhooks/paypal', [WebhookController::class, 'handle']);



namespace App\Processors;

use Ideacrafters\EloquentPayable\Processors\BaseProcessor;
use Ideacrafters\EloquentPayable\Models\Payment;

class PayPalProcessor extends BaseProcessor
{
    public function getName(): string
    {
        return 'paypal';
    }

    public function process($payable, $payer, float $amount, array $options = []): Payment
    {
        // Your PayPal integration logic
        $payment = $this->createPayment($payable, $payer, $amount, $options);
        
        // Process with PayPal API
        $paypalPayment = $this->createPayPalPayment($amount, $options);
        
        $payment->update([
            'reference' => $paypalPayment->id,
            'status' => 'processing'
        ]);

        return $payment;
    }

    public function refund(Payment $payment, ?float $amount = null): Payment
    {
        // Your PayPal refund logic
        return $payment;
    }

    public function handleWebhook(array $payload)
    {
        // Handle PayPal webhooks
    }
}

'processors' => [
    'stripe' => \Ideacrafters\EloquentPayable\Processors\StripeProcessor::class,
    'paypal' => \App\Processors\PayPalProcessor::class,
    'offline' => \Ideacrafters\EloquentPayable\Processors\OfflineProcessor::class,
    'none' => \Ideacrafters\EloquentPayable\Processors\NoProcessor::class,
],

class Invoice extends Model implements PayableContract
{
    use Payable;

    public function getPayableAmount($payer = null): float
    {
        $baseAmount = $this->subtotal;
        
        // Apply discounts
        if ($payer && $payer->hasDiscount()) {
            $baseAmount *= 0.9;
        }
        
        // Add taxes
        $baseAmount += $this->calculateTax($baseAmount);
        
        return $baseAmount;
    }

    public function isPayableBy($payer): bool
    {
        // Only allow payment by the invoice client
        if ($this->client_id !== $payer->id) {
            return false;
        }
        
        // Check if invoice is in payable status
        if (!in_array($this->status, ['pending', 'overdue'])) {
            return false;
        }
        
        // Check if not already fully paid
        $totalPaid = $this->completedPayments()->sum('amount');
        return $totalPaid < $this->total_amount;
    }
}

// Get all completed payments
Payment::completed()->get();

// Get pending offline payments
Payment::pending()->offline()->get();

// Get payments from today
Payment::today()->get();

// Get payments from this month
Payment::thisMonth()->get();

// Get payments for specific payable
$invoice->payments()->completed()->sum('amount');

use Ideacrafters\EloquentPayable\Tests\TestCase;

class PaymentTest extends TestCase
{
    /** @test */
    public function can_process_payment()
    {
        $invoice = Invoice::factory()->create(['amount' => 100]);
        $user = User::factory()->create();
        
        $payment = $invoice->pay($user, 100);
        
        $this->assertEquals('completed', $payment->status);
        $this->assertEquals(100, $payment->amount);
    }
}
bash
php artisan vendor:publish --provider="Ideacrafters\EloquentPayable\PayableServiceProvider" --tag="config"
bash
php artisan migrate