I am trying to integrate clover eCommerce pay API in a sandbox environment using PHP for making a payment. For this need to run 3 API.
- To getting API key using token.
- Get a pay Key which is used for encryption card details.
- Use for card tokenize or generate a token.
The first two are working fine but the last one not working always returns encryption pan error in all cases. Below is my code.
<?php
/*phpseclib1.0.2*/
include('phpseclib/Crypt/RSA.php');
include('phpseclib/Math/BigInteger.php');
/* ========== GET API KEY USING TOKEN ===========*/
$authToken = 'xxxxxxx-cdde-xxxxx-xxxx-xxxxxxxxx'; /* which is generate from clover backend system*/
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://apisandbox.dev.clover.com/pakms/apikey',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Authorization: Bearer '.$authToken
),
));
$response = curl_exec($curl);
curl_close($curl);
$apikeyArr = json_decode($response);
$apiKey = $apikeyArr->apiAccessKey;
echo 'API KEY <br/> ';
echo $apiKey;
/* ========== GET PAY KEY FOR ENCRYPT CARD DETAILS ===========*/
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.dev.clover.com/v2/merchant/B0T4DYVTYBTZ1/pay/key',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Authorization: Bearer '.$authToken,
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
$pay_key_data = json_decode($response);
echo '<br/> Key Data Response <br/> <pre>';
print_r($pay_key_data);
echo '<pre>';
$rsa = new Crypt_RSA();
$prefix = $pay_key_data->prefix;
$modulus = $pay_key_data->modulus;
$exponent = $pay_key_data->exponent;
/* ========= PREPARING CARD DETAILS TO PASS FOR TOKEN ============= */
$user_cc_no = '6011366668';
$user_cc_mo = '12';
$user_cc_yr = '2021';
$user_cc_cvv = '123';
$user_zip = '23402';
$stingToEnc = $prefix.$user_cc_no;
$modulus = new Math_BigInteger($modulus);
$exponent = new Math_BigInteger($exponent);
$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
$mypublickey = $rsa->getPublicKey();
$stingToEncPublickey = $stingToEnc;
$ciphertext = $rsa->encrypt($stingToEncPublickey);
$stingBase64Encpted = base64_encode($ciphertext);
$orderData = array();
$orderData['cardEncrypted'] = $stingBase64Encpted;
$orderData['first6'] = substr($user_cc_no, 0, 6);
$orderData['last4'] = substr($user_cc_no,-4);
$orderData['exp_month'] = $user_cc_mo;
$orderData['exp_year'] = $user_cc_yr;
$orderData['cvv'] = $user_cc_cvv;
$orderData['brand'] = "DISCOVER";
$cardData['card'] = $orderData;
$jsonCardData = json_encode($cardData);
echo '<br/> Card data that Passed <br/>';
echo '<pre>';
print_r($cardData);
echo '<pre>';
/* =============== NOW CALL API FOR TOKEN =================*/
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://token-sandbox.dev.clover.com/v1/tokens',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>$jsonCardData,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'apikey: '.$apiKey,
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
$responseCardTokenDetails = json_decode($response);
echo '<br/> Final Result <br/>';
echo '<pre>';
print_r($responseCardTokenDetails);
echo '</pre>';
?>
Below is the response that is getting from the last API.
Array
(
[card] => Array
(
[cardEncrypted] => qmLHcbgABk0abTNxm/tugSbR7OheVxlepRyciQDQBLw4WsGIr9UU6TjqxMcNuRxD/dD/e8p8c/G93B97Y1WygLpwmmN0H43E6QNlsNlQ/B/5AE3fpexTseOxLtB0/0wdmPbr1wA4vnxPfBMzNR7yPJ0Vk0iTsUc6ywkel+zn84wCBHjpAqMEtzy0WpdBe4VNVt0FxXZH7JTh7a/BxiGuvBiKPMvdGQChBvMBqEvPO8IQTjGlwjxoVKyKhuj7gT+AFA2SJ2NEIFigrbskkQQduGICxC5GdmT/YQWRPNlxgPvf8mckDNLfANBD5SeiuErmDT8DsdWu2kBhuKhGrf7FVQ==
[first6] => 601136
[last4] => 6668
[exp_month] => 12
[exp_year] => 2021
[cvv] => 123
[brand] => DISCOVER
)
)
Final Result
stdClass Object
(
[message] => 400 Bad Request
[error] => stdClass Object
(
[type] => invalid_request_error
[code] => invalid_request
[message] => Please provide either raw pan or encrypted pan.
)
)
One more thing in card details data if I remove cardEncrypted field then errors are still the same. Does anyone have an idea bout the above issue? Thanks in advance.
I came upon this question while having a problem of my own concerning clover payment. Needless to say, I found a solution to your problem before solving mine.
By the look of the response you were getting, you were missing the
primary account numberorPANfor short. And after taking a look into the createtoken documentation, thecardEncryptedyou are passing should beencrypted_panor you could add the card number undernumberwithout encryption.I am a month late so hopefully, this benefits someone in the future.