class QrcodePixRuby::Payload

Constants

ATTRIBUTES
ID_ADDITIONAL_DATA_FIELD_TEMPLATE
ID_ADDITIONAL_DATA_FIELD_TEMPLATE_TXID
ID_COUNTRY_CODE
ID_CRC16
ID_MERCHANT_ACCOUNT_INFORMATION
ID_MERCHANT_ACCOUNT_INFORMATION_DESCRIPTION
ID_MERCHANT_ACCOUNT_INFORMATION_GUI
ID_MERCHANT_ACCOUNT_INFORMATION_KEY
ID_MERCHANT_ACCOUNT_INFORMATION_URL
ID_MERCHANT_CATEGORY_CODE
ID_MERCHANT_CITY
ID_MERCHANT_NAME
ID_PAYLOAD_FORMAT_INDICATOR
ID_POINT_OF_INITIATION_METHOD
ID_POSTAL_CODE
ID_TRANSACTION_AMOUNT
ID_TRANSACTION_CURRENCY

Public Class Methods

new(**kwargs) click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 30
def initialize(**kwargs)
  verify_kwargs(kwargs.keys)

  ATTRIBUTES.each do |attribute|
    singleton_class.class_eval { attr_accessor attribute }
    instance_variable_set("@#{attribute}", kwargs[attribute])
  end
end

Public Instance Methods

base64() click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 57
def base64
  ::RQRCode::QRCode.new(payload).as_png(
    bit_depth: 1,
    border_modules: 0,
    color_mode: 0,
    color: 'black',
    file: nil,
    fill: 'white',
    module_px_size: 6,
    resize_exactly_to: false,
    resize_gte_to: false
  ).to_data_url
end
payload() click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 39
def payload
  p = ''

  p += emv(ID_PAYLOAD_FORMAT_INDICATOR, '01')
  p += emv_repeatable
  p += emv_merchant
  p += emv(ID_MERCHANT_CATEGORY_CODE, '0000')
  p += emv(ID_TRANSACTION_CURRENCY, currency || '986')
  p += emv(ID_TRANSACTION_AMOUNT, amount) if amount
  p += emv(ID_COUNTRY_CODE, country_code || 'BR')
  p += emv(ID_MERCHANT_NAME, merchant_name)
  p += emv(ID_MERCHANT_CITY, merchant_city)
  p += emv(ID_POSTAL_CODE, postal_code) if postal_code
  p += emv_additional_data

  p + crc16(p)
end

Private Instance Methods

crc16(text) click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 103
def crc16(text)
  extended_payload = "#{text}#{ID_CRC16}04"
  extended_payload_length = extended_payload.length
  polynomial = 0x1021
  result = 0xFFFF

  if extended_payload_length.positive?
    offset = 0

    while offset < extended_payload_length
      result ^= extended_payload[offset].bytes[0] << 8
      bitwise = 0

      while bitwise < 8
        result <<= 1
        result ^= polynomial if result & 0x10000 != 0
        result &= 0xFFFF
        bitwise += 1
      end

      offset += 1
    end
  end

  "#{ID_CRC16}04#{result.to_s(16).upcase}"
end
emv(id, value) click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 81
def emv(id, value)
  size = value.to_s.length.to_s.rjust(2, '0')
  "#{id}#{size}#{value}"
end
emv_additional_data() click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 98
def emv_additional_data
  txid = emv(ID_ADDITIONAL_DATA_FIELD_TEMPLATE_TXID, transaction_id || '***')
  emv(ID_ADDITIONAL_DATA_FIELD_TEMPLATE, txid)
end
emv_merchant() click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 90
def emv_merchant
  merchant_gui         = emv(ID_MERCHANT_ACCOUNT_INFORMATION_GUI, 'BR.GOV.BCB.PIX')
  merchant_pix_key     = emv(ID_MERCHANT_ACCOUNT_INFORMATION_KEY, pix_key) if pix_key
  merchant_description = emv(ID_MERCHANT_ACCOUNT_INFORMATION_DESCRIPTION, description) if description
  merchant_url         = emv(ID_MERCHANT_ACCOUNT_INFORMATION_URL, url.gsub(/https?:\/\//, '')) if url
  emv(ID_MERCHANT_ACCOUNT_INFORMATION, "#{merchant_gui}#{merchant_pix_key}#{merchant_description}#{merchant_url}")
end
emv_repeatable() click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 86
def emv_repeatable
  emv(ID_POINT_OF_INITIATION_METHOD, repeatable ? '11' : '12')
end
verify_kwargs(keys) click to toggle source
# File lib/qrcode_pix_ruby/payload.rb, line 73
def verify_kwargs(keys)
  unknowns = keys - ATTRIBUTES

  return unless unknowns.any?

  raise QrcodePixRuby::PayloadArgumentError, "Unknown attributes: #{unknowns.join(', ')}"
end