transaksikita / php
Official PHP SDK for TransaksiKita Payment Gateway
1.0.1
2026-04-27 12:36 UTC
Requires
- php: >=8.0
- ext-curl: *
- ext-json: *
README
Official PHP SDK untuk TransaksiKita Payment Gateway — Terima pembayaran QRIS di aplikasi PHP Anda.
- Zero dependencies — hanya butuh
ext-curldanext-json(bawaan PHP) - PHP 8.0+
- Retry otomatis dengan exponential backoff
- Signature verification bawaan untuk callback
Instalasi
composer require transaksikita/php
Atau tanpa Composer, cukup require file-nya:
require_once 'path/to/transaksikita-php/src/TransaksiKitaError.php'; require_once 'path/to/transaksikita-php/src/TransaksiKita.php';
Quick Start
use TransaksiKita\TransaksiKita; $tk = new TransaksiKita([ 'projectId' => 'PROJECT_ID', 'publicKey' => 'tk_sandbox_xxxx', 'secretKey' => 'sk_sandbox_xxxx', ]); // Test koneksi $info = $tk->ping(); echo $info['projectName']; // "Toko Saya" echo $info['mode']; // "sandbox" // Buat pembayaran $payment = $tk->createPayment([ 'amount' => 50000, 'customerName' => 'Budi Santoso', 'description' => 'Pembelian Paket Premium', 'referenceId' => 'ORDER-001', 'expiredMinutes' => 60, ]); echo $payment['checkoutFullUrl']; // Redirect customer ke sini echo $payment['qrisPayload']; // Atau tampilkan QR code
Daftar API
new TransaksiKita($config)
| Parameter | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
projectId |
string |
✅ | — | Project ID dari dashboard |
publicKey |
string |
✅ | — | Public Key (tk_sandbox_xxx / tk_production_xxx) |
secretKey |
string |
✅ | — | Secret Key (sk_sandbox_xxx / sk_production_xxx) |
baseUrl |
string |
❌ | https://transaksikita.com |
Base URL API |
timeout |
int |
❌ | 30 |
Request timeout dalam detik |
maxRetries |
int |
❌ | 0 |
Jumlah retry jika gagal (max: 3) |
$tk->ping(): array
Test koneksi ke API.
$info = $tk->ping(); // ['projectId' => '...', 'projectName' => '...', 'mode' => 'sandbox', 'timestamp' => '...']
$tk->createPayment($params): array
Buat pembayaran baru.
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
amount |
int |
✅ | Nominal dalam Rupiah (min: 500) |
customerName |
string |
❌ | Nama customer |
description |
string |
❌ | Deskripsi pembayaran |
referenceId |
string |
❌ | ID referensi unik Anda |
expiredMinutes |
int |
❌ | Waktu expired (5-1440 menit) |
paymentMethod |
string |
❌ | 'QRIS' atau '' |
idempotencyKey |
string |
❌ | Cegah duplikasi |
sandbox |
bool |
❌ | Force sandbox mode |
$payment = $tk->createPayment([ 'amount' => 100000, 'customerName' => 'Budi', 'description' => 'Order #123', 'referenceId' => 'ORD-123', 'expiredMinutes' => 30, ]);
$tk->checkStatus($paymentId): array
Cek status pembayaran.
$status = $tk->checkStatus('PAY-xxxxx'); if ($status['status'] === 'paid') { echo 'Dibayar pada: ' . $status['paidAt']; echo 'Jumlah: ' . TransaksiKita::formatRupiah($status['paidAmount']); } elseif ($status['status'] === 'pending') { $remaining = floor($status['remainingMs'] / 60000); echo "Sisa waktu: {$remaining} menit"; }
$tk->cancelPayment($paymentId): array
Batalkan pembayaran (hanya status pending).
$result = $tk->cancelPayment('PAY-xxxxx'); echo $result['status']; // "cancelled"
$tk->listPayments($params): array
Daftar pembayaran dengan filter.
// 10 pembayaran terbaru $result = $tk->listPayments(['limit' => 10]); foreach ($result['data'] as $p) { echo "{$p['paymentId']}: {$p['status']}\n"; } // Filter yang sudah bayar $paid = $tk->listPayments(['status' => 'paid']); // Pagination $page2 = $tk->listPayments(['page' => 2, 'limit' => 20]); echo "Halaman {$page2['pagination']['page']} dari {$page2['pagination']['totalPages']}";
$tk->verifyCallback($payload): bool
Verifikasi callback payload (re-check ke API).
$payload = json_decode(file_get_contents('php://input'), true); $isValid = $tk->verifyCallback($payload);
$tk->verifySignature($rawBody, $signature): bool
Verifikasi HMAC-SHA256 callback signature.
$rawBody = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_CALLBACK_SIGNATURE'] ?? ''; if (!$tk->verifySignature($rawBody, $signature)) { http_response_code(401); die(json_encode(['error' => 'Invalid signature'])); }
$tk->waitForPayment($paymentId, $interval, $maxAttempts): array
Polling sampai status berubah dari pending.
$result = $tk->waitForPayment('PAY-xxxxx', 5, 60); if ($result['status'] === 'paid') { echo 'Pembayaran berhasil!'; }
TransaksiKita::formatRupiah($amount): string
TransaksiKita::formatRupiah(50000); // "Rp 50.000" TransaksiKita::formatRupiah(1500000); // "Rp 1.500.000"
Callback Handler
use TransaksiKita\TransaksiKita; use TransaksiKita\TransaksiKitaError; $tk = new TransaksiKita([ 'projectId' => $_ENV['TK_PROJECT_ID'], 'publicKey' => $_ENV['TK_PUBLIC_KEY'], 'secretKey' => $_ENV['TK_SECRET_KEY'], ]); // 1. Verifikasi signature $rawBody = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_CALLBACK_SIGNATURE'] ?? ''; if (!$tk->verifySignature($rawBody, $signature)) { http_response_code(401); die(json_encode(['error' => 'Invalid signature'])); } // 2. Parse dan verifikasi data $payload = json_decode($rawBody, true); if (!$tk->verifyCallback($payload)) { http_response_code(400); die(json_encode(['error' => 'Invalid data'])); } // 3. Proses pembayaran if ($payload['status'] === 'paid') { // Update database, kirim email konfirmasi, dll // PENTING: pastikan idempotent (cek apakah sudah diproses) } http_response_code(200); echo json_encode(['received' => true]);
Error Handling
use TransaksiKita\TransaksiKita; use TransaksiKita\TransaksiKitaError; $tk = new TransaksiKita([ 'projectId' => 'xxx', 'publicKey' => 'tk_sandbox_xxx', 'secretKey' => 'sk_sandbox_xxx', 'maxRetries' => 2, ]); try { $payment = $tk->createPayment(['amount' => 50000]); } catch (TransaksiKitaError $e) { echo "Error: {$e->getMessage()}\n"; echo "Status: {$e->getStatusCode()}\n"; echo "Detail: {$e->getDetail()}\n"; if ($e->isAuthError()) { echo 'Cek kembali API keys Anda'; } elseif ($e->isRateLimited()) { echo 'Terlalu banyak request, coba lagi nanti'; } elseif ($e->isValidationError()) { echo 'Parameter tidak valid'; } elseif ($e->isRetryable()) { echo 'Error sementara, bisa di-retry'; } }
Contoh Laravel
// routes/web.php use TransaksiKita\TransaksiKita; $tk = new TransaksiKita([ 'projectId' => config('services.transaksikita.project_id'), 'publicKey' => config('services.transaksikita.public_key'), 'secretKey' => config('services.transaksikita.secret_key'), ]); Route::post('/create-order', function (Request $request) use ($tk) { $payment = $tk->createPayment([ 'amount' => $request->amount, 'customerName' => $request->name, 'referenceId' => 'ORD-' . $request->order_id, ]); return response()->json(['checkout_url' => $payment['checkoutFullUrl']]); }); Route::post('/callback', function (Request $request) use ($tk) { $rawBody = $request->getContent(); $signature = $request->header('X-Callback-Signature', ''); if (!$tk->verifySignature($rawBody, $signature)) { return response()->json(['error' => 'Invalid'], 401); } $payload = $request->all(); if ($payload['status'] === 'paid') { // Update order... } return response()->json(['received' => true]); })->withoutMiddleware([\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class]);
Environment Variables
$tk = new TransaksiKita([ 'projectId' => $_ENV['TK_PROJECT_ID'], 'publicKey' => $_ENV['TK_PUBLIC_KEY'], 'secretKey' => $_ENV['TK_SECRET_KEY'], ]);
TK_PROJECT_ID=your-project-id TK_PUBLIC_KEY=tk_sandbox_xxxx TK_SECRET_KEY=sk_sandbox_xxxx
Tanpa Composer
Jika tidak menggunakan Composer:
require_once __DIR__ . '/transaksikita-php/src/TransaksiKitaError.php'; require_once __DIR__ . '/transaksikita-php/src/TransaksiKita.php'; $tk = new \TransaksiKita\TransaksiKita([ 'projectId' => 'xxx', 'publicKey' => 'tk_sandbox_xxx', 'secretKey' => 'sk_sandbox_xxx', ]);