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

Laravel Oneclick Laravel Package

sextanet/laravel-oneclick

Sextanet's Laravel OneClick package brings one-click convenience to Laravel apps, letting you trigger common setup and action flows from a single call. Lightweight, easy to configure, and designed to fit naturally into existing Laravel projects.

View on GitHub
Deep Wiki
Context7

Getting Started

First, a correction worth making up front: the package summary in some indexes describes magic-link auth or a shared-hosting web installer. That is wrong. sextanet/laravel-oneclick wraps Transbank Oneclick (Webpay Oneclick), the Chilean card-on-file payment gateway: you inscribe a card once, get a tbk_user token back, and then charge that token repeatedly without the cardholder present. Plan accordingly — this is a payments dependency, not an auth one.

  1. composer require sextanet/laravel-oneclick
  2. Publish the config: php artisan vendor:publish --tag=oneclick-config (check the provider for the exact tag).
  3. Put credentials in .env:
    ONECLICK_ENVIRONMENT=integration
    ONECLICK_COMMERCE_CODE=597055555541
    ONECLICK_API_KEY=<integration secret>
    
    The integration commerce code and secret are Transbank's public sandbox values — never ship them to production.
  4. Where to look first: config/oneclick.php for the credential/environment wiring, then src/ for the facade and the single client class behind it. The README is thin and there are no real docs, so the source is the documentation.

First use case to build: the inscription round-trip. A logged-in user clicks "Save card", you redirect them to Webpay, they return to a callback route, and you persist the resulting tbk_user on their account. Once that works, everything else (charging, deleting) is a short hop.

Implementation Patterns

Inscription (two routes, one controller). Route A builds the request and redirects out; route B receives the POST back from Transbank with a TBK_TOKEN in the body.

// POST /cards/inscribe
public function start(Request $request)
{
    $result = Oneclick::startInscription(
        username:   (string) $request->user()->id,
        email:      $request->user()->email,
        responseUrl: route('cards.callback'),
    );

    return redirect()->away($result->url);
}

// POST /cards/callback  (outside `auth`, see gotchas)
public function callback(Request $request)
{
    $result = Oneclick::finishInscription($request->input('TBK_TOKEN'));

    $request->user()->cards()->create([
        'tbk_user'    => $result->tbkUser,
        'card_type'   => $result->cardType,
        'last4'       => $result->last4,
    ]);

    return redirect()->route('billing.index');
}

Persist the token properly. tbk_user is a bearer credential — whoever holds it can charge the card. Cast it encrypted on the model, exclude it from $fillable mass-assignment where you can, and keep it out of toArray()/queue payloads.

Charging. parentBuyOrder identifies the basket, childBuyOrder the individual line; both must be unique across your commerce. Amounts are integers.

$charge = Oneclick::authorize(
    username:       (string) $order->user_id,
    tbkUser:        $card->tbk_user,
    parentBuyOrder: $order->number,      // ≤ 26 chars
    childBuyOrder:  "{$order->number}-1",
    amount:         (int) $order->total, // CLP, no decimals
);

if ($charge->responseCode !== 0) {
    throw new PaymentDeclined($charge->responseCode);
}

Wrap it, don't sprinkle it. Put a CardCharger / InscriptionService around the facade and dispatch a domain event (CardInscribed, PaymentCharged) for each result. Auditing is the whole reason to have an events layer here — when Transbank disputes a charge you want your own record of the buy orders and response codes.

Integration tips that save time:

  • Test against ONECLICK_ENVIRONMENT=integration with Transbank's published sandbox cards; production credentials will not work there and vice-versa.
  • Http::fake() the Transbank endpoints for unit tests, but keep at least one manual pass through the real sandbox — the redirect flow is where things break, not your JSON parsing.
  • If you support multiple merchants, bind a configured client instance per tenant in a service provider and resolve it from the container rather than reading the global config at call time.
  • php artisan config:cache after every env change during setup; stale config is the #1 "why is it hitting production" cause.

Gotchas and Tips

  • Amounts are integer CLP. No cents, no floats. 9990.0 will either fail validation or charge the wrong value.
  • Buy orders are unique forever. Retrying a failed authorize with the same buy order will be rejected. Generate a fresh child order on retry, or reconcile before re-attempting — never blind-retry inside a queued job.
  • Only responseCode === 0 is approved. Everything else is a failure with a distinct meaning; log the code rather than a boolean.
  • The callback route must be reachable without your auth middleware (Transbank POSTs from outside), but you still need to know which user is inscribing. Stash the user id in the session before redirecting, or use a signed URL as the responseUrl — Laravel's URL::temporarySignedRoute fits neatly here.
  • Users hit back / double-submit. finishInscription on an already-consumed token throws. Wrap both callback handlers in try/catch and render a friendly "card wasn't saved, try again" instead of a 500.
  • Redirect tokens expire fast. Don't build the inscription request and queue the email for later; create it at click time.
  • No refund/void in the wrapper. Reversals go through Transbank's separate transaction APIs or the merchant portal. Design your order model assuming a charge is final until an out-of-band reversal is recorded.
  • Set an HTTP timeout on the underlying client (5–10s). Transbank's endpoints occasionally hang, and a checkout request blocking a PHP-FPM worker is a bad afternoon.
  • Redact on log. Never log TBK_TOKEN, tbk_user, or the API key. Log the buy order, amount, and response code — that's enough to debug and safe to keep.
  • Version risk: 2.1.1 is a test-merge release with no functional change from 2.1.0, so pinning ^2.1 is safe. But the package is young and single-maintainer — read the diff before bumping a minor, and keep your own thin adapter layer so a breaking change is a one-file fix.
  • Ignore the internet. Blog posts and package-index summaries that describe this as a login-link or installer tool are describing something else entirely; if you follow them you'll spend an hour looking for a facade that doesn't exist.
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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core