PHPackages                             laragear/transbank - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. laragear/transbank

ActiveLibrary[API Development](/categories/api)

laragear/transbank
==================

Easy-to-use Transbank SDK for PHP.

v4.0.0(2mo ago)31.1k↓46.7%MITPHPPHP ^8.3CI passing

Since Feb 23Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/Laragear/Transbank)[ Packagist](https://packagist.org/packages/laragear/transbank)[ Fund](https://github.com/sponsors/DarkGhostHunter)[ Fund](https://paypal.me/darkghosthunter)[ RSS](/packages/laragear-transbank/feed)WikiDiscussions 4.x Synced 1mo ago

READMEChangelog (10)Dependencies (18)Versions (25)Used By (0)

Transbank
=========

[](#transbank)

[![Latest Version on Packagist](https://camo.githubusercontent.com/fcbca0d89c367c88401979209c5d7291a88cbfb181e9f04c19ad369eeff3c879/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c617261676561722f7472616e7362616e6b2e737667)](https://packagist.org/packages/laragear/transbank)[![Latest stable test run](https://github.com/Laragear/Transbank/workflows/Tests/badge.svg)](https://github.com/Laragear/Transbank/actions)[![Codecov Coverage](https://camo.githubusercontent.com/400361c690755fba3075607a0fd26fc6a0fc759189ed2287d21275e9200d6e84/68747470733a2f2f636f6465636f762e696f2f67682f4c617261676561722f5472616e7362616e6b2f67726170682f62616467652e7376673f746f6b656e3d4c4b6e766533506b526c)](https://codecov.io/gh/Laragear/Transbank)[![Maintainability](https://camo.githubusercontent.com/f1903fe1d800e1828d3ee687064c92a61dd41ae854652607fd9e292bda838a5f/68747470733a2f2f716c74792e73682f6261646765732f63363937353037322d643935332d346430612d616236612d3163346534373564623266352f6d61696e7461696e6162696c6974792e737667)](https://qlty.sh/gh/Laragear/projects/Transbank)[![Sonarcloud Status](https://camo.githubusercontent.com/93a0e6f9116476f7841c6b3b99efb68e208efb500a6a05cb498bb1ec3aab6682/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4c617261676561725f5472616e7362616e6b266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/dashboard?id=Laragear_Transbank)[![Laravel Octane Compatibility](https://camo.githubusercontent.com/70359a356da237cd29561bc5d0bb80baae775b5ff62f288ed324755382858342/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2532304f6374616e652d436f6d70617469626c652d737563636573733f7374796c653d666c6174266c6f676f3d6c61726176656c)](https://laravel.com/docs/13.x/octane#introduction)

Easy-to-use Transbank SDK for PHP for Webpay, Webpay Mall, and Oneclick Mall.

```
use Laragear\Transbank\Facades\Webpay;
use Laragear\Transbank\Http\Requests\WebpayRequest;

public function pay(Request $request)
{
    return Webpay::create('pink teddy bear', 1990, url('confirm'));
}

public function confirm(WebpayRequest $payment)
{
    if ($payment->isSuccessful()) {
        return 'Your pink teddy bear is on the way!';
    };
}
```

Note

Only supports Webpay and Oneclick Mall at the moment. Other services are planned based on support.

Become a sponsor
----------------

[](#become-a-sponsor)

[![](.github/assets/support.png)](https://github.com/sponsors/DarkGhostHunter)

Your support allows me to keep this package free, up-to-date, and maintainable. Alternatively, you can **[spread the word!](http://twitter.com/share?text=I%20am%20using%20this%20cool%20PHP%20package&url=https://github.com%2FLaragear%2FReCaptcha&hashtags=PHP,Laravel,Transbank,WebPay)**

Requisites
----------

[](#requisites)

- PHP 8.3 or later
- Laravel 12 or later

Installation
============

[](#installation)

You can install the package via Composer:

```
composer require laragear/transbank
```

Usage
-----

[](#usage)

This SDK mimics all the Webpay methods from the [official Transbank SDK for PHP](https://github.com/TransbankDevelopers/transbank-sdk-php).

You can check the documentation of these services in Transbank Developer's site.

- [Webpay](https://www.transbankdevelopers.cl/documentacion/webpay-plus#webpay-plus)

Quickstart
----------

[](#quickstart)

Use the service facade you want to make a payment for.

For example, to make a payment request, use `Webpay::create()`, along with the URL to return to your application once the payment is done. The order should be a unique string with a 26-character maximum (like an ULID) to identify the transaction.

```
use Illuminate\Support\Str;
use Laragear\Transbank\Facades\Webpay;

public function pay()
{
    $order = Str::ulid();

    return Webpay::create($order, 1990, route('confirm'));
}
```

Once done, you can confirm the payment using the convenient `WebpayRequest` in your controller.

This request object exposes the `isSuccessful()` method to check if the transaction was successful or failed by any reason, and the `buyOrder()` method to retrieve the buy order set by your application.

```
use Laragear\Transbank\Http\Requests\WebpayRequest;

public function confirm(WebpayRequest $request)
{
    if ($request->isSuccessful()) {
        $order = $request->buyOrder();

        return "Your payment was successful! Follow your order as #$order.";
    };

    return 'Your payment failed. Try again!'
}
```

### Checking the transaction status

[](#checking-the-transaction-status)

When the WebPay Request is received by your application, the `TBK_TOKEN` query parameter will be sent to your application if the transaction resulted in an error, along the `TBK_ORDEN_COMPRA` query parameter for the `buy_order` you have set for your transaction.

Because Transbank may return an error if the transaction was aborted, failed, or invalid, it's imperative to use `isSuccessful()` before retrieving a failed transaction that may yield an exception by the library.

```
use Laragear\Transbank\Http\Requests\WebpayRequest;
use App\Models\Checkout;
use App\Events\CheckoutPaid;

public function confirm(WebpayRequest $request)
{
    if ($request->isSuccessful()) {
        // Assume the transaction was successful, consolidate the checkout.
        CheckoutPaid::dispatch($request->buyOrder(), $request->transaction())

        // ...
    };

    // Assume the transaction failed.
    Checkout::whereKey($request->buyOrder())->update([
        'failed_at' => now()
    ]);

    // ...
}
```

### Validating Transbank Requests

[](#validating-transbank-requests)

If a user or bot hits your "return" URL without the transaction token, an exception will be thrown by your application. To avoid this, you may enable validation to redirect the browser to your application home or any other given relative path. You may enable this in your `bootstrap/app.php` or `AppServiceProvider` at boot time.

```
use Illuminate\Foundation\Application;
use Laragear\Transbank\Http\Requests\WebpayRequest;

return Application::configure(basePath: dirname(__DIR__))
    ->booted(function (): void {
        WebpayRequest::$validate = '/payment/path';
    })->create();
```

Alternatively, you may control the path the user should be redirected to using a callback. Since the callback is resolved by the Service Container, you may type-hint the current Request or any other service you need.

```
use Illuminate\Routing\Redirector;
use Laragear\Transbank\Http\Requests\WebpayRequest;

WebpayRequest::$validate = function (Redirector $redirect) {
    return $redirect->route('payments.webpay')
};
```

Environments and credentials
----------------------------

[](#environments-and-credentials)

By default, this SDK starts up in **integration** environment, where all transactions made are fake by using Transbank's own *integration* server, and it comes with integration credentials.

Transbank will give you production credentials for each service you have contracted. You can them set them conveniently using the `.env` file.

```
WEBPAY_KEY=597055555532
WEBPAY_SECRET=579B532A7440BB0C9079DED94D31EA1615BACEB56610332264630D42D0A36B1C
```

To operate in production mode, where all transactions will be real, you will need to set the environment to `production` **explicitly** in using your `.env` environment file.

```
TRANSBANK_ENV=production
```

Note

Production keys don't work on *integration* and vice versa.

Middleware endpoint protection
------------------------------

[](#middleware-endpoint-protection)

You may want to use the included `transbank.protect` middleware to validate the transaction response from Transbank (the route which Transbank returns the user to). It will void any request without the proper tokens.

```
use Illuminate\Support\Facades\Route;

Route::get('confirm', function (WebpayRequest $request) {
    // ...
})->middleware('transbank.handle')
```

Additionally, you can enable [endpoint protection](#endpoint-protection) to only let Transbank requests to be allowed into the application.

Transaction Failure Middleware
------------------------------

[](#transaction-failure-middleware)

Transbank failure responses for transactions are sent using a `POST` request. **This disrupts the session** because these come back without cookies, hence a new empty session is generated. This renders authentication useless and loses refers or intended URLs.

To avoid that, use the convenient `RouteRedirect` facade to create a ready-made route that handles the `POST` failure request back to your application. When this redirection is processed, your browser sends its cookies to the application, recovering the session.

```
use Illuminate\Support\Facades\Route;
use Laragear\Transbank\Http\Requests\WebpayRequest;
use Laragear\Transbank\Facades\RouteRedirect;

Route::get('confirm', function (WebpayRequest $request) {
    // ...
})->middleware('transbank.protect');

RouteRedirect::as('confirm');
```

By default, the redirection uses the same path, but you can change it using a second parameter.

```
use Illuminate\Support\Facades\Route;
use Laragear\Transbank\Http\Requests\WebpayRequest;
use Laragear\Transbank\Facades\RouteRedirect;

Route::get('confirm', function (WebpayRequest $request) {
    // ... Handle the successful transaction.
})->middleware('transbank.protect');

Route::get('failed-transaction', function () {
    // ... Handle the failed transaction.
})->middleware('transbank.protect');

RouteRedirect::as('confirm', 'failed-transaction');
```

Important

If you're using you own middleware to verify CSRF/XSRF tokens, set the class in `RouteRedirect::$csrfMiddleware`.

Events
------

[](#events)

You will be able to hear all transactions started and completed. This package sends the following events:

- `TransactionCreating` before a transaction is created in Transbank.
- `TransactionCreated` after a transaction is created in Transbank, but pending payment.
- `TransactionCompleted` after a transaction or refund is completed in Transbank, regardless of the success.

Livewire Component
------------------

[](#livewire-component)

This package includes the [`Laragear/Transbank/Livewire/InteractsWithWebpay`](src/Livewire/InteractsWithWebpay.php) Liveware trait that automatically handles receiving a Webpay Transaction from Transbank [thanks to lifecycle hooks](https://livewire.laravel.com/docs/4.x/lifecycle-hooks#using-hooks-inside-a-trait).

This also includes the [`Laragear/Transbank/Livewire/InteractsWithOneclick`](src/Livewire/InteractsWithOneclick.php) Livewire trait to handle incoming registration attempts from Transbank.

The only requirement is to implement the `handleSuccessfulTransaction()` method, which receives the successful transaction or registration. For example, you may use this to mark a hypothetical "Cart" model as paid.

```
use App\Models\Checkout;
use Illuminate\Contracts\View\View;
use Laragear\Transbank\Livewire\InteractsWithWebpay;
use Laragear\Transbank\Services\Transactions\Transaction;
use Livewire\Component;

class Payment extends Component
{
    use InteractsWithWebpay;

    protected function handleSuccessfulTransaction(Transaction $transaction) : void
    {
        $checkout = Checkout::find($transaction->session_id);

        $checkout->markAsPaid();
    }

    public function render(): View
    {
        return view('cart.payment.status');
    }
}
```

For the case of Oneclick registration, you should implement the `handleSuccessfulRegistration()` in your component.

```
use App\Models\Checkout;
use Illuminate\Contracts\View\View;
use Laragear\Transbank\Livewire\InteractsWithOneclick;
use Laragear\Transbank\Services\Transactions\Transaction;
use Livewire\Component;

class Subscription extends Component
{
    use InteractsWithOneclick;

    protected function handleSuccessfulTransaction(Transaction $transaction) : void
    {
        auth()->user()->card()->updateOrCreate([
            'transbank_user' => $transaction->get('tbk_user')
            'card_type' => $transaction->get('card_type'),
            'card_number' => $transaction->getCreditCardNumber(),
        ]);
    }

    public function render(): View
    {
        return view('cart.subscription.status');
    }
}
```

Apart from the `$isSuccessful` property to check the transaction success, this trait also offers other methods you can override for your convenience:

- `handleWebpayException()`: Controls exceptions thrown by Webpay (like connection errors).
- `afterTransactionReceived()`: Handles the freshly retrieved transaction.
- `handleTransactionStatus()`: Handles how the transaction should be considered successful or failed.
- `handleFailedTransaction()`: Handles the Transaction when it has failed.
- `afterHandledTransaction()`: Handles the Transaction after failure or success.
- `handleNonWebpayResponse()`: Handles the component if no transaction was retrieved from Webpay.

Note

Similar methods are availble for the `InteractsWithOneclick` trait, like `handleNonOneclickResponse()`.

You can use these methods to show different messages to the user. For example, you can use `handleNonWebpayResponse()` to redirect the user back to the cart checkout route, or `handleFailedTransaction()` to store the failure for analytics.

The `handleWebpayException()` receives any exception, like connection errors or form aborts, and lets you handle it as you wish. For example, you may suppress the exception and render your component as not-successful. Otherwise, any Exception returned will be thrown as usual, so it's great to *replace* exceptions with your own.

```
use Laragear\Transbank\Exceptions\ClientException;
use Throwable;

public $title = '';
public $message = '';

protected function handleWebpayException(Throwable $exception)
{
    if ($exception instanceof ClientException) {
        $this->isSuccessful = false;
    } else {
        report($exception);

        $this->title = 'Transbank is unresponsive';
        $this->message = 'We will look into it as soon as possible.';
    }
}
```

The `afterTransactionReceived()` method is great to override when you require doing logic *after* the transaction has been received, but *before* any other logic. For example, to retrieve a Checkout process.

```
use App\Models\Checkout;
use Laragear\Transbank\Services\Transactions\Transaction;

public ?Checkout $checkout = null;

protected function afterTransactionReceived(Transaction $transaction): void
{
    if ($order = $transaction->get('buy_order')) {
        $this->checkout = Checkout::find($order)
    }
}
```

Additionally, you can override `handleTransactionStatus()` method for additional transaction checks, as its result will be stored in the `$isSuccessful` property. For example, you may deem the transaction failed if the payment does not match the Checkout amount.

```
use Filament\Notifications\Notification;
use Laragear\Transbank\Services\Transactions\Transaction;

public ?Checkout $checkout = null;

public function handleTransactionStatus(Transaction $transaction): bool
{
    return $transaction->isSuccessful()
        && $transaction->get('amount') === $this->chekout?->amount
}

protected function handleSuccessfulTransaction(Transaction $transaction) : void
{
    // Since the transaction was successful, the checkout exists.
    $this->checkout->markAsPaid();

    Notification::make('paid')
        ->title('Payment successful!')
        ->body('We will prepare your purchase as soon as possible.')
        ->send();
}
```

### Filament PHP Action

[](#filament-php-action)

If you use Filament PHP, you can use the [`Laragear\Transbank\Filament\WebpayAction`](src/Filament/WebpayAction.php) and [`Laragear\\Transbank\\Filament\\OneclickAction](src/Filament/OneclickAction.php) [Filament Actions](https://filamentphp.com/docs/5.x/actions/overview) to show a button that automatically creates a payment and redirects the user to Transbank for the payment flow.

You should use this [adding custom actions](https://filamentphp.com/docs/5.x/resources/editing-records#custom-actions), or anywhere you want. Simple use the `data()` or the methods `buyOrder()`, `amount()` and `returnUrl()` to set the minimum data to create a Transaction in Webpay servers, or `username()`, `email()` and `returnUrl()` for a Oneclick registration.

```
use App\Models\Checkout;
use Filament\Schemas\Schema;
use Illuminate\Support\Number;
use Laragear\Transbank\Filament\OneclickAction;use Laragear\Transbank\Filament\WebpayAction;

public ?Checkout $checkout = null;

public function mount()
{
    $this->chekout = Checkout::find(session('current_checkout_id'));
}

protected function getFormActions(): array
{
    return [
        ...parent::getFormActions(),
        WebpayAction::make('pay')
            ->label("Pay " . Number::currency($this->checkout->amount))
            ->data([
                'buyOrder' => $this->checkout->asUlid(),
                'amount' => $this->checkout->total(),
                'returnUrl' => action('App\Filament\Checkout\Pages\Checkout'),
            ]),
        OneclickAction::make('register')
            ->label('Pay automatically')
            ->data([
                'username' => auth()->user()->name,
                'email' => auth()->user()->email,
                'returnUrl' => action('App\Filament\Checkout\Pages\Register')
            ])
    ];
}
```

When clicking the `Pay with Webpay` button, a redirection will be returned so the user immediately start the payment flow.

For the case of the `OneclickAction`, a modal will be rendered to manually redirect the user to Transbank using a `POST` redirection.

Exceptions
----------

[](#exceptions)

All exceptions implement `TransbankException`, so you can catch and check what happened.

Important

Transactions properly rejected by banks or credit card issuers **do not** throw exceptions.

There are 4 types of exceptions:

- `ClientException`: Any error byproduct of bad transactions, misconfiguration, aborts, abandonment, timeout, or invalid values.
- `ServerException`: Any internal Transbank servers errors.
- `NetworkException`: Any communication error from Transbank Server, like network timeouts or wrong endpoints.
- `UnknownException`: Any other error.

Advanced configuration
----------------------

[](#advanced-configuration)

There is a handy configuration file you can use if you need nitpicking. Publish it with Artisan:

```
php artisan vendor:publish --provider="Laragear\Transbank\TransbankServiceProvider" --tag="config"
```

You will receive the `config/transbank.php` file with the following contents:

```
