Một địa chỉ ví không phải là một hệ thống thanh toán. Nó chỉ là một điểm đến, không hơn không kém. Bất kỳ ai có chuỗi ký tự đó đều có thể gửi bất cứ thứ gì vào đó bất cứ lúc nào. Đối với một giao dịch một lần giữa hai người tin tưởng nhau, điều đó có thể là đủ. Nhưng nếu bạn đang vận hành một sản phẩm SaaS, một sàn thương mại (marketplace) hoặc một cửa hàng trực tuyến, việc dán một địa chỉ tĩnh lên trang thanh toán là công thức dẫn đến sự hỗn loạn trong vận hành. Bạn sẽ phải dành cả ngày để đối soát các giao dịch bí ẩn với khách hàng thực tế, đoán xem ai đã trả bao nhiêu, và dọn dẹp đống hỗn độn khi ai đó gửi sai token trên sai mạng lưới.
Để xây dựng một thứ gì đó có khả năng mở rộng, bạn phải ngừng tư duy như một chiếc hũ quyên góp và bắt đầu tư duy như một hệ thống thanh toán có cấu trúc.
Tại sao địa chỉ ví thất bại khi mở rộng quy mô
Vấn đề nằm ở ngữ cảnh, hoặc sự thiếu hụt ngữ cảnh. Khi khách hàng sao chép địa chỉ ví của bạn và gửi crypto từ một sàn giao dịch hoặc một ví tự quản (self-custody wallet), blockchain chỉ ghi lại những gì đã di chuyển: một số tiền, một mốc thời gian và hai địa chỉ công khai. Nó không ghi lại số hóa đơn của bạn. Nó không bao gồm ID khách hàng. Nó không cho biết liệu việc chuyển khoản đó là gia hạn đăng ký, nâng cấp theo tỷ lệ thời gian sử dụng, hay là một giao dịch mua mới hoàn toàn.
Hãy xem xét một công ty SaaS thanh toán cho năm trăm khách hàng bằng stablecoin mỗi tháng. Nếu mọi khách hàng đều gửi USDT đến cùng một địa chỉ tĩnh, đội ngũ kế toán của bạn sẽ phải đối mặt với một cơn ác mộng trên bảng tính. Một giao dịch trông hoàn toàn giống hệt một giao dịch khác. Bạn không thể biết liệu 20 đô la vừa đến lúc 2 giờ sáng là của Khách hàng A đang gia hạn gói dịch vụ hay của Khách hàng B đang nâng cấp giữa chu kỳ. Blockchain chỉ thấy một con số. Doanh nghiệp của bạn cần một câu chuyện.
Các sàn thương mại (marketplaces) cảm nhận được nỗi đau này ở cả hai phía của giao dịch. Bạn cần biết người mua đã nạp tiền, giữ số tiền đó trong khi người bán giao hàng, và chỉ giải ngân sau khi có xác nhận giao hàng. Một địa chỉ thô không cung cấp cho bạn bất kỳ cách thức lập trình nào để phân biệt khoản tiền gửi của người mua với một giao dịch chuyển đến ngẫu nhiên hoặc tiền của chính nhà cung cấp. Thương mại điện tử cũng hỗn loạn không kém. Nếu không liên kết giao dịch với một đơn hàng cụ thể, bạn không thể kích hoạt quy trình hoàn tất đơn hàng. Ai đó sẽ phải quét chuỗi một cách thủ công, tìm giao dịch và cập nhật cơ sở dữ liệu của bạn. Làm việc đó mười lần một ngày, bạn sẽ bỏ lỡ các giao dịch khớp. Làm việc đó một nghìn lần, bạn sẽ mất tiền.
Sự chuyển đổi này tuy đơn giản nhưng lại cực kỳ quan trọng. Đừng hỏi liệu tiền đã đến một địa chỉ nào đó chưa. Hãy bắt đầu hỏi liệu một yêu cầu thanh toán cụ thể đã đạt đến trạng thái chính xác hay chưa.
Xây dựng dựa trên Yêu cầu Thanh toán
Một luồng thanh toán crypto đáng tin cậy coi yêu cầu thanh toán (payment request) là đối tượng trung tâm. Địa chỉ ví trở thành một vật chứa tạm thời tồn tại để phục vụ cho yêu cầu đó. Yêu cầu này mang theo các metadata giúp biến một giao dịch blockchain thành một sự kiện kinh doanh có thể nhận diện được.
Trước khi hiển thị tùy chọn thanh toán, hãy xác định các điểm dữ liệu giúp việc thanh toán có thể nhận dạng được:
- Một ID mua hàng hoặc ID đăng ký, để bạn biết chính xác lý do tại sao tiền được chuyển đi.
- Số tiền dự kiến, được chỉ định chính xác đến từng chữ số thập phân.
- Loại tài sản và mạng lưới chính xác, vì gửi USDT trên Ethereum không thể thay thế cho việc gửi trên Tron hoặc Polygon.
- Thông tin tham chiếu đến khách hàng hoặc tài khoản nội bộ.
- Thời gian hết hạn, để một báo giá đã thanh toán một nửa từ tháng Ba không vô tình đóng một đơn hàng vào tháng Sáu.
Khi khách hàng nhấn thanh toán, hệ thống của bạn sẽ tạo ra một yêu cầu chứa các trường thông tin này. Sau đó, khách hàng thanh toán dựa trên yêu cầu cụ thể đó, chứ không chỉ đơn thuần là một địa chỉ. Giao dịch trên chuỗi giờ đây đã có một định danh off-chain. Hệ thống của bạn biết khoản thanh toán đó dành cho việc gì ngay cả trước khi nó truy vấn trình khám phá khối (block explorer).
Mô hình hóa Trạng thái một cách trung thực
Tiền trên blockchain di chuyển theo từng giai đoạn. Hệ thống nội bộ của bạn cần một bộ từ vựng khớp với các giai đoạn đó, nếu không, các đội ngũ kỹ thuật, hỗ trợ và vận hành của bạn sẽ không thể hiểu ý nhau.
Hãy giữ mô hình ở dạng phẳng và mang tính mô tả. Một nhân viên hỗ trợ không chuyên về kỹ thuật cũng có thể đọc trạng thái và biết cần phải nói gì với khách hàng.
- Created: Yêu cầu đã tồn tại, nhưng blockchain chưa hiển thị gì. Khách hàng chưa gửi giao dịch lên mạng lưới.
- Detected: Hệ thống giám sát của bạn đã phát hiện một giao dịch liên quan trong mempool hoặc một khối gần đây, nhưng nó chưa đạt được tính xác thực cuối cùng (finality). Đừng giao sản phẩm.
- Confirming: Giao dịch đã nằm trên chuỗi và đang tích lũy các xác nhận. Các chuỗi khối hoạt động với tốc độ khác nhau. Bitcoin có thể cần sáu khối. Ethereum có thể cần mười hai khối hoặc nhiều hơn tùy thuộc vào mức độ chấp nhận rủi ro của bạn. Hệ thống của bạn nên tuân thủ cơ chế hoạt động riêng của mạng lưới.
- Completed: Khoản thanh toán khớp với số tiền, tài sản, mạng lưới và ngữ cảnh dự kiến. Mọi quy tắc bạn đã thiết lập đều được thỏa mãn. Bây giờ bạn có thể thực hiện đơn hàng, kích hoạt gói đăng ký hoặc giải ngân tiền ký quỹ (escrow).
- Expired: Khách hàng đã bỏ lỡ khung thời gian thanh toán. Yêu cầu này không nên chấp nhận các khoản thanh toán trong tương lai trừ khi bạn chủ động kích hoạt lại nó.
- Mismatch: Khách hàng đã gửi tiền, nhưng có gì đó không ổn. Số tiền bị thiếu, mạng lưới khác biệt hoặc tài sản không khớp. Hãy chuyển trường hợp này cho bộ phận hỗ trợ. Đừng để hệ thống xử lý đơn hàng của bạn phải tự đoán.
Quy trình này biến một luồng dữ liệu chuỗi khối hỗn loạn thành một quy trình mà toàn bộ công ty của bạn có thể hiểu và nắm bắt được.
Ngừng Polling. Hãy bắt đầu Lắng nghe.
Một trong những cách nhanh nhất để đốt cháy ngân sách hạ tầng là để backend của bạn liên tục hỏi nhà cung cấp sau mỗi vài giây xem tiền đã đến chưa. Việc này gây lãng phí tài nguyên cho cả hai bên và làm tăng độ trễ không cần thiết.
Một kiến trúc tốt hơn sẽ sử dụng mô hình thông báo trạng thái. Nhà cung cấp thanh toán hoặc hạ tầng node của bạn nên đẩy một sự kiện (event) đến hệ thống của bạn ngay khi trạng thái thay đổi. Bạn sẽ nhận được một webhook khi giao dịch được phát hiện, một webhook khác khi nó đang xác nhận, và một webhook cuối cùng khi nó hoàn tất hoặc thất bại.
Điều này giúp hệ thống của bạn luôn phản hồi nhanh mà không tiêu tốn các chu kỳ CPU không cần thiết.
