javaspringqr-code

Problems with Cyrillic in generation QR codes


Im generating qr code for paying.

public GenerateQrResponse createQr(CreateQrRequest request) {
        var bnplEntity = bnplRepository.findByOrderId(request.getOrderNumber());
        if (bnplEntity.isEmpty()) {
            messengerUtils.sendTelegramBotMessage(telegramChatId, "bnpl not found by orderId. createQr method, orderNumber = " + request.getOrderNumber());
            throw new RuntimeException("bnpl entity not found while requesting qr code for bnpl with order number = " + request.getOrderNumber());
        }
        var bnplDto = bnplService.prepareBnplResponse(bnplEntity.get());
        bnplDto.setBnplId(bnplEntity.get().getId());
        bnplDto.setDate(bnplEntity.get().getCreatedAt());
        String linkUrl = bnplUrlService.getBnplUrl(bnplDto);

        BufferedImage logoImage = createRedCircleImage(50, 50);
        String logoBase64 = convertImageToBase64(logoImage);

        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(linkUrl, BarcodeFormat.QR_CODE, 250, 250, getQrCodeHintMap());

            BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

            byte[] logoBytes = Base64.getDecoder().decode(logoBase64);
            ByteArrayInputStream logoStream = new ByteArrayInputStream(logoBytes);
            logoImage = ImageIO.read(logoStream);

            BufferedImage combined = new BufferedImage(250, 250, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = combined.createGraphics();
            g.drawImage(qrImage, 0, 0, null);
            int x = (combined.getWidth() - logoImage.getWidth()) / 2;
            int y = (combined.getHeight() - logoImage.getHeight()) / 2;
            g.drawImage(logoImage, x, y, null);
            g.dispose();

            ByteArrayOutputStream combinedOutputStream = new ByteArrayOutputStream();
            ImageIO.write(combined, "PNG", combinedOutputStream);
            byte[] imageBytes = combinedOutputStream.toByteArray();
            return new GenerateQrResponse(Base64.getEncoder().encodeToString(imageBytes), request.getOrderNumber(), request.getAmount(), linkUrl);
        } catch (IOException | WriterException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

The problem is: when i building DTO for qr, i need to put address. If address will be in English, no any problems. But if address will be in cyrillic, in qr link all cyrillic text become like ?????

Main problem is that i have all adresses in cyrillic, our system working like this. Here DTO

return BnplDTO.builder()
                      .bnplId(bnpl.getId())
                      .amount(bnpl.getAmount())
                      .bin("111111111111")
                      .address("ул. Астана 58А")
                      .legalName("Example")
                      .build();

Im using qrgen library

<dependency>
            <groupId>net.glxn</groupId>
            <artifactId>qrgen</artifactId>
            <version>1.4</version>
</dependency>

Have idea to change library but may be anyone know how to solse this problem? thanks in advance


Solution

  • AFAIK QR codes are used to point to URLs. And they are commonly encoded as UTF-8. To be sure, use URL-encoding. See https://stackoverflow.com/a/10786112/4222206

    Another option would be to not put the whole data into the QR code but generate URL with a (transaction) code that leads back to your website, which then produces the full information.