iPay88 Indonesia - Core API

Selamat datang di laman Core API iPay88 Indonesia.
Segera integrasikan API ini dengan situs Anda untuk memulai transaksi dengan gerbang pembayaran iPay88 Indonesia.

Catatan Penting
  1. iPay88 Indonesia belum menyediakan fitur iFrame untuk payment page di laman merchant.
  2. Metode CURL tidak dapat digunakan untuk seluruh API iPay88 Indonesia.
  3. Lakukan uji transaksi pada fase development atau sandbox terlebih dahulu sebelum memasuki fase production.
  4. Pastikan seluruh kode yang Anda tulis telah memenuhi standar pemrograman dan keamanan data.

Online Payment System Gateway Versi 1.6.3

Segera integrasikan iPay88 Online Payment System Gateway (OPSG) ini dengan situs Anda. API ini menjadikan situs Anda untuk menerima pembayaran online secara langsung melalui iPay88 Indonesia.


Download OPSG Verse 1.6.3

ePayment

Segmen ini menjelaskan fungsionalitas dari sistem Online Payment Switching Gateway (OPSG) iPay88 Indonesia. Diantaranya:

  1. ePayment: berbagai metode pembayaran untuk situs e-commerce milik merchant.
  2. Reports: online view transaction report.


Objektif

Merchant dapat menyediakan berbagai metode pembayaran kepada pelanggan untuk melakukan pembayaran secara langsung dengan metode HTTPs Post Form Data melalui iPay88 Indonesia.


Prasyarat Integrasi Merchant

  1. Diharuskan menggunakan merchant code dan merchant key dari iPay88 Indonesia.
  2. Merchant harus menyediakan request url ke iPay88 Support Team.
  3. Request URL yang terdaftar harus berupa IP atau berbasis domain.
    Catatan: Localhost tidak diperbolehkan.

Catatan Penting

  1. Uji transaksi harus dari Request URL yang terdaftar.
  2. Uji transaksi dengan jumlah IDR 3.000,00.
  3. Uji transaksi bersifat terbatas untuk metode pembayaran dengan kartu kredit.
  4. Uji transaksi dengan kartu kredit akan dikembalikan (refund) pada hari akhir.
  5. Response URL dapat diatur dibagian input ResponseURL pada saat request laman pembayaran iPay88.
  6. Backend post URL dapat diatur dibagian input BackendURL pada saat request laman pembayaran iPay88.
  7. Notifikasi email tidak dijamin oleh iPay88 Indonesia karena bergantung pada ISP. Lihat bagian pemberitahuan via email pada laman dokumentasi. Notifikasi email tidak boleh digunakan sebagai patokan identifikasi oleh merchant, gunakan online report untuk memeriksa status pembayaran.
  8. Pastikan orang teknik ditugaskan oleh merchant sebelum integrasi.
  9. Merchant harus memberi tahu iPay88 Support Team untuk tanggal live yang diinginkan minimal 3 hari kerja sebelumnya.

Diagram Transaksi

Berikut ini adalah diagram alir transaksi merchant dengan iPay88 Indonesia.


Proses Transaksi

Berikut ini adalah proses transaksi merchant dengan iPay88 Indonesia.

  1. Merchant mengirimkan HTTPs Post Request yang berisi detail pembayaran ke laman pembayaran iPay88 Indonesia. Detil pembayaran harus menyertakan:
    1. Merchant Code.
    2. Payment Method.
    3. Merchant Reference Number.
    4. Payment Amount.
    5. Currency.
    6. Product Description.
    7. Customer Name.
    8. Customer Email.
    9. Customer Contact.
    10. Merchant Remark.
    11. Signature.
    12. Response URL.
    13. Backend URL.

  2. Pengguna melihat dan mengkonfirmasi rincian pembayaran disertakan pada proses nomor 1. Untuk metode pembayaran dengan kartu kredit, pengguna perlu memasukkan informasi kartu kredit.

  3. Pengguna meneruskan sampai mengisi nama pengguna dan kata sandi di laman bank (untuk metode pembayaran selain kartu kredit).

  4. Pengguna memilih akun untuk mendebit pembayaran (untuk metode pembayaran selain kartu kredit).

  5. Pengguna mengonfirmasi pembayaran. Jika ya, lanjut ke-langkah berikutnya (untuk metode pembayaran selain kartu kredit).

  6. Pengguna melihat dan cetak detil pembayaran (untuk metode pembayaran selain kartu kredit).

  7. Respon dikembalikan ke iPay88 Indonesia untuk untuk menunjukkan apakah transaksi telah berhasil atau gagal.

  8. iPay88 Indonesia merespon kembali status pembayaran ke merchant dengan signature.

  9. Jika status pembayaran sukses, merchant harus membandingkan signature dari iPay88 Indonesia dengan signature yang dihasilkan oleh merchant.

Integrasi Merchant

Berikut ini adalah langkah-langkah integrasi merchant dengan iPay88 online payment switching gateway (OPSG).


URL

  1. Development: https://sandbox.ipay88.co.id/epayment/entry.asp
  2. Production: https://payment.ipay88.co.id/epayment/entry.asp
  3. Requery: https://payment.ipay88.co.id/epayment/enquiry.asp

Merchant Request URL disediakan oleh merchant sebelum integrasi.

Definisi: Merchant Request URL adalah laman pembayaran di situs merchant yang mengirimkan parameter / nilai yang diperlukan ke iPay88 OPSG.


Merchant Response URL dapat ditentukan dengan mengisi parameter ResponseURL di laman request.

Definisi: Response page URL adalah laman di situs merchant yang akan menerima status pembayaran dari iPay88 OPSG.


Logo

iPay88 OPSG menyediakan merchant logo/banner tampil di laman pembayaran dan pemberitahuan email. Merchant dapat memberikan logo ke tim iPay88 Support untuk diunggah ke akun merchant.

Ukuran maksimum yang diperbolehkan untuk logo adalah 600 piksel (lebar) dan 100 piksel (tinggi). Format yang diperbolehkan adalah JPG, PNG, BMP, dan GIF.


Payment Request Parameter

Berikut ini adalah parameter request dengan HTTPS POST pada merchant yang dikirim ke iPay88 OPSG untuk menuju laman pembayaran.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode String (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
PaymentId Integer O Payment ID untuk metode pembayaran yang dituju.
RefNo String (20) M Nomor unik transaksi merchant atau Order ID.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
Currency String (5) M Harus IDR.
ProdDesc String (100) M Deskripsi produk.
UserName String (100) M Nama pelanggan.
UserEmail String (100) M Email pelanggan untuk mendapatkan nota pembayaran.
UserContact String (20) M Nomor kontak pelanggan.
Remark String (100) O Catatan merchant.
Lang String (20) O Encoding type
"ISO-8859-1" – English.
"UTF-8" – Unicode.
"GB2312" – Chinese Simplified.
"GD18030" – Chinese Simplified.
"BIG5" – Chinese Traditionl.
Signature String (100) M SHA signature.
ResponseURL String (200) M Payment response page.
BackendURL String (200) M Backend response page URL.
xfield1 String O Parameter ini hanya berlaku untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

<html>
    <body>

    <form method="post" name="ePayment" action="https://sandbox.ipay88.co.id/epayment/entry.asp">
        <input type="hidden" name="MerchantCode" value="ID00001">
        <input type="hidden" name="PaymentId" value="1">
        <input type="hidden" name="RefNo" value="A00000001">
        <input type="hidden" name="Amount" value="300000">
        <input type="hidden" name="Currency" value="IDR">
        <input type="hidden" name="ProdDesc" value="Photo Print">
        <input type="hidden" name="UserName" value="John Tan">
        <input type="hidden" name="UserEmail" value="john@hotmail.com">
        <input type="hidden" name="UserContact" value="0126500100">
        <input type="hidden" name="Remark" value="">
        <input type="hidden" name="Lang" value="UTF-8">
        <input type="hidden" name="Signature" value="Q/iIMzpjZCrhJ2Yt2dor1PaFEFI=">
        <input type="hidden" name="ResponseURL" value="http://www.abc.com/payment/response.asp">
        <input type="hidden" name="BackendURL" value="http://www.abc.com/payment/backend_response.asp">
        <input type="submit" value="Proceed with Payment" name="Submit"> 
    </form>

    </body>
</html>
<html>
    <body>

<!--Parameter xfield1 ditambahkan khusus untuk metode 
pembayaran kartu kredit dengan fitur cicilan dan diskon-->

    <form method="post" name="ePayment" action="https://sandbox.ipay88.co.id/epayment/entry.asp">
        <input type="hidden" name="MerchantCode" value="ID00001">
        <input type="hidden" name="PaymentId" value="1">
        <input type="hidden" name="RefNo" value="A00000001">
        <input type="hidden" name="Amount" value="300000">
        <input type="hidden" name="Currency" value="IDR">
        <input type="hidden" name="ProdDesc" value="Photo Print">
        <input type="hidden" name="UserName" value="John Tan">
        <input type="hidden" name="UserEmail" value="john@hotmail.com">
        <input type="hidden" name="UserContact" value="0126500100">
        <input type="hidden" name="Remark" value="">
        <input type="hidden" name="Lang" value="UTF-8">
        <input type="hidden" name="Signature" value="Q/iIMzpjZCrhJ2Yt2dor1PaFEFI=">
        <input type="hidden" name="ResponseURL" value="http://www.abc.com/payment/response.asp">
        <input type="hidden" name="BackendURL" value="http://www.abc.com/payment/backend_response.asp">
        <input type="hidden" name="xfield1" value="||IPP:3||">
        <input type="submit" value="Proceed with Payment" name="Submit"> 
    </form>

    </body>
</html>

Payment Response Parameter

Berikut ini adalah respon dengan HTTPS POST dari iPay88 OPSG ke merchant setelah selesai proses pembayaran.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode String (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
PaymentId Integer O Payment ID untuk metode pembayaran yang dituju.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
Currency Varchar (5) M Harus IDR.
Remark Varchar (100) O Catatan merchant.
TransId Varchar (30) O iPay88 OPSG ID Transaksi.
AuthCode Varchar (20) O Kode persetujuan bank.
Status Varchar (1) M Status pembayaran
"1" – Success.
"0" – Fail.
"6" – Pending (hanya tersedia untuk metode pembayaran ATM Transfer).
ErrDesc Varchar (100) O Deskripsi penyebab gagal-nya transaksi (lihat referensi).
Signature Varchar (100) M SHA1 Signature (merujuk ke 3.2).
xfield1 String O Parameter ini hanya berlaku untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.
VirtualAccountAssigned String O Parameter ini hanya berlaku untuk metode pembayaran ATM Transfer.
TransactionExpiryDate String O Parameter ini hanya berlaku untuk metode pembayaran ATM Transfer.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


<%

MerchantCode	= Request.Form("MerchantCode")
PaymentId		= Request.Form("PaymentId")
RefNo			= Request.Form("RefNo")
Amount			= Request.Form("Amount")
eCurrency		= Request.Form("Currency")
Remark			= Request.Form("Remark")
TransId			= Request.Form("TransId")
AuthCode		= Request.Form("AuthCode")
eStatus 			= Request.Form("Status")
ErrDesc 		= Request.Form("ErrDesc")
Signature		= Request.Form("Signature")

%>

<Add your programming code here>
<?php

$merchantcode 	= $_REQUEST["MerchantCode"];
$paymentid 	= $_REQUEST["PaymentId"];
$refno 		= $_REQUEST["RefNo"];
$amount 	= $_REQUEST["Amount"];
$ecurrency 	= $_REQUEST["Currency"];
$remark 	= $_REQUEST["Remark"];
$transid 	= $_REQUEST["TransId"];
$authcode 	= $_REQUEST["AuthCode"];
$estatus 	= $_REQUEST["Status"];
$errdesc 	= $_REQUEST["ErrDesc"];
$signature	= $_REQUEST["Signature"];

?>

//Add your programming code here
<%

'Parameter xfield1 ditambahkan khusus untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.

'Parameter VirtualAccountAssigned dan TransactionExpiryDate ditambahkan khusus untuk metode pembayaran ATM Transfer.

MerchantCode			= Request.Form("MerchantCode")
PaymentId				= Request.Form("PaymentId")
RefNo					= Request.Form("RefNo")
Amount					= Request.Form("Amount")
eCurrency				= Request.Form("Currency")
Remark					= Request.Form("Remark")
TransId					= Request.Form("TransId")
AuthCode				= Request.Form("AuthCode")
eStatus 					= Request.Form("Status")
ErrDesc 				= Request.Form("ErrDesc")
Signature				= Request.Form("Signature")
xfield1 					= Request.Form("xfield1")
VirtualAccountAssigned	= Request.Form("VirtualAccountAssigned")
TransactionExpiryDate	= Request.Form("TransactionExpiryDate")

%>

<Add your programming code here>
<?php

//Parameter xfield1 ditambahkan khusus untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.

//Parameter VirtualAccountAssigned dan TransactionExpiryDate ditambahkan khusus untuk metode pembayaran ATM Transfer.

$merchantcode	= $_REQUEST["MerchantCode"];
$paymentid 	    = $_REQUEST["PaymentId"];
$refno 		    = $_REQUEST["RefNo"];
$amount 	    = $_REQUEST["Amount"];
$ecurrency 	    = $_REQUEST["Currency"];
$remark 	    = $_REQUEST["Remark"];
$transid 	    = $_REQUEST["TransId"];
$authcode 	    = $_REQUEST["AuthCode"];
$estatus 	    = $_REQUEST["Status"];
$errdesc 	    = $_REQUEST["ErrDesc"];
$signature	    = $_REQUEST["Signature"];
$xfield1 	    = $_REQUEST["xfield1"];
$va_assigned	= $_REQUEST["VirtualAccountAssigned"];
$expiry_date	= $_REQUEST["ETransactionExpiryDate"];

?>

//Add your programming code here

Backend Post Feature

Backend post feature adalah teknologi antar server yang tidak bergantung pada web browser customer merchant. Fitur ini harus diimplementasikan pada website merchant dengan tujuan untuk mendapatkan status pembayaran dari iPay88 OPSG. Merchant bisa mendapatkan status pembayaran melalui halaman backend merchant. iPay88 OPSG dapat mengirim status pembayaran secara berulang walaupun halaman response merchant gagal mendapatkan status pembayaran tersebut yang disebabkan oleh customer web browser yang tertutup secara tidak sengaja, koneksi internet terputus, dan lain sebagainya.


Catatan

  1. iPay88 OPSG hanya mengirim status pembayaran melalui halaman backend merchant apabila status pembayaran pada transaksi merchant telah sukses. jika status pembayaran gagal, maka iPay88 OPSG tidak akan mengirimkan status melalui halaman backend merchant.

  2. Halaman backend merchant harus menerapkan beberapa pengecekan yang sama dengan halaman response seperti pengecekan signature, dan lain sebagainya untuk mencegah terjadi pembajakan pada sistem merchant.

  3. Halaman backend merchant tidak boleh memiliki kode session sehingga sistem merchant masih dapat menerima status pembayaran dari iPay88 OPSG bahkan jika customer telah keluar dari proses pembayaran atau session berakhir.

  4. Merchant perlu melakukan validasi untuk menentukan apakah proses update status transaksi melalui "halaman response" atau "halaman backend" sehingga tidak terjadinya proses update status transaksi lebih dari satu kali.

    Note : Setelah iPay88 OPSG menerima informasi dari bank atau principal bahwa status pembayaran pada transaksi merchant telah sukses, iPay88 OPSG secara bersamaan akan mengirimkan status pembayaran tersebut ke "halaman response" dan "halaman backend" merchant.

  5. Halaman backend bukan sebagai pengganti halaman response. Merchant tetap harus menggunakan halaman response untuk proses redirect kembali dari halaman pembayaran.



Backend Post Parameter

Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar(20) M Merchant Code disediakan oleh iPay88
PaymentID Integer O Payment ID untuk metode pembayaran yang dituju.
RefNo String (20) M Nomor unik transaksi merchant.
Amount varchar(5) M Jumlah atau nominal transaksi dengan 2 nol di belakang koma .00
Currency Currency M Mata uang yang digunakan dalam transaksi.
Remark Varchar (100) O Catatan merchant.
TransId Varchar(30) O ID Transaksi iPay88 OPSG
AuthCode Varchar(20) O Kode persetujuan bank.
Status Varchar(1) M Status Transaksi
“1” – Success
“0” – Fail
“6” – Pending (Hanya tersedia pada metode pembayaran ATM Transfer).
ErrDesc Varchar(100) O Deskripsi transaksi gagal (lihat Referensi).
Signature Varchar(100) M SHA1 Signature (lihat Backend Post Signature )
PaymentDate String M Tanggal dan Waktu Transaksi.


Backend Post Sample

{
"MerchantCode":"ID00001",
"PaymentId":"35",
"RefNo":"324202292135AM",
"Amount":"1000000",
"Currency":"IDR",
"Remark":"
"TransId":"T0058006300",
"AuthCode":"637096",
"Status":"1",
"ErrDesc":""
"Signature":"UEiWe+q62TdPef4vptlgMuGmtng=",
"Payment Date":"24-03-2022 16:22",
}


Backend Post Signature

iPay88 OPSG akan mengirimkan pesan response berisi signature hash SHA1 ke halaman backend merchant. Signature hash untuk response adalah hash berikut:

  1. MerchantKey (Diberikan oleh iPay88 OPSG dan hanya dibagikan kepada merchant)
  2. MerchantCode
  3. PaymentId
  4. RefNo
  5. Amount
  6. Currency
  7. Status
  8. Xfield1 (Opsional)

Field harus tersusun mengikuti aturan berikut:
(MerchantKey & MerchantCode & PaymentId & RefNo & Amount & Currency & Status)

Contoh:
MerchantKey = “apple”
MerchantCode = “ID00001”
PaymentId = “1”
RefNo = “A00000001”
Amount = “300000” (Note: 300000 represent amount as Rp 3.000,00)
Currency = “IDR”
Status = “1”
Xfield 1 = “||IPP:3||”

Hash akan dikalkulasi melalui string berikut:
applekeyID000011A00000001300000IDR1||IPP:3||

Hasilnya memiliki nilai signature (menggunakan algoritma SHA1) berikut:
LG6ywEKkZxBYnZjHcUcSKGO4gwQ=

Untuk memastikan signature yang dibuat sudah sesuai, kunjungi halaman di bawah ini untuk melakukan perbandingan signature: https://payment.ipay88.co.id/epayment/testing/TestSignature.asp



Backend Post Response

Pada website merchant, buat satu halaman sebagai halaman backend untuk menerima parameter dari iPay88 OPSG. Parameter backend yang dikirim oleh iPay88 OPSG sama seperti parameter yang dikirim ke halaman response merchant.

Pada halaman request merchant, tentukan url backend melalui parameter "BackendURL".

Contoh:
<input name = "BackendURL" value = "http://www.abc.com/backend_response.asp">

Pada halaman 'backend_response.asp' Anda perlu menuliskan kata 'RECEIVEOK' saja (tanpa tanda kutip) sebagai konfirmasi setelah halaman backend berhasil mendapatkan status pembayaran dari iPay88 OPSG.

iPay88 OPSG akan mencoba mengirim kembali status pembayaran ke halaman 'backend_response.asp' hingga 5 kali pada interval tertentu jika tidak mendapat konfirmasi 'RECEIVEOK' .



Backend Post Response Sample

response.write "RECEIVEOK"
echo "RECEIVEOK";

Catatan:
Pastikan hanya menuliskan kata 'RECEIVEOK' saja pada halaman backend tanpa tag HTML apa pun.



Requery Payment Status Parameters (Response URL to enquiry.asp)

Berikut ini adalah parameter dengan HTTPS POST pada merchant yang dikirim ke iPay88 OPSG untuk re-query status pembayaran.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


Berikut ini adalah kemungkinan pesan didapatkan dari iPay88 OPSG.


Pesan
Deskripsi
00 Pembayaran sukses.
Invalid parameters Parameter yang dikirimkan merchant tidak tepat.
Record not found Data tidak ditemukan.
Incorrect amount Total yang tidak tepat (berbeda).
Payment fail Pembayaran gagal.
Payment Pending Pembayaran tertunda dan pelanggan harus membayar di mesin ATM.
Haven’t Paid (0) Tagihan belum dibayar atau berhenti di laman pembayaran iPay88.
Haven’t Paid (1) Tagihan belum dibayar atau berhenti di laman bank.
M88Admin Status pembayaran diubah oleh iPay88 Admin (gagal).

<%
Function SendToiPayInq(byval MerchantCode, byval RefNo, 
byval Amount)	
	
Dim TryNo, thenQString, URL, strReturn	
TryNo = 0

QString = "MerchantCode=" & MerchantCode & 
	    "&RefNo=" & RefNo & _
        "&Amount=" & Amount
	
URL = "https://payment.ipay88.co.id/epayment/enquiry.asp"	

On Error Resume Next

Do

Set xobj = Server.CreateObject ("Msxml2.ServerXMLHTTP.3.0")
xobj.setTimeouts 30000, 60000, 60000, 60000
xobj.open "POST", URL, false
xobj.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xobj.send QString

TryNo = TryNo + 1		
Loop While xobj.status <> 200 and TryNo < 3
	
If xobj.status <> 200 Then			
	SendToiPayInq = Err.Description & "(" & Err.Number & ")"
Else
	SendToiPayInq = xobj.responseText
End If
set xobj = nothing		

End Function

%>
<?php

function Requery ($MerchantCode, $RefNo, $Amount)
{
   $query = "https://payment.ipay88.co.id/epayment/enquiry.asp?MerchantCode=".$MerchantCode."&RefNo=".$RefNo."&Amount=".$Amount;
	
   $url     = parse_url($query);
   $host    = $url["host"];
   $path    = $url["path"] . "?" . $url["query"];
   $timeout = 1;
	
   $fp = fsockopen ($host, 80, $errno, $errstr, $timeout);
	
   if ($fp) 
   {
      fputs ($fp, "GET $path HTTP/1.0\nHost: ".$host."\n\n");
	  while (!feof($fp)) 
	  {
	     $buf .= fgets($fp, 128);
	  }
		
	  $lines   = split("\n", $buf);
	  $Result  = $lines[count($lines)-1];
		
	  fclose($fp);
   } 
	
   else 
   {
      //enter error handing code here
   }
	
   return $Result;
}

?>

Kontrol Keamanan

Untuk meningkatkan keamanan, silahkan ikuti langkah-langkah berikut di laman penerimaan status pembayaran merchant (Response URL).

  1. Periksa nilai HTTP_REFERER dari https://payment.ipay88.co.id (hanya berlaku jika situs web merchant berfungsi dengan Sertifikat SSL).
  2. Periksa jumlah pembayaran dari iPay88 OPSG sesuai dengan pelanggan Anda.
  3. Bandingkan signature dari iPay88 OPSG dengan signature yang Anda hasilkan sendiri.


Integritas Data dan Keamanan menggunakan Signature Acak

Pengacakan SHA1 adalah fitur keamanan yang memungkinkan skrip Anda untuk mengidentifikasi hasil transaksi sebenarnya dari sumber otorisasi yang sesuai. Bagi iPay88 OPSG, fitur ini berguna untuk memastikan integritas data yang diterima pada setiap request transaksi dari merchant.

Menggunakan algoritma SHA1, signature atau fingerprint dari transaksi dapat dihasilkan. Algoritma matematika yang digunakan untuk membangun signature ini dirancang sedemikian rupa sehingga setiap adanya perubahan pada informasi yang digunakan dalam perhitungan akan menghasilkan signature yang berbeda pula.

Informasi yang digunakan dalam perhitungan signature tidak dapat diketahui walau dengan menganalisa signature itu sendiri. Signature dihasilkan dengan menggunakan informasi dari akun Anda sebagai merchant. Setiap transaksi yang diproses melalui sistem memiliki pengacakan signature tersendiri yang berkaitan dengan transaksi tersebut.


Request Page Signature

Signature harus disertakan pada proses request laman pembayaran iPay88 OPSG disetiap transaksi merchant. Signature tersebut adalah hasil dari pengacakan lima bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 OPSG)
  2. MerchantCode
  3. RefNo
  4. Amount
  5. Currency

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & RefNo & Amount & Currency

Contoh:

MerchantKey = "applekey"
MerchantCode = "ID00001"
RefNo = "A00000001"
Amount = "300000" (catatan: 300000 adalah representasi dari total Rp3.000,00)
Currency = "IDR"

Pengacakan akan dihitung melalui string berikut:
applekeyID00001A00000001300000IDR

Hasil signature (menggunakan algoritma SHA1) adalah:
Q/iIMzpjZCrhJ2Yt2dor1PaFEFI=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.

Public Shared Function ComputeHas(ByVal Key As String)
Dim objSHA1 As New SHA1CryptoServicesProvider()
objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
Dim buffer() As Byte = objSHA1.Hash
DIm HashValue As String = System.Convert.ToBase64String(buffer)

Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Response Page Signature

Jika status pembayaran dari transaksi merchant dinyatakan sukses, iPay88 OPSG akan mengirim signature di laman response dan backend merchant. Signature ini harus dibandingkan dengan signature yang dihasilkan oleh merchant sendiri guna mengindari adanya pembajakan. Signature tersebut adalah hasil dari pengacakan tujuh bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 OPSG)
  2. MerchantCode
  3. PaymentId
  4. RefNo
  5. Amount
  6. Currency
  7. Status

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & PaymentId & RefNo & Amount & Currency & Status


Contoh:

MerchantKey = "applekey"
MerchantCode = "ID00001"
PaymentId = "1"
RefNo = "A00000001"
Amount = "300000" (catatan: 300000 adalah representasi dari total Rp3.000,00)
Currency = "IDR"
Status = "1"

Pengacakan akan dihitung melalui string berikut:
applekeyID000011A00000001300000IDR1

Hasil signature (menggunakan algoritma SHA1) adalah:
01sh+jPUL2wdqCcWJTgiuNuiiTI=

Ketika iPay88 OPSG menerima request atau transaksi dari merchant, iPay88 OPSG akan memeriksa nilai acak signature yang dihasilkan untuk dicocokkan dengan nilai signature yang merchant kirim. Ketika sistem merchant menerima hasil transaksi, merchant dapat membuat signature dan pastikan sama dengan signature yang dikirim balik oleh iPay88 OPSG. Merchant akan mendapatkan signature di laman response jika transaksi tidak error (tidak termasuk transaksi yang disetujui atau ditolak).

Setelah merchant menerima informasi dari iPay88 OPSG terkait status pembayaran dari transaksi, merchant harus menjalanakan algoritma acak pada tujuh bidang utama yg telah disebutkan diatas sehingga menghasilkan suatu signature. Merchant wajib mencocokkan hasil signature merchant dengan signature iPay88 OPSG. Dapat dipastikan jika signature yang dihasilkan merchant saat proses request dan dikirim ke iPay88 OPSG, maka transaksi merchant telah diproses oleh sistem iPay88 OPSG.

Merchant key dibuat oleh iPay88 OPSG untuk merchant. Merchant key bersifat rahasia bersama (antara merchant dan iPay88 OPSG), dan merupakan salah satu bagian kunci informasi untuk proses pengacakan signature. Merchant key akan dibuat ulang jika iPay88 OPSG mencurigai bahwa merchant key sudah tidak aman atau terjadi kasus penipuan. Informasi lebih lanjut tentang algoritma acak SHA1, termasuk sampel kode untuk implementasi dapat ditemukan di RFC 3174 dalam laman Task Force Internet Engineering.

Public Shared Function ComputeHas(ByVal Key As String)
   Dim objSHA1 As New SHA1CryptoServicesProvider()
   objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
   Dim buffer() As Byte = objSHA1.Hash
   DIm HashValue As String = System.Convert.ToBase64String(buffer)
    
   Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Laporan dan Pemberitahuan

Kami menyediakan referensi sebagai informasi tambahan untuk Anda. Berikut ini adalah referensi mengenai laporan dan pemberitahuan. Informasi ini perlu Anda ketahui sebagai merchant kami.


Laporan dan Transaksi Merchant

Kami memberikan fasilitas kepada merchant untuk melihat laporan dan cek transaksi secara online.

  1. Merchant dapat mengunjungi laman laporan iPay88 OPSG melalui:
    1. Report URL
      • Sandbox: https://sandbox.ipay88.co.id/epayment/report/index.asp
      • Production: https://payment.ipay88.co.id/epayment/report/index.asp
    2. Login Name: disediakan oleh iPay88 OPSG
    3. Password: disediakan oleh iPay88 OPSG
  2. Setelah login, select all transaction, filter transaction date, dan klik search.
  3. Laporan transaksi akan ditampilkan.

Pemberitahuan Via Email

Pemberitahuan via email tidak dijamin oleh iPay88 OPSG karena bergantung pada ISP. Laporan Online (online report) adalah media utama untuk melihat status transaksi. Pemberitahuan via email tidak boleh diambil atau disimpulkan sebagai pengganti media utama.

Transmisi email tidak dapat dijamin aman atau bebas dari kesalahan karena informasi dapat disadap, rusak, hilang, hancur, datang terlambat atau tidak lengkap, atau mengandung virus. Oleh karena itu pengirim tidak bertanggung jawab atas kesalahan atau kelalaian apa pun dalam isi email, yang timbul sebagai akibat dari transmisi email. iPay88 tidak bertanggung jawab atas isi email, atau konsekuensi dari tindakan apa pun yang diambil atas dasar informasi yang diberikan, kecuali jika informasi itu kemudian dikonfirmasi secara tertulis.


1. Email Pembayaran Pelanggan

Pelanggan akan menerima email pemberitahuan berisi detil pembayaran setelah pembayaran berhasil. Dibawah ini adalah contoh email yang dikirimkan ke pelanggan.



2. Email Pemberitahuan Merchant

Merchant juga menerima email pemberitahuan berisi detil pembayaran setelah pembayaran berhasil. Untuk memastikan Anda dapat menerima semua email kami, pastikan Anda telah menjalani langkah-langkah berikut:

  1. Dari mailbox Anda, pastikan white-list alamat email iPay88 dengan menambahkan sales@ipay88.co.id ke dalam daftar teman Anda.
  2. Selain itu, pastikan mailbox Anda tidak melakukan black-list alamat email iPay88 yaitu sales@ipay88.co.id.
  3. Untuk pelayanan yang lebih baik, white-list alamat email dan domain iPay88.co.id. Harap verifikasi atau izinkan personel teknik Anda (webhosting atau email server) untuk memverifikasi status email Anda. Di bawah ini adalah contoh email:

Dibawah ini adalah contoh email yang dikirimkan ke merchant.




Log Online Payment System Gateway

Kami memberikan informasi mengenai perubahan pada dokumentasi Online Payment Switching Gateway iPay88 Indonesia (iPay88 OPSG). Apabila ada pertanyaan silahkan kirim email ke techsupport@ipay88.co.id.

Versi
Tanggal
Deskripsi Perubahan
1.6.1 21 Mei 2013
  1. Penerbitan pertama.
1.6.2 19 Desember 2017
  1. Menambah parameter status Pending dan Xfield1 dibagian payment request.
  2. Mengubah URL test signature.
  3. Mengubah sampel kode untuk payment request dan payment response.
  4. Menambah "Haven't Paid (0)", "Haven't Paid (1)", dan "Payment Pending" yang memungkinkan pada saat Re-Query.
  5. Mengubah signature dibagian request page dan response page.
  6. Mengubah report url.

Online Payment System Gateway Versi 2.0.9

Welcome to iPay88 Indonesia Online Payment Switching Gateway 2.0.X. We provide e-payment services and reports that are integrated with your business site. Merchants can provide various payment methods to customers to make payments directly using our API through iPay88 Indonesia.


Download OPSG Verse 2.0.9 PDF Documentations

Payment Request

1 Sandbox https://sandbox.ipay88.co.id/ePayment/WebService/PaymentAPI/Checkout
2 Production https://payment.ipay88.co.id/ePayment/WebService/PaymentAPI/Checkout

Request Parameter

Merchants send parameters via JSON as a request to iPay88 Indonesia. Here are some parameters as a request :


No. Field Name Type (Size) Sample M/O Description
1. ApiVersion string(5) 2.0 M Version API
2. MerchantCode string (20) ID00001 M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
3. PaymentId string(4) 70 M Payment method identifier, see Payment Method for the list.
4. Currency string(5) IDR M Support to IDR, USD, THB, MYR
5. RefNo string(30) 920201930925AM M Unique merchant transaction number / Order ID
6. Amount decimal 100000 M The amount must only contain the exact amount without 2 digits after.
For example:
100.50 is expressed as 100,50
10 is expressed as 10
0.50 is expressed as 0.50
Amount = Sum of Each transaction + Amount Of Shipping + Amount Of Discount
7. ProdDesc string(100) Alat Elektronik M Product description
8. UserName string(100) Thoriq M Customer name
9. UserEmail string(100) thoriq@ipay88.co.id M Customer email for receiving receipt
10. UserContact string(100) 08123123123 M User contact number
11. RequestType string(20) REDIRECT O Request type identifier, see Request Type for the list.
12. Remark string(100) O Merchant remarks
13. Lang string(20) ISO-8859-1 M Encoding type
ISO-8859-1 English
UTF-8 Unicode
GB2312 Chinese Simplified
GD18030 Chinese Simplified
BIG5 Chinese Traditional
14. ResponseURL string(200) https://store.co.id/resp.asp M Response page URL is the page at the merchant website that will receive payment status from iPay88 OPSG.
15. BackendURL string(200) https://store.co.id/backend.asp M Backend response page
16. Signature string(100) M SHA256 signature (example: Request Signature)
17. FullTransactionAmount decimal 10000000 O *mandatory for BCA KlikPay
18. MiscFee decimal 10000000 O for BCA KlikPay
19. xfield1 string(200) O To enable installment and discount payments
20. ItemTransactions List (n) M Only for installment detail with multiple product
1. Id string (50) 001 M Product id
2. Name string(100) Smartphone M Name of item
3. Quantity integer 2 M Quantity of item
4. Amount integer 5000 M Total Amount of item product
5. Type string(100) O Type of Product
6. Url string(100) O URL of the product in the merchant site / platform
7. ImageUrl string(256) O URL of the image of the product in the merchant site / platform
8. Tenor string(100) O for BCA KlikPay
9. CodePlan string(100) O for BCA KlikPay
10. MerchantId string(100) O for BCA KlikPay
11. ParentType string(100) SELLER or ITEM M Possible values: SELLER, ITEM
12. ParentId string(100) SELLER88 M It will correspond to the SELLER ID if the parentType is SELLER, alternatively it will correspond to the ITEM ID if the parentType is ITEM
21. ShippingAddress M Shipping Address Detail
1. FirstName string(100) Recipient first name M Shipping FirstName
2. LastName string(100) Recipient last name M Shipping LastName
3. Address string(100) JL. Letjen S. Parman No 22-24 M Shipping Address
4. City string(100) Jakarta Barat M Shipping City
5. State string(20) Jakarta M Shipping State
6. PostalCode string(20) 11480 M Shipping Postal Code
7. Phone string(20) 08788888888 M Shipping Phone
8. CountryCode string(20) ID M Shipping Country Code
22. BillingAddress M Billing Address detail
1. FirstName string(100) Customer first name M Billing FirstName
2. LastName string(100) Customer last name M Billing LastName
3. Address string(100) JL. Letjen S. Parman No 22-24 M Billing Address
4. City string(100) Jakarta Barat M Billing City
5. State string(20) Jakarta M Billing State
6. PostalCode string(20) 11480 M Billing Postal Code
7. Phone string(20) 08788888888 M Billing Phone
8. CountryCode string(20) ID M Billing Country Code
23. Sellers List (n) M Only For Seller Detail
1. Id string(100) Your-seller-id M Seller’s ID
2. Name string(100) Your-seller-name M Seller’s Name
3. SelleridNumber string(100) Your-seller-id-number M Seller's identifier number (KTP / SIM / etc)
4. Email string(100) seller@ipay88.co.id M Seller’s Email
5 URL string(100) www.sunrise.com M Seller’s Website
6. Address M Seller’s Shop
1. FirstName string(100) Seller First name M Seller’s Shop FirstName
2. LastName string(100) Seller Last Name M Seller’s Shop LastName
3. Address string(100) JL. Letjen S. Parman No. 22-24 M Seller’s Shop Address
4. City string(100) DKI Jakarta M Seller’s Shop City
5. State string(100) Jakarta Barat M Seller’s Shop State
6. PostalCode string(6) 11480 M Seller’s Shop Postal Code
7. Phone string(20) 08788888888 M Seller’s Shop Phone
8. CountryCode string(16) ID M Seller’s Shop Country Code
24. SettingField List (n)
1. Name string(100) TenorInstallment O For other : example installment
2. Value string(100) 3 O For other : example installment

Request Signature

This signature must be included in the request of every transaction then encrypted using SHA256. This hash signature for a request is a hash of the following five fields:

  1. MerchantKey (Provided by iPay88 Indonesia and share between iPay88 and merchant only)
  2. MerchantCode (Provided by iPay88 Indonesia and share between iPay88 and merchant only)
  3. RefNo
  4. Amount
  5. Currency

The fields must set in the following order:
|| MerchantKey || MerchantCode || RefNo || Amount || Currency ||

Example: MerchantKey = “apple”
MerchantCode = “ID00001”
RefNo = “A00000001”
Amount = “3000” (Note: 3000 represent amount as Rp 3.000)
Currency = “IDR”
The hash would be calculated on the following string:
||Apple||ID00001||A00000001||3000||IDR||

The resulting has signature value equals to (using SHA256 algorithm):
3ee767e49d29c46b6187db2fe511287ccd986e874a057fa2e1bb222442b68f63

To ensure the signature generated was correct, visit the link below for signature comparison. https://payment.ipay88.co.id/epayment/testing/TestSignaturev2.asp


Signature Sample Code

<?php
echo hash('sha256', "||" . MerchantKey . "||" . MerchantCode . "||" . RefNo . "||" . Amount . "||" . Currency . "||");
?>
String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex("||" + MerchantKey + "||" + MerchantCode + "||" + RefNo + "||" + Amount + "||" + Currency + "||" );


Request Sample

{
    "APIVersion": "2.0",
    "MerchantCode": "ID00001",
    "PaymentId": "71",
    "Currency": "IDR",
    "RefNo": "10182019103003AM",
    "Amount": "500000",
    "ProdDesc": "Alat Elektronik",
    "RequestType": "Seamless",
    "UserName": "Technical Support",
    "UserEmail": "techsupp@ipay88.co.id",
    "UserContact": "081234567890",
    "Remark": "",
    "Lang": "iso-8859-1",
    "ResponseURL": "https://sandbox.ipay88.co.id/epayment/fujipaystatusv2.asp",
    "BackendURL": "http://sandbox.ipay88.co.id/ePayment/testing/RequestForm_savetemp.asp",
    "Signature": "b469c7da241554364e55b65ca807ffc501bdf981126c248c636ac9e38592fc12",
    "ItemTransactions": [
        {
            "Id": "00001",
            "Name": "Smartphone Wireless Charger",
            "Quantity": "1",
            "Amount": "300000",
            "ParentType": "SELLER",
            "ParentId": "SELLER123"
        },
        {
            "Id": "00002",
            "Name": "Powerbank 10000maH",
            "Quantity": "1",
            "Amount": "200000",
            "ParentType": "SELLER",
            "ParentId": "SELLER456"
        },
        {
            "Id": "shippingfee",
            "Name": "Shipping Fee",
            "Quantity": "1",
            "Amount": "5000"
        },
        {
         "Id": "discount",
            "Name": "Discount",
            "Quantity": "1",
            "Amount": "5000"
        }
    ],
    "ShippingAddress": {
        "FirstName": "Techsupp",
        "LastName": "Alpha",
        "Address": "Jl. Test Blok R No.1",
        "City": "Jakarta",
        "State": "DKI Jakarta",
        "PostalCode": "18800",
        "Phone": "08123456789",
        "CountryCode": "1"
    },
    "BillingAddress": {
        "FirstName": "Techsupp",
        "LastName": "Alpha",
        "Address": "Jl. Test Blok R No.1",
        "City": "Jakarta",
        "State": "DKI Jakarta",
        "PostalCode": "18800",
        "Phone": "08123456789",
        "CountryCode": "1"
    },
    "Sellers": [
        {
            "Id": "SELLER123",
            "Name": "Sellername",
            "LegalId": "3274011001900001",
            "SellerIdNumber": null,
            "Email": "sellername@gmail.com",
            "Url": "www.sunrise.com",
            "address": {
                "FirstName": "Seller",
                "LastName": "Alpha",
                "Address": "Jalan Tentara Pelajar no 49",
                "City": "Jakarta Utara",
                "State": "DKI Jakarta",
                "PostalCode": "12960",
                "Phone": "08123456789",
                "CountryCode": "IDN"
            }
        },
        {
            "Id": "SELLER456",
            "Name": "Sellername B",
            "LegalId": "3173021507910004",
            "SellerIdNumber": null,
            "Email": "sellernameb@gmail.com",
            "Url": "www.tokobagus.com",
            "address": {
                "FirstName": "Seller",
                "LastName": "Beta",
                "Address": "Jalan Krici raya IX",
                "City": "Jakarta Selatan",
                "State": "DKI Jakarta",
                "PostalCode": "12960",
                "Phone": "08123456789",
                "CountryCode": "IDN"
            }
        }
    ],
    "SettingField": [
        {
            "Name": "TenorInstallment",
            "Value": "3"
        }
    ]
}


Response Format

iPay88 Indonesia sends parameters via JSON as a response to Merchant. Here are some parameters as a response:


No. Field Name Type Sample Description
1. RefNo string 720201745653AM Unique merchant transaction number / Order ID
2. Signature string b469c7da241554364e55b65ca807
ffc501bdf981126c248c636ac9e38592fc12
Signature generated with SHA256 (see Request Signature)
3. VirtualAccountAssigned string IDR Virtual Account number
4. TransactionExpiryDate string 18-08-2020 07:57 Expired date for Virtual Account (DD-MM-YYYY HH:MM)
5. CheckoutID string T0036521900 iPay88 OPSG Transaction ID
6. Code string “1” – Payment Request Received
“0” – Fail
Transaction Status
7. Message string Data received Transaction Message

Response Sample

{
  "RefNo": "10182019103003AM",
  "Signature": "b469c7da241554364e55b65ca807ffc501bdf981126c248c636ac9e38592fc12",
  "CheckoutID": "3acf947c2e40b975d07d60906aff9ef832357ba573b933faa007140d84492cb2",
  "Code": "1",
  "Message": "CheckoutURL generated"
}


Payment Redirect

1 Sandbox https://sandbox.ipay88.co.id/PG/
2 Production https://payment.ipay88.co.id/PG/

Payment Redirect Parameter

No. Field Name Type Sample Description
1. CheckoutID string(20) 3acf947c2e40b975d07d60906aff9
ef832357ba573b933faa007140d84492cb2
Unique ID iPay88 generated from payment response
2. Signature integer b469c7da241554364e55b65ca807ffc
501bdf981126c248c636ac9e38592fc12
Signature generated with SHA256 (see Request Signature )

Payment Redirect Sample

<form method="POST" name="redirect" action="{redirect url}">
    <input type="hidden" name="CheckoutID" value="{CheckoutID}" />
    <input type="hidden" name="Signature" value="{Signature}" />
</form>
<script language=javascript>
    document.redirect.submit();
</script>


Payment Response

HTTPS POST redirect response to ResponseURL (refer to Request Parameter No. 14) from iPay88 OPSG after performing payment.

No. Field Name Type Sample Description
1. MerchantCode string(20) ID00001 Merchant code assigned by iPay88
2. RefNo string(30) 920201930925AM Unique merchant transaction number / Order ID

Payment Response Sample

<%
MerchantCode = Request.Form("MerchantCode")
RefNo = Request.Form("RefNo")
%>
<Add your programming code here>
<?PHP
$merchantcode = $_REQUEST["MerchantCode"];
$refno = $_REQUEST["RefNo"];
PHP?>
<Add your programming code here>


BackendPost

Backendpost will be sent after a user payment attempt using method POST with type application/json. iPay88 will send a backendpost with 3 times retry until merchant response with Code 1.


BackendPost Parameter

No. Field Name Type Description
1. MerchantCode string Merchant code assigned by iPay88
2. PaymentID string Payment method identifier, see References for the list.
3. Refno string Merchant Reference Number
4. Amount string Transaction Amount, with .00
5. Currency string Transaction Currency
6. Remark string Additional Value
7. TransId string iPay88 transaction ID
8. AuthCode string Code from Bank
9 TransactionStatus string Transaction Status
“1” – Success
“0” – Fail
“6” – Pending (Only available for ATM Transfer payment)
10. ErrDesc string Transaction Error Description
11. Signature string Signature generated using SHA256 (example: Backend Post Signature)
12. PaymentDate string Transaction Date

BackendPost Signature

This signature must be included in the request of every transaction then encrypted using SHA256. This hash signature for a request is a hash of the following five fields:

  1. MerchantKey (Provided by iPay88 Indonesia and share between iPay88 and merchant only)
  2. MerchantCode (Provided by iPay88 Indonesia and share between iPay88 and merchant only)
  3. RefNo
  4. Amount
  5. Currency
  6. TransactionStatus (the status of transaction, can be obtain from iPay88)

The fields must set in the following order:
|| merchantkey || MerchantCode || RefNo || Amount || Currency || PaymentStatus ||

Example: MerchantKey = “apple”
MerchantCode = “ID00001”
PaymentID = “1”
RefNo = “A00000001”
Amount = “3000.47” (Note: 3000.47 represent amount as Rp 3.000,47)
Currency = “IDR”
PaymentStatus = “1”

The hash would be calculated on the following string:
||apple||ID00001||1||A00000001||3000.47||IDR||1||

The resulting has signature value equals to (using SHA256 algorithm):
ed14e9c0373a1e1f887c29929fd8d063a402f6b1924d78df0763e03bae025ee0

To ensure the signature generated was correct, visit the link below for signature comparison. https://payment.ipay88.co.id/epayment/testing/TestSignaturev2.asp


BackendPost Signature Sample Code

<?php
echo hash('sha256', "||" . MerchantKey . "||" . MerchantCode . "||" . PaymentId . "||" . RefNo . "||" . Amount . "||" . Currency . "||" . PaymentStatus . "||" );
?>
String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex("||" + MerchantKey + "||" + MerchantCode + "||" + PaymentId + "||" + RefNo + "||" + Amount + "||" + Currency + "||" + PaymentStatus + "||");


BackendPost Sample

{
	"MerchantCode": "ID00001",
	"PaymentId": "41",
	"RefNo": "224202234712AM",
	"Amount": "30000.00",
	"Currency": "IDR",
	"Remark": "",
	"TransId": "T0057525100",
	"AuthCode": "496441",
	"TransactionStatus": "1",
	"ErrDesc": "",
	"Signature": "8f77ece4585bd071aa2316aed09ebf85109cdbb2d75f7a5e58cc5c5275d4eaec",
	"IssuerBank": "PT. BANK CENTRAL ASIA TBK",
	"PaymentDate": "24-02-2022 10:48",
	"Xfield1": "",
	"DCCConversionRate": "0",
	"OriginalAmount": "0",
	"OriginalCurrency": "",
	"SettlementAmount": "0",
	"SettlementCurrency": "",
	"Binbank": "400000"
}


BackendPost Response

No. Field Name Type Description
1. Code string 0 for Failed, 1 for Success
2. Message
1. Indonesia string Message in Indonesia
2. English string Message in English

BackendPost Response Sample

{
    "Code":"1"
    "Message":
    {
       "English":"Status Received",
       "Indonesian":"Pembayaran diterima"
    }
}


Requery Payment Status

1 Sandbox https://sandbox.ipay88.co.id/epayment/enquiry.asp
2 Production https://payment.ipay88.co.id/epayment/enquiry.asp

Request Parameter

Field Name Type M/O Description
MerchantCode string(20) M Merchant Code assigned by iPay88
RefNo string(30) M Unique merchant transaction number / Order ID
Amount integer M The amount must contain 2 digits after as decimals
For example:
100.50 is expressed as 100,50
10 is expressed as 10,00
0.50 is expressed as 0,50

Legend:
M: Mandatory field
O: Optional field, value can be empty but parameter must exist


Requery Sample

<%
Function SendToiPayInq(byval MerchantCode, byval RefNo, byval Amount)
	Dim TryNo, thenQString, URL, strReturn
	TryNo = 0
	QString = "MerchantCode=" & MerchantCode & "&RefNo=" & RefNo & _
	"&Amount=" & Amount
	URL = "https://payment.ipay88.co.id/epayment/enquiry.asp"
	On Error Resume Next
	Do
		Set xobj = Server.CreateObject ("Msxml2.ServerXMLHTTP.3.0")
		xobj.setTimeouts 30000, 60000, 60000, 60000
		xobj.open "POST", URL, false
		xobj.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
		xobj.send QString
		TryNo = TryNo + 1
	Loop While xobj.status <%> 200 and TryNo < 3
	If xobj.status <%> 200 Then
		SendToiPayInq = Err.Description & "(" & Err.Number & ")"
	Else
		SendToiPayInq = xobj.responseText
	End If
	set xobj = nothing
End Function
%>
<?PHP
function Requery($MerchantCode, $RefNo, $Amount)
{
    $query = "https://payment.ipay88.co.id/epayment/enquiry.asp?MerchantCode=" . $MerchantCode . "&RefNo=" . $RefNo . "&Amount=" . $Amount;
    $url = parse_url($query);
    $host = $url["host"];
    $path = $url["path"] . "?" . $url["query"];
    $timeout = 1;
    $fp = fsockopen($host, 443, $errno, $errstr, $timeout);
    if ($fp)
    {
        fputs($fp, "GET $path HTTP/1.0\nHost: " . $host . "\n\n");
        while (!feof($fp))
        {
            $buf .= fgets($fp, 128);
        }
        $lines = split("\n", $buf);
        $Result = $lines[count($lines) - 1];
        fclose($fp);
    }
    else
    {
        # enter error handing code here
        
    }
    return $Result;
}
?>


Response Format

Response iPay88 OPSG Description
00 Successful payment
Invalid parameters Parameters pass in incorrect
Record not found Cannot found the record
Incorrect amount Amount different
Payment fail Payment fail
Payment Pending Payment is pending and need customer to pay at the ATM Machine
Payment In Progress Payment is not paid yet or idle on iPay88 payment page or Bank page

Online Payment System Gateway
Merchant Host - Credit Card Versi 1.0.0


Segera integrasikan iPay88 Online Payment System Gateway (OPSG) Merchant Host - Credit Card ini dengan situs Anda. API ini menjadikan situs Anda untuk menerima pembayaran online secara langsung melalui iPay88 Indonesia.


Download OPSG Merchant Host

ePayment

Segmen ini menjelaskan fungsionalitas dari sistem Online Payment Switching Gateway (OPSG) iPay88 Indonesia. Diantaranya:

  1. ePayment: berbagai metode pembayaran untuk situs e-commerce milik merchant.
  2. Reports: online view transaction report.


Objektif

Merchant dapat menyediakan metode pembayaran kartu kredit dan pelanggan dapat melakukan pengisian data kartu kredit secara langsung di laman merchant dengan metode HTTPs Post Form Data melalui iPay88 Indonesia.


Prasyarat Integrasi Merchant

  1. Diharuskan menggunakan merchant code dan merchant key dari iPay88 Indonesia.
  2. Merchant harus menyediakan request url ke iPay88 Support Team.
  3. Request URL yang terdaftar harus berupa IP atau berbasis domain.
    Catatan: Localhost tidak diperbolehkan.

Catatan Penting

  1. Uji transaksi harus dari Request URL yang terdaftar.
  2. Uji transaksi dengan jumlah IDR 3.000,00.
  3. Uji transaksi bersifat terbatas untuk metode pembayaran dengan kartu kredit.
  4. Uji transaksi dengan kartu kredit akan dikembalikan (refund) pada hari akhir.
  5. Response URL dapat diatur dibagian input ResponseURL pada saat request laman pembayaran iPay88.
  6. Backend post URL dapat diatur dibagian input BackendURL pada saat request laman pembayaran iPay88.
  7. Notifikasi email tidak dijamin oleh iPay88 Indonesia karena bergantung pada ISP. Lihat bagian pemberitahuan via email pada laman dokumentasi. Notifikasi email tidak boleh digunakan sebagai patokan identifikasi oleh merchant, gunakan online report untuk memeriksa status pembayaran.
  8. Pastikan orang teknik ditugaskan oleh merchant sebelum integrasi.
  9. Merchant harus memberi tahu iPay88 Support Team untuk tanggal live yang diinginkan minimal 3 hari kerja sebelumnya.

Diagram Transaksi

Berikut ini adalah diagram alir transaksi merchant dengan iPay88 Indonesia.


Proses Transaksi

Berikut ini adalah proses transaksi merchant dengan iPay88 Indonesia.

  1. Merchant mengirimkan HTTPs Post Request yang berisi detail pembayaran ke laman pembayaran iPay88 Indonesia. Detil pembayaran harus menyertakan:
    1. MerchantCode
    2. PaymentId
    3. RefNo
    4. Amount
    5. Currency
    6. ProdDesc
    7. UserName
    8. UserEmail
    9. UserContact
    10. Remark
    11. CCHolderName
    12. CCNo
    13. CCMonth
    14. CCYear
    15. CCCVV
    16. Lang
    17. Signature
    18. Response URL
    19. Backend URL

  2. iPay88 OPSG akan memverifikasi semua nilai yang dikirim oleh merchant, jika sudah sesuai dilanjutkan dengan kangkah berikutnya.

  3. Informasi akan dikirim ke bank untuk verifikasi lebih lanjut.

  4. Jika kartu tersebut adalah kartu 3D, halaman verifikasi 3D akan muncul, jika tidak akan dilanjutkan dengan langkah selanjutnya.

  5. Respon dikembalikan ke iPay88 Indonesia untuk untuk menunjukkan apakah transaksi telah berhasil atau gagal.

  6. iPay88 Indonesia merespon kembali status pembayaran ke merchant dengan signature.

  7. Jika status pembayaran sukses, merchant harus membandingkan signature dari iPay88 Indonesia dengan signature yang dihasilkan oleh merchant.

Integrasi Merchant

Berikut ini adalah langkah-langkah integrasi merchant dengan iPay88 online payment switching gateway (OPSG).


URL

  1. Development: https://sandbox.ipay88.co.id/epayment/entry_v2.asp
  2. Production: https://payment.ipay88.co.id/epayment/entry_v2.asp
  3. Requery: https://payment.ipay88.co.id/epayment/enquiry.asp

Merchant Request URL disediakan oleh merchant sebelum integrasi.

Definisi: Merchant Request URL adalah laman pembayaran di situs merchant yang mengirimkan parameter / nilai yang diperlukan ke iPay88 OPSG.


Merchant Response URL dapat ditentukan dengan mengisi parameter ResponseURL di laman request.

Definisi: Response page URL adalah laman di situs merchant yang akan menerima status pembayaran dari iPay88 OPSG.


Logo

iPay88 OPSG menyediakan merchant logo/banner tampil di laman pembayaran dan pemberitahuan email. Merchant dapat memberikan logo ke tim iPay88 Support untuk diunggah ke akun merchant.

Ukuran maksimum yang diperbolehkan untuk logo adalah 600 piksel (lebar) dan 100 piksel (tinggi). Format yang diperbolehkan adalah JPG, PNG, BMP, dan GIF.


Payment Request Parameter

Berikut ini adalah parameter request dengan HTTPS POST pada merchant yang dikirim ke iPay88 OPSG untuk menuju laman pembayaran.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode String (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
PaymentId Integer O Payment ID untuk metode pembayaran yang dituju.
RefNo String (20) M Nomor unik transaksi merchant atau Order ID.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
Currency String (5) M Harus IDR.
ProdDesc String (100) M Deskripsi produk.
UserName String (100) M Nama pelanggan.
UserEmail String (100) M Email pelanggan untuk mendapatkan nota pembayaran.
UserContact String (20) M Nomor kontak pelanggan.
Remark String (100) O Catatan merchant.
CCHolderName String (100) M Nama pemegang kartu kredit.
CCNo Integer M Nomor kartu kredit.
CCCVV Integer M Nomor CVV pemegang kartu kredit. Contoh 123.
CCMonth Integer M Bulan kadaluarsa kartu kredit. Contoh 01.
CCYear Integer M Tahun kadaluarsa kartu kredit. Contoh 15.
Lang String (20) O Encoding type
"ISO-8859-1" – English.
"UTF-8" – Unicode.
"GB2312" – Chinese Simplified.
"GD18030" – Chinese Simplified.
"BIG5" – Chinese Traditionl.
Signature String (100) M SHA signature (merujuk ke 3.1).
ResponseURL String (200) M Payment response page.
BackendURL String (200) M Backend response page URL.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

<html>
    <body>

        <form method="post" name="ePayment" action="https://sandbox.ipay88.co.id/epayment/entry_v2.asp">
            <input type="hidden" name="MerchantCode" value="ID00001">
            <input type="hidden" name="PaymentId" value="1">
            <input type="hidden" name="RefNo" value="A00000001">
            <input type="hidden" name="Amount" value="300000">
            <input type="hidden" name="Currency" value="IDR">
            <input type="hidden" name="ProdDesc" value="Photo Print">
            <input type="hidden" name="UserName" value="John Tan">
            <input type="hidden" name="UserEmail" value="john@hotmail.com">
            <input type="hidden" name="UserContact" value="0126500100">
            <input type="hidden" name="Remark" value="">
            <input type="hidden" name="CCHolderName" value="">
            <input type="hidden" name="CCNo" value="">
            <input type="hidden" name="CCCVV" value="">
            <input type="hidden" name="CCMonth" value="">
            <input type="hidden" name="CCYear" value="">
            <input type="hidden" name="Lang" value="UTF-8">
            <input type="hidden" name="Signature" value="Q/iIMzpjZCrhJ2Yt2dor1PaFEFI=">
            <input type="hidden" name="ResponseURL" value="http://www.abc.com/payment/response.asp">
            <input type="hidden" name="BackendURL" value="http://www.abc.com/payment/backend_response.asp">
            <input type="submit" value="Proceed with Payment" name="Submit"> 
        </form>

    </body>
</html>

Payment Response Parameter

Berikut ini adalah respon dengan HTTPS POST dari iPay88 OPSG ke merchant setelah selesai proses pembayaran.

Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode String (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
PaymentId Integer O Payment ID untuk metode pembayaran yang dituju.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
Currency Varchar (5) M Harus IDR.
Remark Varchar (100) O Catatan merchant.
TransId Varchar (30) O iPay88 OPSG ID Transaksi.
AuthCode Varchar (20) O Kode persetujuan bank.
Status Varchar (1) M Status pembayaran
"1" – Success.
"0" – Fail.
"6" – Pending (hanya tersedia untuk metode pembayaran ATM Transfer).
ErrDesc Varchar (100) O Deskripsi penyebab gagal-nya transaksi.
Signature Varchar (100) M SHA1 Signature (merujuk ke 3.2).

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

<%

MerchantCode	= Request.Form("MerchantCode")
PaymentId 		= Request.Form("PaymentId")
RefNo 			= Request.Form("RefNo")
Amount 			= Request.Form("Amount")
eCurrency 		= Request.Form("Currency")
Remark 			= Request.Form("Remark")
TransId 			= Request.Form("TransId")
AuthCode 		= Request.Form("AuthCode")
eStatus 			= Request.Form("Status")
ErrDesc                 = Request.Form("ErrDesc")
Signature 		= Request.Form("Signature")

%>

<Add your programming code here>
<?php

$merchantcode 	= $_REQUEST["MerchantCode"];
$paymentid 	= $_REQUEST["PaymentId"];
$refno 		= $_REQUEST["RefNo"];
$amount 	= $_REQUEST["Amount"];
$ecurrency 	= $_REQUEST["Currency"];
$remark 	= $_REQUEST["Remark"];
$transid 	= $_REQUEST["TransId"];
$authcode 	= $_REQUEST["AuthCode"];
$estatus 	= $_REQUEST["Status"];
$errdesc 	= $_REQUEST["ErrDesc"];
$signature	= $_REQUEST["Signature"];

?>

//Add your programming code here

Backend Post Feature

Backend post feature adalah teknologi server ke server yang tidak bergantung pada web browser si pelanggan merchant. Fitur ini harus diimplementasikan di situs merchant. Tujuan fitur ini adalah untuk mendapatkan status pembayaran dari iPay88 OPSG. Merchant bisa mendapatkan status pembayaran melalui laman backend merchant. iPay88 OPSG dapat mengirim status pembayaran secara berulang walaupun laman respon merchant gagal mendapatkan status tersebut yang disebabkan oleh browser web ditutup, batas waktu koneksi internet, dan lain sebagainya.


Sistem manajemen konten yang telah mendukung fitur backend post melalui plugin iPay88 Indonesia.

  1. Drupal
  2. Magento
  3. OpenCart
  4. Prestashop
  5. WHMCS
  6. Woocommerce
  7. WP Charitable


Catatan

  1. iPay88 OPSG hanya mengirim status pembayaran melalui laman backend merchant apabila status pembayaran pada transaksi merchant telah sukses. Jika status pembayaran gagal, maka iPay88 OPSG tidak akan mengirimkan status melalui laman backend merchant.

  2. Laman backend merchant harus menerapkan beberapa pengecekan yang sama seperti laman response seperti pengecekan signature, dan lain sebagainya untuk mencegah tejadinya pembajakan pada sistem merchant.

  3. laman backend merchant tidak boleh memiliki kode session sehingga sistem merchant masih dapat menerima status pembayaran dari iPay88 OPSG bahkan jika pelanggan telah keluar atau session telah berakhir.

  4. Anda perlu melakukakan pemeriksaan untuk menentukan fungsi perubah status transaksi baik di "laman response" atau "laman backend" sehingga tidak terjadinya perubahan status transaksi lebih dari satu kali.

    Note: Setelah iPay88 OPSG menerima informasi dari bank bahwa status pembayaran pada transaksi merchant telah suskes, iPay88 OPSG secara bersamaan akan mengirimkan status pembayaran tersebut ke "laman response" dan "laman backend" merchant.

  5. Laman backend bukan sebagai pengganti laman response. Anda harus terus menggunakan laman response seperti biasa.


Implementasi

Pada situs merchant, buat laman lain sebagai backend untuk menerima parameter dari iPay88 OPSG. Parameter backend yang dikirim oleh iPay88 OPSG sama seperti parameter yang dikirim ke laman response merchant. Pada laman request merchant, tentukan url backend melalui parameter "BackendURL".

Sebagai contoh, <input name = "BackendURL" value = "http://www.abc.com/backend_response">

Pada laman 'backend_response' Anda perlu menuliskan kata 'RECEIVEOK' saja (tanpa tanda kutip) sebagai konfirmasi setelah laman backend berhasil mendapatkan status pembayaran dari iPay88 OPSG. Tentunya kata tersebut tertulis setelah dilakukan pengecekan seperti signature dan lain sebagainya di laman backend merchant. iPay88 OPSG akan mencoba mengirim kembali status pembayaran ke laman 'backend_response' hingga 5 kali pada interval yang berbeda jika tidak terdeteksi 'RECEVEIOK'.

Contoh:

Di ASP >> response.write "RECEIVEOK"
Di PHP >> echo "RECEIVEOK";

Catatan: Pastikan hanya kata 'RECEIVEOK' tanpa tag HTML apa pun.


Requery Payment Status Parameters (Response URL to enquiry.asp)

Berikut ini adalah parameter dengan HTTPS POST pada merchant yang dikirim ke iPay88 OPSG untuk re-query status pembayaran.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


Berikut ini adalah kemungkinan pesan didapatkan dari iPay88 OPSG.


Pesan
Deskripsi
00 Pembayaran sukses.
Invalid parameters Parameter yang dikirimkan merchant tidak tepat.
Record not found Data tidak ditemukan.
Incorrect amount Total yang tidak tepat (berbeda).
Payment fail Pembayaran gagal.
Payment Pending Pembayaran tertunda dan pelanggan harus membayar di mesin ATM.
Haven’t Paid (0) Tagihan belum dibayar atau berhenti di laman pembayaran iPay88.
Haven’t Paid (1) Tagihan belum dibayar atau berhenti di laman bank.
M88Admin Status pembayaran diubah oleh iPay88 Admin (gagal).
<%
Function SendToiPayInq(byval MerchantCode, byval RefNo, 
byval Amount)	
                    
Dim TryNo, thenQString, URL, strReturn	
TryNo = 0

QString = "MerchantCode=" & MerchantCode & 
    "&RefNo=" & RefNo & _
        "&Amount=" & Amount
                    
    URL = "https://payment.ipay88.co.id/epayment/enquiry.asp"	

    On Error Resume Next

    Do

    Set xobj = Server.CreateObject ("Msxml2.ServerXMLHTTP.3.0")
    xobj.setTimeouts 30000, 60000, 60000, 60000
    xobj.open "POST", URL, false
    xobj.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    xobj.send QString

    TryNo = TryNo + 1		
    Loop While xobj.status <> 200 and TryNo < 3
                    
    If xobj.status <> 200 Then			
        SendToiPayInq = Err.Description & "(" & Err.Number & ")"
    Else
        SendToiPayInq = xobj.responseText
    End If
        set xobj = nothing		

    End Function

%>
<?php

function Requery ($MerchantCode, $RefNo, $Amount)
{
$query = "https://payment.ipay88.co.id/epayment/enquiry.asp?MerchantCode=".$MerchantCode."&RefNo=".$RefNo."&Amount=".$Amount;
                    
$url     = parse_url($query);
$host    = $url["host"];
$path    = $url["path"] . "?" . $url["query"];
$timeout = 1;
                    
$fp = fsockopen ($host, 80, $errno, $errstr, $timeout);
                    
if ($fp) 
{
    fputs ($fp, "GET $path HTTP/1.0\nHost: ".$host."\n\n");
    while (!feof($fp)) 
    {
        $buf .= fgets($fp, 128);
    }
                        
    $lines   = split("\n", $buf);
    $Result  = $lines[count($lines)-1];
                        
    fclose($fp);
} 
                    
else 
{
    //enter error handing code here
}
                    
return $Result;
}

?>

Kontrol Keamanan

Untuk meningkatkan keamanan, silahkan ikuti langkah-langkah berikut di laman penerimaan status pembayaran merchant (Response URL).

  1. Periksa nilai HTTP_REFERER dari https://payment.ipay88.co.id (hanya berlaku jika situs web merchant berfungsi dengan Sertifikat SSL).
  2. Periksa jumlah pembayaran dari iPay88 OPSG sesuai dengan pelanggan Anda.
  3. Bandingkan signature dari iPay88 OPSG dengan signature yang Anda hasilkan sendiri.


Integritas Data dan Keamanan menggunakan Signature Acak

Pengacakan SHA1 adalah fitur keamanan yang memungkinkan skrip Anda untuk mengidentifikasi hasil transaksi sebenarnya dari sumber otorisasi yang sesuai. Bagi iPay88 OPSG, fitur ini berguna untuk memastikan integritas data yang diterima pada setiap request transaksi dari merchant.

Menggunakan algoritma SHA1, signature atau fingerprint dari transaksi dapat dihasilkan. Algoritma matematika yang digunakan untuk membangun signature ini dirancang sedemikian rupa sehingga setiap adanya perubahan pada informasi yang digunakan dalam perhitungan akan menghasilkan signature yang berbeda pula.

Informasi yang digunakan dalam perhitungan signature tidak dapat diketahui walau dengan menganalisa signature itu sendiri. Signature dihasilkan dengan menggunakan informasi dari akun Anda sebagai merchant. Setiap transaksi yang diproses melalui sistem memiliki pengacakan signature tersendiri yang berkaitan dengan transaksi tersebut.


Request Page Signature

Signature harus disertakan pada proses request laman pembayaran iPay88 OPSG disetiap transaksi merchant. Signature tersebut adalah hasil dari pengacakan lima bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 OPSG)
  2. MerchantCode
  3. RefNo
  4. CCNo
  5. CCMonth
  6. CCYear
  7. CCCVV
  8. Amount
  9. Currency

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & RefNo & CCNo & CCMonth & CCYear & CCCVV & Amount & Currency

Contoh:

MerchantKey = "apple"
MerchantCode = "ID00001"
RefNo = "A00000001"
CCNo = "4111111111111111"
CCMonth = "01"
CCYear = "18"
CCCVV = "123"
Amount = "1000000" (catatan: 1000000 adalah representasi dari total Rp10.000,00)
Currency = "IDR"

Pengacakan akan dihitung melalui string berikut:
appleID00001A00000001411111111111111101181231000000IDR

Hasil signature (menggunakan algoritma SHA1) adalah:
u4UJxVz6jgxx0qFA0b6oLC6sUgs=

Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.

Public Shared Function ComputeHas(ByVal Key As String)
Dim objSHA1 As New SHA1CryptoServicesProvider()
objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
Dim buffer() As Byte = objSHA1.Hash
DIm HashValue As String = System.Convert.ToBase64String(buffer)
                    
Return HashValue
End Function
<?php

function iPay88_signature($source)
{
    return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
    for ($i=0;$i<strlen($hexSource);$i=$i+2)
{
    $bin .= chr(hexdec(substr($hexSource,$i,2)));
}
                
    return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
public static String encrypt(String password) 
{
    MessageDigest md;
    try 
    {
        md = MessageDigest.getInstance("SHA");
        md.update(password.getBytes("UTF-8"));
        byte raw[] = md.digest();
        String hash = (new BASE64Encoder()).encode(raw);
                        
        return hash;
    } 
                    
    catch (NoSuchAlgorithmException e) 
    {
    } 
                    
    catch (java.io.UnsupportedEncodingException e) 
    {
    }
                    
    return null;
}

public static void main(String[] args) 
{
    System.out.println(encrypt("my password"));	
    // string to hash is here
}
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file

var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
* Perform a simple self-test to see if the VM is working
*/
function sha1_vm_test()
{
return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function core_sha1(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;

var w = Array(80);
var a =  1732584193;
var b = -271733879;
var c = -1732584194;
var d =  271733878;
var e = -1009589776;

for(var i = 0; i < x.length; i += 16)
{
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
    if(j < 16) w[j] = x[i + j];
    else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
    var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                    safe_add(safe_add(e, w[j]), sha1_kt(j)));
    e = d;
    d = c;
    c = rol(b, 30);
    b = a;
    a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
}
return Array(a, b, c, d, e);

}

/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
function sha1_ft(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}

/*
* Determine the appropriate additive constant for the current iteration
*/
function sha1_kt(t)
{
return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
        (t < 60) ? -1894007588 : -899497514;
}

/*
* Calculate the HMAC-SHA1 of a key and some data
*/
function core_hmac_sha1(key, data)
{
var bkey = str2binb(key);
if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

var ipad = Array(16), opad = Array(16);
for(var i = 0; i < 16; i++)
{
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
}

var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160);
}

/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}

/*
* Bitwise rotate a 32-bit number to the left.
*/
function rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}

/*
* Convert an 8-bit or 16-bit string to an array of big-endian words
* In 8-bit function, characters >255 have their hi-byte silently ignored.
*/
function str2binb(str)
{
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
return bin;
}

/*
* Convert an array of big-endian words to a string
*/
function binb2str(bin)
{
var str = "";
var mask = (1 << chrsz) - 1;
for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
return str;
}

/*
* Convert an array of big-endian words to a hex string.
*/
function binb2hex(binarray)
{
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
    hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
}
return str;
}

/*
* Convert an array of big-endian words to a base-64 string
*/
function binb2b64(binarray)
{
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for(var i = 0; i < binarray.length * 4; i += 3)
{
var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
            | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
            |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
    if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
    else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
}
return str;
}

Response Page Signature

Jika status pembayaran dari transaksi merchant dinyatakan sukses, iPay88 OPSG akan mengirim signature di laman response dan backend merchant. Signature ini harus dibandingkan dengan signature yang dihasilkan oleh merchant sendiri guna mengindari adanya pembajakan. Signature tersebut adalah hasil dari pengacakan tujuh bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 OPSG)
  2. MerchantCode
  3. PaymentId
  4. RefNo
  5. Amount
  6. Currency
  7. Status

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & PaymentId & RefNo & Amount & Currency & Status


Contoh:

MerchantKey = "apple"
MerchantCode = "ID00001"
PaymentId = "1"
RefNo = "A00000001"
Amount = "1000000" (catatan: 1000000 adalah representasi dari total Rp10.000,00)
Currency = "IDR"
Status = "1"

Pengacakan akan dihitung melalui string berikut:
appleID000011A000000011000000IDR1

Hasil signature (menggunakan algoritma SHA1) adalah:
vewK2KcOl3lyFug1UEsnzDjTDDA=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.


Ketika iPay88 OPSG menerima request atau transaksi dari merchant, iPay88 OPSG akan memeriksa nilai acak signature yang dihasilkan untuk dicocokkan dengan nilai signature yang merchant kirim. Ketika sistem merchant menerima hasil transaksi, merchant dapat membuat signature dan pastikan sama dengan signature yang dikirim balik oleh iPay88 OPSG. Merchant akan mendapatkan signature di laman response jika transaksi tidak error (tidak termasuk transaksi yang disetujui atau ditolak).

Setelah merchant menerima informasi dari iPay88 OPSG terkait status pembayaran dari transaksi, merchant harus menjalanakan algoritma acak pada tujuh bidang utama yg telah disebutkan diatas sehingga menghasilkan suatu signature. Merchant wajib mencocokkan hasil signature merchant dengan signature iPay88 OPSG. Dapat dipastikan jika signature yang dihasilkan merchant saat proses request dan dikirim ke iPay88 OPSG, maka transaksi merchant telah diproses oleh sistem iPay88 OPSG.

Merchant key dibuat oleh iPay88 OPSG untuk merchant. Merchant key bersifat rahasia bersama (antara merchant dan iPay88 OPSG), dan merupakan salah satu bagian kunci informasi untuk proses pengacakan signature. Merchant key akan dibuat ulang jika iPay88 OPSG mencurigai bahwa merchant key sudah tidak aman atau terjadi kasus penipuan. Informasi lebih lanjut tentang algoritma acak SHA1, termasuk sampel kode untuk implementasi dapat ditemukan di RFC 3174 dalam laman Task Force Internet Engineering.

Public Shared Function ComputeHas(ByVal Key As String)
Dim objSHA1 As New SHA1CryptoServicesProvider()
objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
Dim buffer() As Byte = objSHA1.Hash
DIm HashValue As String = System.Convert.ToBase64String(buffer)
                    
Return HashValue
End Function
<?php

function iPay88_signature($source)
{
return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
for ($i=0;$i<strlen($hexSource);$i=$i+2)
{
    $bin .= chr(hexdec(substr($hexSource,$i,2)));
}
                
return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
public static String encrypt(String password) 
{
    MessageDigest md;
    try 
    {
        md = MessageDigest.getInstance("SHA");
        md.update(password.getBytes("UTF-8"));
        byte raw[] = md.digest();
        String hash = (new BASE64Encoder()).encode(raw);
                        
        return hash;
    } 
                    
    catch (NoSuchAlgorithmException e) 
    {
    } 
                    
    catch (java.io.UnsupportedEncodingException e) 
    {
    }
                    
    return null;
}

public static void main(String[] args) 
{
    System.out.println(encrypt("my password"));	
    // string to hash is here
}
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
* Perform a simple self-test to see if the VM is working
*/
function sha1_vm_test()
{
return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function core_sha1(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;

var w = Array(80);
var a =  1732584193;
var b = -271733879;
var c = -1732584194;
var d =  271733878;
var e = -1009589776;

for(var i = 0; i < x.length; i += 16)
{
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
    if(j < 16) w[j] = x[i + j];
    else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
    var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
            safe_add(safe_add(e, w[j]), sha1_kt(j)));
    e = d;
    d = c;
    c = rol(b, 30);
    b = a;
    a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
}
return Array(a, b, c, d, e);

}

/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
function sha1_ft(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}

/*
* Determine the appropriate additive constant for the current iteration
*/
function sha1_kt(t)
{
return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
        (t < 60) ? -1894007588 : -899497514;
}

/*
* Calculate the HMAC-SHA1 of a key and some data
*/
function core_hmac_sha1(key, data)
{
var bkey = str2binb(key);
if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

var ipad = Array(16), opad = Array(16);
for(var i = 0; i < 16; i++)
{
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
}

var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160);
}

/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}

/*
* Bitwise rotate a 32-bit number to the left.
*/
function rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}

/*
* Convert an 8-bit or 16-bit string to an array of big-endian words
* In 8-bit function, characters >255 have their hi-byte silently ignored.
*/
function str2binb(str)
{
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
return bin;
}

/*
* Convert an array of big-endian words to a string
*/
function binb2str(bin)
{
var str = "";
var mask = (1 << chrsz) - 1;
for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
return str;
}

/*
* Convert an array of big-endian words to a hex string.
*/
function binb2hex(binarray)
{
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
            hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
}
return str;
}

/*
* Convert an array of big-endian words to a base-64 string
*/
function binb2b64(binarray)
{
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for(var i = 0; i < binarray.length * 4; i += 3)
{
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
                    {
    if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
    else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
}
return str;
}

Laporan dan Pemberitahuan

Kami menyediakan referensi sebagai informasi tambahan untuk Anda. Berikut ini adalah referensi mengenai laporan dan pemberitahuan. Informasi ini perlu Anda ketahui sebagai merchant kami.


Laporan dan Transaksi Merchant

Kami memberikan fasilitas kepada merchant untuk melihat laporan dan cek transaksi secara online.

  1. Merchant dapat mengunjungi laman laporan iPay88 OPSG melalui:
    1. Report URL
      • Sandbox: https://sandbox.ipay88.co.id/epayment/report/index.asp
      • Production: https://payment.ipay88.co.id/epayment/report/index.asp
    2. Login Name: disediakan oleh iPay88 OPSG
    3. Password: disediakan oleh iPay88 OPSG
  2. Setelah login, select all transaction, filter transaction date, dan klik search.
  3. Laporan transaksi akan ditampilkan.

Pemberitahuan Via Email

Pemberitahuan via email tidak dijamin oleh iPay88 OPSG karena bergantung pada ISP. Laporan Online (online report) adalah media utama untuk melihat status transaksi. Pemberitahuan via email tidak boleh diambil atau disimpulkan sebagai pengganti media utama.

Transmisi email tidak dapat dijamin aman atau bebas dari kesalahan karena informasi dapat disadap, rusak, hilang, hancur, datang terlambat atau tidak lengkap, atau mengandung virus. Oleh karena itu pengirim tidak bertanggung jawab atas kesalahan atau kelalaian apa pun dalam isi email, yang timbul sebagai akibat dari transmisi email. iPay88 tidak bertanggung jawab atas isi email, atau konsekuensi dari tindakan apa pun yang diambil atas dasar informasi yang diberikan, kecuali jika informasi itu kemudian dikonfirmasi secara tertulis.


1. Email Pembayaran Pelanggan

Pelanggan akan menerima email pemberitahuan berisi detil pembayaran setelah pembayaran berhasil. Dibawah ini adalah contoh email yang dikirimkan ke pelanggan.



2. Email Pemberitahuan Merchant

Merchant juga menerima email pemberitahuan berisi detil pembayaran setelah pembayaran berhasil. Untuk memastikan Anda dapat menerima semua email kami, pastikan Anda telah menjalani langkah-langkah berikut:

  1. Dari mailbox Anda, pastikan white-list alamat email iPay88 dengan menambahkan sales@ipay88.co.id ke dalam daftar teman Anda.
  2. Selain itu, pastikan mailbox Anda tidak melakukan black-list alamat email iPay88 yaitu sales@ipay88.co.id.
  3. Untuk pelayanan yang lebih baik, white-list alamat email dan domain iPay88.co.id. Harap verifikasi atau izinkan personel teknik Anda (webhosting atau email server) untuk memverifikasi status email Anda. Di bawah ini adalah contoh email:

Dibawah ini adalah contoh email yang dikirimkan ke merchant.


Recurring Payment Versi 2.0.3


Segera integrasikan iPay88 Recurring Payment ini dengan situs Anda. API ini menjadikan situs Anda untuk menerima pembayaran berulang dan memudahkan memudahkan pelanggan Anda dalam bertransaksi.


Download iPay88 Recurring Payment

Objektif

Merchant dapat mendaftarkan transaksi recurring payment kepada pelanggan dengan metode HTTPs Post Form Data melalui iPay88 Indonesia.


URL

Berikut URL yang digunakan sebagai Subscription Request dan Response.

  1. Subscription Request URL:
    https://payment.ipay88.co.id/recurringpayment2.0/subscription.asp
  2. Subscription Response URL:
    [provided by merchant before start the integration]

Parameter

Berikut ini adalah parameter yang digunakan untuk proses recurring dengan iPay88 Indonesia.


Subscription Request Parameters

Merchant mengirimkan parameter melalui HTTPS POST sebagai subscription request kepada iPay88 Indonesia.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
FirstPaymentDate Datetime M Tanggal pembayaran pertama (DDMMYYYY).
Currency Varchar (5) M Hanya IDR.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
NumberofPayments int M Subscription cycle. Contoh 12.
Frequency Int M Tipe frekuensi:
1 = Weekly
2 = Monthly
3 = Quarterly
4 = Half-Yearly
5 = Yearly

*Pass “2” for monthly frequency.
Desc Varchar (100) M Deskripsi produk.
CC_Ic Varchar (50) M IC pemegang kartu kredit atau nomor paspor.
CC_Email Varchar (255) M Alamat email pemegang kartu kredit.
CC_Phone Varchar (100) M Nomor kontak pemegang kartu kredit.
P_Name Varchar (100) M Nama subscriber yang tertulis pada kartu identitas (KTP) atau passpor.
P_Email Varchar (255) M Alamat email subscriber.
P_Phone Varchar (100) M Nomor kontak subscriber.
P_Addr|1 Varchar (100) M Alamat baris pertama subscriber.
P_Addr|2 Varchar (100) O Alamat baris kedua subscriber.
P_City Varchar (100) M Kota subscriber.
P_State Varchar (100) M Provinsi subscriber.
P_Zip Varchar (100) M Kode pos subscriber.
P_Country Varchar (100) M Negara subscriber.
Signature String (100) M SHA signature.
ResponseURL String (200) M Payment response page.
BackendURL String (200) M Backend response page URL.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


Subscription Response Parameters

iPay88 Indonesia mengirimkan parameter melalui HTTPS POST sebagai subscription response kepada merchant.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
SubscriptionNo Varchar (20) M Unique iPay88 subscription number.
Note: SubscriptionNo sebagai RefNo yang dikirim kembali kepada merchant melalui BackendURL ketika recurring payment telah sukses. Contoh S00001701.
FirstPaymentDate Datetime M Tanggal pembayaran pertama (DDMMYYYY).
Currency Varchar (3) M Hanya IDR.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
NumberofPayments Int (10) M Subscription cycle. Contoh 12.
Frequency Int (10) M Tipe frekuensi:
1 = Weekly
2 = Monthly
3 = Quarterly
4 = Half-Yearly
5 = Yearly

*Pass “2” for monthly frequency
TransId Varchar (30) O iPay88 transaction ID.
AuthCode Varchar (10) O Kode konfirmasi bank.
Desc Varchar (100) M Deskripsi subscription.
Status Varchar (2) M Subscription status.
'00' - Success.
'01' - Fail.
ErrDesc Varchar (100) M Error deskripsi.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


Termination Request Parameters

Merchant mengirimkan parameter melalui HTTPS POST sebagai termination request kepada iPay88 Indonesia.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID yang dikirim oleh merchant sebagai penanda untuk subscription request.
Signature String (100) M SHA signature.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


Termination Response Parameters

iPay88 Indonesia mengirimkan parameter melalui HTTPS POST sebagai termination response kepada merchant.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Status Varchar (2) M Subscription status.
'00' - Success.
'01' - Fail.
ErrDesc Varchar (100) M Error deskripsi.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


**Gunakan XML parser untuk to mendapatkan termination response kembali.

Backend URL Response Parameters

Fitur pada backend post ini akan dikirim oleh iPay88 Indonesia kepada merchant jika proses recurring payment pelanggan Anda telah dinyatakan sukses. Fitur ini tidak berlaku jika proses pembayaran dinyatakan gagal.

Implementasi
Pada situs merchant, Anda harus membuat sebuah laman yang dapat menerima response paramenets yang disebutkan dibawah. Contoh laman: http://www.abc.com/backend_response.asp

Di laman subscription request, Anda dapat memberi spesifikasi backend post URL melalui BackendURL parameter. Contoh: <input name = "BackendURL" value = "http://www.abc.com/backend_response">

Di laman backend_response Anda harus menulis kata "RECEIVEOK" saja (tanpa petik) jika laman backend sukses atau berhasil mendapatkan balikan status dari iPay88 Indonesia. Jika tidak, iPay88 Indonesia akan mengirim status ke laman backend merchant sebanyak 3 kali dalam tempo yang berbeda.

Contoh:

Di ASP >> response.write "RECEIVEOK"
Di PHP >> echo "RECEIVEOK";

Catatan: Pastikan hanya kata 'RECEIVEOK' tanpa tag HTML apa pun.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode String (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
PaymentId Integer O Payment ID untuk metode pembayaran yang dituju.
RefNo Varchar (20) M Nomor unik transaksi untuk recurring payment yang dikembalikan oleh iPay88.
Contoh:
S00001701-1 (first recurring payment).
S00001701-2 (second recurring payment).
Catatan: Refno ini adalah SubscriptionNo yang dikembalikan ke merchant setelah selesai tahap register recurring payment. Pengembalian RefNo akan memiliki tanda hubung (-) diikuti oleh 1 atau 2 untuk menunjukkan cicilan keberapa.
RecurringRefno Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Catatan: nilai yang dikembalikan melalui RecurringRefno adalah RefNo yang dikirimkan oleh merchant.
Amount Currency M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
Currency Varchar (5) M Hanya IDR.
Remark Varchar (100) O Catatan merchant.
TransId Varchar (30) O iPay88 OPSG ID Transaksi.
AuthCode Varchar (20) O Kode persetujuan bank.
Status Varchar (1) M Status pembayaran
"1" – Success.
"0" – Fail.
ErrDesc Varchar (100) O Deskripsi penyebab gagal-nya transaksi.
Signature Varchar (100) M SHA1 Signature.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

<%

MerchantCode	= Request.Form("MerchantCode")
PaymentId 		= Request.Form("PaymentId")
RefNo 			= Request.Form("RefNo")
RecurringRefno	= Request.Form("RecurringRefno")
Amount 		= Request.Form("Amount")
eCurrency 		= Request.Form("Currency")
Remark 		= Request.Form("Remark")
TransId 			= Request.Form("TransId")
AuthCode 		= Request.Form("AuthCode")
eStatus 			= Request.Form("Status")
ErrDesc                 = Request.Form("ErrDesc")
Signature 		= Request.Form("Signature")

%>

<Add your programming code here>
<?php

$merchantcode 	= $_REQUEST["MerchantCode"];
$paymentid 	= $_REQUEST["PaymentId"];
$refno 		= $_REQUEST["RefNo"];
$RecurringRefno	= $_REQUEST["RecurringRefno"];
$amount 	= $_REQUEST["Amount"];
$ecurrency 	= $_REQUEST["Currency"];
$remark 	= $_REQUEST["Remark"];
$transid 	= $_REQUEST["TransId"];
$authcode 	= $_REQUEST["AuthCode"];
$estatus 	= $_REQUEST["Status"];
$errdesc 	= $_REQUEST["ErrDesc"];
$signature	= $_REQUEST["Signature"];

?>

//Add your programming code here

Kontrol Keamanan

Untuk meningkatkan keamanan, silahkan ikuti langkah-langkah berikut di laman penerimaan status pembayaran merchant (Response URL).

  1. Periksa nilai HTTP_REFERER dari https://payment.ipay88.co.id (hanya berlaku jika situs web merchant berfungsi dengan Sertifikat SSL).
  2. Periksa jumlah pembayaran dari iPay88 Indonesia sesuai dengan pelanggan Anda.
  3. Bandingkan signature dari iPay88 Indonesia dengan signature yang Anda hasilkan sendiri.

Integritas Data dan Keamanan menggunakan Signature Acak

Pengacakan SHA1 adalah fitur keamanan yang memungkinkan skrip Anda untuk mengidentifikasi hasil transaksi sebenarnya dari sumber otorisasi yang sesuai. Bagi iPay88 Indonesia, fitur ini berguna untuk memastikan integritas data yang diterima pada setiap request transaksi dari merchant.

Menggunakan algoritma SHA1, signature atau fingerprint dari transaksi dapat dihasilkan. Algoritma matematika yang digunakan untuk membangun signature ini dirancang sedemikian rupa sehingga setiap adanya perubahan pada informasi yang digunakan dalam perhitungan akan menghasilkan signature yang berbeda pula.

Informasi yang digunakan dalam perhitungan signature tidak dapat diketahui walau dengan menganalisa signature itu sendiri. Signature dihasilkan dengan menggunakan informasi dari akun Anda sebagai merchant. Setiap transaksi yang diproses melalui sistem memiliki pengacakan signature tersendiri yang berkaitan dengan transaksi tersebut.

Subscription Request Page Signature

Signature harus disertakan pada proses request laman pembayaran iPay88 Indonesia disetiap transaksi merchant. Signature tersebut adalah hasil dari pengacakan delapan bidang utama berikut.

  1. MerchantCode
  2. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 Indonesia)
  3. RefNo
  4. Firstpaymentdate
  5. Currency
  6. Amount
  7. NumberofPayments
  8. Frequency

Field harus tersusun mengikuti aturan berikut:
MerchantCode & MerchantKey & RefNo & Firstpaymentdate & Currency & Amount & NumberofPayments & Frequency

Contoh:

MerchantCode = "M00003"
MerchantKey = "apple"
RefNo = "A00000001"
Firstpaymentdate = "11112013"
Currency = "IDR"
Amount = "100" (catatan: 100 adalah representasi dari total Rp1,00)
NumberOfPayments = "12"
Frequency = "1"

Pengacakan akan dihitung melalui string berikut:
M00003appleA0000000111112013IDR100121

Hasil signature (menggunakan algoritma SHA1) adalah:
eR9amDNDKTzlX3sE8ZTgx5lFZ8M=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.

Public Shared Function ComputeHas(ByVal Key As String)
   Dim objSHA1 As New SHA1CryptoServicesProvider()
   objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
   Dim buffer() As Byte = objSHA1.Hash
   DIm HashValue As String = System.Convert.ToBase64String(buffer)
    
   Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Termination Request Page Signature

Signature harus disertakan pada proses request laman pembayaran iPay88 Indonesia disetiap transaksi merchant. Signature tersebut adalah hasil dari pengacakan tiga bidang utama berikut.

  1. MerchantCode
  2. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 Indonesia)
  3. RefNo

Field harus tersusun mengikuti aturan berikut:
MerchantCode & MerchantKey & RefNo

Contoh:

MerchantCode = "M00003"
MerchantKey = "apple"
RefNo = "A00000001"

Pengacakan akan dihitung melalui string berikut:
M00003appleA00000001

Hasil signature (menggunakan algoritma SHA1) adalah:
4d3NplZBQx8cdm/b5sHZ2exSTS8=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.

Public Shared Function ComputeHas(ByVal Key As String)
   Dim objSHA1 As New SHA1CryptoServicesProvider()
   objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
   Dim buffer() As Byte = objSHA1.Hash
   DIm HashValue As String = System.Convert.ToBase64String(buffer)
    
   Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Backend URL Signature

Jika transaksi yang dilakukan merchant telah berhasil, merchant diharuskan membuat signature untuk faktor keamanan data disetiap transaksi merchant. Signature tersebut adalah hasil dari pengacakan tujuh bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 Indonesia)
  2. MerchantCode
  3. PaymentId
  4. RefNo
  5. Amount
  6. Currency
  7. Status

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & PaymentId & RefNo & Amount & Currency & Status

Contoh:

MerchantKey = "apple"
MerchantCode = "M00003"
PaymentId = "2"
RefNo = "S00001701-1"
Amount = "100" (catatan: 100 adalah representasi dari total Rp1,00)
Currency = "IDR"
Status = "1"

Pengacakan akan dihitung melalui string berikut:
appleM000032S00001701-1100IDR1

Hasil signature (menggunakan algoritma SHA1) adalah:
kX7Icxcj2TtCbSL/wWw5haKaU4A=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.


Ketika iPay88 Indonesia menerima request atau transaksi dari merchant, iPay88 Indonesia akan memeriksa nilai acak signature yang dihasilkan untuk dicocokkan dengan nilai signature yang merchant kirim. Ketika sistem merchant menerima hasil transaksi, merchant dapat membuat signature dan pastikan sama dengan signature yang dikirim balik oleh iPay88 Indonesia. Merchant akan mendapatkan signature di laman response jika transaksi tidak error (tidak termasuk transaksi yang disetujui atau ditolak).

Setelah merchant menerima informasi dari iPay88 Indonesia terkait status pembayaran dari transaksi, merchant harus menjalanakan algoritma acak pada tujuh bidang utama yg telah disebutkan diatas sehingga menghasilkan suatu signature. Merchant wajib mencocokkan hasil signature merchant dengan signature iPay88 Indonesia. Dapat dipastikan jika signature yang dihasilkan merchant saat proses request dan dikirim ke iPay88 Indonesia, maka transaksi merchant telah diproses oleh sistem iPay88 Indonesia.

Merchant key dibuat oleh iPay88 Indonesia untuk merchant. Merchant key bersifat rahasia bersama (antara merchant dan iPay88 Indonesia), dan merupakan salah satu bagian kunci informasi untuk proses pengacakan signature. Merchant key akan dibuat ulang jika iPay88 Indonesia mencurigai bahwa merchant key sudah tidak aman atau terjadi kasus penipuan. Informasi lebih lanjut tentang algoritma acak SHA1, termasuk sampel kode untuk implementasi dapat ditemukan di RFC 3174 dalam laman Task Force Internet Engineering.

Public Shared Function ComputeHas(ByVal Key As String)
   Dim objSHA1 As New SHA1CryptoServicesProvider()
   objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
   Dim buffer() As Byte = objSHA1.Hash
   DIm HashValue As String = System.Convert.ToBase64String(buffer)
    
   Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Sampel Email

Berikut adalah sampel email yang akan dikirimkan kepada pelanggan Anda.


Recurring Berhasil Ditagih

Berikut ini adalah sampel email jika proses recurring telah berhasil.


Recurring Gagal Ditagih

Berikut ini adalah sampel email jika proses recurring gagal.


Seamless Payment Versi 1.0.5


Segera integrasikan iPay88 Seamless Payment ini dengan platform online bisnis Anda. API ini menjadikan situs Anda dapat menerima pembayaran melalui Online Credit seperti Kredivo, Indodana, dan Akulaku.


Download iPay88 Seamless Payment

Objektif

Merchant dapat menyediakan metode pembayaran Kredivo, Indodana, dan Akulaku secara full payment maupun cicilan kepada pelanggan dengan metode JavaScript Object Notation (JSON) melalui iPay88 Indonesia.


Proses Transaksi

Berikut ini adalah diagram alir transaksi merchant dengan iPay88 Indonesia.


Payment Request

Berikut ini adalah parameter yang digunakan untuk proses request dengan iPay88 Indonesia.


URL Request

  1. Development:
    https://sandbox.ipay88.co.id/ePayment/WebService/PaymentAPI/Checkout
  2. Production:
    https://payment.ipay88.co.id/ePayment/WebService/PaymentAPI/Checkout


Request Format

Merchant mengirimkan parameter melalui JSON sebagai request kepada iPay88 Indonesia. Merchant diharuskan untuk melakukan pengacakan pada signature.


No
Nama Field
Tipe Data
M/O
Deskripsi
1 MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
2 PaymentId Integer M Payment ID 55 untuk untuk metode pembayaran Kredivo, 70 untuk metode pembayaran Indodana, dan 71 untuk metode pembayaran Akulaku.
3 Currency Varchar (5) M Hanya IDR.
4 RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
5 Amount Integer M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800. Total adalah jumlah yang harus dibayar secara keseluruhan.
6 ProdDesc Varchar (100) M Deskripsi produk.
7 UserName Varchar (100) M Nama pelanggan.
8 UserEmail Varchar (100) M Email pelanggan untuk mendapatkan nota pembayaran.
9 UserContact Varchar (20) M Nomor kontak pelanggan.
10 Remark Varchar (100) O Catatan merchant.
11 Lang Varchar (20) O Encoding type
"ISO-8859-1" – English.
"UTF-8" – Unicode.
"GB2312" – Chinese Simplified.
"GD18030" – Chinese Simplified.
"BIG5" – Chinese Traditionl.
12 ResponseURL Varchar (200) M Payment response page. Contoh https://ipay88-store.com/response.
13 BackendURL Varchar (200) M Backend response page URL. Contoh https://ipay88-store.com/backend.
14 Signature Varchar (100) M SHA signature (merujuk ke 3.1).
15 xfield1 Varchar (20) O Parameter ini hanya berlaku untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.
16 itemTransaction List (n) M Daftar produk yang dipesan oleh pelanggan.
16.1 Id Varchar (50) M ID produk yang dipesan.
16.2 Name Varchar (100) M Nama produk yang dipesan.
16.3 Quantity Integer M Kuantitas produk yang dipesan.
16.4 Amount Integer M Harga produk dikalikan dengan jumlah kuantitas. Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
16.5 Type Varchar (100) M Tipe produk yang dipesan. Khusus taxfee, shippingfee, dan discount tidak perlu mencantumkan parameter ini.
16.6 Url Varchar (100) M Url produk yang dipesan. Khusus taxfee, shippingfee, dan discount tidak perlu mencantumkan parameter ini.
16.7 ImageUrl Varchar (100) O Url gambar produk yang dipesan. Khusus taxfee, shippingfee, dan discount tidak perlu mencantumkan parameter ini.
16.8 ParentType Varchar (100) M Parameter ini dapat diisi dengan Seller atau Item.
16.9 ParentId Varchar (100) M Parameter ini dapat diisi dengan Seller ID jika parameter ParentType berisi Seller atau diisi dengan Item ID jika parameter ParentType berisi Item.
17 ShippingAddress List (n) M Daftar alamat pengiriman produk.
17.1 FirstName Varchar (100) M Nama awal yang tertuju untuk alamat pengiriman produk.
17.2 LastName Varchar (100) M Nama akhir yang tertuju untuk alamat pengiriman produk.
17.3 Address Varchar (100) M Alamat yang tertuju untuk pengiriman produk.
17.4 City Varchar (100) M Kota yang tertuju untuk alamat pengiriman produk.
17.5 PostalCode Varchar (6) M Kode pos yang tertuju untuk alamat pengiriman produk.
17.6 Phone Varchar (20) M Nomor telepon yang tertuju untuk alamat pengiriman produk.
17.7 CountryCode Varchar (3) M Kode negara yang tertuju untuk alamat pengiriman produk. Contoh ID untuk Indonesia.
18 BillingAddress List (n) M Daftar alamat pengiriman produk.
18.1 FirstName Varchar (100) M Nama awal yang tertuju untuk alamat pengiriman produk.
18.2 LastName Varchar (100) M Nama akhir yang tertuju untuk alamat pengiriman produk.
18.3 Address Varchar (100) M Alamat yang tertuju untuk pengiriman produk.
18.4 City Varchar (100) M Kota yang tertuju untuk alamat pengiriman produk.
18.5 PostalCode Varchar (6) M Kode pos yang tertuju untuk alamat pengiriman produk.
18.6 Phone Varchar (20) M Nomor telepon yang tertuju untuk alamat pengiriman produk.
18.7 CountryCode Varchar (3) M Kode negara yang tertuju untuk alamat pengiriman produk. Contoh ID untuk Indonesia.
19 Sellers List (n) M Daftar informasi Seller.
19.1 Id Varchar (100) M Seller ID.
19.2 Name Varchar (100) M Nama Seller.
19.3 Url Varchar (100) M Url Seller.
19.4 SerialIdNumber Varchar (100) M Nomor tanda pengenal Seller seperti KTP, SIM, dan sebagainya.
19.5 Email Varchar (100) M Alamat email Seller.
19.6 Address List(n) M Daftar informasi toko Seller.
19.6.1 FirstName Varchar (100) M Nama awal toko Seller.
19.6.2 LastName Varchar (100) M Nama akhir toko Seller.
19.6.3 Address Varchar (100) M Alamat Seller.
19.6.4 City Varchar (100) M Kota yang tertuju pada alamat toko Seller.
19.6.5 PostalCode Varchar (6) M Kode pos yang tertuju pada alamat toko Seller.
19.6.6 Phone Varchar (20) M Nomor telepon toko Seller.
19.6.7 CountryCode Varchar (3) M Kode negara yang tertuju pada alamat toko Seller.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

{
    "MerchantCode"	: "your-merchant-code",
    "PaymentId"	   	: "71",
    "Currency"     	: "IDR",
    "RefNo"        	: "88",
    "Amount"		: "6500000",
    "ProdDesc" 		: "Souvenir 1, Souvenir 2",
    "UserName"		: "Your Customer Name",
    "UserEmail"		: "your.customer.email.@ipay88.co.id",
    "UserContact"	: "08788888888",
    "Remark"		: "Transaction 2018-03-26 17:12:55",	
    "Lang"         	: "UTF-8",
    "ResponseURL"	: "https://your-site/ipay88-response",
    "BackendURL" 	: "https://your-site/ipay88-backend",
    "Signature"		: "SrhVUhH2IboZYrGhfqJ01Qx0clM=",
    "xfield1"		: "",
    
    "itemTransactions":
    [{
        "Id"		: "88",
        "Name"		: "Souvenir 1",
        "Quantity"	: "2",
        "Amount"	: "1000000",
        "Type"		: "Product 88",
        "Url"		: "https://your-site/product-id=88",
        "ImageUrl"	: "https://your-site/product-id=88/image.png",
        "ParentType"	: "SELLER",
        "ParentId"	: "SELLER88"		
    },
    {
        "Id"		: "89",
        "Name"		: "Souvenir 1",
        "Quantity"	: "1",
        "Amount"	: "2000000",
        "Type"		: "Product 89",
        "Url"		: "https://your-site/product-id=89",
        "ImageUrl"	: "https://your-site/product-id=88/image.png",
        "ParentType"	: "SELLER",
        "ParentId"	: "SELLER88"
    },
    {
        "Id"		: "shippingfee",
        "Name"		: "Shipping Fee",
        "Quantity"	: "1",
        "Amount"	: "2500000",
        "Type"		: null,
        "Url"		: null,
        "ImageUrl"	: null,
        "ParentType"	: null,
        "ParentId"	: null
    },
	{
        "Id"		: "taxfee",
        "Name"		: "Tax Fee",
        "Quantity"	: "1",
        "Amount"	: "1500000",
        "Type"		: null,
        "Url"		: null,
        "ImageUrl"	: null,
        "ParentType"	: null,
        "ParentId"	: null
    },
    {
        "Id"		: "discount",
        "Name"		: "Discount",
        "Quantity"	: "1",
        "Amount"	: "500000",
        "Type"		: null,
        "Url"		: null,
        "ImageUrl"	: null,
        "ParentType"	: null,
        "ParentId"	: null
    }],
    
    "ShippingAddress":
    {
        "FirstName"	: "Customer recipient first name",
        "LastName"	: "Customer recipient last name",
        "Address"	: "Jl. Letjen S. Parman No.22-24",
        "City"		: "Jakarta Barat",
        "PostalCode"	: "11480",
        "Phone"		: "08788888888",
        "CountryCode"	: "ID"
    },
    
    "BillingAddress":
    {
        "FirstName"	: "Customer first name",
        "LastName"	: "Customer last name",
        "Address"	: "Jl. Letjen S. Parman No.22-24",
        "City"		: "Jakarta Barat",
        "PostalCode"	: "11480",
        "Phone"		: "08788888888",
        "CountryCode"	: "ID"
    },
	
	"Sellers": 
	[{
		"Id"		: "your-seller-id",
		"Name"		: "Your Seller Name",
		"Url"		: "https://your-seller-site",
		"SellerIdNumber"	: "your-seller-id-number",
		"Email"		: "seller@ipay88.co.id",
        
        	"address": 
            	{
            		"FirstName"	: "Seller first name",
                	"LastName"	: "Seller last name",
                	"Address"	: "Jl. Letjen S. Parman No.22-24",
                	"City"		: "Jakarta Barat",
                	"PostalCode"	: "11480",
                	"Phone"		: "08788888888",
                	"CountryCode"	: "ID"
           	}
	}],
}

Response Format

iPay88 Indonesia akan mengirimkan parameter melalui JSON sebagai response kepada merchant. Merchant diharuskan melakukan perbandingan terhadap signature yang dikirim oleh iPay88 Indonesia dengan hasil pengacakan yang dilakukan oleh Merchant sendiri.


No
Nama Field
Tipe Data
M/O
Deskripsi
1 MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
2 PaymentId Integer M Payment ID 55 untuk untuk metode pembayaran Kredivo, 70 untuk metode pembayaran Indodana, dan 71 untuk metode pembayaran Akulaku.
3 RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
4 Amount Integer M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
5 Currency Varchar (5) M Hanya IDR.
6 Remark Varchar (100) O Catatan merchant.
7 TransId Varchar (30) O iPay88 OPSG ID Transaksi.
8 AuthCode Varchar (20) M Kode persetujuan Bank.
9 Status Varchar (1) M Status pembayaran
"0" – Fail.
"6" – Pending.
10 ErrDesc Varchar (100) O Deskripsi penyebab gagal-nya transaksi (lihat referensi).
11 Signature Varchar (100) M SHA signature (merujuk ke 3.1).
12 CheckoutURL Varchar (100) M URL untuk redirect ke laman pembayaran iPay88 Indonesia.
13 xfield1 Varchar (20) O Parameter ini hanya berlaku untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

{
    "MerchantCode"	: "ID00001",
    "PaymentId"		: "71",
    "RefNo"		: "720201745653AM",
    "Amount"		: "100000000",
    "Currency"		: "IDR",
    "Remark"		: "",
    "TransId"		: "T0027546100",
    "AuthCode"		: "",    
    "Status"		: "6",
    "ErrDesc"		: "",
    "Signature"		: "lkvo2Xuy7BImSfMoTBznJSUOEC8=",
    "CheckoutURL"	: "https://sandbox.ipay88.co.id/epayment/entry.asp?CheckoutID=5F822C024A102470C16A762C19EA29D7879A47B2EFF7C4151E309F00EDEADC6F&Signature=Nv2ub5JULwXf1X2x7B9CLe3z7K4%3d",
    "xfield1"		: "",
}

Checkout URL

Setelah Merchant mendapatkan data response yang dikirimkan oleh iPay88 Indonesia, langkah selanjutnya adalah membandingkan hasil signature. Jika nilai signature sama, maka merchant harus redirect ke laman pembayaran iPay88 Indonesia melalui parameter CheckoutURL.

window.location.replace("https://sandbox.ipay88.co.id/epayment/entry.asp?CheckoutID=5F822C024A102470C16A762C19EA29D7879A47B2EFF7C4151E309F00EDEADC6F&Signature=Nv2ub5JULwXf1X2x7B9CLe3z7K4%3d");
<?php
            
$checkout = 'https://sandbox.ipay88.co.id/epayment/entry.asp?CheckoutID=5F822C024A102470C16A762C19EA29D7879A47B2EFF7C4151E309F00EDEADC6F&Signature=Nv2ub5JULwXf1X2x7B9CLe3z7K4%3d';

$load_file_function = '<script language="JavaScript"> $(document).ready(function(){ document.ipay88_request_paramaters.submit();});</script>';

echo $load_file_function;

echo "<form  name='ipay88_request_paramaters' ACTION='".$checkout."' method='POST'>";
echo "</form>";
      
?>

Payment Response

Berikut ini adalah parameter yang digunakan ketika mendapatkan response dari iPay88 Indonesia.


Response Format

Berikut ini adalah respon dengan HTTPS POST dari iPay88 Indonesia ke merchant setelah selesai proses pembayaran.


Nama Field
Tipe Data
M/O
Deskripsi
MerchantCode Varchar (20) M Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
PaymentId Integer O Lihat referensi.
RefNo Varchar (20) M Nomor unik transaksi merchant atau Order ID.
Amount Integer M Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
Currency Varchar (5) M Harus IDR.
Remark Varchar (100) O Catatan merchant.
TransId Varchar (30) O iPay88 OPSG ID Transaksi.
AuthCode Varchar (20) O Kode persetujuan bank.
Status Varchar (1) M Status pembayaran
"1" – Success.
"0" – Fail.
ErrDesc Varchar (100) O Deskripsi penyebab gagal-nya transaksi (lihat referensi).
Signature Varchar (100) M SHA1 Signature (merujuk ke 3.2).
xfield1 Varchar (20) O Parameter ini hanya berlaku untuk metode pembayaran kartu kredit dengan fitur cicilan dan diskon.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

<%

MerchantCode	= Request.Form("MerchantCode")
PaymentId 		= Request.Form("PaymentId")
RefNo 			= Request.Form("RefNo")
Amount 			= Request.Form("Amount")
eCurrency 		= Request.Form("Currency")
Remark 			= Request.Form("Remark")
TransId 		= Request.Form("TransId")
AuthCode 		= Request.Form("AuthCode")
eStatus 		= Request.Form("Status")
ErrDesc         = Request.Form("ErrDesc")
Signature 		= Request.Form("Signature")

%>

<Add your programming code here>
<?php

$merchantcode 	= $_REQUEST["MerchantCode"];
$paymentid 	= $_REQUEST["PaymentId"];
$refno 		= $_REQUEST["RefNo"];
$amount 	= $_REQUEST["Amount"];
$ecurrency 	= $_REQUEST["Currency"];
$remark 	= $_REQUEST["Remark"];
$transid 	= $_REQUEST["TransId"];
$authcode 	= $_REQUEST["AuthCode"];
$estatus 	= $_REQUEST["Status"];
$errdesc 	= $_REQUEST["ErrDesc"];
$signature	= $_REQUEST["Signature"];

?>

//Add your programming code here

Backend Post Feature

Backend post feature adalah teknologi server ke server yang tidak bergantung pada web browser si pelanggan merchant. Fitur ini harus diimplementasikan di situs merchant. Tujuan fitur ini adalah untuk mendapatkan status pembayaran dari iPay88 OPSG. Merchant bisa mendapatkan status pembayaran melalui laman backend merchant. iPay88 OPSG dapat mengirim status pembayaran secara berulang walaupun laman respon merchant gagal mendapatkan status tersebut yang disebabkan oleh browser web ditutup, batas waktu koneksi internet, dan lain sebagainya.


Sistem manajemen konten yang telah mendukung fitur backend post melalui plugin iPay88 Indonesia.

  1. Drupal
  2. Magento
  3. OpenCart
  4. Prestashop
  5. WHMCS
  6. Woocommerce
  7. WP Charitable


Catatan

  1. iPay88 OPSG hanya mengirim status pembayaran melalui laman backend merchant apabila status pembayaran pada transaksi merchant telah sukses. Jika status pembayaran gagal, maka iPay88 OPSG tidak akan mengirimkan status melalui laman backend merchant.

  2. Laman backend merchant harus menerapkan beberapa pengecekan yang sama seperti laman response seperti pengecekan signature, dan lain sebagainya untuk mencegah tejadinya pembajakan pada sistem merchant.

  3. laman backend merchant tidak boleh memiliki kode session sehingga sistem merchant masih dapat menerima status pembayaran dari iPay88 OPSG bahkan jika pelanggan telah keluar atau session telah berakhir.

  4. Anda perlu melakukakan pemeriksaan untuk menentukan fungsi perubah status transaksi baik di "laman response" atau "laman backend" sehingga tidak terjadinya perubahan status transaksi lebih dari satu kali.

    Note: Setelah iPay88 OPSG menerima informasi dari bank bahwa status pembayaran pada transaksi merchant telah suskes, iPay88 OPSG secara bersamaan akan mengirimkan status pembayaran tersebut ke "laman response" dan "laman backend" merchant.

  5. Laman backend bukan sebagai pengganti laman response. Anda harus terus menggunakan laman response seperti biasa.


Implementasi

Pada situs merchant, buat laman lain sebagai backend untuk menerima parameter dari iPay88 OPSG. Parameter backend yang dikirim oleh iPay88 OPSG sama seperti parameter yang dikirim ke laman response merchant. Pada laman request merchant, tentukan url backend melalui parameter "BackendURL".

Sebagai contoh, <input name = "BackendURL" value = "http://www.abc.com/backend_response">

Pada laman 'backend_response' Anda perlu menuliskan kata 'RECEIVEOK' saja (tanpa tanda kutip) sebagai konfirmasi setelah laman backend berhasil mendapatkan status pembayaran dari iPay88 OPSG. Tentunya kata tersebut tertulis setelah dilakukan pengecekan seperti signature dan lain sebagainya di laman backend merchant. iPay88 OPSG akan mencoba mengirim kembali status pembayaran ke laman 'backend_response' hingga 5 kali pada interval yang berbeda jika tidak terdeteksi 'RECEVEIOK'.

Contoh:

Di ASP >> response.write "RECEIVEOK"
Di PHP >> echo "RECEIVEOK";

Catatan: Pastikan hanya kata 'RECEIVEOK' tanpa tag HTML apa pun.


Kontrol Keamanan

Untuk meningkatkan keamanan, silahkan ikuti langkah-langkah berikut di laman penerimaan status pembayaran merchant (Response URL).

  1. Periksa nilai HTTP_REFERER dari https://payment.ipay88.co.id (hanya berlaku jika situs web merchant berfungsi dengan Sertifikat SSL).
  2. Periksa jumlah pembayaran dari iPay88 OPSG sesuai dengan pelanggan Anda.
  3. Bandingkan signature dari iPay88 OPSG dengan signature yang Anda hasilkan sendiri.


Integritas Data dan Keamanan menggunakan Signature Acak

Pengacakan SHA1 adalah fitur keamanan yang memungkinkan skrip Anda untuk mengidentifikasi hasil transaksi sebenarnya dari sumber otorisasi yang sesuai. Bagi iPay88 OPSG, fitur ini berguna untuk memastikan integritas data yang diterima pada setiap request transaksi dari merchant.

Menggunakan algoritma SHA1, signature atau fingerprint dari transaksi dapat dihasilkan. Algoritma matematika yang digunakan untuk membangun signature ini dirancang sedemikian rupa sehingga setiap adanya perubahan pada informasi yang digunakan dalam perhitungan akan menghasilkan signature yang berbeda pula.

Informasi yang digunakan dalam perhitungan signature tidak dapat diketahui walau dengan menganalisa signature itu sendiri. Signature dihasilkan dengan menggunakan informasi dari akun Anda sebagai merchant. Setiap transaksi yang diproses melalui sistem memiliki pengacakan signature tersendiri yang berkaitan dengan transaksi tersebut.


Request Page Signature

Signature harus disertakan pada proses request laman pembayaran iPay88 OPSG disetiap transaksi merchant. Signature tersebut adalah hasil dari pengacakan lima bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 OPSG)
  2. MerchantCode
  3. RefNo
  4. Amount
  5. Currency

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & RefNo & Amount & Currency

Contoh:

MerchantKey = "applekey"
MerchantCode = "ID00001"
RefNo = "A00000001"
Amount = "300000" (catatan: 300000 adalah representasi dari total Rp3.000,00)
Currency = "IDR"

Pengacakan akan dihitung melalui string berikut:
applekeyID00001A00000001300000IDR

Hasil signature (menggunakan algoritma SHA1) adalah:
Q/iIMzpjZCrhJ2Yt2dor1PaFEFI=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.


Public Shared Function ComputeHas(ByVal Key As String)
   Dim objSHA1 As New SHA1CryptoServicesProvider()
   objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
   Dim buffer() As Byte = objSHA1.Hash
   DIm HashValue As String = System.Convert.ToBase64String(buffer)
    
   Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Response Page Signature

Jika status pembayaran dari transaksi merchant dinyatakan sukses, iPay88 OPSG akan mengirim signature di laman response dan backend merchant. Signature ini harus dibandingkan dengan signature yang dihasilkan oleh merchant sendiri guna mengindari adanya pembajakan. Signature tersebut adalah hasil dari pengacakan tujuh bidang utama berikut.

  1. MerchantKey (disediakan dan hanya untuk merchant oleh iPay88 OPSG)
  2. MerchantCode
  3. PaymentId
  4. RefNo
  5. Amount
  6. Currency
  7. Status

Field harus tersusun mengikuti aturan berikut:
MerchantKey & MerchantCode & PaymentId & RefNo & Amount & Currency & Status


Contoh:

MerchantKey = "applekey"
MerchantCode = "ID00001"
PaymentId = "1"
RefNo = "A00000001"
Amount = "300000" (catatan: 300000 adalah representasi dari total Rp3.000,00)
Currency = "IDR"
Status = "1"

Pengacakan akan dihitung melalui string berikut:
applekeyID000011A00000001300000IDR1

Hasil signature (menggunakan algoritma SHA1) adalah:
01sh+jPUL2wdqCcWJTgiuNuiiTI=


Untuk memastikan signature yang dihasilkan sudah benar, silahkan klik tautan ini untuk perbandingan signature.


Ketika iPay88 OPSG menerima request atau transaksi dari merchant, iPay88 OPSG akan memeriksa nilai acak signature yang dihasilkan untuk dicocokkan dengan nilai signature yang merchant kirim. Ketika sistem merchant menerima hasil transaksi, merchant dapat membuat signature dan pastikan sama dengan signature yang dikirim balik oleh iPay88 OPSG. Merchant akan mendapatkan signature di laman response jika transaksi tidak error (tidak termasuk transaksi yang disetujui atau ditolak).

Setelah merchant menerima informasi dari iPay88 OPSG terkait status pembayaran dari transaksi, merchant harus menjalanakan algoritma acak pada tujuh bidang utama yg telah disebutkan diatas sehingga menghasilkan suatu signature. Merchant wajib mencocokkan hasil signature merchant dengan signature iPay88 OPSG. Dapat dipastikan jika signature yang dihasilkan merchant saat proses request dan dikirim ke iPay88 OPSG, maka transaksi merchant telah diproses oleh sistem iPay88 OPSG.

Merchant key dibuat oleh iPay88 OPSG untuk merchant. Merchant key bersifat rahasia bersama (antara merchant dan iPay88 OPSG), dan merupakan salah satu bagian kunci informasi untuk proses pengacakan signature. Merchant key akan dibuat ulang jika iPay88 OPSG mencurigai bahwa merchant key sudah tidak aman atau terjadi kasus penipuan. Informasi lebih lanjut tentang algoritma acak SHA1, termasuk sampel kode untuk implementasi dapat ditemukan di RFC 3174 dalam laman Task Force Internet Engineering.

Public Shared Function ComputeHas(ByVal Key As String)
   Dim objSHA1 As New SHA1CryptoServicesProvider()
   objSHA1.ComputeHas(system.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
   Dim buffer() As Byte = objSHA1.Hash
   DIm HashValue As String = System.Convert.ToBase64String(buffer)
    
   Return HashValue
End Function
<?php

function iPay88_signature($source)
{
   return base64_encode(hex2bin(sha1($source)));
}

function hex2bin($hexSource)
{
   for ($i=0;$i<strlen($hexSource);$i=$i+2)
   {
      $bin .= chr(hexdec(substr($hexSource,$i,2)));
   }
   
   return $bin;
}

?>
import java.security.*;
import sun.misc.BASE64Encoder;
import java.io.*;

public class test 
{
   public static String encrypt(String password) 
   {
      MessageDigest md;
      try 
      {
         md = MessageDigest.getInstance("SHA");
         md.update(password.getBytes("UTF-8"));
         byte raw[] = md.digest();
         String hash = (new BASE64Encoder()).encode(raw);
         
         return hash;
       } 
       
       catch (NoSuchAlgorithmException e) 
       {
       } 
       
       catch (java.io.UnsupportedEncodingException e) 
       {
       }
       
       return null;
   }

   public static void main(String[] args) 
   {
      System.out.println(encrypt("my password"));	
      // string to hash is here
   }
}
<script language="javascript" type="text/javascript" 
src="sha1.js"></script>

<script language="javascript">
   document.write(iPay88Signature("d3kdhKeH93M00045A00257110800MYR")); //sample signature
</script>
sha1.js file
var hexcase = 0;  
/* hex output format. 0 - lowercase; 1 - uppercase        */

var b64pad  = ""; 
/* base-64 pad character. "=" for strict RFC compliance   */

var chrsz   = 8;  
/* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function iPay88Signature(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz))+"=";}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";

  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Seamless Virtual Account versi 1.0.0


Segera integrasikan iPay88 Seamless Payment ini dengan platform online bisnis Anda. API ini menjadikan situs Anda dapat menerima pembayaran melalui Online Credit seperti Kredivo, Indodana, dan Akulaku.


Download iPay88 Seamless Virtual Account

BCA KlikPay Versi 1.7.4


Segera integrasikan iPay88 Technical Documentation untuk BCA KlikPay versi 1.7.3 ini dengan situs Anda. API ini menjadikan situs Anda untuk menerima pembayaran melalui online banking BCA KlikPay.


Download iPay88 - BCA KlikPay

Objektif

Merchant dapat menyediakan metode pembayaran online banking BCA KlikPay kepada pelanggan melalui iPay88 Indonesia.


Langkah Awal

Dokumentasi ini ditujukan untuk merchant yang ingin memiliki metode pembayaran online banking menggunakan proyek KlikPay di BCA. Dokumen ini mendukung kebutuhan proses bisnis dan pergerakan data dengan secara teknis, dari BCA ke merchant. Dokumen ini juga menjelaskan proses sistem, aliran data, dan beberapa hal yang diperlukan, baik untuk BCA atau merchant agar dapat berkomunikasi.

Konsep utama yang diterapkan adalah pelanggan dapat melakukan pembayaran untuk semua transaksi di laman merchant menggunakan akun BCA KlikPay.


Flowchart

Berikut ini adalah diagram alir transaksi merchant dengan BCA KlikPay melalui iPay88 Indonesia.



Proses Transaksi

Berikut ini adalah proses transaksi merchant dengan BCA KlikPay melalui iPay88 Indonesia.



Sistem Proses

Proses sistem dipisahkan dalam tiga sub proses, yaitu payment request, redirect forward, dan pemanggilan payment flag kepada merchant.


Payment Request

Ketika pelanggan memilih pembayaran menggunakan KlikPay di situs merchant, merchant harus memastikan bahwa jumlah total transaksi tidak melebihi batas transaksi KlikPay. Setelah itu, merchant akan melakukan proses pertama yaitu payment request.



URL yang digunakan untuk payment request adalah:

  1. UAT:
    https://sandbox.ipay88.co.id/ePayment/WebService/SeamlessPayment/Entry.asmx
  2. Production:
    https://payment.ipay88.co.id/ePayment/WebService/SeamlessPayment/Entry.asmx


Request

Berikut ini adalah data yang dikirimkan merchant dengan metode web service.


No
Nama Field
Tipe
Deskripsi
1 MerchantCode Varchar (20) Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
2 PaymentId Integer Payment ID 8 untuk metode pembayaran online banking BCA KlikPay.
3 Currency Varchar (5) Harus IDR.
4 RefNo Varchar (20) Nomor unik transaksi merchant atau Order ID.
5 Amount Currency Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp3.000,00 diekspresikan menjadi 300000. Amount = FullTransactionAmount + installmentTransactions[n].amount + MiscFee
6 ProdDesc Varchar (100) Deskripsi produk.
7 UserName Varchar (100) Nama pelanggan.
8 UserEmail Varchar (100) Email pelanggan untuk mendapatkan nota pembayaran.
9 UserContact Varchar (20) Nomor kontak pelanggan.
10 Remark Varchar (100) Catatan merchant.
11 Lang Varchar (20) Encoding type
"ISO-8859-1" – English.
"UTF-8" – Unicode.
"GB2312" – Chinese Simplified.
"GD18030" – Chinese Simplified.
"BIG5" – Chinese Traditionl.
12 ResponseURL Varchar (200) Payment response page. Contoh merchant-ipay88.co.id/response.
13 BackendURL Varchar (200) Backend response page URL. Contoh merchant.ipay88.co.id/backend.
14 Signature Varchar (100) SHA signature.
15 xfield1 Varchar (20)
16 MiscFee Varchar (12) Biaya lain lain. MiscFee diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp500,00 diekspresikan menjadi 50000.
17 FullTransactionAmount List (n) FullTransactionAmount diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.000,00 diekspresikan menjadi 100000.
18 InstallmentTransactions List (n) Parameter ini hanya berlaku untuk jenis pembayaran cicilan dengan berbagai macam produk.
18.1 itemName String (50) Nama dari produk yang dibeli dengan jenis pembayaran cicilan.
18.2 quantity Integer (3) Kuantitas dari produk yang dibeli dengan jenis pembayaran cicilan.
18.3 amount Currency Harga produk dikalikan dengan jumlah kuantitas. Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.500,00 diekspresikan menjadi 150000.
18.4 tenor Integer (2) Tenor cicilan. Sebagai contoh, 3 bulan masa cicilan diekspresikan menjadi 03.
18.5 codePlan String (2) Contoh 000.
18.6 merchantId Integer (9) MID dari BCA. Contoh 1241.

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

Full Payment

POST [DOMAIN]/ePayment/WebService/SeamlessPayment/Entry.asmx HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;
SOAPAction="Request"

<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>
<Request xmlns="http://www.ipay88.co.id">
   <MerchantCode>your-merchant-code</MerchantCode>
   <PaymentId>8</PaymentId>
   <Currency>IDR</Currency>
   <RefNo>117201783440AM</RefNo>
   <Amount>10000000</Amount>
   <ProdDesc>Souvenir 1</ProdDesc>
   <UserName>Customer Name</UserName>
   <UserEmail>customer.email.@ipay88.co.id</UserEmail>
   <UserContact>08788888888</UserContact>
   <Remark>Transaction 2018-03-26 17:12:55</Remark>
   <Lang></Lang>
   <ResponseURL>https://your-site/response</ResponseURL>
   <BackendURL>https://your-site/backend</BackendURL>
   <Signature>42QMKfAYvkaUUvPp9MTo8loOtGY=</Signature>
   <xfield1></xfield1>
   <FullTransactionAmount>10000000</FullTransactionAmount>
   <MiscFee>000</MiscFee>
   <InstallmentTransactions>
      <installmentTransaction>
      <itemName></itemName>
      <quantity></quantity>
      <amount>000</amount>
      <tenor></tenor>
      <codePlan></codePlan>
      <merchantId></merchantId>
      </installmentTransaction>
   </InstallmentTransactions>
</Request>
</soap:Body>
</soap:Envelope>
<?php

//Full Payment

$client = new SoapClient("https://sandbox.ipay88.co.id/epayment/WebService/SeamlessPayment/Entry.asmx?WSDL");

$client->__setLocation('https://sandbox.ipay88.co.id/ePayment/WebService/SeamlessPayment/Entry.asmx');

$params = new stdClass();
$params->MerchantCode	= 'your-merchant-code';
$params->PaymentId	= '8';
$params->Currency	= 'IDR';
$params->RefNo		= '117201783440AM';
$params->Amount		= '100000000';
$params->ProdDesc	= 'Souvenir 1';
$params->UserName	= 'Customer Name';
$params->UserEmail	= 'customer.email.@ipay88.co.id';
$params->UserContact 	= '08788888888';
$params->Remark		= 'Transaction 2018-03-26 17:12:55';
$params->Lang		= 'iso-8859-1';
$params->ResponseURL	= 'https://your-site/response';
$params->BackendURL	= 'https://your-site/backend';
$params->Signature	= '42QMKfAYvkaUUvPp9MTo8loOtGY=';
$params->xfield1	= '';
$params->MiscFee	= '000';
$params->FullTransactionAmount = '50000000';

$installmentTransaction = new stdClass();
$installmentTransaction->itemName	= '';
$installmentTransaction->quantity	= '';
$installmentTransaction->amount		= '';
$installmentTransaction->tenor		= '';
$installmentTransaction->codePlan	= '';
$installmentTransaction->merchantId	= '';
$params->InstallmentTransactions[0] 	= $installmentTransaction;

//Approval ipay88
$results		= $client->Request($params);
$result			= $results[0];
$Amount			= $result->Amount;
$Currency		= $result->Currency;
$ErrDesc		= $result->ErrDesc;
$MerchantCode		= $result->MerchantCode;
$PaymentId		= $result->PaymentId;
$RefNo			= $result->RefNo;
$Remark			= $result->Remark;
$Status			= $result->Status;
$TransId		= $result->TransId;
$Signature		= $result->Signature;

echo "ErrDesc: 	".$ErrDesc."</br>";
echo "Status:	".$Status."</br>";
echo "TransId: 	".$TransId."</br>";

?>

Installment

POST [DOMAIN]/ePayment/WebService/SeamlessPayment/Entry.asmx HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;
SOAPAction="Request"

<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> 
<Request xmlns="http://www.ipay88.co.id"> 
   <MerchantCode>ID00001</MerchantCode> 
   <PaymentId>8</PaymentId> 
   <Currency>IDR</Currency> 
   <RefNo>117201783440AM</RefNo> 
   <Amount>100000000</Amount> 
   <ProdDesc>Buku</ProdDesc> 
   <UserName>Customer Name</UserName> 
   <UserEmail>customer.email.@ipay88.co.id</UserEmail> 
   <UserContact>08788888888</UserContact> 
   <Remark>Transaction 2018-03-26 17:12:55</Remark> 
   <Lang></Lang> 
   <ResponseURL>https://your-site/response</ResponseURL> 
   <BackendURL>https://your-site/backend</BackendURL> 
   <Signature>42QMKfAYvkaUUvPp9MTo8loOtGY=</Signature> 
   <xfield1></xfield1> 
   <FullTransactionAmount></FullTransactionAmount> 
   <MiscFee>000</MiscFee> 
   <InstallmentTransactions> 
      <installmentTransaction> 
         <itemName>Product 1</itemName> 
         <quantity>2</quantity> 
         <amount>30000000</amount> 
         <tenor>06</tenor> 
         <codePlan>000</codePlan> 
         <merchantId>12323</merchantId> 
      </installmentTransaction> 
      <installmentTransaction> 
         <itemName>Product 2</itemName> 
         <quantity>2</quantity> 
         <amount>30000000</amount> 
         <tenor>03</tenor> 
         <codePlan>000</codePlan> 
         <merchantId>12322</merchantId> 
      </installmentTransaction> 
      <installmentTransaction> 
         <itemName>Product 3</itemName> 
         <quantity>2</quantity> 
         <amount>40000000</amount> 
         <tenor>09</tenor> 
         <codePlan>000</codePlan> 
         <merchantId>12324</merchantId>
      </installmentTransaction> 
   </InstallmentTransactions>
</Request> 
</soap:Body> 
</soap:Envelope>
<?php

//Installment

$client = new SoapClient("https://sandbox.ipay88.co.id/epayment/WebService/SeamlessPayment/Entry.asmx?WSDL");

$client->__setLocation('https://sandbox.ipay88.co.id/ePayment/WebService/SeamlessPayment/Entry.asmx');

$params = new stdClass();
$params->MerchantCode	= 'your-merchant-code';
$params->PaymentId	= '8';
$params->Currency	= 'IDR';
$params->RefNo		= '117201783440AM';
$params->Amount		= '100000000';
$params->ProdDesc	= 'Souvenir 1';
$params->UserName	= 'Customer Name';
$params->UserEmail	= 'customer.email.@ipay88.co.id';
$params->UserContact 	= '08788888888';
$params->Remark		= 'Transaction 2018-03-26 17:12:55';
$params->Lang		= 'iso-8859-1';
$params->ResponseURL	= 'https://your-site/response';
$params->BackendURL	= 'https://your-site/backend';
$params->Signature	= '42QMKfAYvkaUUvPp9MTo8loOtGY=';
$params->xfield1	= '';
$params->MiscFee	= '000';
$params->FullTransactionAmount = '50000000';

$installmentTransaction = new stdClass();
$installmentTransaction->itemName	= 'test product';
$installmentTransaction->quantity	= '2';
$installmentTransaction->amount		= '50000000';
$installmentTransaction->tenor		= '03';
$installmentTransaction->codePlan	= '000';
$installmentTransaction->merchantId	= '12322';
$params->InstallmentTransactions[0] 	= $installmentTransaction;

//approval ipay88
$results		= $client->Request($params);
$result			= $results[0];
$Amount			= $result->Amount;
$Currency		= $result->Currency;
$ErrDesc		= $result->ErrDesc;
$MerchantCode		= $result->MerchantCode;
$PaymentId		= $result->PaymentId;
$RefNo			= $result->RefNo;
$Remark			= $result->Remark;
$Status			= $result->Status;
$TransId		= $result->TransId;
$Signature		= $result->Signature;

echo "ErrDesc: 	".$ErrDesc."</br>";
echo "Status:	".$Status."</br>";
echo "TransId: 	".$TransId."</br>";

?>

Request Signature Algorithm

Parameter yang digunakan adalah sebagai berikut.

  1. KlikPay Code
  2. Transaction Time (format: ddMMyyyy)
  3. Transaction Number
  4. Total Amount (catatan: format dalam nilai integer, tidak ada angka desimal)
  5. Currency
  6. Key Id (key digunakan untuk transaksi)


Fungsi PHP mcrypt_encrypt hanya berlaku untuk PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0. Berikut penjelasan yang dikutip dari situs resmi PHP.

Untuk informasi lebih lanjut, silahkan klik tautan berikut.

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class GenerateKey
{
    private static String HEX_DIGITS = "0123456789ABCDEF";
    
    private static int getHash(String val)
	{
    	int h = 0;
        char[] vals = val.ToCharArray();
        for (int i = 0; i < vals.Length; i++)
        {
        	h = (h * 31) + (int)vals[i];
      	}
        
    	return h;
    }
    	    
    public static String generateSignature(String klikPayCode, String transactionDate, String transactionNo, String amount, String currency, String keyId)
   	{
    	// Generate Key Step 1
        String tempKey1 = klikPayCode + transactionNo + currency + keyId;
        int hashKey1 = getHash(tempKey1);
        
        // Generate Key Step 2
        // Reformat Input Date
        DateTime date = new DateTime();
        date = DateTime.ParseExact(transactionDate, "dd/MM/yyyy HH:mm:ss", null);

        int transDate = Convert.ToInt32(date.ToString("ddMMyyyy"));
        int amt = (Int32)Convert.ToDouble(amount);

        String tempKey2 = (transDate + amt).ToString();
        int hashKey2 = getHash(tempKey2);

        // Hash the value using integer arithmatic and absolute value
        Decimal hash = Math.Abs(decimal.Add(new Decimal(hashKey1), new Decimal(hashKey2)));

        return hash.ToString();
    }
    
    private static byte[] fromHexString(String s)
   	{
        byte[] bytes = new byte[s.Length / 2];
        for (int i = 0; i < s.Length / 2; i++)
        {
            bytes[i] = (byte)(Convert.ToInt32(s.Substring(2 * i, 2), 16));
        }
        
        return bytes;
    }

    private static String toHexString(byte[] b)
  	{
        if ((b == null) || (b.Length == 0))
        {
            return "";
        }
        
        else
        {
        	return toHexString(b, 0, b.Length);
        }
    }

    /** Convert bytes to HEX string */
    private static String toHexString(byte[] b, int off, int len)
   	{
        StringBuilder s = new StringBuilder();
        for (int i = off; i < off + len; i++)
        {
            s.Append(HEX_DIGITS[(b[i] & 0xff) >> 4]); s.Append(HEX_DIGITS[b[i] & 0xf]);
            // or
            //s.Append((b[i]).ToString("X2"));
        }
        
        return s.ToString();
    }

    public static String generateAuthKey(String klikPayCode, String transactionNo, String currency, string transactionDate, String keyId)
   	{
        return generateAuthKey(klikPayCode.PadRight(10, '0') + transactionNo.PadRight(18, 'A') + currency.PadRight(5, '1') + transactionDate.PadLeft(19, 'C') + keyId, keyId); 
    }

    private static String generateAuthKey(String secondValue, String keyId)
  	{
        MD5 sha = MD5.Create();

        byte[] byteHash = sha.ComputeHash(Encoding.UTF8.GetBytes(secondValue)); ;
        String hashData = toHexString(byteHash);

        byte[] byteHashData = fromHexString(hashData);
        byte[] byteKey = fromHexString(keyId);

        if (!(byteKey.Length == 16 || byteKey.Length == 24))
        {
            throw new Exception("Length not valid :" + byteKey.Length);
        }

        byte[] key = new byte[24];

        if (byteKey.Length == 16)
        {
            for (int za = 0; za < 16; za++)
            {
                key[za] = byteKey[za];
            }
            
            for (int za = 0; za < 8; za++)
            {
                key[za + 16] = byteKey[za];
            }
        }

        if (byteKey.Length == 24)
        {
            for (int za = 0; za < 24; za++)
            {
                key[za] = byteKey[za];
            }
        }

        MemoryStream ms	= new MemoryStream();
        TripleDES alg	= TripleDES.Create();
        alg.Key 	= key;
        alg.Mode 	= CipherMode.ECB;
        alg.Padding 	= PaddingMode.None;
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        
        cs.Write(byteHashData, 0, byteHashData.Length);

        cs.FlushFinalBlock();
        byte[] CipherBytes = ms.ToArray();
        ms.Close();
        cs.Close();

        String encryptedHashKey = toHexString(CipherBytes);

        return encryptedHashKey;
    }

    public static String generateKeyId(String clearKey)
 	{
        byte[] bytes = Encoding.UTF8.GetBytes(clearKey);
        return toHexString(bytes);
    }
}

private void static example()
{
    String keyId 	= BcaKeyGenerator.GenerateKey.generateKeyId(clearKey);
    
    sSignature		= BcaKeyGenerator.GenerateKey.generateSignature(klikPayCode, transactionDate, transactionNo, totalAmount, currency, keyId);
    
    sAuthKey 		= BcaKeyGenerator.GenerateKey.generateAuthKey(klikPayCode, transactionNo, currency, transactionDate, keyId);
}
<?php

function toHexString($string)
{
    $hex = '';
    
    for ($i=0; $i<strlen($string); $i++)
    {
    	$ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
	
    return strToUpper($hex);
}

function fromHexString($hex)
{
    $string = '';

    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    
    return $string;
}

function generateSignature($klikPayCode, $transactionDate, $transactionNo, $amount, $currency, $keyId)
{   
    date_default_timezone_set("Asia/Jakarta");
    
    $tempKey1 	= $klikPayCode.$transactionNo.$currency.$keyId;
    $hashKey1 	= getHash($tempKey1);
    $tdate	= date_create_from_format("d/m/Y G:i:s",$transactionDate);
    $idate	= (int)date_format($tdate, 'dmY');
    $iamount 	= (int)$amount;
    $tempKey2 	= ($idate + $iamount);
    $tempKey2 	= $tempKey2 . "";
    $hashKey2 	= getHash($tempKey2);
    $hash	= abs($hashKey1+$hashKey2);
    
    return $hash."";
}

function generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId)
{    
    $str1 = str_pad($klikPayCode,10, '0', STR_PAD_RIGHT) . str_pad($transactionNo,18, 'A', STR_PAD_RIGHT) . str_pad($currency,5, '1',STR_PAD_RIGHT) .  str_pad($transactionDate,19, 'C', STR_PAD_LEFT) . $keyId;
    
    $mdstr1 = md5($str1);
    $my_key = fromHexString($keyId);
    $data   = fromHexString($mdstr1); 
    $my_key .= substr($my_key,0,8);
    
    $secret = mcrypt_encrypt(MCRYPT_3DES, $my_key, $data, MCRYPT_MODE_ECB); 
    
    return toHexString($secret);
}

function generateKeyId($str)
{
	return toHexString($str);
}

function getHash ($value)
{       
    $hash = 0;
	
    for ($i = 0; $i < strlen($value); $i++)
    {
        $hash = (intval($hash) * 31) + ord($value[$i]);
        $hash = intval32bits($hash);
    }
	
    return (int)$hash;
}

function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

    if ($value & 0x80000000)
    {
        $value = -((~$value & 0xFFFFFFFF) + 1);
    }

    return $value;
}

$clearKey		= "ClearKey00000001";
$klikPayCode		= "BCAPAY0001";

//format: "d/m/Y G:i:s"
$transactionDate	= "11/04/2014 16:15:53";

$transactionNo 		= "R223248";
$totalAmount 		= 3000.00;
$currency		= "IDR";
$keyId 			= generateKeyId($clearKey);
$sSignature 		= generateSignature($klikPayCode, $transactionDate, $transactionNo, $totalAmount, $currency, $keyId);
$sAuthKey 		= generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId);

echo $keyId."<br/>".$sSignature."<br/>".$sAuthKey;

?>

Payment Approval

Payment approval adalah hasil balikan dari payment request webservice dengan iPay88 Indonesia. Berikut ini adalah parameter response yang dikirim iPay88 Indonesia kepada merchant.


No
Nama Field
Tipe
Deskripsi
1 MerchantCode Varchar (20) Merchant Code disediakan oleh iPay88 dan digunakan untuk mengidentifikasi merchant.
2 PaymentId Integer Payment ID untuk metode pembayaran yang dituju. Payment ID 8 untuk metode pembayaran online banking BCA KlikPay.
3 RefNo String (20) Nomor unik transaksi merchant atau Order ID.
4 Amount Currency Total diharuskan tidak mengandung angka desimal, penanda ribuan, dan kode mata uang. Sebagai contoh, Rp1.278,00 diekspresikan menjadi 127800.
5 Currency String (5) Harus IDR.
6 Remark String (100) Catatan merchant.
7 Signature String (100) SHA signature.
8 xfield1 String
9 TransId Varchar (30)
10 Status Integer (2) Status pembayaran
"0" – Payment request approved.
"6" – Payment request failed.
11 ErrDesc Varchar (100) Deskripsi penyebab gagal-nya transaksi (lihat referensi).

Keterangan:
M: Mandatory (diharuskan).
O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<soap:Body>
   <RequestResponse xmlns="http://www.ipay88.co.id">
      <RequestResult>
         <Status>6</Status>
         <ErrDesc/>
         <MerchantCode>ID00001</MerchantCode>
         <PaymentId>8</PaymentId>
         <RefNo>117201783440AM</RefNo>
         <Amount>100000000</Amount>
         <Currency>IDR</Currency>
         <Remark/>
         <xfield1/>
         <Signature>jVZBU7kXCMKijkhEc1p8CFZnf50=</Signature>
         <TransId>T0000970500</TransId>
         <AuthCode/>
      </RequestResult>
   </RequestResponse>
</soap:Body>
</soap:Envelope>

Payment Approval Signature Algorithm

Parameter yang digunakan adalah sebagai berikut.

  1. KlikPay Code
  2. Transaction Time (format: ddMMyyyy)
  3. Transaction Number
  4. Total Amount (catatan: format dalam nilai integer, tidak ada angka desimal)
  5. Currency
  6. Key Id (key digunakan untuk transaksi)


Fungsi PHP mcrypt_encrypt hanya berlaku untuk PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0. Berikut penjelasan yang dikutip dari situs resmi PHP.

Untuk informasi lebih lanjut, silahkan klik tautan berikut.


using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class GenerateKey
{
    private static String HEX_DIGITS = "0123456789ABCDEF";
    
    private static int getHash(String val)
	{
    	int h = 0;
        char[] vals = val.ToCharArray();
        for (int i = 0; i < vals.Length; i++)
        {
        	h = (h * 31) + (int)vals[i];
      	}
        
    	return h;
    }
    	    
    public static String generateSignature(String klikPayCode, String transactionDate, String transactionNo, String amount, String currency, String keyId)
   	{
    	// Generate Key Step 1
        String tempKey1 = klikPayCode + transactionNo + currency + keyId;
        int hashKey1 = getHash(tempKey1);
        
        // Generate Key Step 2
        // Reformat Input Date
        DateTime date = new DateTime();
        date = DateTime.ParseExact(transactionDate, "dd/MM/yyyy HH:mm:ss", null);

        int transDate = Convert.ToInt32(date.ToString("ddMMyyyy"));
        int amt = (Int32)Convert.ToDouble(amount);

        String tempKey2 = (transDate + amt).ToString();
        int hashKey2 = getHash(tempKey2);

        // Hash the value using integer arithmatic and absolute value
        Decimal hash = Math.Abs(decimal.Add(new Decimal(hashKey1), new Decimal(hashKey2)));

        return hash.ToString();
    }
    
    private static byte[] fromHexString(String s)
   	{
        byte[] bytes = new byte[s.Length / 2];
        for (int i = 0; i < s.Length / 2; i++)
        {
            bytes[i] = (byte)(Convert.ToInt32(s.Substring(2 * i, 2), 16));
        }
        
        return bytes;
    }

    private static String toHexString(byte[] b)
  	{
        if ((b == null) || (b.Length == 0))
        {
            return "";
        }
        
        else
        {
        	return toHexString(b, 0, b.Length);
        }
    }

    /** Convert bytes to HEX string */
    private static String toHexString(byte[] b, int off, int len)
   	{
        StringBuilder s = new StringBuilder();
        for (int i = off; i < off + len; i++)
        {
            s.Append(HEX_DIGITS[(b[i] & 0xff) >> 4]); s.Append(HEX_DIGITS[b[i] & 0xf]);
            // or
            //s.Append((b[i]).ToString("X2"));
        }
        
        return s.ToString();
    }

    public static String generateAuthKey(String klikPayCode, String transactionNo, String currency, string transactionDate, String keyId)
   	{
        return generateAuthKey(klikPayCode.PadRight(10, '0') + transactionNo.PadRight(18, 'A') + currency.PadRight(5, '1') + transactionDate.PadLeft(19, 'C') + keyId, keyId); 
    }

    private static String generateAuthKey(String secondValue, String keyId)
  	{
        MD5 sha = MD5.Create();

        byte[] byteHash = sha.ComputeHash(Encoding.UTF8.GetBytes(secondValue)); ;
        String hashData = toHexString(byteHash);

        byte[] byteHashData = fromHexString(hashData);
        byte[] byteKey = fromHexString(keyId);

        if (!(byteKey.Length == 16 || byteKey.Length == 24))
        {
            throw new Exception("Length not valid :" + byteKey.Length);
        }

        byte[] key = new byte[24];

        if (byteKey.Length == 16)
        {
            for (int za = 0; za < 16; za++)
            {
                key[za] = byteKey[za];
            }
            
            for (int za = 0; za < 8; za++)
            {
                key[za + 16] = byteKey[za];
            }
        }

        if (byteKey.Length == 24)
        {
            for (int za = 0; za < 24; za++)
            {
                key[za] = byteKey[za];
            }
        }

        MemoryStream ms	= new MemoryStream();
        TripleDES alg	= TripleDES.Create();
        alg.Key 	= key;
        alg.Mode 	= CipherMode.ECB;
        alg.Padding 	= PaddingMode.None;
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        
        cs.Write(byteHashData, 0, byteHashData.Length);

        cs.FlushFinalBlock();
        byte[] CipherBytes = ms.ToArray();
        ms.Close();
        cs.Close();

        String encryptedHashKey = toHexString(CipherBytes);

        return encryptedHashKey;
    }

    public static String generateKeyId(String clearKey)
 	{
        byte[] bytes = Encoding.UTF8.GetBytes(clearKey);
        return toHexString(bytes);
    }
}

private void static example()
{
    String keyId 	= BcaKeyGenerator.GenerateKey.generateKeyId(clearKey);
    
    sSignature		= BcaKeyGenerator.GenerateKey.generateSignature(klikPayCode, transactionDate, transactionNo, totalAmount, currency, keyId);
    
    sAuthKey 		= BcaKeyGenerator.GenerateKey.generateAuthKey(klikPayCode, transactionNo, currency, transactionDate, keyId);
}
<?php

function toHexString($string)
{
    $hex = '';
    
    for ($i=0; $i<strlen($string); $i++)
    {
    	$ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
	
    return strToUpper($hex);
}

function fromHexString($hex)
{
    $string = '';

    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    
    return $string;
}

function generateSignature($klikPayCode, $transactionDate, $transactionNo, $amount, $currency, $keyId)
{   
    date_default_timezone_set("Asia/Jakarta");
    
    $tempKey1 	= $klikPayCode.$transactionNo.$currency.$keyId;
    $hashKey1 	= getHash($tempKey1);
    $tdate	= date_create_from_format("d/m/Y G:i:s",$transactionDate);
    $idate	= (int)date_format($tdate, 'dmY');
    $iamount 	= (int)$amount;
    $tempKey2 	= ($idate + $iamount);
    $tempKey2 	= $tempKey2 . "";
    $hashKey2 	= getHash($tempKey2);
    $hash	= abs($hashKey1+$hashKey2);
    
    return $hash."";
}

function generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId)
{    
    $str1 = str_pad($klikPayCode,10, '0', STR_PAD_RIGHT) . str_pad($transactionNo,18, 'A', STR_PAD_RIGHT) . str_pad($currency,5, '1',STR_PAD_RIGHT) .  str_pad($transactionDate,19, 'C', STR_PAD_LEFT) . $keyId;
    
    $mdstr1 = md5($str1);
    $my_key = fromHexString($keyId);
    $data   = fromHexString($mdstr1); 
    $my_key .= substr($my_key,0,8);
    
    $secret = mcrypt_encrypt(MCRYPT_3DES, $my_key, $data, MCRYPT_MODE_ECB); 
    
    return toHexString($secret);
}

function generateKeyId($str)
{
	return toHexString($str);
}

function getHash ($value)
{       
    $hash = 0;
	
    for ($i = 0; $i < strlen($value); $i++)
    {
        $hash = (intval($hash) * 31) + ord($value[$i]);
        $hash = intval32bits($hash);
    }
	
    return (int)$hash;
}

function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

    if ($value & 0x80000000)
    {
        $value = -((~$value & 0xFFFFFFFF) + 1);
    }

    return $value;
}

$clearKey		= "ClearKey00000001";
$klikPayCode		= "BCAPAY0001";

//format: "d/m/Y G:i:s"
$transactionDate	= "11/04/2014 16:15:53";

$transactionNo 		= "R223248";
$totalAmount 		= 3000.00;
$currency		= "IDR";
$keyId 			= generateKeyId($clearKey);
$sSignature 		= generateSignature($klikPayCode, $transactionDate, $transactionNo, $totalAmount, $currency, $keyId);
$sAuthKey 		= generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId);

echo $keyId."<br/>".$sSignature."<br/>".$sAuthKey;

?>

Redirect Forward

Setelah menerima persetujuan pembayaran dari iPay88 Indonesia, merchant harus menetapkan atau mengatur proses redirect forward, jadi pelanggan akan melakukan login di laman BCA KlikPay.



URL yang digunakan untuk proses redirect forward adalah:

  1. Development:
    https://sandbox.ipay88.co.id/klikpaybca/purchasing/purchase.asp?action=loginRequest
  2. UAT:
    https://sb-ipay.u-appspecto.com:8081/purchasing/purchase.do?action=loginRequest
  3. Production:
    https://klikpay.klikbca.com/purchasing/purchase.do?action=loginRequest


Input

Berikut ini adalah data table spesifikasi pada input dan tipe data yag digunakan.


No
Nama Field
Deskripsi
Tipe
Format
M/O
1 klikPayCode klikPay Code String (10) (AN) M
2 transactionNo Transaction Number String (18) (AN) M
3 totalAmount Total Amount String (12) 999999999.00 M
4 currency Currency String (5) (A) M
5 payType Payment Type String (2) 99 M
6 callback Call Back URL String (100) (AN) M
7 transactionDate Transaction Date String (19) DD/MM/YYYY
hh:mm:ss
M
8 Descp Description String (60) (AN) O
9 miscFee Miscellanous Fee String (12) 999999999.00 O
10 signature Signature String (10) (N) M

Keterangan:

  1. (AN): Alpha-numeric format.
  2. 2 digit terakhir untuk totalAmount dan miscFee harus menjadi titik desimal. Titik desimal harus bernilai .00.
  3. Nilai dari TotalAmount adalah total untuk transaksi tetapi tidak termasuk miscFee.
  4. payType dapat diisi dengan nilai berikut:
    1. 01 = Full
    2. 02 = Installment
    3. 03 = 01 dan 02
  5. Currency harus bernilai IDR.
  6. M: Mandatory (diharuskan).
  7. O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


<html>
<body>

<form method="post" name="ePayment" action="https://klikpay.klikbca.com/purchasing/purchase.do?action=loginRequest">
<input type="hidden" name="klikPayCode" value="BCAPAY0001">
<input type="hidden" name="clearKey" value="ClearKey00000001">
<input type="hidden" name="transactionNo" value="R811184">
<input type="hidden" name="totalAmount" value="3000\">
<input type="hidden" name="Currency" value="IDR">
<input type="hidden" name="payType" value="01">
<input type="hidden" name="transactionDate" value="17/04/2014 11:24:55">
<input type="hidden" name="descp" value="test Pembelian">
<input type="hidden" name="miscFee" value="0.00">
<input type="hidden" name="signature" value="240101082">
<input type="hidden" name="callback" value="https://dvl1.ipay88.co.id/klikpaybca/purchasing/callback.asp?trxno=R811184">
<input type="submit" value="Proceed with Payment" name="Submit">
</form>

</body>
</html>

Signature Algorithm

Parameter yang digunakan adalah sebagai berikut.

  1. KlikPay Code
  2. Transaction Time (format: ddMMyyyy)
  3. Transaction Number
  4. Total Amount (catatan: format dalam nilai integer, tidak ada angka desimal)
  5. Currency
  6. Key Id (key digunakan untuk transaksi)


Fungsi PHP mcrypt_encrypt hanya berlaku untuk PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0. Berikut penjelasan yang dikutip dari situs resmi PHP.

Untuk informasi lebih lanjut, silahkan klik tautan berikut.

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class GenerateKey
{
    private static String HEX_DIGITS = "0123456789ABCDEF";
    
    private static int getHash(String val)
	{
    	int h = 0;
        char[] vals = val.ToCharArray();
        for (int i = 0; i < vals.Length; i++)
        {
        	h = (h * 31) + (int)vals[i];
      	}
        
    	return h;
    }
    	    
    public static String generateSignature(String klikPayCode, String transactionDate, String transactionNo, String amount, String currency, String keyId)
   	{
    	// Generate Key Step 1
        String tempKey1 = klikPayCode + transactionNo + currency + keyId;
        int hashKey1 = getHash(tempKey1);
        
        // Generate Key Step 2
        // Reformat Input Date
        DateTime date = new DateTime();
        date = DateTime.ParseExact(transactionDate, "dd/MM/yyyy HH:mm:ss", null);

        int transDate = Convert.ToInt32(date.ToString("ddMMyyyy"));
        int amt = (Int32)Convert.ToDouble(amount);

        String tempKey2 = (transDate + amt).ToString();
        int hashKey2 = getHash(tempKey2);

        // Hash the value using integer arithmatic and absolute value
        Decimal hash = Math.Abs(decimal.Add(new Decimal(hashKey1), new Decimal(hashKey2)));

        return hash.ToString();
    }
    
    private static byte[] fromHexString(String s)
   	{
        byte[] bytes = new byte[s.Length / 2];
        for (int i = 0; i < s.Length / 2; i++)
        {
            bytes[i] = (byte)(Convert.ToInt32(s.Substring(2 * i, 2), 16));
        }
        
        return bytes;
    }

    private static String toHexString(byte[] b)
  	{
        if ((b == null) || (b.Length == 0))
        {
            return "";
        }
        
        else
        {
        	return toHexString(b, 0, b.Length);
        }
    }

    /** Convert bytes to HEX string */
    private static String toHexString(byte[] b, int off, int len)
   	{
        StringBuilder s = new StringBuilder();
        for (int i = off; i < off + len; i++)
        {
            s.Append(HEX_DIGITS[(b[i] & 0xff) >> 4]); s.Append(HEX_DIGITS[b[i] & 0xf]);
            // or
            //s.Append((b[i]).ToString("X2"));
        }
        
        return s.ToString();
    }

    public static String generateAuthKey(String klikPayCode, String transactionNo, String currency, string transactionDate, String keyId)
   	{
        return generateAuthKey(klikPayCode.PadRight(10, '0') + transactionNo.PadRight(18, 'A') + currency.PadRight(5, '1') + transactionDate.PadLeft(19, 'C') + keyId, keyId); 
    }

    private static String generateAuthKey(String secondValue, String keyId)
  	{
        MD5 sha = MD5.Create();

        byte[] byteHash = sha.ComputeHash(Encoding.UTF8.GetBytes(secondValue)); ;
        String hashData = toHexString(byteHash);

        byte[] byteHashData = fromHexString(hashData);
        byte[] byteKey = fromHexString(keyId);

        if (!(byteKey.Length == 16 || byteKey.Length == 24))
        {
            throw new Exception("Length not valid :" + byteKey.Length);
        }

        byte[] key = new byte[24];

        if (byteKey.Length == 16)
        {
            for (int za = 0; za < 16; za++)
            {
                key[za] = byteKey[za];
            }
            
            for (int za = 0; za < 8; za++)
            {
                key[za + 16] = byteKey[za];
            }
        }

        if (byteKey.Length == 24)
        {
            for (int za = 0; za < 24; za++)
            {
                key[za] = byteKey[za];
            }
        }

        MemoryStream ms	= new MemoryStream();
        TripleDES alg	= TripleDES.Create();
        alg.Key 	= key;
        alg.Mode 	= CipherMode.ECB;
        alg.Padding 	= PaddingMode.None;
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        
        cs.Write(byteHashData, 0, byteHashData.Length);

        cs.FlushFinalBlock();
        byte[] CipherBytes = ms.ToArray();
        ms.Close();
        cs.Close();

        String encryptedHashKey = toHexString(CipherBytes);

        return encryptedHashKey;
    }

    public static String generateKeyId(String clearKey)
 	{
        byte[] bytes = Encoding.UTF8.GetBytes(clearKey);
        return toHexString(bytes);
    }
}

private void static example()
{
    String keyId 	= BcaKeyGenerator.GenerateKey.generateKeyId(clearKey);
    
    sSignature		= BcaKeyGenerator.GenerateKey.generateSignature(klikPayCode, transactionDate, transactionNo, totalAmount, currency, keyId);
    
    sAuthKey 		= BcaKeyGenerator.GenerateKey.generateAuthKey(klikPayCode, transactionNo, currency, transactionDate, keyId);
}
<?php

function toHexString($string)
{
    $hex = '';
    
    for ($i=0; $i<strlen($string); $i++)
    {
    	$ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
	
    return strToUpper($hex);
}

function fromHexString($hex)
{
    $string = '';

    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    
    return $string;
}

function generateSignature($klikPayCode, $transactionDate, $transactionNo, $amount, $currency, $keyId)
{   
    date_default_timezone_set("Asia/Jakarta");
    
    $tempKey1 	= $klikPayCode.$transactionNo.$currency.$keyId;
    $hashKey1 	= getHash($tempKey1);
    $tdate	= date_create_from_format("d/m/Y G:i:s",$transactionDate);
    $idate	= (int)date_format($tdate, 'dmY');
    $iamount 	= (int)$amount;
    $tempKey2 	= ($idate + $iamount);
    $tempKey2 	= $tempKey2 . "";
    $hashKey2 	= getHash($tempKey2);
    $hash	= abs($hashKey1+$hashKey2);
    
    return $hash."";
}

function generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId)
{    
    $str1 = str_pad($klikPayCode,10, '0', STR_PAD_RIGHT) . str_pad($transactionNo,18, 'A', STR_PAD_RIGHT) . str_pad($currency,5, '1',STR_PAD_RIGHT) .  str_pad($transactionDate,19, 'C', STR_PAD_LEFT) . $keyId;
    
    $mdstr1 = md5($str1);
    $my_key = fromHexString($keyId);
    $data   = fromHexString($mdstr1); 
    $my_key .= substr($my_key,0,8);
    
    $secret = mcrypt_encrypt(MCRYPT_3DES, $my_key, $data, MCRYPT_MODE_ECB); 
    
    return toHexString($secret);
}

function generateKeyId($str)
{
	return toHexString($str);
}

function getHash ($value)
{       
    $hash = 0;
	
    for ($i = 0; $i < strlen($value); $i++)
    {
        $hash = (intval($hash) * 31) + ord($value[$i]);
        $hash = intval32bits($hash);
    }
	
    return (int)$hash;
}

function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

    if ($value & 0x80000000)
    {
        $value = -((~$value & 0xFFFFFFFF) + 1);
    }

    return $value;
}

$clearKey		= "ClearKey00000001";
$klikPayCode		= "BCAPAY0001";

//format: "d/m/Y G:i:s"
$transactionDate	= "11/04/2014 16:15:53";

$transactionNo 		= "R223248";
$totalAmount 		= 3000.00;
$currency		= "IDR";
$keyId 			= generateKeyId($clearKey);
$sSignature 		= generateSignature($klikPayCode, $transactionDate, $transactionNo, $totalAmount, $currency, $keyId);
$sAuthKey 		= generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId);

echo $keyId."<br/>".$sSignature."<br/>".$sAuthKey;

?>

Payment Flag Invocations to Merchants

Dari proses pertama (list inquiry of transactions) sampai proses terakhir (setelah melakukan semua proses transaksi), BCA akan memproses nilai akun rekening pelanggan (debit dan/atau akun kredit) dan mengirim konfirmasi pembayaran untuk dikonfirmasi oleh merchant.


Proses Transaksi

Berikut proses transaksi antara Merchant dengan iPay88 Indonesia.



Catatan:

  1. Payment flag from BCA to Merchant.
  2. Response from Merchant to BCA.


Input

Berikut ini adalah data table spesifikasi pada input dan tipe data yag digunakan.


No
Nama Field
Deskripsi
Tipe
Format
M/O
1 klikPayCode klikPay Code String (10) (AN) M
2 transactionDate Transaction Date String (19) DD/MM/YYYY
hh:mm:ss
M
3 transactionNo Transaction Number String (18) (AN) M
4 currency Currency String (5) (A) M
5 totalAmount Total Amount String (12) 999999999.00 M
6 payType Payment Type String (2) 99 M
7 approvalCodeFullTransaction Kode persetujuan untuk transaksi full payment Number (6) (N) O
8 approvalCodeInstallmentTransaction Kode persetujuan untuk transaksi cicilan Number (6) (N) O
9 authKey Kunci otorisasi String (32) (N) M
10 additionalData Data tambahan String (999) (AN) O

Keterangan:

  1. (AN): Alpha-numeric format.
  2. Approval Code untuk fullTransaction akan diisi jika pelanggan memiliki transaksi penuh dan memilih untuk melakukan pembayaran pada transaksi penuh tersebut menggunakan kartu kredit.
  3. Approval Code untuk installmentTransaction akan diisi jika pelanggan memiliki angsuran transaksi.
  4. 2 digit terakhir untuk totalAmount dan miscFee harus menjadi titik desimal. Titik desimal harus bernilai .00.
  5. Field pada totalAmount adalah total untuk transaksi.
  6. payType dapat diisi dengan nilai berikut:
    1. 01 = Full
    2. 02 = Installment
    3. 03 = 01 dan 02
  7. Currency harus bernilai IDR.
  8. M: Mandatory (diharuskan).
  9. O: Optional (tidak diharuskan), nilai boleh kosong tetapi parameter harus ada.


Auth Key Algorithm

Berikut Authkey Flag yang digunakan untuk transaksi:



Parameter yang digunakan adalah sebagai berikut.

  1. A = klikPayCode
  2. B = transactionNo
  3. C = currency
  4. D = transactionDate
  5. K = keyId (current key used for transaction)
  6. e = encrypt using 3DES by keyId
  7. h = hash function


Fungsi PHP mcrypt_encrypt hanya berlaku untuk PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0. Berikut penjelasan yang dikutip dari situs resmi PHP.

Untuk informasi lebih lanjut, silahkan klik tautan berikut.

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class GenerateKey
{
    private static String HEX_DIGITS = "0123456789ABCDEF";
    
    private static int getHash(String val)
	{
    	int h = 0;
        char[] vals = val.ToCharArray();
        for (int i = 0; i < vals.Length; i++)
        {
        	h = (h * 31) + (int)vals[i];
      	}
        
    	return h;
    }
    	    
    public static String generateSignature(String klikPayCode, String transactionDate, String transactionNo, String amount, String currency, String keyId)
   	{
    	// Generate Key Step 1
        String tempKey1 = klikPayCode + transactionNo + currency + keyId;
        int hashKey1 = getHash(tempKey1);
        
        // Generate Key Step 2
        // Reformat Input Date
        DateTime date = new DateTime();
        date = DateTime.ParseExact(transactionDate, "dd/MM/yyyy HH:mm:ss", null);

        int transDate = Convert.ToInt32(date.ToString("ddMMyyyy"));
        int amt = (Int32)Convert.ToDouble(amount);

        String tempKey2 = (transDate + amt).ToString();
        int hashKey2 = getHash(tempKey2);

        // Hash the value using integer arithmatic and absolute value
        Decimal hash = Math.Abs(decimal.Add(new Decimal(hashKey1), new Decimal(hashKey2)));

        return hash.ToString();
    }
    
    private static byte[] fromHexString(String s)
   	{
        byte[] bytes = new byte[s.Length / 2];
        for (int i = 0; i < s.Length / 2; i++)
        {
            bytes[i] = (byte)(Convert.ToInt32(s.Substring(2 * i, 2), 16));
        }
        
        return bytes;
    }

    private static String toHexString(byte[] b)
  	{
        if ((b == null) || (b.Length == 0))
        {
            return "";
        }
        
        else
        {
        	return toHexString(b, 0, b.Length);
        }
    }

    /** Convert bytes to HEX string */
    private static String toHexString(byte[] b, int off, int len)
   	{
        StringBuilder s = new StringBuilder();
        for (int i = off; i < off + len; i++)
        {
            s.Append(HEX_DIGITS[(b[i] & 0xff) >> 4]); s.Append(HEX_DIGITS[b[i] & 0xf]);
            // or
            //s.Append((b[i]).ToString("X2"));
        }
        
        return s.ToString();
    }

    public static String generateAuthKey(String klikPayCode, String transactionNo, String currency, string transactionDate, String keyId)
   	{
        return generateAuthKey(klikPayCode.PadRight(10, '0') + transactionNo.PadRight(18, 'A') + currency.PadRight(5, '1') + transactionDate.PadLeft(19, 'C') + keyId, keyId); 
    }

    private static String generateAuthKey(String secondValue, String keyId)
  	{
        MD5 sha = MD5.Create();

        byte[] byteHash = sha.ComputeHash(Encoding.UTF8.GetBytes(secondValue)); ;
        String hashData = toHexString(byteHash);

        byte[] byteHashData = fromHexString(hashData);
        byte[] byteKey = fromHexString(keyId);

        if (!(byteKey.Length == 16 || byteKey.Length == 24))
        {
            throw new Exception("Length not valid :" + byteKey.Length);
        }

        byte[] key = new byte[24];

        if (byteKey.Length == 16)
        {
            for (int za = 0; za < 16; za++)
            {
                key[za] = byteKey[za];
            }
            
            for (int za = 0; za < 8; za++)
            {
                key[za + 16] = byteKey[za];
            }
        }

        if (byteKey.Length == 24)
        {
            for (int za = 0; za < 24; za++)
            {
                key[za] = byteKey[za];
            }
        }

        MemoryStream ms	= new MemoryStream();
        TripleDES alg	= TripleDES.Create();
        alg.Key 	= key;
        alg.Mode 	= CipherMode.ECB;
        alg.Padding 	= PaddingMode.None;
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        
        cs.Write(byteHashData, 0, byteHashData.Length);

        cs.FlushFinalBlock();
        byte[] CipherBytes = ms.ToArray();
        ms.Close();
        cs.Close();

        String encryptedHashKey = toHexString(CipherBytes);

        return encryptedHashKey;
    }

    public static String generateKeyId(String clearKey)
 	{
        byte[] bytes = Encoding.UTF8.GetBytes(clearKey);
        return toHexString(bytes);
    }
}

private void static example()
{
    String keyId 	= BcaKeyGenerator.GenerateKey.generateKeyId(clearKey);
    
    sSignature		= BcaKeyGenerator.GenerateKey.generateSignature(klikPayCode, transactionDate, transactionNo, totalAmount, currency, keyId);
    
    sAuthKey 		= BcaKeyGenerator.GenerateKey.generateAuthKey(klikPayCode, transactionNo, currency, transactionDate, keyId);
}
<?php

function toHexString($string)
{
    $hex = '';
    
    for ($i=0; $i<strlen($string); $i++)
    {
    	$ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
	
    return strToUpper($hex);
}

function fromHexString($hex)
{
    $string = '';

    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    
    return $string;
}

function generateSignature($klikPayCode, $transactionDate, $transactionNo, $amount, $currency, $keyId)
{   
    date_default_timezone_set("Asia/Jakarta");
    
    $tempKey1 	= $klikPayCode.$transactionNo.$currency.$keyId;
    $hashKey1 	= getHash($tempKey1);
    $tdate	= date_create_from_format("d/m/Y G:i:s",$transactionDate);
    $idate	= (int)date_format($tdate, 'dmY');
    $iamount 	= (int)$amount;
    $tempKey2 	= ($idate + $iamount);
    $tempKey2 	= $tempKey2 . "";
    $hashKey2 	= getHash($tempKey2);
    $hash	= abs($hashKey1+$hashKey2);
    
    return $hash."";
}

function generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId)
{    
    $str1 = str_pad($klikPayCode,10, '0', STR_PAD_RIGHT) . str_pad($transactionNo,18, 'A', STR_PAD_RIGHT) . str_pad($currency,5, '1',STR_PAD_RIGHT) .  str_pad($transactionDate,19, 'C', STR_PAD_LEFT) . $keyId;
    
    $mdstr1 = md5($str1);
    $my_key = fromHexString($keyId);
    $data   = fromHexString($mdstr1); 
    $my_key .= substr($my_key,0,8);
    
    $secret = mcrypt_encrypt(MCRYPT_3DES, $my_key, $data, MCRYPT_MODE_ECB); 
    
    return toHexString($secret);
}

function generateKeyId($str)
{
	return toHexString($str);
}

function getHash ($value)
{       
    $hash = 0;
	
    for ($i = 0; $i < strlen($value); $i++)
    {
        $hash = (intval($hash) * 31) + ord($value[$i]);
        $hash = intval32bits($hash);
    }
	
    return (int)$hash;
}

function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

    if ($value & 0x80000000)
    {
        $value = -((~$value & 0xFFFFFFFF) + 1);
    }

    return $value;
}

$clearKey		= "ClearKey00000001";
$klikPayCode		= "BCAPAY0001";

//format: "d/m/Y G:i:s"
$transactionDate	= "11/04/2014 16:15:53";

$transactionNo 		= "R223248";
$totalAmount 		= 3000.00;
$currency		= "IDR";
$keyId 			= generateKeyId($clearKey);
$sSignature 		= generateSignature($klikPayCode, $transactionDate, $transactionNo, $totalAmount, $currency, $keyId);
$sAuthKey 		= generateAuthKey($klikPayCode, $transactionNo, $currency, $transactionDate, $keyId);

echo $keyId."<br/>".$sSignature."<br/>".$sAuthKey;

?>

Output

Berikut ini adalah data table spesifikasi pada output dan tipe data yag digunakan.


No
Nama Field
Tipe
Format
Nullable
1 status string (2) (AN) False
2 english String (50) (AN) False
3 indonesian String (50) (AN) False

<?php
$vklikPayCode		= $_REQUEST['klikPayCode'];
$vtransactionNo		= $_REQUEST['transactionNo'];
$vtransactionDate	= $_REQUEST['transactionDate'];
$vcurrency		= $_REQUEST['currency'];
$vtotalAmount		= $_REQUEST['totalAmount'];
$vpayType		= $_REQUEST['payType'];

$vapprovalCodeFullTransaction
= $_REQUEST['approvalCodeFullTransaction'];

$vapprovalCodeInstallmentTransaction
= $_REQUEST['approvalCodeInstallmentTransaction'];

$vauthKey		= $_REQUEST['authKey'];
$vadditionalData	= $_REQUEST['additionalData'];

//Do Authkey & Amount checking,write success if correct
echo "00:||:Success.:||:Sukses.";

Key ID untuk Transaksi

Berikut Key ID yang digunakan untuk transaksi.



Catatan:

  1. clearKey: Clear key yang diberikan oleh BCA.
  2. bytes: Array daripada bytes dari clear key.
  3. hexArray: Array daripada char untuk karakter hexa.
  4. keyId: String daripada hexa dari clear key, dikenal sebagai current key yang digunakan untuk transaksi.



Lampiran

Berikut lampiran yang dapat digunakan sebagai informasi tambahan untuk integrasi dengan BCA KlikPay melalui iPay88 Indonesia.


Response Codes

Berikut ini adalah data table spesifikasi kode yang didapatkan ketika response dari merchant.


No
Response Code
Response Code
1 00 TRX_SUCCESS (*)
2 01 TRX_REJECTED (*)

Reason (Deskripsi Error)

Berikut ini adalah data table spesifikasi untuk contoh penyebab kegagalan pada transaksi yang dapat digunakan oleh merchant.


No
Condition
Reason (Error Deskripsi)
1 Your transaction has been canceled Transaksi Anda telah dibatalkan
2 Your transaction has been paid Transaksi Anda sudah dibayar
3 Your transaction has expired or exceeded Your transaction has expired or exceededtime limit Transaksi Anda sudah kadaluarsa atau telah mencapai waktu yang ditetapkan
4 Technical problem Transaksi Anda tidak bisa diproses
5 Transaction data (amount, etc.) from bank is different with transaction data in the merchantTechnical problem Transaksi Anda tidak sesuai

Referensi

Kami berusaha memberikan informasi selengkap mungkin untuk Anda. Adanya informasi tersebut menjadikan proses integrasi Anda dengan iPay88 OPSG menjadi mudah dan cepat. Untuk itu, kami meyediakan referensi sebagai informasi tambahan untuk Anda. Berikut ini adalah referensi dari iPay88 OPSG.


Testing Credentials

Uji transaksi dengan metode pembayaran kartu kredit melalui sandbox memerlukan data sampel kartu. Berikut ini adalah testing credentials yang dapat digunakan untuk uji transaksi dengan metode pembayaran kartu kredit.


1. Pengujian Data

Card Number
CVV/CVV2
EXP Date (MM/YY)
Card Status
4000000000000044
123
03/33
Good card
5500000000000004
123
03/33
Good card

2. Pengujian Data Eksespsi

Card Number
CVV/CVV2
EXP Date (MM/YY)
Card Status
Error Message
4000000000000028
223
07/18
Bad card
Bank declined transaction
5200000000000007
223
07/18
Bad card
Bank declined transaction
5200000000000015
223
07/18
Bad card
Bank declined transaction


Payment ID

Berikut ini adalah daftar Payment ID iPay88 Indonesia berdasarkan metode pembayaran yang tersedia.


1. Credit Card

Metode Pembayaran
Payment ID
Credit Card (BCA)
52
Credit Card (BRI)
35
Credit Card (CIMB)
42
Credit Card (CIMB Authorization)
56
Credit Card (CIMB IPG)
34
Credit Card (Danamon)
45
Credit Card (Mandiri)
53
Credit Card (Maybank)
43
Credit Card (UnionPay)
54
Credit Card (UOB)
46
Credit Card (GPN)
49

2. Online Banking

Metode Pembayaran
Payment ID
BCA KlikPay
8
CIMB Clicks
11
Muamalat IB
14
Danamon Online Banking
23

3. ATM Transfer

Metode Pembayaran
Payment ID
Maybank VA
9
Mandiri ATM
17
BCA VA
25/30
BNI VA
26/68
Permata VA
31
BRI VA
61

4. e-Wallet

Metode Pembayaran
Payment ID
ShopeePay
75
DANA
77
LinkAja
13
OVO
63

5. Others

Metode Pembayaran
Payment ID
PayPal
6
Kredivo
55
Alfamart
60
Indomaret
65
Indodana
70
Akulaku
71


Mata Uang

Berikut ini adalah mata uang yang diharuskan untuk integrasi dengan iPay88 Indonesia.

Deskripsi Mata Uang
Simbol
Indonesia Rupiah
IDR


Deskripsi Error

Berikut ini adalah daftar pesan dan deskripsi error dari iPay88 Indonesia saat integrasi dengan merchant.

Pesan Error
Deskripsi Error
Duplicate transaction reference number. Nomor referensi digunakan kembali setelah nomor tersebut digunakan untuk pembayaran yang terlah sukses.
Merchant identifier is missing or unregistered. Merchant code tidak terdaftar atau merchant code salah.
Transaction exceeds maximum allowed amount. Kelebihan nilai total per transaksi.
Unregistered merchant callback URL. Request url milik merchant yang terdaftar di iPay88 tidak tepat. Silahkan registrasi request url situs Anda ke iPay88.
Transaction signature is not match. Signature yang dihasilkan merchant tidak tepat.
Merchant account is suspended or inactive. Akun telah disuspend atau tidak aktif.
Invalid transaction amount format. Format value pada parameter Amount tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid transaction currency format. Format value pada parameter Currency tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid merchant identifier. Format value pada parameter MerchantCode tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid transaction channel identifier. Format value pada parameter PaymentId tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid purchased item description format. Format value pada parameter ProdDesc tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid transaction reference number. Format value pada parameter RefNo tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid customer email format. Format value pada parameter UserEmail tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Invalid customer name format. Format value pada parameter UserName tidak sesuai atau tidak ada value pada parameter tersebut ketika merchant request ke iPay88.
Transaction time has expired when receiving authorization response. Respon dari Issuer/Acquirer melebihi waktu transaksi (timeout).
Payment method or channel is not subscribed. Merchant menggunakan metode pembayaran yang tidak didaftarkan ke iPay88.
Transaction does not pass all fraud security check. Transaksi ditolak oleh parameter Fraud Detection System (FDS).