CChainPay
Войти

Приём USDT в WooCommerce без плагина

Плагина WooCommerce для ChainPay пока нет. API достаточно маленькое, чтобы интегрировать его примерно шестьюдесятью строками PHP: показать адрес для депозита на странице заказа и пометить заказ оплаченным, когда придёт вебхук.

Как это работает

  1. Клиент оформляет заказ со способом оплаты, после которого статус остаётся pending или on-hold (например, «Прямой банковский перевод», переименованный в «USDT»).
  2. Страница благодарности просит у ChainPay адрес для депозита на этот заказ и показывает его.
  3. Клиент платит. ChainPay переводит средства на ваш кошелёк и отправляет вебхук на ваш сайт.
  4. Обработчик вебхука проверяет секрет и сумму и вызывает payment_complete().

mu-плагин

Сохраните как wp-content/mu-plugins/chainpay.php:

<?php
// wp-content/mu-plugins/chainpay.php
const CHAINPAY_API = 'https://api.chainpay.site';
const CHAINPAY_SECRET = 'change-me';
const CHAINPAY_WALLET = 'TYourOwnTronWallet...';

function chainpay_address(WC_Order $order): ?string {
    $cached = $order->get_meta('_chainpay_address');
    if ($cached) {
        return $cached;
    }
    $res = wp_remote_post(CHAINPAY_API . '/deposit-address', [
        'headers' => ['Content-Type' => 'application/json'],
        'timeout' => 15,
        'body' => wp_json_encode([
            'ticker' => 'trc20/usdt',
            'callbackUrl' => rest_url('chainpay/v1/webhook') . '?token=' . CHAINPAY_SECRET,
            'forwardAddress' => CHAINPAY_WALLET,
            'externalReference' => 'wc-' . $order->get_id(),
        ]),
    ]);
    if (is_wp_error($res)) {
        return null;
    }
    $address = json_decode(wp_remote_retrieve_body($res), true)['address'] ?? null;
    if ($address) {
        $order->update_meta_data('_chainpay_address', $address);
        $order->save();
    }
    return $address;
}

add_action('woocommerce_thankyou', function ($order_id) {
    $order = wc_get_order($order_id);
    if (!$order || !$order->has_status(['pending', 'on-hold'])) {
        return;
    }
    $address = chainpay_address($order);
    if ($address) {
        echo '<p>Send ' . esc_html($order->get_total()) . ' USDT (TRC20) to <code>'
            . esc_html($address) . '</code></p>';
    }
});

add_action('rest_api_init', function () {
    register_rest_route('chainpay/v1', '/webhook', [
        'methods' => 'POST',
        'permission_callback' => '__return_true',
        'callback' => function (WP_REST_Request $req) {
            if (!hash_equals(CHAINPAY_SECRET, (string) $req->get_param('token'))) {
                return new WP_REST_Response(null, 403);
            }
            $event = $req->get_json_params();
            if (($event['status'] ?? '') !== 'confirmed') {
                return ['ok' => true];
            }
            $order = wc_get_order((int) str_replace('wc-', '', $event['externalReference'] ?? ''));
            if ($order && !$order->is_paid() && (float) $event['amount'] >= (float) $order->get_total()) {
                $order->payment_complete($event['txHash']);
            }
            return ['ok' => true];
        },
    ]);
});

Заметки

См. также