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

Jms Payment Bridge Laravel Package

payum/jms-payment-bridge

Bridge between Payum and the JMS Payment library, adding gateway factories and actions so JMS payment gateways can run inside Payum's unified payment workflow. Useful for projects already on JMS Payment that want Payum's abstraction layer.

View on GitHub
Deep Wiki
Context7

Getting Started

Check compatibility before writing any code. The bridge was last released in 2016 and sits between two abandoned/rewritten dependencies: jmspaymentcorebundle (JMS Payment, effectively EOL) and Payum (which moved from 1.x to 2.x with renamed interfaces). Open composer.json first and note the pinned payum/core and symfony/* ranges — if they don't resolve against your app, stop and fork/vendor the bridge rather than fighting the resolver.

composer require payum/jms-payment-bridge
# then read vendor/payum/jms-payment-bridge/composer.json + src/

Where to look, in order:

  1. src/ — the gateway factory (the class implementing Payum's GatewayFactoryInterface). This is the entry point and tells you the config keys the bridge expects (plugin, payment_service, etc.).
  2. src/Action/ — the request handlers. These are where the actual adaptation happens: a Payum Capture/Status/Notify request gets translated into a call on the JMS PluginInterface / PaymentService.
  3. README.md / any Resources/config — service wiring and the factory name string (typically jms_payment).

Minimal first use case — wrap one existing JMS plugin (e.g. PayPal Express) and drive it through Payum's request/reply API so the rest of your app only depends on $gateway->execute(...):

$payum = (new PayumBuilder())
    ->addGatewayFactory(new JmsPaymentGatewayFactory())
    ->addGateway('jms_paypal', [
        'factory' => 'jms_payment',
        'plugin'  => 'jms_payment_paypal_express.plugin', // your JMS plugin service
        // return/cancel URL config consumed by the JMS plugin
    ])
    ->getPayum();

$gateway = $payum->getGateway('jms_paypal');
$gateway->execute($capture = new Capture($payment)); // $payment is a Payum Payment

In Symfony, register the same factory through the Payum bundle's gateway config and use the factory name instead of the class. Verify the exact key names against the factory's createConfig() — they are the bridge's public contract.

Implementation Patterns

Translate, don't mix. The bridge's whole job is Payum\Request → JMS PaymentInstruction → JMS plugin call → Payum\Reply. Keep that boundary intact: build the JMS PaymentInstruction inside the action, pass return/cancel URLs from Payum's token factory into it, then discard the JMS object. Application code should only ever see Payum Payment objects.

Persist the JMS instruction id, not the object. Store jms_instruction_id (and nothing else plugin-specific) in the Payum payment's details array. On Notify/callback you can rehydrate the instruction via the JMS PaymentService and let the status action reconcile. This also keeps your details blob small and non-PII.

Status mapping belongs in one place. JMS uses STATE_NEW, STATE_PENDING, STATE_APPROVED, STATE_DEPOSITING, STATE_DEPOSITED, STATE_FAILED; Payum uses Payment::STATUS_*. Write a single mapStatus() helper and unit-test every transition, because the status action is where mismatches silently turn a failed payment into a "captured" one.

Request/reply flow to wire up:

Payum request What the bridge action should do
Capture Create/approve the JMS instruction, call the plugin, return HttpRedirect or NullReply
Status Re-read the instruction, map state to Payment::STATUS_*, return NullReply
Notify Verify the callback (JMS plugin handles signature), re-enter status sync
Sync Reconcile after a redirect return, before Status

Add custom actions when the bridge is short. If it only implements Capture and your plugin needs refunds/voids, subclass or add your own ActionInterface and register it per-gateway:

->addGateway('jms_paypal', [
    'factory' => 'jms_payment',
    'actions' => [new MyRefundAction(), /* defaults appended after */],
])

Test at the action level, not end-to-end. Mock the JMS PluginInterface, feed the action a Request, and assert on the Reply type and the Payment status. Payum's test-case helpers (GatewayTestCase / ActionTestCase in 1.x) are the least painful route; do not try to spin up a fake JMS plugin controller.

Migration pattern. If you're moving a legacy JMS-based app to Payum, this bridge is a stepping stone: route new code through Payum first, keep the JMS plugin untouched behind the bridge, then swap the gateway factory for a native Payum gateway later. Do not build new features on the JMS side.

Gotchas and Tips

  • It will not install on modern stacks. Both sides of the bridge are dated; expect composer conflicts on PHP 8 / Symfony 5+. Fork the repo, bump constraints, run the actions against a current Payum — it's a few hundred lines of glue, not a framework.
  • Payum interface drift. Payum 1.0 renamed Instruction → Payment and replaced some request/reply interfaces. If the bridge tag predates your Payum version you'll see "class not found" or signature errors. Match the bridge tag to payum/core before debugging anything else; composer why payum/core is your first command.
  • Callback URL ownership is split. The JMS plugin builds return/cancel/notify URLs from its own routing config; Payum wants tokens. If the bridge doesn't forward Payum tokens into the instruction, callbacks won't carry a token and Notify will fail to resolve the payment. Check return_url on the plugin and whether the action overrides it.
  • Notify may bypass Payum entirely. JMS commonly expects its own PluginController endpoint to receive callbacks. If so, add a thin action that re-enters Payum with $gateway->execute(new Notify($token)) so the normal status/reply pipeline runs. Two callback paths is the classic bug here.
  • Never log the full JMS object. ExtendedData can carry tokens and PII, and Payum's Debug extension will dump whatever you pass through details. Log the instruction id and mapped status only.
  • Exception translation. JMS plugin exceptions are not Payum replies. Add a small action (registered first) that catches plugin exceptions and converts them to Cancel/Notify replies, otherwise failures escape the gateway and leave payments stuck in PENDING.
  • Debugging loop: enable Payum's Debug extension with a PSR-3 logger, log id, state, and mapped STATUS_* after every action; the JMS PaymentInstruction state after each step is the ground truth.
  • Treat it as unmaintained. 1 star, 0 dependents, last release 2016 — there is no upstream help. Vendor-copy or fork, add one smoke test per JMS plugin you bridge, and document the exact payum/core + JMS versions you validated against in your own README, because nobody else will.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log