tigusigalpa/telegram-wallet-php
Composer 安装命令:
composer require tigusigalpa/telegram-wallet-php
包简介
Complete PHP SDK for Telegram Wallet Pay API v1.2.0 with first-class Laravel support
README 文档
README
Accept crypto payments in your PHP app or Laravel project. This SDK wraps the Telegram Wallet Pay API, letting your users pay with TON, USDT, BTC, and NOT — right inside Telegram.
Why This Package?
Building a Telegram bot with payments? We've got you covered:
- Laravel-first — Service Provider, Facade, Middleware out of the box
- Works anywhere — Use standalone in any PHP 8.1+ project
- Secure webhooks — HMAC-SHA256 signature verification built-in
- Type-safe — Modern PHP with enums, DTOs, and typed exceptions
- Tested — Comprehensive test suite you can trust
Installation
Install via Composer:
composer require tigusigalpa/telegram-wallet-php
Requirements
- PHP 8.1 or higher
ext-jsonextension- Laravel 9.x, 10.x, 11.x, 12.x, or 13.x (optional, for Laravel integration)
Quick Start
Here's how simple it is to create a payment:
<?php use Tigusigalpa\TelegramWallet\WalletPayClient; use Tigusigalpa\TelegramWallet\DTO\CreateOrderRequest; use Tigusigalpa\TelegramWallet\DTO\MoneyAmount; // Initialize with your API key from Wallet Pay $client = new WalletPayClient(apiKey: 'YOUR_STORE_API_KEY'); // Create a payment order $order = $client->createOrder(new CreateOrderRequest( amount: new MoneyAmount('USD', '9.99'), description: 'Premium subscription for 1 month', externalId: 'ORDER-' . uniqid(), // Your unique order ID timeoutSeconds: 3600, // 1 hour to pay customerTelegramUserId: 123456789, // Who can pay this order autoConversionCurrency: 'USDT', // Receive payment in USDT returnUrl: 'https://t.me/YourBot/YourApp', customData: json_encode(['user_id' => 42]) )); // Send this link to your user — they'll pay right in Telegram! echo $order->directPayLink;
With Laravel
Using Laravel? It's even cleaner with the Facade:
use Tigusigalpa\TelegramWallet\Laravel\Facades\WalletPay; use Tigusigalpa\TelegramWallet\DTO\CreateOrderRequest; use Tigusigalpa\TelegramWallet\DTO\MoneyAmount; $order = WalletPay::createOrder(new CreateOrderRequest( amount: new MoneyAmount('USD', '9.99'), description: 'Premium subscription', externalId: 'SUB-' . $user->id . '-' . time(), timeoutSeconds: 3600, customerTelegramUserId: $user->telegram_id, autoConversionCurrency: 'USDT', returnUrl: 'https://t.me/YourBot/YourApp', customData: json_encode(['user_id' => $user->id]) )); return response()->json(['pay_url' => $order->directPayLink]);
Handling Webhooks
When a payment succeeds (or fails), Wallet Pay will notify your server:
use Tigusigalpa\TelegramWallet\Webhook\WebhookVerifier; use Tigusigalpa\TelegramWallet\Enums\WebhookEventType; $verifier = new WebhookVerifier('YOUR_STORE_API_KEY'); try { // Verify signature and parse events in one call $events = $verifier->verifyAndParse( $_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), $_SERVER['HTTP_WALLETPAY_TIMESTAMP'], file_get_contents('php://input'), $_SERVER['HTTP_WALLETPAY_SIGNATURE'] ); foreach ($events as $event) { if ($event->type === WebhookEventType::ORDER_PAID) { // 🎉 Payment successful! $customData = json_decode($event->payload->customData, true); // Now you can: // - Update your database // - Grant premium access // - Send a thank-you message } } http_response_code(200); echo 'OK'; } catch (InvalidWebhookSignatureException $e) { http_response_code(401); echo 'Invalid signature'; }
Configuration
The defaults work great for most cases. Here's how to customize if needed:
use Tigusigalpa\TelegramWallet\WalletPayClient; use GuzzleHttp\Client; // Simple — just your API key $client = new WalletPayClient(apiKey: getenv('WALLETPAY_API_KEY')); // Custom — bring your own HTTP client $client = new WalletPayClient( apiKey: getenv('WALLETPAY_API_KEY'), timeout: 60, httpClient: new Client(['verify' => true]) );
Laravel Configuration
Publish the configuration file:
php artisan vendor:publish --tag=walletpay-config
Edit config/walletpay.php:
<?php return [ 'api_key' => env('WALLETPAY_API_KEY'), 'base_url' => env('WALLETPAY_BASE_URL', 'https://pay.wallet.tg'), 'timeout' => env('WALLETPAY_TIMEOUT', 30), 'webhook_path' => env('WALLETPAY_WEBHOOK_PATH', '/webhook/walletpay'), ];
Add to your .env:
WALLETPAY_API_KEY=your_store_api_key_here WALLETPAY_WEBHOOK_PATH=/webhook/walletpay
API Reference
Here's everything you can do with the client:
| Method | What it does |
|---|---|
createOrder($request) |
Create a new payment order |
getOrderPreview($orderId) |
Check order status |
getOrderList($offset, $count) |
List orders (paginated, max 10,000) |
getOrderAmount() |
Get total order count |
Order Parameters
| Parameter | Required | What it's for |
|---|---|---|
amount |
Yes | How much to charge (e.g., new MoneyAmount('USD', '9.99')) |
description |
Yes | What the user sees (5-100 chars) |
externalId |
Yes | Your order ID — use this to match payments |
timeoutSeconds |
Yes | How long the order stays valid (30s to 10 days) |
customerTelegramUserId |
Yes | Only this Telegram user can pay |
autoConversionCurrency |
No | Convert payment to TON/USDT/BTC/NOT (+1% fee) |
returnUrl |
No | Where to send user after payment |
failReturnUrl |
No | Where to send user if payment fails |
customData |
No | Your metadata — comes back in webhooks |
Currencies
For pricing: USD, EUR
For receiving: TON, USDT, BTC, NOT
Order Lifecycle
| Status | Meaning |
|---|---|
ACTIVE |
Waiting for payment |
PAID |
Payment received! 🎉 |
EXPIRED |
Time ran out |
CANCELLED |
User or system cancelled |
Webhook Events
ORDER_PAID— Money's in! Time to deliver.ORDER_FAILED— Something went wrong (expired, cancelled, etc.)
Setting Up Webhooks
Webhooks tell you when payments happen. Here's how to set them up properly.
Step 1: Configure Your URL
In your Wallet Pay store settings, set the webhook URL:
https://yourdomain.com/webhook/walletpay
Important:
- Must be HTTPS with a real SSL certificate (Let's Encrypt works great)
- Self-signed certs won't work
- Always return HTTP 200 to confirm receipt
Step 2: Allowlist Wallet Pay IPs
If you have a firewall, allow these IPs:
188.42.38.156172.255.249.124
Step 3: Handle Duplicate Webhooks
Wallet Pay might send the same webhook multiple times (network issues happen). Use eventId to avoid processing
duplicates:
<?php // Example: Store processed event IDs in database if (ProcessedWebhookEvent::where('event_id', $event->eventId)->exists()) { return; // Already processed } // Process the event processPayment($event); // Mark as processed ProcessedWebhookEvent::create(['event_id' => $event->eventId]);
How Signature Verification Works
You don't need to implement this yourself (our WebhookVerifier handles it), but here's what happens under the hood:
stringToSign = HTTP_METHOD + "." + URI_PATH + "." + TIMESTAMP + "." + Base64(BODY)
signature = Base64(HmacSHA256(stringToSign, API_KEY))
Heads up: The URI path must match exactly what you configured — including the trailing slash (or lack thereof).
Laravel Deep Dive
Service Provider
The package auto-registers — no setup needed! But if you need manual registration:
// config/app.php 'providers' => [ Tigusigalpa\TelegramWallet\Laravel\WalletPayServiceProvider::class, ],
Facade
// config/app.php 'aliases' => [ 'WalletPay' => Tigusigalpa\TelegramWallet\Laravel\Facades\WalletPay::class, ],
Webhook Middleware
We include middleware that verifies webhook signatures for you. Register it in app/Http/Kernel.php:
protected $middlewareAliases = [ 'walletpay.webhook' => \Tigusigalpa\TelegramWallet\Laravel\Http\Middleware\VerifyWalletPayWebhook::class, ];
Simple Route Example
// routes/api.php use Tigusigalpa\TelegramWallet\Webhook\WebhookVerifier; Route::post('/webhook/walletpay', function (Request $request, WebhookVerifier $verifier) { $events = $verifier->parseWebhookEvents($request->getContent()); foreach ($events as $event) { Log::info('Payment webhook', [ 'event_id' => $event->eventId, 'type' => $event->type->value, ]); } return response('OK', 200); })->middleware('walletpay.webhook');
Full Controller Example
Here's a production-ready controller with payment creation and webhook handling:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Tigusigalpa\TelegramWallet\Laravel\Facades\WalletPay; use Tigusigalpa\TelegramWallet\DTO\CreateOrderRequest; use Tigusigalpa\TelegramWallet\DTO\MoneyAmount; use Tigusigalpa\TelegramWallet\Enums\WebhookEventType; use Tigusigalpa\TelegramWallet\Webhook\WebhookVerifier; class PaymentController extends Controller { public function createPayment(Request $request) { $user = $request->user(); $order = WalletPay::createOrder(new CreateOrderRequest( amount: new MoneyAmount('USD', '9.99'), description: 'Premium subscription', externalId: 'SUB-' . $user->id . '-' . time(), timeoutSeconds: 3600, customerTelegramUserId: $user->telegram_id, autoConversionCurrency: 'USDT', returnUrl: 'https://t.me/YourBot/YourApp', customData: json_encode(['user_id' => $user->id]) )); // Save to your database Payment::create([ 'user_id' => $user->id, 'wallet_pay_order_id' => $order->id, 'amount' => $order->amount->amount, 'status' => 'pending', ]); return response()->json(['pay_url' => $order->directPayLink]); } public function webhook(Request $request, WebhookVerifier $verifier) { $events = $verifier->parseWebhookEvents($request->getContent()); foreach ($events as $event) { if ($event->type === WebhookEventType::ORDER_PAID) { $customData = json_decode($event->payload->customData, true); // Update payment status Payment::where('wallet_pay_order_id', $event->payload->id) ->update(['status' => 'paid']); // Grant premium access User::find($customData['user_id']) ->update(['is_premium' => true]); } } return response('OK', 200); } }
When Things Go Wrong
Errors are typed, so you can handle them gracefully:
| Exception | What happened |
|---|---|
InvalidRequestException |
Bad request (check your parameters) |
InvalidApiKeyException |
Invalid API key |
OrderNotFoundException |
Order doesn't exist |
RateLimitException |
Slow down! Too many requests |
ServerException |
Wallet Pay is having issues |
InvalidWebhookSignatureException |
Webhook signature doesn't match |
Example
use Tigusigalpa\TelegramWallet\Exceptions\OrderNotFoundException; use Tigusigalpa\TelegramWallet\Exceptions\RateLimitException; use Tigusigalpa\TelegramWallet\Exceptions\WalletPayException; try { $order = $client->getOrderPreview('123456'); } catch (OrderNotFoundException $e) { // Order doesn't exist return response()->json(['error' => 'Order not found'], 404); } catch (RateLimitException $e) { // Too many requests — back off and retry return response()->json(['error' => 'Try again later'], 429); } catch (WalletPayException $e) { // Something else went wrong Log::error('Wallet Pay error', ['message' => $e->getMessage()]); return response()->json(['error' => 'Payment error'], 500); }
Things to Know
Opening the Payment Link
The payment link (directPayLink) needs to be opened correctly:
✅ In a Telegram Web App: Use Telegram.WebApp.openTelegramLink(url)
✅ In a bot message: Use it as an Inline Button URL
❌ Don't use: openLink() or MenuButtonWebApp — payment will fail
Payment Button Text
Telegram requires specific button text:
👛 Wallet Pay👛 Pay via Wallet
Yes, the purse emoji is mandatory. 👛
Preventing Duplicate Orders
Use externalId as your idempotency key. If you retry with the same ID, you'll get the existing order back:
$externalId = 'ORDER-' . $userId . '-' . $productId . '-' . time();
Auto-Conversion Fees
Want to receive payments in a specific crypto? Set autoConversionCurrency, but note:
- 1% fee applies
- Minimum: $1.30 (or $3 for BTC)
When Can You Withdraw?
Funds are held for 48 hours after payment before you can withdraw them. This is a Wallet Pay policy.
One User Per Order
Only the Telegram user specified in customerTelegramUserId can pay that order. This prevents payment link sharing.
Testing
composer install vendor/bin/phpunit # Just unit tests vendor/bin/phpunit --testsuite Unit # Just feature tests vendor/bin/phpunit --testsuite Feature
What's Next?
This package is built to grow. The architecture separates payment functionality from future trading features (spot trading, tokenized stocks, perpetual futures). When Wallet adds new APIs, we'll add support without breaking your existing code.
Contributing
Found a bug? Have an idea? PRs are welcome!
- Fork it
- Create your branch (
git checkout -b fix/something) - Make your changes
- Run tests (
vendor/bin/phpunit) - Open a PR
Please follow PSR-12 and include tests for new features.
License
MIT — do whatever you want with it.
Links
Need Help?
Open an issue on GitHub — I'll do my best to help.
Built by Igor Sazonov
tigusigalpa/telegram-wallet-php 适用场景与选型建议
tigusigalpa/telegram-wallet-php 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 15 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「payment」 「crypto」 「laravel」 「bitcoin」 「wallet」 「telegram」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 tigusigalpa/telegram-wallet-php 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 tigusigalpa/telegram-wallet-php 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 tigusigalpa/telegram-wallet-php 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
High-level cryptographic primitives and security utilities for Maatify systems including password hashing, reversible encryption, HKDF key derivation, and key rotation.
Alfabank REST API integration
A simple PHP Cryptography Implementation for the Ark Blockchain.
A simple PHP API client for the Ark Blockchain.
A Laravel bridge for Ark Core.
Laravel Minimal Wallet Plugin
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 32
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-15