Ενέργειες μετά την εγκατάσταση και onboarding
Οι ενέργειες μετά την εγκατάσταση καθορίζουν τι συμβαίνει αμέσως μόλις ένας χρήστης εγκαταστήσει το Stripe App σας. Μια καλά σχεδιασμένη εμπειρία μετά την εγκατάσταση καθοδηγεί τους χρήστες στη ρύθμιση και αυξάνει τα ποσοστά ενεργοποίησης.
Τύποι ενεργειών μετά την εγκατάσταση
Το Stripe υποστηρίζει τέσσερις τύπους ενεργειών μετά την εγκατάσταση, καθένας από τους οποίους ρυθμίζεται στο manifest της εφαρμογής σας:
1. Σύνδεσμος προς την εφαρμογή (προεπιλογή)
Ανοίγει την εφαρμογή στο προεπιλεγμένο viewport drawer. Αυτή είναι η προεπιλεγμένη συμπεριφορά, αν δεν οριστεί post_install_action:
{ "post_install_action": { "type": "default" }}Ο χρήστης βλέπει το viewport drawer.default της εφαρμογής στην πλευρική στήλη του Stripe Dashboard.
2. Σύνδεσμος προς το onboarding
Ανοίγει την ειδική προβολή onboarding της εφαρμογής, προσφέροντας μια εστιασμένη εμπειρία ρύθμισης:
{ "post_install_action": { "type": "onboarding" }}Αυτό απαιτεί να έχει δηλωθεί ένα viewport onboarding στο manifest σας:
{ "ui_extension": { "views": [ { "viewport": "stripe.dashboard.onboarding", "component": "OnboardingView" } ] }, "post_install_action": { "type": "onboarding" }}3. Σύνδεσμος προς τις ρυθμίσεις
Ανοίγει την προβολή ρυθμίσεων της εφαρμογής, κάτι που είναι χρήσιμο όταν η εφαρμογή χρειάζεται κλειδιά API ή διαμόρφωση πριν από τη χρήση της:
{ "post_install_action": { "type": "settings" }}Αυτό απαιτεί ένα viewport settings:
{ "ui_extension": { "views": [ { "viewport": "stripe.dashboard.settings", "component": "SettingsView" } ] }, "post_install_action": { "type": "settings" }}4. Σύνδεσμος προς εξωτερικό URL
Ανακατευθύνει τον χρήστη σε ένα εξωτερικό URL για τη ρύθμιση. Χρησιμοποιήστε το όταν η ροή onboarding σας βρίσκεται εκτός του Stripe Dashboard:
{ "post_install_action": { "type": "external", "url": "https://app.tajo.io/stripe/setup" }}Caution
Τα εξωτερικά URL πρέπει να χρησιμοποιούν HTTPS και να περιλαμβάνονται στα allowed_redirect_uris σας. Η ομάδα ελέγχου του Stripe θα επαληθεύσει ότι το εξωτερικό URL προσφέρει μια λειτουργική εμπειρία ρύθμισης.
Βέλτιστες πρακτικές για το onboarding
Κάντε το αβίαστο
Ελαχιστοποιήστε τα βήματα που χρειάζονται για να ξεκινήσει κάποιος:
- Συμπληρώστε εκ των προτέρων τις πληροφορίες που είναι διαθέσιμες από το πλαίσιο του λογαριασμού Stripe
- Χρησιμοποιήστε λογικές προεπιλογές για τις επιλογές διαμόρφωσης
- Επιτρέψτε την παράλειψη προαιρετικών βημάτων, με σαφή τρόπο ολοκλήρωσής τους αργότερα
- Δείξτε την πρόοδο με ενδείξεις βημάτων στις ροές πολλαπλών βημάτων
Κάντε το παραμετροποιήσιμο
Αφήστε τους χρήστες να προσαρμόσουν την ενσωμάτωση στις ανάγκες τους:
- Επιλογές αντιστοίχισης δεδομένων, αφήστε τους χρήστες να επιλέξουν ποια πεδία του Stripe συγχρονίζονται με το Brevo
- Συχνότητα συγχρονισμού, προσφέρετε επιλογές συγχρονισμού σε πραγματικό χρόνο, ανά ώρα ή ανά ημέρα
- Επιλεκτικός συγχρονισμός, αφήστε τους χρήστες να επιλέξουν ποιους πελάτες ή ποια προϊόντα θα συγχρονίζονται
- Προτιμήσεις ειδοποιήσεων, ρυθμίστε ειδοποιήσεις για σφάλματα συγχρονισμού ή σημαντικά συμβάντα
Κάντε το ουσιαστικό
Δείξτε αξία από την πρώτη στιγμή:
- Προεπισκόπηση των συγχρονισμένων δεδομένων πριν από την ενεργοποίηση της ενσωμάτωσης
- Δείξτε τι θα συμβεί όταν ο χρήστης ολοκληρώσει τη ρύθμιση
- Προσφέρετε δοκιμαστικό συγχρονισμό για να επιβεβαιωθεί ότι η σύνδεση λειτουργεί
- Εμφανίστε μετρήσεις επιτυχίας μόλις ολοκληρωθεί ο αρχικός συγχρονισμός
Το στοιχείο OnboardingView
Το στοιχείο OnboardingView εμφανίζεται σε ένα εστιασμένο παράθυρο modal όταν ο χρήστης εγκαθιστά την εφαρμογή:
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 > SMTP & API > 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;Ροή σύνδεσης με το SignInView
Αν η εφαρμογή σας απαιτεί από τους χρήστες να συνδεθούν σε έναν εξωτερικό λογαριασμό (όπως ο λογαριασμός Tajo), χρησιμοποιήστε μια ειδική προβολή σύνδεσης:
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> );};Εκκίνηση deep link με παραμέτρους ερωτήματος
Μπορείτε να εκκινήσετε συγκεκριμένα βήματα onboarding ή να προσυμπληρώσετε δεδομένα χρησιμοποιώντας παραμέτρους ερωτήματος στα 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};Δημιουργήστε deep links που προσυμπληρώνουν τα δεδομένα του onboarding:
// From your Tajo dashboard, generate a link that pre-fills the Brevo API keyconst 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('');Διαχείριση των χρηστών που επιστρέφουν
Όταν ένας χρήστης ανοίγει την εφαρμογή σας αφού έχει ολοκληρώσει το onboarding, εντοπίστε την κατάστασή του και εμφανίστε την κατάλληλη προβολή:
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
Αποθηκεύστε την κατάσταση ολοκλήρωσης του onboarding στο Secret Store του Stripe, ώστε να εντοπίζετε τους χρήστες που επιστρέφουν χωρίς κλήση σε εξωτερικό API.