bpjs-bridging 0.1.0__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.
- bpjs_bridging-0.1.0/LICENSE +22 -0
- bpjs_bridging-0.1.0/PKG-INFO +151 -0
- bpjs_bridging-0.1.0/README.md +114 -0
- bpjs_bridging-0.1.0/pyproject.toml +6 -0
- bpjs_bridging-0.1.0/setup.cfg +4 -0
- bpjs_bridging-0.1.0/setup.py +58 -0
- bpjs_bridging-0.1.0/src/bpjs/__init__.py +1 -0
- bpjs_bridging-0.1.0/src/bpjs/bpjs.py +195 -0
- bpjs_bridging-0.1.0/src/bpjs_bridging.egg-info/PKG-INFO +151 -0
- bpjs_bridging-0.1.0/src/bpjs_bridging.egg-info/SOURCES.txt +11 -0
- bpjs_bridging-0.1.0/src/bpjs_bridging.egg-info/dependency_links.txt +1 -0
- bpjs_bridging-0.1.0/src/bpjs_bridging.egg-info/requires.txt +3 -0
- bpjs_bridging-0.1.0/src/bpjs_bridging.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Moriz
|
|
4
|
+
Copyright (c) 2026 Syamsul
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bpjs-bridging
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial Python client for BPJS Kesehatan API supporting VClaim, iCare, Antrean RS, and Aplicare.
|
|
5
|
+
Home-page: https://github.com/shiday1993/bpjs
|
|
6
|
+
Author: Syamsul
|
|
7
|
+
Author-email: shiday1993@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/shiday1993/bpjs/issues
|
|
10
|
+
Project-URL: Source Code, https://github.com/shiday1993/bpjs
|
|
11
|
+
Keywords: bpjs,vclaim,icare,antrean-rs,aplicare,jkn
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: lzstring
|
|
22
|
+
Requires-Dist: requests
|
|
23
|
+
Requires-Dist: pycryptodome
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: keywords
|
|
31
|
+
Dynamic: license
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
Dynamic: project-url
|
|
34
|
+
Dynamic: requires-dist
|
|
35
|
+
Dynamic: requires-python
|
|
36
|
+
Dynamic: summary
|
|
37
|
+
|
|
38
|
+
# BPJS Python Client
|
|
39
|
+
|
|
40
|
+
Unofficial Python client untuk integrasi API BPJS Kesehatan.
|
|
41
|
+
|
|
42
|
+
Library ini menyediakan interface sederhana untuk melakukan request ke beberapa layanan BPJS Kesehatan seperti **VClaim, iCare, Antrean RS, dan Aplicare**, termasuk pembuatan signature dan dekripsi response pada service yang membutuhkannya.
|
|
43
|
+
|
|
44
|
+
> Project ini bukan library resmi dari BPJS Kesehatan.
|
|
45
|
+
|
|
46
|
+
## Fitur
|
|
47
|
+
|
|
48
|
+
- Generate `X-Signature` menggunakan HMAC SHA-256
|
|
49
|
+
- Generate header autentikasi BPJS
|
|
50
|
+
- Dekripsi response terenkripsi menggunakan AES
|
|
51
|
+
- Dekompresi response menggunakan LZString
|
|
52
|
+
- Mendukung beberapa service:
|
|
53
|
+
- VClaim
|
|
54
|
+
- iCare
|
|
55
|
+
- Antrean RS
|
|
56
|
+
- Aplicare
|
|
57
|
+
- Interface request yang sama untuk setiap service
|
|
58
|
+
- Mendukung GET, POST, PUT, dan DELETE
|
|
59
|
+
- Normalisasi response BPJS
|
|
60
|
+
|
|
61
|
+
## Instalasi
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install bpjs-bridging
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> Nama package dapat berubah sebelum rilis resmi ke PyPI.
|
|
68
|
+
|
|
69
|
+
## Penggunaan
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from bpjs import Bridging
|
|
73
|
+
|
|
74
|
+
config = {
|
|
75
|
+
"consid": "your_consid",
|
|
76
|
+
"secret": "your_secret",
|
|
77
|
+
"user_key": "your_userkey",
|
|
78
|
+
"host": "base_url",
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
vclaim = Bridging(config, "vclaim")
|
|
82
|
+
|
|
83
|
+
response = vclaim.request("referensi/propinsi")
|
|
84
|
+
|
|
85
|
+
print(response)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### POST Request
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
payload = {
|
|
92
|
+
"param": "0000000000000",
|
|
93
|
+
"kodedokter": 123456,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
response = icare.request(
|
|
97
|
+
"api/rs/validate",
|
|
98
|
+
method="post",
|
|
99
|
+
payload=payload,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
print(response)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Service
|
|
106
|
+
|
|
107
|
+
Service ditentukan ketika membuat instance `Bridging`.
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
vclaim = Bridging(config, "vclaim")
|
|
111
|
+
icare = Bridging(config, "icare")
|
|
112
|
+
antrean = Bridging(config, "antrean")
|
|
113
|
+
aplicare = Bridging(config, "aplicare")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Setiap konfigurasi `config` membawa host service yang akan digunakan.
|
|
117
|
+
|
|
118
|
+
## Konfigurasi
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
config = {
|
|
122
|
+
"host": "SERVICE_HOST",
|
|
123
|
+
"consid": "consid",
|
|
124
|
+
"secret": "secret",
|
|
125
|
+
"user_key": "userkey",
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Jangan menyimpan credential BPJS secara langsung di source code pada aplikasi production. Gunakan environment variable atau mekanisme secret management lainnya.
|
|
130
|
+
|
|
131
|
+
## Credit
|
|
132
|
+
|
|
133
|
+
Implementasi awal mekanisme signature dan dekripsi response
|
|
134
|
+
dikembangkan berdasarkan:
|
|
135
|
+
|
|
136
|
+
[morizbebenk/pybpjs](https://github.com/morizbebenk/pybpjs)
|
|
137
|
+
|
|
138
|
+
Project ini kemudian direfaktor dan dikembangkan lebih lanjut
|
|
139
|
+
untuk mendukung beberapa service BPJS melalui interface berbasis class.
|
|
140
|
+
|
|
141
|
+
## Sumber Daya
|
|
142
|
+
- https://dvlp.bpjs-kesehatan.go.id:8888/trust-mark/portal.html
|
|
143
|
+
|
|
144
|
+
## Lisensi
|
|
145
|
+
- Aplikasi ini open source dengan lisensi [MIT](LICENSE).
|
|
146
|
+
|
|
147
|
+
## Disclaimer
|
|
148
|
+
|
|
149
|
+
Project ini merupakan library pihak ketiga dan tidak berafiliasi, didukung, atau dikelola oleh BPJS Kesehatan.
|
|
150
|
+
|
|
151
|
+
Pengguna bertanggung jawab atas penggunaan credential dan kepatuhan terhadap ketentuan API BPJS Kesehatan.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# BPJS Python Client
|
|
2
|
+
|
|
3
|
+
Unofficial Python client untuk integrasi API BPJS Kesehatan.
|
|
4
|
+
|
|
5
|
+
Library ini menyediakan interface sederhana untuk melakukan request ke beberapa layanan BPJS Kesehatan seperti **VClaim, iCare, Antrean RS, dan Aplicare**, termasuk pembuatan signature dan dekripsi response pada service yang membutuhkannya.
|
|
6
|
+
|
|
7
|
+
> Project ini bukan library resmi dari BPJS Kesehatan.
|
|
8
|
+
|
|
9
|
+
## Fitur
|
|
10
|
+
|
|
11
|
+
- Generate `X-Signature` menggunakan HMAC SHA-256
|
|
12
|
+
- Generate header autentikasi BPJS
|
|
13
|
+
- Dekripsi response terenkripsi menggunakan AES
|
|
14
|
+
- Dekompresi response menggunakan LZString
|
|
15
|
+
- Mendukung beberapa service:
|
|
16
|
+
- VClaim
|
|
17
|
+
- iCare
|
|
18
|
+
- Antrean RS
|
|
19
|
+
- Aplicare
|
|
20
|
+
- Interface request yang sama untuk setiap service
|
|
21
|
+
- Mendukung GET, POST, PUT, dan DELETE
|
|
22
|
+
- Normalisasi response BPJS
|
|
23
|
+
|
|
24
|
+
## Instalasi
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install bpjs-bridging
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
> Nama package dapat berubah sebelum rilis resmi ke PyPI.
|
|
31
|
+
|
|
32
|
+
## Penggunaan
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from bpjs import Bridging
|
|
36
|
+
|
|
37
|
+
config = {
|
|
38
|
+
"consid": "your_consid",
|
|
39
|
+
"secret": "your_secret",
|
|
40
|
+
"user_key": "your_userkey",
|
|
41
|
+
"host": "base_url",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
vclaim = Bridging(config, "vclaim")
|
|
45
|
+
|
|
46
|
+
response = vclaim.request("referensi/propinsi")
|
|
47
|
+
|
|
48
|
+
print(response)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### POST Request
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
payload = {
|
|
55
|
+
"param": "0000000000000",
|
|
56
|
+
"kodedokter": 123456,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
response = icare.request(
|
|
60
|
+
"api/rs/validate",
|
|
61
|
+
method="post",
|
|
62
|
+
payload=payload,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
print(response)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Service
|
|
69
|
+
|
|
70
|
+
Service ditentukan ketika membuat instance `Bridging`.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
vclaim = Bridging(config, "vclaim")
|
|
74
|
+
icare = Bridging(config, "icare")
|
|
75
|
+
antrean = Bridging(config, "antrean")
|
|
76
|
+
aplicare = Bridging(config, "aplicare")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Setiap konfigurasi `config` membawa host service yang akan digunakan.
|
|
80
|
+
|
|
81
|
+
## Konfigurasi
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
config = {
|
|
85
|
+
"host": "SERVICE_HOST",
|
|
86
|
+
"consid": "consid",
|
|
87
|
+
"secret": "secret",
|
|
88
|
+
"user_key": "userkey",
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Jangan menyimpan credential BPJS secara langsung di source code pada aplikasi production. Gunakan environment variable atau mekanisme secret management lainnya.
|
|
93
|
+
|
|
94
|
+
## Credit
|
|
95
|
+
|
|
96
|
+
Implementasi awal mekanisme signature dan dekripsi response
|
|
97
|
+
dikembangkan berdasarkan:
|
|
98
|
+
|
|
99
|
+
[morizbebenk/pybpjs](https://github.com/morizbebenk/pybpjs)
|
|
100
|
+
|
|
101
|
+
Project ini kemudian direfaktor dan dikembangkan lebih lanjut
|
|
102
|
+
untuk mendukung beberapa service BPJS melalui interface berbasis class.
|
|
103
|
+
|
|
104
|
+
## Sumber Daya
|
|
105
|
+
- https://dvlp.bpjs-kesehatan.go.id:8888/trust-mark/portal.html
|
|
106
|
+
|
|
107
|
+
## Lisensi
|
|
108
|
+
- Aplikasi ini open source dengan lisensi [MIT](LICENSE).
|
|
109
|
+
|
|
110
|
+
## Disclaimer
|
|
111
|
+
|
|
112
|
+
Project ini merupakan library pihak ketiga dan tidak berafiliasi, didukung, atau dikelola oleh BPJS Kesehatan.
|
|
113
|
+
|
|
114
|
+
Pengguna bertanggung jawab atas penggunaan credential dan kepatuhan terhadap ketentuan API BPJS Kesehatan.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import setuptools
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setuptools.setup(
|
|
7
|
+
name="bpjs-bridging",
|
|
8
|
+
version="0.1.0",
|
|
9
|
+
|
|
10
|
+
author="Syamsul",
|
|
11
|
+
author_email="shiday1993@gmail.com",
|
|
12
|
+
|
|
13
|
+
description=(
|
|
14
|
+
"Unofficial Python client for BPJS Kesehatan API "
|
|
15
|
+
"supporting VClaim, iCare, Antrean RS, and Aplicare."
|
|
16
|
+
),
|
|
17
|
+
|
|
18
|
+
long_description=long_description,
|
|
19
|
+
long_description_content_type="text/markdown",
|
|
20
|
+
|
|
21
|
+
url="https://github.com/shiday1993/bpjs",
|
|
22
|
+
|
|
23
|
+
project_urls={
|
|
24
|
+
"Bug Tracker": "https://github.com/shiday1993/bpjs/issues",
|
|
25
|
+
"Source Code": "https://github.com/shiday1993/bpjs",
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
classifiers=[
|
|
29
|
+
"Development Status :: 3 - Alpha",
|
|
30
|
+
"Operating System :: OS Independent",
|
|
31
|
+
"License :: OSI Approved :: MIT License",
|
|
32
|
+
"Programming Language :: Python :: 3",
|
|
33
|
+
"Programming Language :: Python :: 3.9",
|
|
34
|
+
"Programming Language :: Python :: 3.14",
|
|
35
|
+
],
|
|
36
|
+
|
|
37
|
+
package_dir={"": "src"},
|
|
38
|
+
packages=setuptools.find_packages(where="src"),
|
|
39
|
+
|
|
40
|
+
python_requires=">=3.9",
|
|
41
|
+
|
|
42
|
+
license="MIT",
|
|
43
|
+
|
|
44
|
+
keywords=[
|
|
45
|
+
"bpjs",
|
|
46
|
+
"vclaim",
|
|
47
|
+
"icare",
|
|
48
|
+
"antrean-rs",
|
|
49
|
+
"aplicare",
|
|
50
|
+
"jkn",
|
|
51
|
+
],
|
|
52
|
+
|
|
53
|
+
install_requires=[
|
|
54
|
+
"lzstring",
|
|
55
|
+
"requests",
|
|
56
|
+
"pycryptodome",
|
|
57
|
+
],
|
|
58
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .bpjs import Bridging
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
from Crypto.Cipher import AES
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import lzstring
|
|
4
|
+
import requests
|
|
5
|
+
import hashlib
|
|
6
|
+
import base64
|
|
7
|
+
import hmac
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Bridging:
|
|
12
|
+
SERVICE_CONFIG = {
|
|
13
|
+
"vclaim": {
|
|
14
|
+
"encrypted": True,
|
|
15
|
+
"use_user_key": True,
|
|
16
|
+
"content_type": "application/x-www-form-urlencoded",
|
|
17
|
+
},
|
|
18
|
+
"icare": {
|
|
19
|
+
"encrypted": True,
|
|
20
|
+
"use_user_key": True,
|
|
21
|
+
"content_type": "application/json",
|
|
22
|
+
},
|
|
23
|
+
"antrean": {
|
|
24
|
+
"encrypted": True,
|
|
25
|
+
"use_user_key": True,
|
|
26
|
+
"content_type": "application/json",
|
|
27
|
+
},
|
|
28
|
+
"aplicare": {
|
|
29
|
+
"encrypted": False,
|
|
30
|
+
"use_user_key": False,
|
|
31
|
+
"content_type": "application/json",
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
UNENCRYPTED_ENDPOINTS = {
|
|
36
|
+
"vclaim": [
|
|
37
|
+
"SEP/2.0/delete",
|
|
38
|
+
"SEP/2.0/update",
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def __init__(self, client, service):
|
|
43
|
+
service = service.lower()
|
|
44
|
+
if service not in self.SERVICE_CONFIG:
|
|
45
|
+
raise ValueError(f"Service BPJS tidak dikenal: {service}")
|
|
46
|
+
self.service = service
|
|
47
|
+
self.config = self.SERVICE_CONFIG[service]
|
|
48
|
+
self.host = client["host"].rstrip("/")
|
|
49
|
+
self.consid = client["consid"]
|
|
50
|
+
self.secret = client["secret"]
|
|
51
|
+
self.user_key = client.get("user_key")
|
|
52
|
+
|
|
53
|
+
# URL
|
|
54
|
+
@staticmethod
|
|
55
|
+
def _fixed_url(value):
|
|
56
|
+
return value.strip("/")
|
|
57
|
+
|
|
58
|
+
def _build_url(self, endpoint):
|
|
59
|
+
return f"{self._fixed_url(self.host)}/{self._fixed_url(endpoint)}"
|
|
60
|
+
|
|
61
|
+
# AUTH / SIGNATURE
|
|
62
|
+
def _timestamp(self):
|
|
63
|
+
return str(int(datetime.now().timestamp()))
|
|
64
|
+
|
|
65
|
+
def _signature(self, timestamp):
|
|
66
|
+
message = f"{self.consid}&{timestamp}"
|
|
67
|
+
signature = hmac.new(
|
|
68
|
+
self.secret.encode("utf-8"),
|
|
69
|
+
message.encode("utf-8"),
|
|
70
|
+
hashlib.sha256
|
|
71
|
+
).digest()
|
|
72
|
+
return base64.b64encode(signature).decode()
|
|
73
|
+
|
|
74
|
+
def _headers(self, timestamp):
|
|
75
|
+
headers = {
|
|
76
|
+
"X-cons-id": self.consid,
|
|
77
|
+
"X-timestamp": timestamp,
|
|
78
|
+
"X-signature": self._signature(timestamp),
|
|
79
|
+
"Content-Type": self.config["content_type"],
|
|
80
|
+
"Accept": "*/*",
|
|
81
|
+
}
|
|
82
|
+
if self.config.get("use_user_key") and self.user_key:
|
|
83
|
+
headers["user_key"] = self.user_key
|
|
84
|
+
return headers
|
|
85
|
+
|
|
86
|
+
# DECRYPT
|
|
87
|
+
def _decrypt(self, encrypted, timestamp):
|
|
88
|
+
if not encrypted:
|
|
89
|
+
return None
|
|
90
|
+
key = f"{self.consid}{self.secret}{timestamp}"
|
|
91
|
+
key_hash = hashlib.sha256(key.encode("utf-8")).digest()
|
|
92
|
+
decryptor = AES.new(
|
|
93
|
+
key_hash[:32],
|
|
94
|
+
AES.MODE_CBC,
|
|
95
|
+
IV=key_hash[:16]
|
|
96
|
+
)
|
|
97
|
+
plain = decryptor.decrypt(base64.b64decode(encrypted))
|
|
98
|
+
compressed = plain.decode("utf-8")
|
|
99
|
+
lz = lzstring.LZString()
|
|
100
|
+
decompressed = lz.decompressFromEncodedURIComponent(compressed)
|
|
101
|
+
return json.loads(decompressed)
|
|
102
|
+
|
|
103
|
+
def _should_decrypt(self, endpoint):
|
|
104
|
+
if not self.config.get("encrypted"):
|
|
105
|
+
return False
|
|
106
|
+
exclusions = self.UNENCRYPTED_ENDPOINTS.get(self.service,[])
|
|
107
|
+
endpoint = self._fixed_url(endpoint)
|
|
108
|
+
for item in exclusions:
|
|
109
|
+
if item.lower() in endpoint.lower():
|
|
110
|
+
return False
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
# RESPONSE
|
|
114
|
+
@staticmethod
|
|
115
|
+
def _error(code, message):
|
|
116
|
+
return {
|
|
117
|
+
"metaData": {
|
|
118
|
+
"code": code,
|
|
119
|
+
"message": message,
|
|
120
|
+
},
|
|
121
|
+
"response": None,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
def _parse_response(self, res, endpoint, timestamp):
|
|
125
|
+
if res.status_code == 404:
|
|
126
|
+
return self._error(404, "URL tidak ditemukan")
|
|
127
|
+
try:
|
|
128
|
+
body = res.json()
|
|
129
|
+
except ValueError:
|
|
130
|
+
return self._error(res.status_code,res.text)
|
|
131
|
+
|
|
132
|
+
metadata = (
|
|
133
|
+
body.get("metaData")
|
|
134
|
+
or body.get("metadata")
|
|
135
|
+
or {}
|
|
136
|
+
)
|
|
137
|
+
code = metadata.get("code", metadata.get("Code", res.status_code))
|
|
138
|
+
message = metadata.get("message", metadata.get("Message", ""))
|
|
139
|
+
try:
|
|
140
|
+
numeric_code = int(code)
|
|
141
|
+
except (TypeError, ValueError):
|
|
142
|
+
numeric_code = code
|
|
143
|
+
|
|
144
|
+
if numeric_code == 0:
|
|
145
|
+
return self._error(400, message)
|
|
146
|
+
|
|
147
|
+
response = body.get("response")
|
|
148
|
+
if response is None:
|
|
149
|
+
return {
|
|
150
|
+
"metaData": {
|
|
151
|
+
"code": code,
|
|
152
|
+
"message": message,
|
|
153
|
+
},
|
|
154
|
+
"response": None,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if self._should_decrypt(endpoint):
|
|
158
|
+
try:
|
|
159
|
+
response = self._decrypt(response, timestamp )
|
|
160
|
+
except Exception as e:
|
|
161
|
+
return self._error(500, f"Gagal decrypt response BPJS: {e}" )
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
"metaData": {
|
|
165
|
+
"code": code,
|
|
166
|
+
"message": message,
|
|
167
|
+
},
|
|
168
|
+
"response": response,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# REQUEST
|
|
172
|
+
def request(self, endpoint, method="GET", payload=None, timeout=30):
|
|
173
|
+
timestamp = self._timestamp()
|
|
174
|
+
url = self._build_url(endpoint)
|
|
175
|
+
headers = self._headers(timestamp)
|
|
176
|
+
method = method.upper()
|
|
177
|
+
try:
|
|
178
|
+
kwargs = {
|
|
179
|
+
"headers": headers,
|
|
180
|
+
"timeout": timeout,
|
|
181
|
+
}
|
|
182
|
+
if payload is not None:
|
|
183
|
+
kwargs["data"] = json.dumps(payload)
|
|
184
|
+
|
|
185
|
+
res = requests.request(method,url,**kwargs)
|
|
186
|
+
return self._parse_response(res,endpoint,timestamp)
|
|
187
|
+
|
|
188
|
+
except requests.exceptions.ConnectTimeout:
|
|
189
|
+
return self._error(504,"Koneksi ke BPJS timeout")
|
|
190
|
+
except requests.exceptions.ReadTimeout:
|
|
191
|
+
return self._error(504, "BPJS terlalu lama merespons")
|
|
192
|
+
except requests.exceptions.ConnectionError as e:
|
|
193
|
+
return self._error(503, f"Gagal terhubung ke BPJS: {e}" )
|
|
194
|
+
except requests.exceptions.RequestException as e:
|
|
195
|
+
return self._error(502, f"Request BPJS gagal: {e}")
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bpjs-bridging
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial Python client for BPJS Kesehatan API supporting VClaim, iCare, Antrean RS, and Aplicare.
|
|
5
|
+
Home-page: https://github.com/shiday1993/bpjs
|
|
6
|
+
Author: Syamsul
|
|
7
|
+
Author-email: shiday1993@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/shiday1993/bpjs/issues
|
|
10
|
+
Project-URL: Source Code, https://github.com/shiday1993/bpjs
|
|
11
|
+
Keywords: bpjs,vclaim,icare,antrean-rs,aplicare,jkn
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: lzstring
|
|
22
|
+
Requires-Dist: requests
|
|
23
|
+
Requires-Dist: pycryptodome
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: keywords
|
|
31
|
+
Dynamic: license
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
Dynamic: project-url
|
|
34
|
+
Dynamic: requires-dist
|
|
35
|
+
Dynamic: requires-python
|
|
36
|
+
Dynamic: summary
|
|
37
|
+
|
|
38
|
+
# BPJS Python Client
|
|
39
|
+
|
|
40
|
+
Unofficial Python client untuk integrasi API BPJS Kesehatan.
|
|
41
|
+
|
|
42
|
+
Library ini menyediakan interface sederhana untuk melakukan request ke beberapa layanan BPJS Kesehatan seperti **VClaim, iCare, Antrean RS, dan Aplicare**, termasuk pembuatan signature dan dekripsi response pada service yang membutuhkannya.
|
|
43
|
+
|
|
44
|
+
> Project ini bukan library resmi dari BPJS Kesehatan.
|
|
45
|
+
|
|
46
|
+
## Fitur
|
|
47
|
+
|
|
48
|
+
- Generate `X-Signature` menggunakan HMAC SHA-256
|
|
49
|
+
- Generate header autentikasi BPJS
|
|
50
|
+
- Dekripsi response terenkripsi menggunakan AES
|
|
51
|
+
- Dekompresi response menggunakan LZString
|
|
52
|
+
- Mendukung beberapa service:
|
|
53
|
+
- VClaim
|
|
54
|
+
- iCare
|
|
55
|
+
- Antrean RS
|
|
56
|
+
- Aplicare
|
|
57
|
+
- Interface request yang sama untuk setiap service
|
|
58
|
+
- Mendukung GET, POST, PUT, dan DELETE
|
|
59
|
+
- Normalisasi response BPJS
|
|
60
|
+
|
|
61
|
+
## Instalasi
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install bpjs-bridging
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> Nama package dapat berubah sebelum rilis resmi ke PyPI.
|
|
68
|
+
|
|
69
|
+
## Penggunaan
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from bpjs import Bridging
|
|
73
|
+
|
|
74
|
+
config = {
|
|
75
|
+
"consid": "your_consid",
|
|
76
|
+
"secret": "your_secret",
|
|
77
|
+
"user_key": "your_userkey",
|
|
78
|
+
"host": "base_url",
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
vclaim = Bridging(config, "vclaim")
|
|
82
|
+
|
|
83
|
+
response = vclaim.request("referensi/propinsi")
|
|
84
|
+
|
|
85
|
+
print(response)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### POST Request
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
payload = {
|
|
92
|
+
"param": "0000000000000",
|
|
93
|
+
"kodedokter": 123456,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
response = icare.request(
|
|
97
|
+
"api/rs/validate",
|
|
98
|
+
method="post",
|
|
99
|
+
payload=payload,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
print(response)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Service
|
|
106
|
+
|
|
107
|
+
Service ditentukan ketika membuat instance `Bridging`.
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
vclaim = Bridging(config, "vclaim")
|
|
111
|
+
icare = Bridging(config, "icare")
|
|
112
|
+
antrean = Bridging(config, "antrean")
|
|
113
|
+
aplicare = Bridging(config, "aplicare")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Setiap konfigurasi `config` membawa host service yang akan digunakan.
|
|
117
|
+
|
|
118
|
+
## Konfigurasi
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
config = {
|
|
122
|
+
"host": "SERVICE_HOST",
|
|
123
|
+
"consid": "consid",
|
|
124
|
+
"secret": "secret",
|
|
125
|
+
"user_key": "userkey",
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Jangan menyimpan credential BPJS secara langsung di source code pada aplikasi production. Gunakan environment variable atau mekanisme secret management lainnya.
|
|
130
|
+
|
|
131
|
+
## Credit
|
|
132
|
+
|
|
133
|
+
Implementasi awal mekanisme signature dan dekripsi response
|
|
134
|
+
dikembangkan berdasarkan:
|
|
135
|
+
|
|
136
|
+
[morizbebenk/pybpjs](https://github.com/morizbebenk/pybpjs)
|
|
137
|
+
|
|
138
|
+
Project ini kemudian direfaktor dan dikembangkan lebih lanjut
|
|
139
|
+
untuk mendukung beberapa service BPJS melalui interface berbasis class.
|
|
140
|
+
|
|
141
|
+
## Sumber Daya
|
|
142
|
+
- https://dvlp.bpjs-kesehatan.go.id:8888/trust-mark/portal.html
|
|
143
|
+
|
|
144
|
+
## Lisensi
|
|
145
|
+
- Aplikasi ini open source dengan lisensi [MIT](LICENSE).
|
|
146
|
+
|
|
147
|
+
## Disclaimer
|
|
148
|
+
|
|
149
|
+
Project ini merupakan library pihak ketiga dan tidak berafiliasi, didukung, atau dikelola oleh BPJS Kesehatan.
|
|
150
|
+
|
|
151
|
+
Pengguna bertanggung jawab atas penggunaan credential dan kepatuhan terhadap ketentuan API BPJS Kesehatan.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
src/bpjs/__init__.py
|
|
6
|
+
src/bpjs/bpjs.py
|
|
7
|
+
src/bpjs_bridging.egg-info/PKG-INFO
|
|
8
|
+
src/bpjs_bridging.egg-info/SOURCES.txt
|
|
9
|
+
src/bpjs_bridging.egg-info/dependency_links.txt
|
|
10
|
+
src/bpjs_bridging.egg-info/requires.txt
|
|
11
|
+
src/bpjs_bridging.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bpjs
|