Payment Sessions
Payment sessions are the most common Embedded flow. This page covers the different ways you can configure them.
How It Works
- Your backend calls
POST /integrations/embedded/initiatewith a payload describing the payment - The API returns a session URL
- Your frontend passes that URL to
Paystar.completePayment(sessionUrl)to open the payment form
The shape of your request payload determines what the user sees — a simple open payment form, a single account balance, a multi-account selector, editable amounts, and more.
Channels
The Channel field determines who is initiating the payment.
| Channel | Description | Use Case |
|---|---|---|
QuickPay | Customer self-service (default) | Online bill pay, checkout pages |
POS | Agent-initiated on behalf of a customer | In-person payments, call center |
- Set
PosUserto the agent's Paystar email address (e.g.,"[email protected]") - The
PosUser's Paystar account must have POS permission enabled — contact your Account Manager to set this up ClientUsercannot be set on POS sessionsPosUsercannot be set on QuickPay sessions
{
"BusinessUnitSlug": "acme-utilities",
"Channel": "POS",
"PosUser": "[email protected]",
"Charges": [
{
"Amount": 15000,
"Description": "Walk-in payment"
}
]
}
Account Modes
The presence or absence of ClientAccount on your charges determines the account mode.
- Accountless
- Single Account
- Multiple Accounts
When to use: Simple payments with no account lookup — donations, one-off invoices, etc.
Charges have no ClientAccount. The user sees a simple payment form with the amounts you specify.
{
"BusinessUnitSlug": "acme-utilities",
"Channel": "QuickPay",
"Charges": [
{
"Amount": 15000,
"Description": "Invoice #123"
}
]
}
When to use: The customer is paying against one specific account (e.g., their utility bill).
One charge with a ClientAccount. The account is synced to Paystar automatically on session creation.
{
"BusinessUnitSlug": "acme-utilities",
"Channel": "QuickPay",
"Charges": [
{
"Amount": 15000,
"Description": "Account Balance",
"ClientAccount": {
"AccountNumber": "ACC-12345",
"Name": "John Doe",
"Balance": 15000
}
}
]
}
When to use: The customer has multiple accounts to pay (e.g., multiple properties).
Multiple charges, each with their own ClientAccount. The user can select which accounts to pay and (depending on configuration) adjust amounts.
{
"BusinessUnitSlug": "acme-utilities",
"Channel": "QuickPay",
"Charges": [
{
"Amount": 15000,
"Description": "123 Main St",
"ClientAccount": {
"AccountNumber": "ACC-12345",
"Name": "John Doe",
"Balance": 15000
}
},
{
"Amount": 8500,
"Description": "456 Oak Ave",
"ClientAccount": {
"AccountNumber": "ACC-67890",
"Name": "John Doe",
"Balance": 8500
}
}
]
}
Data Sync
When you create a payment session, Paystar creates and maintains its own records from the data you provide.
Account Sync
For every ClientAccount in your Charges array, Paystar creates an account record identified by AccountNumber (and SubAccountNumber if provided). This happens automatically on payment sessions — no flag is needed.
On future requests, if you change any values on the ClientAccount (add, change, or remove fields), Paystar's account record updates to match what you sent. The Note field and custom account fields do not sync.
AccountNumber and Name are required on every ClientAccount.
For AutoPay and Paperless sessions, account sync is controlled by the SyncAccount flag — it must be set to true for the account to sync. SyncAccount must be true when the account is being introduced to Paystar for the first time. Wallet and Notification sessions don't use accounts. See the API Reference for details.
Customer Sync
When you provide a ClientUser, Paystar creates a customer record identified by EmailAddress and associates that customer with any accounts in the session. This is automatic across all session types.
FirstName and LastName are optional but immutable — they are saved when the customer is first introduced to Paystar. Future requests with the same EmailAddress but different name values will not update the record.
Customer sync enables features like saved payment methods (wallet) and lets Paystar link the customer to their accounts across sessions.
Charges
Each item in the Charges array represents a line item in the payment.
All Amount and Balance values are integers in cents. For example, 15000 = $150.00.
Charge Fields
| Field | Type | Required | Description |
|---|---|---|---|
Amount | integer | Yes | Amount in cents (e.g., 15000 = $150.00) |
Description | string | No | Display text for this line item |
ChargeType | string | No | Custom charge type identifier |
ClientAccount | object | No | Account to associate with this charge |
ClientAccount Fields
| Field | Type | Required | Description |
|---|---|---|---|
AccountNumber | string | Yes | Your system's account identifier |
SubAccountNumber | string | No | Sub-account identifier |
Name | string | Yes | Account holder name |
Balance | integer | No | Account balance in cents |
PhoneNumber | string | No | Phone number on file |
DueDate | string | No | ISO 8601 date |
IssueDate | string | No | ISO 8601 date |
Note | string | No | Additional context |
Address | object | No | Account address (see below) |
Address Fields
All address fields are optional:
| Field | Type | Description |
|---|---|---|
StreetAddress | string | Street line 1 (max 100 chars) |
StreetAddress2 | string | Street line 2 (max 100 chars) |
City | string | City (max 100 chars) |
State | string | State abbreviation |
ZipCode | string | ZIP code |
Customer Identity
The ClientUser field identifies the customer making the payment.
| Field | Type | Required | Description |
|---|---|---|---|
EmailAddress | string | Yes (if ClientUser provided) | Customer email — used as the unique identifier |
FirstName | string | No | Customer first name |
LastName | string | No | Customer last name |
With ClientUser: Paystar creates a customer record identified by EmailAddress and associates it with any accounts in the charges. FirstName and LastName are saved on the first request that introduces this customer — they are not updated by future requests. The payment form will show the option to save their payment method for future use (wallet).
Without ClientUser: Anonymous checkout. No wallet, no saved payment methods.
{
"BusinessUnitSlug": "acme-utilities",
"Channel": "QuickPay",
"ClientUser": {
"EmailAddress": "[email protected]",
"FirstName": "John",
"LastName": "Doe"
},
"Charges": [...]
}
Additional Options
| Field | Type | Description |
|---|---|---|
PaymentDescriptor | string | Custom descriptor for the payment |
ClientReference | string | Your system's reference ID for tracking — must be unique if provided |
SuccessUrl | string | Redirect URL after successful payment |
ReturnUrl | string | Redirect URL on cancel/back |
PaymentFields | object | Pre-configured custom fields (see below) |
CustomMeta | object | Arbitrary metadata attached to the session (see below) |
CustomMeta
CustomMeta is an optional object that accepts any key/value pairs. Whatever you pass is recorded directly onto the payment session and returned to you via webhooks, the Query API, and SDK events. No prior configuration is needed — use it to attach any data you want to flow through the payment back to your system.
{
"CustomMeta": {
"invoiceId": "INV-2025-001",
"department": "Water",
"source": "customer-portal"
}
}
PaymentFields
PaymentFields works similarly to CustomMeta in that you can pass key/value data through the payment session. The difference is that payment fields must be configured with your Account Manager before use, and they have a fallback behavior: if a configured payment field is not included in your API payload, Paystar presents it to the user as a form field to fill in. If it is included, the value you provide is used directly.
This makes PaymentFields useful for data that you may or may not have at the time of session creation — you can supply it when you have it, and let the user provide it when you don't.
{
"PaymentFields": {
"invoiceNumber": "INV-2025-001",
"memoLine": "January payment"
}
}
If you provide SuccessUrl, you must also provide ReturnUrl, and vice versa. Provide both or neither.
When set, the payment form displays "I'm done" (linking to SuccessUrl) and "Go back" (linking to ReturnUrl) buttons after the payment completes. This is typically not used with the SDK iframe modal — it's intended for redirect-based integrations where the user navigates away from your site.
Full Example
A complete single-account payment with customer identity and redirect URLs:
const response = await axios.post(
"https://dev-gateway.paystar.io/integrations/embedded/initiate",
{
BusinessUnitSlug: "acme-utilities",
Channel: "QuickPay",
ClientUser: {
EmailAddress: "[email protected]",
FirstName: "John",
LastName: "Doe",
},
Charges: [
{
Amount: 15000,
Description: "January 2025 Water Bill",
ClientAccount: {
AccountNumber: "ACC-12345",
Name: "John Doe",
Balance: 15000,
DueDate: "2025-02-01T00:00:00Z",
},
},
],
},
{
headers: {
"Content-Type": "application/json",
"X-Paystar-Api-Key": process.env.PAYSTAR_API_KEY,
},
},
);
const sessionUrl = response.data.data.PaymentLogInLink;
// Then on the frontend:
Paystar.completePayment(sessionUrl);
Response
{
"hasErrors": false,
"errors": [],
"data": {
"PaymentSessionIdentifier": "abc123...",
"PaymentLogInLink": "https://dev.paystar.io/app/embedded/your-slug/session/abc123...",
"Status": "RequiresPaymentSource"
}
}
Validation & Business Rules
- Amounts are in cents —
15000= $150.00 - Max 25 charges per request
SuccessUrlandReturnUrlmust both be set or both be omitted- POS sessions cannot have
ClientUser; QuickPay sessions cannot havePosUser - Account sync — Paystar creates/updates an account record for each
ClientAccount, identified byAccountNumber/SubAccountNumber. Future requests update the record (exceptNoteand custom fields) - Customer sync — if
ClientUseris provided, Paystar creates a customer record (byEmailAddress) and associates it with the accounts.FirstName/LastNameare immutable after the first request