firmantr3/laravel-midtrans

Laravel 的 Midtrans 支付 API 包装器。

1.0.9 2020-07-16 09:23 UTC

This package is auto-updated.

Last update: 2024-09-16 18:58:30 UTC


README

Midtrans-PHP 库包装,适用于 Laravel。

功能

  • Laravel 5/6 集成。
  • 所有 Midtrans 服务的 Facade:Snap、VT-Direct。使用更方便,并创建测试的模拟。

安装

composer require firmantr3/laravel-midtrans

Laravel <= 5.4

将以下内容添加到您的 config/app.php 文件中的 Providers 部分数组中

<?php
return [
    'providers': [
        // Other Providers above
        Firmantr3\Midtrans\Providers\MidtransServiceProvider::class,
    ],
];

Laravel 5.5+ / 6

通过包发现自动添加。

发布配置

运行 artisan vendor:publish 命令发布迁移

php artisan vendor:publish --provider=Firmantr3\\Midtrans\\Providers\\MidtransServiceProvider

配置

更新您的 Laravel Midtrans 配置:/config/midtrans.php 或将其追加到您的 .env 文件中

MIDTRANS_SERVER_KEY="My Midtrans Server Key"
MIDTRANS_CLIENT_KEY="My Midtrans Client Kye"
MIDTRANS_ENV=development
MIDTRANS_SANITIZE=true
MIDTRANS_3DS=false

如果您想使用 Facade,请将其添加到您的 /config/app.php 文件中的 Facades 中

'Midtrans' => Firmantr3\Midtrans\Facade\Midtrans::class,

用法

使用提供的 Facade Firmantr3\Midtrans\Facade\Midtrans::snapOrVtDirectMethods()app('midtrans')->snapOrVtDirectMethods(),但您也可以直接使用官方类。

官方文档可在此处找到 这里

SNAP 示例

获取 Snap 令牌

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

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

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

Snap 重定向

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller

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

try {
  // Get Snap Payment Page URL
  $paymentRedirectUrl = Midtrans::createTransaction($params)->redirect_url;
  
  // Redirect to Snap Payment Page
  return redirect($paymentRedirectUrl);
}
catch (Exception $e) {
  echo $e->getMessage();
}

核心 API (VT-Direct)

获取前端客户端密钥

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

$clientKey = Midtrans::clientKey();

后端完整示例

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller

// 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
);

// Create transaction summary
$transaction_details = array(
    'order_id'    => time(),
    'gross_amount'  => 200000
);

// Token ID from checkout page
$token_id = app('request')->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
);

// do charge
$response = Midtrans::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>";
}

处理传入通知(Web Hook)

为处理来自 Midtrans 的传入通知更新设置您自己的路由和控制器,然后

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller

$notification = Midtrans::notification();
/**
* $notificationArray = $notification->toArray();
* $notificationObject = $notification->toObject();
**/

$transaction = $notification->transaction_status;
$fraud = $notification->fraud_status;

error_log("Order ID $notification->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'
}

处理交易

获取交易状态

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller
$status = Midtrans::status($orderId);
var_dump($status);

批准交易

如果交易 fraud_status == CHALLENGE,您可以从商家仪表板或 API 中批准交易

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller
$approve = Midtrans::approve($orderId);
var_dump($approve);

取消交易

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

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller
$cancel = Midtrans::cancel($orderId);
var_dump($cancel);

过期交易

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

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

// somewhere in your controller
$cancel = Midtrans::cancel($orderId);
var_dump($cancel);

VT 代表什么

如果您像我一样好奇 VT 是什么,答案是:Midtrans 的前身为 Veritrans ;)

测试

Mocking Midtrans 示例

<?php

use Firmantr3\Midtrans\Facade\Midtrans;

Midtrans::shouldReceive('getSnapToken')
    ->once()
    ->with(['parameters'])
    ->andReturn('My Token');

$myToken = Midtrans::getSnapToken(['parameters'])); // returns "My Token"

官方 Laravel 文档: https://laravel.net.cn/docs/5.8/mocking#mocking-facades

更好的自动完成

如果您需要更好的 IDE Facade 自动完成,您可以通过 Barry 安装此良好的包: Laravel IDE Helper Generator

运行测试

vendor/bin/phpunit