npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xulis/payment-sdk

v0.1.4

Published

SDK TypeScript para comunicação com maquininhas Android POS via WebView Xulis

Downloads

756

Readme

@xulis/payment-sdk

SDK oficial em TypeScript para comunicação com maquininhas Android POS por WebView Xulis.

Toda a comunicação com a maquininha fica encapsulada no SDK.

Instalação

npm install @xulis/payment-sdk

Uso básico

import { XulisPayment } from '@xulis/payment-sdk';

const payment = new XulisPayment({
  clientId: 'seu-client-id',
  clientSecret: 'seu-secret-id',
});

await payment.initialize();

Crédito

const result = await payment.credit({
  amount: 150.5,
  installments: 1,
  referenceId: 'pedido-123',
  items: [{ name: 'Produto', quantity: 1, unitPrice: 150.5 }],
});

Crédito parcelado

const result = await payment.credit({
  amount: 150.5,
  installments: 3,
  installmentType: 'merchant',
});

Débito

const result = await payment.debit({
  amount: 100,
});

PIX

const result = await payment.pix({
  amount: 250,
});

Voucher

const result = await payment.voucher({
  amount: 80,
});

Eventos

payment.on('started', (event) => {
  console.log('Pagamento iniciado', event);
});

payment.on('approved', (response) => {
  console.log('Pagamento aprovado', response.transactionId);
});

payment.on('declined', (response) => {
  console.log('Pagamento recusado', response);
});

payment.on('cancelled', (response) => {
  console.log('Operação cancelada', response);
});

payment.on('error', (error) => {
  console.error('Erro na operação', error);
});

payment.on('completed', (response) => {
  console.log('Operação finalizada', response);
});

Cancelamento

O cancelamento Cielo precisa dos dados retornados no pagamento: ID da ordem, codigo de autorizacao, NSU/Cielo Code e valor. A maquininha executa o cancelamento na Cielo e registra o retorno em POST /transactions com status CANCELLED.

const result = await payment.cancel({
  transactionId: 'order-id-cielo',
  amount: 150.5,
  method: 'credit',
  nsu: '799871',
  authorizationCode: '140126',
});

Impressão

A impressão é local na maquininha e não envia dados para a API.

await payment.printText({
  text: 'XULIS SDK\nVenda demo\nObrigado!\n',
  styles: [{ key_attributes_align: 0, key_attributes_textsize: 22 }],
});

Para imagem, envie imageDataUrl, imageBase64 ou um imagePath já existente no dispositivo. Quando receber base64/data URL, o app salva a imagem localmente antes de chamar a Cielo.

await payment.printImage({
  imageDataUrl: 'data:image/jpeg;base64,...',
  styles: [{ key_attributes_align: 0, form_feed: 1 }],
});

Consulta

const result = await payment.status({
  transactionId: 'transaction-id',
});

Reimpressão

const result = await payment.reprint({
  transactionId: 'transaction-id',
});

Terminal

const terminal = await payment.getTerminal();
console.log(terminal.serialNumber);

DadosPOS

DadosPOS não recebe parâmetros e não exige clientId/clientSecret. A função conversa com o app Xpay dentro da WebView e retorna os dados disponíveis da maquininha e da empresa configurada no painel.

const payment = new XulisPayment({});
const dadosPOS = await payment.DadosPOS();

console.log(dadosPOS.cnpj);
console.log(dadosPOS.sdkAuthToken);
console.log(dadosPOS.acquirer);
console.log(dadosPOS.webSdkLink);

Exemplo de resposta:

{
  "serialNumber": "POS123456",
  "model": "Android POS",
  "manufacturer": "Android POS",
  "merchantId": "uuid-da-empresa",
  "merchantName": "Posto Exemplo",
  "companyUuid": "uuid-da-empresa",
  "companyName": "Posto Exemplo",
  "legalName": "Empresa Exemplo Ltda",
  "tradeName": "Posto Exemplo",
  "cnpj": "12.345.678/0001-90",
  "document": "12.345.678/0001-90",
  "sdkAuthToken": "token-configurado-no-painel",
  "acquirer": "ADIQ",
  "integrationType": "WEB_SDK",
  "webSdkLink": "https://seu-site.com/pagamento",
  "appName": "Xpay",
  "appVersion": "0.0.1",
  "nativeApplicationVersion": "1.0.0",
  "nativeBuildVersion": "1",
  "packageName": "com.xposto",
  "softwareVersion": "1.0.0",
  "sdkVersion": "0.1.0",
  "isOnline": true
}

Também existe o alias camelCase:

const dadosPOS = await payment.dadosPOS();

JavaScript puro

Com bundler:

import { XulisPayment } from '@xulis/payment-sdk';

const payment = new XulisPayment({
  clientId: 'seu-client-id',
  clientSecret: 'seu-secret-id',
});

payment.pix({ amount: 25 }).then(console.log).catch(console.error);

HTML puro via CDN

Para páginas sem bundler, use a build global do navegador. Ela expõe o SDK em window.XulisPaymentSDK.

Via unpkg:

<!doctype html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8" />
    <title>Pagamento POS</title>
  </head>
  <body>
    <button id="pay">Pagar PIX</button>

    <script src="https://unpkg.com/@xulis/[email protected]/dist/xulis-payment-sdk.global.js"></script>
    <script>
      const { XulisPayment } = window.XulisPaymentSDK;

      const payment = new XulisPayment({
        clientId: 'seu-client-id',
        clientSecret: 'seu-secret-id',
      });

      payment.on('approved', function (response) {
        console.log('Aprovado', response.transactionId);
      });

      payment.on('error', function (error) {
        console.error('Erro', error.message);
      });

      document.getElementById('pay').addEventListener('click', async function () {
        const dadosPOS = await payment.DadosPOS();
        console.log('Dados POS', dadosPOS);

        const result = await payment.pix({ amount: 25 });
        console.log(result);
      });
    </script>
  </body>
</html>

Via jsDelivr:

<script src="https://cdn.jsdelivr.net/npm/@xulis/[email protected]/dist/xulis-payment-sdk.global.js"></script>

React / Next.js

Use o SDK apenas no client-side, pois a Bridge depende de window.

'use client';

import { useMemo } from 'react';
import { XulisPayment } from '@xulis/payment-sdk';

export function PayButton() {
  const payment = useMemo(
    () =>
      new XulisPayment({
        clientId: 'seu-client-id',
        clientSecret: 'seu-secret-id',
      }),
    [],
  );

  return (
    <button
      onClick={async () => {
        const result = await payment.credit({ amount: 100 });
        console.log(result);
      }}
    >
      Pagar
    </button>
  );
}

Timeout e logs

const payment = new XulisPayment({
  clientId: 'seu-client-id',
  clientSecret: 'seu-secret-id',
  timeout: 90000,
  debug: true,
});

WebView da maquininha

Dentro da maquininha, a tela WebSdk do app xposto escuta as mensagens enviadas por este SDK. O fluxo real fica assim:

  1. A pagina Web SDK instancia XulisPayment com clientId e clientSecret gerados em /api-keys.
  2. O SDK envia o comando para window.ReactNativeWebView.postMessage.
  3. A tela nativa valida as credenciais em POST /auth/tokens.
  4. A maquininha executa a adquirente configurada. Por enquanto, o fluxo implementado e Cielo.
  5. Ao aprovar, negar, falhar ou cancelar, a maquininha registra a transacao em POST /transactions com acquirer: "CIELO" e devolve a resposta ao site.
  6. Impressões de texto/imagem ficam somente na maquininha. Para PRINT_IMAGE, a imagem é salva localmente e o caminho do arquivo é enviado ao deeplink Cielo.

Exemplo local completo: examples/simple/index.html. Primeiro rode npm run build dentro de sdk-payment para gerar dist/xulis-payment-sdk.global.js, depois hospede a pasta examples/simple em uma URL configurada como Link Web SDK da empresa.

Live Demo

Demo publicado:

Para testar na maquininha, configure o Link Web SDK da empresa com a URL acima.

Emulador Cielo

Para testar integração Cielo fora da maquininha física, baixe e instale o emulador LIO:

No momento, o fluxo nativo implementado no app da maquininha para Web SDK está disponível para adquirente Cielo.

Retorno padronizado

Todas as operações retornam um objeto no formato:

{
  success: true,
  status: 'APPROVED',
  transactionId: '',
  authorizationCode: '',
  nsu: '',
  rrn: '',
  amount: 150,
  brand: 'Visa',
  installments: 3,
  cardHolder: '',
  cardLast4: '1234',
  receiptCustomer: '',
  receiptMerchant: '',
  date: '',
  time: '',
  raw: {}
}

Build

npm run build

Publicação

npm publish --access public