Sometimes you need more control over your signup flow than what our standard embeds provide. Perhaps you would like to develop a multi-step onboarding process, implement custom validation, or have full control over the styling. With Outseta's JavaScript Embed API, you can build a completely custom signup form and seamlessly hand off to Outseta for payment processing and account creation.

💡 This approach lets you control the entire user experience while leveraging Outseta's secure payment processing and subscription management.

👉 For simpler cases where you need to pre-populate fields, see Pre-populate sign-up form fields with Registration Defaults.

How It Works

The custom signup form approach follows these steps:

  1. Collect user information with your custom HTML form
  2. Process form data with JavaScript to build registration defaults
  3. Launch Outseta's checkout version of the signup embed in the checkout state
  4. Let Outseta handle payment processing, account creation, and email confirmations

Prerequisites

Before implementing a custom signup form, ensure you have:

  • The Outseta script configured correctly in your site's <head> element
  • Plan UIDs for the subscription plans you want to offer
  • Any custom properties configured in your Outseta account

Your basic Outseta configuration should look something like:

<!-- Outseta Configuration -->
<script>
var o_options = {
domain: "[your-domain].outseta.com",
}
</script>

<!-- Outseta Script (doing all the automagic) -->
<script src="https://cdn.outseta.com/outseta.min.js" data-options="o_options"></script>

Building the Custom Form

1. Create Your HTML Form

Design your form to suit your needs. Here's an example that collects standard registration data plus a custom company mascot field:

<form onsubmit="register(event)">
<label for="userEmail">Email (required)</label>
<input
type="email"
id="userEmail"
name="userEmail"
required
/>

<label for="firstName">First Name</label>
<input
type="text"
id="firstName"
name="firstName"
/>

<label for="lastName">Last Name</label>
<input
type="text"
id="lastName"
name="lastName"
/>

<label for="companyName">Company Name</label>
<input
type="text"
id="companyName"
name="companyName"
/>

<!-- Custom property example -->
<label for="maskot">Company Mascot</label>
<input
type="text"
id="maskot"
name="maskot"
/>

<!-- Plan selection -->
<h3>Choose Your Plan</h3>
<div class="plan-selection">
<label>
<input type="radio" name="plan" value="starter" checked />
Starter - $9/month
</label>
<label>
<input type="radio" name="plan" value="professional" />
Professional - $29/month
</label>
<label>
<input type="radio" name="plan" value="enterprise" />
Enterprise - $99/month
</label>
</div>

<button type="submit">Continue to Checkout</button>
</form>

2. Implement the Registration Function

Create a JavaScript function to handle form submission and launch Outseta's signup embed in the checkout state:

<script>
function register(event) {
event.preventDefault();
const formData = new FormData(event.target);

// Build registration defaults from form data
const registrationDefaults = {
Person: {
Email: formData.get("userEmail"),
FirstName: formData.get("firstName"),
LastName: formData.get("lastName")
},
Account: {
Name: formData.get("companyName"),
// Custom property example
Maskot: formData.get("maskot")
}
};

// Map plan selections to your actual plan UIDs
const planUids = {
starter: "your-starter-plan-uid",
professional: "your-professional-plan-uid",
enterprise: "your-enterprise-plan-uid"
};

// Open Outseta checkout with pre-populated data
Outseta.auth.open({
planUid: planUids[formData.get("plan")],
state: "checkout",
registrationDefaults: registrationDefaults
});
}
</script>

Key Configuration Options

Finding Plan UIDs

💡 To find your plan UIDs, go to Billing → Plans in your Outseta account. The UID is displayed on each plan's details page.

Registration Defaults Structure

The registrationDefaults object supports these main sections:

  • Person: Individual user information (Email, FirstName, LastName, custom properties, and more)
  • Account: Company/organization information (Name, custom properties, and more)
  • Subscription: Subscription-related data, like discount coupons

State Options

The state parameter controls where in the flow users start:

  • login Same as setting widgetMode to log in
  • forgotPassword Same as clicking "Forgot password?"
  • selectPlan Same as setting widgetMode to register
  • register Skips plan selection. 
    • planUid must be set.
  • checkout Skip to the last step of the registration process. 
    • registrationDefaults and planUid must be set.

Advanced Features

Form Validation

Add custom validation before launching Outseta:

<script>
function register(event) {
event.preventDefault();
const formData = new FormData(event.target);

// Custom validation example
const email = formData.get("userEmail");
if (!email.includes("@")) {
alert("Please enter a valid email address");
return;
}

// Continue with registration...
}
</script>

Conditional Plan Selection

You can dynamically determine which plan to offer based on form data:

<script>
function register(event) {
// ... form data collection ...

// Determine plan based on company size
let selectedPlan = "starter";
const companySize = formData.get("companySize");

if (companySize === "large") {
selectedPlan = "enterprise";
} else if (companySize === "medium") {
selectedPlan = "professional";
}

Outseta.auth.open({
planUid: planUids[selectedPlan],
state: "checkout",
registrationDefaults: registrationDefaults
});
}
</script>

Custom Properties

If you have custom properties configured in Outseta, include them in the appropriate section:

// For Person custom properties
Person: {
Email: formData.get("userEmail"),
// Standard properties
FirstName: formData.get("firstName"),
// Custom properties
Department: formData.get("department")
}

// For Account custom properties
Account: {
Name: formData.get("companyName"),
// Custom properties
Industry: formData.get("industry"),
CompanySize: formData.get("companySize")
}

Complete Example

Here's a minimal working example that demonstrates the complete integration:

<!DOCTYPE html>
<html>
<head>
<title>Custom Signup</title>

<!-- Outseta Configuration -->
<script>
var o_options = {
domain: "[your-domain].outseta.com",
};
</script>

<!-- Outseta Script -->
<script src="https://cdn.outseta.com/outseta.min.js" data-options="o_options"></script>
</head>

<body>
<form onsubmit="register(event)">
<input type="email" name="userEmail" placeholder="Email" required />
<input type="text" name="firstName" placeholder="First Name" />
<input type="text" name="companyName" placeholder="Company" />

<select name="plan">
<option value="starter">Starter - $9/month</option>
<option value="pro">Professional - $29/month</option>
</select>

<button type="submit">Sign Up</button>
</form>

<script>
function register(event) {
event.preventDefault();
const formData = new FormData(event.target);

const planUids = {
starter: "your-starter-uid",
pro: "your-pro-uid"
};

Outseta.auth.open({
planUid: planUids[formData.get("plan")],
state: "checkout",
registrationDefaults: {
Person: {
Email: formData.get("userEmail"),
FirstName: formData.get("firstName")
},
Account: {
Name: formData.get("companyName")
}
}
});
}
</script>
</body>
</html>

Full demo on Code Sandbox

Test the fully functional version over on Code Sandbox:

Benefits of This Approach

Full Control: Design your form exactly how you want it, with custom styling, validation, and user experience.

Flexible Data Collection: Collect information with custom inputs before handing off to Outseta.

Secure Payment Processing: Let Outseta handle the complex and sensitive payment processing.

Seamless Integration: Users experience a smooth transition from your custom form to Outseta's checkout.

This approach gives you the best of both worlds: complete control over your signup experience with the security and reliability of Outseta's payment processing and subscription management.