hopekelldev / laravel-payvessel
A Laravel package for interacting with Payvessel API
v1.0.0
2025-07-18 11:37 UTC
Requires
- php: ^8.0
- illuminate/support: ^9.0|^10.0|^11.0
README
Laravel Payvessel is a Laravel 10+ package that provides a clean Facade-based integration with the Payvessel API. It allows you to easily create virtual accounts, retrieve account details, and update account BVNs using Laravel's fluent API.
Requirements
- PHP >= 8.0
- Laravel >= 10.0
- Laravel HTTP Client (built-in from Laravel 7+)
Installation
Install the package via Composer:
composer require hopekelldev/laravel-payvessel
Configuration
Publish Configuration File
Run the following command to publish the configuration file:
php artisan vendor:publish --tag=config --provider="HopekellDev\Payvessel\PayvesselServiceProvider"
Environment Variables
Add the following to your .env
file:
PAYVESSEL_API_KEY=your_api_key PAYVESSEL_API_SECRET=your_api_secret PAYVESSEL_BUSINESS_ID=your_business_id PAYVESSEL_API_URL=https://api.payvessel.com
Usage Example
Create a Virtual Account
use Payvessel; $response = Payvessel::virtualAccounts()->createVirtualAccount([ 'email' => 'johndoe@example.com', 'name' => 'JOHN DOE', 'phoneNumber' => '09012345678', 'bankcode' => ['999991'], // Example: PalmPay code 'account_type' => 'STATIC', 'bvn' => '12345678901', // Or 'nin' => '123456789' ]); if (isset($response['status']) && $response['status'] === 'success') { // Success logic } else { // Handle failure }
Available Methods
Category | Method | Description |
---|---|---|
Virtual Accounts | virtualAccounts()->createVirtualAccount($data) |
Create a reserved virtual account |
Virtual Accounts | virtualAccounts()->getSingleVirtualAccount($account) |
Get virtual account details |
Virtual Accounts | virtualAccounts()->accountBVNUpdate($account, $bvn) |
Update the BVN of a virtual account |
Example Controller Usage
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use HopekellDev\Payvessel\Facades\Payvessel; class PayvesselController extends Controller { public function createVirtualAccount(Request $request): JsonResponse { $validated = $request->validate([ 'email' => 'required|email', 'name' => 'required|string', 'phoneNumber' => 'required|string', 'bankcode' => 'required|array', 'account_type' => 'required|string|in:STATIC,DYNAMIC', 'bvn' => 'nullable|string', 'nin' => 'nullable|string', ]); try { $result = Payvessel::virtualAccounts()->createVirtualAccount($validated); return response()->json($result, 201); } catch (\InvalidArgumentException $e) { return response()->json(['error' => $e->getMessage()], 422); } catch (\Exception $e) { return response()->json(['error' => 'Server Error'], 500); } } public function getVirtualAccount($account): JsonResponse { try { $result = Payvessel::virtualAccounts()->getSingleVirtualAccount($account); return response()->json($result, 200); } catch (\Exception $e) { return response()->json(['error' => 'Server Error'], 500); } } public function updateAccountBVN(Request $request, $account): JsonResponse { $validated = $request->validate([ 'bvn' => 'required|string', ]); try { $result = Payvessel::virtualAccounts()->accountBVNUpdate($account, $validated['bvn']); return response()->json($result, 200); } catch (\Exception $e) { return response()->json(['error' => 'Server Error'], 500); } } /** * Handle Payvessel Webhook */ public function webhook(Request $request): JsonResponse { if (!$request->isMethod('post')) { return response()->json(['message' => 'Method not allowed'], 405); } $payload = $request->getContent(); $signature = $request->header('Payvessel-Http-Signature'); $ipAddress = $request->ip(); $allowedIps = ["3.255.23.38", "162.246.254.36"]; $secret = env("PAYVESSEL_API_SECRET"); $expectedHash = hash_hmac('sha512', $payload, $secret); if ($signature !== $expectedHash || !in_array($ipAddress, $allowedIps)) { return response()->json(['message' => 'Permission denied, invalid hash or IP address.'], 400); } $data = json_decode($payload, true); if ( !$data || !isset($data['transaction']['reference'], $data['order']['amount'], $data['virtualAccount']['virtualAccountNumber']) ) { return response()->json(['message' => 'Invalid payload structure'], 422); } $reference = $data['transaction']['reference']; $amount = floatval($data['order']['amount']); $virtualAccount = $data['virtualAccount']['virtualAccountNumber']; $virtualBankAccount = StaticBankAccount::where('account_number', $virtualAccount)->first(); if (!$virtualBankAccount || !$virtualBankAccount->user_id) { return response()->json(['message' => 'User not found'], 404); } $user = User::find($virtualBankAccount->user_id); if (!$user) { return response()->json(['message' => 'User not found'], 404); } if (Transaction::where('reference', $reference)->exists()) { return response()->json(['message' => 'Transaction already exists'], 200); } $transactionData = [ 'amount' => $amount, 'payment' => 'Wallet Funding', 'reference' => $reference, 'gateway_id' => 5, ]; Transaction::create([ 'user_id' => $user->id, 'reference' => $reference, 'amount' => $amount, 'status' => 'successful', 'gateway_id' => 5, ]); $user->increment('balance', $amount); return response()->json(['message' => 'success'], 200); } }
License
This package is released under the MIT License.
Author
Ezenwa Hopekell
- GitHub: HopekellDev
- Email: hopekelltech@gmail.com
- Message Hopekell on Whatsapp
Contributions & Issues
Feel free to submit a GitHub Issue or pull request for improvements or bug reports.