fadhila36/pakasir-sdk
A modern, type-safe Laravel SDK for the Pakasir payment gateway with QRIS, multi-bank Virtual Account, and PayPal support, plus automatic fees, retries, DTOs, events, and secure webhook verification.
composer require. The decision it unblocks is which gateway to sign with, not whether to write your own HTTP client: the SDK is a thin, well-shaped wrapper, so the switching cost is mostly the commercial Pakasir contract, not code.createPayment() returning a paymentUrl, paymentNumber (QRIS string or VA number), and totalPayment (amount + fee) covers the minimum viable checkout: generate a charge, redirect, show the code. That is enough to ship a paid pilot without a payments squad.PaymentMethod is a backed enum with per-method fee rules (QRIS ~0.7–1%, VA flat Rp2,000–3,500, PayPal 1% min Rp3,000) and minimum-amount validation baked in. A PM can price and sequence rail rollout — launch QRIS-only in week one, add VA for B2B invoicing later — without re-planning engineering work, because enabling a rail is a config/UI change rather than a new integration.verifyWebhook() validates schema, project slug, and expected amount, then makes a back-channel call to Pakasir to confirm the payment state. That is effectively a product decision to treat webhooks as untrusted hints rather than as source-of-truth events — a meaningful stance to be able to state explicitly to risk and finance. It also means your reconciliation flow needs a deliberate retry/fallback path for the case where Pakasir is unreachable at webhook time.TransactionCreated, PaymentCompleted, TransactionCanceled, and WebhookReceived events let fulfilment, provisioning, receipts, and analytics subscribe without bespoke glue. This is the difference between "we accept payments" and "payment triggers the product," and it directly affects how fast you can ship post-purchase flows (e.g. instant license issuance, WhatsApp/email receipts via the bundled PaymentLinkNotification).detailPayment() plus simulationPayment() (sandbox) also means QA and support can reproduce payment states without a live charge — a real reduction in release friction.orderId with an amount. That makes your order-ID scheme a payments-critical decision (retries, double-submits, cart re-entry), and the SDK's surface forces that conversation early — which is where most payment incidents originate.Adopt when all of the following hold:
Look elsewhere when:
cancelPayment() on a pending bill is the extent of the reversal story.v2.0.0...v1.0.1 comparison, and the recorded last-release date is ahead of today) are exactly the signals a strict supply-chain review flags. Some orgs will reject on that alone, and they're not wrong.For executives — one paragraph. We need to take payments in Indonesia, where QRIS and bank virtual accounts are table stakes. The fadhila36/pakasir-sdk is a free (MIT), type-safe Laravel wrapper around the Pakasir gateway that gives us QRIS, nine VA rails, and PayPal behind roughly a dozen lines of code, with automatic fee calculation, retry/timeout handling, and framework-native events and notifications. It is a fast, low-commitment path to a working checkout — we can demo a paid transaction in days, not a quarter. The trade-off is honest and bounded: it is a small, single-maintainer open-source project with essentially no adoption, and we would be early adopters. We mitigate that two ways — the code is permissively licensed and small enough that we can fork and maintain it ourselves if it goes stale, and more importantly the real dependency is our commercial relationship with Pakasir, not this wrapper. If the package dies, we lose the convenience layer, not the integration.
For engineering — the technical case. PHP 8.3+, Laravel 11–13, declare(strict_types=1), readonly DTOs on every response, a container-bound PakasirInterface for testability, PHPStan Level 8 green, Pest/PHPUnit CI across PHP 8.3–8.4 and Laravel 11–13. Response mapping is typed (TransactionCreateResponse, TransactionDetailResponse, WebhookPayload) so no array-key archaeology in controllers. Webhooks are handled properly: verifyWebhook() validates payload shape, project slug, and expected amount against our own database value, then re-queries Pakasir to confirm the state — this closes the spoofing hole that unsigned webhooks would otherwise leave open, and it's the single strongest argument for using this over hand-rolling. Timeout/retry/logging are config-driven rather than scattered through our code. Caveats to own explicitly: no refund primitive beyond cancelling a pending bill; no idempotency key beyond our orderId, so our order-number generation becomes a payments-critical invariant; verifyWebhook() adds a synchronous outbound call we must make resilient (queue it, alert on it); and we should pin the version and vendor or mirror the source given the low upstream activity.
The ask. Timebox a one-sprint spike: integrate in a sandbox project, model fees end-to-end, run the webhook path including the failure mode where Pakasir is unreachable, and confirm the PHP 8.3 / Laravel 11+ prerequisite against our actual stack. Decide on spike results — with a documented fallback to a direct HTTP client if the spike surfaces maintainer or API gaps. Do not adopt for a revenue-critical launch without a named internal owner for the dependency.
How can I help you explore Laravel packages today?