Tham Chiếu App Manifest
File manifest stripe-app.json là cấu hình trung tâm cho Stripe App của bạn. Nó khai báo danh tính, quyền, views UI, chính sách bảo mật và hành vi sau khi cài đặt của app.
Ví Dụ Manifest Đầy Đủ
{ "id": "com.tajo.brevo-integration", "version": "1.2.0", "name": "Tajo for Brevo", "icon": "./assets/icon.png", "distribution_type": "public", "sandbox_install_compatible": true, "stripe_api_access_type": "oauth", "allowed_redirect_uris": [ "https://tajo.io/stripe/callback", "https://tajo.io/stripe/oauth/complete" ], "permissions": [ { "permission": "customer_read", "purpose": "Read customer profiles to sync with Brevo contacts" }, { "permission": "customer_write", "purpose": "Update customer metadata with Brevo sync status" }, { "permission": "charge_read", "purpose": "Access payment history for Brevo event tracking" }, { "permission": "product_read", "purpose": "Sync product catalog to Brevo for personalized campaigns" }, { "permission": "event_read", "purpose": "Subscribe to real-time events for Brevo automation triggers" }, { "permission": "invoice_read", "purpose": "Track invoice lifecycle events in Brevo" } ], "ui_extension": { "views": [ { "viewport": "stripe.dashboard.customer.detail", "component": "CustomerDetailView" }, { "viewport": "stripe.dashboard.customer.list", "component": "CustomerListView" }, { "viewport": "stripe.dashboard.home.overview", "component": "OverviewView" }, { "viewport": "stripe.dashboard.drawer.default", "component": "DrawerView" }, { "viewport": "stripe.dashboard.settings", "component": "SettingsView" }, { "viewport": "stripe.dashboard.onboarding", "component": "OnboardingView" } ], "content_security_policy": { "connect-src": [ "https://api.tajo.io", "https://api.brevo.com" ], "image-src": [ "https://cdn.tajo.io", "https://assets.brevo.com" ], "purpose": "Connect to Tajo API for data sync and Brevo API for contact management" } }, "post_install_action": { "type": "onboarding" }, "constants": { "API_BASE_URL": "https://api.tajo.io/v1", "SYNC_INTERVAL_SECONDS": "300" }}Tham Chiếu Schema
Trường Cấp Cao Nhất
| Trường | Kiểu | Bắt Buộc | Mô Tả |
|---|---|---|---|
id | string | Có | Định danh app duy nhất theo ký hiệu reverse domain (dạng slug) |
version | string | Có | Chuỗi semantic version (vd. "1.2.0") |
name | string | Có | Tên hiển thị trên marketplace (tối đa 35 ký tự) |
icon | string | Có | Đường dẫn tương đối đến file icon app (PNG hoặc SVG 300x300) |
distribution_type | string | Có | "public" cho marketplace hoặc "private" cho nội bộ |
sandbox_install_compatible | boolean | Không | App có thể được cài đặt ở chế độ sandbox/test không |
stripe_api_access_type | string | Không | Phương thức truy cập API: "oauth" hoặc "api_key" |
allowed_redirect_uris | string[] | Không | Các URI redirect OAuth được phép cho luồng cài đặt |
permissions | PermissionRequest[] | Có | Mảng các yêu cầu quyền |
ui_extension | UIExtensionManifest | Không | Cấu hình UI extension |
post_install_action | PostInstallAction | Không | Hành động thực hiện sau khi cài đặt app |
constants | object | Không | Các cặp key-value có thể truy cập trong app lúc runtime |
id
Định danh app là chuỗi dạng slug, thường theo ký hiệu reverse domain:
"id": "com.tajo.brevo-integration"- Phải là duy nhất trên toàn bộ Stripe Apps
- Chỉ sử dụng chữ thường, số, dấu gạch ngang và dấu chấm
- Không thể thay đổi sau khi app được tạo
- Xác định URL của app trên marketplace
version
Tuân theo semantic versioning:
"version": "1.2.0"- MAJOR: Thay đổi breaking hoặc bổ sung tính năng quan trọng
- MINOR: Tính năng mới, tương thích ngược
- PATCH: Sửa lỗi và cải tiến nhỏ
- Phải được tăng cho mỗi lần upload
distribution_type
Kiểm soát ai có thể cài đặt app của bạn:
| Giá Trị | Mô Tả |
|---|---|
"public" | Có sẵn trên Stripe App Marketplace cho tất cả người dùng |
"private" | Chỉ có thể cài đặt bởi tài khoản Stripe của bạn |
stripe_api_access_type
Xác định cách app của bạn xác thực với Stripe API:
| Giá Trị | Mô Tả |
|---|---|
"oauth" | Sử dụng luồng OAuth 2.0 để xác thực (khuyến nghị cho app công khai) |
"api_key" | Sử dụng restricted API keys (phù hợp cho app private) |
PermissionRequest
Mỗi yêu cầu quyền khai báo một quyền Stripe API cụ thể mà app cần:
{ "permission": "customer_read", "purpose": "Read customer profiles to sync with Brevo contacts"}| Trường | Kiểu | Bắt Buộc | Mô Tả |
|---|---|---|---|
permission | string | Có | Định danh quyền (xem Tham Chiếu Permissions) |
purpose | string | Có | Giải thích dễ hiểu tại sao quyền này cần thiết |
Hướng dẫn mục đích:
- Viết giải thích rõ ràng, cụ thể mà merchants có thể hiểu
- Giải thích quyền được dùng để làm gì, không chỉ nó cấp phép gì
- Giữ mô tả ngắn gọn (một câu)
- Tránh thuật ngữ kỹ thuật
UIExtensionManifest
Cấu hình các thành phần UI của app:
{ "ui_extension": { "views": [...], "content_security_policy": {...} }}| Trường | Kiểu | Bắt Buộc | Mô Tả |
|---|---|---|---|
views | ViewManifest[] | Có | Mảng khai báo views |
content_security_policy | CSPRequest | Không | Content Security Policy cho các tài nguyên bên ngoài |
ViewManifest
Mỗi view ánh xạ một React component đến một Stripe Dashboard viewport:
{ "viewport": "stripe.dashboard.customer.detail", "component": "CustomerDetailView"}| Trường | Kiểu | Bắt Buộc | Mô Tả |
|---|---|---|---|
viewport | string | Có | Vị trí Dashboard nơi view này render (xem Tham Chiếu Viewports) |
component | string | Có | Tên của React component để render (phải khớp với tên component được export) |
Một app có thể khai báo nhiều views cho các viewport khác nhau:
"views": [ { "viewport": "stripe.dashboard.customer.detail", "component": "CustomerDetailView" }, { "viewport": "stripe.dashboard.payment.detail", "component": "PaymentDetailView" }, { "viewport": "stripe.dashboard.home.overview", "component": "OverviewView" }]CSPRequest
Content Security Policy kiểm soát các domain bên ngoài mà app của bạn có thể kết nối:
{ "content_security_policy": { "connect-src": [ "https://api.tajo.io", "https://api.brevo.com" ], "image-src": [ "https://cdn.tajo.io" ], "purpose": "Connect to Tajo API for data sync and load images from CDN" }}| Trường | Kiểu | Bắt Buộc | Mô Tả |
|---|---|---|---|
connect-src | string[] | Không | Các domain mà app có thể gửi network requests đến |
image-src | string[] | Không | Các domain mà app có thể load hình ảnh từ |
purpose | string | Có | Giải thích tại sao cần các kết nối bên ngoài này |
Caution
Chỉ bao gồm các domain mà app của bạn thực sự cần kết nối. Các mục CSP quá nhiều có thể gây ra kiểm tra xem xét bổ sung.
PostInstallAction
Cấu hình điều gì xảy ra ngay sau khi người dùng cài đặt app:
{ "post_install_action": { "type": "onboarding" }}| Trường | Kiểu | Bắt Buộc | Mô Tả |
|---|---|---|---|
type | string | Có | Kiểu hành động (xem bên dưới) |
url | string | Có điều kiện | URL cho hành động kiểu external |
Các Kiểu Hành Động
| Kiểu | Hành Vi |
|---|---|
"onboarding" | Mở onboarding view của app trong Dashboard |
"settings" | Mở settings view của app trong Dashboard |
"external" | Chuyển hướng người dùng đến URL bên ngoài (yêu cầu trường url) |
Ví dụ:
// Mở luồng onboarding{ "post_install_action": { "type": "onboarding" }}
// Mở trang settings{ "post_install_action": { "type": "settings" }}
// Chuyển hướng đến thiết lập bên ngoài{ "post_install_action": { "type": "external", "url": "https://app.tajo.io/stripe/setup" }}Xem hướng dẫn Post-Install Actions để biết các mẫu triển khai chi tiết.
Constants
Định nghĩa các cặp key-value tĩnh có thể truy cập lúc runtime trong app:
{ "constants": { "API_BASE_URL": "https://api.tajo.io/v1", "SYNC_INTERVAL_SECONDS": "300", "MAX_BATCH_SIZE": "100" }}- Tất cả giá trị phải là strings
- Constants được nhúng vào app lúc build time
- Sử dụng constants cho cấu hình thay đổi giữa các môi trường
- Không bao giờ lưu secrets hoặc API keys dưới dạng constants, sử dụng Secret Store API thay thế
Truy cập constants trong code app của bạn:
import { constants } from '@stripe/ui-extension-sdk/constants';
const apiUrl = constants.API_BASE_URL;Manifest Mở Rộng Cho Phát Triển
Trong quá trình phát triển local, có thêm các trường:
{ "id": "com.tajo.brevo-integration", "version": "0.1.0", "name": "Tajo for Brevo (Dev)", "icon": "./assets/icon-dev.png", "distribution_type": "private", "sandbox_install_compatible": true, "dev": { "hot_reload": true, "port": 4242 }}Phần dev bị loại bỏ trong production builds và app uploads. Chỉ sử dụng cho các cài đặt phát triển local.
Validation
Validate manifest trước khi upload:
# Validate cú pháp và schema manifeststripe apps validate
# Kiểm tra các vấn đề phổ biếnstripe apps checkCác lỗi validation phổ biến:
| Lỗi | Nguyên Nhân | Cách Sửa |
|---|---|---|
Invalid permission | Định danh quyền không biết | Kiểm tra Tham Chiếu Permissions |
Invalid viewport | Định danh viewport không biết | Kiểm tra Tham Chiếu Viewports |
Missing purpose | Quyền không có trường purpose | Thêm chuỗi purpose cho mỗi quyền |
Invalid version | Chuỗi version không phải semver | Sử dụng định dạng MAJOR.MINOR.PATCH |
Icon not found | Đường dẫn icon không phân giải được | Xác minh file icon tồn tại tại đường dẫn đã chỉ định |