kra-etims-sdk 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kra-etims-sdk
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Python SDK for KRA eTIMS OSCU API
5
5
  Author: Emmanuel Bartile
6
6
  License: MIT
@@ -41,7 +41,7 @@ Dynamic: license-file
41
41
 
42
42
  A production-ready **Python SDK** for integrating with the Kenya Revenue Authority (KRA) **eTIMS OSCU** (Online Sales Control Unit) API. Built to match the official Postman collection specifications with strict header compliance, token management, and comprehensive Pydantic validation.
43
43
 
44
- > ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the legacy eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
44
+ > ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the VSCU eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
45
45
 
46
46
  ## Author
47
47
  **Bartile Emmanuel**
@@ -73,15 +73,15 @@ A production-ready **Python SDK** for integrating with the Kenya Revenue Authori
73
73
 
74
74
  ## Introduction to eTIMS OSCU
75
75
 
76
- KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike legacy systems, OSCU requires:
76
+ KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike VSCU, OSCU requires:
77
77
 
78
78
  - Pre-registered device serial numbers (`dvcSrlNo`)
79
79
  - Communication key (`cmcKey`) lifecycle management
80
80
  - Strict payload schema compliance per KRA specifications
81
81
 
82
- ### OSCU vs Legacy eTIMS
82
+ ### OSCU vs VSCU eTIMS
83
83
 
84
- | Feature | OSCU (This SDK) | Legacy eTIMS |
84
+ | Feature | OSCU (This SDK) | VSCU eTIMS |
85
85
  |---------|-----------------|--------------|
86
86
  | **Hosting** | KRA-hosted (cloud) | Self-hosted (on-premise) |
87
87
  | **Device Registration** | Mandatory pre-registration | Not required |
@@ -191,17 +191,18 @@ flowchart TD
191
191
  Before integration, you **MUST** complete these prerequisites:
192
192
 
193
193
  ### 1. Device Registration (MANDATORY)
194
- - Register OSCU device via [eTIMS Taxpayer Sandbox Portal](https://sbx.kra.go.ke)
194
+ - Register OSCU device via [eTIMS Taxpayer Production Portal](https://etims.kra.go.ke)
195
+ - Register OSCU device via [eTIMS Taxpayer Sandbox Portal](https://etims-sbx.kra.go.ke)
195
196
  - Obtain **approved device serial number** (`dvcSrlNo`)
196
197
  - ⚠️ **Dynamic/unregistered device serials fail with `resultCd: 901`** ("It is not valid device")
197
198
 
198
199
  ### 2. Communication Key Lifecycle
199
200
  ```python
200
201
  # 1. Initialize FIRST (returns cmcKey)
201
- response = etims.initialize({
202
+ response = etims.select_init_osdc_info({
202
203
  "tin": config.oscu["tin"],
203
204
  "bhfId": config.oscu["bhf_id"],
204
- "dvcSrlNo": "dvcv1130", # KRA-approved serial
205
+ "dvcSrlNo": config.oscu["device_serial"], # KRA-approved serial
205
206
  })
206
207
 
207
208
  # 2. Extract cmcKey (sandbox returns at root level)
@@ -304,19 +305,19 @@ config = KraEtimsConfig(
304
305
  },
305
306
 
306
307
  api={
307
- "sandbox": {"base_url": "https://sbx.kra.go.ke/etims-oscu/api/v1".strip()},
308
- "production": {"base_url": "https://api.developer.go.ke/etims-oscu/api/v1".strip()}
308
+ "sandbox": {"base_url": "https://etims-api-sbx.kra.go.ke/etims-api".strip()},
309
+ "production": {"base_url": "https://etims-api.kra.go.ke/etims-api".strip()}
309
310
  },
310
311
 
311
312
  oscu={
312
313
  "tin": os.environ["KRA_TIN"],
313
- "bhf_id": os.environ["KRA_BHF_ID"],
314
- "cmc_key": "", # Set AFTER initialization
314
+ "bhf_id": os.environ["KRA_BHF_ID"],
315
+ "cmc_key": os.environ["CMC_KEY"] # Set AFTER initialization
315
316
  },
316
317
 
317
318
  endpoints={
318
319
  # INITIALIZATION (ONLY endpoint without tin/bhfId/cmcKey headers)
319
- "initialize": "/initialize",
320
+ "selectInitOsdcInfo": "/selectInitOsdcInfo",
320
321
 
321
322
  # DATA MANAGEMENT
322
323
  "selectCodeList": "/selectCodeList",
@@ -355,7 +356,7 @@ config = KraEtimsConfig(
355
356
  ```
356
357
 
357
358
  > 💡 **Production URL Note**:
358
- > Production base URL is `https://api.developer.go.ke/etims-oscu/api/v1` (NOT `kra.go.ke`)
359
+ > Production base URL is `https://etims-api.kra.go.ke/etims-api` (NOT `https://etims-api-sbx.kra.go.ke/etims-api`)
359
360
 
360
361
  ---
361
362
 
@@ -386,12 +387,11 @@ except AuthenticationException as e:
386
387
  try:
387
388
  # ⚠️ MUST use KRA-approved device serial (NOT dynamic!)
388
389
  # Common sandbox test value (if pre-provisioned by KRA):
389
- device_serial = "dvcv1130" # REPLACE with your approved serial
390
390
 
391
- response = etims.initialize({
391
+ response = etims.select_init_info({
392
392
  "tin": config.oscu["tin"],
393
393
  "bhfId": config.oscu["bhf_id"],
394
- "dvcSrlNo": device_serial.strip(),
394
+ "dvcSrlNo": config.oscu["device_serial"],
395
395
  })
396
396
 
397
397
  # Extract cmcKey (sandbox returns at root level)
@@ -506,7 +506,7 @@ except ApiException as e:
506
506
 
507
507
  | Category | Purpose | Endpoints |
508
508
  |----------|---------|-----------|
509
- | **Initialization** | Device registration & cmcKey acquisition | `initialize` |
509
+ | **Initialization** | Device registration & cmcKey acquisition | `select_init_info` |
510
510
  | **Data Management** | Retrieve standard codes & master data | `select_code_list`, `select_item_cls_list`, `select_bhf_list`, `select_taxpayer_info`, `select_customer_list`, `select_notice_list` |
511
511
  | **Branch Management** | Manage branch offices & users | `branch_insurance_info`, `branch_user_account`, `branch_send_customer_info` |
512
512
  | **Item Management** | Item master data | `save_item`, `item_info` |
@@ -720,7 +720,7 @@ KRA mandates successful completion of automated tests before verification:
720
720
  3. Deploy directly to production environment
721
721
  4. No SLA execution required
722
722
 
723
- > 💡 **Production URL**: `https://api.developer.go.ke/etims-oscu/api/v1`
723
+ > 💡 **Production URL**: `https://etims-api.kra.go.ke/etims-api`
724
724
  > ⚠️ **Never use sandbox credentials in production** – KRA monitors environment separation strictly
725
725
 
726
726
  ---
@@ -18,7 +18,7 @@
18
18
 
19
19
  A production-ready **Python SDK** for integrating with the Kenya Revenue Authority (KRA) **eTIMS OSCU** (Online Sales Control Unit) API. Built to match the official Postman collection specifications with strict header compliance, token management, and comprehensive Pydantic validation.
20
20
 
21
- > ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the legacy eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
21
+ > ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the VSCU eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
22
22
 
23
23
  ## Author
24
24
  **Bartile Emmanuel**
@@ -50,15 +50,15 @@ A production-ready **Python SDK** for integrating with the Kenya Revenue Authori
50
50
 
51
51
  ## Introduction to eTIMS OSCU
52
52
 
53
- KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike legacy systems, OSCU requires:
53
+ KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike VSCU, OSCU requires:
54
54
 
55
55
  - Pre-registered device serial numbers (`dvcSrlNo`)
56
56
  - Communication key (`cmcKey`) lifecycle management
57
57
  - Strict payload schema compliance per KRA specifications
58
58
 
59
- ### OSCU vs Legacy eTIMS
59
+ ### OSCU vs VSCU eTIMS
60
60
 
61
- | Feature | OSCU (This SDK) | Legacy eTIMS |
61
+ | Feature | OSCU (This SDK) | VSCU eTIMS |
62
62
  |---------|-----------------|--------------|
63
63
  | **Hosting** | KRA-hosted (cloud) | Self-hosted (on-premise) |
64
64
  | **Device Registration** | Mandatory pre-registration | Not required |
@@ -168,17 +168,18 @@ flowchart TD
168
168
  Before integration, you **MUST** complete these prerequisites:
169
169
 
170
170
  ### 1. Device Registration (MANDATORY)
171
- - Register OSCU device via [eTIMS Taxpayer Sandbox Portal](https://sbx.kra.go.ke)
171
+ - Register OSCU device via [eTIMS Taxpayer Production Portal](https://etims.kra.go.ke)
172
+ - Register OSCU device via [eTIMS Taxpayer Sandbox Portal](https://etims-sbx.kra.go.ke)
172
173
  - Obtain **approved device serial number** (`dvcSrlNo`)
173
174
  - ⚠️ **Dynamic/unregistered device serials fail with `resultCd: 901`** ("It is not valid device")
174
175
 
175
176
  ### 2. Communication Key Lifecycle
176
177
  ```python
177
178
  # 1. Initialize FIRST (returns cmcKey)
178
- response = etims.initialize({
179
+ response = etims.select_init_osdc_info({
179
180
  "tin": config.oscu["tin"],
180
181
  "bhfId": config.oscu["bhf_id"],
181
- "dvcSrlNo": "dvcv1130", # KRA-approved serial
182
+ "dvcSrlNo": config.oscu["device_serial"], # KRA-approved serial
182
183
  })
183
184
 
184
185
  # 2. Extract cmcKey (sandbox returns at root level)
@@ -281,19 +282,19 @@ config = KraEtimsConfig(
281
282
  },
282
283
 
283
284
  api={
284
- "sandbox": {"base_url": "https://sbx.kra.go.ke/etims-oscu/api/v1".strip()},
285
- "production": {"base_url": "https://api.developer.go.ke/etims-oscu/api/v1".strip()}
285
+ "sandbox": {"base_url": "https://etims-api-sbx.kra.go.ke/etims-api".strip()},
286
+ "production": {"base_url": "https://etims-api.kra.go.ke/etims-api".strip()}
286
287
  },
287
288
 
288
289
  oscu={
289
290
  "tin": os.environ["KRA_TIN"],
290
- "bhf_id": os.environ["KRA_BHF_ID"],
291
- "cmc_key": "", # Set AFTER initialization
291
+ "bhf_id": os.environ["KRA_BHF_ID"],
292
+ "cmc_key": os.environ["CMC_KEY"] # Set AFTER initialization
292
293
  },
293
294
 
294
295
  endpoints={
295
296
  # INITIALIZATION (ONLY endpoint without tin/bhfId/cmcKey headers)
296
- "initialize": "/initialize",
297
+ "selectInitOsdcInfo": "/selectInitOsdcInfo",
297
298
 
298
299
  # DATA MANAGEMENT
299
300
  "selectCodeList": "/selectCodeList",
@@ -332,7 +333,7 @@ config = KraEtimsConfig(
332
333
  ```
333
334
 
334
335
  > 💡 **Production URL Note**:
335
- > Production base URL is `https://api.developer.go.ke/etims-oscu/api/v1` (NOT `kra.go.ke`)
336
+ > Production base URL is `https://etims-api.kra.go.ke/etims-api` (NOT `https://etims-api-sbx.kra.go.ke/etims-api`)
336
337
 
337
338
  ---
338
339
 
@@ -363,12 +364,11 @@ except AuthenticationException as e:
363
364
  try:
364
365
  # ⚠️ MUST use KRA-approved device serial (NOT dynamic!)
365
366
  # Common sandbox test value (if pre-provisioned by KRA):
366
- device_serial = "dvcv1130" # REPLACE with your approved serial
367
367
 
368
- response = etims.initialize({
368
+ response = etims.select_init_info({
369
369
  "tin": config.oscu["tin"],
370
370
  "bhfId": config.oscu["bhf_id"],
371
- "dvcSrlNo": device_serial.strip(),
371
+ "dvcSrlNo": config.oscu["device_serial"],
372
372
  })
373
373
 
374
374
  # Extract cmcKey (sandbox returns at root level)
@@ -483,7 +483,7 @@ except ApiException as e:
483
483
 
484
484
  | Category | Purpose | Endpoints |
485
485
  |----------|---------|-----------|
486
- | **Initialization** | Device registration & cmcKey acquisition | `initialize` |
486
+ | **Initialization** | Device registration & cmcKey acquisition | `select_init_info` |
487
487
  | **Data Management** | Retrieve standard codes & master data | `select_code_list`, `select_item_cls_list`, `select_bhf_list`, `select_taxpayer_info`, `select_customer_list`, `select_notice_list` |
488
488
  | **Branch Management** | Manage branch offices & users | `branch_insurance_info`, `branch_user_account`, `branch_send_customer_info` |
489
489
  | **Item Management** | Item master data | `save_item`, `item_info` |
@@ -697,7 +697,7 @@ KRA mandates successful completion of automated tests before verification:
697
697
  3. Deploy directly to production environment
698
698
  4. No SLA execution required
699
699
 
700
- > 💡 **Production URL**: `https://api.developer.go.ke/etims-oscu/api/v1`
700
+ > 💡 **Production URL**: `https://etims-api.kra.go.ke/etims-api`
701
701
  > ⚠️ **Never use sandbox credentials in production** – KRA monitors environment separation strictly
702
702
 
703
703
  ---
@@ -32,10 +32,11 @@ class BaseClient:
32
32
  def _request(self, method, endpoint, data):
33
33
  url = self.base_url() + endpoint
34
34
  headers = self._headers(endpoint)
35
+ print(url, headers, data)
35
36
  return requests.request(method, url, json=data, headers=headers, timeout=30)
36
37
 
37
38
  def _headers(self, endpoint):
38
- if endpoint.endswith("/initialize"):
39
+ if endpoint.endswith("/selectInitOsdcInfo"):
39
40
  return {
40
41
  "Authorization": f"Bearer {self.auth.token()}",
41
42
  "Content-Type": "application/json",
@@ -11,12 +11,12 @@ class EtimsClient(BaseClient):
11
11
  def _validate(self, data: dict, schema: str) -> dict:
12
12
  return self.validator.validate(data, schema)
13
13
 
14
- # -----------------------------
15
- # INITIALIZATION (POSTMAN-COMPLIANT)
16
- # -----------------------------
17
- def initialize(self, data: dict) -> dict:
18
- validated = self._validate(data, "initialization")
19
- return self.post("initialize", validated)
14
+ def select_init_osdc_info(self, data: dict) -> dict:
15
+ """
16
+ Initialize the OSCU device with KRA.
17
+ Returns cmcKey and device information.
18
+ """
19
+ return self.post("selectInitOsdcInfo", self._validate(data, "initialization"))
20
20
 
21
21
  # -----------------------------
22
22
  # BASIC DATA ENDPOINTS
@@ -14,7 +14,7 @@ from pydantic import (
14
14
  # =========================================================
15
15
 
16
16
  TIN = Annotated[str, StringConstraints(min_length=1, max_length=20)]
17
- BHF = Annotated[str, StringConstraints(min_length=1, max_length=10)]
17
+ BHF = Annotated[str, StringConstraints(min_length=1, max_length=20)]
18
18
 
19
19
  YN = Annotated[str, StringConstraints(pattern="^[YN]$")]
20
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kra-etims-sdk
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Python SDK for KRA eTIMS OSCU API
5
5
  Author: Emmanuel Bartile
6
6
  License: MIT
@@ -41,7 +41,7 @@ Dynamic: license-file
41
41
 
42
42
  A production-ready **Python SDK** for integrating with the Kenya Revenue Authority (KRA) **eTIMS OSCU** (Online Sales Control Unit) API. Built to match the official Postman collection specifications with strict header compliance, token management, and comprehensive Pydantic validation.
43
43
 
44
- > ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the legacy eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
44
+ > ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the VSCU eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
45
45
 
46
46
  ## Author
47
47
  **Bartile Emmanuel**
@@ -73,15 +73,15 @@ A production-ready **Python SDK** for integrating with the Kenya Revenue Authori
73
73
 
74
74
  ## Introduction to eTIMS OSCU
75
75
 
76
- KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike legacy systems, OSCU requires:
76
+ KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike VSCU, OSCU requires:
77
77
 
78
78
  - Pre-registered device serial numbers (`dvcSrlNo`)
79
79
  - Communication key (`cmcKey`) lifecycle management
80
80
  - Strict payload schema compliance per KRA specifications
81
81
 
82
- ### OSCU vs Legacy eTIMS
82
+ ### OSCU vs VSCU eTIMS
83
83
 
84
- | Feature | OSCU (This SDK) | Legacy eTIMS |
84
+ | Feature | OSCU (This SDK) | VSCU eTIMS |
85
85
  |---------|-----------------|--------------|
86
86
  | **Hosting** | KRA-hosted (cloud) | Self-hosted (on-premise) |
87
87
  | **Device Registration** | Mandatory pre-registration | Not required |
@@ -191,17 +191,18 @@ flowchart TD
191
191
  Before integration, you **MUST** complete these prerequisites:
192
192
 
193
193
  ### 1. Device Registration (MANDATORY)
194
- - Register OSCU device via [eTIMS Taxpayer Sandbox Portal](https://sbx.kra.go.ke)
194
+ - Register OSCU device via [eTIMS Taxpayer Production Portal](https://etims.kra.go.ke)
195
+ - Register OSCU device via [eTIMS Taxpayer Sandbox Portal](https://etims-sbx.kra.go.ke)
195
196
  - Obtain **approved device serial number** (`dvcSrlNo`)
196
197
  - ⚠️ **Dynamic/unregistered device serials fail with `resultCd: 901`** ("It is not valid device")
197
198
 
198
199
  ### 2. Communication Key Lifecycle
199
200
  ```python
200
201
  # 1. Initialize FIRST (returns cmcKey)
201
- response = etims.initialize({
202
+ response = etims.select_init_osdc_info({
202
203
  "tin": config.oscu["tin"],
203
204
  "bhfId": config.oscu["bhf_id"],
204
- "dvcSrlNo": "dvcv1130", # KRA-approved serial
205
+ "dvcSrlNo": config.oscu["device_serial"], # KRA-approved serial
205
206
  })
206
207
 
207
208
  # 2. Extract cmcKey (sandbox returns at root level)
@@ -304,19 +305,19 @@ config = KraEtimsConfig(
304
305
  },
305
306
 
306
307
  api={
307
- "sandbox": {"base_url": "https://sbx.kra.go.ke/etims-oscu/api/v1".strip()},
308
- "production": {"base_url": "https://api.developer.go.ke/etims-oscu/api/v1".strip()}
308
+ "sandbox": {"base_url": "https://etims-api-sbx.kra.go.ke/etims-api".strip()},
309
+ "production": {"base_url": "https://etims-api.kra.go.ke/etims-api".strip()}
309
310
  },
310
311
 
311
312
  oscu={
312
313
  "tin": os.environ["KRA_TIN"],
313
- "bhf_id": os.environ["KRA_BHF_ID"],
314
- "cmc_key": "", # Set AFTER initialization
314
+ "bhf_id": os.environ["KRA_BHF_ID"],
315
+ "cmc_key": os.environ["CMC_KEY"] # Set AFTER initialization
315
316
  },
316
317
 
317
318
  endpoints={
318
319
  # INITIALIZATION (ONLY endpoint without tin/bhfId/cmcKey headers)
319
- "initialize": "/initialize",
320
+ "selectInitOsdcInfo": "/selectInitOsdcInfo",
320
321
 
321
322
  # DATA MANAGEMENT
322
323
  "selectCodeList": "/selectCodeList",
@@ -355,7 +356,7 @@ config = KraEtimsConfig(
355
356
  ```
356
357
 
357
358
  > 💡 **Production URL Note**:
358
- > Production base URL is `https://api.developer.go.ke/etims-oscu/api/v1` (NOT `kra.go.ke`)
359
+ > Production base URL is `https://etims-api.kra.go.ke/etims-api` (NOT `https://etims-api-sbx.kra.go.ke/etims-api`)
359
360
 
360
361
  ---
361
362
 
@@ -386,12 +387,11 @@ except AuthenticationException as e:
386
387
  try:
387
388
  # ⚠️ MUST use KRA-approved device serial (NOT dynamic!)
388
389
  # Common sandbox test value (if pre-provisioned by KRA):
389
- device_serial = "dvcv1130" # REPLACE with your approved serial
390
390
 
391
- response = etims.initialize({
391
+ response = etims.select_init_info({
392
392
  "tin": config.oscu["tin"],
393
393
  "bhfId": config.oscu["bhf_id"],
394
- "dvcSrlNo": device_serial.strip(),
394
+ "dvcSrlNo": config.oscu["device_serial"],
395
395
  })
396
396
 
397
397
  # Extract cmcKey (sandbox returns at root level)
@@ -506,7 +506,7 @@ except ApiException as e:
506
506
 
507
507
  | Category | Purpose | Endpoints |
508
508
  |----------|---------|-----------|
509
- | **Initialization** | Device registration & cmcKey acquisition | `initialize` |
509
+ | **Initialization** | Device registration & cmcKey acquisition | `select_init_info` |
510
510
  | **Data Management** | Retrieve standard codes & master data | `select_code_list`, `select_item_cls_list`, `select_bhf_list`, `select_taxpayer_info`, `select_customer_list`, `select_notice_list` |
511
511
  | **Branch Management** | Manage branch offices & users | `branch_insurance_info`, `branch_user_account`, `branch_send_customer_info` |
512
512
  | **Item Management** | Item master data | `save_item`, `item_info` |
@@ -720,7 +720,7 @@ KRA mandates successful completion of automated tests before verification:
720
720
  3. Deploy directly to production environment
721
721
  4. No SLA execution required
722
722
 
723
- > 💡 **Production URL**: `https://api.developer.go.ke/etims-oscu/api/v1`
723
+ > 💡 **Production URL**: `https://etims-api.kra.go.ke/etims-api`
724
724
  > ⚠️ **Never use sandbox credentials in production** – KRA monitors environment separation strictly
725
725
 
726
726
  ---
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kra-etims-sdk"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Python SDK for KRA eTIMS OSCU API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -60,10 +60,10 @@ CONFIG = {
60
60
 
61
61
  "api": {
62
62
  "sbx": {
63
- "base_url": "https://sbx.kra.go.ke/etims-oscu/api/v1",
63
+ "base_url": "https://etims-api-sbx.kra.go.ke/etims-api",
64
64
  },
65
65
  "prod": {
66
- "base_url": "https://kra.go.ke/etims-oscu/api/v1",
66
+ "base_url": "https://etims-api.kra.go.ke/etims-api",
67
67
  },
68
68
  },
69
69
 
@@ -72,13 +72,14 @@ CONFIG = {
72
72
  },
73
73
 
74
74
  "oscu": {
75
- "tin": os.getenv("KRA_TIN", "P000000002"),
76
- "bhf_id": os.getenv("KRA_BHF_ID", "00"),
77
- "cmc_key": "",
75
+ "tin": os.getenv("KRA_TIN", ""),
76
+ "bhf_id": os.getenv("KRA_BHF_ID", ""),
77
+ "cmc_key": os.getenv("CMC_KEY", ""),
78
+ "device_serial": os.getenv("DEVICE_SERIAL", ""),
78
79
  },
79
80
 
80
81
  "endpoints": {
81
- "initialize": "/initialize",
82
+ "selectInitOsdcInfo": "/selectInitOsdcInfo",
82
83
  "selectCodeList": "/selectCodeList",
83
84
  "selectTaxpayerInfo": "/selectTaxpayerInfo",
84
85
  "selectNoticeList": "/selectNoticeList",
@@ -124,28 +125,26 @@ except AuthenticationException as e:
124
125
  header("STEP 2: OSCU INITIALIZATION")
125
126
  warning("Device serial MUST be pre-registered with KRA")
126
127
 
127
- DEVICE_SERIAL = "dvcv1130" # 🔴 REPLACE WITH APPROVED SERIAL
128
-
129
128
  try:
130
129
  etims = EtimsClient(CONFIG, auth)
131
130
 
132
- response = etims.initialize({
133
- "tin": CONFIG["oscu"]["tin"],
134
- "bhfId": CONFIG["oscu"]["bhf_id"],
135
- "dvcSrlNo": DEVICE_SERIAL,
136
- })
131
+ # response = etims.select_init_info({
132
+ # "tin": CONFIG["oscu"]["tin"],
133
+ # "bhfId": CONFIG["oscu"]["bhf_id"],
134
+ # "dvcSrlNo": CONFIG["oscu"]["device_serial"],
135
+ # })
137
136
 
138
- pprint(response)
137
+ # pprint(response)
138
+
139
+ # cmc_key = response.get("cmcKey") or response.get("data", {}).get("info", {}).get("cmcKey")
140
+ # if not cmc_key:
141
+ # raise RuntimeError("cmcKey missing from initialization response")
139
142
 
140
- cmc_key = response.get("cmcKey") or response.get("data", {}).get("cmcKey")
141
- if not cmc_key:
142
- raise RuntimeError("cmcKey missing from initialization response")
143
+ # success("Initialization successful")
144
+ # print("cmcKey:", cmc_key[:15], "...")
143
145
 
144
- CONFIG["oscu"]["cmc_key"] = cmc_key
145
146
  etims = EtimsClient(CONFIG, auth)
146
147
 
147
- success("Initialization successful")
148
- print("cmcKey:", cmc_key[:15], "...")
149
148
  except ApiException as e:
150
149
  error(f"Initialization failed: {e}")
151
150
  pprint(e.details)
@@ -160,10 +159,10 @@ try:
160
159
  "bhfId": CONFIG["oscu"]["bhf_id"],
161
160
  "lastReqDt": format_date(),
162
161
  })
163
-
164
162
  count = len(response.get("itemList", []))
165
163
  success(f"Retrieved {count} code list items")
166
164
  except ApiException as e:
165
+ print("emm")
167
166
  error(str(e))
168
167
  sys.exit(1)
169
168
 
File without changes
File without changes