Bridging INA-CBG5 SIMRS dengan visual basic 6 dan PHP (PART 1)

INA CBG EKLAIM
INA CBG EKLAIM

LAMAN TERKAIT

  1. Membuat Web Service PHP untuk jembatan ke Web Api INACBG
  2. Mengakses Web Service Jembatan
  3. Mengakses Web Service Jembatan dari Visual Basic 6

APLIKASI INA-CBG

INA-CBG merupakan singkatan dari Indonesia Case Base Groups. Aplikasi yang dikeluarkan oleh Kementrian Kesehatan ini digunakan Rumah Sakit untuk mengajukan klaim pada pemerintah. Dalam penentuan tarif INA-CBG menggunakan sistem paket berdasarkan penyakit yang diderita oleh pasien. Aplikasi INA-CBG akan menghasilkan kode INA-CBG berdasarkan diagnosa penyakit dan diagnosa tindakan pasien. Bisa diartikan juga Kode INA-CBG adalah kode kumpulan kelompok penyakit.Dengan INA-CBG, rumah sakit akan mendapatkan pembayaran rata-rata yang dihabiskan oleh suatu kelompok penyakit. 
Aplikasi INA-CBG dikembangkan dari sistem casemix UNU-IIGH (The United Nations University-International Institute for Global Health). Jadi sistem ini sudah digunakan oleh banyak negara juga.

Dulu aku sempat bingung dengan istilah-istilah di INA-CBG. Contohnya istilah ngoding. Ceritanya mas dodo tanya "Mas caranya batal final itu gimana?"  Karena aku orang baru disitu. Jangankan batal final, cara memfinal saja aku tidak tahu. Lha caranya memfinal gimana mas? tanyaku. Lalu dia jawab "Setelah selesai koding kan terus final mas". 
Aku sangat takjub dengan keahlian mas Dodo, ternyata selain ahli mengurusi berkas rekam medis, mas dodo ini pintar bahasa pemrograman. Aku saja yang sudah agak lama belajar ngoding tetap nggak bisa menata dokumen rekam medis (Kalau pun bisa juga percuma). "Ya udah mas, berarti tinggal di edit saja tho kodingannya" Jawabku polos. Rupanya dia sadar kalau aku salah arah, eh maksudnya gagal paham. Skip skip. 
Sekarang aku jelaskan arti kata ngoding, dan koder. Orang rekam medis yang memeriksa dan menginput kode diagnosa yang akan dimasukkan ke INA-CBG disebut koder. Proses memasukkan diagnosa ke aplikasi INA-CBG disebut ngoding. Jadi ngoder dan ngoding itu adalah istilah meramu diagnosa untuk mendapatkan hasil kode inacbg yang sesuai.

BRIDGING SIMRS

INA-CBG memberikan fasilitas Bridging dengan service SEP BPJS dan juga dengan SIMRS. untuk integrasi dengan server SEP BPJS cukup mudah. Kamu tinggal masukkan Cons-Id, Secret Key dan alamat web service SEP di tempat kamu dan cring. SEP dan INA-CBG akan langsung terkoneksi.

INA-CBG juga menyediakan service untuk bridging INA-CBG dengan SIMRS. untuk lebih detailnya bisa dibaca disini:
https://inacbg.kemkes.go.id/DL/Petunjuk_Teknis_Eklaim_Build_5.1.0.201703170645.pdf

Sebelum melakukan bridging, Rumah sakit disarankan membuat enkripsi key. Enkripsi key ini nantinya akan menjadi pengaman komunikasi data antara Aplikasi INA-CBG dengan Aplikasi SIMRS.

Untuk menggenerate enkripsi key, buka menu - Integrasi - SIMRS

laman integrasi simrs
Laman Integrasi SIMRS




Klik tombol "Generate Key" Untuk menggenerate kata kunci enkripsi. Klik "Yes" selanjutnya masukkan kode captha dan tralaaa Enkryption key kamu sudah jadi.

Mekanisme koneksi web service INA-CBG dengan SIMRS bisa kamu lihat di gambar ini:
Flow Koneksi SIMRS ke Web Service INA-CBG
Flow Koneksi SIMRS ke Web Service INA-CBG 

SIMRS mengirim data ke E-Klaim dengan method "POST". Permintaan/request dimasukkan di body post dengan format json yang terenkripsi. Setelah permintaan diproses oleh E-Klaim. E-Klaim akan memberikan hasil yang juga di enkripsi. Setelah data sampai di SIMRS, data akan dedecode menjadi json yang tidak terenkripsi.

Sederhana bukan? Kalau kamu pakai php itu menjadi sederhana sekali. Apalagi di Juknis sudah dicontohkan enkripsi dan dekripsinya. Namun berbeda kalau kamu memakai aplikasi lain. Kalau tidak salah enkripsi INA-CBG menggunakan enkripsi AES 256 bit. Kalau kamu tertarik untuk mengembangkan dengan aplikasi lain bisa kamu coba tuh.

Untuk mencoba memanggil servicenya, kamu bisa pakai aplikasi rest client kesukaanmu. Aku sendiri suka memakai Advanced Rest Client di Google Chrome.

Contoh Penggunaan Advanced Rest Client untuk memanggi service INA-CGB
Contoh Penggunaan Advanced Rest Client untuk memanggi service INA-CGB


Alamat web service bisa diakses di
     http://alamat_server_aplikasi/E-Klaim/ws.php
Untuk mode debug, kamu cukup menambahkan mode=debug
    http://alamat_server_aplikasi/E-Klaim/ws.php?mode=debug


Alamat Url:     http://localhost/E-Klaim/ws.php?mode=debug
Contoh Method/Request Buat Klaim Baru (Update Jika Sudah Ada)
    {
     "metadata": {
     "method": "new_claim"
      },
     "data": {
                  "nomor_kartu": "0000668870001",
                  "nomor_sep": "1710R01011160000249",
                   "nomor_rm": "123-45-67",
                   "nama_pasien": "NAMA TEST PASIEN",
                   "tgl_lahir": "1940-01-01 02:00:00",
                   "gender": "2"
                   }
        }

Kemudian Contoh hasilnya sepeti berikut

{
 "metadata": {
 "code": 200,
 "message": "Ok"
 },
 "response": {
 "patient_id": 453,
 "admission_id": 1,
 "hospital_admission_id": 678
 }
}

Pesan Error jika ada duplikasi data


{
 "metadata": {
 "code": 400,
 "message": "Duplikasi nomor SEP",
 "error_no": "E2007"
 },
 "duplicate": [
 {
 "nama_pasien": "TEST PASIEN",
 "nomor_rm": "3849988",
 "tgl_masuk": "2016-12-19 21:10:07"
 },
 {
 "nama_pasien": "TEST TEST",
 "nomor_rm": "3887726",
 "tgl_masuk": "2016-12-23 04:48:53"
 }
 ]
}

Mode Debug sangat tidak direkomendasikan dan hanya digunakan untuk testing saja. 

Salah satu tujuanku menulis tentang artikel ini juga supaya teman-teman yang kesulitan di Enkripsi dan memakai mode debug di web service INA-CBG. 
Karena mode ini bisa sewaktu-waktu dihapus dari Service INA-CBG. 

Seperti yang tak bold diatas, tujuan artikel ini agar teman-teman sesama pengoding aplikasi bridging INA-CBG SIMRS tidak terbuai dengan manisnya mode debug. Karena aplikasi SIMRS memakai pihak ke-3 untuk terhubung dengan Web Service INA-CBG. Trus kelebihan memakai pihak ketiga itu apa? Kalau tidak cocok tinggal ganti CV aja, gitu aja kok repot.

Untuk daftar servicenya bisa kamu lihat di pdf yang sudah aku kasih linknya diatas. Beberapa web service yang penting untuk adalah web service yang berhubungan dengan input klaim, seperti:

  1. Membuat Klaim Baru
  2. Mengisi/Update Data Klaim
  3. Grouping Stage1
  4. Grouping Stage2
  5. Final
  6. Mengedit Ulang Klaim
6 service itu dulu, kalau dijalankan dengan istiqomah Insya Allah bridgingnya lancar.
PENDAHULUAN

Sebelum maju ke teknik koding, aku ceritakan dulu prinsip kerja bridging INA-CBG SIMRS yang aku pakai. Kalau boleh cerita. Awal ide ini karena aku sendiri merasa kesulitan dengan koneksi ke web service INA-CBG dengan Aplikasi Visual Basic 6. Kesulitan pertama, karena output keluarannya JSON. JSON itu keluarnya kapan. Visual Basic 6 Keluarnya kapan? Perlu teman-teman ketahui, Visual Basic 6 keluar sekitar tahun 1998 dan sekarang adalah tahun 2017. Mantab sekali. 

ALAT PERTAMA YANG DIBUTUHKAN ADALAH JSON PARSER
Apa itu Json Parse, Json parser adalah alat untuk merubah format JSON menjadi format yang dimengerti oleh aki-aki kayak mbah Visual Basic 6 ini. Sebelumnya pengen bikin sendiri. Tapi ilmu belum mumpuni, akhirnya googling aja deh :P. Alhamdulilah wa Syukurilah aku menemukan JSON PARSE yang mudah dan powerfull buat aku. Namanya VBJSON. Silahkan download di situs resminya:


ALAT KEDUA ADALAH WEB SERVER

JSON Parsernya sudah ketemu. Sekarang saatnya mencari kesulitan kedua. Alat keduaku adalah web server. Untuk web server aku rekomendasikan xampp, selain populer, xampp juga mudah dioperasikan.

Btw, kenapa alat keduanya web server?
Pada juknis bridging inacbg simrs kita diwajibkan memakai enkripsi. Kslau tidak salah inacbg menggunakan Enkripsi AES 256. Ngomong-ngomong tentang enkripsi aku jadi ingat sewaktu mendevelop Bridging SEP. Waktu itu aku sudah menemukan cara enkripsi HMAC SHA-1 di Visual Basic 6. Tetapi sayang, ternyata Enkrypsinya hanya bisa berjalan di Windows 7 ke-atas. Padahal ditempatku masih banyak yang pakai Windows XP. Lagi pula aplikasi simrs tempatku harus berjslan di compability mode Windows XP, soalnya Crystal Reportnya bakal ngambek.
Visual Basic 6 + Crystal Report 8.5, mereka memang romantis. Cinta mereka tak tergerus oleh zaman.

Dengan berbagai pertimbangan yang tidak matang. Maka aku memutuskan untuk memakai web service sebagai jembatan antara mereka (Visual Basic 6 dan API INA-CBG).

Memilih Framework PHP

Biar kekinian, aku sengaja nggak koding native untuk PHPnya. Setelah mencoba mencari-cari framework yang kekinian. CI, Laravel, Cake PHP, ternyata nggak ada yang cocok. Nggak ada yang cocok apa akunya yang nggak bisa ya? Mungkin semuanya benar.
Setelah lama memilih akhirnya aku memakai Slim Micro Framework. Kenapa memakai SLIM Micro Framework? Karena kesederhannannya. Saking sederhananya (cuma bisa untuk membuat REST). Slim bukan hanya kecil dan cepat, tetapi juga mudah dipelajari.
Buat yang kepo sama SLIM Micro Framework bisa meluncur kesini:

Slim Micro Framework
https://www.slimframework.com/

Lets Code!

MEMBUAT WEB SERVICE

Download SLIM Micro Framework.
Struktur file SLIM Micro Framework seperti gambar berikut.

Isi Folder SLIM MICRO FRAMEWORK (minus db.phpya,  itu file buatanku)
Isi Folder SLIM MICRO FRAMEWORK (minus db.phpya,  itu file buatanku)

Buat file konfigurasi. Sebagai contoh buat file db.php di folder utama SLIM micro Framework
Isi File konfigurasi db.php adalah seperti berikut:

<?php

function getKey() {
   $keyRS = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";   //Kunci Enkripsi Dari Eklaim
   return $keyRS;
}

function getUrlWS() {
    $UrlWS = "http://192.168.100.100/E-Klaim/ws.php";                         //IP SERVER EKLAIM
    return $UrlWS;
}

?>

Setelah file konfigurasinya disimpan. Sekarang kita buat file utamanya. Masukkan Koding ini ke file Index.php.
Di file Index.php semua fungsi bridging dimasukkan kesini. Aku sengaja memakai method "Post" pada web service penghubung ini, supaya koding pengiriman datanya lebih mudah.

<?php
require 'vendor/autoload.php';
require 'db.php';
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\App;


$app = new Slim\App();


$app->get('/', 'Depan');
$app->post('/test', 'test');
$app->post('/BuatKlaimBaru', 'BuatKlaimBaru');
$app->post('/IsiDataKlaim', 'IsiDataKlaim');
$app->post('/AmbilDataKlaim', 'AmbilDataKlaim');
$app->post('/Grouper1', 'Grouper1');
$app->post('/Grouper2', 'Grouper2');
$app->post('/FinalKlaim', 'FinalKlaim');
$app->post('/KirimOnline', 'KirimOnline');
$app->post('/EditFinal', 'EditFinal');


$app->run();


/* METHOD GET DISINI */
/* ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
function Depan() {
  echo "Halaman Depan";
}

Function BuatKlaimBaru($request, $response, $args) {  
  
    $json = '{
   "metadata":{
      "method":"new_claim"
   },
   "data":{
      "nomor_kartu":"'.$request->getParsedBody()['nokartu'].'",
      "nomor_sep":"'.$request->getParsedBody()['nosep'].'",
      "nomor_rm":"'.$request->getParsedBody()['norm'].'",
      "nama_pasien":"'.$request->getParsedBody()['namapasien'].'",
      "tgl_lahir":"'.$request->getParsedBody()['tgllahir'].'",
      "gender":"'.$request->getParsedBody()['jeniskelamin'].'"
    }}';



    $json = mc_encrypt ($json, getKey());

    $ch = curl_init(getUrlWS());  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);

    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  


    $response->write($result);  
    return $response;  
}
Function IsiDataKlaim($request, $response, $args) {  
    $nosep = $request->getParsedBody()['nosep'];
    $nokartu = $request->getParsedBody()['nokartu'];
    $tgl_masuk=$request->getParsedBody()['tgl_masuk'];
    $tgl_pulang=$request->getParsedBody()['tgl_pulang'];
    $jenis_rawat=$request->getParsedBody()['jenis_rawat'];
    $kelas_rawat=$request->getParsedBody()['kelas_rawat'];
    $adl_sub_acute=$request->getParsedBody()['adl_sub_acute'];
    $adl_chronic=$request->getParsedBody()['adl_chronic'];
    $icu_indicator=$request->getParsedBody()['icu_indicator'];
    $icu_los=$request->getParsedBody()['icu_los'];
    $ventilator_hour=$request->getParsedBody()['ventilator_hour'];
    $upgrade_class_ind=$request->getParsedBody()['upgrade_class_ind'];
    $upgrade_class_class=$request->getParsedBody()['upgrade_class_class'];
    $upgrade_class_los=$request->getParsedBody()['upgrade_class_los'];
    $birth_weight=$request->getParsedBody()['birth_weight'];
    $discharge_status=$request->getParsedBody()['discharge_status'];
    $diagnosa=$request->getParsedBody()['diagnosa'];
    $procedure=$request->getParsedBody()['procedure'];
    $tarif_rs=$request->getParsedBody()['tarif_rs'];
    $tarif_poli_eks=$request->getParsedBody()['tarif_poli_eks'];
    $nama_dokter=$request->getParsedBody()['nama_dokter'];
    $kode_tarif=$request->getParsedBody()['kode_tarif'];
    $payor_id=$request->getParsedBody()['payor_id'];
    $payor_cd=$request->getParsedBody()['payor_cd'];
    $coder_nik=$request->getParsedBody()['coder_nik'];
  
  
  
    $json = '{
   "metadata":{
      "method":"set_claim_data",
      "nomor_sep":"'.$nosep.'"
   },
   "data":{
      "nomor_sep":"'.$nosep.'",
      "nomor_kartu":"'.$nokartu.'",
      "tgl_masuk":"'.$tgl_masuk.'",
      "tgl_pulang":"'.$tgl_pulang.'",
      "jenis_rawat":"'.$jenis_rawat.'",
      "kelas_rawat":"'.$kelas_rawat.'",
      "adl_sub_acute":"'.$adl_sub_acute.'",
      "adl_chronic":"'.$adl_chronic.'",
      "icu_indikator":"'.$icu_indicator.'",
      "icu_los":"'.$icu_los.'",
      "ventilator_hour":"'.$ventilator_hour.'",
      "upgrade_class_ind":"'.$upgrade_class_ind.'",
      "upgrade_class_class":"'.$upgrade_class_class.'",
      "upgrade_class_los":"'.$upgrade_class_los.'",
      "birth_weight":"'.$birth_weight.'",
      "discharge_status":"'.$discharge_status.'",
      "diagnosa":"'.$diagnosa.'",
      "procedure":"'.$procedure.'",
      "tarif_rs":"'.$tarif_rs.'",
      "tarif_poli_eks":"'.$tarif_poli_eks.'",
      "nama_dokter":"'.$nama_dokter.'",
      "kode_tarif":"'.$kode_tarif.'",
      "payor_id":"'.$payor_id.'",
      "payor_cd":"'.$payor_cd.'",
      "coder_nik":"'.$coder_nik.'"
   }
}';
   //print_r($json);
    $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);          


  

    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  

    return $response;
}

Function Grouper1($request, $response, $args) {  
    $special_cmg_list = '';
    $nosep = $request->getParsedBody()['nosep'];
    $json = '{
   "metadata":{
      "method":"grouper",
      "stage":"1"
   },
   "data":{
      "nomor_sep":"'.$nosep.'"
   }
}'; 
  
  
    $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    curl_close($ch);

    $hasil = substr ($result, 29, strlen ($result));
    $hasil = substr ($hasil, 0,-28);
    $resultDec = mc_decrypt (getKey(), $hasil);
    $result = $resultDec;
  

    $decode = json_decode($result, true);
    //print_r($decode);
    if (!array_key_exists('special_cmg_option', $decode)){
        $status = array('special_cmg'=>'false');      
    }else{
        $status = array('special_cmg'=>'true');
    }
  
    if (!array_key_exists('sub_acute', $decode)){
        $status1 = array('sub_acute'=>'false');      
    }else{
        $status1 = array('sub_acute'=>'true');
    }
  
    if (!array_key_exists('chronic', $decode)){
        $status2 = array('chronic'=>'false');      
    }else{
        $status2 = array('chronic'=>'true');
    }
  
    $arr1 = array_merge ($status1, $status2);
    $arr2 = array_merge($arr1, $status);
    $data = json_decode ($result, true);
    $result = array_merge($data, $arr2);
    $response->write(json_encode($result));

    return $response;  
}

Function Grouper2($request, $response, $args) {      
    $nosep = $request->getParsedBody()['nosep'];
    $Specialcmg = $request->getParsedBody()['special_cmg'];
  
    $json = '{
   "metadata":{
      "method":"grouper",
      "stage":"2"
   },
   "data":{
      "nomor_sep":"'.$nosep.'",
      "special_cmg":"'.$Specialcmg.'"
   }}';
 
  
       $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());

  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);
    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  
    return $response;
}

Function FinalKlaim($request, $response, $args) {  
    $nosep = $request->getParsedBody()['nosep'];
    $coder_nik= $request->getParsedBody()['coder_nik'];
  
    $json = '{
   "metadata":{
      "method":"claim_final"
   },
   "data":{
      "nomor_sep":"'.$nosep.'",
      "coder_nik":"'.$coder_nik.'"
   }
}';
    $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());
  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);  

    //$result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    //$result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    //$result = mc_decrypt (getKey(), $result);              
   // $response->write($result);  
  


   $json = '{
     "metadata": {
      "method":"send_claim_individual"
     },
     "data": {
     "nomor_sep":"'.$nosep.'"
     }
    }';


    $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());
  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);
    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  

    $sql = "Update DetailBridgingBPJS set KirimPusatData = 1 where NoSJP = '".$nosep."'";
    $db = getConnectionSQL();
    $stmt=$db->prepare($sql);
    $stmt->execute();
    echo $sql;
    return $response;  


  
  
}

Function KirimOnline($request, $response, $args) {  
    $nosep = $request->getParsedBody()['nosep'];

$json = '{
 "metadata": {
 "method":"send_claim_individual"
 },
 "data": {
 "nomor_sep":"'.$nosep.'"
 }
}';


    $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());
 

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);
    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  
    return $response;  
}






Function EditFinal($request, $response, $args) {  
    $nosep = $request->getParsedBody()['nosep'];  
  
    $json = '{
            "metadata": {
            "method":"reedit_claim"
            },
            "data": {
            "nomor_sep":"' .$nosep.'"
            }
        }';
      
 
  
    $json = mc_encrypt ($json, getKey());
    $ch = curl_init(getUrlWS());
  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);
    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  
}

Function AmbilDataKlaim($request, $response, $args) {  


    $json = '{
 "metadata": {
 "method":"pull_claim"
 },
 "data": {
 "start_dt":"'.$request->getParsedBody()['stat_dt'].'",
 "stop_dt":"'.$request->getParsedBody()['stop_dt'].'",
 "jenis_rawat":"'.$request->getParsedBody()['jenis'].'"
 }
}';
  
    $json = mc_encrypt ($json, getKey());

    $ch = curl_init(getUrlWS());  
  

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    curl_close($ch);


    if ($request->getParsedBody()['krip'] == 'true') {
    $result = str_replace ('----BEGIN ENCRYPTED DATA----', '', $result);
    $result = str_replace ('----END ENCRYPTED DATA----', '', $result);
    $result = mc_decrypt (getKey(), $result);              
    $response->write($result);  
    }else{$response->write($result);}
    return $response;  
}



function mc_encrypt($data, $key) {
$key = hex2bin($key);
if (mb_strlen($key, "8bit") !== 32) {
throw new Exception("Needs a 256-bit key!");

}
$iv_size = openssl_cipher_iv_length("aes-256-cbc");

$iv = openssl_random_pseudo_bytes($iv_size);
$encrypted = openssl_encrypt($data,"aes-256-cbc",$key,OPENSSL_RAW_DATA,$iv );

$signature = mb_substr(hash_hmac("sha256",$encrypted,$key,true),0,10,"8bit");
$encoded = chunk_split(base64_encode($signature.$iv.$encrypted));
return $encoded;
}

function mc_decrypt($strkey, $str) {
$key = hex2bin($strkey);

///    check key length, must be 256 bit or 32 bytes
if (mb_strlen($key, "8bit") !== 32) {
throw new Exception("Needs a 256-bit key!");
}


$iv_size = openssl_cipher_iv_length("aes-256-cbc");
$decoded = base64_decode($str);
$signature = mb_substr($decoded,0,10,"8bit");
$iv = mb_substr($decoded,10,$iv_size,"8bit");
$encrypted = mb_substr($decoded,$iv_size+10,NULL,"8bit");
$calc_signature = mb_substr(hash_hmac("sha256",$encrypted,$key,true),0,10,"8bit");
if(!mc_compare($signature,$calc_signature)) {
return "SIGNATURE_NOT_MATCH"; /// signature doesn't match
}

$decrypted = openssl_decrypt($encrypted,"aes-256-cbc",$key,OPENSSL_RAW_DATA,$iv);
return $decrypted;
}

///    Compare Function
function mc_compare($a, $b) {

///    compare individually to prevent timing attacks

///    compare length

if (strlen($a) !== strlen($b)) return false;

///    compare individual
$result = 0;

for($i = 0; $i < strlen($a); $i ++) { $result |= ord($a[$i]) ^ ord($b[$i]);
}

return $result == 0;
}

function Cari_Special_Prosthesis($array, $field, $value)
{
   foreach($array as $key => $array)
   {
      if ( $array[$field] === $value )
         return $key;
   }
   return false;
}

?>

Setelah semua kamu kopi paste ke Index.php. Berarti bridging kamu sudah jadi. untuk menggunakannya kamu tinggal panggil dari Advanced Rest Client.
Cara manggilnya seperti ini:

Method : BuatKlaimBaru
Url: http://localhost/BridgingINACBG/BuatKlaimBaru
Post Header: Content-Type:application/x-www-form-urlencoded
Body Post: nokartu=xxxxxxxxxx&nosep=xxxxxxxxxx&norm=xxxxxx&namapasien=xxxxxx&tgllahir=yyyy/MM/dd&jeniskelamin=1

Nanti Responsenya seperti ini:
{ "metadata": { "code": 200, "message": "Ok" }, "response": { "patient_id": 453, "admission_id": 1, "hospital_admission_id": 678 } }


Sekian dahulu tehnik Bridging INACBG-SIMRS dengan Visual Basic 6 dan PHP. Sebenarnya ini hanya prototype karena masih beberapa service saja yang aku buat. Untuk service lainnya bisa kalian teruskan sendiri. Karena aku juga belum sempat buat. Selamat Koding. Semoga sample source ini bermanfaat buat teman-teman.

Kalau butuh file yang sudah jadi japri saja. Jangan lupa kasih nama dan dari Rumah Sakit mana.

Ada yang kelupaan, Untuk Web Service yang sudah jadi bisa download disini
https://drive.google.com/file/d/0B1NbkNRwjYEya19YcFd5RmQzMk0/view?usp=sharing


Web Service Penghubung INACBG


LANJUT PART 2 Mengakses Web Service Jembatan











36 comments for "Bridging INA-CBG5 SIMRS dengan visual basic 6 dan PHP (PART 1)"

  1. Kereeeen.. Tapi aku horaaa mudeng :D

    Btw, dari aku kok ada yg lompat pakai saya ya.. :)

    Istiqomah pak, pake yang mana, hehe.

    ReplyDelete
  2. Nyoba belajar VB gan,

    ijin donload scrib

    trimakasih

    ReplyDelete
    Replies
    1. silahkan pak, semoga bermanfaat, jangan malu bertanya, siapa tahu saya bisa menjawab

      Delete
  3. gan kalau enkripsi langsung tanpa web service bisa? bisa di share source code nya?

    ReplyDelete
    Replies
    1. kalau pakai .net bisa mas, kalau vb6 sepertinya tidak bisa, FYI enkripsinya pakai AES 128 dengan vektor

      Delete
  4. mas bro... link "https://inacbg.kemkes.go.id/DL/Petunjuk_Teknis_Eklaim_Build_5.1.0.201703170645.pdf" dah gak ada ya?? barangkali mas bro punya pdf nya, bisa dishare dong.. thanks

    ReplyDelete
    Replies
    1. ini yang terbaru pak, silahkan diunduh https://inacbg.kemkes.go.id/DL/Petunjuk_Teknis_Eklaim_5.1.1.201705010501.pdf

      Delete
  5. Mas.. web service integrasi VB.net dengan inacbgs bisa di share

    ReplyDelete
    Replies
    1. Dari vb.net bisa langsung mas, nggak usah pakai web service penengah seperti vb6, tp sy belum punya kodenya, kapan2 kalau sempat research pst aku upload

      Delete
    2. Saya Coba Responsenya malah Kosong...Knp ya?

      Delete
  6. MAs kok saya keluarnya masih terencrypt yah?

    ReplyDelete
    Replies
    1. Masak mas, kalau keluarnya masih encrypt harusnya error gagal decrypt

      Delete
  7. Saya nyoba mas, response : SIGNATURE_NOT_MATCHSIGNATURE_NOT_MATCH
    Knapa ya??
    btw terimakasih script nya..

    ReplyDelete
    Replies
    1. Setelah di teliti, ternyata Response nya kosong (No Text) :D..
      Kenapa ya? apa ada yg berubah...

      tp sy ga ngerubah apa2 sih... :D

      Delete
    2. Signature keynya sudah digenerate belum, jangan lupa diset di file db.php, trus transaksi yg buat sample harus setelah november 2016

      Delete
    3. Sudah pak.. dan sudah di set di db.php juga...
      dan dicoba data sep bulan okt'17..

      hasilnya masih sama, response nya kosong + pesan error "SIGNATURE_NOT_MATCH"

      Mohon Pencerahannya.. :)

      Trmksh

      Delete
    4. Coba kirim source codenya ke saya mas, vbcupu@gmail.com

      Delete
    5. Sudah saya email mas source code nya..

      oia, btw, saya masih berkutat di aplikasi bridging nya mas, yg PHP, pengetesan menggunakan Advance Rest Client masih belum mendapat respone (kosong).. dengan pesan error "SIGNATURE_NOT_MATCH"..

      demikian mas..

      Trmksh..

      Salam.

      Delete
  8. Sudah saya email mas source code nya..

    oia, btw, saya masih berkutat di aplikasi bridging nya mas, yg PHP, pengetesan menggunakan Advance Rest Client masih belum mendapat respone (kosong).. dengan pesan error "SIGNATURE_NOT_MATCH"..

    demikian mas..

    Trmksh..

    Salam.

    ReplyDelete
    Replies
    1. signature not match kemungkinan karena data signature di file db.php tidak sama dengan signaturekey yang mas riedan generate di aplikasi eklaim

      Delete
  9. Mas kalo mau ngisi Special Drug nya gimana ya...?

    ReplyDelete
    Replies
    1. Di grouper tahap 2 mas, waktu menjalankan grouper 1, kalau ditemukan special cmd, nanti keluar pilihan special cmdnya. Kalau ada special cmdnya, special cmd dimasukkan di grouper 2

      Delete
  10. Mantab pak
    Izin porting ke python 3.selama ini saya pakai python untuk bridgenya. Menyederhanakan kerepotan urus ini itu. Aplikasi jadi standalone dengan size 5 sd 8MB saja 😀
    Memang yang inacbg lebih merepotkan daripada bpjs 😥

    ReplyDelete
    Replies
    1. Siap, silahkan pak. Mantab nih, kayaknya baru 2 kali ini sy ketemu programmer python

      Delete
  11. Mas, mau nanya.
    Waktu proses group di aplikasi E-Klaim, dibagian hasil grouper, yg keluar FAILED: EMPTY RESULT

    Itu kenapa ya mas?

    ReplyDelete
    Replies
    1. Sudah coba pakai diagnosa yg lain atau setiap grouping hasilnya seperti itu?

      Delete
    2. Sudah mas, hasil nya tetap sama aja.
      Saya juga sudah baca di panduan e-klaim nya, tidak ada mas.

      Delete
    3. Mungkin ada mslh dengan parameter lainya mas. Seperti umur, jk dll

      Delete
  12. mas nanya klo dari katalog copy-paste, terus misalkan dibuat :

    $enc = inacbg_encrypt("RAHASIA", "123");
    $data = inacbg_decrypt($enc,"123");

    untuk $data itu apakah muncul RAHASIA, soalnya saya coba SIGNATURE_NOT_MATCH

    ReplyDelete
    Replies
    1. Di file db.php, function get key, api keynya diisi sesuai dengan aplikasi eklaim

      Delete
  13. Coba di check di function getKey() yg ada di file db.php mas.
    Disesuaikan dulu sama key yg di dapat dari aplikasi.

    ReplyDelete
  14. untuk link nya bisa dikirim by email bang?

    ReplyDelete
    Replies
    1. baca artikelnya sampai habis mas, itu ada link gdrivenya

      Delete

Post a Comment