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
/api/v1/kahunacart/customers
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
/api/v1/kahunacart/customers/{id}
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
/api/v1/kahunacart/customers/{id}/invite
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 |
Email a customer a sign-in link
/api/v1/kahunacart/customers/{id}/magic-link
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
/api/v1/kahunacart/customers/{id}/clear-2fa
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
/api/v1/kahunacart/customers/{id}/state
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
/api/v1/kahunacart/customers/{id}/addresses
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
/api/v1/kahunacart/customers/{id}/addresses
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
/api/v1/kahunacart/customers/{id}/addresses/{addressId}
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
/api/v1/kahunacart/customers/{id}/addresses/{addressId}
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
/api/v1/kahunacart/customers/{id}/addresses/{addressId}/default
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
/api/v1/kahunacart/countries
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.