PHPackages                             klc/tami-laravel - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. klc/tami-laravel

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

klc/tami-laravel
================

Tami sanal POS için Laravel-native paket — tip-güvenli, test edilebilir, güvenli

V0.2.0(2w ago)066↑218.2%MITPHPPHP ^8.2

Since May 19Pushed 2w agoCompare

[ Source](https://github.com/klc/tami-laravel)[ Packagist](https://packagist.org/packages/klc/tami-laravel)[ RSS](/packages/klc-tami-laravel/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (9)Versions (4)Used By (0)

Tami Laravel
============

[](#tami-laravel)

Tami sanal POS için Laravel-native paket. Tip-güvenli, test edilebilir, güvenli.

Kurulum
-------

[](#kurulum)

```
composer require klc/tami-laravel
```

Laravel 10.x+ ve PHP 8.1+ gerektirir. Paket auto-discovery ile otomatik yüklenir.

Konfigürasyon
-------------

[](#konfigürasyon)

```
php artisan vendor:publish --tag=tami-config
```

`.env` dosyasına aşağıdaki değişkenleri ekleyin:

```
TAMI_ENVIRONMENT=sandbox
TAMI_MERCHANT_ID=77006950
TAMI_TERMINAL_ID=84006953
TAMI_SECRET_KEY=your-secret-key
TAMI_JWK_KID=your-jwk-kid
TAMI_JWK_K=your-jwk-k
# Normal API response securityHash doğrulaması, Tami algoritması netleşene kadar kapalı kalmalıdır.
TAMI_RESPONSE_HASH_ENABLED=false
```

Canlı ortam için:

```
TAMI_ENVIRONMENT=production
TAMI_MERCHANT_ID=your-production-merchant
TAMI_TERMINAL_ID=your-production-terminal
TAMI_SECRET_KEY=your-production-secret
TAMI_JWK_KID=your-production-kid
TAMI_JWK_K=your-production-k
```

Kullanım
--------

[](#kullanım)

### Ödeme (Payment)

[](#ödeme-payment)

```
use Klc\Tami\Facades\Tami;
use Klc\Tami\DTOs\CardDto;
use Klc\Tami\DTOs\AddressDto;
use Klc\Tami\DTOs\BuyerDto;
use Klc\Tami\DTOs\BasketItemDto;
use Klc\Tami\DTOs\BasketDto;
use Klc\Tami\DTOs\Payment\AuthRequestDto;
use Klc\Tami\Enums\ItemType;
use Klc\Tami\Enums\PaymentChannel;

// Kart
$card = new CardDto(
    number: '4824910501747014',
    holderName: 'Örnek Kullanıcı',
    cvv: '123',
    expireMonth: 12,
    expireYear: 2026,
);

// Adres
$address = new AddressDto(
    address: 'Örnek Mah. Test Sk. No:1',
    city: 'İstanbul',
    companyName: 'Örnek Firma',
    country: 'Türkiye',
    district: 'Kadıköy',
    contactName: 'Örnek İletişim',
    phoneNumber: '05555555555',
    zipCode: '34700',
);

// Alıcı
$buyer = new BuyerDto(
    ipAddress: '127.0.0.1',
    buyerId: 'buyer-001',
	    name: 'Örnek',
	    surName: 'Kullanıcı',
	    emailAddress: 'ornek@eposta.com',
	    phoneNumber: '05555555555',
	    // Aşağıdaki alanlar Tami dokümanında opsiyonel/senaryoya bağlıdır.
	    identityNumber: '11111111111',
	    city: 'İstanbul',
	    country: 'Türkiye',
	    zipCode: '34700',
	    registrationAddress: 'Örnek Mah. Test Sk. No:1',
	    registrationDate: '2023-01-01T10:00:00',
	    lastLoginDate: '2023-06-01T10:00:00',
);

// Sepet
$item = new BasketItemDto(
	    itemId: 'item-001',
	    name: 'Örnek Ürün',
	    itemType: ItemType::Physical,
	    numberOfProducts: 1,
	    totalPrice: '100.00',
	    unitPrice: '100.00',
	    category: 'Elektronik',
	    subCategory: 'Bilgisayar',
);

$basket = new BasketDto('basket-001', [$item]);

// Ödeme isteği
	$dto = new AuthRequestDto(
	    orderId: 'order-' . uniqid(),
	    amount: '100.00',
    currency: 'TRY',
    installmentCount: 1,
    paymentGroup: 'PRODUCT',
    paymentChannel: PaymentChannel::Web,
    card: $card,
    billingAddress: $address,
    shippingAddress: $address,
    buyer: $buyer,
    basket: $basket,
);

// Ödemeyi gerçekleştir
$response = Tami::payment()->auth($dto);

if ($response->isSuccess()) {
    echo "Ödeme başarılı! Sipariş: " . $response->getOrderId();
} else {
    echo "Hata: " . $response->getErrorCode() . " - " . $response->getErrorMessage();
}
```

### 3D Secure Ödeme

[](#3d-secure-ödeme)

```
// Geri dönüş URL'si ile 3DS başlatma
	$authDto = new AuthRequestDto(
	    orderId: 'order-' . uniqid(),
	    amount: '100.00',
    currency: 'TRY',
    installmentCount: 1,
    paymentGroup: 'PRODUCT',
    paymentChannel: PaymentChannel::Web,
    card: $card,
    billingAddress: $address,
    shippingAddress: $address,
    buyer: $buyer,
    basket: $basket,
    callbackUrl: 'https://example.com/tami/callback',
);

$response = Tami::payment()->auth($authDto);

if ($response->is3dsRequired()) {
    echo $response->getHtmlContent(); // Banka 3DS sayfasına yönlendir
}
```

### 3DS Callback Yönetimi

[](#3ds-callback-yönetimi)

Paket otomatik olarak `POST /tami/callback` ve `GET /tami/callback` route'larını kaydeder. Callback payload'ında `hashedData` varsa paket Tami'nin 3DS HMAC-SHA256 formülüne göre doğrular; doğrulama başarısızsa `/payment/complete-3ds` çağrısı yapılmadan hata event'i yayınlanır. Başarılı/başarısız durumlar için event dinleyicileri:

```
// EventServiceProvider.php
use Klc\Tami\Events\TamiPaymentSucceeded;
use Klc\Tami\Events\TamiPaymentFailed;

protected $listen = [
    TamiPaymentSucceeded::class => [
        // Siparişi tamamla, stok düş, vs.
    ],
    TamiPaymentFailed::class => [
        // Hata logla, kullanıcıyı bilgilendir
    ],
];
```

### Ön Otorizasyon (Pre-Auth)

[](#ön-otorizasyon-pre-auth)

```
$preAuthResponse = Tami::payment()->preAuth($authDto);

// Daha sonra kapama (capture)
use Klc\Tami\DTOs\Payment\PostAuthRequestDto;

	$postAuthDto = new PostAuthRequestDto(
	    orderId: $preAuthResponse->getOrderId(),
	    amount: '100.00', // Kısmi kapama için daha düşük tutar
);
$captureResponse = Tami::payment()->postAuth($postAuthDto);
```

### İptal / İade

[](#i̇ptal--i̇ade)

```
use Klc\Tami\DTOs\Payment\ReverseRequestDto;

// Tam iade
$reverseDto = new ReverseRequestDto(orderId: 'order-123');
$reverseResponse = Tami::payment()->reverse($reverseDto);

// Kısmi iade
	$reverseDto = new ReverseRequestDto(
	    orderId: 'order-123',
	    amount: '50.00',
    reason: 'Kısmi iade',
);
$reverseResponse = Tami::payment()->reverse($reverseDto);
```

### Sipariş Sorgulama

[](#sipariş-sorgulama)

```
use Klc\Tami\DTOs\Payment\QueryRequestDto;

$queryDto = new QueryRequestDto(
    orderId: 'order-123',
    isTransactionDetail: true,
);
$queryResponse = Tami::payment()->query($queryDto);

echo "Sipariş Durumu: " . $queryResponse->getOrderStatus();
echo "Ödeme Durumu: " . $queryResponse->getPaymentStatus();
echo "Taksit Sayısı: " . $queryResponse->getInstallmentCount();
```

### Taksit ve Kart Bilgisi

[](#taksit-ve-kart-bilgisi)

```
use Klc\Tami\DTOs\Installment\BinInfoRequestDto;
use Klc\Tami\DTOs\Installment\InstallmentInfoRequestDto;

// BIN sorgulama
$binDto = new BinInfoRequestDto('48249105');
$binResponse = Tami::installment()->binInfo($binDto);

echo "Banka: " . $binResponse->getBankName();
echo "Kart Tipi: " . $binResponse->getCardType(); // CREDIT/DEBIT
echo "Kart Ağı: " . $binResponse->getCardOrg();   // VISA/MASTERCARD/TROY/AMEX

// Taksit seçenekleri
$installmentDto = new InstallmentInfoRequestDto('48249105');
$installmentResponse = Tami::installment()->installmentInfo($installmentDto);

$installments = $installmentResponse->getInstallments(); // [1, 3, 5]
$requires3ds = $installmentResponse->isForce3ds();
$requiresCvv = $installmentResponse->isForceCvc();
```

### Bonus / Puan Sorgulama

[](#bonus--puan-sorgulama)

```
use Klc\Tami\DTOs\Vas\BonusInquiryRequestDto;

$bonusDto = new BonusInquiryRequestDto(
    ipAddress: '127.0.0.1',
    emailAddress: 'ornek@eposta.com',
    cardNumber: '4824910501747014',
    expireMonth: 12,
    expireYear: 2026,
    currencyCode: 949, // TRY için 949
	    amount: '100.00',
);
$bonusResponse = Tami::vas()->bonusInquiry($bonusDto);

if ($bonusResponse->isApproved()) {
    foreach ($bonusResponse->getRewardList() as $reward) {
        echo $reward['type'] . ': ' . $reward['amount'];
    }
}
```

### Puanlı Satış

[](#puanlı-satış)

```
use Klc\Tami\DTOs\RewardDto;
use Klc\Tami\DTOs\RewardToBeUsedDto;

	$reward = new RewardDto(type: 'BNS', amount: '20.00');
$rewardToBeUsed = new RewardToBeUsedDto([$reward]);

$dto = new AuthRequestDto(
    // ... diğer alanlar
    orderId: 'order-' . uniqid(),
	    amount: '100.00',
    currency: 'TRY',
    installmentCount: 1,
    paymentGroup: 'PRODUCT',
    paymentChannel: PaymentChannel::Web,
    card: $card,
    billingAddress: $address,
    shippingAddress: $address,
    buyer: $buyer,
    basket: $basket,
    isRewardToBeUsed: true,
    rewardToBeUsed: $rewardToBeUsed,
);

$response = Tami::payment()->auth($dto);
```

### Ortak Ödeme Sayfası (Hosted Payment)

[](#ortak-ödeme-sayfası-hosted-payment)

Tami'nin sunduğu ortak ödeme sayfası entegrasyonu — işyerinin kart bilgisi toplamasına gerek kalmadan, ödeme sayfası Tami tarafından sunulur. Masterpass ile kayıtlı kartlarla veya yeni kart bilgisiyle ödeme yapılabilir.

**Token geçerlilik süresi:** Test ortamında 15 dakika, prod ortamda 6 dakika. Token alınır alınmaz kullanıcı sayfaya yönlendirilmelidir.

```
use Klc\Tami\Facades\Tami;
use Klc\Tami\DTOs\HostedToken\HostedTokenRequestDto;

// 1. Token oluştur
$dto = new HostedTokenRequestDto(
    amount: 150.00,
    orderId: 'order-' . uniqid(),
    successCallbackUrl: 'https://example.com/odeme/basarili',
    failCallbackUrl: 'https://example.com/odeme/basarisiz',
    mobilePhoneNumber: '905343000201', // 905xxxxxxxxx formatında zorunlu
    data: ['key-1' => 'extra-info'],   // opsiyonel
);

$response = Tami::hosted()->createToken($dto);

// 2. Kullanıcıyı ortak ödeme sayfasına yönlendir
return redirect($response->getPaymentUrl());
// → https://portal.tami.com.tr/hostedPaymentPage?token=...
```

**Callback yönetimi:** Başarılı ödemede Tami, `successCallbackUrl`'e yönlendirme yapar. Callback verisi taşımadığı için işlem durumunu Query servisi ile sorgulayın:

```
// successCallbackUrl handler'ında:
$queryResponse = Tami::payment()->query(new QueryRequestDto(
    orderId: $orderId,
    isTransactionDetail: true,
));

if ($queryResponse->getPaymentStatus() === 'SUCCESS') {
    // Siparişi tamamla
}
```

**Not:** `failCallbackUrl` şu an için Tami tarafından kullanılmamaktadır, `successCallbackUrl` ile aynı değer verilebilir. Hata durumunda kullanıcıya Tami sayfasında hata mesajı gösterilir.

Hata Yönetimi
-------------

[](#hata-yönetimi)

```
use Klc\Tami\Exceptions\TamiConnectionException;
use Klc\Tami\Exceptions\TamiAuthException;
use Klc\Tami\Exceptions\TamiApiException;
use Klc\Tami\Exceptions\TamiValidationException;
use Klc\Tami\Exceptions\TamiSecurityException;

try {
    $response = Tami::payment()->auth($dto);
} catch (TamiValidationException $e) {
    // DTO validasyon hatası
    $errors = $e->errors; // MessageBag
} catch (TamiConnectionException $e) {
    // Bağlantı hatası
} catch (TamiAuthException $e) {
    // Kimlik doğrulama hatası (HTTP 401)
} catch (TamiApiException $e) {
    // API hatası
    echo $e->errorCode;
    echo $e->errorMessage;
    echo $e->errorGroup;
} catch (TamiSecurityException $e) {
    // Security hash doğrulama hatası
}
```

Route Konfigürasyonu
--------------------

[](#route-konfigürasyonu)

```
# Route'ları kapat
TAMI_ROUTES_ENABLED=false

# Route ön eki
TAMI_ROUTES_PREFIX=payment

# Başarı/başarısızlık URL'leri
TAMI_SUCCESS_URL=/odeme/basarili
TAMI_FAILURE_URL=/odeme/basarisiz
```

Güvenlik Notları
----------------

[](#güvenlik-notları)

Paket, Tami'ye gönderilen request body için `securityHash` değerini Tami PHP örneğiyle uyumlu JWK/HS512 JWT algoritmasıyla üretir. `securityHash`, request body'ye eklenmeden önceki JSON üzerinden hesaplanır.

Normal API response'larında dönen `securityHash` için Tami PHP örneklerinde doğrulama algoritması bulunmadığı için bu paket o alanı yanlış algoritmayla doğrulamaya çalışmaz. `TAMI_RESPONSE_HASH_ENABLED=true` yapılırsa paket fail-closed davranır ve `TamiSecurityException` fırlatır. Bu ayarı ancak normal API response hash algoritması netleşip pakette ayrıca implemente edildikten sonra açın.

3DS callback payload'ında `hashedData` varsa paket bu değeri `secretKey` ile HMAC-SHA256 kullanarak doğrular. Callback payload'ına güvenip siparişi doğrudan tamamlamayın; paket callback sonrası server-to-server `/payment/complete-3ds` çağrısı yapar.

Test
----

[](#test)

```
# Docker ile (önerilen)
make test

# veya doğrudan
docker compose run --rm php vendor/bin/phpunit
```

3DS Callback ve CSRF
--------------------

[](#3ds-callback-ve-csrf)

3DS callback route'u varsayılan olarak `api` middleware ile kaydedilir — banka callback'i CSRF token taşımadığı için `web` middleware altında 419 hatası alabilir. Eğer `web` middleware kullanmak isterseniz `VerifyCsrfToken` middleware'ine `tami/callback` yolunu ekleyin:

```
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
    'tami/callback',
];
```

Lisans
------

[](#lisans)

MIT

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance96

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

3

Last Release

20d ago

PHP version history (2 changes)V0.1.0PHP ^8.1

V0.1.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/e71d284fd2e01efdb0eda7625243d46824c259137aeaba73b68b4e562cda5023?d=identicon)[klc](/maintainers/klc)

---

Top Contributors

[![klc](https://avatars.githubusercontent.com/u/26712751?v=4)](https://github.com/klc "klc (7 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/klc-tami-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/klc-tami-laravel/health.svg)](https://phpackages.com/packages/klc-tami-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k14.1M120](/packages/laravel-pulse)[flarum/core

Delightfully simple forum software.

261.4M2.2k](/packages/flarum-core)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
