Skip to content

The Partner API is for the partner’s servers: it takes a partner secret key (psk_live_…/psk_test_…) as Authorization: Bearer and refuses browsers (no CORS). The full reference is Partner API; the Node, PHP, Python and Go helpers include a client.

Create a store when a business is created on your platform. The call is idempotent on externalRef: repeating it returns the same store, so retries are safe.

partner.ts
// When a store opens on your platform: idempotent on externalRef, so retrying returns the same store.
export async function openStore(shop: {
id: string
name: string
ownerName: string
ownerEmail: string
}) {
const store = await nexafon.stores.create({
externalRef: shop.id,
name: shop.name,
owner: { name: shop.ownerName, email: shop.ownerEmail },
country: 'SO',
timezone: 'Africa/Mogadishu',
locale: 'so',
})
return store.workspaceId
}
Terminal window
curl -X POST "https://api.nexafone.so/api/v1/partner/stores" \
-H "Authorization: Bearer $NEXAFON_PARTNER_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"externalRef": "shop-1", "name": "Shop One", "owner": {"name": "Amina Ali", "email": "[email protected]"}, "country": "SO", "timezone": "Africa/Mogadishu", "locale": "so"}'

The new store starts on your default store plan with its subscription running, and answers with its workspaceId. Then:

Operation
GET /api/v1/partner/stores Your stores, paged
GET /api/v1/partner/stores/{externalRef} One store
PATCH /api/v1/partner/stores/{externalRef} Rename it, or reopen a closed store with status: active
POST /api/v1/partner/stores/{externalRef}/close Close it: it becomes read-only and keeps its data
GET /api/v1/partner Your partner profile, status and default plan’s features

The same key calls the workspace operations of the API for your own stores, by workspaceId:

Terminal window
curl "https://api.nexafone.so/api/v1/workspaces/$WORKSPACE_ID/conversations" \
-H "Authorization: Bearer $NEXAFON_PARTNER_SECRET_KEY"

A workspace that is not one of your stores (another partner’s, or a business outside your platform) answers 404, exactly like one that does not exist. The key’s workspace scopes limit what it may do there.

Staff sign in with partner user tokens, which create or update their membership of each store they list. Leaving a store out of a token does not remove access; tell Nexafon explicitly:

partner.ts
// Staff are managed on your platform: change a role or remove someone from a store when they change there.
export async function staffChanged(storeRef: string, userId: string, role: string | null) {
if (role === null) await nexafon.members.disable(storeRef, userId)
else await nexafon.members.update(storeRef, userId, { role })
}
Operation
PUT /api/v1/partner/stores/{externalRef}/members/{partnerUserId} Change the user’s role (and teams) in that store; their menu updates live
DELETE /api/v1/partner/stores/{externalRef}/members/{partnerUserId} Disable them in that store; their open sessions end within seconds

Store sales are paid into the store’s own PayPoint account (see store payments):

Operation
PUT /api/v1/workspaces/{workspaceId}/payments/paypoint Save the store’s API key and merchant id; answers only “saved” and the last 4 characters
POST …/payments/paypoint/test Check the key with PayPoint without charging anyone
PUT …/payments/paypoint/wallets The wallets customers may pay with
DELETE …/payments/paypoint Remove the key

The key is encrypted at rest and never returned or logged.

Creating operations accept an Idempotency-Key header; see the API overview. Rate limits are per key (rate limits).