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

Payliance Bundle Laravel Package

nti/payliance-bundle

Integrate Payliance payment services into your PHP application with this bundle. It provides configuration and service wiring for connecting to Payliance APIs, helping streamline payment workflows, reduce boilerplate setup, and keep payment integration organized within your existing stack.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalize: nti/payliance-bundle is a Symfony bundle, not a Laravel package. There is no PaylianceServiceProvider, no config/payliance.php to publish, no facade. composer require nti/payliance-bundle in a Laravel app will install files but nothing will boot. With 1 star, 0 dependents, and a last release in August 2020, treat it as reference source code, not a maintained dependency.

Where to look first, in order:

  1. composer.json — confirm "type": "symfony-bundle", the PHP version constraint, and which symfony/* components it drags in.
  2. src/DependencyInjection/*Extension.php and Resources/config/services.yml — this is where the real configuration schema and constructor arguments live. This tells you exactly what the API client needs.
  3. The main client class (typically src/Api/Client.php or similar) — the actual Payliance HTTP calls, endpoints, and auth scheme.
  4. src/Resources/config/ — the bundle's default config keys (base URL, credentials, merchant ID), which you will translate to Laravel config manually.

Pick an integration route before writing any code:

  • Extract the client (recommended): copy the client class and its DTOs into app/Services/Payliance/. No Symfony dependency, full control, Laravel-idiomatic.
  • Sidecar service: run the bundle inside a tiny Symfony app and call it over HTTP from Laravel. Only worth it if you already run Symfony somewhere.
  • Install Symfony components in Laravel: technically possible, but pulls in symfony/dependency-injection and friends for zero benefit. Avoid.

Minimal extracted setup:

// config/services.php
'payliance' => [
    'base_url'    => env('PAYLIANCE_BASE_URL', 'https://sandbox.payliance.com'),
    'username'    => env('PAYLIANCE_USERNAME'),
    'password'    => env('PAYLIANCE_PASSWORD'),
    'merchant_id' => env('PAYLIANCE_MERCHANT_ID'),
],
// app/Providers/AppServiceProvider.php
$this->app->singleton(PaylianceClient::class, fn ($app) =>
    new PaylianceClient($app['config']['services.payliance'])
);

First use case to prove the wiring: a read-only call (list merchants, fetch a transaction, or whatever "ping"/lookup endpoint the client exposes) executed from php artisan tinker against sandbox credentials. Do not start with a charge.

Implementation Patterns

Wrap the client, don't call it from controllers. Define your own interface (App\Contracts\PaymentGateway) and have the extracted PaylianceClient implement it. This is the single highest-value decision, because it lets you swap to Payliance's current API or another processor without touching business logic.

Normalize the transport. Once extracted, replace Guzzle calls with Http::withBasicAuth(...)->baseUrl(...) so timeouts, retries, logging, and Http::fake() tests come free from Laravel. Keep the original Guzzle code in a git tag for reference on request shapes.

Every money movement goes through a queued job. ACH submissions and card authorizations should never block a request. Pattern:

final class SubmitAchDebit implements ShouldQueue
{
    public int $tries = 3;
    public array $backoff = [10, 60, 300];

    public function handle(PaylianceClient $client): void
    {
        $result = $client->achDebit($this->payment->toGatewayPayload());
        $this->payment->recordGatewayResponse($result);
    }
}

Idempotency is mandatory. Add a unique idempotency_key (UUID) to your payments table and pass it to the gateway if supported. If the old client doesn't support it, enforce it locally: a submitted_at column and a guard clause that refuses a second submission for the same payment row.

Model the lifecycle locally with a state machine. draft → submitted → settled | returned | failed. Never derive state from a single API response — ACH returns and chargebacks arrive days later via webhook or reconciliation.

Webhook/return-URL handling. Register a route outside auth middleware, exclude it from CSRF, respond 200 immediately, and push payload processing to a job. Verify whatever signature scheme Payliance offers (the 2020 client likely doesn't implement one — check the docs; if none exists, restrict by IP allowlist and reconcile amounts against your DB rather than trusting the body).

Nightly reconciliation command. php artisan payliance:reconcile --date=yesterday that pulls transaction statuses and diffs against local rows. Schedule it in routes/console.php. This catches dropped webhooks, which are inevitable.

Testing seam. Because you own the interface, tests use a fake implementation for unit tests and Http::fake() with recorded sandbox fixtures for integration tests. Keep a tests/Fixtures/payliance/*.json directory — the real API responses are your documentation since the package's docs are stale.

Gotchas and Tips

  • It is abandoned. Last release 2020, no security advisory coverage, no Laravel 10/11 support, one star. Do not ship it as a live Composer dependency in a production Laravel app. Vendor the source into your repo (with a comment on origin and date) so you can patch it.
  • Symfony DI plumbing will bite you. The client constructor typically expects Psr\Log\LoggerInterface, possibly an EventDispatcherInterface, and a config array. If you instantiate manually you must supply these — use app('log') for the logger and null or app('events') for the dispatcher, then verify nothing calls dispatch() on a null.
  • Environment placeholders don't translate. Symfony bundle configs use %env(PAYLIANCE_USERNAME)% syntax, which Symfony's container resolves and Laravel does not. Strip these and map to config/services.php with real env() calls. Only use env() inside config files so php artisan config:cache doesn't silently break you.
  • Check the HTTP status and the body. Payment APIs from this era commonly return 200 OK with an error code and message in the JSON body. A status-only check will mark failed charges as successful. Always inspect a success/response_code style field and map it to your state machine.
  • Sandbox and production base URLs are different hosts. Pin them via PAYLIANCE_BASE_URL per environment, and add a boot-time guard in AppServiceProvider that throws if app()->isProduction() is false but the base URL contains sandbox while credentials look live (or vice versa). Mixing these is the classic way to move real money in a demo.
  • Retries must be idempotent. Laravel's queue $tries will happily resubmit an ACH debit on timeout. If the request reached Payliance but the response was lost, a naive retry double-charges. Only retry on connection failures and 5xx; treat timeout as "unknown — reconcile before retrying."
  • Timeouts. Set explicit Guzzle/HTTP timeouts (5s connect, 15–30s total). The default is no timeout, and a hung socket will stall a queue worker.
  • Logging leaks account numbers. The bundle's logger may dump full request bodies including routing and account numbers. Add a middleware or a tap on the client that masks anything matching \d{9,17} before it hits your log channel. Store only the last four digits in your database; tokenize where the API allows it.
  • Extension points are thin. The client is usually a concrete, non-final class with no interface — so subclassing or decorating is your only hook. Keep a thin adapter (PaylianceGateway implements PaymentGateway) around it rather than extending the vendored class directly; vendored code changes are then isolated to one file.
  • Debugging locally: register a Guzzle middleware that dumps request/response to storage/logs/payliance.log when APP_DEBUG=true, and keep the raw payloads as fixtures. Without this you'll be guessing at request shapes, because the bundle's documentation (if any) is from 2020 and will not match the current API.
  • Budget for replacement. Payliance's current API has almost certainly moved on since August 2020. Plan the interface so migration is a one-class change, and check with Payliance support for their current official SDK before investing heavily in this one.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource