PHP code example of hamadou / fundry

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

    

hamadou / fundry example snippets


// app/Models/User.php
use Hamadou\Fundry\Traits\HasWallets;

class User extends Authenticatable
{
    use HasWallets;
    
    // ... vos autres traits et méthodes
}

return [
    // Devise par défaut
    'default_currency' => env('FUNDRY_DEFAULT_CURRENCY', 'USD'),
    
    // Précision décimale
    'precision' => env('FUNDRY_PRECISION', 8),
    
    // Utiliser le stockage en cents (non recommandé)
    'use_cents_storage' => env('FUNDRY_USE_CENTS', false),
    
    // Limites par défaut
    'limits' => [
        'daily_deposit' => env('FUNDRY_DAILY_DEPOSIT_LIMIT', 10000),
        'daily_withdrawal' => env('FUNDRY_DAILY_WITHDRAWAL_LIMIT', 10000),
        'daily_transfer' => env('FUNDRY_DAILY_TRANSFER_LIMIT', 50000),
    ],
    
    // Provider de taux de change
    'exchange_rate_provider' => env('FUNDRY_EXCHANGE_RATE_PROVIDER', 'manual'),
    'exchange_rate_api_key' => env('FUNDRY_EXCHANGE_RATE_API_KEY', null),
    
    // Cache
    'cache' => [
        'enabled' => env('FUNDRY_CACHE_ENABLED', true),
        'ttl' => env('FUNDRY_CACHE_TTL', 3600), // 1 heure
        'prefix' => 'fundry',
    ],
    
    // Exports
    'exports' => [
        'pdf' => [
            'orientation' => 'portrait',
            'paper' => 'a4',
        ],
        'excel' => [
            'format' => 'xlsx',
        ],
    ],
];

use Hamadou\Fundry\Facades\Fundry;

use Hamadou\Fundry\Facades\Fundry;
use Hamadou\Fundry\Enums\WalletType;
use Hamadou\Fundry\Models\Currency;

// Récupérer une devise
$usd = Currency::findByIsoCode('USD');

// Créer un portefeuille
$wallet = Fundry::createWallet($user, [
    'currency_id' => $usd->id,
    'name' => 'Mon Portefeuille Principal',
    'type' => WalletType::PERSONAL,
    'balance' => 0,
    'max_balance' => 100000.00,
    'min_balance' => 0,
    'transaction_limit' => 5000.00,
    'is_default' => true,
]);

$transaction = Fundry::deposit($wallet, 1000.00, 'Dépôt initial');

use Hamadou\Fundry\DTOs\DepositDTO;

$dto = new DepositDTO(
    userId: $user->id,
    walletId: $wallet->id,
    amount: 1000.00,
    description: 'Dépôt initial',
    commissionPercentage: 2.5 // 2.5% de commission
);

$transaction = Fundry::depositWithDTO($dto);

// Le montant net déposé sera 975.00 (1000 - 2.5%)
// La commission sera 25.00

$dto = DepositDTO::fromArray([
    'user_id' => $user->id,
    'wallet_id' => $wallet->id,
    'amount' => 1000.00,
    'description' => 'Dépôt',
    'commission_percentage' => 2.5,
    'metadata' => [
        'source' => 'bank_transfer',
        'reference' => 'BANK123456',
    ],
]);

$transaction = Fundry::withdraw($wallet, 500.00, 'Retrait');

use Hamadou\Fundry\DTOs\WithdrawalDTO;

$dto = new WithdrawalDTO(
    userId: $user->id,
    walletId: $wallet->id,
    amount: 500.00, // Montant net retiré
    description: 'Retrait',
    commissionPercentage: 1.0 // 1% de commission
);

$transaction = Fundry::withdrawWithDTO($dto);

// Le montant total débité sera 505.00 (500 + 1%)
// La commission sera 5.00

$transaction = Fundry::transfer($wallet1, $wallet2, 1000.00, 'Transfert');

use Hamadou\Fundry\DTOs\TransferDTO;

$dto = new TransferDTO(
    userId: $user->id,
    fromWalletId: $wallet1->id,
    toWalletId: $wallet2->id,
    amount: 1000.00,
    description: 'Transfert entre comptes',
    commissionPercentage: 1.5 // 1.5% de commission
);

$transaction = Fundry::transferWithDTO($dto);

// 1015.00 sera débité du wallet source
// 985.00 sera crédité au wallet destination
// 15.00 sera la commission

// Solde d'un portefeuille
$balance = Fundry::getWalletBalance($wallet);

// Historique des transactions
$history = Fundry::getWalletHistory($wallet, 50); // 50 dernières transactions

// Transactions d'un utilisateur
$transactions = Fundry::getUserTransactions($user->id, [
    'type' => 'deposit',
    'status' => 'completed',
    'start_date' => '2024-01-01',
    'end_date' => '2024-12-31',
], 100);

// Conversion simple
$amount = Fundry::convertAmount(100, 'USD', 'EUR');

// Conversion sécurisée avec validation
use Hamadou\Fundry\Models\Currency;

$usd = Currency::findByIsoCode('USD');
$eur = Currency::findByIsoCode('EUR');

try {
    $amount = $usd->convertToSafe(100, $eur);
    // Conversion réussie
} catch (\Hamadou\Fundry\Exceptions\InvalidCurrencyException $e) {
    // Gérer l'erreur
}

// Créer un portefeuille
$wallet = $user->createWallet([
    'currency_id' => $currency->id,
    'name' => 'Mon Wallet',
    'type' => WalletType::PERSONAL,
]);

// Récupérer un portefeuille par devise
$usdWallet = $user->getWalletByCurrency('USD');

// Portefeuille par défaut
$defaultWallet = $user->getDefaultWallet();

// Solde dans une devise
$balance = $user->getWalletBalance('USD');

// Solde total en USD
$totalUsd = $user->getTotalBalanceInUsd();

// Vérifier si le solde est suffisant
if ($user->hasSufficientBalance(500, 'USD')) {
    // Le solde est suffisant
}

// Portefeuilles par type
$businessWallets = $user->getWalletsByType(WalletType::BUSINESS);

use Hamadou\Fundry\Models\Country;

$senegal = Country::create([
    'name' => 'Sénégal',
    'name_en' => 'Senegal',
    'iso_code' => 'SN',
    'iso_code_3' => 'SEN',
    'numeric_code' => '686',
    'phone_code' => '+221',
    'continent' => 'Africa',
    'capital' => 'Dakar',
    'currency_code' => 'XOF',
    'currency_name' => 'West African CFA Franc',
    'currency_symbol' => 'CFA',
]);

use Hamadou\Fundry\Models\Currency;
use Hamadou\Fundry\Enums\CurrencyType;

$senegal = Country::findByIsoCode('SN');

$xof = Currency::create([
    'iso_code' => 'XOF',
    'code' => 'XOF',
    'name' => 'Franc CFA',
    'country_id' => $senegal->id,
    'type' => CurrencyType::FIAT,
    'symbol' => 'CFA',
    'exchange_rate' => 0.0017,
    'decimals' => 0,
]);

// Par code ISO 4217 (avec cache)
$usd = Currency::findByIsoCode('USD');

// Par pays
$france = Country::findByIsoCode('FR');
$euro = $france->currencies()->first();

// Par code devise du pays
$country = Country::where('currency_code', 'EUR')->first();

// Créer un portefeuille
Fundry::createWallet($user, array $data): Wallet

// Obtenir le solde
Fundry::getWalletBalance(Wallet $wallet): float

// Historique des transactions
Fundry::getWalletHistory(Wallet $wallet, int $limit = 50): Collection

// Transfert simple
Fundry::transfer(Wallet $from, Wallet $to, float $amount, ?string $description): Transaction

// Transfert avec DTO
Fundry::transferWithDTO(TransferDTO $dto): Transaction

// Dépôt simple
Fundry::deposit(Wallet $wallet, float $amount, ?string $description): Transaction

// Dépôt avec DTO
Fundry::depositWithDTO(DepositDTO $dto): Transaction

// Retrait simple
Fundry::withdraw(Wallet $wallet, float $amount, ?string $description): Transaction

// Retrait avec DTO
Fundry::withdrawWithDTO(WithdrawalDTO $dto): Transaction

// Obtenir une transaction par référence
Fundry::getTransactionByReference(string $reference): ?Transaction

// Transactions d'un utilisateur
Fundry::getUserTransactions($userId, array $filters = [], int $limit = 50): Collection

// Volume quotidien
Fundry::calculateDailyVolume($userId, string $currencyCode): float

// Créer une devise
Fundry::createCurrency(array $data): Currency

// Mettre à jour le taux de change
Fundry::updateExchangeRate(string $currencyCode, float $rate): bool

// Convertir un montant
Fundry::convertAmount(float $amount, string $fromCurrency, string $toCurrency): ?float

// Obtenir les devises supportées
Fundry::getSupportedCurrencies(): array

// Relations
$wallet->user()              // BelongsTo User
$wallet->currency()         // BelongsTo Currency
$wallet->fromTransactions() // HasMany Transaction
$wallet->toTransactions()   // HasMany Transaction

// Scopes
Wallet::active()            // Portefeuilles actifs
Wallet::default()           // Portefeuille par défaut
Wallet::byType($type)       // Par type
Wallet::hasBalance($amount) // Avec solde suffisant

// Méthodes
$wallet->canWithdraw($amount): bool
$wallet->deposit($amount): void
$wallet->withdraw($amount): void
$wallet->belongsToUser($user): bool
$wallet->getBalanceInUsd(): float
$wallet->getFormattedBalance(): string

// Relations
$transaction->user()        // BelongsTo User
$transaction->fromWallet() // BelongsTo Wallet
$transaction->toWallet()    // BelongsTo Wallet
$transaction->currency()    // BelongsTo Currency

// Scopes
Transaction::completed()    // Transactions complétées
Transaction::pending()      // Transactions en attente
Transaction::failed()       // Transactions échouées
Transaction::byType($type)  // Par type
Transaction::recent($days)  // Récentes

// Méthodes
$transaction->markAsCompleted(): void
$transaction->markAsFailed(?string $reason): void
$transaction->isPositive(): bool
$transaction->getFormattedAmount(): string

// Relations
$currency->country()        // BelongsTo Country
$currency->wallets()        // HasMany Wallet
$currency->transactions()   // HasMany Transaction

// Scopes
Currency::fiat()            // Devises fiat
Currency::crypto()          // Cryptomonnaies
Currency::device()          // Devises device
Currency::active()           // Devises actives

// Méthodes statiques
Currency::isValidIso4217Code(string $code): bool
Currency::findByIsoCode(string $isoCode): ?Currency

// Méthodes d'instance
$currency->convertTo($amount, Currency $target): float
$currency->convertToSafe($amount, Currency $target): float
$currency->canConvertTo(Currency $target): bool
$currency->getValueInUsd($amount): float
$currency->getValueInEur($amount): float
$currency->getFormattedAmount($amount): string

// Relations
$country->currencies()      // HasMany Currency

// Scopes
Country::active()           // Pays actifs
Country::byIsoCode($code)   // Par code ISO
Country::byCurrencyCode($code) // Par code devise

// Méthodes statiques
Country::isValidIsoCode(string $code): bool
Country::isValidCurrencyCode(string $code): bool
Country::findByIsoCode(string $isoCode): ?Country
Country::findByCurrencyCode(string $currencyCode): ?Country

// Constructeur
new DepositDTO(
    userId: int|string,
    walletId: int,
    amount: float,
    description?: ?string,
    commissionPercentage?: ?float,
    metadata?: ?array
)

// Méthodes
$dto->getNetAmount(): float           // Montant net après commission
$dto->getCommissionAmount(): float     // Montant de la commission
$dto->toArray(): array                 // Convertir en tableau
DepositDTO::fromArray(array): DepositDTO // Créer depuis un tableau

// Constructeur
new WithdrawalDTO(
    userId: int|string,
    walletId: int,
    amount: float,
    description?: ?string,
    commissionPercentage?: ?float,
    metadata?: ?array
)

// Méthodes
$dto->getTotalAmount(): float          // Montant total (montant + commission)
$dto->getCommissionAmount(): float     // Montant de la commission
$dto->toArray(): array
WithdrawalDTO::fromArray(array): WithdrawalDTO

// Constructeur
new TransferDTO(
    userId: int|string,
    fromWalletId: int,
    toWalletId: int,
    amount: float,
    description?: ?string,
    commissionPercentage?: ?float,
    metadata?: ?array
)

// Méthodes
$dto->getTotalAmount(): float          // Montant total débité
$dto->getNetAmount(): float            // Montant net crédité
$dto->getCommissionAmount(): float     // Montant de la commission
$dto->toArray(): array
TransferDTO::fromArray(array): TransferDTO

// Cette opération lancera une UnauthorizedWalletException
$dto = new DepositDTO(
    userId: $user1->id,
    walletId: $user2Wallet->id, // ❌ Erreur !
    amount: 100.00,
);

// Dans WalletService::deposit()
$wallet = Wallet::lockForUpdate()->findOrFail($walletId);
// ... opération sécurisée

use Hamadou\Fundry\Exceptions\{
    InsufficientFundsException,      // Fonds insuffisants
    InvalidAmountException,          // Montant invalide
    UnauthorizedWalletException,    // Wallet n'appartient pas à l'utilisateur
    InvalidCurrencyException,        // Problème de devise
    ConcurrencyException             // Erreur de concurrence
};

// config/fundry.php
'cache' => [
    'enabled' => true,
    'ttl' => 3600, // 1 heure
    'prefix' => 'fundry',
],

use Hamadou\Fundry\Services\CurrencyService;

$currencyService = app(CurrencyService::class);
$currencyService->clearCache();

try {
    $transaction = Fundry::withdrawWithDTO($dto);
} catch (InsufficientFundsException $e) {
    // Fonds insuffisants ou limites dépassées
    return response()->json(['error' => $e->getMessage()], 400);
} catch (InvalidAmountException $e) {
    // Montant invalide (négatif, trop de décimales, etc.)
    return response()->json(['error' => $e->getMessage()], 400);
} catch (UnauthorizedWalletException $e) {
    // Wallet n'appartient pas à l'utilisateur
    return response()->json(['error' => $e->getMessage()], 403);
} catch (InvalidCurrencyException $e) {
    // Problème de devise (inactive, taux invalide, etc.)
    return response()->json(['error' => $e->getMessage()], 400);
} catch (ConcurrencyException $e) {
    // Erreur de concurrence
    return response()->json(['error' => $e->getMessage()], 409);
}

use Hamadou\Fundry\Facades\Fundry;
use Hamadou\Fundry\DTOs\DepositDTO;
use Hamadou\Fundry\Enums\WalletType;

// 1. Créer un wallet pour le client
$wallet = Fundry::createWallet($customer, [
    'currency_id' => Currency::findByIsoCode('USD')->id,
    'name' => 'Portefeuille E-commerce',
    'type' => WalletType::PERSONAL,
]);

// 2. Traiter un paiement avec commission
$dto = new DepositDTO(
    userId: $customer->id,
    walletId: $wallet->id,
    amount: 150.00, // Montant de la commande
    description: "Paiement commande #{$orderId}",
    commissionPercentage: 2.9, // Commission de la plateforme
    metadata: [
        'order_id' => $orderId,
        'payment_method' => 'credit_card',
        'gateway' => 'stripe',
    ]
);

$transaction = Fundry::depositWithDTO($dto);

// 3. Vérifier le solde
$balance = Fundry::getWalletBalance($wallet);

// 4. Rembourser si nécessaire
if ($needsRefund) {
    $refundDto = new DepositDTO(
        userId: $customer->id,
        walletId: $wallet->id,
        amount: $transaction->amount,
        description: "Remboursement commande #{$orderId}",
        metadata: ['original_transaction_id' => $transaction->id]
    );
    Fundry::depositWithDTO($refundDto);
}

use Hamadou\Fundry\DTOs\TransferDTO;

// Vérifier que l'expéditeur a suffisamment de fonds
if (!$sender->hasSufficientBalance(50, 'USD')) {
    return response()->json(['error' => 'Solde insuffisant'], 400);
}

// Effectuer le transfert avec commission
$dto = new TransferDTO(
    userId: $sender->id,
    fromWalletId: $senderWallet->id,
    toWalletId: $receiverWallet->id,
    amount: 50.00,
    description: "Paiement de {$sender->name} à {$receiver->name}",
    commissionPercentage: 1.0, // 1% de commission pour la plateforme
    metadata: [
        'payment_type' => 'peer_to_peer',
        'sender_email' => $sender->email,
        'receiver_email' => $receiver->email,
    ]
);

$transaction = Fundry::transferWithDTO($dto);

// Notifier les utilisateurs
event(new PaymentCompleted($transaction));

// Récupérer tous les wallets d'un utilisateur
$wallets = $user->wallets()->with('currency')->active()->get();

// Convertir tous les soldes en USD
$totalUsd = 0;
$usd = Currency::findByIsoCode('USD');

foreach ($wallets as $wallet) {
    if ($wallet->currency->iso_code === 'USD') {
        $totalUsd += $wallet->balance;
    } else {
        try {
            $converted = $wallet->currency->convertToSafe($wallet->balance, $usd);
            $totalUsd += $converted;
        } catch (InvalidCurrencyException $e) {
            \Log::warning("Impossible de convertir {$wallet->currency->iso_code}: {$e->getMessage()}");
        }
    }
}

return response()->json([
    'total_balance_usd' => round($totalUsd, 2),
    'wallets_count' => $wallets->count(),
]);

// Calculer la commission en fonction du montant
function calculateCommission(float $amount): float
{
    if ($amount < 100) {
        return 3.0; // 3% pour les petits montants
    } elseif ($amount < 1000) {
        return 2.5; // 2.5% pour les montants moyens
    } else {
        return 1.5; // 1.5% pour les gros montants
    }
}

$amount = 500.00;
$commission = calculateCommission($amount);

$dto = new DepositDTO(
    userId: $user->id,
    walletId: $wallet->id,
    amount: $amount,
    commissionPercentage: $commission,
    description: 'Dépôt avec commission dynamique'
);

$transaction = Fundry::depositWithDTO($dto);

use Hamadou\Fundry\Facades\Fundry;

// Vérifier le volume quotidien
$dailyVolume = Fundry::calculateDailyVolume($user->id, 'USD');
$dailyLimit = config('fundry.limits.daily_deposit', 10000);

if ($dailyVolume + $amount > $dailyLimit) {
    return response()->json([
        'error' => 'Limite quotidienne dépassée',
        'daily_limit' => $dailyLimit,
        'current_volume' => $dailyVolume,
        'remaining' => $dailyLimit - $dailyVolume,
    ], 400);
}

// Procéder au dépôt
$transaction = Fundry::deposit($wallet, $amount);

// Vérifier les limites du wallet
$wallet->min_balance;
$wallet->transaction_limit;
$wallet->max_balance;

// Vérifier si le retrait est possible
if ($wallet->canWithdraw($amount)) {
    // OK
}

use Hamadou\Fundry\Services\CurrencyService;

$currencyService = app(CurrencyService::class);
$currencyService->clearCache();

// Vérifier l'appartenance avant l'opération
if (!$wallet->belongsToUser($user)) {
    throw new UnauthorizedWalletException();
}
bash
# Publier les migrations
php artisan vendor:publish --tag=fundry-migrations

# Publier la configuration
php artisan vendor:publish --tag=fundry-config
bash
php artisan migrate
bash
# Synchroniser les pays
php artisan fundry:sync-countries

# Seeder les devises principales
php artisan db:seed --class="Hamadou\Fundry\Seeders\CurrencySeeder"
bash
php artisan fundry:install
bash
php artisan fundry:sync-countries
bash
php artisan fundry:sync-countries --force
bash
php artisan fundry:validate-currencies
bash
# Validation simple
php artisan fundry:validate-currencies

# Validation avec correction automatique
php artisan fundry:validate-currencies --fix

🔍 Validation des devises...

✅ Toutes les devises sont valides!
📊 Total de devises validées: 25
bash
php artisan fundry:update-rates
bash
# Mode manuel (aucune mise à jour automatique)
php artisan fundry:update-rates

# Avec ExchangeRate-API
php artisan fundry:update-rates \
    --provider=exchangerate-api \
    --api-key=your_api_key_here \
    --base=USD

🔄 Mise à jour des taux de change (Provider: exchangerate-api, Base: USD)...
🌐 Récupération des taux depuis ExchangeRate-API...
✅ 25 taux de change mis à jour avec succès!

📊 Exemples de taux mis à jour:
  • EUR: 1.1
  • GBP: 1.27
  • XOF: 0.0017
  • MAD: 0.10
  • TND: 0.32
bash
php artisan fundry:currencies {action?}
bash
php artisan fundry:cash {action?}
bash
php artisan fundry:crypto {action?}
bash
php artisan fundry:report {type} [options]
bash
# Rapport des transactions en PDF
php artisan fundry:report transactions --format=pdf

# Rapport des transactions en Excel avec filtres
php artisan fundry:report transactions \
    --format=excel \
    --start-date=2024-01-01 \
    --end-date=2024-12-31 \
    --user-id=1 \
    --currency=USD

# Rapport des portefeuilles
php artisan fundry:report wallets --format=pdf --wallet-type=personal

# Rapport des devises
php artisan fundry:report currencies --format=excel

# Rapport avec fichier de sortie personnalisé
php artisan fundry:report transactions \
    --format=pdf \
    --output=rapport_janvier_2024

tests/
├── TestCase.php                    # Classe de base
├── Unit/
│   ├── Models/
│   │   ├── CurrencyTest.php
│   │   └── WalletTest.php
│   ├── DTOs/
│   │   ├── DepositDTOTest.php
│   │   ├── WithdrawalDTOTest.php
│   │   └── TransferDTOTest.php
│   └── Services/
│       ├── CurrencyServiceTest.php
│       ├── WalletServiceTest.php
│       └── TransactionServiceTest.php
└── Feature/
    └── WalletOperationsTest.php
bash
# Vérifier que les devises sont bien seedées
php artisan fundry:validate-currencies

# Re-seeder si nécessaire
php artisan db:seed --class="Hamadou\Fundry\Seeders\CurrencySeeder"