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

Payline Sdk Laravel Package

monext/payline-sdk

A PHP SDK for integrating Monext Payline payment services into your application. It provides client classes and helpers for calling Payline web services, managing payment transactions, and connecting PHP projects to the Payline API.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the SDK first, then verify its constraints before writing application code:

composer require monext/payline-sdk
composer show monext/payline-sdk         # read the declared PHP + ext-* requirements
ls vendor/monext/payline-sdk/src         # namespace layout, entry points

Look at the SDK's PaylineClient / Payline classes and the WebService/Object folders first — that's where Payment, Transaction, Order, Wallet, DoWebPayment, and DoAuthorization live. Read the vendor docs alongside the source; the two drift.

Prerequisites you must have in hand before a single line of code:

  • A Payline merchant ID, access key, and contract number (the contract number scopes which payment methods you can accept).
  • Homologation (sandbox) credentials — always start here, never against production.
  • Confirmed PHP version fit with your Laravel target (8.1+ for L10–12) and that ext-curl, ext-json, and — on legacy code paths — ext-soap are present in your container image. SOAP is the silent blocker.

Your first use case should be hosted payment (DoWebPayment), not direct card capture. Hosted keeps you in SAQ A-EP territory, gives you a redirect flow you can ship in days, and forces you to solve the two things everything else depends on: order state persistence and the return-URL handler.

Wire it up minimally:

// config/payline.php
return [
    'merchant_id'     => env('PAYLINE_MERCHANT_ID'),
    'access_key'      => env('PAYLINE_ACCESS_KEY'),
    'contract_number' => env('PAYLINE_CONTRACT_NUMBER'),
    'environment'     => env('PAYLINE_ENV', 'homologation'), // or 'production'
    'return_url'      => env('PAYLINE_RETURN_URL'),
    'cancel_url'      => env('PAYLINE_CANCEL_URL'),
];
// app/Providers/PaylineServiceProvider.php
public function register(): void
{
    $this->app->singleton(PaylineClient::class, fn () => new PaylineClient(
        config('payline.merchant_id'),
        config('payline.access_key'),
        config('payline.contract_number'),
        config('payline.environment'),
    ));
}

Secrets come from Vault / AWS Secrets Manager in deployed environments, not .env baked into images.

The happy path: create an Order with your merchant reference → call DoWebPayment with returnURL/cancelURL → redirect the user → on return, call getWebPaymentDetails with the returned token and reconcile the result against the order you stored before redirecting.

Implementation Patterns

Never call the SDK from a controller. Put an anti-corruption layer in front of it: an internal PaymentGateway interface with authorize(), capture(), refund(), status(). The SDK's vocabulary (contractNumber, DoAuthorization, Payment/Transaction objects) must not leak into controllers, models, or domain events. When you add a second PSP, you swap the adapter — the app doesn't know.

interface PaymentGateway
{
    public function authorize(AuthorizeRequest $r): AuthorizeResult;
    public function capture(string $ref, Money $amount): CaptureResult;
    public function refund(string $ref, Money $amount): RefundResult;
    public function status(string $ref): PaymentStatus;
}

Every payment attempt gets a client-generated merchant reference and idempotency key, persisted on your orders row before you call the SDK. Payline's Order.ref (merchant reference) is your reconciliation key — you will need it to find orphaned transactions after timeouts.

Model the lifecycle as a state machine, not booleans. created → redirected → authorized → captured → refunded, with explicit failed, cancelled, unknown branches. unknown (post-timeout, no response) is a real state and must not be conflated with failed. 3DS challenges, hosted-page abandonment, and partial refunds all require resumable state — treat the return-URL callback as "resume the flow," not "fire and forget."

Webhook endpoint pattern:

Route::post('/webhooks/payline', PaylineWebhookController::class)
    ->withoutMiddleware([VerifyCsrfToken::class]);

Accept the webhook as an event, not as the source of truth: verify the signature (see Gotchas — verify Payline's documented scheme rather than guessing, or fall back to IP allowlist + a follow-up getTransactionDetails), persist the event ID, and reply 200 fast. Do the state transition on the follow-up query, not on the payload. Idempotency: store webhook IDs and reject duplicates.

Reconciliation job — build this first, not last. A scheduled command that pages Payline's transaction report for the last 24–48 hours and diffs against your orders. It resolves unknown states, catches lost webhooks, and prevents duplicate charges when you retry after a timeout. Without it, every timeout becomes either a duplicate charge or silent revenue loss.

Test against the sandbox, not mocks. Write contract tests that exercise: successful authorize, decline, timeout, malformed response, 3DS challenge, 3DS abandonment. Mocks will lie to you about the payload shapes and error codes.

Wire domain events (PaymentAuthorized, PaymentFailed, PaymentRefunded) out of the adapter, so notifications, order fulfillment, and analytics subscribe to your domain rather than to Payline.

Timeout discipline: set explicit connect/read timeouts on whatever transport the SDK uses (5s connect / 15s read is a reasonable baseline). Payline adds 300–1500ms plus redirect time for 3DS — do not block a synchronous web request for the full round-trip if you can avoid it.

Stage the rollout: auth/config → authorize/capture → webhook receipt → refunds → recurring/wallets → 3DS rules. Each is independently shippable and revertible.

Gotchas and Tips

  • It is not a Laravel package. No service provider, no config file, no facade, no publishable assets. You own all glue: the provider above, config, webhook routing, signature verification, retries, circuit breaker, and error mapping. Budget for that scope up front — it's ~1–2 weeks of the integration, not cleanup later.
  • Zero stars / zero dependents is not a red flag here — vendor SDKs are distributed through merchant contracts, not GitHub popularity. But it does mean you are the early integrator: no community answers, so confirm the Monext support channel, SLA, release cadence, and last-commit date during onboarding, not during your first incident. Support is French-first; confirm English coverage for your operating hours.
  • PCI scope is your decision, not the SDK's. Hosted page / widget = SAQ A-EP. Direct API card capture = SAQ D-EP and a much larger audit and key-management burden. Settle this before writing code.
  • Error semantics are weak by default. Vintage PHP SDKs typically throw generic exceptions or return raw arrays. Map Payline error codes to your own taxonomy: retryable vs terminal, and declined vs unknown. A declined is a business outcome; unknown is a reconciliation task.
  • ext-soap. Older Payline code paths use SOAP; a minimal PHP-FPM image without it will fail at runtime, not install time. Grep the vendor source for SoapClient if you can't find it in composer.json requirements.
  • Tokens do not migrate across PSPs. Stored card tokens are Payline-specific. If multi-PSP is on your roadmap, plan re-entry or network-token migration — cost it into the plan now.
  • Sandbox ≠ production. Test card behavior, 3DS simulation, and contract scoping differ. Document the divergence you actually observe during the spike; the docs won't tell you.
  • Rounding and minor units. Verify amount handling for EUR (and any non-EUR currencies) against Payline's expectation of integer minor units. French-market defaults can mask EUR-only assumptions that break when you add another currency.
  • Pin the version exactly ("monext/payline-sdk": "x.y.z", not ^x). Subscribe to the release feed and budget a few hours per quarter — the bigger maintenance cost is Payline endpoint version deprecations, not the library itself.
  • Extension points: if you need custom HTTP behavior (retries, circuit breakers, correlation IDs), wrap the SDK's transport rather than reaching inside it. If the SDK forces its own transport, isolate it behind your PaymentGateway so a future transport swap doesn't touch call sites.
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.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console