Skip to content

Instantly share code, notes, and snippets.

@DavidCabral
Last active March 18, 2022 19:23
Show Gist options
  • Save DavidCabral/a47a4ed2b08bb8df43e1b28af526c11a to your computer and use it in GitHub Desktop.
Save DavidCabral/a47a4ed2b08bb8df43e1b28af526c11a to your computer and use it in GitHub Desktop.
Java PIX estático, geração do QRCODE
/**
* Fonte = https://youtu.be/eO11iFgrdCA
*/
import java.text.DecimalFormat;
public class PixPayload {
private static final String ID_PAYLOAD_FORMAT_INDICATOR = "00";
private static final String ID_POINT_OF_INITIATION_METHOD = "01";
private static final String ID_MERCHANT_ACCOUNT_INFORMATION = "26";
private static final String ID_MERCHANT_ACCOUNT_INFORMATION_GUI = "00";
private static final String ID_MERCHANT_ACCOUNT_INFORMATION_KEY = "01";
private static final String ID_MERCHANT_ACCOUNT_INFORMATION_DESCRIPTION = "02";
private static final String ID_MERCHANT_CATEGORY_CODE = "52";
private static final String ID_TRANSACTION_CURRENCY = "53";
private static final String ID_TRANSACTION_AMOUNT = "54";
private static final String ID_COUNTRY_CODE = "58";
private static final String ID_MERCHANT_NAME = "59";
private static final String ID_MERCHANT_CITY = "60";
private static final String ID_ADDITIONAL_DATA_FIELD_TEMPLATE = "62";
private static final String ID_ADDITIONAL_DATA_FIELD_TEMPLATE_TXID = "05";
private static final String ID_CRC16 = "63";
private static final DecimalFormat VALUE = new DecimalFormat("00");
private static final DecimalFormat PIX_VALOR = new DecimalFormat("#00.00");
private String pixKey;
private String descricaoPagamento;
private String titularConta;
private String cidade;
private String txid;
private String valor;
public PixPayload(String pixKey, String descricaoPagamento, String titularConta, String cidade, String txid, String valor ) {
this.pixKey = pixKey;
this.descricaoPagamento = descricaoPagamento;
this.titularConta = titularConta;
this.cidade = cidade;
this.txid = txid;
this.valor = valor;
}
public static PixPayloadBuilder builder() {
return new PixPayloadBuilder();
}
public String getPayload() {
StringBuilder pay = new StringBuilder(getValue(ID_PAYLOAD_FORMAT_INDICATOR, "01"));
pay.append(getValue(ID_POINT_OF_INITIATION_METHOD, "12"));
pay.append(getMerchantAccountInformation());
pay.append(getValue(ID_MERCHANT_CATEGORY_CODE, "0000"));
pay.append(getValue(ID_TRANSACTION_CURRENCY, "986"));
pay.append(getValue(ID_TRANSACTION_AMOUNT, getValor()));
pay.append(getValue(ID_COUNTRY_CODE, "BR"));
pay.append(getValue(ID_MERCHANT_NAME, getTitularConta()));
pay.append(getValue(ID_MERCHANT_CITY, getCidade()));
pay.append(getAdditionalDatafieldTemplate());
String p = pay + ID_CRC16 + "04";
return pay + crc16(p.getBytes());
}
public static String crc16(final byte[] value) {
final int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
int result = 0xFFFF; // initial value
for (final byte b : value) {
for (int i = 0; i < 8; i++) {
final boolean bit = (b >> 7 - i & 1) == 1;
final boolean c15 = (result >> 15 & 1) == 1;
result <<= 1;
if (c15 ^ bit) {
result ^= polynomial;
}
}
}
result &= 0xffff;
return ID_CRC16 + "04" + esc(Integer.toHexString(result).toUpperCase(), 4, "0");
}
public static String esc(String valor, int qtd, String v) {
StringBuilder valorBuilder = new StringBuilder(valor);
while (valorBuilder.length() < qtd) {
valorBuilder.insert(0, v);
}
return valorBuilder.toString();
}
private String getAdditionalDatafieldTemplate() {
String txid = getValue(ID_ADDITIONAL_DATA_FIELD_TEMPLATE_TXID, getTxid());
return getValue(ID_ADDITIONAL_DATA_FIELD_TEMPLATE, txid);
}
private String getValue(String id, String valor) {
String size = VALUE.format(valor.length());
return id + size + valor;
}
private String getMerchantAccountInformation() {
String gui = getValue(ID_MERCHANT_ACCOUNT_INFORMATION_GUI, "br.gov.bcb.pix");
String key = getValue(ID_MERCHANT_ACCOUNT_INFORMATION_KEY, getPixKey());
String desc = getValue(ID_MERCHANT_ACCOUNT_INFORMATION_DESCRIPTION, descricaoPagamento);
return getValue(ID_MERCHANT_ACCOUNT_INFORMATION, gui + key + desc);
}
public String getPixKey() {
return this.pixKey;
}
public String getDescricaoPagamento() {
return this.descricaoPagamento;
}
public String getTitularConta() {
return this.titularConta;
}
public String getCidade() {
return this.cidade;
}
public String getTxid() {
return this.txid;
}
public String getValor() {
return this.valor;
}
public void setPixKey(String pixKey) {
this.pixKey = pixKey;
}
public void setDescricaoPagamento(String descricaoPagamento) {
this.descricaoPagamento = descricaoPagamento;
}
public void setTitularConta(String titularConta) {
this.titularConta = titularConta;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public void setTxid(String txid) {
this.txid = txid;
}
public void setValor(String valor) {
this.valor = valor;
}
public static class PixPayloadBuilder {
private String pixKey;
private String descricaoPagamento;
private String titularConta;
private String cidade;
private String txid;
private String valor;
PixPayloadBuilder() {
}
public PixPayloadBuilder pixKey(String pixKey) {
this.pixKey = pixKey;
return this;
}
public PixPayloadBuilder descricaoPagamento(String descricaoPagamento) {
this.descricaoPagamento = descricaoPagamento;
return this;
}
public PixPayloadBuilder titularConta(String titularConta) {
this.titularConta = titularConta;
return this;
}
public PixPayloadBuilder cidade(String cidade) {
this.cidade = cidade;
return this;
}
public PixPayloadBuilder txid(String txid) {
this.txid = txid;
return this;
}
public PixPayloadBuilder valor(double valor) {
this.valor = PIX_VALOR.format(valor).replace(",", ".");
return this;
}
public PixPayloadBuilder valor(String valor) {
this.valor = valor;
return this;
}
public PixPayload build() {
return new PixPayload(pixKey, descricaoPagamento, titularConta, cidade, txid, valor );
}
}
public class Test {
public static void main(String[] args) throws Exception {
PixPayload pay = PixPayload.builder()
.pixKey("chave")
.descricaoPagamento("descricao")
.titularConta("David")
.cidade("recife")
.valor(50.0)
.txid("0000000000000000000000000")
.build();
System.out.println(pay.getPayload());
}
}
// fonte = https://youtu.be/eO11iFgrdCA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment