Implements custom checkout along with ordercloud provider

This commit is contained in:
goncy
2021-09-14 15:37:17 -03:00
parent a7c13d2d42
commit 30744c5a6c
67 changed files with 1886 additions and 174 deletions

View File

@@ -0,0 +1,35 @@
import type { CheckoutEndpoint } from '.'
const getCheckout: CheckoutEndpoint['handlers']['getCheckout'] = async ({
res,
body: {cartId},
config: { restFetch },
}) => {
// Return an error if no item is present
if (!cartId) {
return res.status(400).json({
data: null,
errors: [{ message: 'Missing cookie' }],
})
}
// Register credit card
const payments = await restFetch('GET', `/orders/Outgoing/${cartId}/payments`).then(
(response: {Items: unknown[]}) => response.Items
)
const address = await restFetch('GET', `/orders/Outgoing/${cartId}`).then(
(response: {ShippingAddressID: string}) => response.ShippingAddressID
)
// Return cart and errors
res.status(200).json({
data: {
hasPayment: payments.length > 0,
hasShipping: Boolean(address)
},
errors: []
})
}
export default getCheckout

View File

@@ -1 +1,23 @@
export default function noopApi(...args: any[]): void {}
import type { CheckoutSchema } from '../../../types/checkout'
import type { OrdercloudAPI } from '../..'
import { GetAPISchema, createEndpoint } from '@commerce/api'
import checkoutEndpoint from '@commerce/api/endpoints/checkout'
import getCheckout from './get-checkout'
import submitCheckout from './submit-checkout'
export type CheckoutAPI = GetAPISchema<OrdercloudAPI, CheckoutSchema>
export type CheckoutEndpoint = CheckoutAPI['endpoint']
export const handlers: CheckoutEndpoint['handlers'] = {
getCheckout,
submitCheckout,
}
const checkoutApi = createEndpoint<CheckoutAPI>({
handler: checkoutEndpoint,
handlers,
})
export default checkoutApi

View File

@@ -0,0 +1,23 @@
import type { CheckoutEndpoint } from '.'
const submitCheckout: CheckoutEndpoint['handlers']['submitCheckout'] = async ({
res,
body: { cartId },
config: { restFetch },
}) => {
// Return an error if no item is present
if (!cartId) {
return res.status(400).json({
data: null,
errors: [{ message: 'Missing item' }],
})
}
// Submit order
await restFetch('POST', `/orders/Outgoing/${cartId}/submit`, {})
// Return cart and errors
res.status(200).json({ data: null, errors: [] })
}
export default submitCheckout

View File

@@ -0,0 +1,49 @@
import type { CustomerAddressEndpoint } from '.'
const addItem: CustomerAddressEndpoint['handlers']['addItem'] = async ({
res,
body: { item, cartId },
config: { restFetch },
}) => {
// Return an error if no item is present
if (!item) {
return res.status(400).json({
data: null,
errors: [{ message: 'Missing item' }],
})
}
// Return an error if no item is present
if (!cartId) {
return res.status(400).json({
data: null,
errors: [{ message: 'Cookie not found' }],
})
}
// Register address
const address = await restFetch('POST', `/me/addresses`, {
"AddressName": "main address",
"CompanyName": item.company,
"FirstName": item.firstName,
"LastName": item.lastName,
"Street1": item.streetNumber,
"Street2": item.streetNumber,
"City": item.city,
"State": item.city,
"Zip": item.zipCode,
"Country": item.country.slice(0, 2).toLowerCase(),
"Shipping": true
}).then(
(response: {ID: string}) => response.ID
)
// Assign address to order
await restFetch('PATCH', `/orders/Outgoing/${cartId}`, {
ShippingAddressID: address
})
return res.status(200).json({ data: null, errors: [] })
}
export default addItem

View File

@@ -0,0 +1,9 @@
import type { CustomerAddressEndpoint } from '.'
const getCards: CustomerAddressEndpoint['handlers']['getAddresses'] = async ({
res,
}) => {
return res.status(200).json({ data: null, errors: [] })
}
export default getCards

View File

@@ -0,0 +1,27 @@
import type { CustomerAddressSchema } from '../../../../types/customer/address'
import type { OrdercloudAPI } from '../../..'
import { GetAPISchema, createEndpoint } from '@commerce/api'
import customerAddressEndpoint from '@commerce/api/endpoints/customer/address'
import getAddresses from './get-addresses'
import addItem from './add-item'
import updateItem from './update-item'
import removeItem from './remove-item'
export type CustomerAddressAPI = GetAPISchema<OrdercloudAPI, CustomerAddressSchema>
export type CustomerAddressEndpoint = CustomerAddressAPI['endpoint']
export const handlers: CustomerAddressEndpoint['handlers'] = {
getAddresses,
addItem,
updateItem,
removeItem,
}
const customerAddressApi = createEndpoint<CustomerAddressAPI>({
handler: customerAddressEndpoint,
handlers,
})
export default customerAddressApi

View File

@@ -0,0 +1,9 @@
import type { CustomerAddressEndpoint } from '.'
const removeItem: CustomerAddressEndpoint['handlers']['removeItem'] = async ({
res,
}) => {
return res.status(200).json({ data: null, errors: [] })
}
export default removeItem

View File

@@ -0,0 +1,9 @@
import type { CustomerAddressEndpoint } from '.'
const updateItem: CustomerAddressEndpoint['handlers']['updateItem'] = async ({
res,
}) => {
return res.status(200).json({ data: null, errors: [] })
}
export default updateItem

View File

@@ -0,0 +1,61 @@
import type { CustomerCardEndpoint } from '.'
import type { OredercloudCreditCard } from '../../../../types/customer/card'
import Stripe from "stripe"
const stripe = new Stripe(process.env.STRIPE_SECRET as string, {
apiVersion: "2020-08-27"
})
const addItem: CustomerCardEndpoint['handlers']['addItem'] = async ({
res,
body: { item, cartId },
config: { restFetch },
}) => {
// Return an error if no item is present
if (!item) {
return res.status(400).json({
data: null,
errors: [{ message: 'Missing item' }],
})
}
// Return an error if no item is present
if (!cartId) {
return res.status(400).json({
data: null,
errors: [{ message: 'Cookie not found' }],
})
}
// Get token
const token = await stripe.tokens.create({
card: {
number: item.cardNumber,
exp_month: item.cardExpireDate.split('/')[0],
exp_year: item.cardExpireDate.split('/')[1],
cvc: item.cardCvc
}
}).then((res: {id: string}) => res.id)
// Register credit card
const creditCard = await restFetch('POST', `/me/creditcards`, {
"Token": token,
"CardType": "credit",
"PartialAccountNumber": item.cardNumber.slice(-4),
"CardholderName": item.cardHolder,
"ExpirationDate": item.cardExpireDate
}).then(
(response: OredercloudCreditCard) => response.ID
)
// Assign payment to order
await restFetch('POST', `/orders/Outgoing/${cartId}/payments`, {
"Type": "CreditCard",
CreditCardID: creditCard
})
return res.status(200).json({ data: null, errors: [] })
}
export default addItem

View File

@@ -0,0 +1,9 @@
import type { CustomerCardEndpoint } from '.'
const getCards: CustomerCardEndpoint['handlers']['getCards'] = async ({
res,
}) => {
return res.status(200).json({ data: null, errors: [] })
}
export default getCards

View File

@@ -0,0 +1,27 @@
import type { CustomerCardSchema } from '../../../../types/customer/card'
import type { OrdercloudAPI } from '../../..'
import { GetAPISchema, createEndpoint } from '@commerce/api'
import customerCardEndpoint from '@commerce/api/endpoints/customer/card'
import getCards from './get-cards'
import addItem from './add-item'
import updateItem from './update-item'
import removeItem from './remove-item'
export type CustomerCardAPI = GetAPISchema<OrdercloudAPI, CustomerCardSchema>
export type CustomerCardEndpoint = CustomerCardAPI['endpoint']
export const handlers: CustomerCardEndpoint['handlers'] = {
getCards,
addItem,
updateItem,
removeItem,
}
const customerCardApi = createEndpoint<CustomerCardAPI>({
handler: customerCardEndpoint,
handlers,
})
export default customerCardApi

View File

@@ -0,0 +1,9 @@
import type { CustomerCardEndpoint } from '.'
const removeItem: CustomerCardEndpoint['handlers']['removeItem'] = async ({
res,
}) => {
return res.status(200).json({ data: null, errors: [] })
}
export default removeItem

View File

@@ -0,0 +1,9 @@
import type { CustomerCardEndpoint } from '.'
const updateItem: CustomerCardEndpoint['handlers']['updateItem'] = async ({
res,
}) => {
return res.status(200).json({ data: null, errors: [] })
}
export default updateItem