EBM HubDeveloper documentationMenu

Current CIS workflow contract

The version 0.2.2 invoice workflow supersedes the earlier basic invoice/refund examples below. Use CIS workflows for receipt profiles, registration, source receipts, inventory and printing.

Use EBM Hub in your browser

Your operator provides your workspace URL and account access. You do not need an API key or coding knowledge to use the browser.

  1. Sign in. If company signup is open, create an account with your company name, TIN, email and password. The operator verifies your company before approving fiscal operations. To access an existing company, ask the operator to add your user; do not register its TIN again.
  2. Choose your environment. Start with Sandbox. Live has separate records, API keys and device initialization. A company may use both at once after approval.
  3. Set up branches. Add the assigned two-digit branch code, branch name and device serial. Initialize each branch in the selected environment after approval.
  4. Fetch RRA reference lists. Retrieve classifications and common codes through an initialized branch. Use the correct classification, quantity/packaging unit and tax codes when registering goods or services.
  5. Build your catalogue. Choose Goods, Service or Raw material; enter the code, name, price including tax and reference codes. Service uses item type 3. Save to your catalogue, then select Register with RRA. Saving locally alone is not RRA registration. Entering an existing item code updates that catalogue entry.
  6. Issue an invoice. Select a branch, enter a unique positive invoice number, choose payment method and add catalogue items and whole-number quantities. Enter customer details and a purchase code where applicable. Review the total, then issue. For a refund, use a new invoice number, identify the original invoice and supply the RRA refund reason code.
  7. Follow delivery and print. Receipts shows issued records and their RRA delivery state. Pending is not accepted. Open a receipt to inspect and print it. If an invoice response is lost, keep the same tab and use Issue / retry; refreshing the page preserves that tab's pending submission so you can recover the same receipt.
  8. Close the day. Daily reports currently expose the supplied WAR's date-validation defect. A rejected request does not submit a Z-report or close the day.

API access is optional. An owner can create a named key for a POS/ERP in the API access screen after environment approval. Copy the key when it is displayed; the full value is shown once. Revoke keys that are no longer needed. Your integration can read its own receipt delivery records with GET/api/portal/receipts and details with GET/api/portal/receipts/{id}, using X-API-Key. Lists return up to 50 records; use ?offset=50 for the next page. API keys stay pinned to their assigned environment.

Owners can change company data and issue invoices. Viewers have read-only company access. Use Change password from the sidebar to replace your password; you will be asked to sign in again. For forgotten passwords or access to another company, contact your operator through the agreed support channel.

A successful password change invalidates your existing browser sessions. If another password or account change overlaps your request, the service refuses to overwrite it and asks you to sign in again. Password changes are recorded in the service audit log without passwords or password hashes; the credential update and audit record are saved together. Company integration API keys are managed separately in API access.

The browser currently supports whole-number quantities, prices with two decimal places, and normal sales/refunds. Ask your integration team about the API for fractional quantities or additional transaction modes. Follow your operator's approved receipt-printing instructions before live use.

Integration key permissions and rotation

In API access, owners can choose permissions for each new key. Uncheck all permissions for read-only access to permitted GET operations. Receipt permission covers issuance, print preparation, cash and report creation. Item registration and stock/receiving workflows also require receipt permission alongside their own permission. Reference lookups use code permission. All keys remain restricted to their company and environment; they cannot manage accounts, keys or reconciliation.

The key list shows granted permissions, last use and revocation state. Secret values appear only when created. To rotate a key, create a replacement with the intended permissions, install and verify it in the integration, then revoke the old key. Revocation does not revoke other integration keys.

The list initially shows the newest 100 keys. Select Load older keys to browse further, including revoked or expired credentials. Each older active key retains its Revoke action. A failed page load leaves the displayed keys intact and can be retried.

Owner-session clients can page GET/api/portal/keys using the returned next_before_id: send ?before_id=<next_before_id> until it is null. The response preserves the data array. Keys sort by creation time and identifier descending; creating newer keys during traversal does not shift older pages. Refresh the first page to see new keys. Cursors must identify an existing key in the selected company and environment; invalid or foreign cursors return HTTP 400. Customer API keys cannot use this management endpoint.

For existing owner-session provisioning integrations, key creation still accepts a name-only body and grants the previous four permissions. Supplying scopes: [] explicitly creates a read-only key. Supplied scopes must be among receipts:write, items:write, codes:read and stock:write; duplicate entries are normalized and unsupported permissions are rejected. Customer API keys cannot provision other keys.

Key creation also offers an optional expiry date/time entered in your browser's local timezone. The portal sends an absolute timestamp; the key table displays expiry in Kigali time and labels expired keys. Leave it blank for no automatic expiry. Expired credentials are rejected even if they were previously valid; create a replacement key through your owner session when needed.

Owner-session provisioning accepts optional expires_at as an RFC 3339 timestamp with an explicit timezone, for example 2099-01-01T12:00:00+02:00. It must be in the future. Omitted/null expiry preserves the existing non-expiring behavior. The creation response and key list include expires_at; listing never returns secret key values.

Creation and revocation record the acting user, company, key identifier/name/prefix, permissions, environment and expiry in the service audit log. The log contains neither the secret key nor its hash. The access change and audit entry commit together: an audit failure rolls back the change. Repeating a completed revocation succeeds without changing its original timestamp or adding another audit event. Owners can view these events in API access → Integration-key history. Select Load history to refresh the newest events or Load older events to continue. The table shows when a key was created/revoked, its name/prefix, who changed it, granted permissions and expiry in the selected environment. Historical changes before key auditing was enabled are not reconstructed. Password and other account audit events are not included in this key-history view.

Owner-session integrations can use GET/api/portal/keys/history. It returns a data array of up to 50 events and nullable next_before_id; request ?before_id=<next_before_id> for older events until null. IDs are decimal strings to preserve large-integer precision. Each event includes id, created_at, action, actor_id, actor, environment, key_id, name, prefix, scopes and expires_at. No secret keys, hashes or arbitrary audit details are returned. Company/environment scope is enforced on every page. Viewers and integration API keys receive HTTP 403; an operator can inspect the selected company's history.

Monthly activity

The overview's Monthly receipt activity panel lets you choose a month and inspect recorded receipts by branch and receipt mode in the selected environment. Month boundaries use Kigali time. Replaying an existing receipt does not increase the count. Delivery status reflects the current state; an older month's accepted/pending counts can change after delivery completes. These counts do not set subscription charges or limits.

Recovering an interrupted reconciliation

Owners/operators must first verify the exact uncertain operation against the configured VSDC records. In Stock & receiving, load unresolved operations and record the verified outcome, evidence reference and successful response when applicable.

The portal saves the exact decision and request key in this browser before sending it, scoped to the company, environment and branch. If the response is lost, reopening Stock & receiving shows Recover saved decision. This explicitly replays the saved request to retrieve its committed result; it does not infer acceptance or invent a new decision. A successful recovery clears the saved request. Reload unresolved operations afterwards to refresh the list.

While a saved decision remains unresolved, a different reconciliation for the same branch is blocked in this browser. Recover the original first. Browser storage is local: clearing it or moving to another browser does not carry the recovery request with you. The server's reconciliation audit remains authoritative.

Reviewing recorded reconciliation decisions

In Stock & receiving, select a branch under Reconcile uncertain deliveries and choose Load operations and history. Recorded reconciliations lists the server's decisions newest first. Expand a record to inspect its audit reference, actor ID, evidence, payload fingerprint and attached response. This history is available to authorized owners/operators even in a fresh browser without a saved local request. It is read-only and records the operator's verified decision; its presence alone is not independent proof of RRA acceptance. Reload after submitting or recovering a decision to refresh the history.

Finding reference codes

In Reference data, choose an initialized branch and fetch common codes, item classifications or registered items. Common codes retain both the category ID and category name. Filter the returned rows by category, active/inactive status, or a code/name search; identical code values in different categories remain separate. An omitted usage flag is shown as Unspecified.

These filters apply to the response for the requested update period, not to a complete cached catalogue. An empty result can mean there were no matching updates. Fetch an earlier period when you need older reference records.

Catalogue registration status

The catalogue lists Registration required for saved or edited items that have not yet been registered. Registered items show the recorded timestamp and branch. After successful registration the catalogue refreshes from the server. Every save clears registration status, so register the reviewed current version before invoicing. A timestamp records success with the configured fiscal backend; it does not establish registration in other branches.

Bringing a registered reference item into your catalogue

Fetch Registered items in Reference data and choose Review in catalogue on the desired row. The catalogue form is populated for the branch used in the fetch. Review every field and fill any missing values. Expand Fetched item details to inspect the source, including optional values such as barcode, batch, standard name, safety quantity and group prices that will be preserved. Active/inactive and insurance flags are editable fields; importing an inactive item does not activate it.

Fetching or reviewing does not save or register anything. Choose Save to catalogue after review, then register the saved version. If the item code already exists, inspect the current record and acknowledge replacement before saving. Replacement keeps the item ID and clears its registration status. This is a manual review workflow, not automatic bulk synchronization. Reviewed replacements carry the catalogue version, and new-code drafts use a create-only condition. If another save occurs after review, the server rejects the stale save without overwriting that item. Reload the reference and review the current catalogue record again before saving. The draft is scoped to the current company/environment and is not persisted across a page reload.

Choosing invoice items

Select the branch before choosing invoice items. The picker shows only items that are active and registered for that branch. If none qualify, review and register your catalogue first. Switching branches clears item selections that do not belong to the new branch; quantities and discounts remain editable. Added lines use the same branch restrictions.

The server checks eligibility again when issuing, so an item changed by another user after the screen loaded can still be rejected. Refunds and copies continue to use their immutable original receipt rather than current catalogue selections.

Questions about onboarding, keys or branches? Contact your EBM Hub onboarding contact.