Skip to content

Instantly share code, notes, and snippets.

@mahmoud-eskandari
Last active June 22, 2024 19:05
Show Gist options
  • Save mahmoud-eskandari/1041cc435f5837b540e69f5312165eb1 to your computer and use it in GitHub Desktop.
Save mahmoud-eskandari/1041cc435f5837b540e69f5312165eb1 to your computer and use it in GitHub Desktop.
گولنگ و پی اچ پی اعتبار سنجی کارت عابر بانک ایران در جاوا اسکریپت , Iranian bank cards validator function, Javascript Golang php ,تابع تشخیص صحت کارت عابربانک
"use strict";
// By Mahmoud Eskandari @ MIT license
function validateCard(card) {
if (typeof card === 'undefined'
|| card === null
|| card.length !== 16) {
return false;
}
let cardTotal = 0;
for (let i = 0; i < 16; i += 1) {
const c = Number(card[i]);
if (i % 2 === 0) {
cardTotal += ((c * 2 > 9) ? (c * 2) - 9 : (c * 2));
} else {
cardTotal += c;
}
}
return (cardTotal % 10 === 0);
}
@kasir-barati
Copy link

The same thing implemented in class-validator . In the following piece of code I write a custom decorator to do the same thing:

is-valid-card-number.decorator.ts:

import {
    registerDecorator,
    ValidationArguments,
    ValidationOptions,
    ValidatorConstraint,
    ValidatorConstraintInterface,
} from 'class-validator';

export const isNil = (value: any) => {
    if (value === undefined || value === null) {
        return true;
    }
    return false;
};

export function IsValidCardNumber(
    validationArguments?: ValidationOptions,
) {
    return function (object: Object, propertyName: string) {
        registerDecorator({
            name: 'IsValidCardNumber',
            propertyName,
            target: object.constructor,
            async: false,
            options: validationArguments,
            validator: IsValidCardNumberConstraint,
        });
    };
}

@ValidatorConstraint({ name: 'IsValidCardNumber', async: false })
export class IsValidCardNumberConstraint
    implements ValidatorConstraintInterface
{
    validate(
        value: string,
        validationArguments?: ValidationArguments,
    ): boolean | Promise<boolean> {
        return validateCard(value);
    }

    defaultMessage(
        validationArguments?: ValidationArguments,
    ): string {
        return `Entered card number - $value - is not a valid Iranian card number`;
    }
}

/**
 * README: This function comes from https://gist.github.com/mahmoud-eskandari/1041cc435f5837b540e69f5312165eb1
 */
function validateCard(card: string): boolean {
    if (
        typeof card === 'undefined' ||
        isNil(card) ||
        card.length !== 16
    ) {
        return false;
    }

    let cardTotal = 0;

    for (let i = 0; i < 16; i += 1) {
        const c = Number(card[i]);
        if (i % 2 === 0) {
            cardTotal += c * 2 > 9 ? c * 2 - 9 : c * 2;
        } else {
            cardTotal += c;
        }
    }

    return cardTotal % 10 === 0;
}

bank-info.dto.ts:

import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, IsString, Length } from 'class-validator';

import { IsValidCardNumber } from '../decorators/is-valid-card-number.decorator';

export class BankInfoDto {
    @ApiProperty({
        required: false,
        description: `bank account card number`,
        example: '1234123412341234',
        nullable: false,
    })
    @IsOptional()
    @Length(16, 16, { message: 'شماره کارت های بانکی ۱۶ رقم است' })
    @IsString()
    @IsValidCardNumber({
        message: 'شماره کارت وارد شده یک شماره کارت مجاز نیست',
    })
    cardNumber?: string;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment