Download the PHP package stackin-io/stackin-php-sdk without Composer

On this page you can find all versions of the php package stackin-io/stackin-php-sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package stackin-php-sdk

**Integrate once. Issue everywhere.** [![PHP](https://img.shields.io/badge/php-%3E%3D8.1-777bb4?style=flat-square)](composer.json) [![Packagist](https://img.shields.io/packagist/v/stackin-io/stackin-php-sdk?style=flat-square)](https://packagist.org/packages/stackin-io/stackin-php-sdk) [![License](https://img.shields.io/badge/license-MIT-informational?style=flat-square)](https://github.com/stackin-io/stackin-php-sdk) [API Reference](https://docs.stackin.io) · [PHP SDK guide](https://docs.stackin.io/blog/php-sdk)

stackin

Official PHP SDK for fiscal document issuance — a handful of business fields, nothing about certificates, XML, XSD, signing or SOAP. The API resolves all of that from the issuer's own configuration, identified by api_key.

One class, Invoice — issue()/consult()/cancel()/reissue()/correct()/invalidate()/pdf()/received()/manifest(), nothing else to instantiate. Each line item is a Br\Product — description/amount apply to any document type; ncm/cfop (plus everything else on Product: cest, tax groups, presumed credits...) are Brazil-specific and required per item for NFE, ignored for NFSE.

What a line item is worth

unitPrice is the price of one unit. amount is the gross total of the line's products, before discount, freight, insurance and other expenses. Send either; sending both asserts that they agree.

Amounts that do not add up are refused before the authorizer sees them, with a 422 naming the line and both numbers (ITEM_TOTAL_MISMATCH).

Migrating

Nothing has to migrate. amount keeps the meaning it always had and is not deprecated in this release.

Install

Usage

Get an api_key from the stackin dashboard — select the issuing company, then Settings → API key (context sdk). One key per issuing company, shown once at creation. The API resolves the issuer (CNPJ, state, address, certificate, environment) entirely from it; nothing about the issuer is ever passed on a call. Defaults to https://sdk.stackin.io.

The recipient Address passed to issue() is the buyer's address — required for NFE and ignored for NFSE. Every field is required, cityCode (the 7-digit IBGE municipality code) included: it becomes enderDest on the wire and the SEFAZ rejects a partial one. state is also what resolves idDest — a buyer in another state is emitted as an interstate operation automatically. A missing or incomplete address throws an InvoiceError locally, before the request goes out.

Retrying safely

Issuing is the one call you must not repeat blindly. If the response is lost — a timeout, a dropped connection — the document may well have been authorized, and a second attempt issues a second fiscal document: another credit, another number burned, and undoing it means cancelling, which has a deadline.

Pass an idempotency key to make the retry safe:

Retry with the same key and the same body and you get the first response back, replayed — no second document, no credit consumed. Reissue takes the same argument.

Situation What the API does
New key issues normally, records the response
Same key, same body replays the recorded response
Same key, different body API error 422
Same key, first call still running API error 409
Previous attempt failed key is released — the retry issues
Key older than 24 hours treated as new

Generate the key yourself and keep it for as long as you might retry — one UUID per business event, not per HTTP call. The SDK never generates one, because a key minted per call would protect nothing, and because two genuinely separate invoices for the same customer and amount on the same day are a normal thing to issue.

Correcting a document

Some mistakes don't need a cancellation. A wrong product name, wrong transport details, a typo in the extra information — a CC-e (carta de correção) fixes those, and it is free: no new credit, no burned series number, no reissue.

The correction text is 15 to 1000 characters, checked locally before the call.

What a CC-e cannot fix: anything that changes the tax owed (base, rate, price, quantity, totals), the buyer or the seller, or the issue date. Those still mean cancelling and reissuing. The API sends the legally fixed wording that says exactly this, attached to every correction.

The original document does not change — the CC-e is an event attached to it, and the authorized XML stays as it was. A document accepts at most 20 of them, and they are numbered for you.

NF-e only. NFS-e has no correction letter, and asking for one returns a 409.

Invalidating unused numbers

NF-e numbering is sequential and the SEFAZ expects it to have no gaps. A number gets reserved the moment issuing starts, so a submission that fails afterwards — a rejection, a timeout — leaves a hole in the series. Reporting that range is how you close it.

The reason is 15 to 255 characters and the range is inclusive; both are checked locally, as is number_end not being below number_start.

A number that already reached the authorizer can't be invalidated. The API checks its own records first and answers 409 naming the offending numbers, without a round trip — and the authorizer checks again for what we can't see from here.

NF-e only, and it takes no access key: there is no document to point at.

Documents issued against you

Everything above serves the issuer. These two serve the recipient: what suppliers billed to this CNPJ, and the formal answer to it.

Reading the list never calls the SEFAZ. The authorizer caps how many times a CNPJ may ask for its distribution per day, so collecting runs on a schedule on the API side and a page refresh cannot spend that allowance.

Before you answer a document the SEFAZ sends only a summary (resNFe): access key, issuer, amount, date. The full document (nfeProc) arrives after a manifestation, and the schema field on each row says which one you hold.

The four answers are 210200 Confirmação da Operação, 210210 Ciência da Operação, 210220 Desconhecimento da Operação and 210240 Operação não Realizada. Only the last one takes a reason, and it requires one — both rules are checked locally, before the request goes out, because a round trip to be told a fixed rule is a round trip wasted.

Looking up a code, or who a CNPJ belongs to

Two more clients, for the tables an issuer reads while filling a document. Neither writes anything.

cfop, ncm, cest, cst, csosn, issService, icmsFuel and ibsCbsClass have accessors. kind($name) reaches anything else, including a classification published after this release — ask kinds() rather than trusting this list.

metadata comes back as the API sends it and differs per kind: utrib on an NCM, ncm_code on a CEST, tax_type on a CST, null on an ISS service.

Three things worth knowing before you loop:

Taxpayer has one method and keeps one: the registry holds the names and addresses of real people, so there is no search over it, by design.

Errors

Building the full fiscal document (issuer data, service code, tax groups, schema-accurate XML) is the API's job — configured once per company, not passed on every call.

Examples

Runnable end-to-end scripts in examples/nfse/ — one script per field variant, from the bare minimum to every field filled. examples/consult_invoice.php, examples/cancel_invoice.php, and examples/reissue_invoice.php cover the operations that act on an already-issued document. examples/lookup_fiscal_reference.php and examples/lookup_taxpayer.php cover the two read-only clients.

Commit convention lives in CONTRIBUTING.md, not here.


All versions of stackin-php-sdk with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
guzzlehttp/guzzle Version ^7.8
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package stackin-io/stackin-php-sdk contains the following files

Loading the files please wait ...