Skip to content

Logging

Laravel Payments provides structured, dot-notation logging with automatic redaction of sensitive data and dual output to Laravel log channels and a queryable database table.

Configuration

php
// config/payments.php
'logging' => [
    'level' => env('PAYMENT_LOG_LEVEL', 'basic'),
    'channel' => env('PAYMENT_LOG_CHANNEL', null), // null = default channel
    'db_logging' => true,
    'redacted_keys' => [
        'secret', 'password', 'token', 'key',
        'card_number', 'cvv', 'cvc', 'pin',
        'authorization', 'signature',
    ],
],

Log Levels

LevelWhat's Logged
offNothing
errors_onlyOnly errors
basicErrors + warnings + key info messages
verboseEverything except debug
debugEverything including raw payloads

Automatic Logging

The payment system logs automatically at every stage:

CategoryLevelWhen
payment.createinfoPayment creation initiated
payment.create.successinfoPayment created successfully
payment.create.failederrorPayment creation failed
payment.verifyinfoPayment verification
payment.refundinfoRefund operation
webhook.receivedinfoWebhook received
webhook.signature.invalidwarningInvalid webhook signature
webhook.processedinfoWebhook processed successfully
webhook.idempotentinfoDuplicate webhook ignored
return.receivedinfoReturn callback received
cancel.receivedinfoCancel callback received

Redaction

Sensitive keys are automatically redacted in log output:

php
// Original context
['credentials' => ['key' => 'sk_test_xxx', 'secret' => 'whsec_yyy']]

// After redaction
['credentials.key' => '[REDACTED]', 'credentials.secret' => '[REDACTED]']

The redaction matches any key that contains any of the configured redacted_keys, case-insensitive.

Database Logs

When db_logging is enabled, logs are stored in the payment_logs table with structured fields:

php
use Frolax\Payment\Models\PaymentLog;

// Query logs by gateway
PaymentLog::forGateway('stripe')->latest('occurred_at')->get();

// Query logs by level
PaymentLog::forLevel('error')->get();

// Query logs by category
PaymentLog::forCategory('webhook.received')->get();

// Each log entry contains:
$log->level;          // 'info', 'warning', 'error', 'debug'
$log->category;       // 'payment.create', 'webhook.received', etc.
$log->message;        // Human-readable message
$log->gateway_name;   // 'stripe'
$log->profile;        // 'test'
$log->tenant_id;      // 'tenant-abc'
$log->payment_id;     // 'PAY-001'
$log->attempt_id;     // 'ATT-001'
$log->context_flat;   // Dot-noted key-value pairs (redacted)
$log->context_nested; // Original nested structure (redacted)
$log->occurred_at;    // Timestamp

Manual Logging

You can use the payment logger directly:

php
use Frolax\Payment\Contracts\PaymentLoggerContract;

class MyService
{
    public function __construct(
        protected PaymentLoggerContract $logger,
    ) {}

    public function doSomething()
    {
        $this->logger->info('custom.operation', 'Starting custom operation', [
            'gateway' => ['name' => 'stripe'],
            'custom_data' => ['key' => 'value'],
        ]);

        $this->logger->error('custom.operation', 'Something went wrong', [
            'error' => ['message' => 'Details here'],
        ]);
    }
}

Dot-Notation Context

Log context is automatically flattened to dot-notation:

php
// Input (nested)
[
    'gateway' => ['name' => 'stripe'],
    'payment' => ['id' => 'PAY-001', 'amount' => 2999],
]

// Stored as context_flat (dot-notation)
[
    'gateway.name' => 'stripe',
    'payment.id' => 'PAY-001',
    'payment.amount' => 2999,
]

This makes database logs easily queryable and filterable.

Released under the MIT License.