Add ordercloud provider (#500)

* Add ordercloud provider

* Fix provider errors

* Make submit checkout optional

* Make submit checkout optional

* Remove nullables when creating endpoint type

* Update readme

* Log checkout error

* Log error

* Save token to cookie

* Update fetch rest

* Use token at checkout

Co-authored-by: Luis Alvarez <luis@vercel.com>
This commit is contained in:
Gonzalo Pozzo
2021-10-05 09:49:01 -03:00
committed by GitHub
parent f9644fecef
commit 3f0c38461b
90 changed files with 2560 additions and 76 deletions

View File

@@ -0,0 +1,47 @@
import type { CustomerAddressEndpoint } from '.'
const addItem: CustomerAddressEndpoint['handlers']['addItem'] = async ({
res,
body: { item, cartId },
config: { restBuyerFetch },
}) => {
// 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 restBuyerFetch('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 restBuyerFetch('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,74 @@
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: { restBuyerFetch, restMiddlewareFetch },
}) => {
// 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 restBuyerFetch('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
const payment = await restBuyerFetch(
'POST',
`/orders/All/${cartId}/payments`,
{
Type: 'CreditCard',
CreditCardID: creditCard,
}
).then((response: { ID: string }) => response.ID)
// Accept payment to order
await restMiddlewareFetch(
'PATCH',
`/orders/All/${cartId}/payments/${payment}`,
{
Accepted: true,
}
)
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

View File

@@ -0,0 +1 @@
export default function noopApi(...args: any[]): void {}