mugwanezamanzi / rra-ebm
PHP SDK for Rwanda Revenue Authority (RRA) EBM 2.1 & OSDC API integration
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.11
- ramsey/uuid: ^4.9
Requires (Dev)
- phpunit/phpunit: ^10
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-19 12:39:42 UTC
README
A lightweight, database-agnostic PHP package to integrate private CIS (Client Invoice System) and pharmacy inventory systems with the Rwanda Revenue Authority (RRA) EBM 2.1 and Online Sales Data Controller (OSDC) API.
Features
- Authentication & Device Init: Initialize OSDC devices and acquire communication keys (
cmcKey). - Basic Data Retrieval: Query standard code lookups, item classifications, notices, and verify customer TIN status.
- Branch Management: Sync branch lists, user accounts, customer records, and branch insurance profiles (Pharmacy-specific).
- Item Management: Register products with EBM and query item catalogs.
- Import Declarations: Search and confirm imported items.
- Purchase Management: Fetch and verify purchase transactions from suppliers.
- Stock & Inventory: Synchronize stock levels, stock movement (transfers), and stock IN/OUT transactions.
- Lookup Codes: Predefined constants for all official RRA EBM code mappings.
Installation
Install the package via Composer:
composer require mugwanezamanzi/rra-ebm-php
Obtaining RRA Credentials & Device Serial Number
To run this package in production, each pharmacy tenant must obtain their official credentials from the Rwanda Revenue Authority (RRA):
- Taxpayer TIN: The 9-digit Taxpayer Identification Number of the pharmacy.
- Branch ID (
bhfId): The 2-digit code representing the pharmacy branch location (00for the head office/main pharmacy,01or higher for branches). - Device Serial Number (
dvcSrlNo): A unique software/virtual device serial number registered with RRA.
Step-by-Step Registration Guide:
- Log in to the official MyRRA Portal (myrra.rra.gov.rw) using the pharmacy's taxpayer credentials.
- Navigate to Service Request > EBM / OSDC Service Request.
- Select Virtual OSDC (Software OSDC) as the integration type.
- Input the system details (CIS) of your pharmacy management application and submit the application.
- Upon RRA approval, the portal will generate and display a unique Device Serial Number (usually starting with a prefix like
SDC...). - Copy this serial number and enter it into your pharmacy application settings to run the client device registration and retrieve the communication key (
cmcKey).
Quick Start
1. Initialize Client
use RRA\EBM\Client; $client = new Client( tin: '999991130', bhfId: '00', // '00' is head office, '01' to 'n' for branches cmcKey: 'your_cmc_key', // Null during initialization isSandbox: true // Set to false for production );
2. Device Registration / Verification
Get your communication key (cmcKey) from RRA:
use RRA\EBM\Services\AuthService; $authService = new AuthService($client); $response = $authService->verifyDevice('YOUR_DEVICE_SERIAL_NUMBER'); $cmcKey = $response['data']['info']['cmcKey'] ?? null; // Store this cmcKey in your database for future API calls!
3. Basic Data Synchronization
Get standard lists (such as tax categories) or verify customer info:
use RRA\EBM\Services\BasicDataService; $dataService = new BasicDataService($client); // Get codes registered/updated since a specific date $codes = $dataService->getCodeList('20260814000000'); // Verify a customer's TIN profile $customer = $dataService->getCustomer('841562115'); echo "Customer Name: " . $customer['data']['custList'][0]['taxprNm'];
4. Register Pharmacy Insurance (Pharmacy-Specific)
Save the insurance company details with the RRA server:
use RRA\EBM\Services\BranchService; $branchService = new BranchService($client); $branchService->saveInsurance([ 'isrccCd' => 'ISRCC01', // Insurance Code 'isrccNm' => 'ISRCC NAME', 'isrcRt' => 20, // Premium rate (%) 'useYn' => 'Y' ]);
5. Sync Products (Save Item)
use RRA\EBM\Services\ItemService; use RRA\EBM\Codes; $itemService = new ItemService($client); $itemService->saveItem([ 'itemCd' => 'RW1NTXU0000002', // Unique Item Code 'itemNm' => 'Panadol Extra 500mg', 'itemTyCd' => Codes::PRODUCT_TYPE_FINISHED_PRODUCT, 'taxTyCd' => Codes::TAX_TYPE_STANDARD, // B (18%) 'dftPrc' => 1500.00, 'pkgUnitCd' => 'NT', // Net Packaging 'qtyUnitCd' => 'U', // Units count 'isrcAplcbYn' => 'Y', // Insurance applicable 'useYn' => 'Y' ]);
6. Submit a Sales Invoice
use RRA\EBM\Services\SalesService; use RRA\EBM\Codes; $salesService = new SalesService($client); $invoice = $salesService->saveSale([ 'invcNo' => 12345, 'orgInvcNo' => 0, 'custTin' => '999991112', 'custNm' => 'Customer Name', 'salesTyCd' => Codes::TRANS_TYPE_NORMAL, 'rcptTyCd' => Codes::RECEIPT_TYPE_SALE, 'pmtTyCd' => Codes::PAYMENT_METHOD_CASH, 'salesDt' => '20260814', 'totItemCnt' => 1, 'totTaxblAmt' => 10000.00, 'totTaxAmt' => 1800.00, 'totAmt' => 11800.00, 'itemList' => [ [ 'itemSeq' => 1, 'itemCd' => 'RW1NTXU0000002', 'itemNm' => 'Panadol Extra 500mg', 'qty' => 10, 'prc' => 1180.00, 'splyAmt' => 11800.00, 'taxTyCd' => Codes::TAX_TYPE_STANDARD, 'taxblAmt' => 10000.00, 'taxAmt' => 1800.00, 'totAmt' => 11800.00 ] ] ]); // Fiscal signatures returned by OSDC $signature = $invoice['data']['rcptSign']; $sdcDateTime = $invoice['data']['sdcDateTime'];
7. Update Inventory (Stock In/Out)
use RRA\EBM\Services\StockService; use RRA\EBM\Codes; $stockService = new StockService($client); // Record stock IN from an import/purchase $stockService->saveStockIO([ 'sarNo' => 1, 'sarTyCd' => Codes::STOCK_MOVE_INCOMING_PURCHASE, 'ocrnDt' => '20260814', 'totItemCnt' => 1, 'totAmt' => 50000.00, 'itemList' => [ [ 'itemSeq' => 1, 'itemCd' => 'RW1NTXU0000002', 'qty' => 50, 'prc' => 1000.00, 'splyAmt' => 50000.00 ] ] ]);
Testing
Run unit tests via PHPUnit:
vendor/bin/phpunit
License
This project is open-source and licensed under the MIT License.