Integrasi Pembayaran Kartu

Proses integrasi dasar untuk pembayaran kartu akan dijelaskan di bawah.

Environment Sandbox

Semua langkah di bawah menggunakan Sandbox environment Midtrans, bukan Production, untuk memudahkan testing proses integrasi. Pastikan Anda sudah mengubah ke mode Sandbox pada dashboard akun Midtrans Anda saat mendapatkan Server Key dan Client Key. Dijelaskan pada Langkah Awal - Persiapan

Server Key dan Client Key bisa didapatkan pada menu Settings > Access Keys

Testing Pembayaran

Untuk mengetest transaksi sebagai customer, silahkan gunakan kredensial testing di sini. Contoh, kartu untuk skenario sukses:

Card Number: 4811 1111 1111 1114 
CVV: 123 
Expiry: <tanggal berapapun di masa depan>

Diagram

Gambaran dari flow transaksi dalam sequence diagaram:

flow transaksi kartu .

Langkah Integrasi

  1. Dapatkan token kartu, melalui frontend.
  2. Kirim data traksaksi ke API Charge dengan token kartu, melalui backend.
  3. (Kondisional) jika transaksi 3DS, buka redirect_url 3DS dengan popup/redirect, melalui frontend.
  4. Terima notifikasi transaksi, pada backend.

1. Dapatkan Token Kartu

token_id kartu adalah representasi dari data kartu customer, yang akan digunakan untuk transaksi. token_id didapatkan menggunakan Library JS MidtransNew3ds pada frontend website merchant, data kartu akan dikirimkan dengan aman dari javascript frontend ke API Midtrans untuk ditukar dengan token_id kartu, untuk menghindari risiko jika data kartu dikirim dari backend merchant.

Gunakan Midtrans JS

Client Key (dari Dashboard) diperlukan untuk tahap ini. Gunakan JS library Midtrans pada halaman pembayaran, dengan menambahkan script tag:

<script id="midtrans-script" type="text/javascript"
src="https://api.midtrans.com/v2/assets/js/midtrans-new-3ds.min.js" 
data-environment="sandbox" 
data-client-key="<MASUKKAN CLIENT KEY ANDA DISINI>"></script>

Penting: Ganti attribute berikut.

Attribute Nilai
data-environment Masukkan sandbox atau production (API environment)
data-client-key Masukkan client key dari Dashboard akun Anda.

Tautan: Definisi lebih detail

Implementasi JS Untuk Mendapatkan Token Kartu

Untuk mendapatkan token_id kartu, kita akan menggunakan function MidtransNew3ds.getCardToken. Implementasikan Javascript berikut pada halaman pembayaran.

// data kartu dari input customer, contohnya
var cardData = {
  "card_number": 4811111111111114,
  "card_exp_month": 02,
  "card_exp_year": 2025,
  "card_cvv": 123,
};

// callback functions
var options = {
  onSuccess: function(response){
    // Sukses mendapatkan token_id kartu, implementasi sesuai kebutuhan
    console.log('Success to get card token_id, response:', response);
    var token_id = response.token_id;
    console.log('This is the card token_id:', token_id);
  },
  onFailure: function(response){
    // Gagal mendapatkan token_id kartu, implementasi sesuai kebutuhan
    console.log('Fail to get card token_id, response:', response);
  }
};

// panggil function `getCardToken`
MidtransNew3ds.getCardToken(cardData, options);

Jika semua lancar, kita akan mendapatkan token_id kartu di dalam callback function onSuccess. Yang akan digunakan sebagai salah satu parameter JSON untuk request API /charge.

token_id akan butuh untuk dikirimkan dari frontend ke backend pada tahap selanjutnya, bisa dilakukan menggunakan Ajax (dengan javascript) atau form HTML (dengan HTTP POST), dsb. Merchant bebas mengimplementasikan.

Catatan: token_id ini hanya valid untuk 1 transaksi. Setiap transaksi diharuskan melalui proses ini lagi, untuk membantu memastikan data kartu dikirimkan dengan aman. Jika Anda ingin untuk menyimpan token kartu, Anda bisa gunakan fitur One-click/Two-clicks.



2. Kirim Data Transaksi ke API Charge

Request API charge akan dilakukan melalui backend Merchant. Server Key (dari Dashboard dashboard Anda) akan dibutuhkan untuk meng-otentikasi request.

Request Charge API

Berikut contoh dari request API /charge dalam Curl, silahkan implementasikan sesuai bahasa pemrograman backend Anda (Anda juga bisa cek library-library pemrograman yang tersedia). Gunakan token_id yang didapat sebelumnya.

# contoh charge dalam CURL
curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <SERVER KEY ANDA ENCODED dalam Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "credit_card",
  "transaction_details": {
    "order_id": "order102",
    "gross_amount": 789000
  },
  "credit_card": {
    "token_id": "<token_id yang didapat dari langkah sebelumnya>",
    "authentication": true,
  }
}'

Opsional: kita bisa kustomisasi object credit_card untuk fitur-fitur yg lebih kompleks. Contohnya:

...
  "credit_card": {
    "token_id": "<token_id yang didapat dari langkah sebelumnya>",
    "authentication": true, //set true untuk 3DS, false jika punya acquiring non 3DS
    "save_token_id": true //opsional, untuk fitur one/two click
    "installment_term": 12, //opsional, untuk fitur installment
    "bank": "bca", //opsional, untuk spesifik bank acquiring
  }
...

Opsional: kita bisa kustomisasi data transaction_details. Untuk menyertakan data seperti customer_details, item_details, dsb. Disarankan untuk mengirim data sebanyak mungkin agar nantinya report/dashboard menampilkan informasi tersebut.

Response Charge API

Kita akan mendapat response API seperti ini.

{
  "status_code": "201",
  "status_message": "Success, Credit Card transaction is successful",
  "transaction_id": "0bb563a9-ebea-41f7-ae9f-d99ec5f9700a",
  "order_id": "order102",
  "redirect_url": "https://api.sandbox.veritrans.co.id/v2/token/rba/redirect/481111-1114-0bb563a9-ebea-41f7-ae9f-d99ec5f9700a",
  "gross_amount": "789000.00",
  "currency": "IDR",
  "payment_type": "credit_card",
  "transaction_time": "2019-08-27 15:50:54",
  "transaction_status": "pending",
  "fraud_status": "accept",
  "masked_card": "481111-1114",
  "bank": "bni",
  "card_type": "credit"
}
  • Jika transaction_status adalah capture dan fraud_status adalah accept, artinya transaksinya tidak butuh 3DS, dan sekarang sudah selesai dengan sukses.

  • Jika transaction_status adalah pending dan terdapat redirect_url, artinya transaksinya membutuhkan 3DS, dan akan butuh untuk dilanjutkan ke tahap selanjutnya, membuka halaman 3DS authentication.

3. Buka Halaman 3DS Authentication

Dari response API, sekarang kita punya redirect_url. Untuk dibuka (ditampilkan ke customer) menggunakan library JS MidtransNew3ds pada frontend website merchant.

Untuk membuka halaman 3DS kita bisa gunakan function MidtransNew3ds.authenticate atau MidtransNew3ds.redirect. Masukkan redirect_url yang didapatkan sebelumnya.

Implementasi JS Untuk Buka Halaman 3DS Authenticate

var redirect_url = '<redirect_url didapatkan dari response Charge>';

// callback functions
var options = {
  performAuthentication: function(redirect_url){
    // Implementasikan bagaimana anda akan membuka iframe untuk menampilkan redirect_url 3DS authentication ke customer
    popupModal.openPopup(redirect_url);
  },
  onSuccess: function(response){
    // 3ds authentication sukses, implementasikan skenario sukses
    console.log('response:',response);
    popupModal.closePopup();
  },
  onFailure: function(response){
    // 3ds authentication gagal, implementasikan skenario gagal
    console.log('response:',response);
    popupModal.closePopup();
  },
  onPending: function(response){
    // transaksi pending, hasil transaksi akan dikirimkan nanti melalui POST notification, implementasikan sesuai kebutuhan
    console.log('response:',response);
    popupModal.closePopup();
  }
};

// panggil function `authenticate`
MidtransNew3ds.authenticate(redirect_url, options);



/**
 * Contoh helper function untuk membuka Iframe popup, Anda bisa ubah implementasi dengan metode anda sendiri.
 * Contoh menggunakan library PicoModal:
 * <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/picomodal/3.0.0/picoModal.js"></script>
 */
var popupModal = (function(){
  var modal = null;
  return {
    openPopup(url){
      modal = picoModal({
        content:'<iframe frameborder="0" width="100%" height="100%" src="'+url+'"></iframe>',
        width: "75%", 
        closeButton: false, 
        overlayClose: false,
        escCloses: false
      }).show();
    },
    closePopup(){
      try{
        modal.close();
      } catch(e) {}
    }
  }
}());

/**
 * Atau alternatifnya, anda bisa redirect customer dengan: 
 * MidtransNew3ds.redirect(redirect_url, { callbackUrl : 'https://mywebsite.com/finish_3ds' });
 **/

JSON Response 3DS Authenticate

Pada callback function JS, kita akan mendapatkan JSON dari hasil transaksi seperi berikut.

{
  "status_code": "200",
  "status_message": "Success, Credit Card transaction is successful",
  "transaction_id": "226ba26f-b050-4fc5-aa25-b7f8169bc67b",
  "order_id": "order102",
  "gross_amount": "789000.00",
  "currency": "IDR",
  "payment_type": "credit_card",
  "transaction_time": "2019-08-27 17:22:08",
  "transaction_status": "capture",
  "fraud_status": "accept",
  "approval_code": "1566901334936",
  "eci": "05",
  "masked_card": "481111-1114",
  "bank": "bni",
  "card_type": "credit",
  "channel_response_code": "00",
  "channel_response_message": "Approved"
}

Jika transaction_status adalah capture dan fraud_status adalah accept, berarti transaksinya sukses, dan sudah selesai.

CATATAN PENTING: Untuk update status transaksi di backend/database Anda, JANGAN hanya mengandalkan callback dari frontend! Untuk alasan keamanan, dengan memastikan status transaksi berasal dari Midtrans, sebaiknya gunakan HTTP Notification atau API Get Status untuk update status transaksi.



4. Terima HTTP Notification

HTTP notification dari Midtrans ke backend Merchant akan dikirimkan pada saat terjadi perubahan transaction_status, untuk memastikan Mercahant mendapat informasi secara aman. Termasuk pada saat status transaksi berubah jadi success atau denied. Jadi selain JSON pada callback di atas, Merchant juga akan menerima notifikasi dari Midtrans.

Request HTTP POST dengan body JSON akan dikirimkan ke notification url Merchant yang dikonfigurasi pada dashboard (Settings > Configuration > Notification URL), berikut contoh body JSON yang akan diterima Merchant:

{
  "transaction_time": "2019-08-27 17:22:08",
  "transaction_status": "capture",
  "transaction_id": "226ba26f-b050-4fc5-aa25-b7f8169bc67b",
  "status_message": "midtrans payment notification",
  "status_code": "200",
  "signature_key": "9b67a07a82d592bc493f3b775eaae5b1862a8bbaa051cdd31a0a81566c84f2c4d306fe2712c86f8167c4faa594a0e2cbe6ae898491bfaebaf849681ae92264d5",
  "payment_type": "credit_card",
  "order_id": "order102",
  "masked_card": "481111-1114",
  "gross_amount": "789000.00",
  "fraud_status": "accept",
  "eci": "05",
  "currency": "IDR",
  "channel_response_message": "Approved",
  "channel_response_code": "00",
  "card_type": "credit",
  "bank": "bni",
  "approval_code": "1566901334936"
}

Lihat disni untuk lebih lengkap dalam menangani HTTP Notification.

Mengubah Ke Production

Untuk menggunakan environment production (menerima pembayaran dari customer sesungguhnya), silahkan pastikan:

  1. Ubah domain API URL dari api.sandbox.midtrans.com menjadi api.midtrans.com
  2. Ubah Client Key dan Server Key dari Dashboard sandbox, dengan key dari Dashboard production.

Selesai

Integrasi pembayaran kartu sekarang selesai. Berikut beberapa referensi tambahan.

Deskripsi

Nilai transaction_status dalam transaksi kartu:

Status Transaksi Deskripsi
capture Transaksi sukses, dana berhasil dipotong
pending Transaksi terbuat dan menunggu tindakan (3DS diselesaikan oleh customer)
deny Transaksi ditolak, cek lebih lanjut channel_response_message atau fraud_status
expire Transaksi gagal karena customer tidak menyelesaikan 3DS dalam waktu tertentu

Link: Definisi lebih detail transaction_status

Link: Definisi lebih detail fraud_status

Referensi

Anda juga bisa lihat contoh implementasi berikut:

Untuk lebih detail: Dokumentasi lengkap Core API