Skip to content

Commit

Permalink
Merge pull request #15 from AndreaDiotallevi/staging
Browse files Browse the repository at this point in the history
feat: create order with theprintspace
  • Loading branch information
AndreaDiotallevi authored Aug 23, 2024
2 parents 0d5f3af + 592a95b commit f684a18
Show file tree
Hide file tree
Showing 6 changed files with 377 additions and 68 deletions.
21 changes: 18 additions & 3 deletions gatsby/src/pages/shop/checkout/success.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ const Success = ({
fetchSession()
}, [sessionId])

type Currency = "eur" | "gbp" | "usd"

const currencyToSymbol: Record<string, string> = {
eur: "€",
gbp: "£",
usd: "$",
chf: "₣", // Switzerland
nok: "kr", // Norway
dkk: "kr", // Denmark
sek: "kr", // Sweden
}

const currencySymbol =
currencyToSymbol[(session?.currency as Currency) || "gbp"]

return (
<Layout loading={session === null}>
{session ? (
Expand Down Expand Up @@ -111,19 +126,19 @@ const Success = ({
))}
<h2>Payment summary</h2>
<p>
Subtotal: £
Subtotal: {currencySymbol}
{((session.amount_subtotal || 0) / 100).toFixed(
2,
)}
<br></br>
Shipping fee: Free<br></br>
Discounts: £
Discounts: {currencySymbol}
{(
(session.total_details?.amount_discount ||
0) / 100
).toFixed(2)}
<br></br>
Total: £
Total: {currencySymbol}
{((session.amount_total || 0) / 100).toFixed(2)}
</p>
<Button
Expand Down
35 changes: 35 additions & 0 deletions serverless/src/handlers/theprintspaceCreateOrder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { SQSEvent } from "aws-lambda"
import Stripe from "stripe"

import {
createConfirmedOrder,
createEmbryonicOrder,
} from "../services/theprintspace"
import { retrieveCheckoutSession } from "../services/stripe"

export const handler = async (event: SQSEvent): Promise<void> => {
try {
for (const record of event.Records) {
const body = JSON.parse(record.body)
const event = body.detail as Stripe.CheckoutSessionCompletedEvent
const sessionId = event.data.object.id
const { session } = await retrieveCheckoutSession({ sessionId })

console.log(JSON.stringify(session))

if (process.env.ENVIRONMENT !== "production") {
// Required until Creativehub updates the SSL certificate for the sandbox API environment (which has expired)
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
}

const { orderId, deliveryOptions } = await createEmbryonicOrder({
session,
})

await createConfirmedOrder({ orderId, deliveryOptions })
}
} catch (error) {
console.error(error)
throw error
}
}
1 change: 1 addition & 0 deletions serverless/src/handlers/theprintspaceHandleWebhooks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const handler = async (event: unknown) => {
console.log(event)
console.log(JSON.stringify(event))
}
165 changes: 100 additions & 65 deletions serverless/src/services/theprintspace.ts
Original file line number Diff line number Diff line change
@@ -1,94 +1,129 @@
import Stripe from "stripe"

import { getParameterValue } from "./ssm"

import {
getCountryIdFromCountryCode,
getCountryNameFromCountryCode,
} from "../data/theprintspace"

import {
CreateConfirmedOrderResponse,
CreateEmbryonicOrderResponse,
} from "../types/theprintspace"

export const createEmbryonicOrder = async ({
session,
}: {
session: Stripe.Checkout.Session
}) => {
try {
const { shipping_details, customer_details, line_items, id } = session
const { shipping_details, customer_details, line_items, id } = session

if (!shipping_details?.address) {
throw new Error("No shipping details")
}
if (!shipping_details.address.country) {
throw new Error("No shipping address country")
}
if (!customer_details) {
throw new Error("No customer details")
}
if (!line_items) {
throw new Error("No line items")
}

const creativehubApiKey = await getParameterValue<string>({
name: "CREATIVEHUB_API_KEY",
withDecryption: true,
})
const creativehubApiKey = await getParameterValue<string>({
name: "CREATIVEHUB_API_KEY",
withDecryption: true,
})

if (!creativehubApiKey) {
throw new Error("No Creativehub API key")
}
if (!creativehubApiKey) {
throw new Error("No Creativehub API key")
}

const url = `${process.env.CREATIVEHUB_API_URL}/api/v1/orders/embryonic`

const requestBody = {
ExternalReference: "",
FirstName: customer_details.name,
LastName: "",
Email: customer_details.email,
MessageToLab: "",
ShippingAddress: {
FirstName: customer_details.name,
LastName: "",
Line1: shipping_details.address.line1,
Line2: shipping_details.address.line2,
Town: shipping_details.address.city,
County: shipping_details.address.state,
PostCode: shipping_details.address.postal_code,
CountryId: getCountryIdFromCountryCode(
shipping_details.address.country
),
CountryCode: shipping_details.address.country,
CountryName: getCountryNameFromCountryCode(
shipping_details.address.country
),
PhoneNumber: null,
const response = await fetch(
`${process.env.CREATIVEHUB_API_URL}/api/v1/orders/embryonic`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `ApiKey ${creativehubApiKey}`,
},
OrderItems: line_items.data.map(item => ({
ProductId: 36026,
PrintOptionId: 4175,
Quantity: item.quantity,
ExternalReference: item.price?.product.metadata.sku,
ExternalSku: "",
})),
body: JSON.stringify({
ExternalReference: id,
FirstName: customer_details?.name,
LastName: "TEST",
Email: customer_details?.email,
MessageToLab: null,
ShippingAddress: {
FirstName: customer_details?.name,
LastName: "TEST",
Line1: shipping_details?.address?.line1,
Line2: shipping_details?.address?.line2,
Town: shipping_details?.address?.city,
County: shipping_details?.address?.state,
PostCode: shipping_details?.address?.postal_code,
CountryId: getCountryIdFromCountryCode(
shipping_details?.address?.country || ""
),
CountryCode: shipping_details?.address?.country,
CountryName: getCountryNameFromCountryCode(
shipping_details?.address?.country || ""
),
PhoneNumber: null,
},
OrderItems: line_items?.data.map(item => ({
ProductId: 36026,
PrintOptionId: 4175,
Quantity: item.quantity,
ExternalReference: item.price?.product.metadata.sku,
ExternalSku: "",
})),
}),
}
)

console.log(JSON.stringify(requestBody))
const data = (await response.json()) as CreateEmbryonicOrderResponse
console.log("CreateEmbryonicOrderResponse: ", JSON.stringify(data))

if (!response.ok) {
console.error(response)
throw new Error("Failed to create order with theprintspace")
}

const options = {
return { orderId: data.Id, deliveryOptions: data.DeliveryOptions }
}

export const createConfirmedOrder = async ({
orderId,
deliveryOptions,
}: {
orderId: number
deliveryOptions: CreateEmbryonicOrderResponse["DeliveryOptions"]
}) => {
const creativehubApiKey = await getParameterValue<string>({
name: "CREATIVEHUB_API_KEY",
withDecryption: true,
})

if (!creativehubApiKey) {
throw new Error("No Creativehub API key")
}

const deliveryOption = deliveryOptions.reduce((min, option) =>
option.DeliveryChargeExcludingSalesTax <
min.DeliveryChargeExcludingSalesTax
? option
: min
)

const response = await fetch(
`${process.env.CREATIVEHUB_API_URL}/api/v1/orders/confirmed`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `ApiKey ${creativehubApiKey}`,
},
body: JSON.stringify(requestBody),
body: JSON.stringify({
OrderId: orderId,
DeliveryOptionId: deliveryOption.Id,
}),
}
)

const response = await fetch(url, options)
const data = (await response.json()) as CreateConfirmedOrderResponse
console.log("CreateConfirmedOrderResponse: ", JSON.stringify(data))

if (!response.ok) {
console.error(response.body)
console.log(response.status, response.statusText)
throw new Error("Failed to create order with theprintspace")
}
} catch (error) {
console.error(error)
throw error
if (!response.ok) {
console.error(response)
throw new Error("Failed to create order with theprintspace")
}
}
Loading

0 comments on commit f684a18

Please sign in to comment.