<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged telegram</title>
<link>https://coderlegion.com/tag/telegram</link>
<description>Powered by Question2Answer</description>
<item>
<title>Building Crypto Payments into Telegram: A Technical Deep Dive into telegram-wallet-php</title>
<link>https://coderlegion.com/14893/building-crypto-payments-into-telegram-a-technical-deep-dive-into-telegram-wallet-php</link>
<description>&lt;p&gt;Telegram is no longer just a messaging app. With an audience exceeding 1 billion monthly active users by early 2025 and deep integration with the TON blockchain, the platform has become serious infrastructure for commerce and decentralized applications. Developers building bots and Telegram Mini Apps (TMAs) now have a genuine opportunity to monetize their products by accepting cryptocurrency payments directly within the chat interface.&lt;/p&gt;
&lt;p&gt;The official Wallet Pay API makes this possible, allowing merchants to accept TON, USDT, BTC, and NOT from users without redirecting them to external sites. However, integrating a raw REST API is never trivial. A developer must implement authentication, construct request payloads, verify cryptographic webhook signatures, and map HTTP status codes to meaningful errors.&lt;/p&gt;
&lt;p&gt;This is exactly the problem that &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/tigusigalpa/telegram-wallet-php&quot;&gt;telegram-wallet-php&lt;/a&gt; solves. Created by Igor Sazonov, this open-source PHP SDK wraps the Wallet Pay API v1.2.0 in a clean, modern, and strictly typed interface. The library works as a standalone solution in any PHP 8.1+ project and provides first-class integration for Laravel (versions 9 through 13). &lt;/p&gt;
&lt;p&gt;This post is a technical walkthrough of the current implementation: architectural shape, webhook security, error handling, and production gotchas.&lt;/p&gt;
&lt;h4 id=&quot;architectural-shape-and-typing&quot;&gt;Architectural Shape and Typing&lt;/h4&gt;
&lt;p&gt;At code level, &lt;code&gt;telegram-wallet-php&lt;/code&gt; follows a fairly direct layered structure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Contracts (interfaces) for the main client&lt;/li&gt;
&lt;li&gt;Data Transfer Objects (DTOs) for request payloads and API responses&lt;/li&gt;
&lt;li&gt;PHP 8.1 Enums for statuses and event types&lt;/li&gt;
&lt;li&gt;Typed exceptions mapped to HTTP status codes&lt;/li&gt;
&lt;li&gt;Laravel integration (Service Provider, Facade, Middleware)&lt;/li&gt;
&lt;li&gt;Webhook handling classes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In practical terms, the main entry point is the &lt;code&gt;WalletPayClient&lt;/code&gt; class, which implements &lt;code&gt;WalletPayClientInterface&lt;/code&gt;. Its constructor accepts a PSR-18 compatible HTTP client, which is critical for unit testing — you can inject a mock client to verify your application logic without making real HTTP requests.&lt;/p&gt;
&lt;p&gt;The library heavily uses DTOs to represent both request payloads and API responses. This is a significant advantage over an array-based approach. Using named arguments (a PHP 8.0 feature) makes the intent of each parameter crystal clear, and your IDE will warn you if you pass the wrong type.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$request = new CreateOrderRequest(
    amount: new MoneyAmount('USD', '9.99'),
    description: 'Premium subscription',
    externalId: 'ORDER-123',
    timeoutSeconds: 3600,
    customerTelegramUserId: 123456789
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Order statuses and webhook event types are represented as PHP 8.1 Enums, eliminating the risk of typos when comparing strings. The order lifecycle follows a clear state machine: from &lt;code&gt;ACTIVE&lt;/code&gt; (awaiting payment) to &lt;code&gt;PAID&lt;/code&gt; (successful payment), &lt;code&gt;EXPIRED&lt;/code&gt; (timeout reached), or &lt;code&gt;CANCELLED&lt;/code&gt; (aborted).&lt;/p&gt;
&lt;h4 id=&quot;webhook-security-the-critical-path&quot;&gt;Webhook Security: The Critical Path&lt;/h4&gt;
&lt;p&gt;Webhooks are the mechanism by which Wallet Pay notifies your server about payment outcomes. Implementing this correctly is the most security-sensitive part of any payment integration.&lt;/p&gt;
&lt;p&gt;When Wallet Pay sends a webhook, it includes two headers: &lt;code&gt;WalletPay-Timestamp&lt;/code&gt; (a nanosecond timestamp) and &lt;code&gt;WalletPay-Signature&lt;/code&gt; (a Base64-encoded HMAC-SHA256 signature). The signature is computed based on the HTTP method, URI path, timestamp, and request body.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;WebhookVerifier&lt;/code&gt; class handles all this cryptography automatically. The developer does not need to implement HMAC verification manually, which is a major security benefit, as manual HMAC implementations are frequently a source of vulnerabilities.&lt;/p&gt;
&lt;p&gt;In Laravel, the package provides a ready-to-use &lt;code&gt;walletpay.webhook&lt;/code&gt; Middleware. Once registered, the webhook routing becomes extremely concise: the Middleware verifies the signature, and the controller simply parses the events and updates the database state.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;Route::post('/webhook/walletpay', function (Request $request, WebhookVerifier $verifier) {
    $events = $verifier-&amp;gt;parseWebhookEvents($request-&amp;gt;getContent());
    
    foreach ($events as $event) {
        if ($event-&amp;gt;type === WebhookEventType::ORDER_PAID) {
            // Payment successful! Update status in DB
        }
    }
    
    return response('OK', 200);
})-&amp;gt;middleware('walletpay.webhook');
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;error-handling-typed-exceptions&quot;&gt;Error Handling: Typed Exceptions&lt;/h4&gt;
&lt;p&gt;One of the most developer-friendly aspects of &lt;code&gt;telegram-wallet-php&lt;/code&gt; is its exception hierarchy. Instead of catching a generic &lt;code&gt;\Exception&lt;/code&gt; and trying to parse the error message, you can precisely handle each failure scenario.&lt;/p&gt;
&lt;p&gt;The exception hierarchy maps directly to the HTTP status codes defined in the Wallet Pay API documentation. For example, &lt;code&gt;InvalidRequestException&lt;/code&gt; corresponds to status 400, &lt;code&gt;RateLimitException&lt;/code&gt; to 429 (allowing you to implement exponential backoff and retries), and &lt;code&gt;InvalidWebhookSignatureException&lt;/code&gt; is thrown when webhook signature verification fails.&lt;/p&gt;
&lt;h4 id=&quot;important-production-gotchas&quot;&gt;Important Production Gotchas&lt;/h4&gt;
&lt;p&gt;Based on the documentation and source code, there are several important considerations for production deployment:&lt;/p&gt;
&lt;p&gt;First, the &lt;code&gt;customerTelegramUserId&lt;/code&gt; field is mandatory, and only the specified Telegram user can pay for the order. This is a security feature that prevents payment link sharing, but it means you cannot create a generic &quot;pay now&quot; link — you must create a unique order for each user.&lt;/p&gt;
&lt;p&gt;Second, the &lt;code&gt;externalId&lt;/code&gt; field serves as an idempotency key. If you create an order with the same &lt;code&gt;externalId&lt;/code&gt; twice (for example, due to a retry on a network timeout), the API will return the existing order rather than creating a duplicate. You should generate your &lt;code&gt;externalId&lt;/code&gt; deterministically.&lt;/p&gt;
&lt;p&gt;Third, the Wallet Pay signature verification includes the exact URI path of the webhook endpoint. The path must match exactly what you configured in your store settings, including the presence or absence of a trailing slash. A mismatch will cause all webhook verifications to fail.&lt;/p&gt;
&lt;h4 id=&quot;the-bottom-line&quot;&gt;The Bottom Line&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;telegram-wallet-php&lt;/code&gt; library is a well-designed, production-ready SDK that significantly lowers the barrier to integrating cryptocurrency payments into PHP applications and Telegram bots. Leveraging modern PHP 8.1 features (Enums, readonly properties, named arguments, and typed DTOs) makes the code safer, more readable, and easier to maintain.&lt;/p&gt;
&lt;p&gt;The first-class Laravel integration is a genuine competitive advantage. The combination of a Service Provider, Facade, and Middleware means that Laravel developers can add Telegram crypto payments to their applications with minimal boilerplate, following conventions they already know. The built-in webhook signature verification eliminates a common source of vulnerabilities in payment integrations.&lt;/p&gt;
&lt;p&gt;For developers building products in the rapidly growing Telegram Mini App ecosystem, this library is an excellent foundation.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14893/building-crypto-payments-into-telegram-a-technical-deep-dive-into-telegram-wallet-php</guid>
<pubDate>Wed, 15 Apr 2026 12:56:51 +0000</pubDate>
</item>
</channel>
</rss>