Unable to tokenize cards (flex). 400 - Token not created

garrettgjb
Regular Visitor

Unable to tokenize cards (flex). 400 - Token not created

I'm getting a 400 for some unknown reason with the response of: Token not created: One or more fields in the request contain invalid data. Resend the request with the correct information.

 

Please note I'm tokenizing a card in PHP just for purposes of unit testing and in production, I'll call the tokenization call from the browser.  I am getting a key with no encryption from the flex/v1/keys call and then using the resulting keyid in the next request to flex/v1/tokens with a test card.

 

 

Here's my code:

 

 

$secret="";
$key="";


function postData($url, $post_fields, $headers = null) {


    echo "\nREQUEST URL: " . $url;
    echo "\nREQUEST HEADERS: " . ($headers ? json_encode($headers) : "");
    echo "\nREQUEST BODY: ";
    echo $post_fields;
    echo "\n";



    $ch = curl_init();
    $timeout =100;
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $data = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }

    echo "---RESPONSE BODY: ";
    print_r($data);
    echo "\n\n\n\n\n";


    curl_close($ch);
    return $data;
}
 
function generateXpayToken($endpoint, $query, $bodyJson, $secret){
    $time = time(); 
 
    $pre_hash_string = $time.$endpoint.$query . $bodyJson; 
     
    $hashtoken = "xv2:".$time.":".hash_hmac('sha256', $pre_hash_string, $secret);
    return $hashtoken;
}


//build key request with no encryption
 
$urlbase="//sandbox.api.visa.com/cybersource";
$query = "apikey=" . $key;
$endpoint = "payments/flex/v1/keys";
$urlCur=$urlbase . $endpoint .'?'. $query;
$body=["encryptionType"=>"None"];
$bodyJson=json_encode($body);
$hashtoken = generateXpayToken($endpoint, $query, $bodyJson, $secret);
                    

 
$response = postData($urlCur, $bodyJson, ["Content-Type: application/json","x-pay-token: $hashtoken"]);
$responseJson = json_decode($response, true);
$kid = $responseJson['keyId'];



//build token request with no encryption


$cardInfoArr = [
'cardNumber' => "4111111111111111",
'cardType' => "001"
];

$bodyJson= json_encode(["keyId"=>$kid, "cardInfo"=>$cardInfoArr]);
$endpoint="payments/flex/v1/tokens";
 
$urlCur = $urlbase . $endpoint . '?' . $query;
$response = postData($urlCur, $bodyJson, ["Accept: application/json", "Content-Type: application/json"]);

 

 

 

Here's the output in case you don't know PHP. I outputted all headers, url and body so you can see what I'm sending.

 

 

REQUEST URL: //sandbox.api.visa.com/cybersource/payments/flex/v1/keys?apikey=REMOVED_API_KEY
REQUEST HEADERS: ["Content-Type: application\/json","x-pay-token: xv2:1560888060:8f6519676b85116de1f0adac2cc2ff871dbc9ca55c158cfa45cb80f21dc1a369"]
REQUEST BODY: {"encryptionType":"None"}
---RESPONSE BODY: {"keyId":"08ilMatl80QFkvQi2CYrSx2Nrcid9qys","der":{"format":"X.509","algorithm":"RSA","publicKey":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ErWtCIOSGzGAL2iLv/Lz9M4cWzh/7eu7EBoMXer2Eim7iB0LcmbqzMmhFHtuEgK69ckx1H6U/NM0q7qwleQ066Xt2Hg2CfmMf8wqMX+gOQxkcmeAQ5DhIpSNDv1ofkEqehDuYNpne+sX63f0OZgnUvRXH4aUW0q9Z4I2p4YKU0EEbPZqthG97RTNFtRN9n880nfJgSWixTQJHI5qhi5+fGp7sI/d4tOAp5EGXOGLesZT1Z5hxZ3G2TeB4GOjZgjyNkUE0eonTGVXqyVTus5l+MJ02+eykbotJK0zjlXStNZAuddzDobmt69Chiu2vPysbeAPgplvQlJMDpaac1cCwIDAQAB"},"jwk":null}





REQUEST URL: //sandbox.api.visa.com/cybersource/payments/flex/v1/tokens?apikey=REMOVED_API_KEY
REQUEST HEADERS: ["Accept: application\/json","Content-Type: application\/json"]
REQUEST BODY: {"keyId":"08ilMatl80QFkvQi2CYrSx2Nrcid9qys","cardInfo":{"cardNumber":"4111111111111111","cardType":"001"}}
---RESPONSE BODY: {"responseStatus":{"status":400,"reason":"TOKENIZATION_ERROR","message":"Token not created: One or more fields in the request contain invalid data.  Resend the request with the correct information.","correlationId":null,"details":[],"_embedded":{"icsReply":{"requestId":"5608880613826310504003","_links":{"self":{"href":"/cybersource/flex/search/v1/logs/tokenProvider/5608880613826310504003"}}}}},"_links":{"self":null,"documentation":[],"next":[]}}

 

 

Please note I had to replace "https://" with "//" just so the formatting didnt get messed up. My code has https://

3 REPLIES 3
API_Managers
Visa Developer Support Specialist

Re: Unable to tokenize cards (flex). 400 - Token not created

Hello garrettgjb,

 

CyberSource Secure Acceptance Flexible Token v1 APIs was deprecated, therefore, you will not be able to use the Flex API. You will need to move to v2 CyberSource Rest APIs going forward.
 
For Cybersource Auth, please use the below URL. The URL on your email refers to v1 which is deprecated.
 
https://sandbox.api.visa.com/cybersource/v2/payments?apikey=
 
For more details , please refer to Cybersource API reference page @ below link.
https://developer.visa.com/capabilities/cybersource/reference#cybersource__cybs_payments_v2__v2__pro...




Thanks,

Tee



Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.

garrettgjb
Regular Visitor

Re: Unable to tokenize cards (flex). 400 - Token not created

I'm not sure I follow. The page you linked to right above that has the documentation to "Secure Acceptance Flexible Token API". And theres no mention of it being deprecated. It says v1 is the latest.

 

Screen Shot 2019-06-18 at 5.52.02 PM.png

 

My goal was to not touch card numbers so I would like to tokenize cards from the front end and send it to the backend. How can I do that with Cybersource Payments REST API?

API_Managers
Visa Developer Support Specialist

Re: Unable to tokenize cards (flex). 400 - Token not created

Hi @garrettgjb,

 

CyberSource V1 is deprecated and not available for use . The CyberSource Payments documentation needs to be updated to reflect this. 

 

For CyberSource questions, we have an expert team that manages questions specific to this product. Please reach out to the CyberSource team directly using the phone number below.

 

CyberSource Support
800-709-7779

 




Thanks,

Tee



Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.