๐Ÿ” Latar Belakang

Saat mengintegrasikan Midtrans Snap menggunakan PHP Native di Fedora 41 dengan LEMP stack (Linux, Nginx, MySQL, PHP), saya mengalami error berikut:

Curl error: Failed to connect to app.sandbox.midtrans.com port 443

Padahal, ketika saya mengetes dengan curl langsung dari terminal, koneksi ke https://app.sandbox.midtrans.com berhasil.

Setelah investigasi cukup panjang, berikut adalah ringkasan penyebab dan solusinya yang semoga bisa membantu developer lain yang mengalami hal serupa.


๐Ÿšจ Masalah

โŒ CURL error dari PHP, tapi sukses dari terminal

  • curl via terminal: โœ… berhasil konek ke app.sandbox.midtrans.com
  • curl via PHP (php-fpm): โŒ gagal koneksi ke port 443

Penyebab utama:

Fedora 41 menggunakan SELinux dalam mode Enforcing, yang secara default memblokir php-fpm melakukan koneksi keluar, termasuk ke API Midtrans.


๐Ÿ› ๏ธ Solusi

โœ… 1. Matikan SELinux Sementara

sudo setenforce 0

โœ… 2. Tes kembali dengan PHP

Buat file test-curl.php:

<?php
$ch = curl_init("https://google.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);

if (curl_errno($ch)) {
  echo "CURL ERROR: " . curl_error($ch);
} else {
  echo "CURL SUKSES";
}
curl_close($ch);
?>

Akses via browser: http://localhost/test-curl.php

Jika muncul CURL SUKSES, berarti SELinux memang penyebabnya.

โœ… 3. Solusi Permanen: Ubah Mode SELinux

Edit file:

sudo nano /etc/selinux/config

Ubah menjadi:

SELINUX=permissive

Lalu reboot:

sudo reboot

๐Ÿงฉ Perbaikan File callback.php

Midtrans mengirim notifikasi via POST JSON ke callback.php. File awal saya salah karena hanya membaca dari $_GET. Berikut versi perbaikannya:

<?php
$json = file_get_contents("php://input");
$data = json_decode($json);

// Logging untuk debug
file_put_contents("midtrans-callback.log", $json . PHP_EOL, FILE_APPEND);

// Validasi
if (!$data || !$data->order_id) {
  http_response_code(400);
  exit("Invalid callback");
}

$order_id           = $data->order_id;
$status_code        = $data->status_code ?? '';
$transaction_status = $data->transaction_status ?? '';

// Mapping status
$status = ($transaction_status === 'settlement' || $transaction_status === 'capture') ? '2' :
          ($transaction_status === 'pending' ? '1' : '0');

// Update database via fungsi sendiri
$update = UpdatePaymentStatus([
  "status" => Escape($status),
  "status_code" => Escape($status_code),
  "transaction_status" => Escape($transaction_status),
  "tanggal_update" => date("Y-m-d H:i:s"),
  "order_code" => Escape($order_id),
]);

http_response_code($update ? 200 : 500);
echo $update ? "OK" : "Failed to update";

๐Ÿงช Testing Callback di Localhost

Untuk bisa menerima notifikasi di lokal, gunakan ngrok:

ngrok http 80

Set di Midtrans Dashboard:

Notification URL = http://<ngrok-url>/callback.php

โœ๏ธ Penutup

Integrasi payment gateway seperti Midtrans memang kadang menantang, terutama di environment seperti Fedora yang mengaktifkan SELinux secara default. Namun, dengan pendekatan sistematis, kita bisa mengidentifikasi masalah dan menerapkan solusi permanen.

Semoga sharing ini bermanfaat untuk kamu yang sedang membangun sistem pembayaran sendiri.