Appearance
Connectors
The products Kiwire already talks to, and what each one needs from the other side.
The connector hub
Grow › Connectors is a single hub for roughly twenty connector types — SMTP, SMS, WhatsApp, Active Directory, LDAP, Omaya, a generic external API, Marketing Email, CRM (HubSpot/Salesforce/Mailchimp/Klaviyo/Zoho), Database and Database API, PMS, Microsoft, Google, Webhook, MyDigitalID, SAML, Okta, Payment Gateway, Accounting, Google Sheets, and OAuth2 Mail — all backed by one underlying table (kiwire_connectors). The hub only shows the cards an admin has permission for (each type has its own manage-connector-* permission), and each card shows how many instances of that type are already configured, with a stats bar totalling how many are active versus inactive across the tenant.
Configuring a connector does not, by itself, turn anything on for guests. A connector is plumbing: once it exists, other parts of the admin — most notably a captive-portal journey's Login Methods — can reference it by its connector_id. Adding "Sign in with Google", an SMS-OTP login step, SAML SSO, MyDigitalID, or a payment-gateway checkout to a journey all require picking an already-configured connector of the matching type; there is no way to select one that does not exist yet. Configure the connector here first, then wire it into the journey.
At a glance
| Group | Connector types | What uses them |
|---|---|---|
| Sign-in and directories | Active Directory, LDAP, SAML 2.0, Okta, Microsoft Entra ID, Google, MyDigitalID, Database, API, Omaya | Login methods in captive-portal and WiFi Enterprise journeys |
| Messaging | SMTP, OAuth2 Mail, SMS, WhatsApp, Marketing Email | One-time codes, notifications, campaigns, scheduled reports |
| Payments | Payment Gateway (Stripe, Alipay, toyyibPay, Billplz, senangPay, iPay88, PayPal, Payfast, Adyen and others) | Buy Panel and captive-portal checkout, ISP subscriber renewals |
| Business systems | Accounting (Bukku, Xero, QuickBooks, Zoho Books, Odoo), CRM, Google Sheets | ISP invoices, guest sync to your CRM, exports to a sheet |
| Hotels | PMS | Room-and-surname sign-in, check-in/out |
| Automation | Webhook | Portal Rules, and events for n8n, Zapier and Make — see Automation tools |
Directory (AD, LDAP, SAML, Microsoft, Google)
Active Directory and LDAP connectors bind to an existing on-prem or hosted directory server so guest or staff accounts can authenticate against credentials that already exist elsewhere, instead of Kiwire holding a separate password. SAML, Microsoft (Entra ID) and Google are OAuth/SSO-style connectors instead — configuring one adds it as a "sign in with…" button option once it is picked as a login method's connector on a journey. Okta works the same way, alongside SAML, as a third SSO option.
Messaging (SMTP, SMS, WhatsApp)
SMTP is Kiwire's outbound email connector, used both for system email (password resets, admin notifications) and, via the separate Marketing Email connector type, for campaign sends. SMS and WhatsApp are gateway connectors used primarily for OTP-based login methods — a guest requests a one-time code and the connector is what actually sends it — and can also carry marketing or transactional messages depending on how a campaign is configured.
Webhooks
The webhook connector is a generic outbound notifier: a URL, an HTTP method (GET/POST/PUT/PATCH/DELETE), and an optional custom header. It serves two purposes:
- Portal Rules and campaign triggers — logins, first logins, connects, disconnects, dwell-time thresholds, recurring visits, milestones, last-visit events — call the URL with the fields the rule defines.
- Events for automation tools — tick events such as guest sign-in, voucher redeemed, payment received or ISP subscriber due, and Kiwire sends each one as a signed JSON
POSTwith retries and a delivery log. This is how n8n, Zapier and Make connect to Kiwire; see Automation tools.
External API
The API connector type is a generic, admin-configurable authenticator rather than an integration with one specific product. You point it at any REST-style endpoint — GET or POST, form or JSON body, no/basic/bearer auth — and tell it, using dot-notation paths, where in the response to find the success signal, an error message, the resolved username, and any extra fields to pull in. That is enough to authenticate guests against a bespoke internal system without Kiwire needing custom code for it; it is the same mechanism the PMS "json" and "get" handlers are built on.
MyDigitalID
MyDigitalID is Malaysia's national digital-identity scheme. Configuring this connector adds MyDigitalID as another SSO-style login option alongside SAML and Okta, so a guest can authenticate at the captive portal with a verified government digital identity instead of a Wi-Fi-specific username and password.
Setting up each connector
Every connector form starts the same way: an Active switch and a Name (optional, "e.g., Admin, Production, Backup") so several instances of the same type can be told apart. Disabling a connector keeps its configuration, but any login method, campaign or journey that references it stops working until it is switched back on. The sections below list the rest of each form, in the order the hub shows the cards. Field names are the labels as they appear on the form.
SMTP
Outbound email for system mail and OTP delivery. Test opens a "Test SMTP Connection" dialog that sends a message to a recipient you enter, using the values currently on the form.
| Field | What to enter |
|---|---|
| SMTP Host * | Hostname or IP address of your outgoing mail server, e.g. smtp.gmail.com. |
| SMTP Port | Common ports: 25, 465 (SSL), 587 (TLS). |
| Authentication | Encryption method required by your mail server: None, STARTTLS (TLS) or SSL/TLS. With None the connection stays unencrypted even if the server offers STARTTLS — pick STARTTLS if you want it used. |
| SMTP Username | Username or email used to authenticate with the SMTP server. |
| SMTP Password | Password or app-specific password for SMTP authentication. |
| SSL Verification (advanced) | Yes / No. Set No when the server is reached by IP address, uses a self-signed certificate, or is an older mail server that only offers outdated encryption (some on-premises Windows mail servers). The connection is still encrypted; only the certificate and cipher checks are relaxed. |
| From Address * (advanced) | The email address that will appear as the sender. |
| From Name (advanced) | Display name shown alongside the sender address. |
| CC (advanced) | Separate multiple addresses with commas. |
| Port | Encryption | When to use |
|---|---|---|
| 25 | None | Server-to-server relay only; many ISPs and cloud providers block outbound port 25. |
| 465 | SSL/TLS | Legacy SSL-wrapped SMTP, still supported by many providers. |
| 587 | STARTTLS (TLS) | The modern standard for authenticated submission — recommended for cloud relays. |
| 2525 | STARTTLS (TLS) | Alternative used by some providers (Mailgun, SendGrid) when 587 is blocked. |
For a personal Gmail account use an App Password (Google Account › Security › App Passwords) rather than the account password. For Google Workspace, prefer a dedicated account or the Gmail SMTP relay in the Admin Console.
SMS
The gateway behind SMS-OTP login and SMS campaigns. Test opens "Send Test SMS" — pick a country prefix, enter the number without the prefix, and Kiwire sends through the operator selected on the form.
| Field | What to enter |
|---|---|
| Operator | Twilio, Synchroweb, Generic or Genusis. The fields below change with the choice. |
| SSL Verification (advanced) | Yes / No. |
Twilio — Twilio Phone No (the Twilio-assigned number, e.g. +13603206925), Twilio SID (Account SID from twilio.com), Twilio Password (the auth token from twilio.com).
Synchroweb — API Key (provided by Synchroweb).
Genusis — Genusis URL (the URL to post SMS requests to), Client ID, Username, Private Key (provided by Genusis — not your password).
Generic — for any HTTP SMS API:
| Field | What to enter |
|---|---|
| Request Method | GET or POST. |
| Full URI | The URI to send the SMS request to. |
| Message | Variable name for the message body. |
| Phone Number | Variable name for the phone number to send to. |
| Headers | Custom headers, e.g. Authorization: Bearer token. |
| Custom Body | Extra body fields — field1:value1, field2:value2. |
| Body Format | Form Data or JSON. |
WhatsApp
Delivers OTP codes and verification links over WhatsApp Business API. Test opens "Test WhatsApp Connection" and sends a message to a number you enter (prefix + number). This is not the Meta Cloud API — it is one of two gateways:
| Field | What to enter |
|---|---|
| Provider | Synchroweb or WATI.io. |
| SSL Verification (advanced) | Yes / No. |
Synchroweb
| Field | What to enter |
|---|---|
| App ID * | Your WhatsApp gateway application ID (e.g. app_xxxxxxxxxxxxxxxx). |
| App Secret * | Secret key used to authenticate API requests. |
| Set as Default * | Yes sends messages using the Synchroweb device; No leaves it unused. |
| Credit Balance | Read-only — click Check to fetch the current balance. |
WATI.io
| Field | What to enter |
|---|---|
| API Endpoint * | Your account's base URL from the WATI dashboard, including your tenant ID (e.g. https://live-mt-server.wati.io/123456). |
| Access Token * | Bearer token from the WATI dashboard (API Docs page). |
| Channel Number * | Your WhatsApp Business sending number, digits only (e.g. 601111840639). |
| Template Name (Default) * | Approved WATI template used when no language-specific override matches. Its first placeholder ({{1}}) receives the OTP code or verification link. |
| Template Names by Language | Optional rows of Language (e.g. ms, zh-CN) → Template Name, matched against the guest's portal language; falls back to the default template. |
| Broadcast Name | Optional label WATI groups the send under; defaults to "Kiwire WiFi". |
Kiwire always sends one parameter, named 1, carrying the OTP code or verification link — make sure your WATI template uses it as {{1}} (for example as the suffix of a Dynamic URL button). Credit balance checking is not available for WATI; use the WATI dashboard.
Active Directory
Authenticates guests or staff against a domain controller. Test binds with the admin credentials on the form and reports success or the LDAP error.
| Field | What to enter |
|---|---|
| Controller * | IP address or hostname of the AD server, e.g. 192.168.1.10 or dc.company.com. |
| Account Suffix | e.g. @yourdomain.com — appended to usernames when binding. |
| Username * | Username used to query the directory, e.g. admin@company.com. |
| Password * | The password for that account. Leave blank to keep the existing password. |
| Base DN | e.g. DC=yourdomain,DC=com. |
| SSL Verification (advanced) | Yes / No. |
LDAP
Same idea against a generic LDAP directory. Test connects to the host and port and attempts the bind.
| Field | What to enter |
|---|---|
| LDAP Server * | IP address or hostname of the LDAP server. |
| Port | Default is 389 (or 636 for LDAPS). |
| RDN / Bind DN | e.g. cn=admin,dc=example,dc=com. Leave blank for anonymous bind. |
| SSL Verification (advanced) | Yes / No. |
There is no bind-password field on this form; a bind DN is used as given, and an empty one means an anonymous bind.
Omaya
Sends presence and analytics data to an Omaya server. No test action.
| Field | What to enter |
|---|---|
| Tenant ID * | Unique tenant identifier provided by Omaya. |
| Tenant Secret * | Secret key for authenticating with the Omaya API. |
| Host * | Base URL of the Omaya API server, e.g. https://api.omaya.io. |
| Port | API port number. Default is 443 for HTTPS. |
Database
Authenticates guests against an external SQL database. Test opens a connection with the values on the form. (Older "Database API" instances appear on this same card but have no form of their own — use the API connector for new HTTP-based authenticators.)
| Field | What to enter |
|---|---|
| DB Host * | Hostname or IP address of the external database server. |
| DB Port | e.g. 3306 for MySQL. |
| DB Username | Username for connecting to the external database. |
| DB Password | Password for the database user account. |
| DB Name | Name of the database to query for user authentication. |
| DB Type * | MySQL or MSSQL. |
| SSL Verification (advanced) | Yes / No. |
API
An inbound authenticator: Kiwire calls your endpoint with the guest's credentials and reads the answer. It does not push anything to you on events (that is the Webhook connector). Test opens "Test API Connection", where you enter a Test Username and Test Password; Kiwire calls the API with the current (unsaved) settings and shows HTTP Status, API Success, Message, Username Extracted, Mapped Data and the Raw Response.
| Field | What to enter |
|---|---|
| Method * | POST or GET. |
| Body Format | JSON or Form (URL-encoded). |
| URL * | Full URL of the external API endpoint, e.g. https://api.example.com/auth/login. |
| URL Parameters | Static key: value pairs appended to the URL as a query string on every request, one per line. |
| HTTP Headers | Extra request headers, one per line: Key: Value. |
| Auth Type | None, HTTP Basic Auth (Username + Password) or Bearer Token (Token). Injected into every request. |
| Username Field | Field name the API expects for the login username (e.g. username, login, email). |
| Password Field | Field name the API expects for the password (e.g. password, passwd, secret). |
| Extra Body Fields | Static key: value pairs always included in every request, one per line. |
| Success Path | Dot-notation path to the success flag (e.g. status, result.code, data.success). Blank treats any HTTP 2xx as success. |
| Expected Value | Value at the success path that means OK (e.g. success, true, 1). Blank accepts any truthy value. |
| Message Path | Dot-notation path to the user-facing message shown on error (e.g. message, error.detail). |
| Username Path | Dot-notation path to the normalised username in the response (e.g. data.username). Blank uses the submitted username. |
| Response Data Mapping | Rows of Response Path → Internal Field (e.g. data.email → email) to pull extra fields into the user record. |
| SSL Verification (advanced) | Yes / No. |
Marketing Email
Subscribes guests to a mailing list. No test action.
| Field | What to enter |
|---|---|
| Provider | Mailchimp or MadMimi. |
| Mailchimp API Key * / Mailchimp List ID | API key from your Mailchimp account (Account → Extras → API keys); the List ID from your list → Settings → List name & defaults, e.g. 306d39834c. |
| MadMimi Email / Username *, MadMimi API Key *, MadMimi List | The login email, the API key from account settings, and the name of the list to subscribe users to. |
| SSL Verification (advanced) | Yes / No. |
PMS
Hotel room-and-name login. The form (PMS Type, host/port, tokens, guest-password mode, Sync DB) is covered on its own page — see PMS and hotel systems.
Microsoft Entra ID
"Sign in with Microsoft" (Entra ID) for the WiFi Enterprise portal and the buy panel, via an Azure app registration. Test checks that the tenant ID resolves against Microsoft's OpenID discovery endpoint.
| Field | What to enter |
|---|---|
| Azure Tenant ID * | Your Azure Active Directory tenant ID (GUID from Azure Portal). |
| Client ID (App ID) * | Application (client) ID from your Azure App Registration. |
| Client Secret | Client secret value from your Azure App Registration. |
| OAuth Scopes | Space-separated list of scopes. Default: openid profile email User.Read. |
| Redirect URI | Read-only, two values shown with copy buttons — Captive Portal https://<your-kiwire-host>/wifi/oauth/microsoft/callback and Buy Panel https://<your-kiwire-host>/buy/oauth/microsoft/callback. Add both to the app registration. |
In the Azure Portal: Microsoft Entra ID → App registrations → New registration, name it (e.g. "Kiwire WiFi Portal") and pick the supported account types. Under Authentication → Add a platform → Web, add both Redirect URIs from the form, exactly as shown including https://. Under Certificates & secrets → New client secret, create a secret and copy its value immediately — Azure shows it once. From Overview, copy the Directory (tenant) ID and Application (client) ID into the form. Client secrets expire; an expired secret blocks every Microsoft login until it is rotated. A redirect-URI mismatch shows up as AADSTS50011 on the Microsoft page; a wrong or expired secret as AADSTS7000215 in the portal log.
Accounts are matched on the Entra object id (oid), so a user keeps the same Kiwire account across app registrations; the sign-in email is taken from the email claim, or the UPN when the account has no mail attribute. The scopes field must keep openid (Kiwire adds it back if it is removed) — without it Microsoft returns no identity token.
Webhooks
An outbound notifier used by Portal Rules and campaign triggers, and — when you tick events — by automation tools such as n8n and Zapier.
| Field | What to enter |
|---|---|
| URL * | The endpoint URL that will receive the webhook request. |
| HTTP Method * | GET, POST, PUT, PATCH or DELETE. Used by Portal Rules; event deliveries are always POST. |
| Headers | One header per line, e.g. Authorization: Bearer …. Sent with every request, including events. |
| Events for automation tools | Tick the events to send: guest signed in, guest registered, voucher redeemed, payment received, subscriber payment due, subscriber expired. Leave all unticked if the webhook is only used by Portal Rules. |
| Signing secret | Created on the first save with an event ticked. Show reveals it, New replaces it. Used for the X-Kiwire-Signature header. |
Once saved, the form also has Send test event and a log of the 20 most recent deliveries with Resend. Event formats, signature checking and retries are on Automation tools.
Google Sheets
Pushes portal data directly to a spreadsheet via a service account. Test Connection verifies the credentials against the spreadsheet.
| Field | What to enter |
|---|---|
| Service Account JSON * | Upload the Google Cloud service account JSON key file. The service account must have Editor access to the spreadsheet. |
| Spreadsheet ID * | The ID from the sheet URL: docs.google.com/spreadsheets/d/{THIS_PART}/edit. |
| Sheet Name | The tab to write to. Defaults to Sheet1. |
Google
"Sign in with Google" for the captive portal and the buy panel. Test checks the client ID and secret against Google.
| Field | What to enter |
|---|---|
| Client ID * | OAuth 2.0 Client ID from Google Cloud Console. |
| Client Secret * | OAuth 2.0 Client Secret from Google Cloud Console. |
| Redirect URI | Read-only, two values shown with copy buttons — Captive Portal https://<your-kiwire-host>/wifi/oauth/google/callback and Buy Panel https://<your-kiwire-host>/buy/oauth/google/callback. Add both to the OAuth client. |
| SSL Verification (advanced) | Yes / No. |
In the Google Cloud Console: create or select a project, then APIs & Services → OAuth consent screen (External for a public guest portal, Internal for Workspace-only). Under Credentials → Create Credentials → OAuth client ID, choose Web application and add both redirect URIs above under Authorised redirect URIs, exactly as shown including https://. Copy the Client ID and Client Secret into the form. A mismatch produces redirect_uri_mismatch at login.
Directory check (Google and Microsoft)
A device enrolled for WiFi Enterprise keeps connecting with its own profile; it does not sign in to Google or Microsoft again. So that people who leave lose access, switch on Directory check at the bottom of the Google or Microsoft connector. Once a day Kiwire asks the directory about each person who enrolled through that connector:
- Deleted, or suspended / blocked from signing in — the Kiwire account is suspended and any live session is disconnected, so every device they enrolled stops connecting.
- Back in the directory — an account the check suspended is made active again. Accounts you suspended yourself are never changed.
- Not answerable — people who signed in with an address outside the directory (a personal Gmail, a guest from another organisation) are skipped, and so is anyone the directory could not be asked about that day.
Safety limit. If one check would suspend more than 5 people and more than a quarter of everyone checked, nothing is changed. Every admin gets a notification instead, and the connector page lists who would be suspended, with a button to go ahead. Admins are also notified when people are suspended or reactivated, and when the check stops working (for example when the connection expires).
Preview shows what a check would change without changing anything. Run now does a real check straight away.
Set up the directory check for Google Workspace
You need access to the Google Cloud project that holds this connector's OAuth client, and a Google Workspace admin account (a super admin, or an admin role that can read users). It takes about five minutes. The connector page shows the same steps, filled in with your connector's details.
- Find the Google Cloud project. The connector's Client ID starts with a number, for example
123456789012-abc….apps.googleusercontent.com; that number is the project number. The project picker in console.cloud.google.com does not search by number. Open each likely project and check Project number on its dashboard, or go to APIs & Services › Credentials and look for an OAuth client whose ID starts with that number. Check the picker's All tab as well as Recent. If none of your projects has it, the OAuth client was created under someone else's Google account. Either ask them to add you to that project, or create a new OAuth client (Web application) in a project you own, add both redirect URIs from the connector form, and save the new Client ID and Client Secret on the connector. - Enable the Admin SDK API. In that project open APIs & Services › Library, search for Admin SDK API and click Enable. Allow a minute or two for it to take effect.
- Stop the connection from expiring. Open APIs & Services › OAuth consent screen (in newer consoles Google Auth Platform › Audience). Internal is right for a staff login, and nothing more is needed. If it shows External with status Testing, switch it to Internal or click Publish app. In Testing mode Google ends the connection after 7 days and the check stops.
- Check the redirect URI. No new redirect URI is needed. Connecting uses the Captive Portal redirect URI shown on the connector, which staff sign-in already uses. Make sure it is listed under Credentials › your OAuth client › Authorised redirect URIs.
- Connect. On the Google connector, scroll to Directory check and click Connect Google Workspace. Sign in with the Workspace admin account and allow both permissions Google asks for: see users and see domains. Kiwire gets read-only access and never changes anything in Google. Open Kiwire at its usual web address before you click; signing in from a different address loses the session. You come back to Connectors with "Google Workspace connected".
- Preview, then switch on. Click Preview to see how many people were checked and who would be suspended. Nothing changes. If the list is right, turn on Check the directory every day.
If something goes wrong:
| Message | What to do |
|---|---|
| Admin SDK API is not enabled … or not a Workspace admin | Step 2 has not taken effect yet (wait a minute and connect again), or the account is not a Workspace admin. |
| Google returned no long-lived access | Google remembered an earlier consent. Remove the app at myaccount.google.com › Security › Third-party connections, then connect again. |
| The read-only user permission was not granted | A permission was unticked on Google's screen. Connect again and allow both. |
| The Google connection expired or was removed | The admin who connected left or lost admin rights, or the consent screen is still in Testing (step 3). Another admin clicks Connect again. |
Error 400: access_not_configured ("You can't access this app until an admin at your institution reviews and configures access") | Your Workspace blocks apps that ask for admin permissions until they are trusted. A super admin opens admin.google.com › Security › Access and data control › API controls and, under App access control, clicks Manage app access. Find the app in the list: it has the name shown on your OAuth consent screen and appears after the first blocked attempt. Open it and set access to Trusted. If it is not listed, use Configure new app and paste the connector's full Client ID. Wait a few minutes (up to an hour), then connect again. Trusting the app only lets it ask; it still gets only the read-only access the admin approves. |
redirect_uri_mismatch on Google's page | The Captive Portal redirect URI is missing from the OAuth client (step 4). |
| That Google sign-in expired or did not start here | You started from one Kiwire address and Google returned to another. Open Kiwire at its usual address and connect again. |
Set up the directory check for Microsoft 365
You need an Entra Global Administrator or Privileged Role Administrator to grant consent. Nothing extra is stored in Kiwire: the check uses the connector's own client ID and secret.
- Open the app registration. In entra.microsoft.com go to Identity › Applications › App registrations › All applications. Open the app whose Application (client) ID matches the connector.
- Add the permission. Open API permissions › Add a permission › Microsoft Graph › Application permissions. It must be Application, not Delegated. Tick User › User.Read.All, then click Add permissions. Kiwire only reads whether each person still exists and can sign in.
- Grant admin consent. On the same page click Grant admin consent for your organisation and confirm. The status of User.Read.All must turn green (Granted).
- Check the tenant ID. The connector's Directory (tenant) ID must be your organisation's own ID, shown on the app's Overview page, or one of its domains.
common,organizationsandconsumerscannot be checked; the connector page warns if one of them is set. - Check the client secret. Under Certificates & secrets, make sure the secret saved on the connector has not expired. If it has, create a new one and save its Value on the connector. An expired secret also stops Microsoft sign-in.
- Preview, then switch on. On the Microsoft connector click Preview, check the result, then turn on Check the directory every day.
If something goes wrong:
| Message | What to do |
|---|---|
| The app registration lacks the Microsoft Graph application permission User.Read.All | The permission was added as Delegated, or admin consent was not granted (steps 2–3). |
| The client secret is wrong or has expired | Step 5. |
| Set the connector's Directory (tenant) ID to your organisation's ID or domain | Step 4. |
OAuth2 Mail
Sends email through Gmail / Google Workspace or Microsoft 365 using XOAUTH2 instead of a stored SMTP password. Save first, then Connect mailbox to authorise; Send test email verifies the connected mailbox.
| Field | What to enter |
|---|---|
| Provider | Google (Gmail / Workspace) or Microsoft 365. |
| Azure Tenant ID (Microsoft 365) | Azure AD tenant ID, or common for multi-tenant apps. The Azure app needs the SMTP.Send permission and the mailbox must allow Authenticated SMTP. |
| Client ID * | The OAuth client ID. |
| Client Secret * | Leave blank on later saves to keep the saved secret. |
| Redirect URI | Read-only: https://<your-kiwire-host>/admin/connector/oauth2/callback. Register this exact URI in your Google Cloud / Azure app. Google requires HTTPS. |
| Sender name (advanced) | Display name on outgoing mail, e.g. "Kiwire WiFi". |
| SSL Verification (advanced) | Yes / No. |
MyDigital ID
Malaysia's MyDigital ID via Keycloak OIDC. Test fetches the OIDC discovery document for the base URL and realm.
| Field | What to enter |
|---|---|
| Keycloak Base URL * | Base URL of the Keycloak server (e.g. https://sso.mydigitalid.gov.my/auth). |
| Realm * | Keycloak realm name provided by MyDigital ID (e.g. mydigitalid). |
| Client ID * | OIDC Client ID registered in the MyDigital ID developer portal. |
| Client Secret * | OIDC Client Secret from the developer portal. |
| Redirect URI | Read-only: https://<your-kiwire-host>/captive-portal/mydigitalid/callback. Register it in your MyDigital ID client configuration. |
| SSL Verification (advanced) | Yes / No. |
SAML 2.0
Enterprise SSO from any SAML 2.0 IdP (Google Workspace, Entra ID, ADFS, Shibboleth). The form starts with the values to copy into the IdP, then the values to copy from it.
Register in your IdP (read-only, with copy buttons):
| Value | Where it comes from |
|---|---|
| SP Entity ID | Your SP Entity ID if set below, otherwise the ACS URL. Paste it as the IdP's "Entity ID" or "Audience URI". |
| ACS URL (Callback / Redirect URL) | https://<your-kiwire-host>/captive-portal/saml/acs — shared by every SAML connector on the tenant. The IdP POSTs the assertion here. |
| SP Metadata URL | https://<your-kiwire-host>/saml/metadata/{id} — available after the first save; import it to auto-configure the SP. |
| Field | What to enter |
|---|---|
| IdP Entity ID * | The unique identifier URI of the identity provider (the entityID in its metadata). |
| SSO URL * | The HTTP-Redirect or HTTP-POST binding URL for initiating SSO (SingleSignOnService in the metadata). |
| Single Logout URL | Optional URL for single logout. |
| IdP X.509 Certificate * | Paste the base64-encoded signing certificate, with or without PEM headers. Rotate it when the IdP does — a stale certificate fails every login with a signature error. |
| SP Entity ID | The identifier Kiwire presents to the IdP. Defaults to the ACS URL if left blank. |
| NameID Format | Email Address (default), Persistent, Transient or Unspecified. |
| Email Attribute | SAML attribute that contains the user's email (default email). If the attribute is absent Kiwire falls back to the NameID. |
| Attribute Mapping — Standard Fields | Full Name, Phone Number, Remark, Site Name: one or more SAML attributes each, joined with Space, None, Comma or Hyphen (e.g. firstName + lastName → Full Name). |
| Attribute Mapping — Custom Extra Fields | Any Field Key (e.g. department) mapped from SAML attributes, stored in the user's extra_fields. |
| Sign AuthnRequests | Sign outgoing authentication requests (requires an SP private key). |
| Require Signed Assertions | Reject assertions that are not signed by the IdP. |
Typical attribute names: email / mail / http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress for the email attribute; displayName / cn / http://schemas.microsoft.com/identity/claims/displayname for Full Name.
Okta
The same SAML 2.0 engine with Okta's own labels. Sign-in method is SAML 2.0 (OIDC, SWA and API Services are listed as coming soon). In Okta: Applications → Create App Integration → SAML 2.0, then copy the two Kiwire values into Okta's "Configure SAML" screen.
| Value shown by Kiwire | Paste into Okta as |
|---|---|
| Audience URI (SP Entity ID) | "Audience URI (SP Entity ID)". |
| Single sign-on URL (ACS) | "Single sign-on URL" — https://<your-kiwire-host>/captive-portal/saml/acs; keep "Use this for Recipient URL and Destination URL" checked. |
| SP Metadata URL | https://<your-kiwire-host>/okta/metadata/{id}, after the first save. |
| Field | What to enter (from Okta's Sign On tab → View SAML setup instructions) |
|---|---|
| Issuer * | The "Identity Provider Issuer" — starts with http://www.okta.com/exk… (not the Metadata URL). |
| Sign On URL * | The "Identity Provider Single Sign-On URL". |
| Sign Out URL | Optional — Okta's sign-out URL for SLO. |
| Signing Certificate * | Okta's X.509 signing certificate, with or without PEM headers. |
| SP Entity ID, NameID Format, Attribute Mapping, Sign AuthnRequests, Require Signed Assertions | As for SAML 2.0 above. |
Payment Gateway
Takes payment for paid Wi-Fi plans on the buy panel, for payment login methods on the captive portal, and — when ISP is on — for subscribers paying their invoices on the User Portal. No test action. The read-only URLs are shown with copy buttons for gateways that need them registered in their dashboard:
| URL | Path |
|---|---|
| Return URL | https://<your-kiwire-host>/buy/payment/return — where the gateway redirects the guest after payment. |
| Callback URL / Notification URL | https://<your-kiwire-host>/buy/payment/callback — the server-to-server (IPN / webhook) endpoint; both labels point at the same path. |
| Cancel URL | https://<your-kiwire-host>/buy/payment/cancel — where the guest lands on a cancelled or failed payment. |
| Field | What to enter |
|---|---|
| Provider * | Stripe, toyyibPay, Billplz, PayPal, senangPay, iPay88, PayFast, Adyen, Alipay (Antom), SarawakPay or Fiuu Pay. |
| Mode | Sandbox (test) or Live (production). |
Credentials per provider (all required):
| Provider | Fields |
|---|---|
| Stripe | Publishable Key, Secret Key (Developers → API keys). Optional Offer Alipay switch: shows Alipay next to cards on the Stripe payment page. Turn Alipay on in your Stripe dashboard (Settings → Payment methods) first and check it supports your currency, or checkout fails. With the switch off, Stripe shows whatever payment methods your dashboard has turned on. |
| toyyibPay | User Secret Key (toyyibPay dashboard), Category Code (create a category in the dashboard and paste its code). Sandbox accounts at dev.toyyibpay.com have their own key. |
| Billplz | API Secret Key and X Signature Key (Settings → Keys & Integration — make sure X Signature is enabled), Collection ID (Billing → Collections). Sandbox accounts at billplz-sandbox.com have their own keys. |
| PayPal | Client ID (REST API app), Secret Key. |
| senangPay | Merchant ID, Secret Key. |
| iPay88 | Merchant Code, Merchant Key. |
| PayFast | Merchant ID, Merchant Key, Passphrase (if configured in your PayFast account). |
| Adyen | Merchant Account, API Secret Key (Customer Area → Developers → API credentials, with the Checkout webservice role), HMAC Key. In Live mode also the Live URL Prefix (Developers → API URLs). Country decides which payment methods Adyen offers (defaults to MY). Set Adyen's standard webhook to the Callback URL above, with HMAC enabled. |
| Alipay (Antom) | For taking Alipay without Stripe. Needs an Antom merchant account (Antom is Alipay's merchant service). Client ID, Region (Asia for Malaysia), Merchant Private Key and Antom Public Key — all from the Antom Dashboard (Developer → Key configuration). Wallet is ALIPAY_CN (Alipay, mainland China) unless you enter another wallet your Antom contract includes, such as ALIPAY_HK or TNG. Settlement Currency only if your contract settles in more than one currency. Paste the Callback URL above as the payment notification URL in the Antom Dashboard. |
| SarawakPay | Merchant ID, Merchant Name, Username, Password. |
| Fiuu Pay | Merchant ID, Secret Key, Verify Key. |
Wirecard and the old Alipay connector are retired (Alipay is now offered through Stripe or Alipay (Antom) above). An existing connector on either shows as retired and can no longer take payments: create a new connector with another provider, point your payment login methods at it, then delete the old one.
Accounting
Issues ISP invoices in your accounting software and reads payments back, so invoice numbering, emailing, tax and e-invoicing stay where your accountant works. Used by the ISP module: choose the connector under System → Settings → ISP → Issue invoices in. See Running a small ISP for what happens to each invoice.
| Field | What to enter |
|---|---|
| Accounting software * | Bukku, Xero, QuickBooks Online, Zoho Books or Odoo. |
| Name | Shown in admin lists, e.g. "Bukku main company". |
| Mode | Sandbox / staging or Live. Bukku staging and QuickBooks sandbox use separate test accounts; Xero, Zoho Books and Odoo ignore this. |
| Prices are | Before tax (tax added on top) or Including tax. |
| Email the invoice to the customer | The accounting software emails each invoice to the email on the Kiwire user. Turn off if you send invoices yourself. |
Per package:
| Package | Fields |
|---|---|
| Bukku | Company subdomain (the part before .bukku.my), Access token (Control Panel → Integrations → turn on API Access), Income account ID (Accounting → Chart of Accounts). Optional: tax code, e-invoice classification code, Submit e-invoice to MyInvois (Bukku submits to LHDN when MyInvois is on in your Bukku company), and the bank/cash account and payment method for payments recorded in Kiwire. |
| Xero | Client ID and Client secret from a Web app at developer.xero.com, Sales account code (e.g. 200). Optional: tax type, bank account code for payments. |
| QuickBooks Online | Client ID and Client secret from an app at developer.intuit.com (Accounting scope), Service item ID (Sales → Products and services). Optional: tax code, deposit account for payments. |
| Zoho Books | Client ID and Client secret from a Server-based client at api-console.zoho.com, Zoho data centre (Malaysian accounts are usually on zoho.com). Optional: organisation ID (filled in on Connect), income account ID, tax ID, and the deposit account and payment mode for payments recorded in Kiwire. |
| Odoo | Odoo address (e.g. https://yourcompany.odoo.com), Database, Login (the user's email) and API key (My Profile → Account Security → New API Key — Odoo Online needs the Custom plan for API access). Optional: income account, tax, sales and payment journals. |
Xero, QuickBooks Online and Zoho Books sign in with OAuth: add the Redirect URI shown on the form to your app in the vendor's developer portal, save the connector, then click Connect. Bukku and Odoo use the token or API key directly.
Test connection and Disconnect are available once the connector is saved. Disconnecting keeps the settings; invoices stop syncing until you connect again. A connector chosen for ISP invoices cannot be deleted until another one is chosen.
CRM
CRM connectors (HubSpot, Salesforce, Mailchimp, Klaviyo, Zoho) push guests to a CRM on login. They are not a hub card — open /admin/connector/crm directly, then New CRM Connector. The vendor is locked once configured; delete and recreate to change it.
| Field | What to enter |
|---|---|
| Vendor | hubspot, salesforce, mailchimp, klaviyo or zoho. |
| Connector name | Shown in admin lists. |
| Client ID, Client Secret (HubSpot, Salesforce, Zoho) | OAuth2 app credentials. Salesforce also needs Instance URL (e.g. https://mycompany.my.salesforce.com); Zoho needs Region (com, eu, in, com.au, jp). After saving, click Connect with OAuth2 — the OAuth redirect URI to register with the vendor is https://<your-kiwire-host>/admin/connector/crm/{id}/connect. |
| API Key, Data Center (Mailchimp) | The API key and its data-center suffix (us1, us2, eu1…). |
| Private API key (Klaviyo) | The pk_… private key. |
| Enabled | Push guests to the CRM on login. |
| Only push guests with marketing_email consent | Strongly recommended; guests who have not opted in are never pushed. |
Test connection and Disconnect are available once the connector is saved.