andreighioc/btipay

Banca Transilvania Payment Gateway for Laravel

Maintainers

Package info

github.com/andreighioc/btipay

pkg:composer/andreighioc/btipay

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-04-14 21:38 UTC

This package is auto-updated.

Last update: 2026-04-14 21:56:54 UTC


README

๐Ÿ‡ท๐Ÿ‡ด Versiunea รฎn romรขnฤƒ

Laravel package for integrating with the Banca Transilvania iPay payment platform.

Supports 1-Phase payments (automatic capture) and 2-Phase payments (pre-authorization + manual deposit), refunds, reversals, transaction status verification, and loyalty point payments (StarBT).

Requirements

  • PHP 8.1+ (Laravel 13 requires PHP 8.3+)
  • Laravel 10, 11, 12 or 13
  • API credentials from Banca Transilvania

Installation

composer require BtiPay/laravel

Full installation (config, migrations, controller, routes, views):

php artisan BtiPay:install
php artisan migrate

The BtiPay:install command creates:

  • config/BtiPay.php โ€” configuration
  • database/migrations/ โ€” BtiPay_transactions table
  • app/Http/Controllers/BtiPayController.php โ€” complete controller with pay, process, finish
  • routes/BtiPay.php โ€” web routes (/BtiPay/pay, /BtiPay/process, /BtiPay/finish)
  • resources/views/BtiPay/ โ€” Blade views (pay.blade.php, finish.blade.php)

Optionally, publish only what you need:

php artisan BtiPay:install --controller   # controller only
php artisan BtiPay:install --routes       # routes only
php artisan BtiPay:install --views        # views only
php artisan BtiPay:install --force        # overwrite existing files

After installation, include the routes in your app. In routes/web.php:

require __DIR__.'/BtiPay.php';

Or in bootstrap/app.php (Laravel 11+):

->withRouting(
    web: __DIR__.'/../routes/web.php',
    then: function () {
        require base_path('routes/BtiPay.php');
    },
)

Configuration

Add to your .env:

BTIPAY_ENVIRONMENT=sandbox
BTIPAY_USERNAME=your_api_username
BTIPAY_PASSWORD=your_api_password
BTIPAY_AUTH_METHOD=header
BTIPAY_RETURN_URL=https://your-site.com/BtiPay/finish
BTIPAY_CURRENCY=946
BTIPAY_LANGUAGE=ro
BTIPAY_PAYMENT_TYPE=1phase
BTIPAY_LOGGING=true

Available Environments

Environment Description
sandbox Test environment (https://ecclients-sandbox.btrl.ro)
production Production environment (https://ecclients.btrl.ro)

Supported Currencies (ISO 4217)

Currency Code
RON 946
EUR 978
USD 840

Usage

1. Simple Payment (1-Phase)

use BtiPay\Laravel\Facades\BtiPay;
use BtiPay\Laravel\Builders\OrderBundle;

// Build orderBundle
$bundle = OrderBundle::make()
    ->orderCreationDate(now()->format('Y-m-d'))
    ->email('client@example.com')
    ->phone('40740123456')
    ->deliveryInfo('delivery', '642', 'Cluj-Napoca', 'Str. Example 10', '400000')
    ->billingInfo('642', 'Cluj-Napoca', 'Str. Example 10', '400000');

// Register order
$response = BtiPay::register([
    'orderNumber'  => 'ORD-' . time(),
    'amount'       => 1500, // 15.00 RON (in minor units / bani)
    'currency'     => 946,
    'returnUrl'    => route('BtiPay.finish'),
    'description'  => 'Order #123',
    'email'        => 'client@example.com',
    'orderBundle'  => $bundle->toArray(),
]);

if ($response->isSuccessful()) {
    // Redirect to the BT payment page
    return redirect($response->getFormUrl());
} else {
    // Registration error
    echo $response->getErrorMessage();
}

2. Pre-Authorized Payment (2-Phase)

// Register pre-authorization
$response = BtiPay::registerPreAuth([
    'orderNumber'  => 'ORD-' . time(),
    'amount'       => 5000, // 50.00 RON
    'returnUrl'    => route('BtiPay.finish'),
    'description'  => 'Delivery order #456',
    'orderBundle'  => $bundle->toArray(),
]);

// Redirect customer to formUrl...

// --- Later, upon delivery: Capture (deposit) ---
$depositResponse = BtiPay::deposit(
    orderId: $response->getOrderId(),
    amount: 5000
);

if ($depositResponse->isSuccessful()) {
    echo 'Payment captured successfully!';
}

3. Reversal (Cancel Pre-Authorization)

$reverseResponse = BtiPay::reverse(
    orderId: 'uuid-order-id'
);

4. Refund

// Partial refund
$refundResponse = BtiPay::refund(
    orderId: 'uuid-order-id',
    amount: 500 // Refund 5.00 RON
);

// Full refund
$refundResponse = BtiPay::refund(
    orderId: 'uuid-order-id',
    amount: 5000 // Refund full amount
);

5. Transaction Status Check

$status = BtiPay::getOrderStatus(orderId: 'uuid-order-id');

// or by orderNumber
$status = BtiPay::getOrderStatus(orderNumber: 'ORD-123');

if ($status->isPaid()) {
    echo 'Transaction completed successfully!';
    echo 'Amount: ' . $status->getAmountFormatted() . ' RON';
    echo 'Card: ' . $status->getMaskedPan();
} elseif ($status->isDeclined()) {
    echo 'Transaction declined: ' . $status->getActionCodeMessage();
}

6. Shortcut: Get Payment URL

$paymentUrl = BtiPay::getPaymentUrl(
    orderNumber: 'ORD-' . time(),
    amount: 2500,
    returnUrl: route('BtiPay.finish'),
    options: [
        'description' => 'Service payment',
        'email' => 'client@email.com',
    ]
);

return redirect($paymentUrl);

7. Finish Page (Return URL)

If you ran php artisan BtiPay:install, the controller and views are already created. The route GET /BtiPay/finish is automatically registered as BtiPay.finish.

The generated controller (BtiPayController) automatically handles:

  • Status verification via getOrderStatusExtended.do
  • Transaction update in the database (card, amount, RRN, ECI, etc.)
  • Display of all 22 required error messages
  • Retry restrictions for action codes 803, 804, 913
  • Event dispatch: PaymentCompleted / PaymentDeclined

For custom integration, you can use the facade directly:

$status = BtiPay::getOrderStatus(orderId: $request->get('orderId'));

if ($status->isPaid()) {
    // Payment successful - card, amount, RRN available
    $status->getMaskedPan();
    $status->getAmountFormatted();
    $status->getAuthRefNum();
}

if ($status->isDeclined()) {
    $status->getActionCodeMessage(); // message in the configured language
}

8. Tracking with BtiPayTransaction Model

use BtiPay\Laravel\Models\BtiPayTransaction;

// Create transaction
$transaction = BtiPayTransaction::create([
    'order_id'       => $response->getOrderId(),
    'order_number'   => 'ORD-123',
    'payment_type'   => '1phase',
    'amount'         => 1500,
    'currency'       => '946',
    'status'         => 'CREATED',
    'form_url'       => $response->getFormUrl(),
    'customer_email' => 'client@email.com',
]);

// Associate with a model (e.g. Order)
$order = Order::find(1);
$transaction->payable()->associate($order);
$transaction->save();

// Queries
BtiPayTransaction::successful()->get();     // All paid transactions
BtiPayTransaction::declined()->get();       // All declined
BtiPayTransaction::preAuthorized()->get();  // Awaiting deposit

9. Model Trait

use BtiPay\Laravel\Traits\HasBtiPayPayments;

class Order extends Model
{
    use HasBtiPayPayments;
}

// Usage
$order = Order::find(1);
$order->BtiPayTransactions;          // All transactions
$order->latestBtiPayTransaction;     // Latest transaction
$order->isPaidViaBtiPay();           // Is it paid?
$order->getTotalPaidViaBtiPay();     // Total paid (in minor units)
$order->getTotalRefundedViaBtiPay(); // Total refunded

10. Loyalty Point Payments (StarBT)

// Deposit with loyalty
$response = BtiPay::deposit(
    orderId: 'uuid-ron-order-id',
    amount: 3000, // Total amount RON + LOY
    depositLoyalty: true
);

// Refund with loyalty
$response = BtiPay::refund(
    orderId: 'uuid-ron-order-id',
    amount: 4000,
    refundLoyalty: true
);

// Reverse with loyalty
$response = BtiPay::reverse(
    orderId: 'uuid-ron-order-id',
    reverseLoyalty: true
);

Events

The package dispatches the following events that you can listen for:

Event Description
PaymentRegistered Payment has been registered with iPay
PaymentCompleted Payment completed successfully (DEPOSITED)
PaymentDeclined Payment was declined
PaymentRefunded Refund processed (partial or full)
// EventServiceProvider.php
protected $listen = [
    \BtiPay\Laravel\Events\PaymentCompleted::class => [
        \App\Listeners\SendPaymentConfirmation::class,
    ],
    \BtiPay\Laravel\Events\PaymentDeclined::class => [
        \App\Listeners\HandleFailedPayment::class,
    ],
];

Error Codes (Action Codes)

The 22 required error codes to handle per BT documentation:

Code Description
104 Restricted card
124 Transaction cannot be authorized per regulations
320 Inactive card
801 Issuer unavailable
803 Card blocked โš ๏ธ Do NOT retry with the same card!
804 Transaction not allowed โš ๏ธ Do NOT retry with the same card!
805 Transaction declined
861 Invalid expiration date
871 Invalid CVV
905 Invalid card
906 Expired card
913 Invalid transaction โš ๏ธ Do NOT retry with the same card!
914 Invalid account
915 Insufficient funds
917 Transaction limit exceeded
952 Suspected fraud
998 Installments not allowed with this card
341016 3DS2 authentication declined
341017 3DS2 status unknown
341018 3DS2 cancelled by customer
341019 3DS2 authentication failed
341020 3DS2 unknown status

Package Structure

BtiPay/
โ”œโ”€โ”€ config/
โ”‚   โ””โ”€โ”€ BtiPay.php                 # Configuration
โ”œโ”€โ”€ database/
โ”‚   โ””โ”€โ”€ migrations/                # Transactions table migration
โ”œโ”€โ”€ stubs/
โ”‚   โ”œโ”€โ”€ BtiPayController.php.stub  # Controller (published via BtiPay:install)
โ”‚   โ”œโ”€โ”€ BtiPay-routes.php.stub     # Routes (published via BtiPay:install)
โ”‚   โ””โ”€โ”€ views/
โ”‚       โ”œโ”€โ”€ pay.blade.php.stub     # Payment form
โ”‚       โ””โ”€โ”€ finish.blade.php.stub  # Finish page (success/error)
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ Builders/
โ”‚   โ”‚   โ””โ”€โ”€ OrderBundle.php        # Fluent builder for orderBundle
โ”‚   โ”œโ”€โ”€ Console/
โ”‚   โ”‚   โ””โ”€โ”€ InstallCommand.php     # php artisan BtiPay:install
โ”‚   โ”œโ”€โ”€ Enums/
โ”‚   โ”‚   โ”œโ”€โ”€ Currency.php           # Currency enum (RON/EUR/USD)
โ”‚   โ”‚   โ”œโ”€โ”€ OrderStatus.php        # Transaction status enum
โ”‚   โ”‚   โ””โ”€โ”€ PaymentType.php        # Payment type enum (1phase/2phase)
โ”‚   โ”œโ”€โ”€ Events/
โ”‚   โ”‚   โ”œโ”€โ”€ PaymentCompleted.php
โ”‚   โ”‚   โ”œโ”€โ”€ PaymentDeclined.php
โ”‚   โ”‚   โ”œโ”€โ”€ PaymentRefunded.php
โ”‚   โ”‚   โ””โ”€โ”€ PaymentRegistered.php
โ”‚   โ”œโ”€โ”€ Exceptions/
โ”‚   โ”‚   โ”œโ”€โ”€ BtiPayAuthenticationException.php
โ”‚   โ”‚   โ”œโ”€โ”€ BtiPayConnectionException.php
โ”‚   โ”‚   โ”œโ”€โ”€ BtiPayException.php
โ”‚   โ”‚   โ””โ”€โ”€ BtiPayValidationException.php
โ”‚   โ”œโ”€โ”€ Facades/
โ”‚   โ”‚   โ””โ”€โ”€ BtiPay.php             # Laravel Facade
โ”‚   โ”œโ”€โ”€ Models/
โ”‚   โ”‚   โ””โ”€โ”€ BtiPayTransaction.php  # Eloquent Model
โ”‚   โ”œโ”€โ”€ Responses/
โ”‚   โ”‚   โ”œโ”€โ”€ ActionCodeMessages.php  # Error messages (RO/EN)
โ”‚   โ”‚   โ”œโ”€โ”€ BaseResponse.php
โ”‚   โ”‚   โ”œโ”€โ”€ DepositResponse.php
โ”‚   โ”‚   โ”œโ”€โ”€ FinishedPaymentInfoResponse.php
โ”‚   โ”‚   โ”œโ”€โ”€ OrderStatusResponse.php
โ”‚   โ”‚   โ”œโ”€โ”€ RefundResponse.php
โ”‚   โ”‚   โ”œโ”€โ”€ RegisterResponse.php
โ”‚   โ”‚   โ””โ”€โ”€ ReverseResponse.php
โ”‚   โ”œโ”€โ”€ Traits/
โ”‚   โ”‚   โ””โ”€โ”€ HasBtiPayPayments.php  # Trait for models
โ”‚   โ”œโ”€โ”€ BtiPayClient.php           # HTTP Client
โ”‚   โ”œโ”€โ”€ BtiPayGateway.php          # Main Gateway
โ”‚   โ””โ”€โ”€ BtiPayServiceProvider.php  # Service Provider
โ”œโ”€โ”€ composer.json
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ README_RO.md

License

MIT License

Contact

For BT iPay API issues: aplicatiiecommerce@btrl.ro