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

Omnipay Komoju Laravel Package

vink/omnipay-komoju

View on GitHub
Deep Wiki
Context7

Getting Started

composer require vink/omnipay-komoju

Before you write a line of code, open the package's composer.json and src/ directory. Two things you need to confirm because they are not obvious from the README:

  1. The PSR-4 namespace (likely Vink\Komoju\ or Vink\OmnipayKomoju\). You need it to instantiate the gateway by FQCN, which is the safe path since this driver is not registered under Omnipay's built-in short-name map.
  2. The Omnipay major version it targets. A 2015 release almost certainly depends on omnipay/common ~2.0, which is a different API surface from 3.x.

Minimal usage:

use Omnipay\Omnipay;

$gateway = Omnipay::create('\Vink\Komoju\Gateway'); // use the FQCN from composer.json
$gateway->initialize([
    'secretKey' => config('services.komoju.secret'),
    // 'testMode' => true, // if supported — check getDefaultParameters()
]);

$response = $gateway->purchase([
    'amount'      => 1200,      // JPY is zero-decimal; 1200 = ¥1,200
    'currency'    => 'JPY',
    'token'       => $tokenFromKomojuJs,
    'description' => 'Order #1042',
])->send();

if ($response->isSuccessful()) {
    $paymentId = $response->getTransactionReference();
}

First real use case: a one-off credit card purchase using a Komoju.js token. Komoju does not expect raw PAN data through a server-side API, so generate the token in the browser with their JS library, POST it to your server, and hand it to Omnipay as token. This is the only flow you can validate end-to-end in an afternoon.

Get sandbox credentials from the Komoju dashboard (test mode toggles a separate key), and hit the sandbox before wiring anything into a checkout.

Implementation Patterns

Register the gateway once, inject it. Don't call Omnipay::create() in controllers. Bind it in a service provider so tests can swap it:

$this->app->singleton('komoju', fn () => Omnipay::create('\Vink\Komoju\Gateway')
    ->initialize(['secretKey' => config('services.komoju.secret')]));

Two-step authorize/capture for credit cards. Komoju supports capture-on-authorize and delayed capture. Use authorize() when you need to validate the card before fulfilment, then capture() with the transaction reference:

$auth = $gateway->authorize([...])->send();
// later, on shipment
$capture = $gateway->capture([
    'transactionReference' => $auth->getTransactionReference(),
    'amount' => 1200,
])->send();

Async payment methods need a different branch. Konbini, bank transfer, Pay-easy and the various prepaid/wallet methods do not settle synchronously. Komoju returns a payment in pending status with a redirect or instructions. Treat $response->isSuccessful() as "accepted", not "paid":

if ($response->isRedirect()) {
    return redirect($response->getRedirectUrl());
}

Persist your own status column, keyed on the Komoju payment ID, and only mark an order paid when you see the webhook.

Webhooks are the source of truth. The driver in all likelihood does not ship a webhook request class (Omnipay drivers rarely did in 2015), so accept the POST yourself, verify the signature using the webhook secret configured in the Komoju dashboard, and reconcile by payment ID:

Route::post('/webhooks/komoju', function (Request $request) {
    // verify signature header against HMAC of $request->getContent()
    $event   = $request->input('event');   // e.g. payment.captured / payment.refunded
    $payment = $request->input('data');
    // look up order by $payment['id'], update status idempotently
    return response()->noContent();
});

Make the handler idempotent — Komoju retries, and replayed captures should be no-ops.

Refunds and partial refunds. refund() takes transactionReference plus amount. Omit the amount for a full refund; pass an explicit amount for partials. Track refund amounts on your side since Komoju's response gives you a refund object, not a running ledger.

Testing. Don't mock the gateway — inject a fake HTTP client. Under Omnipay 2 this is a Guzzle 3/5 client; pass a MockHandler via the gateway constructor to assert the exact JSON you send, which is the fastest way to discover what the driver actually serialises (field names, amount vs total, etc.).

Gotchas and Tips

  • Omnipay 2 vs 3 is a hard wall. If your app is on omnipay/common ^3, composer will refuse to install this. There is no upgrade path in the package itself; you would fork and port the request classes (mostly namespace and constructor changes) or write the ~150 lines of Komoju REST calls yourself. For a 3-star, no-dependent package from 2015, the fork is often cheaper than debugging the original.
  • Amount units. Omnipay's Amount helper can convert to minor units. JPY has none, so 1200 means ¥1,200 — do not multiply by 100. Watch out if you copy patterns from a USD integration.
  • Token, not card. Check supportsToken() / supportsCard() on the gateway before assuming. If the driver only supports token, passing an Omnipay\Common\CreditCard will either throw or fail silently at the API.
  • Auth is basic-auth with the secret key as username. If you see 401s, verify the key was passed through initialize() and that getDefaultParameters() actually declares secretKey — a mismatched key name will be silently ignored.
  • API drift. Komoju's API has changed since 2015 (base URL, some payment method identifiers, webhook payload shape). Run the sandbox suite against every method you enable, especially konbini, before launching. Read the current Komoju API docs alongside the driver source, not the driver's README.
  • Error mapping is shallow. Expect getMessage() to be Komoju's raw error.message and little more. Log $response->getData() (full decoded body) on failures — you will want it, because the driver won't give you structured error codes.
  • Debugging HTTP. Inject a logging HTTP client into the gateway constructor to see raw requests/responses. This is the single highest-value five minutes you'll spend with this package.
  • Extension point. Every request comes from createRequest() in the Gateway. Subclass the gateway, override it, and add your own AbstractRequest subclasses for endpoints the driver omitted (e.g. void/cancel, if absent) rather than editing vendor code.
  • Treat it as a reference implementation. At 3 stars and zero dependents, assume the happy path works and the edges don't. Budget for reading src/ in full — it's small — and keep the Komoju dashboard open in another tab.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin