Tài liệu / Tích hợp/ Tích hợp Laravel

Tích hợp Laravel

Tích hợp Cập nhật: 22/03/2026

Tích hợp ThueAPI.VN vào Laravel

Hướng dẫn đầy đủ tích hợp webhook ThueAPI vào ứng dụng Laravel với queue processing và lưu database.

1. Cấu hình

# Thêm vào .env
THUEAPI_KEY=your_api_key_here
THUEAPI_WEBHOOK_SECRET=your_webhook_secret_here
THUEAPI_BASE_URL=https://thueapi.vn/api/v1
// config/services.php
'thueapi' => [
    'key'            => env('THUEAPI_KEY'),
    'webhook_secret' => env('THUEAPI_WEBHOOK_SECRET'),
    'base_url'       => env('THUEAPI_BASE_URL', 'https://thueapi.vn/api/v1'),
],

2. Migration

// database/migrations/xxxx_create_bank_transactions_table.php
Schema::create('bank_transactions', function (Blueprint $table) {
    $table->id();
    $table->string('transaction_number')->unique();
    $table->string('gateway', 20);
    $table->string('account_number', 50);
    $table->enum('transfer_type', ['IN', 'OUT']);
    $table->unsignedBigInteger('transfer_amount');
    $table->text('content');
    $table->timestamp('transaction_date');
    $table->timestamps();
    $table->index(['account_number', 'transfer_type']);
    $table->index('transaction_date');
});

3. Model

// app/Models/BankTransaction.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class BankTransaction extends Model
{
    protected $fillable = [
        'transaction_number', 'gateway', 'account_number',
        'transfer_type', 'transfer_amount', 'content', 'transaction_date',
    ];

    protected $casts = [
        'transaction_date' => 'datetime',
        'transfer_amount'  => 'integer',
    ];
}

4. Route

// routes/api.php
// Bỏ qua CSRF cho webhook endpoint
Route::post('/webhook/thueapi', [ThueApiWebhookController::class, 'handle'])
     ->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);

5. Controller

// app/Http/Controllers/ThueApiWebhookController.php
namespace App\Http\Controllers;

use App\Jobs\ProcessBankTransaction;
use App\Models\BankTransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class ThueApiWebhookController extends Controller
{
    public function handle(Request $request)
    {
        // Xác thực chữ ký HMAC
        $secret    = config('services.thueapi.webhook_secret');
        $payload   = $request->getContent();
        $signature = $request->header('X-Webhook-Signature', '');
        $expected  = hash_hmac('sha256', $payload, $secret);

        if (!hash_equals($expected, $signature)) {
            Log::warning('ThueAPI webhook: chữ ký không hợp lệ', [
                'ip' => $request->ip(),
            ]);
            return response()->json(['error' => 'Invalid signature'], 401);
        }

        // Đưa vào queue để xử lý bất đồng bộ
        foreach ($request->input('transactions', []) as $tx) {
            // Kiểm tra trùng trước khi dispatch
            if (!BankTransaction::where('transaction_number', $tx['transactionNumber'])->exists()) {
                ProcessBankTransaction::dispatch($tx);
            }
        }

        return response()->json(['success' => true]);
    }
}

6. Job xử lý bất đồng bộ

// app/Jobs/ProcessBankTransaction.php
namespace App\Jobs;

use App\Models\BankTransaction;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class ProcessBankTransaction implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries   = 3;
    public int $timeout = 60;

    public function __construct(private array $transaction) {}

    public function handle(): void
    {
        $tx = $this->transaction;

        // Lưu vào database (INSERT IGNORE để tránh duplicate)
        BankTransaction::firstOrCreate(
            ['transaction_number' => $tx['transactionNumber']],
            [
                'gateway'          => $tx['gateway'],
                'account_number'   => $tx['accountNumber'],
                'transfer_type'    => $tx['transferType'],
                'transfer_amount'  => $tx['transferAmount'],
                'content'          => $tx['content'],
                'transaction_date' => $tx['transactionDate'],
            ]
        );

        Log::info('ThueAPI: giao dịch đã lưu', [
            'number' => $tx['transactionNumber'],
            'type'   => $tx['transferType'],
            'amount' => $tx['transferAmount'],
        ]);

        // TODO: Thêm business logic tại đây
        // - Cập nhật trạng thái đơn hàng
        // - Gửi email xác nhận
        // - Tích điểm khách hàng
    }
}
ThueAPI.VN
Đăng nhập với Google
hoặc đăng nhập bằng email
Quên mật khẩu?

Chưa có tài khoản?

Đăng ký với Google
hoặc đăng ký bằng email

Bằng cách đăng ký, bạn đồng ý với Điều khoản dịch vụChính sách bảo mật của chúng tôi.

Đã có tài khoản?