Ajukan akses awal

Masukkan nama depan serta email atau nomor telepon Anda. Kami akan menghubungi Anda dengan detail akses Tajo.

Aksi Pasca-Instalasi & Onboarding

Aksi pasca-instalasi (post-install action) menentukan apa yang terjadi segera setelah pengguna memasang Stripe App Anda. Pengalaman pasca-instalasi yang dirancang dengan baik memandu pengguna melewati proses penyiapan dan meningkatkan tingkat aktivasi.

Jenis aksi pasca-instalasi

Stripe mendukung empat jenis aksi pasca-instalasi, masing-masing dikonfigurasi di manifest aplikasi Anda:

1. Tautan ke aplikasi (bawaan)

Membuka aplikasi pada viewport drawer bawaan. Ini adalah perilaku bawaan jika post_install_action tidak ditentukan:

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

Pengguna melihat viewport drawer.default milik aplikasi di sidebar Stripe Dashboard.

2. Tautan ke onboarding

Membuka tampilan onboarding khusus milik aplikasi, sehingga memberikan pengalaman penyiapan yang terfokus:

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

Ini membutuhkan viewport onboarding yang dideklarasikan di manifest Anda:

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

3. Tautan ke pengaturan

Membuka tampilan pengaturan aplikasi, berguna ketika aplikasi membutuhkan API key atau konfigurasi sebelum digunakan:

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

Ini membutuhkan viewport settings:

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

4. Tautan ke URL eksternal

Mengalihkan pengguna ke URL eksternal untuk penyiapan. Gunakan ini ketika alur onboarding Anda berada di luar Stripe Dashboard:

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

Caution

URL eksternal harus menggunakan HTTPS dan sebaiknya dicantumkan pada allowed_redirect_uris Anda. Tim peninjau Stripe akan memverifikasi bahwa URL eksternal tersebut menyediakan pengalaman penyiapan yang berfungsi.

Praktik terbaik onboarding

Buat semudah mungkin

Kurangi jumlah langkah yang dibutuhkan untuk mulai:

  • Isi otomatis informasi yang tersedia dari konteks akun Stripe
  • Gunakan nilai bawaan yang masuk akal untuk opsi konfigurasi
  • Izinkan melewati langkah opsional dengan jalur yang jelas untuk menyelesaikannya nanti
  • Tampilkan kemajuan dengan indikator langkah untuk alur bertahap

Buat dapat disesuaikan

Biarkan pengguna mengonfigurasi integrasi sesuai kebutuhan mereka:

  • Opsi pemetaan data, biarkan pengguna memilih bidang Stripe mana yang disinkronkan ke Brevo
  • Frekuensi sinkronisasi, tawarkan opsi sinkronisasi real-time, tiap jam, atau harian
  • Sinkronisasi selektif, biarkan pengguna memilih pelanggan atau produk mana yang disinkronkan
  • Preferensi notifikasi, konfigurasikan peringatan untuk error sinkronisasi atau peristiwa penting

Buat relevan

Tunjukkan nilainya sejak awal:

  • Pratinjau data yang disinkronkan sebelum mengaktifkan integrasi
  • Tunjukkan apa yang akan terjadi ketika pengguna menyelesaikan penyiapan
  • Sediakan opsi sinkronisasi uji coba untuk memastikan koneksi berfungsi
  • Tampilkan metrik keberhasilan setelah sinkronisasi awal selesai

Komponen OnboardingView

Komponen OnboardingView dirender dalam modal terfokus saat pengguna memasang aplikasi:

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;

Alur masuk dengan SignInView

Jika aplikasi Anda mengharuskan pengguna masuk ke akun eksternal (seperti Tajo), gunakan tampilan masuk khusus:

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>
);
};

Anda dapat meluncurkan langkah onboarding tertentu atau mengisi data terlebih dahulu menggunakan parameter kueri pada deep link:

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
};

Buat deep link yang mengisi data onboarding terlebih dahulu:

// 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('');

Menangani pengguna yang kembali

Ketika pengguna membuka aplikasi Anda setelah menyelesaikan onboarding, deteksi status mereka dan tampilkan tampilan yang sesuai:

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

Simpan status penyelesaian onboarding di Stripe Secret Store agar Anda dapat mendeteksi pengguna yang kembali tanpa panggilan API eksternal.

Ajukan akses awal

Masukkan nama depan serta email atau nomor telepon Anda. Kami akan menghubungi Anda dengan detail akses Tajo.

deteksi otomatis
Asisten AI

Halo! Tanyakan apa saja tentang dokumentasi.