Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Satim Laravel Package

gts-meghni/laravel-satim

A Laravel package for integrating SATIM online payments, with configuration and helpers to initiate payment requests, handle responses, and add SATIM checkout flows to your PHP application.

View on GitHub
Deep Wiki
Context7

Getting Started

Start with docs/satim-gateway.md. It is now the canonical reference for endpoints, parameters, error codes, and order statuses, and it will answer most questions faster than reading the source. From there, the three entry points you will actually touch are Satim (facade), SatimOperation (the enum of gateway operations), and the SatimTransport contract that sits underneath both.

For a first integration, wire a single registration flow end to end:

  1. Publish config and language files (satim.php, satim-lang) so you can adjust credentials and the SATIM hotline wording without patching the package.
  2. Generate the order number with Satim::orderNumber(). It produces a 10-character value and, importantly, skips anything already present in the audit trail, so you do not need your own uniqueness guard against previously-sent orders.
  3. Call the register operation and persist the returned order id against your own model.
  4. Render the redirect/form the gateway expects, then handle the return URL by resolving the audit record and confirming the order.

Test that flow with Satim::fake() before you ever point at the sandbox. Because the fake replaces only the transport, validation, events, and the audit trail all keep running, so your first test exercises the same code path production will.

The one piece that is easy to forget on day one: nothing prunes the audit trail until you schedule model:prune. See the retention note below.

Implementation Patterns

Fake-first feature tests. Satim::fake() is the intended default in tests. Use named responses for readability (registered, registerFailed, paid, declined, reversed, acknowledgeRefunded, refunded, refundFailed, connectionFailure) and make() when you need a bespoke payload. Queue per-operation responses when a test walks through register → pay → refund, so each call gets the response belonging to its operation rather than a single shared stub.

Assert on the facade, not on the client. assertRegistered, assertAcknowledged, assertRefunded, assertSent, assertNotSent, assertNothingSent, assertSentCount, and recorded give you assertion vocabulary that survives refactors of the underlying transport. Prefer recorded when you need to inspect payload shape; prefer the semantic assertions for behavioural tests.

Map errors through the enum. SatimErrorCode covers the codes in the integration guide and exposes description() per operation, because the same code can mean different things depending on whether you were registering or refunding. On any of the three results, call error() and branch on the enum case, not on the raw string. Translate to user-facing copy via your own lang files, keeping description() for logs and support tickets.

Show Satim::supportMessage() on rejection pages. SATIM requires the hotline text to appear on a rejected return page, and that page has no receipt to carry it. Call supportMessage() with an explicit locale when the page language is known, or omit the argument to use the configured default. Do not hardcode the number — v1.1.0 changed the French wording to match the guide, and the package is the source of truth.

Reconcile the drop-offs. Customers abandoning the payment page is the normal failure mode, not an edge case. Schedule satim:reconcile on the cadence your satim.reconcile.after / within / limit values imply: after is the grace period before an order is considered stuck, within bounds how far back to look, and limit caps the batch. Listen for SatimOrderReconciled and update your order state from the event rather than polling yourself. Treat the event as authoritative for that check only — it reports the gateway's answer, which may still be pending.

Keep the transport seam clean. If you need a stub gateway for local development or a proxy for logging, bind your own implementation of SatimTransport rather than subclassing SatimClient. The contract is deliberately narrow, and SatimOperation now carries its own endpoint, so your implementation receives an operation and can switch on it directly.

Schedule the audit prune. Set satim.audit.retention (default ten years, tracking article 12 of the Algerian code de commerce) and add the audit model to your model:prune schedule. Without the schedule, nothing is ever deleted — which is the safe default but not a plan.

Gotchas and Tips

The fake is not a mock of your application. Satim::fake() swaps the transport only. Validation still rejects bad input, events still fire, and the audit trail still records. If a test passes with the fake but fails against the sandbox, suspect your request construction or your return-URL handling, not the fake.

orderNumber() consults the audit trail. It skips numbers this application already sent, which means the guarantee depends on the audit table being present and populated. In a fresh test database with the trail truncated, collisions are theoretically possible again. Do not clear audit records casually outside of the prune path.

Retention defaults are long by design. Ten years means the table grows. Index the columns you query on for reconciliation, and check that satim:reconcile's within window does not force a scan pattern your indexes cannot serve. If you shorten retention, confirm that is defensible under your own compliance obligations before changing the config.

Prune is opt-in, not automatic. The retention config is inert until model:prune is scheduled. Two failure modes: forgetting to schedule it at all (table grows forever), or scheduling it but forgetting the audit model is prunable (silent no-op). Verify with a dry run in staging.

Reconcile windows interact. after too small will query orders the gateway has not settled yet, producing pending answers you then have to re-check; within too large combined with a low limit means the batch never catches up during a backlog. Watch for SatimOrderReconciled firing with a non-final status and design your listener to be idempotent.

Error codes are operation-scoped. Because description() varies by operation, do not cache a code-to-message map keyed on the code alone. Key on the pair, or always go through error() on the result you actually hold.

Hotline wording is publishable, and it changed. The French text now reads "numéro vert de la SATIM"; English and Arabic were reworded to match. If you had overridden satim-lang with the old wording, republish and re-apply your customisations — and remember the requirement is about the text appearing on the page, so a translation that drops the hotline reference is a compliance bug, not a style choice.

SatimOperation no longer takes an endpoint string. Any code you wrote passing an endpoint into the transport needs updating to pass the operation. This is the one breaking-ish surface in v1.1.0; grep for direct transport calls, especially in custom test doubles written before the SatimTransport contract existed.

Debugging tip: when a call fails opaquely in production, pull the audit record first — it holds what was sent and to which operation — then compare the gateway's returned code against SatimErrorCode with the correct operation context. That combination resolves most tickets faster than replaying the request.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox