Integration Guide
This guide walks you through integrating Paystar Embedded into your website step by step.
Prerequisites
Before you begin, you'll need:
- API Credentials from Paystar — an API Key and a Business Unit Slug (contact your Account Manager)
- A backend server to store your API key securely and make API calls to create sessions
- HTTPS in production (localhost works for development)
Step 1: Install the SDK
Add the Paystar SDK snippet to your HTML. This creates a lightweight command queue that buffers method calls while the full SDK loads asynchronously.
- Development
- Production
<script>
!(function () {
var n = (window.Paystar = window.Paystar || []);
if (!n.x) {
((n.x = !0),
(n.m = [
"initialize",
"completePayment",
"startFlow",
"subscribe",
"destroy",
]),
(n.f = function (t) {
return function () {
var e = Array.prototype.slice.call(arguments);
(e.unshift(t), n.push(e), n);
};
}));
}
for (var o = 0; o < n.m.length; o++) {
var c = n.m[o];
n[c] = n.f(c);
}
((n.load = function (t, e) {
var sdkUrl = "https://dev.paystar.io/app/embedded.loader.js";
n._loadOptions = e;
n._dismissError = function () {
var d = document.getElementById("paystar-error");
if (d) {
d.close();
d.remove();
}
var s = document.getElementById("paystar-error-style");
if (s) s.remove();
};
n._showError = function () {
n._dismissError();
var s = document.createElement("style");
s.id = "paystar-error-style";
s.textContent = "#paystar-error::backdrop{background:#000000ba}";
document.head.appendChild(s);
var d = document.createElement("dialog");
d.id = "paystar-error";
d.style.cssText =
"border:0;padding:0;width:530px;max-width:100%;height:100%;max-height:calc(100vh - 4rem);margin:2rem auto;box-shadow:0 0 6px 2px #00000078;display:flex;align-items:center;justify-content:center;font-family:Poppins,sans-serif";
d.innerHTML =
'<button onclick="window.Paystar._dismissError()" style="position:absolute;top:8px;right:8px;background:none;border:0;font-size:1.25rem;cursor:pointer;color:#555">×</button><p style="margin:0;padding:2rem;font-size:1.15rem;color:#333;text-align:center;text-align:balance"><strong style="font-size:2rem">Something went wrong.</strong><br><br>This may be caused by a VPN, proxy, or connection from outside the United States. Please disable any such services, connect directly from a US-based network, and try again.</p>';
d.addEventListener("close", function () {
n._dismissError();
});
d.addEventListener("click", function (e) {
if (e.target === d) n._dismissError();
});
document.body.appendChild(d);
d.showModal();
};
var a = document.createElement("script");
a.type = "text/javascript";
a.async = true;
a.src = sdkUrl;
a.onerror = function () {
n.completePayment = function () {
n._showError();
};
n.startFlow = function () {
n._showError();
};
n.initialize = function () {};
n.destroy = function () {
n._dismissError();
};
n.subscribe = function () {};
};
var r = document.getElementsByTagName("script")[0];
r.parentNode.insertBefore(a, r);
}),
(n.SNIPPET_VERSION = "0.2.0"));
Paystar.initialize();
Paystar.load();
})();
</script>
<script>
(function () {
var n = (window.Paystar = window.Paystar || []);
if (!n.x) {
((n.x = !0),
(n.m = [
"initialize",
"completePayment",
"startFlow",
"subscribe",
"destroy",
]),
(n.f = function (t) {
return function () {
var e = Array.prototype.slice.call(arguments);
(e.unshift(t), n.push(e), n);
};
}));
}
for (var o = 0; o < n.m.length; o++) {
var c = n.m[o];
n[c] = n.f(c);
}
((n.load = function (t, e) {
var sdkUrl = "https://secure.paystar.io/app/embedded.loader.js";
n._loadOptions = e;
n._dismissError = function () {
var d = document.getElementById("paystar-error");
if (d) {
d.close();
d.remove();
}
var s = document.getElementById("paystar-error-style");
if (s) s.remove();
};
n._showError = function () {
n._dismissError();
var s = document.createElement("style");
s.id = "paystar-error-style";
s.textContent = "#paystar-error::backdrop{background:#000000ba}";
document.head.appendChild(s);
var d = document.createElement("dialog");
d.id = "paystar-error";
d.style.cssText =
"border:0;padding:0;width:530px;max-width:100%;height:100%;max-height:calc(100vh - 4rem);margin:2rem auto;box-shadow:0 0 6px 2px #00000078;display:flex;align-items:center;justify-content:center;font-family:Poppins,sans-serif";
d.innerHTML =
'<button onclick="window.Paystar._dismissError()" style="position:absolute;top:8px;right:8px;background:none;border:0;font-size:1.25rem;cursor:pointer;color:#555">×</button><p style="margin:0;padding:2rem;font-size:1.15rem;color:#333;text-align:center;text-align:balance"><strong style="font-size:2rem">Something went wrong.</strong><br><br>This may be caused by a VPN, proxy, or connection from outside the United States. Please disable any such services, connect directly from a US-based network, and try again.</p>';
d.addEventListener("close", function () {
n._dismissError();
});
d.addEventListener("click", function (e) {
if (e.target === d) n._dismissError();
});
document.body.appendChild(d);
d.showModal();
};
var a = document.createElement("script");
a.type = "text/javascript";
a.async = true;
a.src = sdkUrl;
a.onerror = function () {
n.completePayment = function () {
n._showError();
};
n.startFlow = function () {
n._showError();
};
n.initialize = function () {};
n.destroy = function () {
n._dismissError();
};
n.subscribe = function () {};
};
var r = document.getElementsByTagName("script")[0];
r.parentNode.insertBefore(a, r);
}),
(n.SNIPPET_VERSION = "0.2.0"));
Paystar.initialize();
Paystar.load();
})();
</script>
Step 2: Create Sessions (Backend)
All sessions must be created from your backend server. Each session type has its own endpoint and returns a session URL.
If a session creation call fails (network error, validation error, non-success response, etc.), Paystar Embedded will not have a session URL to display — your application is responsible for catching the error and showing an appropriate message to the user.
Payment Session
Create a session for one-time payments. Accounts in Charges[].ClientAccount are automatically synced to Paystar — no flag needed. Future requests with the same account update the record.
- JavaScript
- C#
async function createPaymentSession(amount, description) {
const response = await fetch(
"https://dev-gateway.paystar.io/integrations/embedded/initiate",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Paystar-Api-Key": process.env.PAYSTAR_API_KEY,
},
body: JSON.stringify({
BusinessUnitSlug: "your-business-unit-slug",
Channel: "QuickPay",
Charges: [
{
Description: description,
Amount: amount, // Amount in cents: 15000 = $150.00
},
],
// Optional: Include customer info to enable wallet features
// and attribute the payment to a customer
ClientUser: {
EmailAddress: "[email protected]",
FirstName: "John",
LastName: "Doe",
},
}),
},
);
const result = await response.json();
return result.data.PaymentLogInLink;
}
async Task<string> CreatePaymentSession(int amount, string description)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Paystar-Api-Key", Environment.GetEnvironmentVariable("PAYSTAR_API_KEY"));
var body = new
{
BusinessUnitSlug = "your-business-unit-slug",
Channel = "QuickPay",
Charges = new[]
{
new
{
Description = description,
Amount = amount // Amount in cents: 15000 = $150.00
}
},
// Optional: Include customer info to enable wallet features
// and attribute the payment to a customer
ClientUser = new
{
EmailAddress = "[email protected]",
FirstName = "John",
LastName = "Doe"
}
};
var response = await client.PostAsync(
"https://dev-gateway.paystar.io/integrations/embedded/initiate",
new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
);
var json = await response.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data").GetProperty("PaymentLogInLink").GetString();
}
AutoPay Session
Create a session for autopay enrollment. Set SyncAccount: true to sync the account to Paystar (required when introducing a new account). ClientUser is always automatically synced.
- JavaScript
- C#
async function createAutopaySession(accountNumber, customerEmail) {
const response = await fetch(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-autopay",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Paystar-Api-Key": process.env.PAYSTAR_API_KEY,
},
body: JSON.stringify({
BusinessUnitSlug: "your-business-unit-slug",
SyncAccount: true,
ClientAccount: {
AccountNumber: accountNumber,
Name: "John Doe",
},
ClientUser: {
EmailAddress: customerEmail,
FirstName: "John",
LastName: "Doe",
},
}),
},
);
const result = await response.json();
return result.data.SessionLink;
}
async Task<string> CreateAutopaySession(string accountNumber, string customerEmail)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Paystar-Api-Key", Environment.GetEnvironmentVariable("PAYSTAR_API_KEY"));
var body = new
{
BusinessUnitSlug = "your-business-unit-slug",
SyncAccount = true,
ClientAccount = new
{
AccountNumber = accountNumber,
Name = "John Doe"
},
ClientUser = new
{
EmailAddress = customerEmail,
FirstName = "John",
LastName = "Doe"
}
};
var response = await client.PostAsync(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-autopay",
new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
);
var json = await response.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data").GetProperty("SessionLink").GetString();
}
Wallet Session
Create a session for payment method management. Wallet sessions are per-customer (no ClientAccount). ClientUser is always automatically synced.
- JavaScript
- C#
async function createWalletSession(customerEmail) {
const response = await fetch(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-wallet",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Paystar-Api-Key": process.env.PAYSTAR_API_KEY,
},
body: JSON.stringify({
BusinessUnitSlug: "your-business-unit-slug",
ClientUser: {
EmailAddress: customerEmail,
FirstName: "John",
LastName: "Doe",
},
}),
},
);
const result = await response.json();
return result.data.SessionLink;
}
async Task<string> CreateWalletSession(string customerEmail)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Paystar-Api-Key", Environment.GetEnvironmentVariable("PAYSTAR_API_KEY"));
var body = new
{
BusinessUnitSlug = "your-business-unit-slug",
ClientUser = new
{
EmailAddress = customerEmail,
FirstName = "John",
LastName = "Doe"
}
};
var response = await client.PostAsync(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-wallet",
new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
);
var json = await response.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data").GetProperty("SessionLink").GetString();
}
Paperless Session
Create a session for paperless billing enrollment. Set SyncAccount: true to sync the account (required when introducing a new account). ClientUser is always automatically synced.
- JavaScript
- C#
async function createPaperlessSession(accountNumber, customerEmail) {
const response = await fetch(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-paperless",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Paystar-Api-Key": process.env.PAYSTAR_API_KEY,
},
body: JSON.stringify({
BusinessUnitSlug: "your-business-unit-slug",
SyncAccount: true,
ClientAccount: {
AccountNumber: accountNumber,
},
ClientUser: {
EmailAddress: customerEmail,
},
}),
},
);
const result = await response.json();
return result.data.SessionLink;
}
async Task<string> CreatePaperlessSession(string accountNumber, string customerEmail)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Paystar-Api-Key", Environment.GetEnvironmentVariable("PAYSTAR_API_KEY"));
var body = new
{
BusinessUnitSlug = "your-business-unit-slug",
SyncAccount = true,
ClientAccount = new
{
AccountNumber = accountNumber
},
ClientUser = new
{
EmailAddress = customerEmail
}
};
var response = await client.PostAsync(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-paperless",
new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
);
var json = await response.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data").GetProperty("SessionLink").GetString();
}
Notification Session
Create a session for managing email/SMS notification preferences. ClientUser is always automatically synced.
- JavaScript
- C#
async function createNotificationSession(customerEmail) {
const response = await fetch(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-notifications",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Paystar-Api-Key": process.env.PAYSTAR_API_KEY,
},
body: JSON.stringify({
BusinessUnitSlug: "your-business-unit-slug",
ClientUser: {
EmailAddress: customerEmail,
FirstName: "John",
LastName: "Doe",
},
}),
},
);
const result = await response.json();
return result.data.SessionLink;
}
async Task<string> CreateNotificationSession(string customerEmail)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Paystar-Api-Key", Environment.GetEnvironmentVariable("PAYSTAR_API_KEY"));
var body = new
{
BusinessUnitSlug = "your-business-unit-slug",
ClientUser = new
{
EmailAddress = customerEmail,
FirstName = "John",
LastName = "Doe"
}
};
var response = await client.PostAsync(
"https://dev-gateway.paystar.io/integrations/embedded/initiate-manage-notifications",
new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
);
var json = await response.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data").GetProperty("SessionLink").GetString();
}
Step 3: Open Sessions (Frontend)
Once you have a session URL from your backend, use the SDK to open it.
Payment Sessions
Use completePayment() to open payment sessions:
Paystar.completePayment(sessionUrl, {
onComplete: function (result) {
console.log("Payment completed!", result);
},
});
All Other Flows
Use startFlow() for AutoPay, Wallet, Paperless, and Notification sessions:
Paystar.startFlow(sessionUrl, {
onEvent: function ({ event, data }) {
console.log("Event:", event, "Data:", data);
},
});
See the SDK Reference for the full options available on each method.
Step 4: Handle Events
Subscribe to events to track user actions:
const unsubscribe = Paystar.subscribe(
"PAYMENT-SESSION.PROCESSED",
function (data) {
console.log("Payment processed:", data);
},
);
// Later: unsubscribe if needed
unsubscribe();
See the Events page for all available events and their payloads.
Step 5: Customize (Optional)
Custom Container
Instead of the default modal, embed the form directly in your page:
<div id="payment-container" style="height: 600px; width: 100%;"></div>
<script>
Paystar.completePayment(sessionUrl, {
container: "#payment-container",
});
</script>
See the SDK Reference for container requirements.
Security Best Practices
Follow these rules to keep your integration secure:
- Never expose your API key in client-side code, HTML, or JavaScript
- Always create sessions from your backend — the frontend only receives session URLs
- Validate webhook signatures if using webhooks
- Use HTTPS in production — localhost is acceptable for development only