:warning::warning: ANNOUNCEMENT :warning::warning:
Please use the updated and composer compatible library: Midtrans PHP. For better more modern composer compatibility.
This repo still be here for archive and compatibility purpose. But it's always recommended to use the newer version Midtrans PHP.
:speaker: END OF ANNOUNCEMENT :speaker:
Midtrans :heart: PHP!
This is the Official PHP wrapper/library for Midtrans Payment API. Visit https://midtrans.com for more information about the product and see documentation at http://docs.midtrans.com for more technical details.
If you are using Composer, add this require line to your composer.json
file:
{
"require": {
"veritrans/veritrans-php": "dev-master"
}
}
and run composer install
on your terminal.
If you are not using Composer, you can clone or download this repository.
// Set your Merchant Server Key
Veritrans_Config::$serverKey = '<your server key>';
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
Veritrans_Config::$isProduction = false;
// Set sanitization on (default)
Veritrans_Config::$isSanitized = true;
// Set 3DS transaction for credit card to true
Veritrans_Config::$is3ds = true;
We have 3 different products of payment that you can use:
Choose one that you think best for your unique needs.
You can see Snap example here.
$params = array(
'transaction_details' => array(
'order_id' => rand(),
'gross_amount' => 10000,
)
);
$snapToken = Veritrans_Snap::getSnapToken($params);
//install library from composer
//in your controller no need to include anything
//make sure call class with \Class_name::method()
public function actionSnapToken() {
\Veritrans_Config::$serverKey = 'Secret Server Key Goes Here';
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
\Veritrans_Config::$isProduction = false;
// Set sanitization on (default)
\Veritrans_Config::$isSanitized = true;
// Set 3DS transaction for credit card to true
\Veritrans_Config::$is3ds = true;
$complete_request = [
"transaction_details" => [
"order_id" => "1234",
"gross_amount" => 10000
]
];
$snap_token = \Veritrans_Snap::getSnapToken($complete_request);
return ['snap_token' => $snap_token];
}
<html>
<body>
<button id="pay-button">Pay!</button>
<pre><div id="result-json">JSON result will appear here after payment:<br></div></pre>
<!-- TODO: Remove ".sandbox" from script src URL for production environment. Also input your client key in "data-client-key" -->
<script src="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<Set your ClientKey here>"></script>
<script type="text/javascript">
document.getElementById('pay-button').onclick = function(){
// SnapToken acquired from previous step
snap.pay('<?=$snapToken?>', {
// Optional
onSuccess: function(result){
/* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
},
// Optional
onPending: function(result){
/* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
},
// Optional
onError: function(result){
/* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
}
});
};
</script>
</body>
</html>
!!! VT-Web is DEPRECATED !!!
Please use Snap Redirect, it has the same functionality, but better. Refer to this section
~You can see some VT-Web examples here.~
$params = array(
'transaction_details' => array(
'order_id' => rand(),
'gross_amount' => 10000,
),
'vtweb' => array()
);
try {
// Redirect to Veritrans VTWeb page
header('Location: ' . Veritrans_Vtweb::getRedirectionUrl($params));
}
catch (Exception $e) {
echo $e->getMessage();
}
You can see some Snap Redirect examples here.
$params = array(
'transaction_details' => array(
'order_id' => rand(),
'gross_amount' => 10000,
),
'vtweb' => array()
);
try {
// Get Snap Payment Page URL
$paymentUrl = Veritrans_Snap::createTransaction($params)->redirect_url;
// Redirect to Snap Payment Page
header('Location: ' . $paymentUrl);
}
catch (Exception $e) {
echo $e->getMessage();
}
You can see some Core API examples here.
Veritrans.client_key = "<your client key>";
Please refer to this file
$transaction_details = array(
'order_id' => time(),
'gross_amount' => 200000
);
// Populate items
$items = array(
array(
'id' => 'item1',
'price' => 100000,
'quantity' => 1,
'name' => 'Adidas f50'
),
array(
'id' => 'item2',
'price' => 50000,
'quantity' => 2,
'name' => 'Nike N90'
));
// Populate customer's billing address
$billing_address = array(
'first_name' => "Andri",
'last_name' => "Setiawan",
'address' => "Karet Belakang 15A, Setiabudi.",
'city' => "Jakarta",
'postal_code' => "51161",
'phone' => "081322311801",
'country_code' => 'IDN'
);
// Populate customer's shipping address
$shipping_address = array(
'first_name' => "John",
'last_name' => "Watson",
'address' => "Bakerstreet 221B.",
'city' => "Jakarta",
'postal_code' => "51162",
'phone' => "081322311801",
'country_code' => 'IDN'
);
// Populate customer's info
$customer_details = array(
'first_name' => "Andri",
'last_name' => "Setiawan",
'email' => "test@test.com",
'phone' => "081322311801",
'billing_address' => $billing_address,
'shipping_address' => $shipping_address
);
// Token ID from checkout page
$token_id = $_POST['token_id'];
// Transaction data to be sent
$transaction_data = array(
'payment_type' => 'credit_card',
'credit_card' => array(
'token_id' => $token_id,
'bank' => 'bni',
'save_token_id' => isset($_POST['save_cc'])
),
'transaction_details' => $transaction_details,
'item_details' => $items,
'customer_details' => $customer_details
);
$response = Veritrans_VtDirect::charge($transaction_data);
// Success
if($response->transaction_status == 'capture') {
echo "<p>Transaksi berhasil.</p>";
echo "<p>Status transaksi untuk order id $response->order_id: " .
"$response->transaction_status</p>";
echo "<h3>Detail transaksi:</h3>";
echo "<pre>";
var_dump($response);
echo "</pre>";
}
// Deny
else if($response->transaction_status == 'deny') {
echo "<p>Transaksi ditolak.</p>";
echo "<p>Status transaksi untuk order id .$response->order_id: " .
"$response->transaction_status</p>";
echo "<h3>Detail transaksi:</h3>";
echo "<pre>";
var_dump($response);
echo "</pre>";
}
// Challenge
else if($response->transaction_status == 'challenge') {
echo "<p>Transaksi challenge.</p>";
echo "<p>Status transaksi untuk order id $response->order_id: " .
"$response->transaction_status</p>";
echo "<h3>Detail transaksi:</h3>";
echo "<pre>";
var_dump($response);
echo "</pre>";
}
// Error
else {
echo "<p>Terjadi kesalahan pada data transaksi yang dikirim.</p>";
echo "<p>Status message: [$response->status_code] " .
"$response->status_message</p>";
echo "<pre>";
var_dump($response);
echo "</pre>";
}
Create separated web endpoint (notification url) to receive HTTP POST notification callback/webhook. HTTP notification will be sent whenever transaction status is changed. Example also available here
$notif = new Veritrans_Notification();
$transaction = $notif->transaction_status;
$fraud = $notif->fraud_status;
error_log("Order ID $notif->order_id: "."transaction status = $transaction, fraud staus = $fraud");
if ($transaction == 'capture') {
if ($fraud == 'challenge') {
// TODO Set payment status in merchant's database to 'challenge'
}
else if ($fraud == 'accept') {
// TODO Set payment status in merchant's database to 'success'
}
}
else if ($transaction == 'cancel') {
if ($fraud == 'challenge') {
// TODO Set payment status in merchant's database to 'failure'
}
else if ($fraud == 'accept') {
// TODO Set payment status in merchant's database to 'failure'
}
}
else if ($transaction == 'deny') {
// TODO Set payment status in merchant's database to 'failure'
}
}
$status = Veritrans_Transaction::status($orderId);
var_dump($status);
If transaction fraud_status == CHALLENGE, you can approve the transaction from Merchant Dashboard, or API :
$approve = Veritrans_Transaction::approve($orderId);
var_dump($approve);
You can Cancel transaction with fraud_status == CHALLENGE
, or credit card transaction with transaction_status == CAPTURE
(before it become SETTLEMENT)
$cancel = Veritrans_Transaction::cancel($orderId);
var_dump($cancel);
You can Expire transaction with transaction_status == PENDING
(before it become SETTLEMENT or EXPIRE)
$cancel = Veritrans_Transaction::cancel($orderId);
var_dump($cancel);
There are several guides that must be taken care of when you develop new plugins.
Handling currency other than IDR. Veritrans v1
and v2
currently accepts payments in Indonesian Rupiah only. As a corrolary, there is a validation on the server to check whether the item prices are in integer or not. As much as you are tempted to round-off the price, DO NOT do that! Always prepare when your system uses currencies other than IDR, convert them to IDR accordingly, and only round the price AFTER that.
Consider using the auto-sanitization feature.