Installation:
composer require kendenigerian/payzephyr
php artisan vendor:publish --provider="KenDeNigerian\PayZephyr\PayZephyrServiceProvider" --tag="migrations"
php artisan migrate
Configuration:
php artisan vendor:publish --provider="KenDeNigerian\PayZephyr\PayZephyrServiceProvider" --tag="config"
.env with your preferred provider credentials (e.g., PAYSTACK_SECRET_KEY, STRIPE_SECRET_KEY).providers array in config/payzephyr.php to define the order of fallback providers:
'providers' => [
'paystack' => [
'enabled' => true,
'priority' => 1,
],
'flutterwave' => [
'enabled' => false,
'priority' => 2,
],
// ...
],
First Use Case:
use KenDeNigerian\PayZephyr\Facades\PayZephyr;
$payment = PayZephyr::charge(1000, 'USD', [
'email' => 'customer@example.com',
'metadata' => ['order_id' => '12345'],
]);
return redirect()->away($payment->getRedirectUrl());
Webhook Setup:
routes/web.php:
Route::post('/payzephyr/webhook', [PayZephyrWebhookController::class, 'handleWebhook']);
config/payzephyr.php under webhooks.One-Time Charges:
Use PayZephyr::charge() for ad-hoc payments. The package automatically retries with the next enabled provider if the first fails.
$payment = PayZephyr::charge(5000, 'NGN', [
'email' => 'user@example.com',
'metadata' => ['invoice_id' => 'INV-2023-001'],
]);
max_attempts in config/payzephyr.php to control how many providers are tried before failing.Subscription Management:
Create subscriptions with PayZephyr::createSubscription():
$subscription = PayZephyr::createSubscription('monthly_plan', 2999, 'USD', [
'customer_email' => 'user@example.com',
'trial_days' => 7,
]);
subscription.created, invoice.payment_succeeded) via Laravel events or webhooks.Refunds and Cancellations:
// Refund a payment
PayZephyr::refund($paymentId, 1000, 'USD');
// Cancel a subscription
PayZephyr::cancelSubscription($subscriptionId);
PayZephyrWebhookController to handle provider-specific events:
public function handleWebhook(Request $request)
{
$event = PayZephyr::handleWebhook($request);
switch ($event->type) {
case 'invoice.payment_succeeded':
// Handle successful payment
break;
case 'subscription.updated':
// Handle subscription changes
break;
}
}
PayZephyr::extend() method to customize provider behavior:
PayZephyr::extend('paystack', function ($payzephyr, $provider) {
$provider->setCustomOption('metadata', ['custom_key' => 'custom_value']);
});
$provider = request()->input('country') === 'US' ? 'stripe' : 'paystack';
PayZephyr::setProvider($provider);
payzephyr_transactions table. Query logs for debugging:
$logs = \KenDeNigerian\PayZephyr\Models\TransactionLog::where('transaction_id', $paymentId)->get();
TransactionLog model or use observers to add custom fields to logs.PayZephyr::dispatchCharge($amount, $currency, $metadata)->onQueue('payments');
TransactionLog or creating custom resources.PayZephyrTestCase trait for seamless testing:
use KenDeNigerian\PayZephyr\Testing\PayZephyrTestCase;
class PaymentTest extends PayZephyrTestCase
{
public function test_payment_flow()
{
$this->mockPaystack()->shouldReceive('charge')->once();
// Test logic here
}
}
$paymentLink = PayZephyr::createPaymentLink(1000, 'USD', [
'email' => 'user@example.com',
'return_url' => route('payment.success'),
]);
paystack.js) alongside PayZephyr for seamless UX. Pass the reference or payment_id from PayZephyr to the SDK.$currency = session()->get('user_currency', 'USD');
PayZephyr::charge($amount, $currency, $metadata);
$price = $this->priceService->getDynamicPrice($productId);
PayZephyr::charge($price, 'USD', $metadata);
$subscription = PayZephyr::createSubscription('premium', 4999, 'USD', [
'trial_days' => 3,
'coupon' => 'WELCOME10',
]);
Webhook Delays:
handleWebhook method or use Laravel's retry middleware.$undelivered = \KenDeNigerian\PayZephyr\Models\WebhookLog::where('status', 'failed')->get();
foreach ($undelivered as $log) {
PayZephyr::retryWebhook($log->id);
}
Idempotency Keys:
Str::uuid() or a combination of user_id + timestamp:
$idempotencyKey = Str::uuid();
PayZephyr::charge($amount, $currency, $metadata, $idempotencyKey);
Currency and Amount Mismatches:
1000 for $10.00) and currencies are valid ISO codes. Providers like Paystack reject invalid formats.$amount = (int) ($price * 100); // Convert to cents
$currency = strtoupper($currency); // Ensure uppercase
Webhook Signature Validation:
config/payzephyr.php:
'webhooks' => [
'validate_signature' => env('APP_ENV') !== 'local',
],
**Provider-Specific Qu
How can I help you explore Laravel packages today?