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).
Laravel JazzCash Mobile Wallet REST API Integration
Key Features:
Mobile Wallet Payment Initiation: Utilizes the JazzCash DoMWalletTransaction v2.0 REST API for direct payment processing. Transaction Status Inquiry: Offers a method to check the status of a previously initiated transaction (implementation based on inferred PaymentInquiry API details, requires verification with official JazzCash documentation). Secure Callback/IPN Handling: Includes robust HMAC-SHA256 hash verification for incoming payment notifications to ensure data integrity and authenticity. Configurable Environments: Easily switch between JazzCash Sandbox and Production (Live) environments via configuration. Laravel Integration: Seamlessly integrates with Laravel applications through a Service Provider and Facade. Important Considerations:
API Focus: This package exclusively supports the direct JazzCash Mobile Wallet REST API. It does not support JazzCash Hosted Checkout, Page Redirection, Voucher Payments, or direct Card Payments. This distinction is important as other integration methods, like those found in packages such as zfhassaan/jazzcash, focus on different flows. API Version & CNIC Requirement: This package is built based on the available documentation for the JazzCash Mobile Wallet REST API v2.0 (CNIC Enabled). A critical requirement of this API version is the pp_CNIC parameter, which necessitates collecting the last 6 digits of the customer's CNIC (Computerized National Identity Card). Your application flow must accommodate this data collection. Failure to provide this will result in failed transactions with this specific API version. Other API versions (v1, v3, v4) are mentioned in JazzCash documentation , but detailed REST API specifications for direct mobile wallet payments through them were not sufficiently available in the provided materials to build a robust implementation in this package. 2. Installation Guide Require the Package via Composer: Open your terminal and run the following command in your Laravel project's root directory:bash composer require your-vendor/laravel-jazzcash
(Replace your-vendor/laravel-jazzcash with the actual package name once published on Packagist.)
Publish Configuration (Optional but Recommended): This package comes with a configuration file that allows you to set your JazzCash credentials and other settings. To publish the configuration file to your application's config directory, run:
Bash
php artisan vendor:publish --provider="Aticmatic\JazzCash\JazzCashServiceProvider" --tag="jazzcash-config" This command will create a config/jazzcash.php file in your application.
Package Auto-Discovery: For Laravel versions 5.5 and above, the package's Service Provider and Facade will be automatically discovered and registered by Laravel. Manual registration in config/app.php is typically not required.
Add the following keys to your .env file and replace the placeholder values with your actual JazzCash credentials:
Code snippet
JAZZCASH_ENVIRONMENT=sandbox # or "live" for production
JAZZCASH_SANDBOX_MERCHANT_ID=your_sandbox_merchant_id JAZZCASH_SANDBOX_PASSWORD=your_sandbox_password JAZZCASH_SANDBOX_SALT=your_sandbox_integrity_salt JAZZCASH_SANDBOX_RETURN_URL="{APP_URL}/jazzcash/callback" # Default, ensure this route exists JAZZCASH_LIVE_MERCHANT_ID=your_live_merchant_id JAZZCASH_LIVE_PASSWORD=your_live_password JAZZCASH_LIVE_SALT=your_live_integrity_salt JAZZCASH_LIVE_RETURN_URL="{APP_URL}/jazzcash/callback" # Default, ensure this route exists The config/jazzcash.php file allows for more detailed configuration:
Configuration Options Table:
Key Path (in config/jazzcash.php) Description Type Default Value (in config) .env Variable Example Environment Specific environment Sets the operating environment. Can be 'sandbox' or 'live'. string sandbox JAZZCASH_ENVIRONMENT No api_version The JazzCash API version this package is configured for. string 2.0 N/A No language Default language for API requests. string EN N/A No sandbox.merchant_id Your JazzCash Sandbox Merchant ID. string null JAZZCASH_SANDBOX_MERCHANT_ID Yes sandbox.password Your JazzCash Sandbox Password. string null JAZZCASH_SANDBOX_PASSWORD Yes sandbox.integrity_salt Your JazzCash Sandbox Integrity Salt (Hash Key). string null JAZZCASH_SANDBOX_SALT Yes sandbox.return_url The URL JazzCash will POST the transaction response to (Sandbox). string /jazzcash/callback JAZZCASH_SANDBOX_RETURN_URL Yes sandbox.api_base_url Base URL for JazzCash Sandbox REST API. string See config file N/A Yes live.merchant_id Your JazzCash Production (Live) Merchant ID. string null JAZZCASH_LIVE_MERCHANT_ID Yes live.password Your JazzCash Production (Live) Password. string null JAZZCASH_LIVE_PASSWORD Yes live.integrity_salt Your JazzCash Production (Live) Integrity Salt (Hash Key). string null JAZZCASH_LIVE_SALT Yes live.return_url The URL JazzCash will POST the transaction response to (Production). string /jazzcash/callback JAZZCASH_LIVE_RETURN_URL Yes live.api_base_url Base URL for JazzCash Production (Live) REST API. string See config file N/A Yes endpoints.do_mobile_wallet_transaction Path for the Mobile Wallet payment initiation API endpoint, relative to api_base_url. string See config file N/A No endpoints.transaction_inquiry Path for the Transaction Status Inquiry API endpoint, relative to api_base_url. (Needs Verification) string See config file N/A No
Export to Sheets Refer to existing JazzCash Laravel packages for common .env key naming conventions. The base API URLs are typically like https://sandbox.jazzcash.com.pk/ApplicationAPI/API/ for sandbox and https://payments.jazzcash.com.pk/ApplicationAPI/API/ for production.
PHP
use Aticmatic\JazzCash\Facades\JazzCash; use Aticmatic\JazzCash\Exceptions\JazzCashApiException;
try { $amount = 1000; // Amount in lowest currency unit (e.g., 10 PKR = 1000 Paisa) [1, 2] $mobileNumber = '03xxxxxxxxx'; // Customer's JazzCash mobile number $cnicLast6 = '123456'; // Last 6 digits of customer's CNIC (Mandatory for API v2.0) [1] $transactionRef = 'ORD-'. time(). rand(100, 999); // Your unique transaction reference number $billRef = 'INV-2023-101'; // Optional: Your bill or order reference $description = 'Payment for Order INV-2023-101';
// Optional parameters (ppmpf_1 to ppmpf_5)
$optionalParams = [
'ppmpf_1' => 'custom_data_1',
// 'ppmpf_2' => 'custom_data_2',
//... up to ppmpf_5
];
$response = JazzCash::initiateMobileWalletPayment(
$amount,
$mobileNumber,
$cnicLast6,
$transactionRef,
$billRef,
$description,
$optionalParams
);
// $response will be an array parsed from JazzCash's JSON response
if (isset($response) && $response === '000') {
// Payment request submitted successfully (this does not mean payment is complete)
// Store $transactionRef and other relevant details, await callback
// The actual payment happens when the user approves on their mobile (if required by JazzCash flow)
// or if it's a direct debit based on prior authorization (less common for initial payments).
// The API response indicates the request was accepted by JazzCash.
// For DoMWalletTransaction, the user might need to enter MPIN on their phone.
// The final status comes via the callback.
Log::info('JazzCash Payment Initiated: ', $response);
// Redirect user to a pending page or show a message to check their phone.
} else {
// Payment initiation failed
$errorMessage = $response?? 'Unknown error during payment initiation.';
Log::error('JazzCash Initiation Failed: '. $errorMessage, $response);
// Handle error, show message to user
}
} catch (JazzCashApiException $e) { Log::error('JazzCash API Exception: '. $e->getMessage()); // Handle API communication errors (e.g., network issues, server errors from JazzCash) } catch (\Exception $e) { Log::error('General Exception: '. $e->getMessage()); // Handle other unexpected errors } Parameters Explained:
$amount: The transaction amount in the lowest currency unit (e.g., for PKR 10.00, pass 1000). JazzCash API v2.0 documentation specifies that the last two digits are treated as decimal places. $mobileNumber: The customer's JazzCash registered mobile number. $cnicLast6: The last 6 digits of the customer's CNIC. This is mandatory for the JazzCash Mobile Wallet REST API v2.0. $transactionRef: A unique transaction reference number generated by you (the merchant). Max 20 alphanumeric characters. $billRef: An optional reference for your bill or order number. $description: A brief description of the transaction. $optionalParams: An associative array for ppmpf_1 through ppmpf_5 custom fields. The $response from initiateMobileWalletPayment is the direct JSON decoded array from the JazzCash API. A pp_ResponseCode of 000 generally indicates the request was successfully received and understood by JazzCash, not necessarily that the payment is complete. The final transaction outcome is communicated via the callback/IPN.
4.2. Checking Transaction Status To inquire about the status of a previously initiated transaction:
PHP
use Aticmatic\JazzCash\Facades\JazzCash; use Aticmatic\JazzCash\Exceptions\JazzCashApiException;
try { $transactionRef = 'ORD-1678886400123'; // The unique merchant transaction reference number
$statusResponse = JazzCash::getTransactionStatus($transactionRef);
// $statusResponse will be an array parsed from JazzCash's JSON response
if (isset($statusResponse)) {
Log::info('JazzCash Transaction Status: ', $statusResponse);
// Process the status:
// $statusResponse
// $statusResponse
// $statusResponse (or similar field indicating status)
// Refer to JazzCash documentation for a full list of response codes and status fields.
} else {
Log::error('JazzCash Status Inquiry Failed - Invalid Response Format: ', $statusResponse);
}
} catch (JazzCashApiException $e) { Log::error('JazzCash API Status Inquiry Exception: '. $e->getMessage()); } catch (\Exception $e) { Log::error('General Exception during Status Inquiry: '. $e->getMessage()); } Parameters Explained:
$transactionRef: The unique merchant-generated transaction reference number that was used when initiating the payment. Disclaimer for Transaction Status Inquiry: The specific JazzCash API endpoint (PaymentInquiry is inferred from community packages like one by rafayhingoro ) and the exact request/response parameters for a direct Mobile Wallet transaction status check via REST API require definitive confirmation from official JazzCash v2.0+ documentation. The current implementation is based on the best available information but should be thoroughly tested against the JazzCash sandbox and validated with their official API specifications for this specific use case. The pp_TxnType for inquiry might differ from payment initiation.
Define a Route: You need to define a route in your Laravel application to receive these POST requests. Typically, this is done in routes/web.php or routes/api.php.
PHP
// In routes/web.php or routes/api.php use Aticmatic\JazzCash\Http\Controllers\JazzCashCallbackController;
Route::post('/jazzcash/callback', [JazzCashCallbackController::class, 'handle'])->name('jazzcash.callback'); Note: Ensure the route path /jazzcash/callback matches what you've configured as your Return URL. Package route examples can be seen in.
Exclude from CSRF Verification: Since the callback is an external POST request from JazzCash, you must exclude this route from Laravel's CSRF protection. Add the route URI to the $except array in your app/Http/Middleware/VerifyCsrfToken.php file:
PHP
// In app/Http/Middleware/VerifyCsrfToken.php protected $except = [ 'jazzcash/callback', // Or your configured callback path // other routes... ]; This is crucial; otherwise, Laravel will reject the callback with a 419 Page Expired error.
Handle the Callback in a Controller: The package provides a default JazzCashCallbackController. Its handle method will automatically:
Verify the pp_SecureHash of the incoming request. Dispatch events: JazzCashPaymentSuccess or JazzCashPaymentFailed with the response data. You should listen for these events in your application to update your order status, notify users, etc.
Example Event Listener (in your EventServiceProvider.php):
PHP
// In app/Providers/EventServiceProvider.php protected $listen =, \Aticmatic\JazzCash\Events\JazzCashPaymentFailed::class => [ \App\Listeners\ProcessFailedJazzCashPayment::class, ], //... other events ]; Example Listener (App\Listeners\ProcessSuccessfulJazzCashPayment.php):
PHP
How can I help you explore Laravel packages today?