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

Sham Cash Sdk Laravel Package

oktocode/sham-cash-sdk

oktocode/sham-cash-sdk is a lightweight PHP SDK for integrating Sham Cash payments into Laravel applications. Send transfers, verify transactions, and manage wallet operations through a clean API with minimal configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is deliberately not a Laravel package. oktocode/sham-cash-sdk is a framework-free Composer library with a documented policy that Laravel/Symfony/WordPress bridges belong in other repositories. For a Laravel codebase this is a library, not a package with a service provider, config, or facade. We own the glue.
  • The surface is small and well-shaped for adapter work: one entry point (Client) with createBill, getBill, refundBill, listTransactions, eachTransaction, parseWebhook. Public types are limited to Client, models, enums, exceptions. Crypto, Http, and Support are @internal — correct encapsulation, and it means we must never reach past Client.
  • Dependency fit is near-ideal: Guzzle 7 is already a transitive dependency of illuminate/http in every Laravel app, and the constructor accepts a PSR-18 client plus an optional PSR-3 logger. That is exactly the seam needed to bind Client as a container singleton fed by config('services.shamcash.*') and Laravel's LogManager.
  • The security-critical JWE path (dir/A256GCM, 12-byte IV, 16-byte tag, AAD = protected header segment, secretKey decoded to 32 raw bytes) is encapsulated. That is the right design and the strongest argument for using the SDK rather than calling the API directly — but it also concentrates risk in a package with 12 stars and 0 dependents. Treat the crypto path as third-party code under review, not as a black box.

Integration feasibility

  • Happy path: high. Create bill → receive webhook → verify → refund is a well-documented flow with sandbox support and examples shipped in the package.
  • Production readiness: medium. Missing pieces we must build: service provider, config publishing, DI binding, webhook route with CSRF exemption, raw-body handling, exception → problem-details mapping, queue jobs, reconciliation sweeper, and test doubles. All thin, all ours.

Technical risk

  1. Raw-body footgun (highest). parseWebhook takes the raw body string and must not be re-encoded. Any Laravel middleware, request validator, or $request->all() call silently breaks verification. This will fail 100% of the time and look like a crypto bug.
  2. Clock skew. Webhook exp/iat tolerance is 30 seconds and token TTL is 300 seconds. Multi-node deployments, container drift, or serverless cold starts will produce intermittent CryptoExceptions that masquerade as "bad token." NTP/chrony discipline is a launch blocker, not a nice-to-have.
  3. Caller-owned idempotency. Refund idempotencyKey is 10–100 characters, supplied by us, and the SDK explicitly does not retry money calls. Laravel queue $tries/$backoff retries will double-refund unless the key is derived deterministically and persisted before dispatch.
  4. No polling by design. getBill is a one-shot fallback ≥10 minutes after create, only when the webhook never arrived. Webhook loss therefore means silent unreconciled state. A scheduled eachTransaction sweep is mandatory, not optional.
  5. Duplicate-create semantics. A repeat createBill can return 1704; we must catch it and call getBill. Easy to omit, easy to miss in QA.
  6. Log hygiene. Laravel's default exception handler, query logging, and Telescope/Clockwork will happily capture encData. Explicit redaction (and a CI assertion) is required.
  7. Vendor and jurisdiction risk. The bilingual EN/AR READMEs and product name indicate the Syrian market. Payment-rail jurisdiction, licensing, sanctions screening, and AML/KYC obligations need compliance sign-off before this appears on a roadmap, independent of code quality.
  8. Metadata anomaly. Last release is stamped 2026-10-24 — a future date. Verify tags on Packagist against the repo before pinning anything.
  9. Bus factor 1, 0 dependents. MIT license is the escape hatch: we can fork to a private VCS and pin an exact tag or commit SHA. Do not float on ^1.0 for a money path.
  10. Unknown result codes. ApiException + ResultCode with no per-code subclasses is a clean design, but we need to confirm forward-compatibility for codes we haven't seen.

Key questions

  • Is there a public sandbox with provisioned test credentials, or is the gitignored local/sandbox.php the only route?
  • Is agentKey per-merchant or per-integration? This determines whether we need multi-tenant client resolution or a single singleton.
  • Webhook retry policy, signing-key rotation cadence, and is there any key versioning beyond the fixed {"alg":"dir","enc":"A256GCM","cty":"json"} header?
  • Refund semantics: full-only or partial? Is idempotencyKey scoped per bill or globally?
  • Is ResultCode exhaustive and documented, and how should clients handle unmapped codes?
  • Settlement timing, uptime SLA, and a named ShamCash escalation contact — GitHub issues alone are insufficient for a payment rail.
  • Maintainer capacity and long-term support commitment for a 12-star, single-maintainer project.
  • Compliance: licensing status, sanctions exposure, and required KYC/AML controls in our jurisdiction.

Integration Approach

Stack fit

  • config.platform.php pinned to 8.2.0 aligns with Laravel 10/11. CI covers PHPUnit, PHPStan level 8 on src, and PSR-12 across PHP 8.2/8.3/8.4 — engineering hygiene is better than the star count implies.
  • Guzzle 7 matches illuminate/http; PSR-18 and PSR-3 match the container and LogManager. No adapter indirection needed for HTTP.

Migration path

  • Wrap, don't embed. Build an internal package (e.g. acme/shamcash-laravel) that depends on oktocode/sham-cash-sdk and exposes:
    • ShamCashServiceProvider — config merge/publish, singleton Client binding, PSR-3 logger injection, TLS verification left on (the SDK enforces this even for injected PSR-18 clients).
    • WebhookController — reads $request->getContent(), is registered outside the web middleware group (no CSRF), verifies synchronously, persists the raw body, dispatches a job, returns 200.
    • CreateBillJob / RefundBillJob — idempotency key generated and persisted before dispatch; no blind retry on money calls.
    • ReconcileShamCashTransactions — scheduled command streaming via eachTransaction.
    • Exception mapping — ApiException / TransportException / CryptoException / InvalidArgumentException → our domain exceptions and HTTP problem responses.
    • ShamCash::fake() — a test double so feature tests never hit the network.
  • If a legacy integration exists, strangler it behind a PaymentGateway interface and route a small percentage of traffic first.

Compatibility

  • No version field in composer.json; Packagist reads git tags. Pin 1.0.0 exactly for the money path. dev-master via a path repository is acceptable only in the spike branch.
  • The wire contract is fixed (POST {baseUrl}/api/ElectronicPayment/{action}, {"encData","agentKey"}, success = result === 2500 && succeeded === true). A future 2.x could change exception taxonomy or the Client signature; read the changelog before any bump.

Sequencing (~4 weeks, one backend engineer)

  1. Week 1 — Spike. Sandbox createBill → webhook → parseWebhook → refund in a throwaway branch. Prove raw-body handling and clock behavior. Read Crypto and Http internals; decide fork vs. upstream-pin.
  2. Weeks 1–2 — Adapter. Internal Laravel package, config, DI, webhook route, exception mapping, redaction rules, feature tests against ShamCash::fake().
  3. Week 2 — Resilience. Reconciliation sweeper, 1704 handling, idempotency persistence, failed_jobs triage.
  4. Week 3 — Staging E2E. Real sandbox, webhook load test, deliberate clock shift, failure injection (timeout, non-200, malformed JSON, succeeded:false).
  5. Week 4 — Pilot. Feature-flagged, single merchant/agentKey, low value cap, dashboards, on-call runbook.

Operational Impact

Maintenance

  • Code surface is small — one Client, a fixed wire protocol. Two recurring duties: (a) track upstream tags on a low-traffic repo, and (b) own the Laravel glue. Budget 1–2 engineer-days per quarter plus a quarterly fork-rebase ritual if we fork.
  • Documentation gap: much of the operational knowledge (the 2500/1704 codes, the no-polling rule, the raw-body requirement, the 10-minute getBill window) lives in the maintainer-facing agents/AGENTS.md, not in consumer-facing docs. We should convert that into an ADR and a runbook on day one.

Support

  • No commercial support channel documented; GitHub issues plus a private security advisory. The real gap is escalation to ShamCash itself. Establish a named contact and, if one exists, a status page before launch.
  • Internal runbook must cover: webhook never arrived, refund stuck/unknown, duplicate bill, crypto verification failure, and ShamCash outage.

Scaling

  • Client is stateless; horizontal scaling is fine.
  • Timeouts are 5s connect / 30s request. A degraded ShamCash endpoint will pin a PHP-FPM worker for up to 30 seconds — money calls must go to queue workers, never run synchronously in a request cycle.
  • eachTransaction is a generator, which is the right primitive for reconciliation without memory blowup, but it must be rate-limited and batched.
  • Webhook bursts: persist the raw body, return 200 fast, process asynchronously. Do not process inline.

Failure modes

  • Clock drift → intermittent CryptoException on an otherwise valid webhook. Mitigate with NTP enforcement and a skew alert; detect by monitoring crypto-failure rate.
  • Webhook never arrives → bills stuck in pending. Mitigate with a scheduled eachTransaction reconciliation sweep and the one-shot getBill ≥10 minutes after create.
  • Body re-encoded by middleware → 100% webhook verification failure. Mitigate with a permanent regression test asserting getContent() is passed through untouched.
  • Queue retry double-refund → duplicate money movement. Mitigate with a deterministic key persisted pre-dispatch and a hard rule against automatic retry of refund jobs.
  • HTTP 200 with succeeded:false → silent business failure. Mitigate by mapping ResultCode to domain errors and alerting on unmapped codes.
  • ShamCash outage / DNS failure → TransportException. Circuit-break, queue non-money work with backoff, surface a clear user-facing message.
  • Secret leakage via logs → secretKey, encData, or decrypted payload in logs. Mitigate with redaction rules, Laravel's dontFlash, Telescope/Clockwork exclusions, and a CI assertion.
  • Upstream divergence → our fork drifts. Mitigate by keeping patches minimal and offering them upstream.

Ramp-up

  • A Laravel-fluent engineer is productive in about a day; the SDK README and shipped examples are reasonable, and the framework-free design means little to unlearn.
  • The non-obvious knowledge is all in the wire rules — JWE specifics, 2500/1704, the no-polling directive, the 10-minute getBill window, and the raw-body constraint. None of that is discoverable from the type signatures. Capture it in an ADR and a runbook before the pilot, or the first on-call rotation will rediscover it at 3 a.m.
  • Calibrate expectations correctly: 12 stars and 0 dependents means this is vendor sample code with a test suite, not an ecosystem-standard library. Our own integration tests are the contract, and our own fork is the insurance policy.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
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