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

Authorizenet Bundle Laravel Package

paymentsuite/authorizenet-bundle

PaymentSuite integration for Authorize.Net that lets PHP applications route card payments through Authorize.Net’s gateway using configurable API credentials and PaymentSuite’s standard payment workflow, simplifying gateway setup within existing PaymentSuite-based projects.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framing: despite the Laravel prompt, paymentsuite/authorizenet-bundle is a Symfony 2.x bundle, not a Laravel package. It ships a DependencyInjection/AuthorizenetExtension, a Resources/config/services.xml, and Symfony routes. On a modern Laravel app you cannot composer require it and use it — the constraints (symfony/symfony ~2.3`, PHP 5.3+) and the 2014 last-release date mean it will not resolve on PHP 8 / Laravel 10+. Treat it as reference source code, not a dependency.

What to read first:

  1. AuthorizenetMethod.php — the thing that implements PaymentMethodInterface. This is where the authorize/capture flow lives and where the Authorize.net AIM payload is assembled.
  2. AuthorizenetManager.php — the network layer that actually posts to Authorize.net. This is the only piece genuinely worth porting.
  3. Resources/config/services.xml — shows the service IDs and constructor args (login_id, transaction_key, test), which tells you exactly which credentials the manager needs.
  4. Resources/config/routing.yml — the execute/success route names you'll need to replicate (or skip) if you reimplement.

Minimal Symfony wiring (for context — what the bundle expects):

# config.yml
authorizenet_bundle:
    login_id:        "%authorizenet.login_id%"
    transaction_key: "%authorizenet.transaction_key%"
    test:            true
    method_name:     authorizenet
// any controller
$method = $this->get('authorizenet.method');   // AuthorizenetMethod
$method->processPayment();                      // hits Authorize.net AIM

First real use case in Laravel: open AuthorizenetManager.php, copy the AIM POST body (x_login, x_tran_key, x_version, x_delim_data, x_amount, x_card_num, x_exp_date, x_type=AUTH_CAPTURE), and wrap it in a Laravel service using the Http facade. That is the practical "getting started" — you're harvesting the API call, not the bundle.

Implementation Patterns

The bundle follows PaymentSuite's core-bundle contract. Understanding the three moving parts makes the code readable even if you never run it:

1. Method lifecycle (PaymentMethodInterface)

interface PaymentMethodInterface {
    public function processPayment();   // charge / authorize
    public function getView();          // returns a PaymentMethodView (Blade-ish form data)
    public function getName();          // "authorizenet"
}

AuthorizenetMethod::processPayment() pulls the amount from the bound PaymentBridge, calls AuthorizenetManager::process(), and dispatches a payment event. getView() returns the fields your form template renders — card number, expiry, CVC. In Laravel terms: a PaymentGateway class with a charge(Order $order, array $card): TransactionResult method plus a viewData() that feeds your Blade form.

2. Bridge pattern (PaymentBridgeInterface)

PaymentSuite decouples the bundle from your domain model. Your Order implements PaymentBridgeInterface (getAmount(), getCurrency(), getOrderId()), and the bundle only ever talks to the bridge. This is the one pattern worth keeping in a Laravel port:

interface PaymentBridge {
    public function getAmount(): int;       // in minor units
    public function getCurrency(): string;
    public function getOrderId(): string;
}

3. Events

The bundle dispatches authorizenet.payment.success / authorizenet.payment.failed via PaymentEvent. In Laravel this maps cleanly to Event::dispatch(new PaymentSucceeded($order)) from inside your service — listeners handle order fulfilment and receipts.

Day-to-day workflow you'd actually build (Laravel):

final class AuthorizeNetGateway
{
    public function __construct(
        private string $loginId,
        private string $transactionKey,
        private bool $test,
    ) {}

    public function charge(Order $order, Card $card): TransactionResult
    {
        $response = Http::asForm()->post(
            $this->test
                ? 'https://test.authorize.net/gateway/transact.dll'
                : 'https://secure.authorize.net/gateway/transact.dll',
            [
                'x_login'          => $this->loginId,
                'x_tran_key'       => $this->transactionKey,
                'x_version'        => '3.1',
                'x_delim_data'     => 'TRUE',
                'x_delim_char'     => '|',
                'x_relay_response' => 'FALSE',
                'x_type'           => 'AUTH_CAPTURE',
                'x_method'         => 'CC',
                'x_amount'        => number_format($order->total / 100, 2, '.', ''),
                'x_card_num'      => $card->number,
                'x_exp_date'      => $card->expiry, // MMYY
                'x_invoice_num'   => $order->id,
            ],
        );

        return TransactionResult::fromDelimited($response->body());
    }
}

Bind it in a service provider and inject it into a ProcessPayment job. That's the whole package, ported.

Integration tips

  • Use AUTH_ONLY + PRIOR_AUTH_CAPTURE (pass x_trans_id) if you ship-then-capture; AUTH_CAPTURE is the default in this bundle and captures immediately.
  • Persist the raw delimited response string in a payment_responses table alongside the parsed fields — you will need it for reconciliation.
  • Guard with DB::transaction(...) around the order-state update after a successful charge, and always store x_trans_id before firing fulfilment.

Gotchas and Tips

  • Framework/PHP mismatch. composer install will fail on PHP 8.2; Symfony 2.x bundles are not compatible with Symfony 5/6 either. Do not attempt to wire this into a Laravel app — extract and rewrite.
  • Delimited response parsing is fragile. Authorize.net returns pipe-delimited fields with no escaping for embedded pipes in the response text (field 8). The bundle splits by | and indexes positionally. If a customer response or AVS message contains |, positions shift. Use x_delim_char that won't appear in the payload (e.g. | is still risky — many ports switch to , plus x_encap_char), or better, use Authorize.net's JSON/XML API for new work.
  • Cents vs dollars. PaymentSuite's PaymentBridge::getAmount() is in minor units but AIM x_amount is a decimal string. The bundle divides by 100 internally; if you port carelessly you'll charge 100× or 1/100×. Assert on amount in tests.
  • Test mode is a payload flag, not a URL. The manager sets x_test_request=TRUE rather than switching endpoints — the transact.dll URL is the same. A common bug is pointing at the sandbox hostname with test credentials; the two must agree.
  • Credentials live in YAML. There's no secrets abstraction; login_id/transaction_key are plain parameters. In a port, use config/services.php + env() and never log the request body (it contains the PAN).
  • CVC and expiry are string-matched, not validated. The bundle forwards whatever the form view produced. Validate and normalise expiry to MMYY (not MM/YY) before sending, or Authorize.net returns a generic decline.
  • Extension point: the manager is registered under authorizenet.manager; the "supported" way to customise was a compiler pass or overriding the service definition. In a Laravel port, make AuthorizeNetGateway an interface so you can swap in a fake in tests without hitting the network.
  • Debugging declines: response code 2 = decline, 3 = error, 4 = held for review. The bundle collapses these into a boolean-ish failure. Capture x_response_reason_text (field 4) — that's the message support will ask for.
  • No idempotency, no refunds, no void, no webhooks in this bundle. Those are separate Authorize.net calls (x_type=VOID / REFUND / CREDIT) you'll implement yourself. Don't assume the bundle covers lifecycle beyond a single charge.
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