Business Ownership Transfer
Hand a business over to another Paysasa account with a PIN and email-OTP protected, two-sided handshake.
https://api.paysasa.com/api/v1Authx-api-keyFormatJSONTransfer a business to another Pay account. Flow: current owner requests (wallet PIN + email OTP) → recipient accepts via emailed link → platform support approves. Chama ownership is not transferable on this path. Optional revoke of active API keys on completion.
Auth: signed-in dashboard/session only (not business API keys).
Availability: ownership transfer can be disabled for the platform. When disabled, the UI is hidden and these endpoints return 403.
UI: Business Settings → Transfer ownership. Accept page: /dashboard/invitations/ownership?token=…
Statuses: pending_acceptance → pending_admin → completed (or cancelled / rejected / expired). Final approval is handled by platform support, not via the merchant API.
Common errors: 403 wrong email / feature off / invalid PIN or OTP; 409 transfer already open; 429 too many OTP attempts.
Owner only. Returns { enabled, transfer }.
action: "send_otp" with pin, or create request with toEmail, pin, otp, optional revokeApiKeys (default true).
Body/query transferId. Cancels open request and rotates the accept token.
/ownership-transfers/acceptPreview (?token=) or accept with JSON body containing token. Must be signed in as the invited email.
// 1) Send OTP (requires wallet PIN)
await fetch("https://api.paysasa.com/api/v1/businesses/biz_xxx/ownership-transfer", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action: "send_otp", pin: "1234" }),
});
// 2) Create transfer request
const res = await fetch("https://api.paysasa.com/api/v1/businesses/biz_xxx/ownership-transfer", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
toEmail: "[email protected]",
pin: "1234",
otp: "654321",
revokeApiKeys: true,
}),
});
const { transfer, accept_url, mail_sent } = await res.json();// Recipient (signed in as invited email)
const preview = await fetch(
"https://api.paysasa.com/api/v1/ownership-transfers/accept?token=" + encodeURIComponent(token)
).then((r) => r.json());
const accepted = await fetch("https://api.paysasa.com/api/v1/ownership-transfers/accept", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token }),
}).then((r) => r.json());
// status becomes pending_admin until an admin approves