yogeshgupta/phonepe-laravel
Laravel integration for PhonePe payments. Provides simple configuration and helper methods to initiate transactions, generate required hashes/signatures, and handle callbacks/responses, making it easier to accept PhonePe payments in your Laravel app.
Strengths:
Phonepe) abstracts OAuth, HTTP requests, and webhook handling, making it ideal for rapid integration.PaymentSucceeded), enabling seamless integration with queues, notifications, or analytics.laravel-env-encrypter.Weaknesses:
MockFacade). This may slow down development if the team prioritizes test coverage.laravel-transactional-observers).Laravel Compatibility:
Log, Events) and guzzlehttp/guzzle (already included), minimizing external risks.PhonePe API Constraints:
/phonepe/webhook).retry helper or a library like spatie/laravel-queue-retries.Data Flow:
initiatePayment) is synchronous, blocking the HTTP request. For better UX, offload to queues (e.g., bus:dispatch).| Risk Area | Assessment | Mitigation Strategy |
|---|---|---|
| API Stability | PhonePe’s v2 API may evolve without backward compatibility. | Monitor PhonePe’s changelog and implement a wrapper layer to isolate changes. |
| Webhook Reliability | No retry mechanism for failed webhook deliveries. | Use Laravel Queues with retry-after or integrate with a dead-letter queue (e.g., spatie/laravel-queue-s3). |
| Security | OAuth tokens stored in Laravel config (plaintext risk). | Use laravel-env-encrypter or AWS Secrets Manager. Rotate tokens via PHONEPE_MERCHANT_SECRET. |
| Testing | Facade pattern complicates mocking in unit tests. | Use Mockery or Laravel Mocks to mock the facade. Test HTTP layer directly with Http::fake(). |
| Performance | Synchronous API calls may block requests under load. | Offload to queues (e.g., PhonePePaymentJob). Use sync:flush for testing. |
| Compliance | Logging may not meet PCI-DSS requirements out of the box. | Extend the logger to include structured JSON with monolog/handler (e.g., StreamHandler). |
| Idempotency | No built-in idempotency for payment retries. | Implement a payment_attempts table or use Laravel’s retry middleware with unique keys. |
reconcile-payments command) or use a service like Stripe’s Radar for dispute resolution.payment_id + transaction_id composite key in your database.merchant_id. Ensure your team has access and escalation paths.Laravel Core Components:
// Before
$response = Http::post('https://api.phonepe.com/pg/v1/pay', [
'merchantId' => config('phonepe.merchant_id'),
'amount' => 100.00,
// ...
]);
// After
$response = Phonepe::initiatePayment([
'amount' => 100.00,
'txnId' => 'txn_12345',
'callbackUrl' => route('payment.callback'),
]);
PaymentSucceeded, PaymentFailed in EventServiceProvider to trigger notifications or inventory updates.phonepe.webhook middleware to validate signatures:
Route::post('/phonepe/webhook', function (Request $request) {
if (!app(\Yogeshgupta\PhonepeLaravel\Traits\WebhookValidator::class)->validate($request)) {
abort(403);
}
// Process webhook
})->middleware('phonepe.webhook');
bus:work:
use Yogeshgupta\PhonepeLaravel\Jobs\ProcessWebhook;
ProcessWebhook::dispatch($webhookData)->onQueue('phonepe');
// config/phonepe.php
'logging' => [
'channel' => 'phonepe',
'level' => 'debug',
],
Third-Party Tools:
config/phonepe.php:
'http' => [
'timeout' => 30,
'retries' => 3,
'retry_delay' => 100, // ms
],
phonepe.* events for debugging..env withHow can I help you explore Laravel packages today?