rachmanzz/php-duitku-client
Composer 安装命令:
composer require rachmanzz/php-duitku-client
包简介
Duitku Payment Gateway SDK for PHP (Laravel)
README 文档
README
⚠️ This is a community-maintained SDK, not an official Duitku package.
Duitku Payment Gateway SDK for PHP, with full Laravel support.
Features
- Create invoice / payment page
- Callback signature verification (HMAC-SHA256)
- Custom base URL
- Sandbox & production environment
- Laravel Service Provider (auto-discovery)
- Laravel Facade (
Duitku)
Installation
Via Packagist (recommended)
composer require rachmanzz/php-duitku-client
Via GitHub directly
If not yet published on Packagist, add the repository to your project's composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/rachmanzz/php-duitku-client"
}
],
"require": {
"rachmanzz/php-duitku-client": "dev-main"
}
}
Then run:
composer update
This package uses Laravel auto-discovery, so the Service Provider and Facade are registered automatically.
Configuration (Laravel)
Set environment variables in .env:
DUITKU_MERCHANT_CODE=your_merchant_code DUITKU_API_KEY=your_api_key DUITKU_SANDBOX=true
Optionally publish the config file for customization:
php artisan vendor:publish --tag=duitku-config
Contents of config/duitku.php:
<?php return [ 'merchant_code' => env('DUITKU_MERCHANT_CODE', ''), 'api_key' => env('DUITKU_API_KEY', ''), 'sandbox' => env('DUITKU_SANDBOX', true), // true = sandbox, false = production 'base_url' => env('DUITKU_BASE_URL'), // optional, custom URL ];
Custom URL
You can set a custom base URL in several ways:
1. Via .env
DUITKU_BASE_URL=https://custom.duitku.com
2. Via published config
// config/duitku.php 'base_url' => 'https://custom.duitku.com',
3. Via Facade (per-request)
use Duitku; Duitku::setBaseUrl('https://custom.duitku.com')->createInvoice($request);
4. Via Dependency Injection (per-request)
use Rachmanzz\Duitku\DuitkuClient; public function __invoke(DuitkuClient $duitku) { $duitku->setBaseUrl('https://custom.duitku.com'); $response = $duitku->createInvoice($request); }
5. Global override in ServiceProvider
// app/Providers/AppServiceProvider.php use Rachmanzz\Duitku\DuitkuClient; public function boot(): void { $this->app->resolving(DuitkuClient::class, function ($client) { $client->setBaseUrl('https://custom.duitku.com'); }); }
6. Via constructor (non-Laravel / manual)
$client = new DuitkuClient( merchantCode: 'DXXXX', apiKey: 'your-api-key', baseUrl: 'https://custom.duitku.com', );
Usage
Create Invoice — Facade
<?php namespace App\Http\Controllers; use Duitku; use Rachmanzz\Duitku\Models\CreateInvoiceRequest; class CheckoutController extends Controller { public function __invoke() { $request = new CreateInvoiceRequest( paymentAmount: 50000, merchantOrderId: 'INV-' . uniqid(), productDetails: 'Premium Package 1 Month', email: 'customer@example.com', phoneNumber: '08123456789', customerVaName: 'John Doe', callbackUrl: route('payment.callback'), returnUrl: route('payment.return'), expiryPeriod: 60, // minutes paymentMethod: 'BT', // optional: BT = Bank Transfer, VC = Credit Card, etc. itemDetails: [ new \Rachmanzz\Duitku\Models\ItemDetail( name: 'Premium Package', price: 50000, quantity: 1, ), ], ); $response = Duitku::createInvoice($request); if ($response->statusCode === '00') { return redirect($response->paymentUrl); } return back()->with('error', $response->statusMessage); } }
Create Invoice — Dependency Injection
<?php namespace App\Http\Controllers; use Rachmanzz\Duitku\DuitkuClient; use Rachmanzz\Duitku\Models\CreateInvoiceRequest; class CheckoutController extends Controller { public function __invoke(DuitkuClient $duitku) { $request = new CreateInvoiceRequest( paymentAmount: 150000, merchantOrderId: 'INV-' . uniqid(), productDetails: 'Gold Package Purchase', email: 'user@example.com', callbackUrl: route('payment.callback'), returnUrl: route('payment.return'), ); $response = $duitku->createInvoice($request); return redirect($response->paymentUrl); } }
Create Invoice — Non-Laravel (vanilla PHP)
use Rachmanzz\Duitku\DuitkuClient; use Rachmanzz\Duitku\Models\CreateInvoiceRequest; $client = new DuitkuClient( merchantCode: 'DXXXX', apiKey: 'your-api-key', ); $response = $client->createInvoice( new CreateInvoiceRequest( paymentAmount: 50000, merchantOrderId: 'INV-001', productDetails: 'Test Product', email: 'customer@example.com', callbackUrl: 'https://yoursite.com/callback', returnUrl: 'https://yoursite.com/return', ) ); header('Location: ' . $response->paymentUrl);
Handling Callback
Create a route for the Duitku callback:
// routes/web.php Route::post('/payment/callback', [PaymentController::class, 'callback'])->name('payment.callback');
Note: Make sure the callback route is not protected by the CSRF middleware. Add it to the
$exceptarray inVerifyCsrfToken:// app/Http/Middleware/VerifyCsrfToken.php protected $except = [ '/payment/callback', ];
Callback Controller Example
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Rachmanzz\Duitku\DuitkuClient; use App\Models\Order; class PaymentController extends Controller { public function callback(Request $request, DuitkuClient $duitku) { try { $duitku->processCallback($request->all(), function ($callback) { $order = Order::where('order_id', $callback->merchantOrderId)->first(); if ($callback->isSuccess()) { $order->update(['status' => 'paid', 'reference' => $callback->reference]); } elseif ($callback->isFailed()) { $order->update(['status' => 'failed']); } }); return response('SUCCESS', 200); } catch (\RuntimeException $e) { // Invalid signature or parse error return response('FAILED', 400); } } }
Manual without processCallback
use Rachmanzz\Duitku\DuitkuClient; use Rachmanzz\Duitku\Models\CallbackRequest; public function callback(Request $request, DuitkuClient $duitku) { $cb = CallbackRequest::fromArray($request->all()); if (!$duitku->verifyCallback($cb)) { return response('INVALID SIGNATURE', 400); } if ($cb->isSuccess()) { // Payment successful } return response('SUCCESS', 200); }
API Reference
DuitkuClient
| Method | Description |
|---|---|
createInvoice(CreateInvoiceRequest) |
Create an invoice, returns CreateInvoiceResponse |
verifyCallback(CallbackRequest) |
Verify callback signature, returns bool |
processCallback(array $data, callable) |
Parse, verify, and execute callback handler |
setBaseUrl(string) |
Set custom base URL (chainable) |
getBaseUrl() |
Get current base URL |
useProduction() |
Switch to production URL (chainable) |
useSandbox() |
Switch to sandbox URL (chainable) |
Static Methods
| Method | Description |
|---|---|
DuitkuClient::verifyCallbackSignature(code, amount, orderId, apiKey, sig) |
Manually verify a callback signature |
DuitkuClient::parseCallbackFromArray(array $data) |
Parse an array into a CallbackRequest |
Models
CreateInvoiceRequest
paymentAmount(int) — requiredmerchantOrderId(string) — requiredproductDetails(string) — requiredemail(string) — requiredcallbackUrl(string) — requiredreturnUrl(string) — requiredphoneNumber(string?) — optionaladditionalParam(string?) — optionalmerchantUserInfo(string?) — optionalcustomerVaName(string?) — optionalpaymentMethod(string?) — optionalitemDetails(array?) — optionalcustomerDetail(CustomerDetail?) — optionalcreditCardDetail(CreditCardDetail?) — optionalexpiryPeriod(int?) — optional, in minutes
CreateInvoiceResponse
merchantCode,reference,paymentUrl,statusCode,statusMessage
CallbackRequest
- All Duitku callback fields, plus
isSuccess()andisFailed()helper methods
License
MIT
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-17