veritrans / veritrans-php
PHP Wraper for Veritrans VT-Web Payment API.
Installs: 293 757
Dependents: 3
Suggesters: 0
Security: 0
Stars: 93
Watchers: 43
Forks: 85
Open Issues: 1
Requires
- php: >=5.4
Requires (Dev)
- phpunit/phpunit: 5.7.*
- psy/psysh: 0.4.*
This package is not auto-updated.
Last update: 2024-10-23 12:10:32 UTC
README
⚠️⚠️ ANNOUNCEMENT ⚠️⚠️
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.
🔈 END OF ANNOUNCEMENT 🔈
Veritrans-PHP
Midtrans ❤️ 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.
1. Installation
1.a Composer Installation
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.
1.b Manual Instalation
If you are not using Composer, you can clone or download this repository.
2. How to Use
2.1 General Settings
// 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;
2.2 Choose Product/Method
We have 3 different products of payment that you can use:
- Snap - Customizable payment popup will appear on your web/app (no redirection). doc ref
- Snap Redirect - Customer need to be redirected to payment url hosted by midtrans. doc ref
- Core API (VT-Direct) - Basic backend implementation, you can customize the frontend embedded on your web/app as you like (no redirection). doc ref
Choose one that you think best for your unique needs.
2.2.a Snap
You can see Snap example here.
Get Snap Token
$params = array( 'transaction_details' => array( 'order_id' => rand(), 'gross_amount' => 10000, ) ); $snapToken = Veritrans_Snap::getSnapToken($params);
Get Snap Token in Yii2
//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]; }
Initialize Snap JS when customer click pay button
<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>
Implement Notification Handler
2.2.b VT-Web
!!! 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.
Get Redirection URL of a Charge
$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(); }
2.2.b Snap Redirect
You can see some Snap Redirect examples here.
Get Redirection URL of a Payment Page
$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(); }
Implement Notification Handler
2.2.c Core API (VT-Direct)
You can see some Core API examples here.
Set Client Key
Veritrans.client_key = "<your client key>";
Checkout Page
Please refer to this file
Checkout Process
1. Create Transaction Details
$transaction_details = array( 'order_id' => time(), 'gross_amount' => 200000 );
2. Create Item Details, Billing Address, Shipping Address, and Customer Details (Optional)
// 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 );
3. Get Token ID from Checkout Page
// Token ID from checkout page $token_id = $_POST['token_id'];
4. Create Transaction Data
// 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 );
5. Charge
$response = Veritrans_VtDirect::charge($transaction_data);
6. Handle Transaction Status
// 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>"; }
7. Implement Notification Handler
2.3 Handle HTTP Notification
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' } }
2.4 Process Transaction
Get Transaction Status
$status = Veritrans_Transaction::status($orderId); var_dump($status);
Approve Transaction
If transaction fraud_status == CHALLENGE, you can approve the transaction from Merchant Dashboard, or API :
$approve = Veritrans_Transaction::approve($orderId); var_dump($approve);
Cancel Transaction
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);
Expire Transaction
You can Expire transaction with transaction_status == PENDING
(before it become SETTLEMENT or EXPIRE)
$cancel = Veritrans_Transaction::cancel($orderId); var_dump($cancel);
Contributing
Developing e-commerce plug-ins
There are several guides that must be taken care of when you develop new plugins.
-
Handling currency other than IDR. Veritrans
v1
andv2
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.