Hành Động Sau Cài Đặt & Onboarding

Hành động sau cài đặt xác định điều gì xảy ra ngay sau khi người dùng cài đặt Stripe App của bạn. Trải nghiệm sau cài đặt được thiết kế tốt sẽ hướng dẫn người dùng qua quá trình thiết lập và tăng tỷ lệ kích hoạt.

Các Loại Hành Động Sau Cài Đặt

Stripe hỗ trợ bốn loại hành động sau cài đặt, mỗi loại được cấu hình trong app manifest:

1. Liên Kết Đến App (Mặc Định)

Mở app trong viewport drawer mặc định. Đây là hành vi mặc định nếu không có post_install_action được chỉ định:

{
"post_install_action": {
"type": "default"
}
}

Người dùng thấy viewport drawer.default của app trong thanh bên Stripe Dashboard.

2. Liên Kết Đến Onboarding

Mở view onboarding chuyên dụng của app, cung cấp trải nghiệm thiết lập tập trung:

{
"post_install_action": {
"type": "onboarding"
}
}

Điều này yêu cầu viewport onboarding được khai báo trong manifest:

{
"ui_extension": {
"views": [
{
"viewport": "stripe.dashboard.onboarding",
"component": "OnboardingView"
}
]
},
"post_install_action": {
"type": "onboarding"
}
}

3. Liên Kết Đến Settings

Mở view settings của app, hữu ích khi app yêu cầu API keys hoặc cấu hình trước khi sử dụng:

{
"post_install_action": {
"type": "settings"
}
}

Điều này yêu cầu viewport settings:

{
"ui_extension": {
"views": [
{
"viewport": "stripe.dashboard.settings",
"component": "SettingsView"
}
]
},
"post_install_action": {
"type": "settings"
}
}

4. Liên Kết Đến URL Bên Ngoài

Chuyển hướng người dùng đến URL bên ngoài để thiết lập. Sử dụng khi luồng onboarding nằm ngoài Stripe Dashboard:

{
"post_install_action": {
"type": "external",
"url": "https://app.tajo.io/stripe/setup"
}
}

Caution

URL bên ngoài phải dùng HTTPS và nên được liệt kê trong allowed_redirect_uris. Nhóm đánh giá Stripe sẽ xác minh rằng URL bên ngoài cung cấp trải nghiệm thiết lập hoạt động tốt.

Các Thực Hành Tốt Nhất Cho Onboarding

Làm Cho Dễ Dàng

Giảm thiểu số bước cần thiết để bắt đầu:

  • Điền trước thông tin có sẵn từ context tài khoản Stripe
  • Sử dụng giá trị mặc định hợp lý cho các tùy chọn cấu hình
  • Cho phép bỏ qua các bước tùy chọn với đường dẫn rõ ràng để hoàn thành sau
  • Hiển thị tiến trình với chỉ số bước cho luồng nhiều bước

Làm Cho Có Thể Tùy Chỉnh

Cho phép người dùng cấu hình tích hợp theo nhu cầu:

  • Tùy chọn ánh xạ dữ liệu, để người dùng chọn trường Stripe nào đồng bộ với Brevo
  • Tần suất đồng bộ, cung cấp tùy chọn đồng bộ theo thời gian thực, mỗi giờ, hoặc hàng ngày
  • Đồng bộ có chọn lọc, để người dùng chọn khách hàng hoặc sản phẩm nào cần đồng bộ
  • Tùy chọn thông báo, cấu hình cảnh báo cho lỗi đồng bộ hoặc sự kiện quan trọng

Làm Cho Phù Hợp

Hiển thị giá trị ngay lập tức:

  • Xem trước dữ liệu được đồng bộ trước khi kích hoạt tích hợp
  • Cho thấy điều gì sẽ xảy ra khi người dùng hoàn thành thiết lập
  • Cung cấp tùy chọn đồng bộ thử để xác minh kết nối hoạt động
  • Hiển thị số liệu thành công sau khi đồng bộ ban đầu hoàn thành

Component OnboardingView

Component OnboardingView hiển thị trong modal tập trung khi người dùng cài đặt app:

import {
Box,
Button,
Inline,
Icon,
Banner,
TextField,
Select,
Divider,
} from '@stripe/ui-extension-sdk/ui';
import type { ExtensionContextValue } from '@stripe/ui-extension-sdk/context';
import { useState } from 'react';
const OnboardingView = ({ environment, userContext }: ExtensionContextValue) => {
const [step, setStep] = useState(1);
const [brevoApiKey, setBrevoApiKey] = useState('');
const [syncMode, setSyncMode] = useState('realtime');
const [isConnecting, setIsConnecting] = useState(false);
const [error, setError] = useState<string | null>(null);
const totalSteps = 3;
const handleConnect = async () => {
setIsConnecting(true);
setError(null);
try {
// Store the API key securely
await storeBrevoApiKey(brevoApiKey);
// Verify the connection
const result = await verifyBrevoConnection(brevoApiKey);
if (result.success) {
setStep(2);
} else {
setError('Unable to connect to Brevo. Please check your API key.');
}
} catch (err) {
setError('Connection failed. Please try again.');
} finally {
setIsConnecting(false);
}
};
return (
<Box css={{ padding: 'large' }}>
{/* Progress indicator */}
<Inline css={{ marginBottom: 'large' }}>
Step {step} of {totalSteps}
</Inline>
{error && (
<Banner type="critical" title="Connection Error">
{error}
</Banner>
)}
{step === 1 && (
<Box>
<Inline css={{ fontWeight: 'bold', fontSize: 'large' }}>
Connect Your Brevo Account
</Inline>
<Inline css={{ marginTop: 'small', color: 'secondary' }}>
Enter your Brevo API key to start syncing customer data.
</Inline>
<TextField
label="Brevo API Key"
placeholder="xkeysib-..."
value={brevoApiKey}
onChange={(e) => setBrevoApiKey(e.target.value)}
css={{ marginTop: 'medium' }}
/>
<Inline css={{ marginTop: 'xsmall', color: 'secondary', fontSize: 'small' }}>
Find your API key in Brevo under Settings &gt; SMTP &amp; API &gt; API Keys
</Inline>
<Button
type="primary"
onPress={handleConnect}
disabled={!brevoApiKey || isConnecting}
css={{ marginTop: 'medium' }}
>
{isConnecting ? 'Connecting...' : 'Connect Brevo'}
</Button>
</Box>
)}
{step === 2 && (
<Box>
<Inline css={{ fontWeight: 'bold', fontSize: 'large' }}>
Configure Sync Settings
</Inline>
<Select
label="Sync Mode"
value={syncMode}
onChange={(value) => setSyncMode(value)}
css={{ marginTop: 'medium' }}
>
<option value="realtime">Real-time (recommended)</option>
<option value="hourly">Every hour</option>
<option value="daily">Once per day</option>
</Select>
<Divider css={{ marginY: 'medium' }} />
<Button type="primary" onPress={() => setStep(3)}>
Continue
</Button>
<Button type="secondary" onPress={() => setStep(1)}>
Back
</Button>
</Box>
)}
{step === 3 && (
<Box>
<Banner type="default" title="Ready to Sync">
Your Brevo account is connected. Tajo will begin syncing
customer data automatically.
</Banner>
<Box css={{ marginTop: 'medium' }}>
<Inline css={{ fontWeight: 'bold' }}>What happens next:</Inline>
<ul>
<li>Existing Stripe customers will sync to Brevo contacts</li>
<li>New customers and events will sync in real-time</li>
<li>View sync status on any customer's detail page</li>
</ul>
</Box>
<Button type="primary" onPress={() => {/* Navigate to dashboard */}}>
Go to Dashboard
</Button>
</Box>
)}
</Box>
);
};
export default OnboardingView;

Luồng Đăng Nhập Với SignInView

Nếu app yêu cầu người dùng đăng nhập vào tài khoản bên ngoài (như Tajo), hãy sử dụng view đăng nhập chuyên dụng:

import {
Box,
Button,
Inline,
TextField,
Banner,
Link,
} from '@stripe/ui-extension-sdk/ui';
import { useState } from 'react';
const SignInView = ({ onSignInComplete }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleSignIn = async () => {
setIsLoading(true);
setError(null);
try {
const response = await fetch('https://api.tajo.io/v1/auth/stripe-app', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error('Invalid credentials');
}
const { token } = await response.json();
// Store the auth token securely in Stripe's Secret Store
await storeAuthToken(token);
onSignInComplete();
} catch (err) {
setError('Sign-in failed. Please check your credentials and try again.');
} finally {
setIsLoading(false);
}
};
return (
<Box css={{ padding: 'large' }}>
<Inline css={{ fontWeight: 'bold', fontSize: 'large' }}>
Sign in to Tajo
</Inline>
<Inline css={{ marginTop: 'small', color: 'secondary' }}>
Connect your Tajo account to enable Brevo sync.
</Inline>
{error && (
<Banner type="critical" title="Sign-in Failed">
{error}
</Banner>
)}
<TextField
label="Email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
css={{ marginTop: 'medium' }}
/>
<TextField
label="Password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
css={{ marginTop: 'small' }}
/>
<Button
type="primary"
onPress={handleSignIn}
disabled={!email || !password || isLoading}
css={{ marginTop: 'medium' }}
>
{isLoading ? 'Signing in...' : 'Sign In'}
</Button>
<Link href="https://app.tajo.io/signup" external css={{ marginTop: 'small' }}>
Don't have a Tajo account? Sign up
</Link>
</Box>
);
};

Bạn có thể khởi chạy các bước onboarding cụ thể hoặc điền trước dữ liệu bằng tham số query trong deep links:

import type { ExtensionContextValue } from '@stripe/ui-extension-sdk/context';
const OnboardingView = ({ environment }: ExtensionContextValue) => {
// Access query parameters from the deep link
const { queryParams } = environment;
// Pre-fill step from query parameter
const initialStep = queryParams?.step ? parseInt(queryParams.step) : 1;
// Pre-fill API key from query parameter (e.g., from Tajo dashboard)
const prefilledApiKey = queryParams?.brevo_key || '';
// Source tracking for analytics
const installSource = queryParams?.source || 'marketplace';
const [step, setStep] = useState(initialStep);
const [brevoApiKey, setBrevoApiKey] = useState(prefilledApiKey);
// ... rest of onboarding logic
};

Tạo deep links điền trước dữ liệu onboarding:

// From your Tajo dashboard, generate a link that pre-fills the Brevo API key
const onboardingLink = [
'https://dashboard.stripe.com/live/acct_xxxxx/dashboard',
'?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.onboarding',
'&apps[com.tajo.brevo-integration][queryParams][step]=1',
'&apps[com.tajo.brevo-integration][queryParams][source]=tajo_dashboard',
].join('');

Xử Lý Người Dùng Quay Lại

Khi người dùng mở app sau khi hoàn thành onboarding, hãy phát hiện trạng thái của họ và hiển thị view phù hợp:

const MainView = ({ environment, userContext }: ExtensionContextValue) => {
const [authState, setAuthState] = useState<'loading' | 'signed-out' | 'onboarding' | 'ready'>('loading');
useEffect(() => {
checkUserState().then((state) => {
setAuthState(state);
});
}, []);
switch (authState) {
case 'loading':
return <Spinner label="Loading..." />;
case 'signed-out':
return <SignInView onSignInComplete={() => setAuthState('onboarding')} />;
case 'onboarding':
return <OnboardingView onComplete={() => setAuthState('ready')} />;
case 'ready':
return <DashboardView />;
}
};

Tip

Lưu trạng thái hoàn thành onboarding trong Stripe Secret Store để bạn có thể phát hiện người dùng quay lại mà không cần gọi API bên ngoài.

Subscribe to updates

developer-docs

Drop your email or phone number — we'll send you what matters next.

Trợ lý AI

Xin chào! Hãy hỏi tôi về tài liệu.

Bắt đầu miễn phí với Brevo