raylongsolutions / gst-gateway
Generate GST e-invoices (IRN) and e-way bills from PHP with GST Gateway by Raylong Solutions.
Package info
git.raylongsolutions.com/raylongsolutions/gst-gateway-php.git
pkg:composer/raylongsolutions/gst-gateway
Requires
- php: >=7.4
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^9.6 || ^10.5 || ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Generate GST e-invoices (IRN) and e-way bills from your PHP software with GST Gateway by Raylong Solutions.
- One function per call, for every e-invoice and e-way bill call
- Errors from GST Gateway and from the government system come out as one exception type
- Lookups retry by themselves when the service is busy; calls that create documents are never resent
- PHP 7.4 or newer with the curl extension. No other dependencies, so it works in Laravel, CodeIgniter, Symfony or plain PHP
composer require raylongsolutions/gst-gateway
Before you start
- Create a GST Gateway account and copy an API key from API keys and GSTINs in your portal.
- A
gstg_test_...key uses the government sandbox and is free. - A
gstg_live_...key makes real e-invoices and e-way bills and uses credits.
- A
- For live calls, add your GSTIN and save its GST portal API username and password on the same page. GST Gateway then logs in to the GST portal for you.
Keep the API key on your server, for example in .env. Never put it in a web page or a mobile app.
Quick start
<?php
require 'vendor/autoload.php';
use Raylong\GstGateway\GstGateway;
use Raylong\GstGateway\GstGatewayError;
$gst = new GstGateway(getenv('GST_GATEWAY_KEY'));
$gstin = '33ABCDE1234F1Z5'; // your GSTIN
try {
$einv = $gst->einvoice->generate($gstin, $invoice);
echo $einv['Irn'], ' ', $einv['AckNo'], PHP_EOL;
$ewb = $gst->ewayBill->generate($gstin, $bill);
echo $ewb['ewayBillNo'], ' valid till ', $ewb['validUpto'], PHP_EOL;
} catch (GstGatewayError $e) {
echo $e->getErrorCode(), ': ', $e->getMessage(), PHP_EOL;
print_r($e->getDetails());
}
$invoice and $bill are plain PHP arrays with the government's own field names (e-invoice schema INV-01 v1.1 and the e-way bill schema), so the government documentation applies as is. Results come back as arrays. Full request examples are in the developer guide.
In Laravel, keep the key in .env and create the client with new GstGateway(env('GST_GATEWAY_KEY')), or bind it once in a service provider.
All functions
Every function takes your GSTIN first. Dates are dd/mm/yyyy.
E-invoice
| Function | What it does |
|---|---|
$gst->einvoice->generate($gstin, $invoice) | Generate an IRN |
$gst->einvoice->cancel($gstin, ['Irn' => ..., 'CnlRsn' => '1', 'CnlRem' => ...]) | Cancel an IRN (within 24 hours) |
$gst->einvoice->get($gstin, $irn) | Look up by IRN |
$gst->einvoice->getByDocument($gstin, $docType, $docNum, $docDate) | Look up by invoice number and date |
$gst->einvoice->gstinDetails($gstin, $otherGstin) | Details of any GSTIN |
$gst->einvoice->generateEwayBill($gstin, ['Irn' => ..., 'Distance' => ...]) | E-way bill for an IRN |
E-way bill
| Function | What it does |
|---|---|
$gst->ewayBill->generate($gstin, $bill) | Generate an e-way bill |
$gst->ewayBill->updateVehicle($gstin, $request) | Update vehicle (Part B) |
$gst->ewayBill->extendValidity($gstin, $request) | Extend validity |
$gst->ewayBill->cancel($gstin, ['ewbNo' => ..., 'cancelRsnCode' => 2, 'cancelRmrk' => ...]) | Cancel |
$gst->ewayBill->reject($gstin, $ewbNo) | Reject one generated against you |
$gst->ewayBill->generateConsolidated($gstin, $request) | Consolidated e-way bill |
$gst->ewayBill->regenerateTripSheet($gstin, $request) | Regenerate a trip sheet |
$gst->ewayBill->initiateMultiVehicle / addMultiVehicle / changeMultiVehicle | Move goods in several vehicles |
$gst->ewayBill->get($gstin, $ewbNo) | Full details |
$gst->ewayBill->getByDocument($gstin, $docType, $docNo) | Find one you generated |
$gst->ewayBill->getTripSheet($gstin, $tripSheetNo) | Trip sheet details |
$gst->ewayBill->listOtherParty($gstin, $date) | Generated against you by others |
$gst->ewayBill->listForTransporter($gstin, $date) | Assigned to you as transporter |
$gst->ewayBill->listForTransporterByGstin($gstin, $generatorGstin, $date) | Same, for one generator |
Masters and printing
| Function | What it does |
|---|---|
$gst->masters->errorList($gstin) | Government error codes |
$gst->masters->hsn($gstin, $hsnCode) | HSN details |
$gst->masters->transporter($gstin, $transporterId) | Transporter details |
$gst->print->ewayBill($gstin, $details) | E-way bill PDF (pass the result of ewayBill->get) |
$gst->print->ewayBillDetailed($gstin, $details) | Detailed e-way bill PDF |
$gst->print->upiQr($gstin, ['upiId' => ..., 'payeeName' => ..., 'bankAc' => ..., 'ifsc' => ..., 'invNo' => ..., 'invDt' => ..., 'invAmt' => ...]) | UPI payment QR for a B2C invoice |
Print functions return a GstFile with contentType and bytes:
$details = $gst->ewayBill->get($gstin, 331001234567);
$pdf = $gst->print->ewayBill($gstin, $details);
$pdf->save('ewaybill.pdf');
$gst->raw($method, $path, ['query' => [...], 'body' => [...]]) sends any other call from the developer guide with the same key and error handling.
Each function also takes an optional last argument of options: authToken and username (only when the GSTIN's GST portal login is not saved in your portal) and timeoutMs.
Errors
Every failure throws a GstGatewayError:
| Method | Meaning |
|---|---|
getErrorCode() | GTW001 to GTW009 from GST Gateway, a government error code (for example 2150, duplicate IRN), or timeout / network. getCode() returns the same string |
getMessage() | The first reason, in plain words |
getDetails() | Every reason given, as ['code' => ..., 'message' => ...] |
getHttpStatus() | HTTP status, or 0 when no answer came back |
getResponse() | The answer as received, for your logs |
GST Gateway codes:
| Code | Meaning |
|---|---|
| GTW001 | Invalid or revoked API key |
| GTW002 | Too many calls per minute (lookups wait and retry by themselves) |
| GTW003 | Unknown address |
| GTW004 | GSTIN not added to your account |
| GTW005 | Not enough credits: buy more in your portal |
| GTW006 | Account blocked |
| GTW007 | The government service is unavailable |
| GTW008 | This call is not enabled |
| GTW009 | GST portal login missing or refused for this GSTIN |
A malformed API key or an empty GSTIN throws InvalidArgumentException before any call is made.
Retries and timeouts
Lookups and prints retry up to 2 times when the service is down or busy. Calls that generate, cancel or change a document are never resent, so a retry can never create a duplicate. If such a call ends with error code timeout or network, the document may or may not have been made: look it up with $gst->einvoice->getByDocument() or $gst->ewayBill->getByDocument() before trying again.
$gst = new GstGateway(getenv('GST_GATEWAY_KEY'), [
'timeoutMs' => 60000, // default 60 seconds
'maxRetries' => 2, // for lookups; 0 turns retries off
]);
Help
Security: see SECURITY.md
Developer guide: https://gst.raylongsolutions.com/docs
- Email: support@raylongsolutions.com
- Phone: +91 70106 37648 (Mon to Sat, 10 AM to 7 PM IST)
MIT licence. © Raylong Solutions.