andreighioc / btipay
Banca Transilvania Payment Gateway for Laravel
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/http: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
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โ configurationdatabase/migrations/โBtiPay_transactionstableapp/Http/Controllers/BtiPayController.phpโ complete controller withpay,process,finishroutes/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