Skip to content

Powered by Grav CMS + Helios Theme

Customers

The customer record, read-only, their address book, the country list address forms draw on, and the three actions on their sign-in account.

The commercial record is read-only; the sign-in account and the address book are not. See Customer accounts and Customers → A customer's address book.

List customers

GET /api/v1/kahunacart/customers Permission kahunacart.customers.view

Everyone who has bought from this store, with their order count, lifetime revenue and, on a store that keeps customer accounts in its own database, the state of each account. db_identity on the response says whether this store does; when it is false there is no account to manage and invite_customer, clear_customer_2fa and set_customer_state do not apply. Money is in minor units. Lifetime revenue is one currency's: the base currency unless you pass currency, named in currency on the response on a store with orders in more than one. A customer who also ordered in other currencies has other_currencies on their row, one entry each with orders, total_minor and average_order_minor, so a customer with only euro orders reads as euro orders and not as nothing spent.

Parameters

Name Type Description
currency_picker optional string Ask for report_currency_available when the store has several currencies or historical foreign orders; no extra field on a single-currency store
One of: 1
currency optional string A known currency code for native totals, or all for exact totals in base currency using each order's frozen fx_to_base. Unrated orders and refunds are excluded and counted separately. Left out, the base currency. A single-currency store stays unchanged; an unknown code is a 422.
q optional string Substring match on the email, the name or the Grav username
group optional string A customer group id to list only its members, or "none" for customers in no group
account optional string Only customers whose store account is in this state. Ignored when db_identity is false.
One of: active, twofa, invited, disabled, none
sort optional string recent (the default), oldest, name, email, value or orders, or cf:<name> / cf:<name>:desc to order by a custom field declared sortable on the customer. A cf sort or filter answers on its own, without q, group or account. With dir, name, email, orders, value and created sort the whole list either way round before it is paged, a cf filter included; without it the named orderings keep their one direction
dir optional string The direction of a name, email, orders, value or created sort
One of: asc, desc
cf optional object Custom fields to narrow by, name to value, every one required: cf[vat_number]=GB123456789. Only a field declared filterable on this entity; any other name is refused with a 422
page optional integer At least 1.
Default: 1
per_page optional integer At least 1.
Default: 25

Response

Answers {customers, total, page, per_page, db_identity}. Each row carries an account value when the store keeps customer identities in its own database.

Get a customer

GET /api/v1/kahunacart/customers/{id} Permission kahunacart.customers.view

One customer with their lifetime stats (in one currency, with other_currencies beside them for anything they ordered in other currencies), their orders including canceled and refunded ones, their saved address book, the state of their account, and any panels contributed by add-on plugins such as a subscription or a membership. The address book is where they are now; an order's address is where they were at checkout, and the two are kept apart on purpose.

Parameters

Name Type Description
currency_picker optional string Ask for report_currency_available when the store has several currencies or historical foreign orders; no extra field on a single-currency store
One of: 1
currency optional string A known currency code for native totals, or all for exact totals in base currency using each order's frozen fx_to_base. Unrated orders and refunds are excluded and counted separately. Left out, the base currency. A single-currency store stays unchanged; an unknown code is a 422.
id required integer Customer id

Response

Answers {customer, orders, addresses, account, db_identity, panels}, where customer is the row plus its lifetime stats and panels is whatever add-ons contribute on the admin channel.

Send a set-password invitation

POST /api/v1/kahunacart/customers/{id}/invite Permission kahunacart.customers.manage

Open a store account for this customer if there is none yet and queue the set-password email, the same message and the same token machinery the checkout opt-in uses. Sending a second one invalidates the first, which is what anybody clicking resend means by it. Answers 409 on a store that does not keep customer accounts in its own database, and 409 when a Grav user account already holds the address, because that account signs in instead.

Parameters

Name Type Description
id required integer Customer id
POST /api/v1/kahunacart/customers/{id}/magic-link Permission kahunacart.customers.manage

Queue a single-use, short-lived link that signs this customer in, to the address on their record and never to one supplied here. For the buyer who orders twice a year and does not remember a password. The link is minted when the mail leaves rather than when this is called, so a queue running behind never posts a link that has already lapsed, and issuing one invalidates any outstanding link for that customer. Setting a password invalidates every outstanding link too. Answers 409 when sign-in links are switched off, and 422 for an account with no password yet — that customer wants the set-password invitation, which is the step that proves the address.

Parameters

Name Type Description
id required integer Customer id

Clear a customer's two-factor secret

POST /api/v1/kahunacart/customers/{id}/clear-2fa Permission kahunacart.customers.manage

Destroy the authenticator secret on a customer's account, for the case where somebody lost their phone. Nothing is shown and nothing is handed back: this removes a lock rather than reading a key, and the customer enrolls a new device after signing in with their password. Answers 404 when the customer has no account.

Parameters

Name Type Description
id required integer Customer id

Enable or disable a customer account

POST /api/v1/kahunacart/customers/{id}/state Permission kahunacart.customers.manage

Switch a customer's ability to sign in on or off. Disabled is refused at authorization and invalidates an existing session on its next request. Nothing commercial moves: the customer record, the orders, the invoices and the download grants all stay exactly as they were. Answers 404 when the customer has no account.

Parameters

Name Type Description
id required integer Customer id
state required string
One of: enabled, disabled

List a customer's saved addresses

GET /api/v1/kahunacart/customers/{id}/addresses Permission kahunacart.customers.view

A customer's address book, default billing and shipping addresses first. Each row carries the address fields under address, its label, and is_default_billing / is_default_shipping. The same rows get_customer carries, without the rest of the record. This is where they are now; an order's address is where they were at checkout.

Parameters

Name Type Description
id required integer Customer id

Add an address to a customer's book

POST /api/v1/kahunacart/customers/{id}/addresses Permission kahunacart.customers.manage

Save an address for a customer, for example one taken over the phone. Checked exactly as the customer's own account page checks one: at least a street, town, postcode or country, a country that is an ISO 3166-1 code, and a state the country has for the countries that list them (stored as its code). A failure is a 422 saying what is wrong. Set is_default_billing or is_default_shipping to make it the default of that kind, which demotes whichever address held it. Answers with the new row and the whole book.

Parameters

Name Type Description
id required integer Customer id
name optional string The recipient
company optional string
address1 optional string
address2 optional string
city optional string
region optional string State or province; a code or a name for the countries that list them
postcode optional string
country optional string ISO 3166-1 alpha-2 code, e.g. DE; see list_countries
phone optional string
label optional string What the customer calls it, e.g. Home or Office
is_default_billing optional boolean
Default: false
is_default_shipping optional boolean
Default: false

Change a saved address

PATCH /api/v1/kahunacart/customers/{id}/addresses/{addressId} Permission kahunacart.customers.manage

Change one address in a customer's book. Only the keys sent change; a field, the label or a default flag left out keeps what it had, and an empty string clears a field. The whole address is checked again the way create_customer_address checks it. false on a default flag stops this address being that default without promoting another. Answers 404 when the address is not in this customer's book.

Parameters

Name Type Description
id required integer Customer id
addressId required integer Address id, from list_customer_addresses
name optional string The recipient
company optional string
address1 optional string
address2 optional string
city optional string
region optional string State or province; a code or a name for the countries that list them
postcode optional string
country optional string ISO 3166-1 alpha-2 code, e.g. DE; see list_countries
phone optional string
label optional string What the customer calls it, e.g. Home or Office
is_default_billing optional boolean
is_default_shipping optional boolean

Delete a saved address

DELETE /api/v1/kahunacart/customers/{id}/addresses/{addressId} Permission kahunacart.customers.manage

Remove an address from a customer's book. When it was a default, no other address is promoted in its place. Orders already sent there keep their own copy. Answers 404 when the address is not in this customer's book.

Parameters

Name Type Description
id required integer Customer id
addressId required integer Address id

Make an address a customer's default

POST /api/v1/kahunacart/customers/{id}/addresses/{addressId}/default Permission kahunacart.customers.manage

Make one saved address the customer's default billing or shipping address, the one checkout and the admin's New order form start on. Whichever address held that default stops holding it.

Parameters

Name Type Description
id required integer Customer id
addressId required integer Address id
kind required string
One of: billing, shipping

List countries and states

GET /api/v1/kahunacart/countries Permission kahunacart.orders.manage

Every country an address may name, as ISO 3166-1 alpha-2 code and English name, and under regions the states of the countries that publish a list of them, keyed by country code. An address naming a country or a state that is not here is refused by create_order and the customer address tools.

Nothing here ever returns a hash, a secret or a live token; the account object says whether those exist, not what they are. All three account actions answer 409 on a store that is not keeping customer accounts in its database, and invite answers 409 when a Grav user account already holds that email address. state refuses anything but enabled or disabled with a 422.