parsisolution/gateway
Parsisolution Gateway is a Laravel package offering a unified interface for multiple payment gateways. It simplifies configuration, payment initiation, and callback verification, letting PHP applications integrate online payments through a consistent, reusable API.
Architecture fit. parsisolution/gateway is a driver-based abstraction over Iranian payment service providers (PSPs) — the pattern popularized by shetabit/payment and laravel/payment: a common contract (pay, verify, settle/cancel) with per-gateway adapters behind a Laravel service provider and facade. For a TPM this is the right shape of dependency: it isolates PSP-specific protocol noise (Zarinpal's REST JSON, Behpardakht/Mellat's SOAP envelope, Parsian and Sadad's token flows, IDPay/Pay.ir/Zibal REST) behind one interface, so adding or swapping a gateway is a config change rather than a controller rewrite. The architectural question is not "does it fit Laravel" — it almost certainly does, via package auto-discovery — but whether the abstraction is complete enough for your flows. Typical gaps to check: whether verify is idempotent, whether reversal/refund is exposed as a first-class operation or left to gateway portal dashboards (most Iranian PSPs only allow refunds via their merchant panel, not API), whether multi-currency/IRT vs. Rial normalization is handled, and whether the callback/redirect URL contract is flexible enough for your routing (subdomain, locale prefix, signed URLs).
Integration feasibility. Mechanically low effort: composer require, publish config for merchant IDs and callback routes, map your order model to the package's payment record, wire a return-URL controller. Realistically 3–8 engineering days for a first gateway end-to-end including test-mode validation, plus 1–2 days per additional gateway. The friction is almost entirely non-code: obtaining merchant credentials, Shaparak-licensed PSP onboarding, and the fact that many Iranian gateways require the callback endpoint to be reachable from Iran and sometimes tied to a registered .ir domain with an approved IP whitelist. That is an infrastructure and legal-entity dependency, not a package dependency — and it will dominate your timeline.
Technical risk. The material risk here is supply chain, not architecture. 24 stars, a composite score of 0.43, and (per available metadata) limited downstream validation mean this library is very likely a single-maintainer project with thin test coverage. It sits directly in the money path and handles merchant credentials and gateway secrets, which makes it a higher-stakes dependency than its popularity suggests. Concretely: unverified Laravel version support (does it work on 10/11/12, or is it pinned to ^8.0?), unknown PHP 8.2/8.3 compatibility, unknown whether drivers are maintained against PSP API changes (Zarinpal in particular has versioned its API and deprecated v3), and unknown handling of the callback verification step — the single most security-sensitive code path, where amount tampering, replayed callbacks, and forged Authority/token values must be rejected. There is also a hard functional ceiling: this package is Iran-domestic only. It is unusable for international card acquiring, so it cannot be a shared abstraction across your global and Iranian checkout paths.
Key questions for the maintainer / spike.
verify API before an order is marked paid — or does the package trust the callback payload?verify safe to call twice (idempotent), and does the package guard against duplicate callback delivery?Stack fit. Assumes a conventional Laravel app (Eloquent order/payment models, queued jobs, HTTP client). Fit is good if your checkout is redirect-based — the customer leaves your app for the PSP page and returns to your callback. That keeps card data entirely out of your scope and is the norm for Shaparak-regulated PSPs, so PCI-DSS scope stays at SAQ-A-ish. If any gateway in your mix requires a direct/post SOAP call from the server with a signed payload (Mellat), confirm the package covers it rather than only the redirect gateways.
Migration path. Do not rip out a working curl integration on day one. Sequence: (1) fork the package into your VCS and pin a commit hash, never a floating ^1.0 constraint; (2) add the package alongside the existing integration behind a feature flag; (3) route one low-volume gateway (e.g., Zibal or IDPay, which have decent sandboxes) through the abstraction in test mode; (4) promote to production for that single gateway; (5) migrate the remainder one at a time, keeping the legacy code path alive until reconciliation parity is proven for a full settlement cycle. If you are greenfield, skip the parallel step but still vendor the fork.
Compatibility. Validate in a throwaway branch: composer why-not against your Laravel/PHP constraints, run the package's own test suite, and diff the config file it publishes against your conventions (route names, middleware group, CSRF exclusions for the callback, web vs api guard). Check for global helpers, facades bound at boot, or config keys read via env() at runtime — env() outside config files breaks under config:cache, which is a classic failure in small Laravel packages.
Sequencing. Hard dependencies first: PSP merchant accounts, licensed entity, Iranian-reachable callback hostname. Only then engineering. Within engineering: contract/adapter wrapper → callback verification + idempotency → persistence of gateway payloads for audit → reconciliation job → observability. Budget a security review of the callback handler as a separate, non-negotiable work item.
Maintenance. You are effectively adopting a fork. Assume the upstream project may go quiet; plan for one engineer to own the fork, track upstream commits quarterly, and be able to patch a driver yourself within days when a PSP changes its API — Iranian PSPs do this without much notice and without versioned deprecation windows. The abstraction layer is what makes this survivable: a broken driver should degrade one payment method, not checkout.
Support. Upstream support is likely best-effort GitHub issues in Persian. That means your on-call runbook cannot depend on the maintainer. Build internal documentation per gateway: how to reproduce a failed verify, where to find the PSP's merchant panel, who to call at the PSP, and what the settlement cut-off times are.
Scaling. Throughput is not the constraint — Iranian PSP rate limits and per-transaction caps are. The package itself is stateless and adds no meaningful latency. Watch the callback endpoint for thundering-herd behavior during campaign spikes, and ensure verification is done synchronously and quickly (the customer is staring at a spinner) while post-payment work (receipts, provisioning, analytics) moves to a queue.
Failure modes to design for now. (a) Customer pays but the callback never arrives — need a reconciliation job polling PSP settlement reports against open orders, not just callback-driven state. (b) Double callback / replay — idempotency key on Authority+order. (c) Amount mismatch between what you sent and what was settled. (d) Gateway timeout on verify where the payment may still have succeeded — never mark failed without an authoritative check; queue a retry with backoff. (e) Partial gateway outage — driver-level circuit breaker and a fallback gateway selector. (f) Secret leakage — credentials in config, encrypted at rest, rotated on staff change, and never logged (the package or your wrapper will log raw gateway payloads by default; scrub them).
Ramp-up. Low for a Laravel developer who has integrated a payment gateway before — half a day to read the contract, a day to build the first flow. Higher for the domain: Shaparak rules, Toman/Rial conventions, settlement timing, and per-PSP quirks are not in the README. Pair the integration with someone who has shipped Iranian payments before; that knowledge transfer is worth more than the code review.
Bottom line. Architecturally sound, operationally thin. Adopt it as a fork you own behind an internal payment interface, never as a trusted black box, and only if the Iran-domestic constraint matches your product. The 0.43 score is a fair proxy for "needs due diligence," not "do not use."
How can I help you explore Laravel packages today?