JazzCash Payment Integration Error: Transaction Type and Version Not Allowed
Problem
I’m trying to integrate JazzCash payment gateway in PHP but getting an error response saying “Provided Transaction Type and Version are not allowed”. I’m using their sandbox environment for testing.
Code
Here’s my PHP class for JazzCash integration:
class JazzCashPayment {
private $merchantId;
private $password;
private $integritySalt;
private $apiUrl;
public function __construct($merchantId, $password, $integritySalt, $isProduction = false) {
$this->merchantId = $merchantId;
$this->password = $password;
$this->integritySalt = $integritySalt;
$this->apiUrl = $isProduction
? 'https://payments.jazzcash.com.pk/ApplicationAPI/API/2.0/Purchase/DoMWalletTransaction'
: 'https://sandbox.jazzcash.com.pk/ApplicationAPI/API/2.0/Purchase/DoMWalletTransaction';
}
public function initializePayment($amount, $mobileNumber, $cnic) {
date_default_timezone_set('Asia/Karachi');
$DateTime = new DateTime();
$dateTime = $DateTime->format('YmdHis');
//------------------------------------------------------
//------------------------------------------------------
//expiry date, add 1 hour to $DateTime
$ExpiryDateTime = $DateTime;
$ExpiryDateTime->modify('+' . 1 . ' day');
$expiryDateTime = $ExpiryDateTime->format('YmdHis');
//------------------------------------------------------
$txnRefNo = 'Sol' . $dateTime;
// $amount = 100 * $amount;
// Create data array with exact structure and order
$data = array(
"pp_CNIC" => $cnic,
"pp_MobileNumber" => $mobileNumber,
"pp_Language" => "EN",
"pp_MerchantID" => $this->merchantId,
"pp_Password" => $this->password,
"pp_BankID" => "",
"pp_ProductID" => "",
"pp_TxnRefNo" => $txnRefNo,
"pp_Amount" => $amount,
"pp_TxnCurrency" => "PKR",
"pp_TxnDateTime" => $dateTime,
"pp_BillReference" => "billRef3781",
"pp_Description" => "Test case description",
"pp_TxnExpiryDateTime" => $expiryDateTime, // Can be modified for different expiry
"pp_SecureHash" => "",
"ppmpf_1" => $mobileNumber,
"ppmpf_2" => "",
"ppmpf_3" => "",
"ppmpf_4" => "",
"ppmpf_5" => ""
);
// Generate and add secure hash
$data['pp_SecureHash'] = $this->generateSecureHash($data);
echo '<pre>';
print_r($data);
echo '</pre>';
return $this->makeApiRequest($data);
}
public function generateSecureHash($data) {
// Step 1: Collect only pp-prefixed fields, excluding pp_SecureHash, pp_TxnType, and pp_Version
$ppData = [];
foreach ($data as $key => $value) {
$lowerKey = strtolower($key);
if (strpos($lowerKey, 'pp') === 0 && $lowerKey !== 'pp_securehash' && $lowerKey !== 'pp_txntype' && $lowerKey !== 'pp_version') {
$ppData[$lowerKey] = $value;
}
}
// Step 2: Sort fields by ASCII alphabetical order of keys
ksort($ppData);
// Step 3: Build the hash string by concatenating values with `&` separator
$hashString = '';
foreach ($ppData as $key => $value) {
if ($value !== "") { // Only non-empty values
$hashString .= ($hashString ? '&' : '') . $value;
}
}
// Step 4: Prepend Integrity Salt
$finalHashString = $this->integritySalt . '&' . $hashString;
// Step 5: Generate the HMAC hash with SHA-256
return strtoupper(hash_hmac('sha256', $finalHashString, $this->integritySalt));
}
/**
* Debug method to verify hash generation
*/
public function debugHash($data) {
echo "Input Data:n";
print_r($data);
// Remove pp_SecureHash
$ppData = $data;
unset($ppData['pp_SecureHash']);
// Sort by keys
ksort($ppData);
echo "nSorted Data:n";
print_r($ppData);
// Create hash string
$str = '';
foreach ($ppData as $value) {
if ($value !== "") {
$str = $str . '&' . $value;
}
}
// Add integrity salt
$str = $this->integritySalt . $str;
echo "nHash String:n$strn";
// Generate hash
$hash = strtoupper(hash_hmac('sha256', $str, $this->integritySalt));
echo "nGenerated Hash:n$hashn";
return $hash;
}
private function makeApiRequest($data) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $this->apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json'
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
throw new Exception("cURL Error: " . $err);
}
return json_decode($response, true);
}
}
Usage
$jazzcash = new JazzCashPayment(
'XXXX', // Merchant ID
'XXXXX', // Password
'XXXX', // Integrity Salt
false // Use sandbox environment
);
$response = $jazzcash->initializePayment(
'100', // Amount
'03123456789', // Mobile Number
'345678' // CNIC
);
Error Response
Array(
[pp_ResponseCode] => 110
[pp_ResponseMessage] => Provided Transaction Type and Version are not allowed.
// ... other response fields
)
What I’ve Tried
- Verified all required fields are being sent
- Double-checked the secure hash generation
- Confirmed the API endpoint URL is correct
- Verified merchant credentials
Question
Looking at the error message, it seems I’m missing the transaction type and version in the request. However, I couldn’t find clear documentation about how to include these parameters. Has anyone successfully integrated JazzCash payments who can point out what I’m missing?
Expected Behavior
The payment should be initialized successfully with the provided parameters.
Additional Context
- Using PHP 7.4+
- Testing in sandbox environment
- Following JazzCash API v2.0`