php – Cannot save last four digits of the card to database-ThrowExceptions

Exception or error:

I am creating payment integration in Laravel. In there I want to save the last 4 digits of the card to the database. Here is the array I used to save the data to the database.

 $return_code = Payment::where('id', $transactionId)->update([
            'return_code' => $status,
            'return_message' => $status == 'success'? 'Successfully Captured': 'Payment Failed - ' .$errorMessage,
            'tx_ref' => $transactionReference,
            'transaction_amount' => !empty($amount) ? $amount : 0.00,
            'brand' => $cardType,
            'last4' => str_pad(substr($maskedPAN, -4), strlen(4), '*', STR_PAD_LEFT),
            'holder' => $cardholderName,
            'expiry' => $expiry,
            'payment_gateway' => 3,
        ]);

        return $status == 'success'?true : false;

From this code, it saves the last four digits to the database, only if the last four digits start without zero. It means if the card number is as 4111 1111 1111 1111 it saves to the database as 1111.

But, if the last four digits of the card starts with zero, it saves only 111 to the database. It means if the card number is as 4000 4000 0000 0111 it saves only 111 to the database.

Please help me to save the last four digits of the card even if the last four digits start with zero as 4000 4000 0000 0111.

Thank you.

How to solve:

Using int as datatype will remove the zeroes on the left.

If you need to keep it you should change to varchar.

In laravel you can create a migration to change it (https://laravel.com/docs/5.8/migrations#modifying-columns):

public function up()
{
    Schema::table('myTable', function (Blueprint $table) {
        $table->string('last4', 4)->change();
    });
}

You may need to run composer require doctrine/dbal

If you can’t change the column data type, another option would be to convert the data to string on runtime and use str_pad() function, but I don’t think this is a good option here.

Answer:

I’m supposing you’re using MySQL.

Since your column it’s a INT you can’t because it’s a number and the number isn’t saved with zeros on the left unless you specify the ZEROFILL int column. What you can do is modify it, ALTER the column and add the ZEROFILL to the column (Not changing the type) to fill with zeros when the number it’s less than 4 digits.

Also, INT(4) doesn’t mean that only accept 0 or 4 digits, you can even store 20 or more than 4 digits, it’s range doesn’t change, you should read this to understand it better.

Answer:

Since you can’t change the type of the table field from int to varchar, a better solution would be to store your value as an int like so

$return_code = Payment::where('id', $transactionId)->update([
               // other fields
               'last4' => (int)substr($maskedPAN, -4),
               // other fields
               ]);

return $status == 'success'?true : false;

Then, always use a method that returns the required number of digits to retrieve the last4 field from Payment

function getLast4($intval) {
    return str_pad($intval, 4, 0, STR_PAD_LEFT);
}

$var = Payment::where('id', $transactionId)->pluck('last4');
$last4 = getLast4($var[0]);

Leave a Reply

Your email address will not be published. Required fields are marked *