Files
medusa-store/docs/content/modules/customers/storefront/implement-customer-profiles.mdx
Shahed Nasser 6f1b49af03 chore: merge docs from master to develop (#3650)
* Fix issue on fixed total amount discount when using includes tax (#3472)

The calculation of the fixed discount amount breaks when having includes_tax setting active, due to the line item totals are incorrect and returning everything as 0, thus the totalItemPercentage will be Infinitiy due to the division by a subtotal of 0

* chore: Add missing changeset for @medusajs/medusa

* feat(medusa): Improve performance of Products domain (#3417)

* feat(medusa): Improve product update performances

* fix tests and update

* update mock repo

* improve repo

* cleanup

* fix

* cleanup + bulk emit + unit test fix

* improvements

* improve

* fix unit tests

* fix export

* fix product update handler

* enhance mock repo

* fix import integration

* fix end point tests

* revert mock repo product variant

* fix unit

* cleanup

* cleanup

* address feedback

* fix quotes in tests

* address feedback

* Create new-tips-mate.md

* use types

* chore: Remove integration-tests from changeset

* chore(release): v1.7.14

* chore(docs): Generated Docs Announcement Bar (automated) (#3489)

Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com>

* fix(medusa): EventBusService.emit using Redis mock (#3491)

* Fix eventBusService.emit using redis mock

* revert gitignore

* enqueuer

* unit test add redis_url

* fix test

* chore(docs): Generated Services Reference (automated) (#3490)

Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com>

* docs: publish restructure (#3496)

* docs: added features and guides overview page

* added image

* added version 2

* added version 3

* added version 4

* docs: implemented new color scheme

* docs: redesigned sidebar (#3193)

* docs: redesigned navbar for restructure (#3199)

* docs: redesigned footer (#3209)

* docs: redesigned cards (#3230)

* docs: redesigned admonitions (#3231)

* docs: redesign announcement bar (#3236)

* docs: redesigned large cards (#3239)

* docs: redesigned code blocks (#3253)

* docs: redesigned search modal and page (#3264)

* docs: redesigned doc footer (#3268)

* docs: added new sidebars + refactored css and assets (#3279)

* docs: redesigned api reference sidebar

* docs: refactored css

* docs: added code tabs transition

* docs: added new sidebars

* removed unused assets

* remove unusued assets

* Fix deploy errors

* fix incorrect link

* docs: fixed code responsivity + missing icons (#3283)

* docs: changed icons (#3296)

* docs: design fixes to the sidebar (#3297)

* redesign fixes

* docs: small design fixes

* docs: several design fixes after restructure (#3299)

* docs: bordered icon fixes

* docs: desgin fixes

* fixes to code blocks and sidebar scroll

* design adjustments

* docs: restructured homepage (#3305)

* docs: restructured homepage

* design fixes

* fixed core concepts icon

* docs: added core concepts page (#3318)

* docs: restructured homepage

* design fixes

* docs: added core concepts page

* changed text of different components

* docs: added architecture link

* added missing prop for user guide

* docs: added regions overview page (#3327)

* docs: added regions overview

* moved region pages to new structure

* docs: fixed description of regions architecture page

* small changes

* small fix

* docs: added customers overview page (#3331)

* docs: added regions overview

* moved region pages to new structure

* docs: fixed description of regions architecture page

* small changes

* small fix

* docs: added customers overview page

* fix link

* resolve link issues

* docs: updated regions architecture image

* docs: second-iteration fixes (#3347)

* docs: redesigned document

* design fixes

* docs: added products overview page (#3354)

* docs: added carts overview page (#3363)

* docs: added orders overview (#3364)

* docs: added orders overview

* added links in overview

* docs: added vercel redirects

* docs: added soon badge for cards (#3389)

* docs: resolved feedback changes + organized troubleshooting pages (#3409)

* docs: resolved feedback changes

* added extra line

* docs: changed icons for restructure (#3421)

* docs: added taxes overview page (#3422)

* docs: added taxes overview page

* docs: fix sidebar label

* added link to taxes overview page

* fixed link

* docs: fixed sidebar scroll (#3429)

* docs: added discounts overview (#3432)

* docs: added discounts overview

* fixed links

* docs: added gift cards overview (#3433)

* docs: added price lists overview page (#3440)

* docs: added price lists overview page

* fixed links

* docs: added sales channels overview page (#3441)

* docs: added sales overview page

* fixed links

* docs: added users overview (#3443)

* docs: fixed sidebar border height (#3444)

* docs: fixed sidebar border height

* fixed svg markup

* docs: added possible solutions to feedback component (#3449)

* docs: added several overview pages + restructured files (#3463)

* docs: added several overview pages

* fixed links

* docs: added feature flags + PAK overview pages (#3464)

* docs: added feature flags + PAK overview pages

* fixed links

* fix link

* fix link

* fixed links colors

* docs: added strategies overview page (#3468)

* docs: automated upgrade guide (#3470)

* docs: automated upgrade guide

* fixed vercel redirect

* docs: restructured files in docs codebase (#3475)

* docs: restructured files

* docs: fixed eslint exception

* docs: finished restructure loose-ends (#3493)

* fixed uses of backend

* docs: finished loose ends

* eslint fixes

* fixed links

* merged master

* added update instructions for v1.7.12

* docs: fixed discount details (#3499)

* docs: fix trailing slash causing 404 (#3508)

* docs: fix error during navigation (#3509)

* docs: removed the gatsby storefront guide (#3527)

* docs: removed the gatsby storefront guide

* docs: fixed query value

* chore(docs): Removed Docs Announcement Bar (automated) (#3536)

Co-authored-by: shahednasser <shahednasser@users.noreply.github.com>

* fix(medusa): Variant update should include the id for the listeners to be able to identify the entity (#3539)

* fix(medusa): Variant update should include the id for the listeners to be able to identify the entity

* fix unit tests

* Create brave-seahorses-film.md

* docs: fix admin redirects (#3548)

* chore(release): v1.7.15

* chore(docs): Generated Docs Announcement Bar (automated) (#3550)

Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com>

* chore(docs): Generated Services Reference (automated) (#3551)

Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* chore: updated READMEs of plugins (#3546)

* chore: updated READMEs of plugins

* added notice to plugins

* docs: added a deploy guide for next.js storefront (#3558)

* docs: added a deploy next.js guide

* docs: fix image zoom

* docs: fixes to next.js deployment guide to vercel (#3562)

* chore(workflows): Enable manual workflow in pre-release mode (#3566)

* chore(docs): Removed Docs Announcement Bar (automated) (#3598)

Co-authored-by: shahednasser <shahednasser@users.noreply.github.com>

* fix(medusa): Rounding issues on line item adjustments (#3446)

* chores(medusa): Attempt to fix discount rounding issues

* add migration

* update entities

* apply multipler factor properly

* fix discount service

* WIP

* fix rounding issues in discounts

* fix some tests

* Exclude raw_discount_total from responses

* fix adjustments

* cleanup response

* fix

* fix draft order integration

* fix order integration

* fix order integration

* address feedback

* fix test

* Create .changeset/polite-llamas-sit.md

* remove comment

---------

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* chore(workflows): Add release notification (#3629)

---------

Co-authored-by: pepijn-vanvlaanderen <pepijn@webbers.com>
Co-authored-by: olivermrbl <oliver@mrbltech.com>
Co-authored-by: Adrien de Peretti <adrien.deperetti@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com>
Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
Co-authored-by: shahednasser <shahednasser@users.noreply.github.com>
Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
2023-03-31 09:34:38 +02:00

668 lines
17 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description: 'Learn how to implement customer account functionalities in your storefront using the REST APIs. This includes implementing customer registration, login, edit profile, and more.'
addHowToData: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# How to Implement Customer Profiles
In this document, youll learn how to implement customer account functionalities in a storefront.
## Overview
Medusa provides the necessary functionalities and endpoints to allow integrating essential customer features. Customers can create accounts to manage their information and keep track of their orders.
### Scenario
You want to implement the following features in a storefront:
- Customer registration
- Customer login and logout
- Allow customers to reset their password
- Allow customers to manage their basic information and shipping addresses
- Show customers their orders
:::note
You can use Medusas Store APIs to achieve more functionalities as well. Check out the [API reference](/api/store/#tag/Customer) to learn more.
:::
---
## Prerequisites
### Medusa Components
It's assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../../development/backend/install.mdx) to get started.
It's also assumed you already have a storefront set up. It can be a custom storefront or one of Medusas storefronts. If you dont have a storefront set up, you can install the [Next.js starter storefront](../../../starters/nextjs-medusa-starter.mdx).
### JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusas JS Client, among other methods.
If you follow the JS Client code blocks, its assumed you already have [Medusas JS Client installed](../../../js-client/overview.md) and have [created an instance of the client](../../../js-client/overview.md#configuration).
### Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
---
## Register a Customer
A customer can register with an email and a password to store and manage their data.
You can register a new customer by sending a request to the [Create a Customer](/api/store/#tag/Customer/operation/PostCustomers) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.create({
email,
password,
first_name,
last_name,
})
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCreateCustomer } from "medusa-react"
const RegisterCustomer = () => {
const createCustomer = useCreateCustomer()
// ...
const handleCreate = () => {
// ...
createCustomer.mutate({
first_name,
last_name,
email,
password,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default RegisterCustomer
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
password,
first_name,
last_name,
}),
})
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request requires the following body parameters:
- `email`: An email used to log in after registration. This email must be unique. You can check if an email is unique using the “[Check if email exists](/api/store/#tag/Auth/operation/GetAuthEmail)” endpoint.
- `password`: A password used to log in after registration.
- `first_name`: The customers first name.
- `last_name`: The customers last name.
This request also accepts optional body parameters, which you can check out in the [API reference](/api/store/#tag/Customer/operation/PostCustomers).
It returns the created customer object in the response.
---
## Log in a Customer
A customer can log in to your store to manage their data and make purchases using their account.
You can log in a customer into your store by sending a request to the [Customer Login](/api/store/#tag/Auth/operation/PostAuth) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.auth.authenticate({
email,
password,
})
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/auth`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
password,
}),
})
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request requires the body parameters `email` and `password`. It returns the customer object in the response.
If youre using the Medusa JS Client, the customers session will already be set and used in all future requests.
However, if youre using the Fetch API, you must include the option `credentials` with the value `include` to make sure all future requests are authenticated.
---
## Log out a Customer
You can log out a customer by sending a request to the [Customer Logout](/api/store/#tag/Auth/operation/DeleteAuth) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.auth.deleteSession()
.then(() => {
// success
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/auth`, {
method: "DELETE",
credentials: "include",
})
.then(() => {
// success
})
```
</TabItem>
</Tabs>
If this request is successful, the customers session will be deleted and theyll be logged out.
---
## Reset Password
Customers might need to reset their password in case they forget it. To reset a customers password, you need to implement two steps.
### Step 1: Request Password Reset
The customer must first enter their accounts email. Then, if an account with that email address exists, an email will be sent to that email address with a link that points the customer to step 2.
You can request to reset a customers password by sending a request to the [Request Password Reset](/api/store/#tag/Customer/operation/PostCustomersCustomerPasswordToken) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.generatePasswordToken({
email,
})
.then(() => {
// successful
})
.catch(() => {
// failed
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/password-token`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
}),
})
.then(() => {
// successful
})
.catch(() => {
// failed
})
```
</TabItem>
</Tabs>
This request requires the body parameter `email`. Its value must be the email associated with the customers account.
If the request has been processed successfully, it returns a `204` status code in the response. In case it fails, an error will be thrown.
:::note
If the customer doesnt receive an email after this request, make sure that youve set up a Notification provider like [SendGrid](../../../plugins/notifications/sendgrid.mdx) successfully. You also need to add a subscriber that handles the [customer.password_reset](../../../development/events/events-list.md#customer-events) event and sends the email.
:::
### Step 2: Verify and Reset Password
After the first step, the customer should receive an email with a link to a page in the storefront. This page should accept a `token` query parameter. Then, the customer should be prompted to enter their email and password.
You can then reset the customers password to the new password they enter by sending a request to the [Reset Password](/api/store/#tag/Customer/operation/PostCustomersResetPassword) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.resetPassword({
email,
password,
token,
})
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/password-reset`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
password,
token,
}),
})
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request requires the following body parameters:
- `email`: The email of the customer. This must be the email associated with the account.
- `password`: The new password the customer wants to use for their account.
- `token`: The token passed as a query into the page.
If successful, this request returns the customer object in the response.
---
## Edit a Customers Info
A logged-in customer can edit their info, such as their first name or email address.
You can edit a customers info using the [Update Customer](/api/store/#tag/Customer/operation/PostCustomersCustomer) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.update({
first_name,
})
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useUpdateMe } from "medusa-react"
const UpdateCustomer = () => {
const updateCustomer = useUpdateMe()
// ...
const handleUpdate = () => {
// ...
updateCustomer.mutate({
id: customer_id,
first_name,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default UpdateCustomer
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/me`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
first_name,
}),
})
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request accepts any of the customers details that should be updated as body parameters. In the example above, the `first_name` of the customer is updated. You can check out the [API reference](/api/store/#tag/Customer/operation/PostCustomersCustomer) for a full list of accepted body parameters.
It returns in the response the updated customer object.
---
## Manage Shipping Addresses
A logged-in customer uses their shipping addresses during the checkout process. They can have more than one shipping address, and they can choose one of them when placing an order.
:::tip
The customer object returned in the requests mentioned in this document include a `shipping_addresses` property. Its an array of the customers shipping addresses. You can access it to display the customers shipping addresses.
:::
### Add a Shipping Address
You can add a shipping address to a customers account by sending a request to the [Add a Shipping Address](/api/store/#tag/Customer/operation/PostCustomersCustomerAddresses) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.addresses.addAddress({
address: {
first_name,
last_name,
address_1,
city,
country_code,
postal_code,
phone,
company,
address_2,
province,
metadata,
},
})
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/me/addresses`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
address: {
first_name,
last_name,
address_1,
city,
country_code,
postal_code,
phone,
company,
address_2,
province,
metadata,
},
}),
})
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request requires an `address` object as a body parameter. The `address` object must have the following properties:
- `first_name`: The first name associated with the shipping address
- `last_name`: The last name associated with the shipping address
- `address_1`: The first address line of the shipping address.
- `city`: The city of the shipping address.
- `country_code`: The 2 character ISO code of the country in lower case.
- `postal_code`: The postal code of the shipping address
It also accepts other optional body parameters, which you can learn more about in the [API reference](/api/store/#tag/Customer/operation/PostCustomersCustomerAddresses).
This request returns the updated customer object in the response.
### Edit a Shipping Address
You can edit a customers shipping address using the [Update a Shipping Address](/api/store/#tag/Customer/operation/PostCustomersCustomerAddressesAddress) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.addresses.updateAddress(addressId, {
first_name,
})
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/me/addresses/${addressId}`,
{
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
first_name,
}),
}
)
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request requires the addresss ID as a path parameter. It accepts as a body parameter any of the addresss properties. In the example above, the `first_name` of the shipping address is updated. You can check the [API reference](/api/store/#tag/Customer/operation/PostCustomersCustomerAddressesAddress) for all the available body parameters.
This request returns the updated customer object in the response.
### Delete a Shipping Address
You can delete a shipping address by sending a request to the [Delete an Address](/api/store/#tag/Customer/operation/DeleteCustomersCustomerAddressesAddress) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.addresses.deleteAddress(addressId)
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/me/addresses/${addressId}`,
{
method: "DELETE",
credentials: "include",
}
)
.then((response) => response.json())
.then(({ customer }) => {
console.log(customer.id)
})
```
</TabItem>
</Tabs>
This request requires the addresss ID as a path parameter. It returns in the response the updated customer object.
---
## Retrieve a Customers Orders
Logged-in customers can see their orders along with the orders details.
You can retrieve a customers orders by sending a request to the [List Orders](/api/store/#tag/Customer/operation/GetCustomersCustomerOrders) endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.customers.listOrders()
.then(({ orders, limit, offset, count }) => {
console.log(orders)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCustomerOrders } from "medusa-react"
import { Order } from "@medusajs/medusa"
const Orders = () => {
// refetch a function that can be used to
// re-retrieve orders after the customer logs in
const { orders, isLoading, refetch } = useCustomerOrders()
return (
<div>
{isLoading && <span>Loading orders...</span>}
{orders?.length && (
<ul>
{orders.map((order: Order) => (
<li key={order.id}>{order.display_id}</li>
))}
</ul>
)}
</div>
)
}
export default Orders
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/customers/me/orders`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ orders, limit, offset, count }) => {
console.log(orders)
})
```
</TabItem>
</Tabs>
This request doesnt require any path or query parameters. You can, however, send optional query parameters used for filters, pagination, and sorting. You can learn more in the [API reference](/api/store/#tag/Customer/operation/GetCustomersCustomerOrders).
It returns the following data in the response:
- `orders`: An array of orders.
- `limit`: The maximum number of orders that can be returned in the request.
- `offset`: The number of orders skipped in the result.
- `count`: The total number of orders available.
:::info
You can learn more about pagination in the [API reference](/api/store/#section/Pagination).
:::