winpay/laravel-sdk
最新稳定版本:1.0.0
Composer 安装命令:
composer require winpay/laravel-sdk
包简介
Winpay Laravel SDK - Official Laravel wrapper for Winpay payment gateway
README 文档
README
Library Laravel resmi untuk Winpay Payment Gateway — integrasi SNAP API & Checkout Page.
Requires: PHP ^8.1, Laravel ^9.0 | ^10.0 | ^11.0
Install
composer require winpay/laravel-sdk
Service provider & facade terdaftar otomatis via auto-discovery.
Konfigurasi
Environment Variables (.env)
WINPAY_PARTNER_ID=your_partner_id WINPAY_MERCHANT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQ..." WINPAY_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIj..." WINPAY_CHANNEL_ID=WEB WINPAY_BASE_URL=https://sandbox-api.bmstaging.id/snap WINPAY_TIMEOUT=30 WINPAY_VERIFY_SSL=true WINPAY_REGISTER_ROUTES=true # Checkout Page (HMAC) WINPAY_CHECKOUT_KEY=your_checkout_key WINPAY_CHECKOUT_SECRET_KEY=your_checkout_secret_key WINPAY_CHECKOUT_BASE_URL=https://sandbox-checkout.winpay.id
Key bisa inline PEM string atau path file:
# Inline WINPAY_MERCHANT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQ..." # File path WINPAY_MERCHANT_PRIVATE_KEY=/path/to/merchant-private.pem
Publish Config (opsional)
php artisan vendor:publish --tag=winpay-config
Cara Pakai
Via Facade
use Winpay; $response = Winpay::snap()->va()->create([...]);
Via Dependency Injection
use Winpay\Core\WinpayClient; class OrderController { public function __construct( private readonly WinpayClient $winpay, ) {} public function store() { $response = $this->winpay->va->create([...]); } }
Response Format
Semua method mengembalikan Winpay\Core\Models\WinpayResponse:
$response->responseCode // string|null, e.g. "2002700" $response->responseMessage // string|null, e.g. "Successful" $response->httpStatusCode // int, e.g. 200 $response->data // array, full response payload $response->isSuccess() // bool, true jika 2xx $response->get('key') // mixed, akses data by key $response->get('key', 'default')
Services
Gunakan Winpay::snap() untuk akses semua channel dengan verb konsisten:
$snap = Winpay::snap(); $snap->va()->create($payload) $snap->va()->inquiry($payload) $snap->va()->status($payload) $snap->va()->delete($payload) $snap->qris()->create($payload) $snap->qris()->status($payload) $snap->qris()->cancel($payload) $snap->ewallet()->create($payload) $snap->ewallet()->status($payload) $snap->ewallet()->cancel($payload) $snap->creditCard()->create($payload) $snap->creditCard()->status($payload) $snap->creditCard()->cancel($payload) $snap->retail()->create($payload) $snap->retail()->status($payload) $snap->retail()->cancel($payload) $snap->report()->balance($payload) $snap->report()->history($payload) $snap->report()->statement($payload) # Checkout Page (HMAC) $snap->checkout()->create($payload) $snap->checkout()->find($id) $snap->checkout()->findByRef($merchantRef) $snap->checkout()->update($id, $payload) $snap->checkout()->delete($id) $snap->checkout()->deleteByRef($merchantRef)
Virtual Account
use Winpay\Core\Enums\VaChannel; use Winpay\Core\Enums\VaType; // Create VA $va = Winpay::snap()->va()->create([ 'partnerServiceId' => '35539457', 'customerNo' => '9876543210', 'virtualAccountNo' => '355394579876543210', 'virtualAccountName' => 'John Doe', 'virtualAccountTrxType' => VaType::ONE_OFF->value, 'totalAmount' => ['value' => '100000.00', 'currency' => 'IDR'], 'expiredDate' => '2026-12-31T23:59:59+07:00', ]); // Inquiry VA $va = Winpay::snap()->va()->inquiry([ 'partnerServiceId' => '35539457', 'customerNo' => '9876543210', 'virtualAccountNo' => '355394579876543210', ]); // Status VA $va = Winpay::snap()->va()->status([ 'partnerServiceId' => '35539457', 'customerNo' => '9876543210', 'virtualAccountNo' => '355394579876543210', ]); // Delete VA Winpay::snap()->va()->delete([ 'partnerServiceId' => '35539457', 'customerNo' => '9876543210', 'virtualAccountNo' => '355394579876543210', ]);
Bank Channel (VaChannel)
BRI, BNI, MANDIRI, MANDIRI_PC, PERMATA, BSI, MUAMALAT, BCA, CIMB, SINARMAS, BNC, MAYBANK
VA Type (VaType)
| Enum | Value | Keterangan |
|---|---|---|
VaType::ONE_OFF |
c |
Dibayar sekali, closed setelah dibayar |
VaType::OPEN_RECURRING |
o |
Bisa dipakai berulang, nominal bebas |
VaType::CLOSE_RECURRING |
r |
Bisa dipakai berulang, nominal tetap |
QRIS
// Generate QRIS $qris = Winpay::snap()->qris()->create([ 'partnerServiceId' => '35539457', 'amount' => [ 'value' => '50000.00', 'currency' => 'IDR', ], 'merchantId' => 'MERCHANT001', 'storeId' => 'STORE001', 'validityPeriod' => '2026-12-31T23:59:59+07:00', ]); // Query QRIS $qris = Winpay::snap()->qris()->status([ 'originalReferenceNo' => 'ORIG_REF_001', ]); // Cancel QRIS Winpay::snap()->qris()->cancel([ 'originalReferenceNo' => 'ORIG_REF_001', ]);
E-Wallet
use Winpay\Core\Enums\EwalletChannel; // Create Payment $ewallet = Winpay::snap()->ewallet()->create([ 'partnerReferenceNo' => 'REF-001', 'amount' => ['value' => '25000.00', 'currency' => 'IDR'], 'additionalInfo' => [ 'channel' => EwalletChannel::DANA->value, 'customerName' => 'John Doe', ], ]); // Status $ewallet = Winpay::snap()->ewallet()->status([ 'originalReferenceNo' => 'REF-001', ]); // Cancel Winpay::snap()->ewallet()->cancel([ 'originalReferenceNo' => 'REF-001', ]);
Channel (EwalletChannel)
| Enum | Value |
|---|---|
EwalletChannel::SPEEDCASH |
SC |
EwalletChannel::OVO |
OVO |
EwalletChannel::DANA |
DANA |
EwalletChannel::SHOPEEPAY |
SPAY |
EwalletChannel::ASTRAPAY |
ASTRA |
Credit Card
// Create Payment $cc = Winpay::snap()->creditCard()->create([ 'partnerReferenceNo' => 'REF-001', 'amount' => ['value' => '500000.00', 'currency' => 'IDR'], 'additionalInfo' => [ 'channel' => 'CC', 'customerName' => 'John Doe', ], ]); // Status $cc = Winpay::snap()->creditCard()->status([...]); // Cancel Winpay::snap()->creditCard()->cancel([...]);
Retail / OTC
use Winpay\Core\Enums\RetailChannel; $retail = Winpay::snap()->retail()->create([ 'partnerServiceId' => '35539457', 'customerNo' => '9876543210', 'paymentCode' => '355394579876543210', 'customerName' => 'John Doe', 'totalAmount' => ['value' => '50000.00', 'currency' => 'IDR'], 'additionalInfo' => [ 'channel' => RetailChannel::ALFAMART->value, ], ]); // Status $retail = Winpay::snap()->retail()->status([ 'originalReferenceNo' => 'REF-001', ]); // Cancel Winpay::snap()->retail()->cancel([ 'originalReferenceNo' => 'REF-001', ]);
Channel (RetailChannel)
| Enum | Value |
|---|---|
RetailChannel::ALFAMART |
ALFAMART |
RetailChannel::INDOMARET |
INDOMARET |
RetailChannel::FASTPAY |
FASTPAY |
Report
// Balance Inquiry $balance = Winpay::snap()->report()->balance([ 'partnerServiceId' => '35539457', ]); // Transaction History $history = Winpay::snap()->report()->history([ 'fromDateTime' => '2026-01-01T00:00:00+07:00', 'toDateTime' => '2026-12-31T23:59:59+07:00', ]); // Bank Statement $statement = Winpay::snap()->report()->statement([ 'accountNo' => '1234567890', 'fromDateTime' => '2026-01-01T00:00:00+07:00', 'toDateTime' => '2026-12-31T23:59:59+07:00', ]);
Checkout Page
Gunakan HMAC-SHA256 signature dengan header X-Winpay-Key, X-Winpay-Timestamp, X-Winpay-Signature.
// Create Invoice $invoice = Winpay::snap()->checkout()->create([ 'customer' => [ 'name' => 'John Doe', 'email' => 'john@example.com', 'phone' => '081234567890', ], 'items' => [ [ 'id' => 'ITEM001', 'name' => 'Product A', 'price' => 25000, 'quantity' => 2, ], ], 'totalAmount' => 50000, 'merchantRef' => 'INV-001', 'expiryMinutes' => 60, 'successUrl' => 'https://example.com/success', 'failureUrl' => 'https://example.com/failure', ]); // Find by ID $invoice = Winpay::snap()->checkout()->find('inv-id-123'); // Find by Merchant Reference $invoice = Winpay::snap()->checkout()->findByRef('INV-001'); // Update Invoice $invoice = Winpay::snap()->checkout()->update('inv-id-123', [ 'totalAmount' => 75000, ]); // Delete by ID Winpay::snap()->checkout()->delete('inv-id-123'); // Delete by Merchant Reference Winpay::snap()->checkout()->deleteByRef('INV-001');
Callback / Webhook
Routes terdaftar otomatis saat provider di-boot. Bisa disable dengan:
WINPAY_REGISTER_ROUTES=false
Endpoint
| Method | URL | Handler | Channel |
|---|---|---|---|
| POST | /api/winpay/callback/v1.0/transfer-va/payment |
vaPayment() |
VA |
| POST | /api/winpay/callback/v1.0/qr/qr-mpm-notify |
qrisNotify() |
QRIS |
| POST | /api/winpay/callback/v1.0/debit/notify |
debitNotify() |
eWallet / CC |
Setiap callback akan:
- Validasi tanda tangan RSA-SHA256 via
WinpayClient::verifyCallback() - Dispatch event
WinpayCallbackReceived - Return
responseCode+responseMessagesesuai standar SNAP (401 jika signature invalid)
Custom Prefix
// Di routes/api.php Winpay\Laravel\WinpayServiceProvider::callbackRoutes('webhook/winpay');
Listening Event
// Di App\Providers\EventServiceProvider.php use Winpay\Laravel\Events\WinpayCallbackReceived; protected $listen = [ WinpayCallbackReceived::class => [ HandleWinpayCallback::class, ], ];
class HandleWinpayCallback { public function handle(WinpayCallbackReceived $event): void { if (! $event->verified) { logger()->warning('Winpay callback invalid signature', [ 'type' => $event->type, ]); return; } if ($event->transactionStatus === '00') { // Process successful payment // $event->type: 'va' | 'qris' | 'ewallet' | 'credit_card' // $event->payload: full request body } } }
Error Handling
use Winpay\Core\Exceptions\WinpayException; use Winpay\Core\Exceptions\HttpException; try { $result = Winpay::snap()->va()->create([...]); } catch (HttpException $e) { // 4xx/5xx — error dari server Winpay $e->getStatusCode(); // int $e->getMessage(); // string $e->getErrors(); // array|null (responseCode, responseMessage, full payload) } catch (WinpayException $e) { // Config error, signature error, network error }
Transaction Status (TransactionStatus)
| Enum | Value | Arti |
|---|---|---|
TransactionStatus::SUCCESS |
00 |
Sukses |
TransactionStatus::INITIATED |
01 |
Initiated |
TransactionStatus::PAYING |
02 |
Sedang dibayar |
TransactionStatus::PENDING |
03 |
Pending |
TransactionStatus::REFUNDED |
04 |
Refund |
TransactionStatus::CANCELED |
05 |
Dibatalkan |
TransactionStatus::FAILED |
06 |
Gagal |
TransactionStatus::NOT_FOUND |
07 |
Tidak ditemukan |
Testing
php vendor/bin/phpunit
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-09