aticmatic/laravel-jazzcash
Laravel package for JazzCash Mobile Wallet REST API v2.0: initiate wallet payments, verify secure callbacks (HMAC-SHA256), and inquire transaction status. Configurable for sandbox/live. Requires pp_CNIC (last 6 CNIC digits).
Installation
composer require aticmatic/laravel-jazzcash
php artisan vendor:publish --provider="AticMatic\JazzCash\JazzCashServiceProvider"
config/jazzcash.php) and migration for transactions table.Configuration
.env with JazzCash credentials:
JAZZCASH_MERCHANT_ID=your_merchant_id
JAZZCASH_API_KEY=your_api_key
JAZZCASH_API_SECRET=your_api_secret
php artisan migrate
First Use Case: Initiate a Payment
use AticMatic\JazzCash\Facades\JazzCash;
$response = JazzCash::initiatePayment([
'amount' => 100.00,
'currency' => 'PKR',
'customer' => [
'phone' => '03001234567',
'name' => 'John Doe'
],
'callback_url' => route('jazzcash.callback'),
'reference' => 'ORDER-12345'
]);
// Redirect to JazzCash payment URL
return redirect($response->payment_url);
Payment Initiation & Callback Handling
JazzCash::initiatePayment() to start a transaction.callback_url with transaction status. Store the response in the jazzcash_transactions table and validate it:
public function handleCallback(Request $request)
{
$transaction = JazzCash::validateCallback($request->all());
if ($transaction->status === 'SUCCESS') {
// Update order status, send confirmation, etc.
}
return response()->json(['status' => 'success']);
}
Transaction Querying
$transaction = JazzCash::getTransaction('ORDER-12345');
$transactions = JazzCash::listTransactions([
'start_date' => '2025-01-01',
'end_date' => '2025-01-31',
]);
Webhook Verification
validateCallback() method to prevent spoofing:
$valid = JazzCash::validateCallback($request->all(), true); // Strict mode
reference field. Example:
$order = Order::find($orderId);
$response = JazzCash::initiatePayment([
'reference' => 'ORDER-'.$order->id,
// ...
]);
JazzCash::setLogger(app(\Psr\Log\LoggerInterface::class));
Callback Validation
validateCallback() and enable strict mode (true) in production:
$valid = JazzCash::validateCallback($request->all(), true);
Amount Precision
100.00 vs 100.0000001).10000 for PKR 100.00) or round amounts:
$amount = round(100.00, 2);
Timeouts
try {
$response = JazzCash::initiatePayment(...);
} catch (\AticMatic\JazzCash\Exceptions\ApiException $e) {
if ($e->getCode() === 408) { // Request Timeout
sleep(2);
retry();
}
}
Configuration Quirks
.env values cause silent failures.if (!config('jazzcash.merchant_id')) {
throw new \RuntimeException('JazzCash merchant_id not configured.');
}
Custom Transaction Model
jazzcash_transactions table by publishing and modifying the migration:
php artisan vendor:publish --tag="jazzcash-migrations"
user_id or order_id to link transactions to your domain models.Custom Responses
JazzCash::setResponseHandler(function ($response) {
return json_decode($response->getBody(), true);
});
Testing
JazzCash::setMockMode(true) to test callbacks locally:
JazzCash::setMockMode(true);
$response = JazzCash::validateCallback($request->all());
$this->partialMock(\AticMatic\JazzCash\JazzCash::class, ['callApi']);
How can I help you explore Laravel packages today?