liharsw / midtrans-php
Midtrans支付API的PHP包装器。
Requires
- php: >=5.4
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: 5.7.*
- psy/psysh: 0.4.*
This package is auto-updated.
Last update: 2024-09-19 19:48:10 UTC
README
Midtrans ❤️ PHP!
这是Midtrans支付API的官方PHP包装器/库,兼容Composer。访问https://midtrans.com获取更多产品信息,并在http://docs.midtrans.com查看更多技术细节。
1. 安装
1.a Composer安装
如果您使用Composer,您可以通过composer CLI进行安装
composer require liharsw/midtrans-php
或者
将此require行添加到您的composer.json文件中
{
"require": {
"midtrans/midtrans-php": "2.*"
}
}
然后在您的终端上运行composer install。
注意:如果您使用Laravel框架,在某些情况下,您还需要运行
composer dumpautoload
/Midtrans将随后在您的Laravel项目中可用(自动加载)。
1.b 手动安装
如果您不使用Composer,您可以克隆或下载此存储库。
然后您应该在您的代码中引入autoload Midtrans.php文件。
require_once dirname(__FILE__) . '/pathofproject/Midtrans.php'; // my code goes here
2. 使用方法
2.1 通用设置
// 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;
覆盖通知URL
您可以选择在每个交易中更改或添加自定义通知URL。这可以通过在请求中加入额外的HTTP头部来实现。
// 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";
注意:当同时使用
appendNotifUrl和overrideNotifUrl时,则只使用overrideNotifUrl。
这两个头部只能接收最多3个URL。
Idempotency-Key
您可以在交易中添加idempotency key。这可以通过在请求中加入额外的HTTP头部来实现。这是一个唯一的值,用于API请求的头部。Midtrans API接受Idempotency-Key头部以安全地处理重试请求,避免执行相同的操作两次。这在商户因为网络问题或其他意外错误没有收到响应时非常有用。
Config::$paymentIdempotencyKey = "Unique-ID";
2.2 选择产品/方法
我们有3种不同的支付产品可供使用
- Snap - 可定制的支付弹出窗口将出现在您的网站/应用程序上(无重定向)。文档参考
- Snap Redirect - 客户需要重定向到由Midtrans托管的支付URL。文档参考
- Core API (VT-Direct) - 基本的后端实现,您可以自定义在前端嵌入到您的网站/应用程序中(无重定向)。文档参考
选择最适合您独特需求的一个。
2.2.a Snap
您可以在这里看到Snap示例。
获取Snap令牌
$params = array( 'transaction_details' => array( 'order_id' => rand(), 'gross_amount' => 10000, ) ); $snapToken = \Midtrans\Snap::getSnapToken($params);
当客户点击支付按钮时初始化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 Snap Redirect
您可以在这里查看一些Snap Redirect的示例。
获取支付页面的重定向URL
$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(); }
实现通知处理器
2.2.c 核心API (VT-Direct)
您可以在这里查看一些核心API的示例。
设置客户端密钥
MidtransNew3ds.clientKey = "<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. 从结账页面获取Token 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, '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 );
5. 充值
$response = \Midtrans\CoreApi::charge($transaction_data);
6. 信用卡3DS身份验证
信用卡充值结果可能包含用于3DS身份验证的redirect_url。3DS身份验证应在前端处理,请参阅API文档
有关信用卡3DS交易的完整示例,请参阅
7. 处理交易状态
// 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>"; }
8. 实现通知处理程序
2.3 处理HTTP通知
创建单独的Web端点(通知URL)以接收HTTP POST通知回调/钩子。每当交易状态改变时,都会发送HTTP通知。示例也在这里提供
$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' }
2.4 处理交易
获取交易状态
$status = \Midtrans\Transaction::status($orderId); var_dump($status);
批准交易
如果交易欺诈状态==挑战,您可以从商户仪表板或API批准交易
$approve = \Midtrans\Transaction::approve($orderId); var_dump($approve);
取消交易
您可以通过fraud_status == CHALLENGE取消交易,或通过transaction_status == CAPTURE(在它成为SETTLEMENT之前)取消信用卡交易
$cancel = \Midtrans\Transaction::cancel($orderId); var_dump($cancel);
过期交易
您可以通过transaction_status == PENDING(在它成为SETTLEMENT或EXPIRE之前)取消交易
$cancel = \Midtrans\Transaction::cancel($orderId); var_dump($cancel);
退款交易
退款交易(并非所有支付渠道都允许通过API进行退款)您可以通过transaction_status == settlement退款交易
$params = array( 'refund_key' => 'order1-ref1', 'amount' => 10000, 'reason' => 'Item out of stock' ); $refund = \Midtrans\Transaction::refund($orderId, $params); var_dump($refund);
直接退款交易
通过直接退款API退款交易您可以通过transaction_status == settlement退款交易
$params = array( 'refund_key' => 'order1-ref1', 'amount' => 10000, 'reason' => 'Item out of stock' ); $direct_refund = \Midtrans\Transaction::refundDirect($orderId, $params); var_dump($direct_refund);
单元测试
集成测试(沙盒真实交易)
请将phpunit.xml中的服务器密钥和客户端密钥更改为您自己的。
所有测试
vendor/bin/phpunit
特定测试
vendor/bin/phpunit tests/integration/CoreApiIntegrationTest.php
贡献
开发电子商务插件
在开发新插件时,必须注意以下几项指南。
-
处理除IDR以外的货币。 Midtrans
v1和v2目前只接受印尼盾的支付。作为一个推论,服务器上有验证来检查商品价格是否为整数。尽管您可能想四舍五入价格,但请不要这样做!当您的系统使用IDR以外的货币时,请相应地将其转换为IDR,然后在四舍五入价格。 -
考虑使用自动清理功能。