Yêu Cầu Chất Lượng Xem Xét App
Stripe xem xét mọi app được gửi lên marketplace dựa trên một bộ yêu cầu chất lượng toàn diện. Hiểu rõ các tiêu chuẩn này trước khi phát triển giúp tiết kiệm thời gian và giảm số vòng xem xét.
Tổng Quan
Xem xét Stripe App đánh giá app của bạn trên sáu lĩnh vực chính:
- Giá Cả Minh Bạch, Giao tiếp rõ ràng về chi phí
- Chức Năng App, Độ tin cậy và tính hoàn chỉnh
- Tiêu Chuẩn Developer, Chất lượng code và sử dụng API
- Chất Lượng UX, Tiêu chuẩn giao diện và trải nghiệm người dùng
- Bảo Mật, Bảo vệ dữ liệu và thực hành an toàn
- Tuân Thủ Pháp Lý, Yêu cầu về quyền riêng tư và quy định
Giá Cả Minh Bạch
App của bạn phải giao tiếp rõ ràng tất cả chi phí cho người dùng:
- Công bố giá cả: Tất cả giá phải được nêu rõ ràng trong listing marketplace
- Không phí ẩn: Người dùng không được gặp các khoản phí bất ngờ sau khi cài đặt
- Điều khoản dùng thử: Nếu có dùng thử, hãy nêu rõ thời hạn và điều gì xảy ra sau đó
- Luồng nâng cấp: Bất kỳ lời nhắc upsell hoặc nâng cấp nào phải không xâm phạm và rõ ràng là tùy chọn
- Đơn vị tiền tệ: Hiển thị giá theo đơn vị tiền tệ địa phương của người dùng khi có thể
Caution
Các app che giấu giá cả hoặc tính phí người dùng mà không có sự đồng ý rõ ràng sẽ bị từ chối ngay lập tức.
Định Dạng Ngày Và Giờ
Tất cả ngày và giờ hiển thị trong app của bạn phải tuân theo quy ước Stripe Dashboard:
- Sử dụng locale của người dùng để định dạng ngày khi có thể
- Hiển thị giờ theo múi giờ địa phương của người dùng
- Sử dụng timestamp tương đối cho các sự kiện gần đây (ví dụ: “2 giờ trước”)
- Sử dụng timestamp tuyệt đối cho các sự kiện cũ hơn với ngày và giờ đầy đủ
- Tuân theo ISO 8601 cho bất kỳ trường ngày nào hướng đến API
// Tốt: Sử dụng các tiện ích định dạng ngày của Stripeimport { formatDate, formatRelativeTime } from '@stripe/ui-extension-sdk/utils';
const formattedDate = formatDate(timestamp); // Theo localeconst relativeTime = formatRelativeTime(timestamp); // "2 giờ trước"Cài Đặt App
Nếu app của bạn yêu cầu cấu hình:
- Cung cấp Settings view chuyên dụng có thể truy cập từ viewport của app
- Điền sẵn các giá trị mặc định hợp lý khi có thể
- Xác thực tất cả đầu vào người dùng với thông báo lỗi rõ ràng
- Cho phép người dùng cập nhật cài đặt mà không cần cài đặt lại app
- Duy trì cài đặt qua các phiên sử dụng Stripe Secret Store API
Hỗ Trợ Sandbox
App của bạn phải hoạt động chính xác trong chế độ sandbox (test) của Stripe:
- Tương thích chế độ test: Tất cả tính năng phải hoạt động trong test mode
- Dữ liệu test: Sử dụng dữ liệu test thực tế minh họa chức năng app
- Không có dữ liệu live trong sandbox: Không bao giờ tiết lộ dữ liệu production trong test mode
- Xử lý nhẹ nhàng: Nếu một tính năng không khả dụng trong sandbox, hiển thị thông báo rõ ràng giải thích lý do
- Đặt
sandbox_install_compatible: truetrong manifest
{ "sandbox_install_compatible": true}Chức Năng App
Độ Tin Cậy
- App không được crash hoặc đóng băng trong quá trình sử dụng bình thường
- Tất cả các tính năng được quảng cáo phải hoạt động như mô tả
- Lỗi mạng phải được xử lý nhẹ nhàng với các tùy chọn thử lại
- App phải vẫn phản hồi trong các hoạt động nền
Tính Hoàn Chỉnh
- Không có nội dung placeholder, tính năng “sắp ra mắt” hoặc liên kết hỏng
- Tất cả các phần tử UI phải hoạt động, không có nút chết hoặc điều khiển không hoạt động
- Văn bản trợ giúp và liên kết tài liệu phải dẫn đến các trang hợp lệ
- Gỡ cài đặt phải xóa sạch tất cả dữ liệu app và webhooks
Hiệu Suất
- UI phải render trong vòng 3 giây trên kết nối tiêu chuẩn
- Các hoạt động đồng bộ nền không được chặn UI
- Các tập dữ liệu lớn phải sử dụng phân trang hoặc lazy loading
- Giảm thiểu các lệnh gọi API để tránh giới hạn tốc độ
Tiêu Chuẩn Developer
Sử Dụng API
- Sử dụng phiên bản ổn định mới nhất của Stripe API
- Tuân theo các phương pháp tốt nhất của Stripe API cho phân trang, xử lý lỗi và idempotency
- Không vượt quá giới hạn tốc độ, triển khai exponential backoff để thử lại
- Sử dụng webhooks cho các cập nhật theo sự kiện thay vì polling
Chất Lượng Code
- Không có lỗi console hoặc cảnh báo trong bản build production
- Xóa tất cả debug logging trước khi gửi
- Xử lý tất cả các trường hợp biên (trạng thái trống, dữ liệu thiếu, lỗi mạng)
- Tuân theo các mẫu thư viện component của Stripe để có UI nhất quán
Versioning
- Sử dụng semantic versioning (MAJOR.MINOR.PATCH)
- Ghi lại các thay đổi breaking trong các bản cập nhật phiên bản
- Duy trì khả năng tương thích ngược khi có thể
Chất Lượng UX
Quảng Cáo
- Không quảng cáo: App của bạn không được hiển thị quảng cáo dưới bất kỳ hình thức nào
- Không cross-promotion: Không quảng bá các sản phẩm hoặc dịch vụ khác trong app UI
- Nội dung thương hiệu: Chỉ hiển thị nhận diện thương hiệu của bạn, không phải thương hiệu bên thứ ba (ngoại trừ đối tác tích hợp như Brevo)
Ngôn Ngữ Và Nội Dung
- Ngôn ngữ nhất quán: Sử dụng thuật ngữ nhất quán trong toàn bộ app
- Giọng điệu chuyên nghiệp: Phù hợp với phong cách giao tiếp chuyên nghiệp, súc tích của Stripe Dashboard
- Không thuật ngữ chuyên môn: Tránh thuật ngữ kỹ thuật mà merchants có thể không hiểu
- Kiểm tra chính tả: Đảm bảo tất cả văn bản không có lỗi chính tả và ngữ pháp
- Chỉ tiếng Anh: Tất cả văn bản hiển thị với người dùng phải bằng tiếng Anh cho các app marketplace
Hộp Thoại Xác Nhận
Yêu cầu xác nhận người dùng cho các hành động phá hủy hoặc quan trọng:
// Tốt: Xác nhận trước các hành động phá hủyconst handleDisconnect = async () => { const confirmed = await showConfirmation({ title: 'Disconnect Brevo Integration', message: 'This will stop syncing customer data to Brevo. You can reconnect at any time.', confirmLabel: 'Disconnect', cancelLabel: 'Cancel', destructive: true, });
if (confirmed) { await disconnectIntegration(); }};Các hành động yêu cầu xác nhận:
- Ngắt kết nối tích hợp
- Xóa dữ liệu đã đồng bộ
- Thay đổi cài đặt ảnh hưởng đến luồng dữ liệu
- Đặt lại cấu hình về mặc định
Trạng Thái Loading
Luôn hiển thị chỉ báo loading cho các hoạt động bất đồng bộ:
// Tốt: Hiển thị trạng thái loading trong quá trình fetch dữ liệuconst CustomerSyncStatus = () => { const { data, isLoading, error } = useSyncStatus();
if (isLoading) { return <Spinner label="Loading sync status..." />; }
if (error) { return <Banner type="critical" title="Failed to load sync status"> {error.message} </Banner>; }
return <SyncStatusDisplay data={data} />;};Yêu cầu:
- Hiển thị spinner hoặc skeleton screen trong quá trình load dữ liệu
- Vô hiệu hóa nút trong quá trình gửi form
- Hiển thị chỉ báo tiến trình cho các hoạt động dài
- Không bao giờ hiển thị màn hình trống trong khi loading
Thông Báo Lỗi
Cung cấp thông báo lỗi rõ ràng, có thể hành động:
// Xấu: Lỗi chung chung"Something went wrong"
// Tốt: Cụ thể và có thể hành động"Unable to sync customer data to Brevo. Please verify your Brevo API keyin Settings and try again."Hướng dẫn thông báo lỗi:
- Giải thích điều gì đã xảy ra bằng ngôn ngữ đơn giản
- Đề xuất một hành động cụ thể người dùng có thể thực hiện để giải quyết vấn đề
- Cung cấp cách thử lại hoạt động thất bại
- Ghi lại thông tin lỗi chi tiết để debug (không hiển thị cho người dùng)
- Bao gồm mã lỗi để tham khảo hỗ trợ khi áp dụng
Bảo Mật
Secret Store API
Sử dụng Stripe’s Secret Store API cho tất cả việc lưu trữ dữ liệu nhạy cảm:
import { createHttpClient, STRIPE_API_KEY } from '@stripe/ui-extension-sdk/http_client';
// Tốt: Lưu trữ secrets sử dụng Secret Store APIconst storeBrevoApiKey = async (apiKey: string) => { const stripe = createHttpClient(STRIPE_API_KEY); await stripe.apps.secrets.create({ name: 'brevo_api_key', payload: apiKey, scope: { type: 'account' }, });};
// Tốt: Lấy secrets từ Secret Storeconst getBrevoApiKey = async () => { const stripe = createHttpClient(STRIPE_API_KEY); const secret = await stripe.apps.secrets.find({ name: 'brevo_api_key', scope: { type: 'account' }, }); return secret.payload;};Không bao giờ lưu trữ dữ liệu nhạy cảm trong:
- Local storage hoặc session storage
- Cookies
- Tham số URL
- Giá trị hardcoded trong source code
- File cấu hình plain text
Mã Hóa
- Không có mã hóa tùy chỉnh: Không tự triển khai các thuật toán mã hóa
- Sử dụng các nguyên thủy bảo mật tích hợp của Stripe (Secret Store, signing secrets)
- Sử dụng HTTPS cho tất cả các lệnh gọi API bên ngoài
- Xác thực tất cả webhook signatures trước khi xử lý
Xử Lý Dữ Liệu
- Chỉ yêu cầu các quyền mà app thực sự cần
- Không lưu trữ dữ liệu Stripe ngoài những gì cần thiết cho chức năng
- Triển khai chính sách lưu giữ dữ liệu phù hợp với chính sách bảo mật
- Cung cấp cơ chế cho người dùng yêu cầu xóa dữ liệu
Tuân Thủ Pháp Lý
Chính Sách Bảo Mật
App của bạn phải có chính sách bảo mật có thể truy cập công khai, bao gồm:
- Dữ liệu nào app thu thập từ Stripe
- Dữ liệu được lưu trữ, xử lý và chia sẻ như thế nào
- Chính sách lưu giữ và xóa dữ liệu
- Quyền của người dùng đối với dữ liệu của họ
- Thông tin liên hệ cho các yêu cầu về quyền riêng tư
- Tuân thủ các quy định hiện hành (GDPR, CCPA, v.v.)
Điều Khoản Dịch Vụ
- Cung cấp điều khoản dịch vụ rõ ràng cho app của bạn
- Không bao gồm các điều khoản mâu thuẫn với Điều khoản Dịch vụ của Stripe
- Nêu rõ bất kỳ hạn chế sử dụng nào
Tuân Thủ Quy Định
- Tuân thủ tất cả các quy định bảo vệ dữ liệu hiện hành
- Triển khai các thỏa thuận xử lý dữ liệu phù hợp
- Hỗ trợ yêu cầu tính di động và xóa dữ liệu
- Duy trì audit logs cho việc truy cập và xử lý dữ liệu
Lịch Trình Xem Xét
| Giai Đoạn | Thời Gian |
|---|---|
| Gửi ban đầu | 5-10 ngày làm việc |
| Xem xét sửa đổi | 3-7 ngày làm việc |
| Phê duyệt cuối | 1-2 ngày làm việc |
| Xuất bản | Ngay sau khi phê duyệt |
Tip
Giải quyết tất cả phản hồi xem xét trong một lần sửa đổi để tránh nhiều vòng xem xét. Nhóm Stripe cung cấp phản hồi cụ thể, có thể hành động cho từng vấn đề được tìm thấy.
Lý Do Từ Chối Phổ Biến
- Thiếu xử lý lỗi, App crash khi gặp lỗi mạng hoặc dữ liệu bất ngờ
- Trạng thái loading không đủ, Màn hình trống trong quá trình fetch dữ liệu
- Giá cả không rõ ràng, Giá không được công bố đầy đủ trong listing
- Quyền quá mức, Yêu cầu các quyền không cần thiết
- Sandbox mode hỏng, App không hoạt động trong test mode
- Vấn đề bảo mật, Lưu trữ secrets bên ngoài Secret Store API
- Thiếu chính sách bảo mật, Không có URL chính sách bảo mật có thể truy cập
- Chức năng không hoàn chỉnh, Tính năng “sắp ra mắt” hoặc nội dung placeholder