Tích hợp

Thanh toán crypto trên WordPress

Cách nhận thanh toán crypto trên WordPress và WooCommerce mà không cần plugin dựng sẵn: hai đoạn mã, đặt ở đâu và thường hỏng ở chỗ nào.

WordPress không có cách nhận crypto tích hợp sẵn, và Qvard chưa có plugin WordPress dựng sẵn. Thứ Qvard có là một API đơn giản, và WordPress hoàn toàn có thể giao tiếp với một API. Bài này hướng dẫn kết nối cửa hàng WooCommerce với Qvard bằng hai đoạn mã nhỏ, và cần kiểm tra gì khi nó không chạy.

Plugin hay mã tự viết: lựa chọn trung thực

Trên WordPress, thứ người ta tìm đầu tiên là plugin, và đó là bản năng hợp lý: cài, dán khóa, xong. Tình hình hiện nay như sau.

  • Qvard chưa có plugin WordPress hay WooCommerce. Việc tích hợp qua API. Chúng tôi thà nói thẳng còn hơn bắt bạn đi tìm một plugin không tồn tại.
  • Plugin bên thứ ba cho các cổng crypto khác sẽ không kết nối được với Qvard. Mỗi plugin nói chuyện với API của chính cổng đó.
  • Cách tự viết khá gọn. Một yêu cầu tạo thanh toán và một endpoint nhận kết quả. Lập trình viên WordPress có thể viết trong một đến hai giờ, và bạn kiểm soát chính xác điều gì xảy ra với đơn hàng.

Nếu bạn muốn thiết lập không cần mã, Qvard chưa đến mức đó. Nếu bạn có lập trình viên, hoặc có thể thuê một giờ, hãy đọc tiếp.

Việc tích hợp hoạt động thế nào

Luồng cho một đơn WooCommerce:

  1. Ở bước thanh toán, khách chọn «Thanh toán bằng crypto». Mã của bạn tạo thanh toán qua API Qvard, dùng số đơn WooCommerce làm id của thanh toán.
  2. Qvard trả về redirectUrl. Bạn chuyển khách tới trang thanh toán do Qvard lưu trữ đó, nơi họ chọn tài sản và mạng rồi trả từ ví của mình.
  3. Khi thanh toán hoàn tất, Qvard gọi một endpoint trên website của bạn.
  4. Endpoint tìm đơn theo id và đánh dấu là đã thanh toán, nhờ đó WooCommerce gửi các email quen thuộc và chuyển đơn sang xử lý.

Website WordPress của bạn không bao giờ tạo địa chỉ hay theo dõi blockchain. Hai đoạn bạn viết là lệnh gọi tạo thanh toán và endpoint nhận kết quả.

Đoạn 1: tạo thanh toán

Trong WordPress, dùng wp_remote_post để gọi https://api.qvard.com/api/v1/payment với khóa API trong header Authorization: Bearer và một JSON: id (số đơn hàng dạng chuỗi) và price (số tiền bằng đô la Mỹ). Lệnh gọi thành công trả về HTTP 201 kèm redirectUrl.

Ví dụ bên dưới làm đúng việc đó cho một đơn WooCommerce. Hãy giữ khóa trong wp-config.php dưới dạng hằng số, không để trong theme và không để trong tùy chọn cơ sở dữ liệu nơi plugin và tệp xuất có thể làm lộ.

Hai chi tiết của WooCommerce cần chú ý:

  • Tiền tệ. Giá được gửi bằng đô la Mỹ. Nếu cửa hàng dùng tiền tệ khác, hãy quy đổi tổng đơn sang đô la trước khi gọi, nếu không khách sẽ bị yêu cầu trả sai số tiền.
  • Thử lại. Gửi cùng id cho cùng phương thức thanh toán sẽ trả về thanh toán hiện có, nên nhấp đúp hoặc yêu cầu bị gửi lặp không tạo thanh toán thứ hai.

Gắn việc này vào một phương thức thanh toán tùy chỉnh, hoặc vào bước thanh toán xử lý lựa chọn «Thanh toán bằng crypto», rồi chuyển hướng khách tới URL được trả về.

PHPqvard-create-payment.php
<?php
// Create a Qvard payment for a WooCommerce order and return the page to send the customer to.
// QVARD_API_KEY is defined in wp-config.php, never in a theme or a public repository.
function qvard_create_payment( WC_Order $order ) {
    $response = wp_remote_post( 'https://api.qvard.com/api/v1/payment', array(
        'timeout' => 15,
        'headers' => array(
            'Authorization'    => 'Bearer ' . QVARD_API_KEY,
            'Content-Type' => 'application/json',
        ),
        'body'    => wp_json_encode( array(
            'id'    => (string) $order->get_id(),   // matched again in the webhook
            'price' => (float) $order->get_total(), // US dollars
        ) ),
    ) );

    if ( is_wp_error( $response ) || 201 !== wp_remote_retrieve_response_code( $response ) ) {
        return null;
    }

    $data = json_decode( wp_remote_retrieve_body( $response ), true );
    return isset( $data['redirectUrl'] ) ? $data['redirectUrl'] : null;
}

Đoạn 2: nhận webhook

Đăng ký một route REST trong WordPress và lưu địa chỉ của nó trong dự án Qvard làm callback URL, ví dụ https://your-site.com/wp-json/qvard/v1/webhook. Khi một thanh toán hoàn tất, Qvard gửi POST kèm id bạn đã cung cấp và status của thanh toán, đồng thời có chữ ký trong header X-Qvard-Signature.

Ba quy tắc cho endpoint:

  • Xác minh chữ ký. Kiểm tra X-Qvard-Signature (HMAC-SHA256 bằng khóa bí mật của bạn) bằng SDK và từ chối mọi giá trị không khớp.
  • Chỉ đánh dấu đơn đã thanh toán khi completed. Việc khách quay lại website của bạn không phải là bằng chứng thanh toán, và trạng thái partial nghĩa là họ gửi ít hơn yêu cầu.
  • Trả lời đúng HTTP 200. Qvard coi mọi mã trạng thái khác là thất bại và thử lại (năm lần trong khoảng sáu phút), và không theo chuyển hướng. Vì có thử lại, trình xử lý phải an toàn khi chạy hai lần; is_paid() trong ví dụ ngăn việc hoàn tất hai lần.

Xem thêm về bảo mật trong cách bảo mật webhook thanh toán crypto.

PHPqvard-webhook.php
<?php
// Webhook endpoint: https://your-site.com/wp-json/qvard/v1/webhook
add_action( 'rest_api_init', function () {
    register_rest_route( 'qvard/v1', '/webhook', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true', // authenticated below by the X-Qvard-Signature header
        'callback'            => function ( WP_REST_Request $request ) {
            try {
                $payload = ( new Qvard\Qvard( QVARD_API_KEY ) )->webhooks->constructEvent( $request->get_body(), $request->get_header( 'x-qvard-signature' ), QVARD_API_KEY );
            } catch ( \Exception $e ) {
                return new WP_REST_Response( null, 401 );
            }
            $order   = wc_get_order( (int) ( $payload['id'] ?? 0 ) );

            if ( $order && 'completed' === ( $payload['status'] ?? '' ) && ! $order->is_paid() ) {
                $order->payment_complete();
            }

            return new WP_REST_Response( null, 200 ); // must be exactly 200
        },
    ) );
} );

Thường hỏng ở đâu trên WordPress

Phần lớn tích hợp thất bại trên WordPress là do môi trường chứ không phải do mã:

  • Webhook không bao giờ đến. Plugin bảo mật, tường lửa hoặc trang «sắp ra mắt» chặn các yêu cầu POST lạ. Hãy cho phép route và thử từ ngoài mạng của bạn.
  • Route trả về 404. Permalink thân thiện bị tắt hoặc tệp plugin không được nạp. Mở route trong trình duyệt; 401 hoặc 405 nghĩa là nó tồn tại, 404 nghĩa là không.
  • Bộ nhớ đệm trang. Đảm bảo plugin cache và CDN không lưu cache hay viết lại các yêu cầu /wp-json/.
  • Đơn bị thanh toán hai lần. Trình xử lý không idempotent. Kiểm tra is_paid() trước khi hoàn tất.
  • Sai số tiền. Tiền tệ cửa hàng không phải đô la Mỹ và chưa quy đổi.
  • Phản hồi chậm. Các plugin nặng gắn vào bước hoàn tất đơn có thể làm chậm câu trả lời của bạn. Trả về 200 nhanh rồi xử lý các việc chậm sau.

Sau khi trả tiền, khách tự quay lại website của bạn vì URL quay lại chưa khả dụng. Hãy cho họ trang đơn hàng hiển thị trạng thái thực, thay vì trang cảm ơn mặc định cho rằng đã thành công.

Thử nghiệm trước khi chạy thật

Mở một hóa đơn demo để thấy trang thanh toán mà khách sẽ nhận. Sau đó:

  1. Tạo thanh toán từ một đơn thử và kiểm tra bạn nhận được redirectUrl.
  2. Thanh toán một khoản tiền thật nhỏ và xác nhận webhook đến và đơn chuyển sang đã thanh toán.
  3. Cho endpoint cố ý trả lỗi một lần, kiểm tra Qvard thử lại và đơn không bị hoàn tất hai lần.
  4. Rút một khoản nhỏ từ số dư về ví của bạn.

Chưa có sandbox riêng, nên hãy dùng số tiền thật nhỏ. Endpoint và các trường có trong tài liệu dành cho lập trình viên, còn tổng quan tích hợp cho biết hiện còn gì được kết nối.

Chi phí vận hành

Không có phí đăng ký. Với mỗi thanh toán, hoa hồng được tính riêng cho dự án của bạn và theo trang bảng giá bắt đầu từ 1%, có thể giảm xuống 0,1%; xem bảng giá để biết điều kiện hiện hành. Rút về ví của bạn chỉ tốn phí mạng. Rút về tài khoản ngân hàng bằng tiền pháp định không khả dụng.

Chi phí duy nhất cần dự tính là thời gian phát triển: ít, chỉ một lần, và một chút bảo trì khi WordPress hoặc WooCommerce thay đổi cách đăng ký phương thức thanh toán.

FAQ

Có plugin Qvard cho WordPress hoặc WooCommerce không?

Chưa có. Hiện tại tích hợp qua API: một yêu cầu tạo thanh toán và một webhook nhận kết quả. Lập trình viên WordPress có thể thêm cả hai vào cửa hàng trong một đến hai giờ.

Tôi có thể dùng plugin crypto làm cho cổng khác không?

Không. Mỗi plugin nói chuyện với cổng riêng của nó và không thể kết nối với Qvard. Bạn cần mã tự viết gọi API Qvard.

Cửa hàng của tôi không tính giá bằng đô la Mỹ. Phải làm sao?

Giá được gửi cho Qvard bằng đô la Mỹ, nên hãy quy đổi tổng đơn trước khi tạo thanh toán. Khách sau đó trả khoản tương đương bằng tài sản họ chọn, theo tỷ giá cố định trong một giờ.

Webhook không đến được website của tôi. Vì sao?

Thường là plugin bảo mật, tường lửa hoặc trang bảo trì chặn yêu cầu, hoặc route REST chưa được đăng ký. Hãy kiểm tra route trả lời được từ ngoài mạng của bạn và trả về đúng HTTP 200 cho một yêu cầu hợp lệ.

Bài viết liên quan

Bài viết liên quan