I unable to get credit card token on clover encryption issue

1k Views Asked by At

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.

  1. To getting API key using token.
  2. Get a pay Key which is used for encryption card details.
  3. 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.

1

There are 1 best solutions below

1
Elias Khazzaka On

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 number or PAN for short. And after taking a look into the createtoken documentation, the cardEncrypted you are passing should be encrypted_pan or you could add the card number under number without encryption.

I am a month late so hopefully, this benefits someone in the future.