MercanPay Blog

Laravel Kripto Ödeme Entegrasyonu: USDT ve TRX Adım Adım

Laravel kripto ödeme entegrasyonu: mercanpay-php ile servis bağlama, USD fiyatlı fatura, CSRF dışı webhook rotası ve kuyruklu, idempotent sipariş onayı.

Yayınlanma: 14 Kasım 202611 dk okumaRead in English
Laravel Kripto Ödeme Entegrasyonu: USDT ve TRX Adım Adım

Laravel kripto ödeme entegrasyonu, resmi mercanpay/mercanpay-php kütüphanesiyle birkaç dosyada tamamlanır. Kütüphaneyi servis konteynerine bağlar, ödeme sırasında USD fiyatlı bir fatura oluşturur, müşteriyi ödeme sayfasına yönlendirir ve imzalı webhook geldiğinde siparişi bir kuyruk işiyle onaylarsınız. Bu rehberde USDT ve TRX (TRC20) ödemelerini bir Laravel uygulamasına adım adım bağlıyoruz.

MercanPay için hazır bir Laravel paketi yoktur. Ancak PHP kütüphanesi bağımlılıksız ve sade olduğu için Laravel'in kendi araçlarıyla temiz bir entegrasyon kurmak kolaydır. Kütüphanenin genel kullanımını PHP ile kripto ödeme entegrasyonu yazımızda anlattık; burada Laravel'e özgü kısımlara odaklanıyoruz.

Gereksinimler

  • PHP 8 veya üzeri, ext-curl ve ext-json
  • Kuyruk sürücüsü yapılandırılmış bir Laravel uygulaması (örneklerde Laravel 11 yapısı kullanılıyor)
  • Onaylanmış bir MercanPay satıcı hesabı ve invoices yetkili bir API anahtarı

Hesabınız yoksa önce satıcı başvurusu yapmanız gerekir.

1. Kütüphaneyi kurun ve yapılandırın

composer require mercanpay/mercanpay-php

Anahtarları .env dosyasına ekleyin:

MERCANPAY_URL=https://mercanpay.com
MERCANPAY_API_KEY=mp_...
MERCANPAY_WEBHOOK_SECRET=whsec_...

config/services.php içine bir giriş ekleyin. Kod içinde env() yerine config() kullanmak, yapılandırma önbelleği (php artisan config:cache) açıkken de değerlerin doğru okunmasını sağlar:

// config/services.php
'mercanpay' => [
    'url'            => env('MERCANPAY_URL', 'https://mercanpay.com'),
    'key'            => env('MERCANPAY_API_KEY'),
    'webhook_secret' => env('MERCANPAY_WEBHOOK_SECRET'),
],

2. İstemciyi servis konteynerine bağlayın

İstemciyi AppServiceProvider içinde tekil (singleton) olarak kaydedin. Böylece controller'lara ve işlere bağımlılık olarak enjekte edebilirsiniz:

// app/Providers/AppServiceProvider.php
use MercanPay\MercanPay;

public function register(): void
{
    $this->app->singleton(MercanPay::class, fn () => new MercanPay(
        config('services.mercanpay.url'),
        config('services.mercanpay.key'),
    ));
}

3. Laravel ile kripto ödeme faturası oluşturun

Müşteri "Öde" butonuna bastığında bir controller faturayı oluşturur ve müşteriyi payment_url adresine yönlendirir:

// app/Http/Controllers/CheckoutController.php
namespace App\Http\Controllers;

use App\Models\Order;
use Illuminate\Support\Facades\Log;
use MercanPay\MercanPay;
use MercanPay\MercanPayException;

class CheckoutController extends Controller
{
    public function pay(Order $order, MercanPay $mercanpay)
    {
        try {
            $invoice = $mercanpay->createUsdInvoice($order->total_usd, [
                'order_id'    => 'order-' . $order->id,
                'description' => 'Sipariş #' . $order->id,
                'success_url' => route('orders.thanks', $order),
                'return_url'  => route('cart'),
                'metadata'    => ['user_id' => $order->user_id],
            ]);
        } catch (MercanPayException $e) {
            Log::warning('MercanPay', ['code' => $e->getErrorCode(), 'message' => $e->getMessage()]);
            return back()->withErrors(['payment' => 'Ödeme sayfası açılamadı, lütfen tekrar deneyin.']);
        }

        return redirect()->away($invoice['payment_url']);
    }
}

Dikkat edilecek noktalar:

  • Tutar metin olmalı. total_usd sütununu decimal olarak tutun ve metin olarak gönderin (ör. '49.90'). Float kullanmayın.
  • order_id idempotenttir. Aynı order_id ile yapılan ikinci istek yeni fatura açmaz, mevcut faturayı döndürür. Kullanıcı butona iki kez bassa bile çift fatura oluşmaz. Ayrıntılar order_id ile fatura-sipariş eşleştirme yazımızda.
  • Coin seçimi müşteride. createUsdInvoice ile müşteri ödeme sayfasında TRX ya da USDT seçer. Yalnızca USDT istiyorsanız 'tokens' => ['USDT'] ekleyin.
  • Minimum fatura 10

4. Webhook rotasını CSRF korumasından çıkarın

Laravel, web rotalarındaki POST isteklerinde CSRF belirteci ister. MercanPay'in sunucudan gönderdiği webhook'ta bu belirteç olmaz, bu yüzden webhook rotasını CSRF doğrulamasından muaf tutmanız gerekir. Güvenliği CSRF yerine HMAC imzası sağlar.

// routes/web.php
use App\Http\Controllers\MercanPayWebhookController;

Route::post('/mercanpay/webhook', MercanPayWebhookController::class)->name('mercanpay.webhook');
// bootstrap/app.php (Laravel 11)
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['mercanpay/webhook']);
})

Laravel 10 ve öncesinde aynı adresi app/Http/Middleware/VerifyCsrfToken.php içindeki $except dizisine eklersiniz. Webhook adresinizi panelde Ayarlar → Webhook URL alanına girin.

5. İmzayı doğrulayın ve işi kuyruğa verin

İmza, isteğin ham gövdesi üzerinden hesaplanır. Bu yüzden $request->all() ya da $request->json() değil, $request->getContent() kullanın:

// app/Http/Controllers/MercanPayWebhookController.php
namespace App\Http\Controllers;

use App\Jobs\HandleMercanPayEvent;
use Illuminate\Http\Request;
use MercanPay\MercanPay;

class MercanPayWebhookController extends Controller
{
    public function __invoke(Request $request)
    {
        $body   = $request->getContent();
        $header = (string) $request->header('X-MercanPay-Signature', '');

        if (!MercanPay::verifyWebhook(config('services.mercanpay.webhook_secret'), $body, $header)) {
            abort(401);
        }

        HandleMercanPayEvent::dispatch(json_decode($body, true));

        return response()->noContent(); // 204
    }
}

verifyWebhook, t=…,v1=… biçimindeki başlığı ayrıştırır, 5 dakikadan eski zaman damgalarını reddeder ve HMAC-SHA256 imzasını sabit zamanlı karşılaştırır. Teorisini webhook imzası doğrulama yazımızda anlattık.

İşi kuyruğa vermenin nedeni basittir: 10 saniye içinde 2xx yanıt dönmezseniz istek yeniden denenir. E-posta gönderme, lisans üretme gibi yavaş işler kuyrukta yapılırsa webhook yanıtı hızlı kalır.

6. Olayı idempotent biçimde işleyin

Webhook'lar yeniden denenebildiği için aynı olay size birden fazla kez ulaşabilir. Olay kimliğini (id) benzersiz bir sütunda saklayarak her olayı yalnızca bir kez işleyin:

// migration
Schema::create('processed_webhook_events', function (Blueprint $table) {
    $table->string('event_id')->primary();
    $table->timestamps();
});
// app/Jobs/HandleMercanPayEvent.php
namespace App\Jobs;

use App\Models\Order;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\DB;

class HandleMercanPayEvent implements ShouldQueue
{
    use Queueable;

    public function __construct(public array $event) {}

    public function handle(): void
    {
        DB::transaction(function () {
            $inserted = DB::table('processed_webhook_events')->insertOrIgnore([
                'event_id' => $this->event['id'], 'created_at' => now(), 'updated_at' => now(),
            ]);
            if ($inserted === 0) {
                return; // bu olay daha önce işlendi
            }

            $invoice = $this->event['data']['invoice'] ?? null;
            if (!$invoice) {
                return; // withdrawal.* ya da test.ping
            }
            $orderId = (int) str_replace('order-', '', $invoice['order_id']);

            match ($this->event['type']) {
                'invoice.paid', 'invoice.overpaid' => Order::whereKey($orderId)
                    ->where('status', '!=', 'paid')
                    ->update(['status' => 'paid', 'paid_token' => $invoice['token'], 'paid_amount' => $invoice['paid_amount']]),
                'invoice.partial' => Order::whereKey($orderId)->update(['status' => 'partially_paid']),
                'invoice.expired', 'invoice.cancelled' => Order::whereKey($orderId)
                    ->where('status', 'pending')->update(['status' => 'cancelled']),
                default => null,
            };
        });
    }
}

Laravel 10'da Queueable yerine Dispatchable, InteractsWithQueue, Queueable, SerializesModels trait'lerini kullanırsınız. Tekrar deneme ve idempotent işleme konusunu webhook yeniden deneme yazımızda derinlemesine ele aldık. Tüm olay türleri için webhook olay türleri rehberine bakabilirsiniz.

7. Teşekkür sayfasında API'ye sorun

success_url yönlendirmesi taklit edilebilir, bu yüzden siparişi oradan onaylamayın. Emin olmak istediğinizde API'ye sorun:

public function thanks(Order $order, MercanPay $mercanpay)
{
    $invoice = $mercanpay->getInvoiceByOrder('order-' . $order->id);
    $paid = in_array($invoice['status'], ['paid', 'overpaid'], true);

    return view('orders.thanks', compact('order', 'paid'));
}

Sık yapılan hatalar ve çözümleri

Laravel entegrasyonlarında sorunların büyük kısmı birkaç tanıdık noktadan çıkar. Canlıya geçmeden önce bunları tek tek gözden geçirmek, ilk gerçek ödemede sürprizle karşılaşmanızı önler.

Ham gövde yerine çözümlenmiş veriyi imzalamak

İmza, MercanPay'in gönderdiği baytların birebir aynısı üzerinden hesaplanır. $request->all() ile alınan diziyi yeniden JSON'a çevirirseniz boşluklar, anahtar sırası ya da sayı biçimi değişebilir ve imza tutmaz. Her zaman $request->getContent() ile gelen metni doğrulayın, JSON'u ancak doğrulamadan sonra çözün.

CSRF istisnasını unutmak

Webhook rotası web grubundaysa ve CSRF istisnasına eklenmemişse Laravel isteği daha controller'a ulaşmadan 419 ile reddeder. Bu durumda panelde Webhooklar sayfasındaki teslimat geçmişinde 419 yanıt kodunu görürsünüz. İstisnayı ekledikten sonra aynı olayı oradan yeniden gönderebilirsiniz.

Kuyruk çalışanının çalışmaması

Webhook 204 döndüğü için MercanPay açısından teslimat başarılıdır. Ancak kuyruk çalışanı durmuşsa iş hiç işlenmez ve siparişler "bekliyor" durumunda kalır. Canlıda queue:work sürecini bir süreç yöneticisiyle sürekli çalışır tutun ve başarısız işleri (failed_jobs) düzenli kontrol edin. Kuyruk sürücüsü sync ise iş istek içinde çalışır; bu geliştirmede kolaylık sağlar ama yavaş işler webhook yanıtını 10 saniyenin ötesine taşıyabilir.

Yapılandırma önbelleği ve env()

php artisan config:cache çalıştırıldıktan sonra kod içindeki env() çağrıları null döner. Anahtarı ve sırrı yalnızca config/services.php üzerinden okuduğunuzda bu sorun yaşanmaz. .env dosyasını değiştirdiğinizde önbelleği yeniden oluşturmayı unutmayın.

Sipariş durumunu koşulsuz güncellemek

Olaylar farklı sırayla ya da tekrar gelebilir. Örneğin where('status', '!=', 'paid') gibi koşullar, ödenmiş bir siparişin geç gelen bir olayla yanlışlıkla iptal durumuna düşmesini engeller. Her güncellemeyi "bu geçiş şu anki durumdan mantıklı mı?" sorusuyla yazın.

Test ve canlıya geçiş

Uçtan uca denemeyi üç adımda yapabilirsiniz:

  1. Bağlantıyı doğrulayın. Panelde Webhooklar → "Test gönder" ile bir test.ping olayı gönderin. Teslimat geçmişinde 2xx yanıt görmelisiniz. Job'ınız test.ping olayını sessizce atlar, çünkü içinde fatura yoktur.
  2. Fatura akışını deneyin. Küçük tutarlı gerçek bir sipariş oluşturun, ödeme sayfasına yönlendirildiğinizi ve success_url dönüşünde teşekkür sayfasının API'ye sorduğunu kontrol edin.
  3. Ödemeyi tamamlayın. Ödeme 20 onaydan sonra kesinleşir. invoice.paid olayı geldiğinde siparişin güncellendiğini ve processed_webhook_events tablosuna bir satır eklendiğini doğrulayın. Aynı olayı panelden yeniden gönderip siparişin ikinci kez işlenmediğini görün.

Canlıya geçmeden önce

  • API anahtarı ve webhook sırrı yalnızca .env içinde, depoda değil.
  • Webhook rotası CSRF'den muaf, imza doğrulaması açık.
  • Kuyruk çalışanı (php artisan queue:work) canlıda sürekli çalışıyor.
  • Panelde Webhooklar → "Test gönder" ile test.ping olayı başarıyla alındı.
  • Akış küçük tutarlı gerçek bir ödemeyle uçtan uca denendi.

Sık sorulan sorular

Hazır bir Laravel paketi var mı?

Hayır. Resmi PHP kütüphanesini yukarıdaki gibi servis konteynerine bağlayarak kullanırsınız. Bu yaklaşım birkaç dosyadan ibarettir ve tam kontrolü size bırakır.

Webhook'ta neden 419 hatası alıyorum?

419, CSRF doğrulamasının başarısız olduğunu gösterir. Webhook rotasını CSRF istisnalarına eklediğinizden emin olun.

İmza neden hep geçersiz çıkıyor?

En sık neden, ham gövde yerine çözümlenmiş JSON'u kullanmaktır. $request->getContent() kullanın ve gövdeyi değiştiren bir ara katman olmadığından emin olun. Sunucu saatinin doğru olması da gerekir.

Çekimleri Laravel'den yapabilir miyim?

Evet. withdrawals yetkili bir anahtarla createWithdrawal('USDT', '50', 'T...', 'benzersiz-anahtar') çağırabilirsiniz. Güvenlik gereği API çekimleri yalnızca panelde güvenilir olarak işaretlenmiş kayıtlı adreslere gider.

MercanPay ile başlayın

Laravel uygulamanıza USDT ve TRX ödemesi eklemek için satıcı başvurunuzu yapın, bir API anahtarı oluşturun ve ilk faturanızı kesin. Tüm alanlar ve hata kodları için dokümantasyonu inceleyin. dır. Ağ ücretleri müşterinin ödediği tutara dahildir.

4. Webhook rotasını CSRF korumasından çıkarın

Laravel, web rotalarındaki POST isteklerinde CSRF belirteci ister. MercanPay'in sunucudan gönderdiği webhook'ta bu belirteç olmaz, bu yüzden webhook rotasını CSRF doğrulamasından muaf tutmanız gerekir. Güvenliği CSRF yerine HMAC imzası sağlar.

// routes/web.php
use App\Http\Controllers\MercanPayWebhookController;

Route::post('/mercanpay/webhook', MercanPayWebhookController::class)->name('mercanpay.webhook');
// bootstrap/app.php (Laravel 11)
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['mercanpay/webhook']);
})

Laravel 10 ve öncesinde aynı adresi app/Http/Middleware/VerifyCsrfToken.php içindeki $except dizisine eklersiniz. Webhook adresinizi panelde Ayarlar → Webhook URL alanına girin.

5. İmzayı doğrulayın ve işi kuyruğa verin

İmza, isteğin ham gövdesi üzerinden hesaplanır. Bu yüzden $request->all() ya da $request->json() değil, $request->getContent() kullanın:

// app/Http/Controllers/MercanPayWebhookController.php
namespace App\Http\Controllers;

use App\Jobs\HandleMercanPayEvent;
use Illuminate\Http\Request;
use MercanPay\MercanPay;

class MercanPayWebhookController extends Controller
{
    public function __invoke(Request $request)
    {
        $body   = $request->getContent();
        $header = (string) $request->header('X-MercanPay-Signature', '');

        if (!MercanPay::verifyWebhook(config('services.mercanpay.webhook_secret'), $body, $header)) {
            abort(401);
        }

        HandleMercanPayEvent::dispatch(json_decode($body, true));

        return response()->noContent(); // 204
    }
}

verifyWebhook, t=…,v1=… biçimindeki başlığı ayrıştırır, 5 dakikadan eski zaman damgalarını reddeder ve HMAC-SHA256 imzasını sabit zamanlı karşılaştırır. Teorisini webhook imzası doğrulama yazımızda anlattık.

İşi kuyruğa vermenin nedeni basittir: 10 saniye içinde 2xx yanıt dönmezseniz istek yeniden denenir. E-posta gönderme, lisans üretme gibi yavaş işler kuyrukta yapılırsa webhook yanıtı hızlı kalır.

6. Olayı idempotent biçimde işleyin

Webhook'lar yeniden denenebildiği için aynı olay size birden fazla kez ulaşabilir. Olay kimliğini (id) benzersiz bir sütunda saklayarak her olayı yalnızca bir kez işleyin:

// migration
Schema::create('processed_webhook_events', function (Blueprint $table) {
    $table->string('event_id')->primary();
    $table->timestamps();
});
// app/Jobs/HandleMercanPayEvent.php
namespace App\Jobs;

use App\Models\Order;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\DB;

class HandleMercanPayEvent implements ShouldQueue
{
    use Queueable;

    public function __construct(public array $event) {}

    public function handle(): void
    {
        DB::transaction(function () {
            $inserted = DB::table('processed_webhook_events')->insertOrIgnore([
                'event_id' => $this->event['id'], 'created_at' => now(), 'updated_at' => now(),
            ]);
            if ($inserted === 0) {
                return; // bu olay daha önce işlendi
            }

            $invoice = $this->event['data']['invoice'] ?? null;
            if (!$invoice) {
                return; // withdrawal.* ya da test.ping
            }
            $orderId = (int) str_replace('order-', '', $invoice['order_id']);

            match ($this->event['type']) {
                'invoice.paid', 'invoice.overpaid' => Order::whereKey($orderId)
                    ->where('status', '!=', 'paid')
                    ->update(['status' => 'paid', 'paid_token' => $invoice['token'], 'paid_amount' => $invoice['paid_amount']]),
                'invoice.partial' => Order::whereKey($orderId)->update(['status' => 'partially_paid']),
                'invoice.expired', 'invoice.cancelled' => Order::whereKey($orderId)
                    ->where('status', 'pending')->update(['status' => 'cancelled']),
                default => null,
            };
        });
    }
}

Laravel 10'da Queueable yerine Dispatchable, InteractsWithQueue, Queueable, SerializesModels trait'lerini kullanırsınız. Tekrar deneme ve idempotent işleme konusunu webhook yeniden deneme yazımızda derinlemesine ele aldık. Tüm olay türleri için webhook olay türleri rehberine bakabilirsiniz.

7. Teşekkür sayfasında API'ye sorun

success_url yönlendirmesi taklit edilebilir, bu yüzden siparişi oradan onaylamayın. Emin olmak istediğinizde API'ye sorun:

public function thanks(Order $order, MercanPay $mercanpay)
{
    $invoice = $mercanpay->getInvoiceByOrder('order-' . $order->id);
    $paid = in_array($invoice['status'], ['paid', 'overpaid'], true);

    return view('orders.thanks', compact('order', 'paid'));
}

Sık yapılan hatalar ve çözümleri

Laravel entegrasyonlarında sorunların büyük kısmı birkaç tanıdık noktadan çıkar. Canlıya geçmeden önce bunları tek tek gözden geçirmek, ilk gerçek ödemede sürprizle karşılaşmanızı önler.

Ham gövde yerine çözümlenmiş veriyi imzalamak

İmza, MercanPay'in gönderdiği baytların birebir aynısı üzerinden hesaplanır. $request->all() ile alınan diziyi yeniden JSON'a çevirirseniz boşluklar, anahtar sırası ya da sayı biçimi değişebilir ve imza tutmaz. Her zaman $request->getContent() ile gelen metni doğrulayın, JSON'u ancak doğrulamadan sonra çözün.

CSRF istisnasını unutmak

Webhook rotası web grubundaysa ve CSRF istisnasına eklenmemişse Laravel isteği daha controller'a ulaşmadan 419 ile reddeder. Bu durumda panelde Webhooklar sayfasındaki teslimat geçmişinde 419 yanıt kodunu görürsünüz. İstisnayı ekledikten sonra aynı olayı oradan yeniden gönderebilirsiniz.

Kuyruk çalışanının çalışmaması

Webhook 204 döndüğü için MercanPay açısından teslimat başarılıdır. Ancak kuyruk çalışanı durmuşsa iş hiç işlenmez ve siparişler "bekliyor" durumunda kalır. Canlıda queue:work sürecini bir süreç yöneticisiyle sürekli çalışır tutun ve başarısız işleri (failed_jobs) düzenli kontrol edin. Kuyruk sürücüsü sync ise iş istek içinde çalışır; bu geliştirmede kolaylık sağlar ama yavaş işler webhook yanıtını 10 saniyenin ötesine taşıyabilir.

Yapılandırma önbelleği ve env()

php artisan config:cache çalıştırıldıktan sonra kod içindeki env() çağrıları null döner. Anahtarı ve sırrı yalnızca config/services.php üzerinden okuduğunuzda bu sorun yaşanmaz. .env dosyasını değiştirdiğinizde önbelleği yeniden oluşturmayı unutmayın.

Sipariş durumunu koşulsuz güncellemek

Olaylar farklı sırayla ya da tekrar gelebilir. Örneğin where('status', '!=', 'paid') gibi koşullar, ödenmiş bir siparişin geç gelen bir olayla yanlışlıkla iptal durumuna düşmesini engeller. Her güncellemeyi "bu geçiş şu anki durumdan mantıklı mı?" sorusuyla yazın.

Test ve canlıya geçiş

Uçtan uca denemeyi üç adımda yapabilirsiniz:

  1. Bağlantıyı doğrulayın. Panelde Webhooklar → "Test gönder" ile bir test.ping olayı gönderin. Teslimat geçmişinde 2xx yanıt görmelisiniz. Job'ınız test.ping olayını sessizce atlar, çünkü içinde fatura yoktur.
  2. Fatura akışını deneyin. Küçük tutarlı gerçek bir sipariş oluşturun, ödeme sayfasına yönlendirildiğinizi ve success_url dönüşünde teşekkür sayfasının API'ye sorduğunu kontrol edin.
  3. Ödemeyi tamamlayın. Ödeme 20 onaydan sonra kesinleşir. invoice.paid olayı geldiğinde siparişin güncellendiğini ve processed_webhook_events tablosuna bir satır eklendiğini doğrulayın. Aynı olayı panelden yeniden gönderip siparişin ikinci kez işlenmediğini görün.

Canlıya geçmeden önce

  • API anahtarı ve webhook sırrı yalnızca .env içinde, depoda değil.
  • Webhook rotası CSRF'den muaf, imza doğrulaması açık.
  • Kuyruk çalışanı (php artisan queue:work) canlıda sürekli çalışıyor.
  • Panelde Webhooklar → "Test gönder" ile test.ping olayı başarıyla alındı.
  • Akış küçük tutarlı gerçek bir ödemeyle uçtan uca denendi.

Sık sorulan sorular

Hazır bir Laravel paketi var mı?

Hayır. Resmi PHP kütüphanesini yukarıdaki gibi servis konteynerine bağlayarak kullanırsınız. Bu yaklaşım birkaç dosyadan ibarettir ve tam kontrolü size bırakır.

Webhook'ta neden 419 hatası alıyorum?

419, CSRF doğrulamasının başarısız olduğunu gösterir. Webhook rotasını CSRF istisnalarına eklediğinizden emin olun.

İmza neden hep geçersiz çıkıyor?

En sık neden, ham gövde yerine çözümlenmiş JSON'u kullanmaktır. $request->getContent() kullanın ve gövdeyi değiştiren bir ara katman olmadığından emin olun. Sunucu saatinin doğru olması da gerekir.

Çekimleri Laravel'den yapabilir miyim?

Evet. withdrawals yetkili bir anahtarla createWithdrawal('USDT', '50', 'T...', 'benzersiz-anahtar') çağırabilirsiniz. Güvenlik gereği API çekimleri yalnızca panelde güvenilir olarak işaretlenmiş kayıtlı adreslere gider.

MercanPay ile başlayın

Laravel uygulamanıza USDT ve TRX ödemesi eklemek için satıcı başvurunuzu yapın, bir API anahtarı oluşturun ve ilk faturanızı kesin. Tüm alanlar ve hata kodları için dokümantasyonu inceleyin.

#Laravel#PHP#Webhook#API

İlgili yazılar

Kripto ödemeleri dakikalar içinde almaya başlayın

USDT ve TRX (TRC20) ile ödeme alın. %0,4'ten başlayan komisyon, hazır ödeme sayfası, API ve webhook.