diff --git a/framework/bigcommerce/api/index.ts b/framework/bigcommerce/api/index.ts
index 609ffcfca..90e04a6a4 100644
--- a/framework/bigcommerce/api/index.ts
+++ b/framework/bigcommerce/api/index.ts
@@ -13,6 +13,7 @@ import type { CartAPI } from './cart'
import type { CustomerAPI } from './customer'
import type { LoginAPI } from './login'
import type { LogoutAPI } from './logout'
+import type { SignupAPI } from './signup'
import login from './operations/login'
export interface BigcommerceConfig extends CommerceAPIConfig {
@@ -114,7 +115,7 @@ export const provider = {
export type Provider = typeof provider
-export type APIs = CartAPI | CustomerAPI | LoginAPI | LogoutAPI
+export type APIs = CartAPI | CustomerAPI | LoginAPI | LogoutAPI | SignupAPI
export type BigcommerceAPI
= CommerceAPI
diff --git a/framework/bigcommerce/api/signup/index.ts b/framework/bigcommerce/api/signup/index.ts
new file mode 100644
index 000000000..9e656990e
--- /dev/null
+++ b/framework/bigcommerce/api/signup/index.ts
@@ -0,0 +1,10 @@
+import type { GetAPISchema } from '@commerce/api'
+import type { SignupSchema } from '../../types/signup'
+import type { BigcommerceAPI } from '..'
+import signup from './signup'
+
+export type SignupAPI = GetAPISchema
+
+export type SignupEndpoint = SignupAPI['endpoint']
+
+export const operations = { signup }
diff --git a/framework/bigcommerce/api/signup/signup.ts b/framework/bigcommerce/api/signup/signup.ts
new file mode 100644
index 000000000..df4f6ec57
--- /dev/null
+++ b/framework/bigcommerce/api/signup/signup.ts
@@ -0,0 +1,62 @@
+import { BigcommerceApiError } from '../utils/errors'
+import type { SignupEndpoint } from '.'
+
+const signup: SignupEndpoint['operations']['signup'] = async ({
+ res,
+ body: { firstName, lastName, email, password },
+ config,
+ commerce,
+}) => {
+ // TODO: Add proper validations with something like Ajv
+ if (!(firstName && lastName && email && password)) {
+ return res.status(400).json({
+ data: null,
+ errors: [{ message: 'Invalid request' }],
+ })
+ }
+ // TODO: validate the password and email
+ // Passwords must be at least 7 characters and contain both alphabetic
+ // and numeric characters.
+
+ try {
+ await config.storeApiFetch('/v3/customers', {
+ method: 'POST',
+ body: JSON.stringify([
+ {
+ first_name: firstName,
+ last_name: lastName,
+ email,
+ authentication: {
+ new_password: password,
+ },
+ },
+ ]),
+ })
+ } catch (error) {
+ if (error instanceof BigcommerceApiError && error.status === 422) {
+ const hasEmailError = '0.email' in error.data?.errors
+
+ // If there's an error with the email, it most likely means it's duplicated
+ if (hasEmailError) {
+ return res.status(400).json({
+ data: null,
+ errors: [
+ {
+ message: 'The email is already in use',
+ code: 'duplicated_email',
+ },
+ ],
+ })
+ }
+ }
+
+ throw error
+ }
+
+ // Login the customer right after creating it
+ await commerce.login({ variables: { email, password }, res, config })
+
+ res.status(200).json({ data: null })
+}
+
+export default signup
diff --git a/framework/bigcommerce/types/signup.ts b/framework/bigcommerce/types/signup.ts
new file mode 100644
index 000000000..58543c6f6
--- /dev/null
+++ b/framework/bigcommerce/types/signup.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/signup'
diff --git a/framework/commerce/api/endpoints/signup.ts b/framework/commerce/api/endpoints/signup.ts
new file mode 100644
index 000000000..d18542289
--- /dev/null
+++ b/framework/commerce/api/endpoints/signup.ts
@@ -0,0 +1,38 @@
+import type { SignupSchema } from '../../types/signup'
+import { CommerceAPIError } from '../utils/errors'
+import isAllowedOperation from '../utils/is-allowed-operation'
+import type { GetAPISchema } from '..'
+
+const signupEndpoint: GetAPISchema<
+ any,
+ SignupSchema
+>['endpoint']['handler'] = async (ctx) => {
+ const { req, res, operations, config } = ctx
+
+ if (
+ !isAllowedOperation(req, res, {
+ POST: operations['signup'],
+ })
+ ) {
+ return
+ }
+
+ const { cookies } = req
+ const cartId = cookies[config.cartCookie]
+
+ try {
+ const body = { ...req.body, cartId }
+ return await operations['signup']({ ...ctx, body })
+ } catch (error) {
+ console.error(error)
+
+ const message =
+ error instanceof CommerceAPIError
+ ? 'An unexpected error ocurred with the Commerce API'
+ : 'An unexpected error ocurred'
+
+ res.status(500).json({ data: null, errors: [{ message }] })
+ }
+}
+
+export default signupEndpoint
diff --git a/framework/commerce/api/index.ts b/framework/commerce/api/index.ts
index f55bf9ce2..3d1521fbd 100644
--- a/framework/commerce/api/index.ts
+++ b/framework/commerce/api/index.ts
@@ -5,6 +5,7 @@ import type { CartSchema } from '../types/cart'
import type { CustomerSchema } from '../types/customer'
import type { LoginSchema } from '../types/login'
import type { LogoutSchema } from '../types/logout'
+import type { SignupSchema } from '../types/signup'
import {
defaultOperations,
OPERATIONS,
@@ -17,6 +18,7 @@ export type APISchemas =
| CustomerSchema
| LoginSchema
| LogoutSchema
+ | SignupSchema
export type GetAPISchema<
C extends CommerceAPI,
diff --git a/framework/commerce/types/signup.ts b/framework/commerce/types/signup.ts
new file mode 100644
index 000000000..ae25da0f0
--- /dev/null
+++ b/framework/commerce/types/signup.ts
@@ -0,0 +1,22 @@
+export type SignupBody = {
+ firstName: string
+ lastName: string
+ email: string
+ password: string
+}
+
+export type SignupTypes = {
+ body: SignupBody
+}
+
+export type SignupSchema = {
+ endpoint: {
+ options: {}
+ operations: {
+ signup: {
+ data: null
+ body: T['body']
+ }
+ }
+ }
+}
diff --git a/pages/api/signup.ts b/pages/api/signup.ts
new file mode 100644
index 000000000..bc24f407a
--- /dev/null
+++ b/pages/api/signup.ts
@@ -0,0 +1,8 @@
+import signup from '@commerce/api/endpoints/signup'
+import { SignupAPI, operations } from '@framework/api/signup'
+import commerce from '@lib/api/commerce'
+
+export default commerce.endpoint({
+ handler: signup as SignupAPI['endpoint']['handler'],
+ operations,
+})