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

Datatrans Bundle Laravel Package

valiton/datatrans-bundle

Valiton Datatrans Bundle is a Symfony integration for the Datatrans payment gateway. It wires Datatrans services into your application and helps configure and handle payment transactions and callbacks with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a thin Symfony 3 bridge between the legacy Datatrans UPP/XML API and JMSCorePaymentBundle. There are only 3 stars, 0 dependents, and a single late-2022 release, so treat it as a reference implementation to vendor or fork, not a maintained dependency.

Minimal adoption path:

  1. Audit constraints first. Open composer.json and check PHP and Symfony version ranges plus the pinned JMS payment bundle version. If you are on Symfony 4+, this will not install without forking. Confirm the JMS PaymentCoreBundle version it expects, because the bundle is useless without it.
  2. Install both bundles. composer require valiton/datatrans-bundle will pull JMS along with it if constraints allow. Register both in app/AppKernel.php; order matters only in that JMS should be enabled before Datatrans so its services and Doctrine mappings exist.
  3. Read two files before anything else:
    • DependencyInjection/Configuration.php — the authoritative config tree (merchant_id, sign_key, sandbox/test, and whatever endpoint/URL options exist).
    • Resources/config/services.yml — the service IDs you will actually inject. The class names vary between releases, so do not assume; copy IDs from here.
  4. Configure credentials in config.yml under the bundle's root key (check Configuration.php for the exact node name), using parameters so test/prod keys are environment-driven:
# config.yml — verify node/key names against Configuration.php
vaulton_datatrans:
    merchant_id: "%datatrans_merchant_id%"
    sign_key:    "%datatrans_sign_key%"
    sandbox:     "%kernel.debug%"
  1. First use case: authorize a single payment through the hosted payment page. Create a PaymentInstruction + PaymentTransaction via JMS, persist them with your own unique refno, then redirect the user to the Datatrans form with merchantId, amount (in minor units), currency, refno, successUrl, errorUrl, cancelUrl, and the signature. A simple "pay once, capture immediately" flow (purchase) is the fastest end-to-end validation that config, signing, and return URLs all work.

Do not start with refunds or voiding — validate authorize + return handling first, because the return/callback format is where the legacy API bites hardest.

Implementation Patterns

Pattern 1 — JMS-driven instruction flow (the intended path). The bundle assumes you already model payments as JMS PaymentInstruction/PaymentTransaction entities. Build the instruction, set amount in minor units, attach a transaction, flush, then hand the instruction to the Datatrans service to obtain the redirect/form payload. Keep the instruction ID as your internal correlation key and store the Datatrans refno/uppTransactionId on the transaction's extended data.

Pattern 2 — Hosted page + return controller. Typical flow:

// Controller: start
$instruction = $this->get('jms_payment_core.payment_instruction_factory')->create();
// ... set amount, currency, your refno ...
$em->persist($instruction);
$em->flush();

$response = $this->get('datatrans.payment_service')->purchase($instruction);
return $this->redirect($response->getRedirectUrl()); // or render a self-posting form
// Controller: success/error/cancel endpoint
public function successAction(Request $request)
{
    // Log the raw payload first — the legacy API returns inconsistent fields.
    $this->get('logger')->info('datatrans.return', $request->request->all());

    $refno  = $request->request->get('refno');
    $status = $request->request->get('status'); // do NOT trust for fulfilment
    // Verify server-side via the service/getStatus before marking paid.
}

Pattern 3 — Server-to-server authorize/settle/void. Wrap the bundle's client service in your own DatatransGateway interface with authorize, capture, refund, void, status. This is the single highest-value thing you can do: it isolates every legacy quirk behind one seam and makes a future migration to Datatrans' JSON API v2 a swap of one class rather than a hunt through controllers.

Pattern 4 — Reconciliation job. A nightly console command that iterates transactions stuck in pending, calls getStatus by refno/transaction id, and settles or marks them failed. Because the browser return is unreliable (users close tabs, providers retry), server-side polling is how you keep state correct.

Integration tips:

  • Make refno a stable, unique, human-readable order reference; Datatrans ties everything to it.
  • Persist the complete raw request and response (JSON column) at every hop — you will need it for disputes and for debugging signature mismatches.
  • Use absolute successUrl/errorUrl/cancelUrl including scheme and host; relative URLs silently fail in some Datatrans flows.
  • If you use Symfony's event system, dispatch your own domain events (PaymentAuthorized, PaymentCaptured) from the gateway, not from the bundle, so the rest of the app never depends on Datatrans types.

Gotchas and Tips

  • It is effectively abandoned. Symfony 3 is EOL, JMS PaymentCoreBundle is itself lightly maintained, and 0 dependents means nobody is filing the bugs you will hit. Budget for forking into src/ (composer.json "replace") and owning the code.
  • Legacy API surface. The bundle targets the UPP/XML endpoints (upStart, upStart.jsp-style flows and XML status calls). New Datatrans merchants are onboarded onto the JSON API v2 with HMAC signing and a different request shape. Confirm with Datatrans support which onboarding you received before writing a line of code.
  • Amounts are in minor units. CHF 12.50 is 1250; zero-decimal currencies (JPY) are not. Currency must match the merchant's configured currencies or Datatrans rejects the request with an unhelpful error.
  • Signing is the number-one source of failures. The sign key differs per merchant and between test and production. The signature covers specific fields in a specific order; changing one hidden field breaks it. Log the pre-signature parameter array to debug.
  • Never trust the browser return. The status/success query parameters in the return URL are forgeable. Always confirm via a server-side status call or the settlement/reconciliation feed before fulfilling an order.
  • Test mode is separate infrastructure. Use the Datatrans-provided test merchant IDs and test cards; a production sign key in sandbox mode (or vice versa) yields generic "invalid request" errors rather than a clear auth failure.
  • Debugging workflow: enable HTTP client logging at the transport level (Guzzle/StreamHandler) to capture the exact outbound form/XML and inbound return. Datatrans support will ask for the refno and uppTransactionId — log both on every request.
  • Extension points: decorate the bundle's client service (decorates: in services.yml) rather than subclassing; override endpoint/host parameters via the config tree if present, otherwise a compiler pass that mutates the service definition after the bundle load.
  • Doctrine mapping conflicts: if you already have your own payment entities, do not enable JMS's mapping — use the bundle's client service only and manage your own persistence. Mixed mappings are a common source of "table already exists" migrations.
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