PHP code example of midtrans / midtrans-php

1. Go to this page and download the library: Download midtrans/midtrans-php library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

midtrans / midtrans-php example snippets




// my code goes here

// Set your Merchant Server Key
\Midtrans\Config::$serverKey = '<your server key>';
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
\Midtrans\Config::$isProduction = false;
// Set sanitization on (default)
\Midtrans\Config::$isSanitized = true;
// Set 3DS transaction for credit card to true
\Midtrans\Config::$is3ds = true;

// Add new notification url(s) alongside the settings on Midtrans Dashboard Portal (MAP)
Config::$appendNotifUrl = "https://example.com/test1,https://example.com/test2";
// Use new notification url(s) disregarding the settings on Midtrans Dashboard Portal (MAP)
Config::$overrideNotifUrl = "https://example.com/test1";

Config::$paymentIdempotencyKey = "Unique-ID";

$params = array(
    'transaction_details' => array(
        'order_id' => rand(),
        'gross_amount' => 10000,
    )
);

$snapToken = \Midtrans\Snap::getSnapToken($params);

$params = array(
    'transaction_details' => array(
        'order_id' => rand(),
        'gross_amount' => 10000,
    )
);

try {
  // Get Snap Payment Page URL
  $paymentUrl = \Midtrans\Snap::createTransaction($params)->redirect_url;
  
  // Redirect to Snap Payment Page
  header('Location: ' . $paymentUrl);
}
catch (Exception $e) {
  echo $e->getMessage();
}

$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'            => "[email protected]",
    '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,
        'authentication'=> true,
//        'bank'          => 'bni', // optional to set acquiring bank
//        'save_token_id' => true   // optional for one/two clicks feature
    ),
    'transaction_details' => $transaction_details,
    'item_details'        => $items,
    'customer_details'    => $customer_details
);

$response = \Midtrans\CoreApi::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>";
}

$notif = new \Midtrans\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 = \Midtrans\Transaction::status($orderId);
var_dump($status);

$approve = \Midtrans\Transaction::approve($orderId);
var_dump($approve);

$cancel = \Midtrans\Transaction::cancel($orderId);
var_dump($cancel);

$cancel = \Midtrans\Transaction::cancel($orderId);
var_dump($cancel);

$params = array(
    'refund_key' => 'order1-ref1',
    'amount' => 10000,
    'reason' => 'Item out of stock'
);
$refund = \Midtrans\Transaction::refund($orderId, $params);
var_dump($refund);

$params = array(
    'refund_key' => 'order1-ref1',
    'amount' => 10000,
    'reason' => 'Item out of stock'
);
$direct_refund = \Midtrans\Transaction::refundDirect($orderId, $params);
var_dump($direct_refund);

//These config value are based on the header stated here https://docs.midtrans.com/reference/getting-started-1
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
\SnapBi\Config::$isProduction = false;
// Set your client id. Merchant’s client ID that will be given by Midtrans, will be used as X-CLIENT-KEY on request’s header in B2B Access Token API.
\SnapBi\Config::$snapBiClientId = "YOUR CLIENT ID";
// Set your private key here, make sure to add \n on the private key, you can refer to the examples
\SnapBi\Config::$snapBiPrivateKey = "YOUR PRIVATE KEY";
// Set your client secret. Merchant’s secret key that will be given by Midtrans, will be used for symmetric signature generation for Transactional API’s header.
\SnapBi\Config::$snapBiClientSecret = "YOUR CLIENT SECRET";
// Set your partner id. Merchant’s partner ID that will be given by Midtrans, will be used as X-PARTNER-ID on Transactional API’s header.
\SnapBi\Config::$snapBiPartnerId = "YOUR PARTNER ID";
// Set the channel id here.
\SnapBi\Config::$snapBiChannelId = "CHANNEL ID";
// Enable logging to see details of the request/response make sure to disable this on production, the default is disabled.
\SnapBi\Config::$enableLogging = false;
// Set your public key here if you want to verify your webhook notification, make sure to add \n on the public key, you can refer to the examples
\SnapBi\Config::$snapBiPublicKey = "YOUR PUBLIC KEY"

   
date_default_timezone_set('Asia/Jakarta');
$time_stamp = date("c");
$date = new DateTime($time_stamp);
$external_id = "uzi-order-testing" . uniqid();
// Add 10 minutes validity time
$date->modify('+10 minutes');
// Format the new date
$valid_until = $date->format('c');
$merchant_id = "M001234";


//create direct debit request body/ payload
//you can change the payment method on the `payOptionDetails`
$debitParams = array(
    "partnerReferenceNo" => $external_id,
    "chargeToken" => "",
    "merchantId" => $merchant_id,
    "urlParam" => array(
        array(
            "url" => "https://www.google.com",
            "type" => "PAY_RETURN",
            "isDeeplink" => "Y"
        )
    ),
    "validUpTo" => $valid_until,
    "payOptionDetails" => array(
        array(
            "payMethod" => "DANA",
            "payOption" => "DANA",
            "transAmount" => array(
                "value" => "100.0",
                "currency" => "IDR" //currently we only support `IDR`
            )
        )
    ),
    "additionalInfo" => array(
        "customerDetails" => array(
            "phone" => "081122334455",
            "firstName" => "Andri",
            "lastName" => "Litani",
            "email" => "[email protected]",
            "billingAddress" => array(
                "firstName" => "Andri",
                "lastName" => "Litani",
                "phone" => "081122334455",
                "address" => "billingAddress",
                "city" => "billingCity",
                "postalCode" => "12790",
                "countryCode" => "CZH"
            ),
            "shippingAddress" => array(
                "firstName" => "Andri",
                "lastName" => "Litani",
                "phone" => "081122334455",
                "address" => "shippingAddress",
                "city" => "shippingCity",
                "postalCode" => "12790",
                "countryCode" => "CZH"
            )
        ),
        "items" => array(
            array(
                "id" => "1",
                "price" => array(
                    "value" => "100.00",
                    "currency" => "IDR"
                ),
                "quantity" => 1,
                "name" => "Apple",
                "brand" => "Apple",
                "category" => "Subscription",
                "merchantName" => "amazon prime",
                "url" => "itemUrl"
            )
        ),
        "metadata" => array()
    )
);
/**
 *  Basic example
 * to change the payment method, you can change the value of the request body on the `payOptionDetails`
 * the `currency` value that we support for now is only `IDR`
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($debitParams)
    ->createPayment($external_id);


$external_id = "uzi-order-testing" . uniqid();
$customerVaNo = "6280123456";
$merchant_id = "M001234";

$vaParams = array(
    "partnerServiceId"=> "   70012",
    "customerNo"=> $customerVaNo,
    "virtualAccountNo"=> "   70012" . $customerVaNo,
    "virtualAccountName"=> "Jokul Doe",
    "virtualAccountEmail"=> "[email protected]",
    "virtualAccountPhone"=> "6281828384858",
    "trxId"=> $external_id,
    "totalAmount"=> [
        "value"=> "10000.00",
        "currency"=> "IDR"
    ],
    "additionalInfo"=> [
        "merchantId"=> $merchant_id,
        "bank"=> "mandiri",
        "flags"=> [
            "shouldRandomizeVaNumber"=> false
        ],
        "mandiri"=> [
            "billInfo1"=> "bank_name",
            "billInfo2"=> "mandiri",
            "billInfo3"=> "Name:",
            "billInfo4"=> "Budi Utomo",
            "billInfo5"=> "Class:",
            "billInfo6"=> "Computer Science",
            "billInfo7"=> "ID:",
            "billInfo8"=> "VT-12345"
        ],
        "customerDetails"=> [
            "firstName"=> "Jokul",
            "lastName"=> "Doe",
            "email"=> "[email protected]",
            "phone"=> "+6281828384858",
            "billingAddress"=> [
                "firstName"=> "Jukul",
                "lastName"=> "Doe",
                "address"=> "Kalibata",
                "city"=> "Jakarta",
                "postalCode"=> "12190",
                "phone"=> "+6281828384858",
                "countryCode"=> "IDN"
            ],
            "shippingAddress"=> [
                "firstName"=> "Jukul",
                "lastName"=> "Doe",
                "address"=> "Kalibata",
                "city"=> "Jakarta",
                "postalCode"=> "12190",
                "phone"=> "+6281828384858",
                "countryCode"=> "IDN"
            ]
        ],
        "customField"=> [
            "1"=> "custom-field-1",
            "2"=> "custom-field-2",
            "3"=> "custom-field-3"
        ],
        "items"=> [
            [
                "id"=> "a1",
                "price"=> [
                    "value"=> "1000.00",
                    "currency"=> "IDR"
                ],
                "quantity"=> 3,
                "name"=> "Apel",
                "brand"=> "Fuji Apple",
                "category"=> "Fruit",
                "merchantName"=> "Fruit-store"

            ],
            [
                "id"=> "a2",
                "price"=> [
                    "value"=> "1000.00",
                    "currency"=> "IDR"
                ],
                "quantity"=> 7,
                "name"=> "Apel Malang",
                "brand"=> "Fuji Apple",
                "category"=> "Fruit",
                "merchantName"=> "Fruit-store"
            ]
        ]
    ]
);

/**
 * basic implementation to create payment using va
 */
$snapBiResponse = SnapBi::va()
    ->withBody($vaParams)
    ->createPayment($external_id);

$external_id = "uzi-order-testing" . uniqid();
$merchant_id = "M001234";
$qrisBody = array(
    "partnerReferenceNo" => $external_id,
    "amount" => array(
        "value" => "1500.00",
        "currency" => "IDR"
    ),
    "merchantId" => $merchant_id,
    "validityPeriod" => "2030-07-03T12:08:56-07:00",
    "additionalInfo" => array(
        "acquirer" => "gopay",
        "items" => array(
            array(
                "id" => "8143fc4f-ec05-4c55-92fb-620c212f401e",
                "price" => array(
                    "value" => "1500.00",
                    "currency" => "IDR"
                ),
                "quantity" => 1,
                "name" => "test item name",
                "brand" => "test item brand",
                "category" => "test item category",
                "merchantName" => "Merchant Operation"
            )
        ),
        "customerDetails" => array(
            "email" => "[email protected]",
            "firstName" => "Merchant",
            "lastName" => "Operation",
            "phone" => "+6281932358123"
        ),
        "countryCode" => "ID",
        "locale" => "id_ID"
    )
);

/**
 * basic implementation to create payment using Qris
 */
$snapBiResponse = SnapBi::qris()
        ->withBody($qrisBody)
        ->createPayment($external_id);

$merchant_id = "M001234";
$external_id = "uzi-order-testing" . uniqid();

$directDebitStatusByExternalIdBody = array(
    "originalExternalId" => "uzi-order-testing66ce90ce90ee5",
    "originalPartnerReferenceNo" => "uzi-order-testing66ce90ce90ee5",
    "serviceCode" => "54",
);

$directDebitStatusByReferenceBody = array(
    "originalReferenceNo" => "A1202408280618283vcBaAmf7RID",
    "serviceCode" => "54",
);

$vaStatusBody = array(
    "partnerServiceId" => "    5818",
    "customerNo" => "628064192914",
    "virtualAccountNo" => "    5818628064192914",
    "inquiryRequestId" => "uzi-order-testing66dc4799e4af5",
    "paymentRequestId" => "uzi-order-testing66dc4799e4af5",
    "additionalInfo" => array(
        "merchantId" => $merchant_id
    )
);

$qrisStatusBody = array(
    "originalReferenceNo" => "A120240910100828anKJlXgsi6ID",
    "originalPartnerReferenceNo" => "uzi-order-testing66e01a9b8c6bf",
    "merchantId" => $merchant_id,
    "serviceCode" => "54"
);

/**
 * Example code for Direct Debit getStatus using externalId
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($statusByExternalId)
    ->getStatus($external_id);

/**
 * Example code for Direct Debit getStatus using referenceNo
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($statusByReference)
    ->getStatus($external_id);
    
/**
 * Example code for VA (Bank Transfer) getStatus
 */
$snapBiResponse = SnapBi::va()
    ->withBody($vaStatusBody)
    ->getStatus($external_id);
    /**
 * 
 * Example code for Qris getStatus
 */
$snapBiResponse = SnapBi::qris()
    ->withBody($qrisStatusBody)
    ->getStatus($external_id);      


$merchant_id = "M001234";
$external_id = "uzi-order-testing" . uniqid();

$directDebitCancelByReferenceBody = array(
    "originalReferenceNo" => "A120240902104935GBqSQK0gtQID"
);
        
$directDebitCancelByExternalIdBody = array(
    "originalExternalId" => "uzi-order-testing66d5983eabc71"
);

$vaCancelBody = array(
    "partnerServiceId" => "    5818",
    "customerNo" => "628014506680",
    "virtualAccountNo" => "    5818628014506680",
    "trxId" => "uzi-order-testing66dc76754bf1c",
    "additionalInfo" => array(
        "merchantId" => $merchant_id
    )
);

$qrisCancelBody = array(
    "originalReferenceNo" => "A120240910091847fYkCqhCH1XID",
    "merchantId" => $merchant_id,
    "reason" => "cancel reason",
);
/**
 * Basic implementation to cancel transaction using referenceNo
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($directDebitCancelByReferenceBody)
    ->cancel($external_id);

/**
 * Basic implementation to cancel transaction using externalId
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($directDebitCancelByExternalIdBody)
    ->cancel($external_id);

/**
 * Basic implementation of VA (Bank Transfer) to cancel transaction
 */
$snapBiResponse = SnapBi::va()
    ->withBody($vaCancelBody)
    ->cancel($external_id);

/**
 * Basic implementation of Qris to cancel transaction
 */
$snapBiResponse = SnapBi::qris()
    ->withBody($qrisCancelBody)
    ->cancel($external_id);

$merchant_id = "M001234";
$external_id = "uzi-order-testing" . uniqid();

$directDebitRefundByExternalIdBody = array(
    "originalExternalId" => "uzi-order-testing66cec41c7f905",
    "partnerRefundNo" =>  "uzi-order-testing66cec41c7f905" . "refund-0001".rand(),
    "reason" => "some-reason",
    "additionalInfo" => array(),
    "refundAmount" => array(
        "value" => "100.00",
        "currency" => "IDR"
    ));

$directDebitRefundByReferenceBody = array(
    "originalReferenceNo" => "A120240828062651Y0NQMbJkDOID",
    "reason" => "some-reason",
    "additionalInfo" => array(),
    "refundAmount" => array(
        "value" => "100.00",
        "currency" => "IDR"
    ));
    
$qrisRefundBody = array(
    "merchantId" => $merchant_id,
    "originalPartnerReferenceNo" => "uzi-order-testing66e01a9b8c6bf",
    "originalReferenceNo" => "A120240910100828anKJlXgsi6ID",
    "partnerRefundNo" => "partner-refund-no-". uniqid(),
    "reason" => "refund reason",
    "refundAmount" => array(
        "value" => "1500.00",
        "currency" => "IDR"
    ),
    "additionalInfo" => array(
        "foo" => "bar"
    )
);
/**
 * Example code for refund using externalId
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($directDebitRefundByExternalIdBody)
    ->refund($external_id);

/**
 * Example code for refund using reference no
 */
$snapBiResponse = SnapBi::directDebit()
    ->withBody($directDebitRefundByReferenceBody)
    ->refund($external_id);
    
    /**
 * Example code for refund using Qris
 */
$snapBiResponse = SnapBi::qris()
    ->withBody($qrisRefundBody)
    ->refund($external_id);


 /**
 * Example code for Direct Debit refund using additional header
 */
$snapBiResponse = SnapBi::directDebit()
    ->withAccessTokenHeader([
        "debug-id"=> "va debug id",
        "X-DEVICE-ID"=>"va device id"
    ])
    ->withTransactionHeader([
        "debug-id"=> "va debug id",
        "X-DEVICE-ID"=>"va device id"
    ])
    ->withBody($directDebitRefundByExternalIdBody)
    ->refund($external_id);
/**
 * Example code for using additional header on creating payment using VA
 */
$snapBiResponse = SnapBi::va()
    ->withAccessTokenHeader([
        "debug-id"=> "va debug id",
        "X-DEVICE-ID"=>"va device id"
    ])
    ->withTransactionHeader([
        "debug-id"=> "va debug id",
        "X-DEVICE-ID"=>"va device id"
    ])
    ->withBody($vaParams)
    ->createPayment($external_id);

/**
 * Example reusing your existing accessToken by using ->withAccessToken
 */
$snapBiResponse = SnapBi::va()
    ->withAccessToken("your-access-token")
    ->withBody($vaParams)
    ->createPayment($external_id);


 
//the request body/ payload sent by the webhook
 $payload = json_decode(
 {
    "originalPartnerReferenceNo": "uzi-order-testing67039fa9da813",
    "originalReferenceNo": "A120241007084530GSXji4Q5OdID",
    "merchantId": "G653420184",
    "amount": {
        "value": "10000.00",
        "currency": "IDR"
    },
    "latestTransactionStatus": "03",
    "transactionStatusDesc": "PENDING",
    "additionalInfo": {
        "refundHistory": [],
        "userPaymentDetails": []
    }
};

// to get the signature value, you need to retrieve it from the webhook header called X-Signature
$xSignature = "CgjmAyC9OZ3pB2JhBRDihL939kS86LjP1VLD1R7LgI4JkvYvskUQrPXgjhrZqU2SFkfPmLtSbcEUw21pg2nItQ0KoX582Y6Tqg4Mn45BQbxo4LTPzkZwclD4WI+aCYePQtUrXpJSTM8D32lSJQQndlloJfzoD6Rh24lNb+zjUpc+YEi4vMM6MBmS26PpCm/7FZ7/OgsVh9rlSNUsuQ/1QFpldA0F8bBNWSW4trwv9bE1NFDzliHrRAnQXrT/J3chOg5qqH0+s3E6v/W21hIrBYZVDTppyJPtTOoCWeuT1Tk9XI2HhSDiSuI3pevzLL8FLEWY/G4M5zkjm/9056LTDw==";

// to get the timeStamp value, you need to retrieve it from the webhook header called X-Timestamp
$xTimeStamp = "2024-10-07T15:45:22+07:00";

// the url path is based on the webhook url of the payment method for example for direct debit is `/v1.0/debit/notify`
$notificationUrlPath = "/v1.0/debit/notify"
/**
 * Example verifying the webhook notification
 */
$isVerified = SnapBi::notification()
    ->withBody($payload)
    ->withSignature($xSignature)
    ->withTimeStamp($xTimeStamp)
    ->withNotificationUrlPath($notificationUrlPath)
    ->isWebhookNotificationVerified()


composer 
json
{
    "idtrans/midtrans-php": "2.*"
    }
}
javascript
MidtransNew3ds.clientKey = "<your client key>";