veritrans/veritrans-php

Veritrans VT-Web 支付 API 的 PHP 封装。

1.2.0 2018-04-26 10:03 UTC

README

⚠️⚠️ 公告 ⚠️⚠️

请使用更新版且兼容 composer 的库: Midtrans PHP。以获得更好的 composer 兼容性。

此仓库仍然存在以供归档和兼容性使用。但始终建议使用较新版本的 Midtrans PHP

🔈 公告结束 🔈

Veritrans-PHP

Build Status

Midtrans ❤️ PHP!

这是 Midtrans 支付 API 的官方 PHP 封装库。访问 https://midtrans.com 获取产品更多信息,并查阅 http://docs.midtrans.com 了解更多技术细节。

1. 安装

1.a Composer 安装

如果您使用 Composer,将以下依赖项行添加到您的 composer.json 文件中

{
	"require": {
		"veritrans/veritrans-php": "dev-master"
	}
}

并在终端上运行 composer install

1.b 手动安装

如果您不使用 Composer,您可以通过克隆或 下载 此存储库。

2. 如何使用

2.1 通用设置

// 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 选择产品/方法

我们有 3 种不同的支付产品 可供您使用

选择最适合您独特需求的一种。

2.2.a Snap

您可以在 这里 看到Snap示例。

获取 Snap 令牌

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

$snapToken = Veritrans_Snap::getSnapToken($params);

在 Yii2 中获取 Snap 令牌

    
    //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];
  
    }

当客户点击支付按钮时初始化 Snap JS

<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>

实现通知处理器

参考本节

2.2.b VT-Web

!!! VT-Web 已弃用 !!!

请使用 Snap Redirect,它具有相同的功能,但更好。参考本节

您可以在 这里 看到一些 VT-Web 示例。

获取费用重定向 URL

$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

您可以在这里查看一些Snap Redirect的示例。

获取支付页面的重定向URL

$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();
}

实现通知处理器

参考本节

2.2.c 核心API (VT-Direct)

您可以在这里查看一些核心API的示例。

设置客户端密钥

Veritrans.client_key = "<your client key>";

结账页面

请参考此文件

结账流程

1. 创建交易详情
$transaction_details = array(
  'order_id'    => time(),
  'gross_amount'  => 200000
);
2. 创建商品详情、账单地址、收货地址和客户详情(可选)
// 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. 从结账页面获取令牌ID
// Token ID from checkout page
$token_id = $_POST['token_id'];
4. 创建交易数据
// 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. 充值
$response = Veritrans_VtDirect::charge($transaction_data);
6. 处理交易状态
// 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. 实现通知处理器

参考本节

2.3 处理HTTP通知

创建独立的网络端点(通知URL)以接收HTTP POST通知回调/钩子。每当交易状态发生变化时,都会发送HTTP通知。示例也在这里提供。

$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 处理交易

获取交易状态

$status = Veritrans_Transaction::status($orderId);
var_dump($status);

批准交易

如果交易欺诈状态为CHALLENGE,您可以从商家仪表板或API批准交易

$approve = Veritrans_Transaction::approve($orderId);
var_dump($approve);

取消交易

您可以通过fraud_status == CHALLENGE取消交易,或者通过transaction_status == CAPTURE的信用卡交易(在它成为SETTLEMENT之前)

$cancel = Veritrans_Transaction::cancel($orderId);
var_dump($cancel);

过期交易

您可以通过transaction_status == PENDING过期交易(在它成为SETTLEMENT或EXPIRE之前)

$cancel = Veritrans_Transaction::cancel($orderId);
var_dump($cancel);

贡献

开发电子商务插件

在您开发新插件时,必须注意以下几个指南。

  1. 处理除IDR以外的货币。 Veritrans v1v2 目前仅接受印尼盾的支付。作为补充,服务器上有一个验证来检查商品价格是否为整数。尽管您可能想四舍五入价格,但请不要这样做!当您的系统使用除IDR以外的货币时,始终准备相应地将它们转换为IDR,并在之后才进行价格四舍五入。

  2. 考虑使用自动清理功能。