<?php

class PayNowQR
{
    public static function generate($uen, $amount, $reference)
    {
        $amount = number_format($amount, 2, '.', '');

        $payload =
            "000201" .
            "010212" .
            "26370009SG.PAYNOW" .
            "0110" . strlen($uen) . $uen .
            "52040000" .
            "5303702" .
            "54" . str_pad(strlen($amount), 2, '0', STR_PAD_LEFT) . $amount .
            "5802SG" .
            "59" . str_pad(strlen("Exclusive Concierge"), 2, '0', STR_PAD_LEFT) . "Exclusive Concierge" .
            "60" . str_pad(strlen("Singapore"), 2, '0', STR_PAD_LEFT) . "Singapore" .
            "62" .
                "05" . str_pad(strlen($reference), 2, '0', STR_PAD_LEFT) . $reference;

        $payload .= "6304" . self::crc16($payload . "6304");

        return $payload;
    }

    private static function crc16($data)
    {
        $crc = 0xFFFF;

        for ($i = 0; $i < strlen($data); $i++) {
            $crc ^= ord($data[$i]) << 8;
            for ($j = 0; $j < 8; $j++) {
                if ($crc & 0x8000) {
                    $crc = ($crc << 1) ^ 0x1021;
                } else {
                    $crc <<= 1;
                }
                $crc &= 0xFFFF;
            }
        }

        return strtoupper(str_pad(dechex($crc), 4, '0', STR_PAD_LEFT));
    }
}
