Răsfoiți Sursa

first commit

glopes 1 lună în urmă
comite
a0c98302f5
8 a modificat fișierele cu 976 adăugiri și 0 ștergeri
  1. 11 0
      .env.example
  2. 4 0
      .gitignore
  3. 19 0
      .vscode/settings.json
  4. 471 0
      README.md
  5. 454 0
      genial-cli
  6. 0 0
      hookcashin.json
  7. 0 0
      hookcashout.json
  8. 17 0
      package.json

+ 11 - 0
.env.example

@@ -0,0 +1,11 @@
+TOKEN_BASIC= **********************************************************************************************************************************
+TOKEN_XORIGEN= **************************
+ACCOUNT1= *********
+ACCOUNT2= *********
+ACCOUNT1_KEY= ************************************
+ACCOUNT2_KEY= 
+DOCUMENT_NUMBER= **************
+ACCOUNT1_NAME= ******************
+ACCOUNT2_NAME= ***************
+ACCOUNT2_DOC= *************
+ACCOUNT1_CITY= ***********

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+vscode
+node_modules
+.env
+package-lock.json

+ 19 - 0
.vscode/settings.json

@@ -0,0 +1,19 @@
+{
+  "files.exclude": {
+    "**/.git": true,
+    "**/.svn": true,
+    "**/.hg": true,
+    "**/.DS_Store": true,
+    "**/Thumbs.db": true,
+    "/.classpath": true,
+    "/.DS_Store": true,
+    "/.factorypath": true,
+    "/.git": true,
+    "/.hg": true,
+    "/.project": true,
+    "/.settings": true,
+    "/.svn": true,
+    "/CVS": true,
+    "/Thumbs.db": true
+  }
+}

+ 471 - 0
README.md

@@ -0,0 +1,471 @@
+# GenialBankHTTPService – Documentação de Endpoints
+
+---
+
+## 1. Autenticação – `getCredentials`
+
+**POST**
+`https://genial-arquitetura-authentication.homolog.api.genial.systems/v1/authentication`
+
+**Request**
+
+```json
+{
+  "headers": {
+    "Authorization": "Bearer <TOKEN>",
+    "X-ORIGEM": "APP"
+  }
+}
+```
+
+**Response**
+
+```json
+{
+  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
+}
+```
+
+---
+
+## 2. Consultar Saldo – `getBalance`
+
+**GET**
+`https://genial-arquitetura-corebank.homolog.api.genial.systems/v1/core-banking/balance/1/{accountNumber}`
+
+**Headers**
+
+```json
+{
+  "Authorization": "Bearer <TOKEN>",
+  "X-ORIGEM": "APP"
+}
+```
+
+**Response**
+
+```json
+{
+  "data": "2025-10-31T15:45:00Z",
+  "saldoDisponivel": 12500.75,
+  "saldoDisponivelParaMovimentacao": 12400.75,
+  "saldoVinculado": 50.00,
+  "saldoBloqueado": 0.00,
+  "saldoContabil": 12550.75,
+  "saldoInvestimento": 2000.00,
+  "saldoAuxilioEmergencial": 0.00,
+  "limiteCreditoDisponivel": 5000.00,
+  "limiteCreditoContratado": 10000.00
+}
+```
+
+---
+
+## 3. Consultar Chave Pix – `getDictKey`
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v2/pix/key-account-partner/1/{accountNumber}/{pixKey}`
+
+**Headers**
+
+```json
+{
+  "Authorization": "Bearer <TOKEN>",
+  "X-ORIGEM": "APP"
+}
+```
+
+**Response**
+
+```json
+{
+  "key": "gustavo.silva@empresa.com",
+  "keyType": "EMAIL",
+  "idPixKey": "5f9a8d27-1c3b-4b8f-bcc1-7d231f0a1234",
+  "pspIdentification": "GENIALBANKBRSPXXX",
+  "accountHolder": {
+    "taxId": "12345678909",
+    "name": "Gustavo Silva"
+  },
+  "status": "ACTIVE",
+  "creationDate": "2025-10-31T14:25:32Z",
+  "updateDate": "2025-10-31T14:25:32Z",
+  "keyLocallyActive": "true",
+  "endToEndId": "E1234567820231031142532000000001"
+}
+```
+
+---
+
+## 4. Status de Envio Pix (PAC008) – `getPixPaymentStatusOutByInstantPaymentId`
+
+**GET**
+`https://genial-baas-operations.homolog.api.genial.systems/v1/cashout/pix-send/instant-payment-id/{instantPaymentId}?date={yyyy-mm-dd}`
+
+**Headers**
+
+```json
+{
+  "Authorization": "Bearer <TOKEN>",
+  "X-ORIGEM": "APP"
+}
+```
+
+**Response**
+
+```json
+{
+  "pixSendRequest": {
+    "debit": {
+      "name": "Gustavo Silva",
+      "agency": 1,
+      "account": "123456",
+      "accountType": "CHECKING",
+      "document": "12345678909"
+    },
+    "credit": {
+      "name": "Maria Oliveira",
+      "agency": 1,
+      "account": "654321",
+      "accountType": "CHECKING",
+      "document": "98765432100",
+      "ispb": "12345678",
+      "key": "maria.oliveira@banco.com",
+      "endToEndId": "E1234567820251031143000000009876"
+    },
+    "idempotencyId": "IDE123456789",
+    "value": 150.75,
+    "transactionApproved": true
+  },
+  "statusResponse": {
+    "value": 150.75,
+    "eventStatus": {
+      "code": "200",
+      "description": "Pagamento confirmado"
+    },
+    "endToEndId": "E1234567820251031143000000009876"
+  },
+  "id": "STAT-PIXOUT-00012345",
+  "createDate": "2025-10-31T15:00:00Z",
+  "updateDate": "2025-10-31T15:00:02Z"
+}
+```
+
+---
+
+## 5. Pagamento via QR Code (PAC008) – `pac008Qr`
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/pix/copy-paste`
+
+**Body**
+
+```json
+{
+  "qrCodeCopyPaste": "0002012658...",
+  "Value": 150.75,
+  "debit": {
+    "name": "Gustavo Silva",
+    "agency": 1,
+    "account": "123456",
+    "accountType": "CHECKING"
+  }
+}
+```
+
+**Response**
+
+```json
+{
+  "data": {
+    "value": 150.75,
+    "instantPaymentId": "PIX-OUT-XYZ123456",
+    "eventStatus": {
+      "code": "200",
+      "description": "Pagamento efetuado com sucesso"
+    }
+  },
+  "error": ""
+}
+```
+
+---
+
+## 6. Iniciar Pagamento via Chave (PAC008 Start)
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/pix/send/initialization`
+
+**Body**
+
+```json
+{
+  "debit": {
+    "name": "Gustavo Silva",
+    "agency": 1,
+    "account": "123456"
+  },
+  "credit": {
+    "key": "maria.oliveira@banco.com"
+  },
+  "value": "200.50"
+}
+```
+
+**Response**
+
+```json
+{
+  "data": {
+    "key": "maria.oliveira@banco.com",
+    "keyType": "EMAIL",
+    "pspIdentification": "GENIALBANKBRSPXXX",
+    "accountHolder": {
+      "taxId": "98765432100",
+      "name": "Maria Oliveira"
+    },
+    "status": "ACTIVE",
+    "endToEndId": "E1234567820251031142532000000001",
+    "idempotencyId": "IDEMP-PIX-0001"
+  },
+  "error": ""
+}
+```
+
+---
+
+## 7. Efetivar Pagamento via Chave (PAC008)
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/pix/send/payment`
+
+**Body**
+
+```json
+{
+  "idempotencyId": "IDEMP-PIX-0001",
+  "ignorePaymentDuplication": false,
+  "additionalInformation": "Pagamento de serviço",
+  "historicComplement": "Ref#1234"
+}
+```
+
+**Response**
+
+```json
+{
+  "data": {
+    "instantPaymentId": "PIX-OUT-XYZ123456",
+    "eventStatus": {
+      "code": "200",
+      "description": "Pagamento concluído"
+    },
+    "transactionPurpose": "PAYMENT"
+  },
+  "error": ""
+}
+```
+
+---
+
+## 8. Status de Recebimento Pix (PAC002) – `getPixPaymentStatusInByTransactionId`
+
+**GET**
+`https://genial-baas-operations.homolog.api.genial.systems/v1/cashin/receiver-reconciliation/{transactionId}`
+
+**Response**
+
+```json
+{
+  "instantPaymentId": "a4f3c2d1-5678-4bcd-8901-123456789abc",
+  "endToEndId": "E1234567820251031143000000001234",
+  "value": 1250.75,
+  "receiver": {
+    "taxId": "12345678909",
+    "addressKey": "gustavo.silva@empresa.com"
+  },
+  "payer": {
+    "taxId": "09876543210",
+    "name": "Maria Oliveira"
+  },
+  "eventStatus": {
+    "code": 200,
+    "description": "Liquidado com sucesso"
+  }
+}
+```
+
+---
+
+## 9. Criar QR Code Dinâmico (PAC002) – `postCreateDynamicQrcode`
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v2/qrcode/dynamic?agency=1&account={accountNumber}`
+
+**Body**
+
+```json
+{
+  "items": [
+    {
+      "addressingKey": {
+        "key": "gustavo.evp.1234567890",
+        "type": "EVP"
+      },
+      "accountHolderName": "Gustavo Silva",
+      "accountHolderCity": "São Paulo",
+      "dynamicQRCodeType": "IMMEDIATE",
+      "immediate": {
+        "expiration": 3600,
+        "paymentValue": {
+          "documentValue": 99.9,
+          "showPaymentValueInQrCode": true
+        },
+        "payerInformation": {
+          "cpfCnpj": "09876543210",
+          "name": "Maria Oliveira",
+          "validatePayerInformation": true
+        },
+        "receiverInformation": {
+          "taxId": "12345678909",
+          "name": "Gustavo Silva",
+          "tradeName": "GSoluções LTDA"
+        }
+      },
+      "payerRequestInformation": "Serviço prestado em 31/10/2025"
+    }
+  ]
+}
+```
+
+**Response**
+
+```json
+{
+  "data": {
+    "items": [
+      {
+        "itemId": "QR-ITEM-001",
+        "data": {
+          "textContent": "0002012658...",
+          "reference": "PIX202510311530",
+          "qrcodeURL": "https://gerador-arquitetura-baas.homolog.api.genial.systems/pix/qrcode/PIX202510311530.png"
+        },
+        "error": ""
+      }
+    ]
+  }
+}
+```
+
+---
+
+## 10. Devolução de Pagamento (PAC004) – `postPac004`
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/pix/return`
+
+**Body**
+
+```json
+{
+  "value": 50.0,
+  "returnReasonCode": "MD06",
+  "eventId": "E1234567820251031143000000009876",
+  "additionalInformation": "Cliente solicitou estorno",
+  "historicComplement": "Devolução parcial"
+}
+```
+
+**Response**
+
+```json
+{
+  "data": {
+    "returnId": "RET-PIX-0001",
+    "creationDateTime": "2025-10-31T15:40:00Z",
+    "originalInstantPaymentId": "PIX-OUT-XYZ123456",
+    "returnedAmount": 50.0
+  },
+  "error": ""
+}
+```
+
+---
+
+## 11. Preview de Pagamento (BOLETO) – `getPaymentPreview`
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/payments/preview`
+
+**Body**
+
+```json
+{
+  "emv": "34191750090001088600609301000001151670000016300"
+}
+```
+
+**Response**
+
+```json
+[
+  {
+    "amount": 163.0,
+    "type": "boleto-payment",
+    "due": "2025-11-05",
+    "taxId": "12345678909"
+  }
+]
+```
+
+---
+
+## 12. Pagamento de Boleto – `postPaymentsBoleto`
+
+**POST**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/payments/boleto`
+
+**Body**
+
+```json
+{
+  "taxId": "12345678909",
+  "description": "Pagamento de boleto",
+  "line": "34191750090001088600609301000001151670000016300",
+  "uuid": "BOLETO123"
+}
+```
+
+**Response**
+
+```json
+[
+  {
+    "status": "success",
+    "paymentId": "BOL-20251031-0001"
+  }
+]
+```
+
+---
+
+## 13. Consultar Pagamento de Boleto – `getPaymentsBoletoByid`
+
+**GET**
+`https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/payments/boleto/{id}`
+
+**Response**
+
+```json
+{
+  "id": "BOL-20251031-0001",
+  "amount": 163.0,
+  "status": "PAID",
+  "paidDate": "2025-10-31T17:10:00Z"
+}
+```
+
+---
+
+Deseja que eu agora gere essa mesma documentação em formato `.md` (pronto para salvar como `README.md`)?

+ 454 - 0
genial-cli

@@ -0,0 +1,454 @@
+#!/usr/bin/env -S /usr/bin/node --no-deprecation
+
+require("dotenv").config({ quiet: true });
+const decimal = require("decimal.js");
+const randomUUID = require("crypto").randomUUID;
+const DEBUG = true;
+
+const AUTH_URL =
+  "https://genial-arquitetura-authentication.homolog.api.genial.systems";
+const COREBK_URL =
+  "https://genial-arquitetura-corebank.homolog.api.genial.systems";
+const BAAS_URL = "https://gerador-arquitetura-baas.homolog.api.genial.systems";
+const OPS_URL = "https://genial-baas-operations.homolog.api.genial.systems";
+
+async function main() {
+  const args = process.argv.slice(2);
+  if (args.length === 0) return help();
+  const cmd = args[0];
+  const rest = args.slice(1);
+
+  try {
+    switch (cmd) {
+      case "token": {
+        const [ok, tok] = await getToken();
+        if (!ok) return fail(tok);
+        console.log(tok);
+        break;
+      }
+      case "balance": {
+        await Balance(rest[0]);
+        break;
+      }
+      case "getkey": {
+        if (rest.length < 1) return fail("Usage: getkey <pixKey>");
+        await getKey(rest[0]);
+        break;
+      }
+      case "decodeQrcode": {
+        if (rest.length < 1) return fail("Usage: decodeQrcode <qrcode>");
+        await decodeQrcode(rest[0]);
+        break;
+      }
+      case "payQr": {
+        if (rest.length < 2)
+          return fail("Usage: payQr <qrCodeCopyPaste>  <value>");
+        console.log(rest[0], rest[1]);
+        await PayQr(rest[0], rest[1]);
+        break;
+      }
+      case "qrcodeStatic": {
+        await qrcodeStatic();
+        break;
+      }
+      case "paykey": {
+        if (rest.length < 1) return fail("Usage: payInit <pixKey> <value>");
+        await PayInit(rest[0], rest[1]);
+        break;
+      }
+      // done up
+      case "qrcodedynamic": {
+        // if (rest.length <2) return fail("Usage: qrcode  <value>");
+        await QrCodeDynamic(rest[1]);
+        break;
+      }
+      case "statusIn": {
+        if (rest.length < 1) return fail("Usage: statusIn <transactionId>");
+        await StatusIn(rest[0]);
+        break;
+      }
+      case "statusOut": {
+        if (rest.length < 1) return fail("Usage: statusOut <e2e>");
+        await StatusOut(rest[0]);
+        break;
+      }
+      // case "paykey": {
+      //   if (rest.length < 1) return fail("Usage: pay <idempotencyId>");
+      //   await paykey(rest[0]);
+      //   break;
+      // } just use it for test
+      case "refund": {
+        if (rest.length < 1) return fail("Usage: refund <eventId> <value>");
+        await Refund(rest[0], rest[1]);
+        break;
+      }
+      case "preview": {
+        if (rest.length < 1) return fail("Usage: preview <emv>");
+        await Preview(rest[0]);
+        break;
+      }
+      case "boletoPay": {
+        if (rest.length < 2)
+          return fail("Usage: boletoPay <taxId> <line> [description] [uuid]");
+        await BoletoPay(rest[0], rest[1], rest[2], rest[3]);
+        break;
+      }
+      case "boletoGet": {
+        if (rest.length < 1) return fail("Usage: boletoGet <id>");
+        await BoletoGet(rest[0]);
+        break;
+      }
+      default:
+        help();
+        return;
+    }
+  } catch (e) {
+    fail(e.message || e);
+    help();
+    return;
+  }
+}
+
+function help() {
+  console.log(`Usage: genial-cli <command> [args]
+Commands:
+  token
+  balance <accountNumber>
+  getkey <accountNumber> <pixKey>
+  statusOut <instantPaymentId> <YYYY-MM-DD>
+  statusIn <transactionId>
+  qrcode <accountNumber> <value>
+  payInit [value] [pixKey]
+  pay <idempotencyId>
+  payQr <accountNumber> <value> <qrCodeCopyPaste>
+  refund <eventId> <value>
+  preview <emv>
+  boletoPay <taxId> <line> [description] [uuid]
+  boletoGet <id>
+`);
+  process.exit(1);
+}
+
+function fail(msg) {
+  console.error("Error:", msg);
+  process.exit(1);
+}
+
+/* =============== Auth =============== */
+
+async function getToken() {
+  const url = `${AUTH_URL}/v1/authentication`;
+  const options = {
+    method: "POST",
+    headers: {
+      basic: process.env.TOKEN_BASIC,
+      "X-ORIGEM": process.env.TOKEN_XORIGEM,
+    },
+  };
+  try {
+    const res = await fetch(url, options);
+    const text = await res.text();
+    if (DEBUG) {
+      console.log("DEBUG getToken status:", res.status);
+      console.log("DEBUG getToken body:", text);
+    }
+    if (res.status < 200 || res.status >= 300)
+      return [false, { status: res.status, body: text }];
+    const json = JSON.parse(text);
+    if (!json.token) return [false, "No token in response"];
+    return [true, json.token];
+  } catch (e) {
+    return [false, e.message];
+  }
+}
+
+async function callApi(method, url, body) {
+  const [ok, token] = await getToken();
+  if (!ok) return [false, token];
+  const headers = {
+    Authorization: token,
+    "X-ORIGEM": process.env.TOKEN_XORIGEM,
+  };
+  const options = { method, headers };
+
+  if (method.toUpperCase() === "POST") {
+    headers["Content-Type"] = "application/json";
+    options.body = body ? JSON.stringify(body) : "";
+  }
+
+  if (DEBUG) {
+    console.log("\nDEBUG callApi:", method, url);
+    if (body) console.log("DEBUG body:", JSON.stringify(body));
+  }
+
+  try {
+    const res = await fetch(url, options);
+    const text = await res.text();
+    if (DEBUG) {
+      console.log("DEBUG status:", res.status);
+      console.log("DEBUG raw:", text);
+    }
+    if (res.status < 200 || res.status >= 300)
+      return [false, { status: res.status, body: text }];
+    try {
+      return [true, JSON.parse(text)];
+    } catch {
+      return [true, text];
+    }
+  } catch (e) {
+    return [false, e.message];
+  }
+}
+/**
+ * @description
+ * account 2 is me the user
+ * account 1 is smartpay the receiver of the payment
+ */
+/* =============== 1) Balance =============== done*/
+
+async function Balance(accountNumber) {
+  //INFO: they share 2 acount to test, but idk if on prod only is gonna be one. ignore this, after i know the answer i will delete
+  let account = process.env.ACCOUNT1;
+  const url = `${COREBK_URL}/v1/core-banking/balance/1/${account}`;
+  const [ok, out] = await callApi("GET", url);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 2) Dict Key =============== done*/
+
+async function getKey(pixKey) {
+  const url = `${BAAS_URL}/v2/pix/key-account-partner/1/${process.env.ACCOUNT1}/${pixKey}`;
+  const [ok, out] = await callApi("GET", url);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== DECODE QRCODE =============== done*/
+async function decodeQrcode(qrcode) {
+  const url = `https://gerador-arquitetura-baas.homolog.api.genial.systems/v1/pix/qrcode-decode?qrcode=${encodeURIComponent(
+    qrcode
+  )}`;
+  const [ok, out] = await callApi("GET", url);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 8) Pay by QR =============== done*/
+
+async function PayQr(qrCodeCopyPaste, value) {
+  const url = `${BAAS_URL}/v1/pix/copy-paste`;
+  /**
+   * debit is our account that is going to pay the qr code, need prod keys to do it correctly
+   */
+  const body = {
+    qrCodeCopyPaste,
+    value: Number(value),
+    debit: {
+      name: process.env.ACCOUNT2_NAME,
+      agency: 1,
+      account: process.env.ACCOUNT2,
+      accountType: "CACC",
+    },
+  };
+  console.log(body);
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 2) QR Code Static =============== done*/
+async function qrcodeStatic() {
+  const url = `${BAAS_URL}/v1/pix/qrcode-static/`;
+  const body = {
+    accountHolderName: process.env.ACCOUNT1_NAME,
+    addressingKey: {
+      key: process.env.ACCOUNT1_KEY,
+      type: "EVP",
+    },
+    account: process.env.ACCOUNT1,
+    agency: 1,
+    // additionalInformation: "Pagamento de teste genial-cli" /**@optional */,
+    // value: 10.0, /**@optional */
+  };
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 3) Status OUT (PAC008) =============== NEED TO CHECK*/
+async function StatusOut(e2e) {
+  const url = `${OPS_URL}/v1/cashout/${encodeURIComponent(e2e)}`;
+  const [ok, out] = await callApi("GET", url);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 4) Status IN (PAC002) =============== NEED TO CHECK*/
+
+async function StatusIn(transactionId) {
+  const url = `${OPS_URL}/v1/cashin/end-to-end-id/${encodeURIComponent(
+    transactionId
+  )}`;
+  const [ok, out] = await callApi("GET", url);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 6) Init Pix by Key (PAC008 Start) ===============  done */
+/**
+ *
+ * @param pixKey
+ * @param value
+ * @returns confirmed idempotencyId [@description we need to create the idempotencyId on our side to confirm the payment later  ]
+ */
+async function PayInit(pixKey, value) {
+  const url = `${BAAS_URL}/v1/pix/send/initialization`;
+  const body = {
+    debit: {
+      name: process.env.ACCOUNT2_NAME,
+      agency: 1,
+      account: process.env.ACCOUNT2,
+      accountType: "CACC",
+    },
+    credit: {
+      key: pixKey,
+    },
+    value: String(value),
+    idempotencyId: randomUUID(),
+  };
+  var [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+  if (out?.data?.idempotencyId) {
+    console.log("idempotencyId:", out.data.idempotencyId);
+  }
+  var [ok, reply] = await paykey(out.data.idempotencyId);
+  if (!ok) return fail(reply);
+  console.dir(reply, { depth: null });
+}
+
+/* =============== 7) Pay by Idempotency (PAC008) =============== done */
+/**
+ *
+ * @param idempotencyId
+ * @param payinfo
+ * @returns
+ */
+async function paykey(idempotencyId, payinfo) {
+  const url = `${BAAS_URL}/v1/pix/send/confirmed`;
+  const body = {
+    idempotencyId: idempotencyId,
+    ignorePaymentDuplication: false,
+    // additionalInformation: payinfo, /**@optional */
+  };
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  if (DEBUG) console.log("Payment confirmed for idempotencyId:", idempotencyId);
+  return [true, out];
+}
+
+/* =============== 9) Refund (PAC004) =============== worked*/
+
+async function Refund(eventId, value) {
+  const url = `${BAAS_URL}/v1/pix/return`;
+  const body = {
+    value: 0.01,
+    returnReasonCode: "MD06",
+    eventId: eventId,
+  };
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+async function QrCodeDynamic() {
+  const url = `${BAAS_URL}/v2/qrcode/dynamic?agency=1&account=${process.env.ACCOUNT1}`;
+  const body = {
+    items: [
+      {
+        addressingKey: {
+          key: process.env.ACCOUNT1_KEY,
+          type: "EVP",
+        },
+        accountHolderName: process.env.ACCOUNT1_NAME,
+        accountHolderCity: "SAO PAULO",
+        dynamicQRCodeType: "IMMEDIATE",
+        immediate: {
+          expiration: 36000,
+          paymentValue: {
+            documentValue: 10,
+            showPaymentValueInQrCode: true,
+            //"cashback": {
+            //"cashbackType": "WITHDRAW",
+            //"value": 0,
+            //"allowValueChange": true,
+            //"withdrawProviders": {
+            //"agentModality": "string",
+            //"serviceProvider": "string"
+            //}
+            //}
+          },
+          payerInformation: {
+            cpfCnpj: "37812511871",
+            name: "gustavo lopes",
+            validatePayerInformation: true,
+          },
+          receiverInformation: {
+            taxId: process.env.DOCUMENT_NUMBER,
+            name: process.env.ACCOUNT1_NAME,
+            tradeName: process.env.ACCOUNT1_NAME,
+          },
+        },
+        payerRequestInformation: "TESTE SOLICITAÇÃO AO PAYER",
+        //"additionalInformation": [
+        //{
+        //"name": "string",
+        //"content": "string",
+        //"showToPayer": true
+        //}
+        //],
+        //"itemId": "string",
+        //"receiverTxId": "CTXXXXXXXXXXXX999999995800"
+      },
+    ],
+  };
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+/* =============== 10) Preview Pagamento (BOLETO) =============== did not test*/
+
+async function Preview(emv) {
+  const url = `${BAAS_URL}/v1/payments/preview`;
+  const body = { emv };
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 11) Boleto Pay =============== did not test*/
+
+async function BoletoPay(taxId, line, description, uuid) {
+  const url = `${BAAS_URL}/v1/payments/boleto`;
+  const body = {
+    taxId,
+    description: description || "Pagamento de boleto",
+    line,
+    uuid: uuid || `BOL-${Date.now()}`,
+  };
+  const [ok, out] = await callApi("POST", url, body);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+/* =============== 12) Boleto Get by Id =============== did not test*/
+
+async function BoletoGet(id) {
+  const url = `${BAAS_URL}/v1/payments/boleto/${encodeURIComponent(id)}`;
+  const [ok, out] = await callApi("GET", url);
+  if (!ok) return fail(out);
+  console.dir(out, { depth: null });
+}
+
+main();

+ 0 - 0
hookcashin.json


+ 0 - 0
hookcashout.json


+ 17 - 0
package.json

@@ -0,0 +1,17 @@
+{
+  "name": "genial_poc",
+  "version": "1.0.0",
+  "main": "genial-cli.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "description": "",
+  "dependencies": {
+    "crypto": "^1.0.1",
+    "decimal.js": "^10.6.0",
+    "dotenv": "^17.2.3"
+  }
+}