- Sekilas Tentang Universal REST Simulator
- File Manager
- Check Path
- File Konfigurasi
- Simulator Sederhana GET application/x-www-form-urlencoded
- Simulator Sederhana POST application/x-www-form-urlencoded
- Simulator Sederhana PUT application/x-www-form-urlencoded
- Simulator Sederhana POST application/json
- Simulator Sederhana PUT application/json
- Simulator Sederhana POST application/xml
- Simulator Sederhana PUT application/xml
- Simulator Sederhana POST application/soap+xml
- Simulator Sederhana PUT application/soap+xml
- Kombinasi GET dan POST
- Kombinasi GET dan PUT
- Simulator Sederhana Input dari URL
- Simulator Sederhana Input dari Header
- Simulator Sederhana Input dari Basic Authorization
- Simulator Sederhana System UUID
- Simulator Sederhana Input Array
- Simulator Sederhana Input Object dan Array
- HTTP Status Standard
- HTTP Status Non-Standard
- Membuat Token
- Memvalidasi Token
- Membuat Callback
- Menggunakan Delay
- Fungsi $DATE()
- Fungsi $CALC()
- Fungsi $ISVALIDTOKEN()
- Fungsi $NUMBERFORMAT()
- Fungsi $SYSTEM.RANDOM()
- Fungsi $JSON.REQUEST()
- Kode PHP Natif
Universal REST Simulator adalah simulator REST untuk membuat simulator server aplikasi. Simulator ini akan mensimulasikan respon dari sebuah sistem saat diberi request tertentu. Universal REST Simulator menggunakan protokol HTTP dengan method GET, POST dan PUT dengan tipe request x-www-form-urlencode, JSON dan XML. Tipe respon dapat berupa text, HTML, XML, JSON maupun CSV.
Sebenarnya simulator REST hanya perlu memberikan respon sesuai dengan request yang diberikan. Akan tetapi, jika aplikasi harus mengolah kembali respon dari simulator untuk proses berikutnya, maka diperlukan sebuah proses pada simulator yang dapat memberikan respon sesuai dengan yang diharapkan.
Universal REST Simulator mengambil input dari request klien melalui beberapa cara yaitu sebagai berikut:
$HEADERyaitu request header dengan nama header yang eksplisit.$AUTHORIZATION_BASICyaitu username dan password pada basic authentication.$URLyaitu nilai yang cocok dari pola URL dengan membandingkan antara URL pada file konfigurasi dengan URL pada request dari klien.$GETyaitu nilai yang diambil dari parameter yang dikirimkan melalui URL dengan pengkodeanx-www-form-urlencode.$POSTyaitu nilai yang diambil dari body request dengan methodPOSTdengan pengkodeanx-www-form-urlencode.$PUTyaitu nilai yang diambil dari body request dengan methodPUTdengan pengkodeanx-www-form-urlencode.$REQUESTtergantung dari method yang digunakan pada file konfigurasi. Berbeda dengan$GET,$PUTdan$POSTyang hanya mendukungx-www-form-urlencode,$REQUESTmendukung content typex-www-form-urlencode,application/jsondanapplication/xmlbaik objek maupun array.$JSON.REQUESTmengambil JSON dari requestPOSTdanPUT. Data yang diambil dapat berupaJSON objectmaupunstringtergantung dari parameter yang dimasukkan.
Selain input dari klien, Universal REST Simulator juga dapat membuat data dari sistem seperti $SYSTEM.RANDOM(), $DATE(), $SYSTEM.UUID dan lain-lain. Universal REST Simulator juga dapat membuat dan memvalidasi JWT atau JSON Web Token.
Output dari Universal REST Simulator adalah HTTP Status, header respon dan body respon.
Universal REST Simulator dilengkapi dengan callback sehingga dapat mengirimkan request ke endpoint tertentu dengan kondisi tertentu sesuai dengan konfigurasi yang dibuat. Pengguna juga dapat mengatur request time out callback.
Universal REST Simulator berbasis PHP dan server Apache. Dengan demikian, Universal REST Simulator bahkan dapat berjalan pada shared hosting dengan paket yang sangat minim sekalipun.
Salah satu fitur penting pada Universal REST Simulator adalah file manager. File manager pada Universal REST Simulator digunakan untuk membuat, mengubah dan mengatur file konfigurasi simulator. Untuk dapat membuat dan mengatur file konfigurasi simulator, pengguna harus login ke file manager. Username dan password pengguna disimpan dalam file .htpasswd yang disimpan di direktori filemanager di dalam direktori simulator.
Untuk mengakses file manager, buka Universal REST Simulator dengan menggunakan browser web dan masukkan path /filemanager/ relatif terhadap path Universal REST Simulator.
Universal REST Simulator menyediakan alat untuk membuat file login ke File Manager.
Link: File Manager
Check path digunakan untuk melihat path dan method yang ada pada semua file konfigurasi. Tujuan dari check path adalah sebagai berikut:
- menghindari konflik path dan method
- memudahkan dalam pencarian file konfigurasi untuk keperluan perubahan dan pembaruan
- jalan pintas untuk mengubah dan memperbarui file konfigurasi
Untuk mengakses check path, buka Universal REST Simulator dengan menggunakan browser web dan masukkan path /checkpath/ relatif terhadap path Universal REST Simulator.
Link: Check Path
Konfigurasi simulator diatur oleh file-file yang disimpan di dalam direktori /config relatif terhadap direktori Universal REST Simulator. Working directory file manager adalah /config sehingga pengguna cukup membuat file konfigurasi pada base directory tanpa memasukkannya ke dalam direktori lagi.
[root]
[config]
config1.ini
config2.ini
config3.iniFile yang berada di dalam direktori (tidak di base directory) tidak akan dibaca oleh simulator. Dengan demikian, apabila pengguna ingin mengarsipkan konfigurasi yang sudah tidak digunakan lagi cukup membuat sebuah direktori dan memasukkan file-file konfigurasi yang tidak digunakan ke dalam direktori tersebut.
Jika Universal REST Simulator dijalankan di dalam Docker atau container sejenis, sangat disarankan untuk melakukan binding direktori sehingga file-file konfigurasi berada di luar container. Hal ini bertujuan untuk mencegah file konfigurasi hilang saat melakukan update atau restart service. Penggunaan volumes pada Docker juga dapat dilakukan untuk tujuan ini.
Pada saat simulator menerima request dari klien, simulator akan mencari file konfigurasi yang cocok dengan method dan path dari request yang diterima. Apabila simulator menemukan file yang sesuai, maka simulator akan berhenti mencari file dan menggunakan konfigurasi pada file yang tersebut. File konfigurasi yang tidak dapat diparsing dengan benar akan diabaikan dan tidak akan menyebabkan kerusakan pada simulator.
File konfigurasi Universal REST Simulator dapat memiliki ekstensi apapun. Akan tetapi, untuk memudahkan penulisan, disarankan menggunakan ekstensi .ini.
Atribut utama dari file konfigurasi adalah sebagai berikut:
- METHOD
- PATH
- REQUETS_TYPE
- RESPONSE_TYPE
- PARSING_RULE
- TRANSACTION_RULE
METHOD
Method adalah metode request dari klien. Method ini secara eksplisit sama antara file konfigurasi dengan request dari klien.
Contoh:
METHOD=POSTPATH
Path adalah path yang diakses oleh klien. Path ini bersifat relatif.
Contoh:
PATH=/core/admin/add-accountDalam beberapa kondisi mungkin membutuhkan path yang sama persis namun dalam kondisi yang lain hanya memerlukan kecocokan pola.
Path juga dapat berisi input dari klien. Dengan demikian, path request yang berbeda mungkin akan menjalankan proses yang sama.
Contoh:
PATH=/core/{[GROUP]}/{[TRANSACTION]}REQUEST_TYPE
Request type adalah content type dari request yang dikirimkan oleh klien. Content type request akan menentukan bagaimaka cara simulator memparsing request dari klien. Ketidaksesuaian antara request type pada konfigurasi dengan content type yang dikirimkan akan menyebabkan data tidak dapat diparsing sama sekali.
Content type yang didukung adalah sebagai berikut:
application/x-www-form-urlencodeduntuk methodGET,POSTdanPUTapplication/xmluntuk methodPOSTdanPUTapplication/jsonuntuk methodPOSTdanPUT
RESPONSE_TYPE
Response type adalah content type respon yang dikirimkan ke klien. Content type ini akan diinformasikan melalui header respon Content-type. Content type ini mengabaikan header request Accept yang dikirimkan oleh klien. Apabila pengguna ingin menggunakan nilai pada header request Accept, pengguna dapat membuat kondisi dengan terlebih dahulu mengambil nilai Accept pada parsing rule sebagai berikut:
PARSING_RULE=\
$INPUT.ACCEPT=$HEADER.ACCEPTKemudian menambahkan kondisi $INPUT.ACCEPT pada transaction rule.
Content type yang didukung lebih luas meskipun terbatas pada content type text misalnya sebagai berikut:
text/plantext/htmlapplication/csvapplication/xmlapplication/json
PARSING_RULE
Parsing rule digunakan untuk memparsing request dari klien. Sumber data yang digunakan antara lain adalah sebagai berikut:
$HEADERyaitu request header dengan nama header yang eksplisit$AUTHORIZATION_BASICyaitu username dan password pada basic authentication$URLyaitu nilai yang cocok dari pola URL dengan membandingkan antara URL pada file konfigurasi dengan URL pada request dari klien$GETyaitu nilai yang diambil dari parameter yang dikirimkan melalui URL dengan pengkodeanx-www-form-urlencode$POSTyaitu nilai yang diambil dari body request dengan methodPOSTdengan pengkodeanx-www-form-urlencode$PUTyaitu nilai yang diambil dari body request dengan methodPUTdengan pengkodeanx-www-form-urlencode$REQUESTyaitu alternatif dari$GET,$POSTdan$PUTtergantung dari method yang digunakan pada file konfigurasi. Berbeda dengan$GET,$PUTdan$POSTyang hanya mendukungx-www-form-urlencode,$REQUESTmendukung content typex-www-form-urlencode, JSON dan XML baik objek maupun array.
Matriks input ditampilkan pada tabel berikut:
| Method | Content Tpe | Data Source | Alternative Object |
|---|---|---|---|
GET |
applicatiom/x-www-form-urlencoded |
Header, URL, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
POST |
applicatiom/x-www-form-urlencoded |
Header, URL, Body, Basic Authorization, GET, POST |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET, $POST |
POST |
applicatiom/json |
Header, URL, Body, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
POST |
applicatiom/xml |
Header, URL, Body, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
POST |
applicatiom/soap+xml |
Header, URL, Body, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
PUT |
applicatiom/x-www-form-urlencoded |
Header, URL, Body, Basic Authorization, GET, PUT |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET, $PUT |
PUT |
applicatiom/json |
Header, URL, Body, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
PUT |
applicatiom/xml |
Header, URL, Body, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
PUT |
applicatiom/soap+xml |
Header, URL, Body, Basic Authorization, GET |
$HEADER, $URL, $REQUEST, $AUTHORIZATION_BASIC, $GET |
Nilai yang diambil dari request disimpan pada variabel yang diawali dengan $INPUT. dan diikuti dengan nama unik dari variabel tersebut.
Untuk mengakses input yang diparsing dapat menggunakan operator titik (.) yang menandakan nilai diambil dari objek atau menggunakan konsep objek atau dengan menggunakan operator kurung siku ([]) yang menandakan nilai diambil dari array atau menggunakan konsep array.
Contoh:
PARSING_RULE=\
$INPUT.TIME_STAMP=$HEADER.X_TIME_STAMP\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.GROUP=$URL.GROUP\
$INPUT.TRANSACTION=$URL.TRANSACTION\
$INPUT.COMMAND=$REQUEST.command\
$INPUT.DESTIONATION_ACCOUNT_NUMBER=$REQUEST.data.destination_account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY_CODE=$REQUEST.data.currency_code\
$INPUT.REFERENCE_NUMBER=$REQUEST.data.reference_number\TRANSACTION_RULE
Transaction rule adalah pengaturan output baik header respon, body respon, HTTP status respon, delay respon, header callback, body callback, dan time out callback sesuai dengan nilai variabel dari request yang telah berhasil diparsing.
Pemilihan kondisi menggunakan kata kunci {[IF]} dengan catatan apabila suatu kondisi sudah terpenuhi, maka simulator akan berhenti pada kondisi tersebut dan memproses output sesuai dengan aturan yang ditentukan. Apabila dua buah kondisi atau lebih dipenuhi dalam satu request yang sama, maka kondisi yang paling atas yang akan digunakan.
Contoh:
TRANSACTION_RULE=\
{[IF]} ($INPUT.USERNAME == "user1" && $INPUT.PASSWORD == "passwd1")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.HEADER=Server: Universal REST Simulator\
X-Timestamp: $DATE('Y-m-d\TH:i:s', 'UTC').000Z\
$OUPUT.BODY={\
"command": "$INPUT.COMMAND",\
"data": {\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY_CODE",\
"reference_number": "$INPUT.REFERENCE_NUMBER",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z"
},\
"response_code": "001",
"response_text": "Success"
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=403 Forbidden\
$OUTPUT.HEADER=Server: Universal REST Simulator\
X-Timestamp: $DATE('Y-m-d\TH:i:s', 'UTC').000Z\
$OUPUT.BODY={\
"command": "$INPUT.COMMAND",\
"data": {\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY_CODE",\
"reference_number": "$INPUT.REFERENCE_NUMBER",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z"
},\
"response_code": "051",
"response_text": "Rejected"
}\
{[ENDIF]}\Contoh Konfigurasi:
METHOD=GET
PATH=/getdata
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text": "Mandatory field can not be empty",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
GET /getdata?name=Bambang&email=bambang@domain.tld&phone=08111111111 HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/jsonContoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 216
{
"response_code": "001",
"response_text": "Success",
"data": {
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111",
"time_stamp": "1619922480"
}
}Contoh Konfigurasi:
METHOD=POST
PATH=/postdata
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text": "Mandatory field can not be empty",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
POST /postdata HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
name=Bambang&email=bambang@domain.tld&phone=08111111111Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 216
{
"response_code": "001",
"response_text": "Success",
"data": {
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111",
"time_stamp": "1619922480"
}
}Contoh Konfigurasi:
METHOD=PUT
PATH=/putdata
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text": "Mandatory field can not be empty",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
PUT /putdata HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
name=Bambang&email=bambang@domain.tld&phone=08111111111Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 216
{
"response_code": "001",
"response_text": "Success",
"data": {
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111",
"time_stamp": "1619922480"
}
}Contoh Konfigurasi:
METHOD=POST
PATH=/postjson
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text": "Mandatory field can not be empty",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
POST /postjson HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/json
Content-Type: application/json
Content-Length: 89
{
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111"
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 216
{
"response_code": "001",
"response_text": "Success",
"data": {
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111",
"time_stamp": "1619922480"
}
}Contoh Konfigurasi:
METHOD=PUT
PATH=/putjson
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text": "Mandatory field can not be empty",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
PUT /putjson HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/json
Content-Type: application/json
Content-Length: 89
{
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111"
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 216
{
"response_code": "001",
"response_text": "Success",
"data": {
"name": "Bambang",
"email": "bambang@domain.tld",
"phone": "08111111111",
"time_stamp": "1619922480"
}
}Contoh Konfigurasi:
METHOD=POST
PATH=/postxml
REQUEST_TYPE=application/xml
RESPONSE_TYPE=application/xml
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<container>\
<response_code>001</response_code>\
<response_text>Success</response_text>\
<data>\
<name>$INPUT.NAME</name>\
<email>$INPUT.EMAIL</email>\
<phone>$INPUT.PHONE</phone>\
<time_stamp>$DATE('U')</time_stamp>\
</data>\
</container>\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<container>\
<response_code>061</response_code>\
<response_text>Mandatory field can not be empty</response_text>\
<data>\
<name>$INPUT.NAME</name>\
<email>$INPUT.EMAIL</email>\
<phone>$INPUT.PHONE</phone>\
<time_stamp>$DATE('U')</time_stamp>\
</data>\
</container>\
{[ENDIF]}\Contoh Request:
POST /postxml HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/xml
Content-Type: application/xml
Content-Length: 157
<?xml version="1.0" encoding="UTF-8"?>
<container>
<name>Bambang</name>
<email>bambang@domain.tld</email>
<phone>08111111111</phone>
</container>Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 319
<?xml version="1.0" encoding="UTF-8"?>
<container>
<response_code>001</response_code>
<response_text>Success</response_text>
<data>\
<name>Bambang</name>
<email>bambang@domain.tld</email>
<phone>08111111111</phone>
<time_stamp>1619922480</time_stamp>
</data>
</container>Contoh Konfigurasi:
METHOD=PUT
PATH=/putxml
REQUEST_TYPE=application/xml
RESPONSE_TYPE=application/xml
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "")\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<container>\
<response_code>001</response_code>\
<response_text>Success</response_text>\
<data>\
<name>$INPUT.NAME</name>\
<email>$INPUT.EMAIL</email>\
<phone>$INPUT.PHONE</phone>\
<time_stamp>$DATE('U')</time_stamp>\
</data>\
</container>\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<container>\
<response_code>061</response_code>\
<response_text>Mandatory field can not be empty</response_text>\
<data>\
<name>$INPUT.NAME</name>\
<email>$INPUT.EMAIL</email>\
<phone>$INPUT.PHONE</phone>\
<time_stamp>$DATE('U')</time_stamp>\
</data>\
</container>\
{[ENDIF]}\Contoh Request:
PUT /putxml HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/xml
Content-Type: application/xml
Content-Length: 157
<?xml version="1.0" encoding="UTF-8"?>
<container>
<name>Bambang</name>
<email>bambang@domain.tld</email>
<phone>08111111111</phone>
</container>Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: 319
<?xml version="1.0" encoding="UTF-8"?>
<container>
<response_code>001</response_code>
<response_text>Success</response_text>
<data>\
<name>Bambang</name>
<email>bambang@domain.tld</email>
<phone>08111111111</phone>
<time_stamp>1619922480</time_stamp>
</data>
</container>Contoh Konfigurasi:
METHOD=POST
PATH=/postsoap
REQUEST_TYPE=applicatiom/soap+xml
RESPONSE_TYPE=applicatiom/soap+xml
PARSING_RULE=\
$INPUT.MSISDN=$REQUEST.Body.TopupRequest.msisdn\
$INPUT.PRODUCT_CODE=$REQUEST.Body.TopupRequest.productCode\
$INPUT.REFERENCE_NUMBER=$REQUEST.Body.TopupRequest.clientRefID
TRANSACTION_RULE=\
{[IF]} ($INPUT.MSISDN == "081266666667")\
{[THEN]}\
$OUTPUT.CALLBACK_URL=http://localhost:8080/process-callback\
$OUTPUT.CALLBACK_METHOD=POST\
$OUTPUT.CALLBACK_TYPE=applicatiom/soap+xml\
$OUTPUT.CALLBACK_BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>0</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
$OUTPUT.BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>1</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
{[ENDIF]}\
{[IF]} ($INPUT.MSISDN == "081266666666")\
{[THEN]}\
$OUTPUT.CALLBACK_URL=http://localhost:8080/process-callback\
$OUTPUT.CALLBACK_METHOD=POST\
$OUTPUT.CALLBACK_TYPE=applicatiom/soap+xml\
$OUTPUT.CALLBACK_BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>0</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
$OUTPUT.BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>0</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>17</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
{[ENDIF]}\Pada Content-type: application/soap+xml, prefix soap: pada setiap tag dihapus sehingga pengguna dapat mengambil input dari request tanpa prefix soap:. Sebagai contoh: data di dalam tag <soap:Body> dapat diambil dengan $REQUEST.Body atau $REQUEST[Body] bukan $REQUEST[soap:Body].
Contoh Request:
PUT /postsoap HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/soap+xml
Content-Type: application/soap+xml
Content-Length: 543
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TopupRequest xmlns="http://ytz.org/">
<msisdn>081266666666</msisdn>
<productCode>X010</productCode>
<userID>USER</userID>
<userPassword>PASS</userPassword>
<clientRefID>0000000000013787</clientRefID>
<storeid>XL</storeid>
</TopupRequest>
</soap:Body>
</soap:Envelope>Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/soap+xml
Content-Length: 477
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TopupRequest xmlns="http://ytz.org/">
<ResponseCode>0</ResponseCode>
<TransID>164</TransID>
<ReferenceID>0000000000013787</ReferenceID>
<SerialNo>0987654321</SerialNo>
</TopupRequest>
</soap:Body>
</soap:Envelope>Contoh Konfigurasi:
METHOD=PUT
PATH=/putsoap
REQUEST_TYPE=applicatiom/soap+xml
RESPONSE_TYPE=applicatiom/soap+xml
PARSING_RULE=\
$INPUT.MSISDN=$REQUEST.Body.TopupRequest.msisdn\
$INPUT.PRODUCT_CODE=$REQUEST.Body.TopupRequest.productCode\
$INPUT.REFERENCE_NUMBER=$REQUEST.Body.TopupRequest.clientRefID
TRANSACTION_RULE=\
{[IF]} ($INPUT.MSISDN == "081266666667")\
{[THEN]}\
$OUTPUT.CALLBACK_URL=http://localhost:8080/process-callback\
$OUTPUT.CALLBACK_METHOD=PUT\
$OUTPUT.CALLBACK_TYPE=applicatiom/soap+xml\
$OUTPUT.CALLBACK_BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>0</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
$OUTPUT.BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>1</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
{[ENDIF]}\
{[IF]} ($INPUT.MSISDN == "081266666666")\
{[THEN]}\
$OUTPUT.CALLBACK_URL=http://localhost:8080/process-callback\
$OUTPUT.CALLBACK_METHOD=PUT\
$OUTPUT.CALLBACK_TYPE=applicatiom/soap+xml\
$OUTPUT.CALLBACK_BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>0</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
$OUTPUT.BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>0</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.BODY=<?xml version="1.0" encoding="utf-8"?>\
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\
<soap:Body>\
<TopupRequest xmlns="http://ytz.org/">\
<ResponseCode>17</ResponseCode>\
<TransID>164</TransID>\
<ReferenceID>$INPUT.REFERENCE_NUMBER</ReferenceID>\
<SerialNo>0987654321</SerialNo>\
</TopupRequest>\
</soap:Body>\
</soap:Envelope>\
{[ENDIF]}\Pada Content-type: application/soap+xml, prefix soap: pada setiap tag dihapus sehingga pengguna dapat mengambil input dari request tanpa prefix soap:. Sebagai contoh: data di dalam tag <soap:Body> dapat diambil dengan $REQUEST.Body atau $REQUEST[Body] bukan $REQUEST[soap:Body].
Contoh Request:
PUT /putsoap HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/soap+xml
Content-Type: application/soap+xml
Content-Length: 543
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TopupRequest xmlns="http://ytz.org/">
<msisdn>081266666666</msisdn>
<productCode>X010</productCode>
<userID>USER</userID>
<userPassword>PASS</userPassword>
<clientRefID>0000000000013787</clientRefID>
<storeid>XL</storeid>
</TopupRequest>
</soap:Body>
</soap:Envelope>Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/soap+xml
Content-Length: 477
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TopupRequest xmlns="http://ytz.org/">
<ResponseCode>0</ResponseCode>
<TransID>164</TransID>
<ReferenceID>0000000000013787</ReferenceID>
<SerialNo>0987654321</SerialNo>
</TopupRequest>
</soap:Body>
</soap:Envelope>Universal REST Simulator dapat mengkombinasikan input GET dengan POST. Untuk mengkombinasikan GET dengan POST, gunakan method POST.
POST hanya berlaku untuk REQUEST_TYPE=application/x-www-form-urlencoded . Dalam hal ini, client juga harus mengirim Content-type: application/x-www-form-urlencoded. Pengambilan input dari GET dan POST sama dengan REQUEST seperti contoh sebagai berikut:
PATH=/universal-simulator/token
METHOD=POST
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.GRANT_TYPE=$POST.grant_type\
$INPUT.DETAIL=$GET.detail\
$INPUT.UUID1=$SYSTEM.UUID\
$INPUT.UUID2=$SYSTEM.UUID\
$INPUT.UUID3=$SYSTEM.UUID\
$INPUT.UUID4=$SYSTEM.UUID
TRANSACTION_RULE=\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME == "username" && $INPUT.PASSWORD == "password" && $INPUT.DETAIL == "yes")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN,\
"email": "token@domain.tld"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME == "username" && $INPUT.PASSWORD == "password")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN\
}\
{[ENDIF]}\Konfigurasi di atas menunjukkan bahwa path tersebut menghendaki method POST dan yang lain. Akan tetapi, pengguna tetap dapat mengambil nilai dari query pada URL menggunakan $GET.
Contoh Request:
POST /universal-simulator/token?detail=yes HTTP/1.1
Host: 127.0.0.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-type: application/x-www-form-urlencoded
Content-length: 29
grant_type=client_credentialsDari contoh di atas, input dari URL /universal-simulator/token?detail=yes diambil dengan $GET.detail. Nilai ini akan sama dengan $REQUEST.detail jika menggunakan method GET. Karena pada konfigurasi telah didefinisikanMETHOD=POST, maka nilai ini hanya bisa diambil dengan $GET.detail karena $REQUEST hanya mengacu kepada request body yang dikirim.
Pengambilan data dari body dapat dilakukan dengan dua cara yaitu $REQUEST dan $POST. Ingat bahwa $POST hanya bisa digunakan jika REQUEST_TYPE=application/x-www-form-urlencoded dan Content-type: application/x-www-form-urlencoded. Untuk content type lain, harus menggunakan $RQUEST.
Pengguna dapat membuat konfigurasi yang memungkinkan klien mengirim data dengan tipe application/json dan mengkombinasikannya dengan GET. Dalam hal ini, REQUEST_TYPE diset menjadi application/json. Tentu saja data yang dikirim dengan GET menggunakan application/x-www-form-urlencoded.
Contoh Konfigurasi:
PATH=/universal-simulator/getandpost
METHOD=POST
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.ACTION=$GET.action\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY_CODE=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.ACTION == "cash-deposit" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}\
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text:" "Success",\
"data": {\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY_CODE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text:" "Mandatory field can not be empty",\
"data": {\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY_CODE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
POST /universal-simulator/getandpost?action=cash-deposit HTTP/1.1
Host: 127.0.0.1
Content-type: application/json
Content-length: 121
{
"data": {
"account_number": "1234567890",
"amount": 5000000,
"currency_code": "IDR"
}
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 218
{
"response_code": "001",
"response_text:": "Success",
"data": {
"account_number": "1234567890",
"amount": 5000000,
"currency_code": "IDR",
"time_stamp": "1619922480"
}
}Universal REST Simulator dapat mengkombinasikan input GET dengan PUT. Untuk mengkombinasikan GET dengan PUT, gunakan method PUT.
PUT hanya berlaku untuk REQUEST_TYPE=application/x-www-form-urlencoded . Dalam hal ini, client juga harus mengirim Content-type: application/x-www-form-urlencoded. Pengambilan input dari GET dan PUT sama dengan REQUEST seperti contoh sebagai berikut:
PATH=/universal-simulator/token
METHOD=PUT
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.GRANT_TYPE=$PUT.grant_type\
$INPUT.DETAIL=$GET.detail\
$INPUT.UUID1=$SYSTEM.UUID\
$INPUT.UUID2=$SYSTEM.UUID\
$INPUT.UUID3=$SYSTEM.UUID\
$INPUT.UUID4=$SYSTEM.UUID
TRANSACTION_RULE=\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME == "username" && $INPUT.PASSWORD == "password" && $INPUT.DETAIL == "yes")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN,\
"email": "token@domain.tld"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME == "username" && $INPUT.PASSWORD == "password")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN\
}\
{[ENDIF]}\Konfigurasi di atas menunjukkan bahwa path tersebut menghendaki method PUT dan yang lain. Akan tetapi, pengguna tetap dapat mengambil nilai dari query pada URL menggunakan $GET.
Contoh Request:
PUT /universal-simulator/token?detail=yes HTTP/1.1
Host: 127.0.0.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-type: application/x-www-form-urlencoded
Content-length: 29
grant_type=client_credentialsDari contoh di atas, input dari URL /universal-simulator/token?detail=yes diambil dengan $GET.detail. Nilai ini akan sama dengan $REQUEST.detail jika menggunakan method GET. Karena pada konfigurasi telah didefinisikanMETHOD=PUT, maka nilai ini hanya bisa diambil dengan $GET.detail karena $REQUEST hanya mengacu kepada request body yang dikirim.
Pengambilan data dari body dapat dilakukan dengan dua cara yaitu $REQUEST dan $PUT. Ingat bahwa $PUT hanya bisa digunakan jika REQUEST_TYPE=application/x-www-form-urlencoded dan Content-type: application/x-www-form-urlencoded. Untuk content type lain, harus menggunakan $RQUEST.
Pengguna dapat membuat konfigurasi yang memungkinkan klien mengirim data dengan tipe application/json dan mengkombinasikannya dengan GET. Dalam hal ini, REQUEST_TYPE diset menjadi application/json. Tentu saja data yang dikirim dengan GET menggunakan application/x-www-form-urlencoded.
Contoh Konfigurasi:
PATH=/universal-simulator/getandput
METHOD=PUT
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.ACTION=$GET.action\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY_CODE=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.ACTION == "cash-deposit" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}\
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text:" "Success",\
"data": {\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY_CODE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text:" "Mandatory field can not be empty",\
"data": {\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY_CODE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Contoh Request:
PUT /universal-simulator/getandput?action=cash-deposit HTTP/1.1
Host: 127.0.0.1
Content-type: application/json
Content-length: 121
{
"data": {
"account_number": "1234567890",
"amount": 5000000,
"currency_code": "IDR"
}
}Tidak jarang developer menggunakan path pada URL sebagai cara untuk mengambil nilai dari klien. Tentu saja aplikasi harus dapat mengekstrak informasi tersebut dari path request yang diberikan.
Nilai yang diambil dari path pun kadang lebih dari satu yang dipisahkan dengan tanda baca garis miring (/). Akan tetapi, ada pula developer yang menggunakan pola tidak umum pada path aplikasi.
Contoh Konfigurasi:
METHOD=GET
PATH=/geturldata/{[TRANSACTION]}/{[ID]}
REQUEST_TYPE=application/x-www-form-urlencode
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.TRANSACTION_TYPE=$URL.TRANSACTION\
$INPUT.TRANSACTION_ID=$URL.ID
TRANSACTION_RULE=\
{[IF]} ($INPUT.TRANSACTION_TYPE == "detail" && $INPUT.TRANSACTION_ID != "")\
{[THEN]}
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {\
"name": "Bambang",\
"account_number": "123456",\
"amount": 5000000\
},\
"response_code": "001",\
"response_text": "Success"\
}\
{[ENDIF]}
{[IF]} (true)\
{[THEN]}
$OUTPUT.STATUS=400\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {},\
"response_code": "061",\
"response_text": "Mandatory field can not be empty"\
}\
{[ENDIF]}Contoh Request:
GET /geturldata/detail/69 HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/jsonContoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 212
{
"action": "detail",
"id": "69",
"data": {
"name": "Bambang",
"account_number": "123456",
"amount": 5000000
},
"response_code": "001",
"response_text": "Success"
}Penggunaan path tidak hanya untuk method GET saja namun bisa juga digunakan pada method POST dan PUT.
Contoh Konfigurasi:
METHOD=POST
PATH=/posturldata/{[TRANSACTION]}/{[ID]}
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.TRANSACTION_TYPE=$URL.TRANSACTION\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.TRANSACTION_TYPE == "deposit" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": 69,\
"data": {\
"name": "Bambang",\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY"\
},\
"response_code": "001",\
"response_text": "Success"\
}\
{[ENDIF]}
{[IF]} (true)\
{[THEN]}
$OUTPUT.STATUS=400\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {},\
"response_code": "061",\
"response_text": "Mandatory field can not be empty"\
}\
{[ENDIF]}Contoh Request:
GET /posturldata/deposit HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Content-Type: application/json
Accept: application/json
Content-Length: 118
{
"data": {
"account_number": "98765432",
"amount": 250000,
"currency_code": "IDR"
}
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 242
{
"action": "deposit",
"id": 69,
"data": {
"name": "Bambang",
"account_number": "123456",
"amount": 250000,
"currency_code": "IDR"
},
"response_code": "001",
"response_text": "Success"
}Contoh Konfigurasi:
METHOD=POST
PATH=/fromheader
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.DATE_TIME=$HEADER.X_DATE_TIME\
$INPUT.SIGNATURE=$HEADER.X_SIGNATURE\
$INPUT.API_KEY=$HEADER.X_API_KEY\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.API_KEY == "api123" && $INPUT.DATE_TIME != "" && $INPUT.SIGNATURE != "" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": 69,\
"data": {\
"date_time": "$INPUT.DATE_TIME",\
"name": "Bambang",\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY"\
},\
"response_code": "001",\
"response_text": "Success"\
}\
{[ENDIF]}
{[IF]} (true)\
{[THEN]}
$OUTPUT.STATUS=400\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {},\
"response_code": "061",\
"response_text": "Mandatory field can not be empty"\
}\
{[ENDIF]}Contoh Request:
GET /fromheader HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Content-Type: application/json
Accept: application/json
Content-Length: 118
X-Api-Key: api123
X-Date-Time: 2021-05-01T10:11:12.000Z
X-Signature: yuYTDtrdoiioidtydDRryooTtee588iKJesrrfr1
{
"data": {
"account_number": "98765432",
"amount": 250000,
"currency_code": "IDR"
}
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 242
{
"action": "deposit",
"id": 69,
"data": {
"date_time": "2021-05-01T10:11:12.000Z",
"name": "Bambang",
"account_number": "123456",
"amount": 250000,
"currency_code": "IDR"
},
"response_code": "001",
"response_text": "Success"
}Pengguna dapat mengambil username dan password dari Basic Authorization tanpa harus memparsingnya secara manual. Simulator secara otomatis memparsing Basic Authorization jika konfigurasi menghendakinya.
Contoh Konfigurasi:
METHOD=POST
PATH=/basicauth
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.USERNAME == "user1" && $INPUT.PASSWORD == "password1" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": 69,\
"data": {\
"date_time": "$INPUT.DATE_TIME",\
"name": "Bambang",\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": $INPUT.AMOUNT,\
"currency_code": "$INPUT.CURRENCY"\
},\
"response_code": "001",\
"response_text": "Success"\
}\
{[ENDIF]}
{[IF]} (true)\
{[THEN]}
$OUTPUT.STATUS=403\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {},\
"response_code": "062",\
"response_text": "Access forbidden"\
}\
{[ENDIF]}Contoh Request:
GET /basicauth HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Content-Type: application/json
Accept: application/json
Content-Length: 118
Authorization: Basic dXNlcjE6cGFzc3dvcmQx
{
"data": {
"account_number": "98765432",
"amount": 250000,
"currency_code": "IDR"
}
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 291
{
"action": "deposit",
"id": 69,
"data": {
"date_time": "2021-05-01T10:11:12.000Z",
"name": "Bambang",
"account_number": "123456",
"amount": 250000,
"currency_code": "IDR"
},
"response_code": "001",
"response_text": "Success"
}Pada beberapa kasus, pengguna mungkin membutuhkan respon dengan ID yang dinamik dan unik. Universal REST Simulator memungkinkan pengguna untuk menghasilkan UUID.
Pengguna dapat menggunakan banyak UUID pada sebuah file konfigurasi.
Contoh Konfigurasi:
PATH=/universal-simulator/token
METHOD=POST
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.UUID1=$SYSTEM.UUID\
$INPUT.UUID2=$SYSTEM.UUID\
$INPUT.UUID3=$SYSTEM.UUID\
$INPUT.UUID4=$SYSTEM.UUID
TRANSACTION_RULE=\
{[IF]} ($INPUT.USERNAME == "user1" && $INPUT.PASSWORD == "password1")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"respnse_code":"001",\
"data":{\
"unique_id_1": "$INPUT.UUID1",\
"unique_id_2": "$INPUT.UUID2",\
"unique_id_3": "$INPUT.UUID3",\
"unique_id_4": "$INPUT.UUID4"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.STATUS=403\
$OUTPUT.BODY={\
"respnse_code":"061",
"data":{\
}\
}\
{[ENDIF]}\Contoh Request:
POST /uuid HTTP/1.1
Host: 127.0.0.1
Authorization: Basic dXNlcjE6cGFzc3dvcmQxContoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 207
{
"respnse_code":"001",
"data":{
"unique_id_1": "4b3403665fea6",
"unique_id_2": "4b3403665eea6",
"unique_id_3": "4b3403665dea6",
"unique_id_4": "4b3403665cea6"
}
}Pada kenyataannya, request tidak hanya mengandung objek saja melainkan juga array. Array bisa berasal dari parameter pada GET, POST dan PUT pada content type application/x-www-form-urlencode, application/json maupun application/xml.
Data tidak dapat diparsing dengan menggunakan operator titik (.). Sebagai gantinya, operator kurung siku ([]) dapat digunakan untuk memparsing data tersebut.
Sebagai contoh, parameter sebuah request adalah sebagai berikut:
item[]=Kemeja&item[]=Sepatu&item[]=Topi
Maka, untuk mengambil data di atas, dapat dilakukan dengan cara sebagai berikut:
PARSING_RULE=\
$INPUT.ITEM0=$REQUEST[item][0]\
$INPUT.ITEM1=$REQUEST[item][1]\
$INPUT.ITEM2=$REQUEST[item][2]Pada bererapa web server mungkin item[]=Kemeja&item[]=Sepatu&item[]=Topi tidak diterima. Sebagai gantinya, klien harus menuliskan indeks secara eksplisit menjadi item[0]=Kemeja&item[1]=Sepatu&item[2]=Topi.
Universal REST Simulator secara cerdas dapat dengan mengambil nilai baik dengan penulisan indeks secara eksplisit maupun tidak. Selain itu, penulisan seperti item[]=Kemeja&item[1]=Sepatu&item[3]=Topi juga dapat diterima meskipun penulisan seperti ini sangat tidak disarankan.
Penggunaan operator kurung siku ([]) menganggap request sebagai sebuah associated array yaitu map dengan key sebuah string dan mempunyai value dengan tipe mixed meskipun dalam hal ini dibatasi pada tipe data string, numeric dan boolean.
Tidak diperbolehkan menggunakan operator kurung siku ([]) dan titik (.) untuk mengambil sebuah nilai. Perlu diingat bahwa Universal REST Simulator akan langsung mengkonversi semua request menjadi object apabila inputnya diawali dengan $REQUEST., $GET., $POST., dan $PUT. dan akan langsung mengkonversi semua request menjadi associated array apabila inputnya diawali dengan $REQUEST[, $GET[, $POST[, dan $PUT[. Oleh sebab itu, meskpun data yang akan diambil merupakan object, namun tetap dapat diparsing menggunakan operator kurung siku ([]).
Sebagai contoh, parameter request name=Kemeja&quantity=1&price=450000 dapat diparsing dengan konfigurasi sebagai berikut:
PARSING_RULE=\
$INPUT.NAME=$REQUEST[name]\
$INPUT.QUANTITY=$REQUEST[quantity]\
$INPUT.PRICE=$REQUEST[price]atau
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.QUANTITY=$REQUEST.quantity\
$INPUT.PRICE=$REQUEST.priceatau
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.QUANTITY=$REQUEST[quantity]\
$INPUT.PRICE=$REQUEST.pricePengguna mungkin menggunakan kombinasi antara array dan object sebagai payload dari request baik GET, POST, PUT, maupun REQUEST. Untuk mengambil nilai dari input yang kesemuanya adalah object dapat menggunakan operator titik (.) sedangkan untuk mengambil nilai dari input yang merupakan kombinasi antara object dan array dapat menggunakan operator kurung siku [].
Contoh Konfigurasi:
PATH=/universal-rest-simulator/array
METHOD=POST
REQUEST_TYPE=application/json
RESPONSE_TYPE=text/plain
PARSING_RULE=\
$INPUT.AMOUNT0=$REQUEST[items][0][amount]\
$INPUT.AMOUNT1=$REQUEST[items][1][amount]\
$INPUT.NAME0=$REQUEST[items][0][name]\
$INPUT.NAME1=$REQUEST[items][1][name]
TRANSACTION_RULE=\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY=\
NAMA ITEM : $INPUT.NAME0\
HARGA ITEM : $INPUT.AMOUNT0\
NAMA ITEM : $INPUT.NAME1\
HARGA ITEM : $INPUT.AMOUNT1\
{[ENDIF]}Operator [] dapat digunakan untuk mengambil nilai dari object dan array. Tidak diperkenankan menggabungkan operator . dan [] dalam mengambil sebuah nilai. Dengan demikian, penulisan $INPUT.AMOUNT0=$REQUEST[items][0].amount tidak diperbolehkan. Meskipun demikian, diperbolehkan menggunakan kombinasinya pada input yang berbeda.
Contoh Kombinasi Operator:
PATH=/universal-rest-simulator/array
METHOD=POST
REQUEST_TYPE=application/json
RESPONSE_TYPE=text/plain
PARSING_RULE=\
$INPUT.CUSTOMER_NAME=$REQUEST.customer.name\
$INPUT.AMOUNT0=$REQUEST[items][0][amount]\
$INPUT.AMOUNT1=$REQUEST[items][1][amount]\
$INPUT.NAME0=$REQUEST[items][0][name]\
$INPUT.NAME1=$REQUEST[items][1][name]
TRANSACTION_RULE=\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY=\
NAMA PELANGGAN : $INPUT.CUSTOMER_NAME\
NAMA ITEM : $INPUT.NAME0\
HARGA ITEM : $INPUT.AMOUNT0\
NAMA ITEM : $INPUT.NAME1\
HARGA ITEM : $INPUT.AMOUNT1\
{[ENDIF]}Contoh Request:
POST /universal-rest-simulator/array HTTP/1.1
Host: 127.0.0.1
Content
{
"items":[
{
"name":"Kopi",
"amount":15000
},
{
"name":"Roti",
"amount":80000
}
],
"customer": {
"name": "Anonim",
"phone": "081111111111111"
}
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 113
NAMA PELANGGAN : Anonim
NAMA ITEM : Kopi
HARGA ITEM : 15000
NAMA ITEM : Roti
HARGA ITEM : 80000$INPUT.CUSTOMER_NAME=$REQUEST.customer.name dapat pula ditulis dengan $INPUT.CUSTOMER_NAME=$REQUEST[customer][name] tanpa spasi sebelum [ dan sesudah ].
Contoh Konfigurasi:
PATH=/universal-simulator/token
METHOD=POST
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.GRANT_TYPE=$POST.grant_type\
$INPUT.DETAIL=$GET.detail
TRANSACTION_RULE=\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME == "username" && $INPUT.PASSWORD == "password")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.STATUS=200\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN,\
"email": "token@domain.tld"\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.STATUS=403\
$OUTPUT.BODY={\
}\
{[ENDIF]}\Contoh Request:
POST /universal-simulator/token?detail=yes HTTP/1.1
Host: 127.0.0.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-type: application/x-www-form-urlencoded
Content-length: 29
grant_type=client_credentialsContoh Respon
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 359
{
"token_type": "Bearer",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJZb3VyIENvbXBhbnkiLCJhdWQiOiJZb3VyIENsaWVudCIsImlhdCI6MTYyMDAyNDI0MiwibmJmIjoxNjIwMDI0MjQyLCJleHAiOjE2MjAwMjc4NDIsImRhdGEiOltdfQ.x_SOclw1fn4irxsNHtX6ai02CTnFAGB5X7O_pRtk5UA",
"expire_at": 1620027842,
"expires_in": 3600,
"email": "token@domain.tld"
}Contoh Konfigurasi:
PATH=/universal-simulator/token
METHOD=POST
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.GRANT_TYPE=$POST.grant_type\
$INPUT.DETAIL=$GET.detail
TRANSACTION_RULE=\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME == "username" && $INPUT.PASSWORD == "password")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.STATUS=200\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN,\
"email": "token@domain.tld"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.GRANT_TYPE == 'client_credentials' && $INPUT.USERNAME != "" && $INPUT.PASSWORD == "")\
{[THEN]} $OUTPUT.DELAY=0\
$OUTPUT.DELAY=0\
$OUTPUT.STATUS=403\
$OUTPUT.BODY={\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.STATUS=999 Invalid Request\
$OUTPUT.BODY={\
}\
{[ENDIF]}\Pada HTTP Status Non-Standard (unofficial HTTP Status), pengguna perlu menambahkan deskripsi di belakang kode. Misalnya 999 Invalid Request. 999 merupakan HTTP Status yang tidak standard. Kode tersebut dapat digunakan dengan catatan pengguna menambahkan deskripsi di belakang kode. Jika pengguna tidak menambahkan deskripsi di belakang kode, maka simulator akan memberikan status 500 Internal Server Error.
Contoh Request:
POST /universal-simulator/token?detail=yes HTTP/1.1
Host: 127.0.0.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-type: application/x-www-form-urlencoded
Content-length: 29
grant_type=client_credentialsContoh Respon
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 359
{
"token_type": "Bearer",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJZb3VyIENvbXBhbnkiLCJhdWQiOiJZb3VyIENsaWVudCIsImlhdCI6MTYyMDAyNDI0MiwibmJmIjoxNjIwMDI0MjQyLCJleHAiOjE2MjAwMjc4NDIsImRhdGEiOltdfQ.x_SOclw1fn4irxsNHtX6ai02CTnFAGB5X7O_pRtk5UA",
"expire_at": 1620027842,
"expires_in": 3600,
"email": "token@domain.tld"
}Universal REST Simulator menggunakan JSON Web Token atau JWT sebagai metode untuk membuat token. Salah satu kelebihan dari JWT adalah bahwa token dapat divalidasi dengan dirinya sendiri. Server menyimpan beberapa informasi rahasia untuk membuat token dan dapat memvalidasi token yang telah dibuat dengan informasi yang ada pada token tersebut dan informasi rahasia yang disimpan di server. Salah satu informasi rahasia yang disimpan di server yang tidak dimasukkan ke dalam token adalah kunci atau key untuk membuat dan memvalidasi token.
JWT mempunyai parameter waktu berlaku. Artinya, sebuah token JWT hanya valid dalam waktu tertentu. Dengan kata lain, apabila token bocor setelah masa berlakunya habis, maka token tersebut tidak dapat digunakan lain oleh siapapun. Tidak ada standard berapa lama masa berlaku JWT. Akan tetapi, banyak yang menggunakan waktu 1 jam untuk masa berlaku token.
Contoh Konfigurasi:
PATH=/auth
METHOD=POST
REQUEST_TYPE=application/x-www-form-urlencoded
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.GRANT_TYPE=$REQUEST.grant_type
TRANSACTION_RULE=\
{[IF]} ($INPUT.USERNAME == 'username' && $INPUT.PASSWORD == 'userpassword' && $INPUT.GRANT_TYPE == 'client_credentials')\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"token_type": "Bearer",\
"access_token": "$TOKEN.JWT",\
"expire_at": $TOKEN.EXPIRE_AT,\
"expires_in": $TOKEN.EXPIRE_IN\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=403\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
}\
{[ENDIF]}\Contoh Request:
POST /auth HTTP/1.1
Host: 127.0.0.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-type: application/x-www-form-urlencoded
Content-length: 29
grant_type=client_credentialsContoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 359
{
"token_type": "Bearer",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJZb3VyIENvbXBhbnkiLCJhdWQiOiJZb3VyIENsaWVudCIsImlhdCI6MTYyMDAyNDYxNiwibmJmIjoxNjIwMDI0NjE2LCJleHAiOjE2MjAwMjgyMTYsImRhdGEiOltdfQ.eisS2qFFf4vjifCz7y_d5OyReqtkNSBtBrJoZuwPumw",
"expire_at": 1620028216,
"expires_in": 3600,
"email": "token@domain.tld"
}Untuk memvalidasi token, pengguna cukup menambahkan fungsi $ISVALIDTOKEN() pada kondisi yang akan diuji. Saat menemukan fungsi $ISVALIDTOKEN(), Universal REST Simulator langsung memproses header Authorization: Bearer ... yang ada pada request header dan menguji apakah token yang diberikan valid atau tidak. Jika valid, fungsi $ISVALIDTOKEN() akan bernilai true namun jika tidak valid, maka fungsi $ISVALIDTOKEN() akan bernilai false.
Universal REST Simulator dapat memvalidasi token untuk method GET, POST maupun PUT. Path untuk memvalidasi token tidak ada hubungannya dengan path ketika melakukan request token. Simulator akan memvalidasi token secara independen tanpa terkait dengan path dan header lain. Universal REST Simulator hanya dapat memvalidasi token yang dibuatnya sendiri. Pengaturan credential token dapat dilakukan dengan mengubah nilai setiap atribut dari objek $appConfig di file /lib.inc/config.php. Dengan demikian, jika diperlukan untuk memvalidasi token yang dibuat oleh Universal REST Simulator yang terpasang pada server lain dapat dilakukan dengan cara menyamakan nilai dari atribut objek $appConfig pada server-server terkait.
PATH=/va-status
METHOD=POST
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.COMMAND=$REQUEST.command\
$INPUT.VA_NUMBER=$REQUEST.data.virtual_account_number\
$INPUT.REQUEST_ID=$REQUEST.data.request_id\
$INPUT.PG_CODE=$REQUEST.data.pg_code\
$INPUT.REF_NUMBER=$REQUEST.data.reference_number\
$INPUT.CUST_NUMBER=$REQUEST.data.customer_number\
$INPUT.CUST_NAME=$REQUEST.data.customer_name\
$INPUT.BANK_CODE=$REQUEST.data.bank_code\
$INPUT.CHANNEL_TYPE=$REQUEST.data.channel_type\
$INPUT.TOTAL_AMOUNT=$REQUEST.data.total_amount\
$INPUT.PAID_AMOUNT=$REQUEST.data.paid_amount
TRANSACTION_RULE=\
{[IF]} ($INPUT.CUST_NUMBER == "1571200004" && $ISVALIDTOKEN())\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"response_code": "00",\
"response_text": "Success",\
"message": {\
"id": "Sukses",\
"en": "Success"\
},\
"data": {\
"bank_code": "$INPUT.BANK_CODE",\
"channel_type": "$INPUT.CHANNEL_TYPE",\
"pg_code": "$INPUT.PG_CODE",\
"merchant_code": "030",\
"merchant_name": "Arta Pay",\
"virtual_account_number": "$INPUT.VA_NUMBER",\
"customer_name": "$INPUT.CUST_NAME",\
"request_id": "$INPUT.REQUEST_ID",\
"reference_number": "$INPUT.REF_NUMBER",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"customer_number": "$INPUT.CUST_NUMBER",\
"currency_code": "IDR",\
"total_amount": $INPUT.TOTAL_AMOUNT,\
"paid_amount": $INPUT.PAID_AMOUNT,\
"bill_list": []\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"response_code": "05",\
"response_text": "Invalid Token",\
"message": {\
"id": "Sukses",\
"en": "Success"\
},\
"data": {\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z"\
}\
}\
{[ENDIF]}\Callback adalah proses lanjutan yang dilakukan oleh Universal REST Simulator setelah menerima request dari klien. Proses ini berbeda dengan respon. Pada proses asinkron, server akan melakukan request ke endpoint lain setelah menerima request dari klein. Endpoin untuk proses callback bisa ditentukan di konfigurasi server dan bisa pula dikirim oleh klien yang melakukan request ke server. Pada Universal REST Simulator, endpoin callback ditentukan di file konfigurasi.
Selain endpoint callback, ada beberapa parameter callback yang dapat ditentukan di dalam file konfigurasi, di antaranya adalah sebagai berikut:
$OUTPUT.CALLBACK_URLadalah URL yang dituju pada proses callback.$OUTPUT.CALLBACK_METHODadalah method dari request callback. Method yang dapat digunakan adalahGET,POST, danPUT.$OUTPUT.CALLBACK_TYPEadalah content type untuk request callback. Content type ini bebas sesuai kebutuhan.$OUTPUT.CALLBACK_TIMEOUTadalah timeout untuk request callback.$OUTPUT.CALLBACK_DELAYadalah delay untuk request callback. Delay ini dapat digunakan untuk mengatur jarak antara waktu respon dikirim dan waktu callback dikirim.$OUTPUT.CALLBACK_DELAYsangat cocok untuk simulator transaksi asinkron.$OUTPUT.CALLBACK_HEADERadalah request header untuk callback. Pengguna dapat menambahkan header apapun sesuai dengan protokol HTTP yang digunakan.$OUTPUT.CALLBACK_BODYadalah request body untuk callback. Body harus sesuai dengan$OUTPUT.CALLBACK_TYPEatau$OUTPUT.CALLBACK_HEADERyang diberikan.
Contoh Konfigurasi:
PATH=/universal-rest-simulator/xml
METHOD=POST
REQUEST_TYPE=application/xml
RESPONSE_TYPE=application/xml
PARSING_RULE=\
$INPUT.PRODUCT=$REQUEST.product_code\
$INPUT.ACCOUNT=$REQUEST.customer_no\
$INPUT.REF_NUMBER=$REQUEST.refno\
$INPUT.AMOUNT=$REQUEST.amount
TRANSACTION_RULE=\
{[IF]} ($INPUT.PRODUCT == "10000" && $INPUT.ACCOUNT == "081266612126" && $INPUT.AMOUNT > 0)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.CALLBACK_URL=http://localhost/test/\
$OUTPUT.CALLBACK_METHOD=POST\
$OUTPUT.CALLBACK_TYPE=application/xml\
$OUTPUT.CALLBACK_HEADER=X-Server-Name: Universal REST Simulator\
X-Response-Code: 00\
X-Response-Text: Success\
$OUTPUT.CALLBACK_BODY=<?xml version="1.0" encoding="UTF-8"?>\
<data>\
<rc>00</rc>\
<sn>82634862385235365285</sn>\
<nama>config2</nama>\
<customer_no>$INPUT.ACCOUNT</customer_no>\
<product_code>$INPUT.PRODUCT</product_code>\
<time_stamp>$DATE('j F Y H:i:s', 'UTC+7')</time_stamp>\
<msg>Ini output dari callback Transaksi ini dikenakan biaya Rp. 250</msg>\
<refid>$INPUT.REF_NUMBER</refid>\
<data>\
$OUTPUT.HEADER=X-Server-Name: Universal REST Simulator\
X-Response-Code: 00\
X-Response-Text: Success\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<data>\
<rc>25</rc>\
<nama>config2</nama>\
<customer_no>$INPUT.ACCOUNT</customer_no>\
<product_code>$INPUT.PRODUCT</product_code>\
<time_stamp>$DATE('j F Y H:i:s', 'UTC+7')</time_stamp>\
<msg>Transaksi ini dikenakan biaya Rp. 250</msg>\
<refid>$INPUT.REF_NUMBER</refid>\
<data>\
{[ENDIF]}\
{[IF]} ($INPUT.PRODUCT == "10001" && $INPUT.ACCOUNT == "081266612127")\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<data>\
<rc>00</rc>\
<sn>82634862385235365285</sn>\
<nama>config2</nama>\
<customer_no>$INPUT.ACCOUNT</customer_no>\
<product_code>$INPUT.PRODUCT</product_code>\
<time_stamp>$DATE('j F Y H:i:s', 'UTC+7')</time_stamp>\
<msg>Transaksi ini dikenakan biaya Rp. 250</msg>\
<refid>$INPUT.REF_NUMBER</refid>\
<data>\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY=<?xml version="1.0" encoding="UTF-8"?>\
<data>\
<rc>25</rc>\
<nama>config2</nama>\
<customer_no>$INPUT.ACCOUNT</customer_no>\
<product_code>$INPUT.PRODUCT</product_code>\
<time_stamp>$DATE('j F Y H:i:s', 'UTC+7')</time_stamp>\
<msg>Pelanggan tidak ditemukan</msg>\
<refid>$INPUT.REF_NUMBER</refid>\
<data>\
{[ENDIF]}\Delay atau sleep digunakan untuk menahan proses selama waktu tertentu. Untuk menerapkan delay pada respon, gunakan $OUTPUT.DELAY. Delay sangat berguna untuk test case time out. Simulator akan melakukan sleep selama waktu tertentu sebelum kemudian mengirimkan respon ke klien. Delay pada Universal REST Simulator diatur pada file konfigurasi sesuai dengan kondisi yang telah ditetapkan. Delay memiliki satuan mili detik.
$OUTPUT.DELAY juga akan mempengaruhi mempengaruhi pengiriman callback (jika ada). Pada prinsipnya, callback akan selalu dikirimkan setelah respon dikirim. Dengan demikian, jika $OUTPUT.DELAY adalah diset 5000 mili detik dan $OUTPUT.CALLBACK_DELAY diset 7000 mili detik, maka respon akan diterima 5 detik setelah request transaksi dikirim dan callback akan diterima 12 detik setelah request transaksi dikirim.
Contoh Konfigurasi:
METHOD=POST
PATH=/postjson
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.NAME=$REQUEST.name\
$INPUT.EMAIL=$REQUEST.email\
$INPUT.PHONE=$REQUEST.phone
TRANSACTION_RULE=\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "" && $INPUT.PHONE == "081222222222)\
{[THEN]}\
$OUTPUT.DELAY=5000\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "" && $INPUT.PHONE == "081222222223)\
{[THEN]}\
$OUTPUT.DELAY=15000\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} ($INPUT.NAME != "" && $INPUT.EMAIL != "" && $INPUT.PHONE == "081222222224)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.STATUS=200 OK\
$OUTPUT.BODY={\
"response_code": "001",\
"response_text": "Success",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=400 Bad Request\
$OUTPUT.BODY={\
"response_code": "061",\
"response_text": "Mandatory field can not be empty",\
"data": {\
"name": "$INPUT.NAME",\
"email": "$INPUT.EMAIL",\
"phone": "$INPUT.PHONE",\
"time_stamp": "$DATE('U')"\
}\
}\
{[ENDIF]}\Pada contoh di atas, apabila parameter data.phone memiliki nilai 081222222222, maka simulator akan melakukan sleep selama 5 detik. Apabila parameter data.phone memiliki nilai 081222222223, maka simulator akan melakukan sleep selama 15 detik. Apabila parameter data.phone memiliki nilai 081222222224, maka simulator tidak akan melakukan sleep.
Fungsi $DATE() berguna untuk membuat tanggal dan jam secara otomatis. Tanggal dan jam akan mengikuti waktu server. Pengguna dapat menggunakan daerah waktu.
Format $DATE() mengikuti format pada bahasa pemrograman PHP. Berikut ini merupakan penjelasan dari format $DATE() pada bahasa pemrograman PHP. Untuk menyisipkan karakter konstan pada fungsi $DATE(), awali dengan \. Misalnya $DATE('Y-m-d\TH:i:s.000\Z', 'UTC+7') akan menampilkan 2020-10:10T20:20:20.000Z. Perhatikan bahwa \T akan menjadi T dan \Z akan menjadi Z.
| format character | Description | Example returned values |
|---|---|---|
| Day | --- | --- |
| d | Day of the month, 2 digits with leading zeros | 01 to 31 |
| D | A textual representation of a day, three letters | Mon through Sun |
| j | Day of the month without leading zeros | 1 to 31 |
| l (lowercase 'L') | A full textual representation of the day of the week | Sunday through Saturday |
| N | ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) | 1 (for Monday) through 7 (for Sunday) |
| S | English ordinal suffix for the day of the month, 2 characters | st, nd, rd or th. Works well with j |
| w | Numeric representation of the day of the week | 0 (for Sunday) through 6 (for Saturday) |
| z | The day of the year (starting from 0) | 0 through 365 |
| Week | --- | --- |
| W | ISO-8601 week number of year, weeks starting on Monday | Example: 42 (the 42nd week in the year) |
| Month | --- | --- |
| F | A full textual representation of a month, such as January or March | January through December |
| m | Numeric representation of a month, with leading zeros | 01 through 12 |
| M | A short textual representation of a month, three letters | Jan through Dec |
| n | Numeric representation of a month, without leading zeros | 1 through 12 |
| t | Number of days in the given month | 28 through 31 |
| Year | --- | --- |
| L | Whether it's a leap year | 1 if it is a leap year, 0 otherwise. |
| o | ISO-8601 week-numbering year. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0) | Examples: 1999 or 2003 |
| Y | A full numeric representation of a year, 4 digits | Examples: 1999 or 2003 |
| y | A two digit representation of a year | Examples: 99 or 03 |
| Time | --- | --- |
| a | Lowercase Ante meridiem and Post meridiem | am or pm |
| A | Uppercase Ante meridiem and Post meridiem | AM or PM |
| B | Swatch Internet time | 000 through 999 |
| g | 12-hour format of an hour without leading zeros | 1 through 12 |
| G | 24-hour format of an hour without leading zeros | 0 through 23 |
| h | 12-hour format of an hour with leading zeros | 01 through 12 |
| H | 24-hour format of an hour with leading zeros | 00 through 23 |
| i | Minutes with leading zeros | 00 to 59 |
| s | Seconds with leading zeros | 00 through 59 |
| u | Microseconds (added in PHP 5.2.2). Note that date() will always generate 000000 since it takes an int parameter, whereas DateTime::format() does support microseconds if DateTime was created with microseconds. | Example: 654321 |
| v | Milliseconds (added in PHP 7.0.0). Same note applies as for u. | Example: 654 |
| Timezone | --- | --- |
| e | Timezone identifier (added in PHP 5.1.0) | Examples: UTC, GMT, Atlantic/Azores |
| I (capital i) | Whether or not the date is in daylight saving time | 1 if Daylight Saving Time, 0 otherwise. |
| O | Difference to Greenwich time (GMT) without colon between hours and minutes | Example: +0200 |
| P | Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3) | Example: +02:00 |
| T | Timezone abbreviation | Examples: EST, MDT ... |
| Z | Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. | -43200 through 50400 |
| Full Date/Time | --- | --- |
| c | ISO 8601 date (added in PHP 5) | 2004-02-12T15:19:21+00:00 |
| r | » RFC 2822 formatted date | Example: Thu, 21 Dec 2000 16:01:07 +0200 |
| U | Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) | See also time() |
Sumber: https://www.php.net/manual/en/datetime.format.php
Catatan: Semua karakter yang tidak dikenali dalam string format akan dicetak apa adanya.
Fungsi $CALC() sangat berguna untuk melakukan operasi matematika di mana $INPUT menjadi salah satu operandnya.
Sebagai contoh: pengguna akan menambahkan jumlah tagihan dengan admin fee. Jika tagihan disimpan di dalam variabel $INPUT.AMOUNT dan admin fee disimpan dalam variabel $INPUT.FEE, maka dapat ditulis dengan $CALC($INPUT.AMOUNT + $INPUT.FEE). Jika admin fee adalah nilai tetap yaitu 2500, maka dapat ditulis dengan $CALC($INPUT.AMOUNT + 2500).
Fungsi $CALC() juga dapat menghitung rumus dalam pasangan kurung. Contoh: $CALC($INPUT.AMOUNT + $INPUT.FEE + ($INPUT.AMOUNT * 10/100)) dan sebagainya. Perhatikan bahwa jumlah kurung buka harus sama dengan jumlah kurung tutup.
PATH=/biller/post/json
METHOD=POST
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.PRODUCT=$REQUEST.product_code\
$INPUT.ACCOUNT=$REQUEST.customer_no\
$INPUT.REF_NUMBER=$REQUEST.refno\
$INPUT.AMOUNT=$REQUEST.amount\
$INPUT.FEE=$REQUEST.admin_fee
TRANSACTION_RULE=\
{[IF]} ($INPUT.PRODUCT == "322112" && $INPUT.FEE > 0)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"rc": "00",\
"description": "Success",\
"mitra_code": "904",\
"product_code": "322112",\
"merchant_type": "5612",\
"customer_no": "$INPUT.ACCOUNT",\
"product_name": "GOPAY",\
"phone_number": "$INPUT.ACCOUNT",\
"name": "GOPAY GP-$INPUT.ACCOUNT",\
"amount": $INPUT.AMOUNT,\
"admin": $INPUT.FEE,\
"total": $CALC($INPUT.AMOUNT + $INPUT.FEE),\
"transaction_date": "$DATE('d-m-Y H:i:s', 'UTC+9')",\
"transaction_code": "000002873147"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.PRODUCT == "322112")\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"rc": "00",\
"description": "Success",\
"mitra_code": "904",\
"product_code": "322112",\
"merchant_type": "5612",\
"customer_no": "$INPUT.ACCOUNT",\
"product_name": "GOPAY",\
"phone_number": "$INPUT.ACCOUNT",\
"name": "GOPAY GP-$INPUT.ACCOUNT",\
"amount": $INPUT.AMOUNT,\
"admin": 2500,\
"total": $CALC($INPUT.AMOUNT + 2500),\
"transaction_date": "$DATE('d-m-Y H:i:s', 'UTC+9')",\
"transaction_code": "000002873147"\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"rc": "00",\
"description": "Success",\
"mitra_code": "904",\
"product_code": "322112",\
"merchant_type": "5612",\
"customer_no": "$INPUT.ACCOUNT",\
"product_name": "GOPAY",\
"phone_number": "$INPUT.ACCOUNT",\
"name": "GOPAY GP-$INPUT.ACCOUNT",\
"amount": $INPUT.AMOUNT,\
"admin": 2500,\
"total": $CALC($INPUT.AMOUNT + 2500),\
"transaction_date": "$DATE('d-m-Y H:i:s')",\
"transaction_code": "000002873147"\
}\
{[ENDIF]}\Fungsi $ISVALIDTOKEN() digunakan pada kondisi untuk memvalidasi token yang dikirimkan melalui Authorization: Bearer. Simulator akan mengambil token yang dikirimkan melalui header dengan key Autorization. Token ini kemudian akan divalidasi sesuai dengan konfigurasi server. Apabila token tersebut benar, $ISVALIDTOKEN() akan bernilai true. Sebaliknya, apabila token tersebut salah, $ISVALIDTOKEN() akan bernilai false.
Fungsi $ISVALIDTOKEN() dapat mengkonfirmasi apakah aplikasi sudah mengirimkan token dengan benar sesuai dengan token yang diberikan oleh simulator. Simulator hanya akan memvalidasi token yang dibuat oleh simulator itu sendiri.
Fungsi $NUMBERFORMAT() digunakan untuk memformat suatu bilangan. Jumlah parameter pada fungsi ini bisa 1, 2 atau 3. Fungsi ini identik dengan fungsi number_format pada PHP. Tutorial fungsi ini dapat dibaca di https://www.php.net/manual/en/function.number-format.php
Nilai balikan atau output dari fungsi ini bertipe string. Perlu dicatat bahwa Universal REST Simulator bekerja pada mode teks. Dengan demikian, output dari fungsi $NUMBERFORMAT() pada JSON wajib diberi tanda kutip.
Contoh penggunaan fungsi ini adalah $NUMBERFORMAT($INPUT.AMOUNT, 2, ',', '.') di mana $INPUT.AMOUNT adalah nilai yang akan ditampilkan.
Contoh Konfigurasi:
METHOD=POST
PATH=/basicauth
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.USERNAME == "user1" && $INPUT.PASSWORD == "password1" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}\
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": 69,\
"data": {\
"date_time": "$INPUT.DATE_TIME",\
"name": "Bambang",\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": "$NUMBERFORMAT($INPUT.AMOUNT, 2, ',', '.')",\
"currency_code": "$INPUT.CURRENCY"\
},\
"response_code": "001",\
"response_text": "Success"\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=403\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {},\
"response_code": "062",\
"response_text": "Access forbidden"\
}\
{[ENDIF]}\Contoh Request:
GET /basicauth HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Content-Type: application/json
Accept: application/json
Content-Length: 118
Authorization: Basic dXNlcjE6cGFzc3dvcmQx
{
"data": {
"account_number": "98765432",
"amount": 250000,
"currency_code": "IDR"
}
}Contoh Respon:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 291
{
"action": "deposit",
"id": 69,
"data": {
"date_time": "2021-05-01T10:11:12.000Z",
"name": "Bambang",
"account_number": "123456",
"amount": "250,000.00",
"currency_code": "IDR"
},
"response_code": "001",
"response_text": "Success"
}Parameter
Opsional
integer param1
integer param2
Jika param1 dan param2 tidak ada, fungsi ini akan menghasilkan bilangan bulat acak dari fungsi mt_rand() pada PHP asli.
Jika param1 ada dan param2 tidak ada, fungsi ini akan menghasilkan bilangan bulat acak dari fungsi mt_rand(0, abs(param1)) pada PHP asli.
Jika ada param1 dan param2, fungsi ini akan menghasilkan bilangan bulat acak dari fungsi mt_rand(min(abs(param1), abs(param2)), max(abs(param1), abs(param2))) pada PHP asli.
Contoh Konfigurasi:
METHOD=POST
PATH=/basicauth
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=\
$INPUT.USERNAME=$AUTHORIZATION_BASIC.USERNAME\
$INPUT.PASSWORD=$AUTHORIZATION_BASIC.PASSWORD\
$INPUT.ACCOUNT_NUMBER=$REQUEST.data.account_number\
$INPUT.AMOUNT=$REQUEST.data.amount\
$INPUT.CURRENCY=$REQUEST.data.currency_code
TRANSACTION_RULE=\
{[IF]} ($INPUT.USERNAME == "user1" && $INPUT.PASSWORD == "password1" && $INPUT.ACCOUNT_NUMBER != "" && $INPUT.AMOUNT > 0)\
{[THEN]}\
$OUTPUT.STATUS=200\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": 69,\
"data": {\
"date_time": "$INPUT.DATE_TIME",\
"name": "Bambang",\
"account_number": "$INPUT.ACCOUNT_NUMBER",\
"amount": "$NUMBERFORMAT($INPUT.AMOUNT, 2, ',', '.')",\
"reference_number": "$SYSTEM.RANDOM(100000, 999999)",\
"currency_code": "$INPUT.CURRENCY"\
},\
"response_code": "001",\
"response_text": "Success"\
}\
{[ENDIF]}\
{[IF]} (true)\
{[THEN]}\
$OUTPUT.STATUS=403\
$OUTPUT.BODY={\
"action": "$INPUT.TRANSACTION_TYPE",\
"id": "$INPUT.TRANSACTION_ID",\
"data": {},\
"response_code": "062",\
"response_text": "Access forbidden"\
}\
{[ENDIF]}\Parameter
Opsional
string selector
boolean asText, default false
Jika selector dan asText tidak diberikan, fungsi ini akan mengembalikan seluruh JSON object dari request.
Jika selector diberikan dan asText tidak diberikan, fungsi ini akan mengembalikan JSON object dari request sesuai dengan selector.
Jika selector diberikan dan asText diberikan, fungsi ini akan mengembalikan JSON object dari request sesuai dengan selector. Jika asText adalah true, fungsi ini akan mengkonversi JSON object dari selector menjadi string yang diescape.
Pada beberapa kasus, pengguna perlu menirimkan kembali request JSON dari klien di respon. Pengguna dapat mengambil request secara keseluruhan maupun salah satu properti dari JSON. Pengguna dapat mengambilnya sebagai objek JSON maupun sebagai string.
Contoh Request
{
"transaction_id": "164084965152152228",
"request": {
"data": {
"lastBalance": "59978",
"dateTime": "2017-11-11 10:10:10.123",
"approvalCode": "CCD970377BCD",
"dataToSam": "12121233345454323",
"merchantId": "TESTMID1",
"session": "sessionid123",
"terminalId": "TESTTID1",
"cardNumber": "6032984002487720"
},
"command": "update-balance"
},
"partner_info": {
"partnerID": 80,
"adapterEndpoint": "http://localhost:3000/process-biller"
},
"client_name": "Dora Remitance",
"client_id": 1
}
$JSON.REQUEST() atau $JSON.REQUEST('') akan mengembalikan JSON object yaitu:
{
"transaction_id": "164084965152152228",
"request": {
"data": {
"lastBalance": "59978",
"dateTime": "2017-11-11 10:10:10.123",
"approvalCode": "CCD970377BCD",
"dataToSam": "12121233345454323",
"merchantId": "TESTMID1",
"session": "sessionid123",
"terminalId": "TESTTID1",
"cardNumber": "6032984002487720"
},
"command": "update-balance"
},
"partner_info": {
"partnerID": 80,
"adapterEndpoint": "http://localhost:3000/process-biller"
},
"client_name": "Dora Remitance",
"client_id": 1
}
$JSON.REQUEST('request') akan mengembalikan JSON object yaitu:
{
"data": {
"lastBalance": "59978",
"dateTime": "2017-11-11 10:10:10.123",
"approvalCode": "CCD970377BCD",
"dataToSam": "12121233345454323",
"merchantId": "TESTMID1",
"session": "sessionid123",
"terminalId": "TESTTID1",
"cardNumber": "6032984002487720"
},
"command": "update-balance"
}
$JSON.REQUEST('request.data') akan mengembalikan JSON object yaitu:
{
"lastBalance": "59978",
"dateTime": "2017-11-11 10:10:10.123",
"approvalCode": "CCD970377BCD",
"dataToSam": "12121233345454323",
"merchantId": "TESTMID1",
"session": "sessionid123",
"terminalId": "TESTTID1",
"cardNumber": "6032984002487720"
}
$JSON.REQUEST('request.data', false) akan mengembalikan JSON object yaitu:
{
"lastBalance": "59978",
"dateTime": "2017-11-11 10:10:10.123",
"approvalCode": "CCD970377BCD",
"dataToSam": "12121233345454323",
"merchantId": "TESTMID1",
"session": "sessionid123",
"terminalId": "TESTTID1",
"cardNumber": "6032984002487720"
}
$JSON.REQUEST('request.data', true) akan mengembalikan string yaitu:
"{\"lastBalance\":\"59978\",\"dateTime\":\"2017-11-11 10:10:10.123\",\"approvalCode\":\"CCD970377BCD\",\"dataToSam\":\"12121233345454323\",\"merchantId\":\"TESTMID1\",\"session\":\"sessionid123\",\"terminalId\":\"TESTTID1\",\"cardNumber\":\"6032984002487720\"}"
Jika ingin mengambil element tertentu dari array, $JSON.REQUEST('request.data', false) dapat ditulis dengan $JSON.REQUEST('[request][data]', false) dan $JSON.REQUEST('request.data', true) dapat ditulis dengan $JSON.REQUEST('[request][data]', true). Dengan demikian, untuk mengambil data bill ke 2 dari request berikut:
{
"transaction_id": "164084965152152228",
"request": {
"data": {
"lastBalance": "59978",
"dateTime": "2017-11-11 10:10:10.123",
"approvalCode": "CCD970377BCD",
"dataToSam": "12121233345454323",
"merchantId": "TESTMID1",
"session": "sessionid123",
"terminalId": "TESTTID1",
"cardNumber": "6032984002487720",
"bill": [
{
"date": "2017-10-11",
"amount": 120000
},
{
"date": "2017-11-11",
"amount": 350000
}
]
},
"command": "update-balance"
},
"partner_info": {
"partnerID": 80,
"adapterEndpoint": "http://localhost:3000/process-biller"
},
"client_name": "Dora Remitance",
"client_id": 1
}
dapat ditulis dengan $JSON.REQUEST('[request][data][bill][1]', false). Ingat bahwa index array selalu diawali dengan 0. Pada kasus di atas, $JSON.REQUEST('[request][data][bill][1]', false) akan mengembalikan JSON object yaitu:
{
"date": "2017-11-11",
"amount": 350000
}
dan $JSON.REQUEST('[request][data][bill][1]', true) akan mengembalikan string yaitu:
"{\n \"date\": \"2017-11-11\",\n \"amount\": 350000\n}"
Contoh Konfigurasi
METHOD=POST
PATH=/process-biller
REQUEST_TYPE=application/json
RESPONSE_TYPE=application/json
PARSING_RULE=$INPUT.COMMAND=$REQUEST.request.command\
$INPUT.CARD_NUMBER=$REQUEST.request.data.cardNumber\
$INPUT.LAST_BALANCE=$REQUEST.request.data.lastBalance\
$INPUT.APPROVAL_CODE=$REQUEST.request.data.approvalCode\
$INPUT.RESPONSE_FROM_SAM=$REQUEST.request.data.dataToSam\
$INPUT.SESSION=$REQUEST.request.data.session\
$INPUT.DATA=$JSON.REQUEST('request.data', false)
TRANSACTION_RULE=\
{[IF]} ($INPUT.COMMAND == 'get-balance')\
{[THEN]}\
$OUTPUT.STATUS=200\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"data": {\
"message": "9000"\
},\
"message_to_provider":$INPUT.DATA,\
"message_from_provider": "{\r\n \"data\": {\r\n \"message\": \"9000\"\r\n }\r\n}",\
"time_stamp": "$DATE('Y-m-d H:i:s', 'UTC+3')"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.COMMAND == 'update-balance')\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"data": {\
"lastBalance": "$INPUT.LAST_BALANCE",\
"amount": "20000",\
"approvalCode": "$INPUT.APPROVAL_CODE",\
"responseFromSam": "$INPUT.RESPONSE_FROM_SAM",\
"cardNumber": "$INPUT.CARD_NUMBER"\
},\
"message_to_provider":$INPUT.DATA,\
"message_from_provider": "{\r\n \"data\": { \r\n \"lastBalance\": \"$INPUT.LAST_BALANCE\", \r\n \"amount\": \"20000\", \r\n \"approvalCode\": \"$INPUT.APPROVAL_CODE\", \r\n \"responseFromSam\": \"$INPUT.RESPONSE_FROM_SAM\", \r\n \"cardNumber\": \"$INPUT.CARD_NUMBER\" \r\n } \r\n}"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.COMMAND == 'confirm-balance')\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"data": {\
"session": "$INPUT.SESSION",\
"cardNumber": "$INPUT.CARD_NUMBER"\
},\
"message_to_provider":$INPUT.DATA,\
"message_from_provider": "{}"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.COMMAND == 'card-command')\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"data": {\
"message": "9948594365465-989\n"\
},\
"message_to_provider":$INPUT.DATA,\
"message_from_provider": "{\"data\":{\"message\":\"9948594365465-989\\n\"}}"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.COMMAND == 'reverse-balance')\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"data": {\
"approvalCode": "$INPUT.APPROVAL_CODE",\
"cardNumber": "$INPUT.CARD_NUMBER"\
},\
"message_to_provider":$INPUT.DATA,\
"message_from_provider": "{\r\n \"data\": {\r\n \"approvalCode\": \"$INPUT.APPROVAL_CODE\",\r\n \"cardNumber\": \"$INPUT.CARD_NUMBER\"\r\n } \r\n}"\
}\
{[ENDIF]}\
{[IF]} ($INPUT.COMMAND == 'transaction-history')\
{[THEN]}\
$OUTPUT.STATUS=200 OK\
$OUTPUT.DELAY=0\
$OUTPUT.BODY={\
"command": "$INPUT.COMMAND",\
"time_stamp": "$DATE('Y-m-d\TH:i:s', 'UTC').000Z",\
"data": {\
"message": "90000"\
},\
"message_to_provider":$INPUT.DATA,\
"message_from_provider": "{\"data\":{\"message\":\"90000\"}}"\
}\
{[ENDIF]}\
Contoh Request
POST /process-biller HTTP/1.1
Host: 127.0.0.1
User-Agent: Service
Accept: application/json
Content-Type: application/json
Content-Length: 512
{
"transaction_id": "164084311750751184",
"request": {
"data": {
"cardAttribute": "09091607595453006BA8009000",
"lastBalance": "2500",
"amount": "0",
"approvalCode": "CCD970377BCD",
"cardInfo": "6032984002487795180801207024050300910301060000000000032091B0790781A29D250353DBF97C96CE510D17C800000000000000000000035E92D2FFFF9000",
"cardUUID": "2F865948"
},
"command": "transaction-history"
},
"client_name": "Dora Remitance",
"client_id": 1
}
Contoh Response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Lengh: 515
{
"command": "transaction-history",
"time_stamp": "2021-12-30T05:45:19.000Z",
"data": {
"message": "90000"
},
"message_to_provider":"{\"cardAttribute\":\"09091607595453006BA8009000\",\"lastBalance\":\"2500\",\"amount\":\"0\",\"approvalCode\":\"CCD970377BCD\",\"cardInfo\":\"6032984002487795180801207024050300910301060000000000032091B0790781A29D250353DBF97C96CE510D17C800000000000000000000035E92D2FFFF9000\",\"cardUUID\":\"2F865948\"}",
"message_from_provider": "{\"data\":{\"message\":\"90000\"}}"
}
Pada beberapa kasus, simulator tidak dapat dibuat dengan file konfigurasi saja. Proses yang terlalu rumit seperti membaca atau menyimpan data transaksi ke database atau sistem file, melakukan enkripsi dan dekripsi, mengkonversi data dari satu bentuk ke bentuk lain, dan sebagainya harus ditangani oleh bahasa pemrograman.
Universal REST Simulator memungkinkan pengguna untuk membuat sendiri kode PHP natif. Cara ini sebenarnya tidak direkomendasikan karena dapat membahayakan simulator. Namun jika pengguna memahami bahasa PHP dengan baik, maka cara ini dapat dilakukan dan akan memberikan hasil yang lebih baik pula.
Untuk menuliskan kode PHP natif pada simulator sangat mudah. Pertama, tentukan METHOD dan PATH kemudian tulis kode PHP di antara {[EVAL_PHP_BEGIN]} dan {[EVAL_PHP_END]}
Parsing data input tentu saja dilakukan secara manual tergantung dari method dan content-type yang dikirim oleh klien.
Apabila file konfigurasi mengandung {[EVAL_PHP_BEGIN]} dan {[EVAL_PHP_END]}, maka yang akan diproses hanyalah METHOD dan PATH saja. Konfigurasi selain METHOD dan PATH akan diabaikan. Simulator akan mengalihkan proses pada kode di antara {[EVAL_PHP_BEGIN]} dan {[EVAL_PHP_END]}.
Pengguna boleh membuat lebih dari satu blok {[EVAL_PHP_BEGIN]} dan {[EVAL_PHP_END]}. Akan tetapi cara ini sangat tidak disarankan. Selain karena pengguna tidak bisa menuliskan konfigurasi lain di luar blok tersebut, pengiriman response header yang dilakukan setelah simulator mengirimkan response body juga dianggap sebagai kesalahan pemrograman sehingga simulator mungkin akan mengirimkan HTTP status 500 Internal Server Error.
Penggunaan Universal REST Simulator untuk kode PHP natif ini lebih kepada penggunaan server HTTP dan interpreter PHP dari simulator yang ada sehingga pengguna tidak perlu membuat server baru untuk membuat beberapa simulator yang mutlak memerlukan kode PHP natif.
Contoh phpinfo()
METHOD=GET
PATH=/php/info
{[EVAL_PHP_BEGIN]}
phpinfo();
{[EVAL_PHP_END]}
Contoh di atas akan menampilkan halaman yang berisi PHPINFO.
Contoh Konfigurasi
METHOD=POST
PATH=/encrypted/payload/
{[EVAL_PHP_BEGIN]}
function encryptEBC($key, $payload){
return bin2hex(openssl_encrypt($payload, 'aes-128-ecb', $key, OPENSSL_RAW_DATA));
}
function decriptEBC($key, $payload){
return openssl_decrypt(hex2bin($payload), 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
}
$rc = '00';
$key = "iY87^R76R%e4d7tD";
$clientID = @$_POST['login'];
$pwd = @$_POST['pwd'];
$terminal = @$_POST['terminal'];
$customer = @$_POST['customer'];
$trx_date = @$_POST['trx_date'];
$trx_type = @$_POST['trx_type'];
$sequence_id = @$_POST['sequence_id'];
$tx_amount = @$_POST['tx_amount'];
$isreversal = @$_POST['isreversal'];
$pwd = decriptEBC($key, $pwd);
$terminal = decriptEBC($key, $terminal);
$customer = decriptEBC($key, $customer);
$trx_date = decriptEBC($key, $trx_date);
$trx_type = decriptEBC($key, $trx_type);
$sequence_id = decriptEBC($key, $sequence_id);
if($customer == '0725553725')
{
$rc = '00';
}
header("Content-type: text/plain");
echo "$rc:$sequence_id";
{[EVAL_PHP_END]}
Pada contoh di atas, $sequence_id dienkripsi oleh klien lalu didekripsi oleh simulator. Algoritma enkripsi tentu saja harus tersedia di PHP di mana simulator berjalan.
Callback dapat dilakukan dengan CURL. Contoh CURL PHP dapat dilihat di https://www.php.net/manual/en/ref.curl.php