Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
silenaker committed Aug 28, 2024
1 parent 781ca23 commit 211429c
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from "./create-line-item-adjustments"
export * from "./create-line-items"
export * from "./create-order-from-cart"
export * from "./create-shipping-method-adjustments"
export * from "./create-payment-collection"
export * from "./find-one-or-any-region"
export * from "./find-or-create-customer"
export * from "./find-sales-channel"
Expand Down
22 changes: 15 additions & 7 deletions packages/core/core-flows/src/order/utils/aggregate-status.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { OrderDetailDTO } from "@medusajs/types"
import { FulfillmentDTO, PaymentCollectionDTO } from "@medusajs/types"
import { MathBN } from "@medusajs/utils"

export const getLastPaymentStatus = (order: OrderDetailDTO) => {
export const getLastPaymentStatus = ({
payment_collections,
}: {
payment_collections: PaymentCollectionDTO[]
}) => {
const PaymentStatus = {
NOT_PAID: "not_paid",
AWAITING: "awaiting",
Expand All @@ -20,7 +24,7 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
paymentStatus[PaymentStatus[status]] = 0
}

for (const paymentCollection of order.payment_collections) {
for (const paymentCollection of payment_collections) {
if (MathBN.gt(paymentCollection.captured_amount ?? 0, 0)) {
paymentStatus[PaymentStatus.CAPTURED] += MathBN.eq(
paymentCollection.captured_amount as number,
Expand All @@ -42,7 +46,7 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
paymentStatus[paymentCollection.status] += 1
}

const totalPayments = order.payment_collections.length
const totalPayments = payment_collections.length
const totalPaymentExceptCanceled =
totalPayments - paymentStatus[PaymentStatus.CANCELED]

Expand Down Expand Up @@ -90,7 +94,11 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
return PaymentStatus.NOT_PAID
}

export const getLastFulfillmentStatus = (order: OrderDetailDTO) => {
export const getLastFulfillmentStatus = ({
fulfillments,
}: {
fulfillments: FulfillmentDTO[]
}) => {
const FulfillmentStatus = {
NOT_FULFILLED: "not_fulfilled",
PARTIALLY_FULFILLED: "partially_fulfilled",
Expand All @@ -113,7 +121,7 @@ export const getLastFulfillmentStatus = (order: OrderDetailDTO) => {
delivered_at: FulfillmentStatus.DELIVERED,
canceled_at: FulfillmentStatus.CANCELED,
}
for (const fulfillmentCollection of order.fulfillments) {
for (const fulfillmentCollection of fulfillments) {
for (const key in statusMap) {
if (fulfillmentCollection[key]) {
fulfillmentStatus[statusMap[key]] += 1
Expand All @@ -122,7 +130,7 @@ export const getLastFulfillmentStatus = (order: OrderDetailDTO) => {
}
}

const totalFulfillments = order.fulfillments.length
const totalFulfillments = fulfillments.length
const totalFulfillmentsExceptCanceled =
totalFulfillments - fulfillmentStatus[FulfillmentStatus.CANCELED]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface StepInput {
provider_id: string
amount: BigNumberInput
currency_code: string
provider_token?: string
context?: PaymentProviderContext
data?: Record<string, unknown>
}
Expand All @@ -27,6 +28,7 @@ export const createPaymentSessionStep = createStep(
input.payment_collection_id,
{
provider_id: input.provider_id,
provider_token: input.provider_token,
currency_code: input.currency_code,
amount: input.amount,
data: input.data ?? {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { PaymentProviderContext, PaymentSessionDTO } from "@medusajs/types"
import {
BigNumberInput,
PaymentProviderContext,
PaymentSessionDTO,
} from "@medusajs/types"
import { MathBN, PaymentSessionStatus } from "@medusajs/utils"
import {
WorkflowData,
createWorkflow,
Expand All @@ -12,8 +17,10 @@ import { deletePaymentSessionsWorkflow } from "./delete-payment-sessions"
interface WorkflowInput {
payment_collection_id: string
provider_id: string
provider_token?: string
data?: Record<string, unknown>
context?: PaymentProviderContext
amount?: BigNumberInput
}

export const createPaymentSessionsWorkflowId = "create-payment-sessions"
Expand All @@ -22,20 +29,31 @@ export const createPaymentSessionsWorkflow = createWorkflow(
(input: WorkflowData<WorkflowInput>): WorkflowData<PaymentSessionDTO> => {
const paymentCollection = useRemoteQueryStep({
entry_point: "payment_collection",
fields: ["id", "amount", "currency_code", "payment_sessions.*"],
fields: [
"id",
"raw_amount",
"raw_authorized_amount",
"currency_code",
"payment_sessions.*",
],
variables: { id: input.payment_collection_id },
list: false,
})

const paymentSessionInput = transform(
{ paymentCollection, input },
(data) => {
const balance = MathBN.sub(
data.paymentCollection.raw_amount,
data.paymentCollection.raw_authorized_amount || 0
)
return {
payment_collection_id: data.input.payment_collection_id,
provider_id: data.input.provider_id,
provider_token: data.input.provider_token,
data: data.input.data,
context: data.input.context,
amount: data.paymentCollection.amount,
amount: MathBN.min(data.input.amount || balance, balance),
currency_code: data.paymentCollection.currency_code,
}
}
Expand All @@ -46,15 +64,14 @@ export const createPaymentSessionsWorkflow = createWorkflow(
(data) => {
return {
ids:
data.paymentCollection?.payment_sessions?.map((ps) => ps.id) || [],
data.paymentCollection?.payment_sessions
?.filter((ps) => ps.status !== PaymentSessionStatus.AUTHORIZED)
?.map((ps) => ps.id) || [],
}
}
)

// Note: We are deleting an existing active session before creating a new one
// for a payment collection as we don't support split payments at the moment.
// When we are ready to accept split payments, this along with other workflows
// need to be handled correctly
// Note: We are deleting all existing non-authorized session before creating a new one
const [created] = parallelize(
createPaymentSessionStep(paymentSessionInput),
deletePaymentSessionsWorkflow.runAsStep({
Expand Down
16 changes: 16 additions & 0 deletions packages/core/js-sdk/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,22 @@ export class Store {
query,
})
},

addPaymentSession: async (
paymentCollectionId: string,
body: Record<string, any>,
query?: SelectParams,
headers?: ClientHeaders
) => {
return this.client.fetch<{
payment_collection: HttpTypes.StorePaymentCollection
}>(`/store/payment-collections/${paymentCollectionId}/payment-sessions`, {
method: "POST",
headers,
body,
query,
})
},
}

public order = {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/types/src/payment/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ export interface CreatePaymentSessionDTO {
*/
provider_id: string

/**
* The provider's payment method token
*/
provider_token?: string

/**
* The ISO 3 character currency code of the payment session.
*/
Expand Down
27 changes: 26 additions & 1 deletion packages/core/types/src/payment/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,20 @@ export type PaymentProviderContext = {
email?: string

/**
* The ID of payment session the provider payment is associated with.
* The associated payment session's ID.
*/
session_id?: string

/**
* The associated cart's ID.
*/
cart_id?: string

/**
* The associated order's ID.
*/
order_id?: string

/**
* The customer associated with this payment.
*/
Expand Down Expand Up @@ -76,6 +86,11 @@ export type CreatePaymentProviderSession = {
* The ISO 3 character currency code.
*/
currency_code: string

/*
* The payment method token
*/
token?: string
}

/**
Expand Down Expand Up @@ -184,6 +199,16 @@ export type WebhookActionData = {
*/
session_id: string

/**
* The associated cart's ID.
*/
cart_id: string

/**
* The associated order's ID.
*/
order_id: string

/**
* The amount to be captured or authorized (based on the action's type.)
*/
Expand Down
15 changes: 8 additions & 7 deletions packages/medusa/src/api/store/orders/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { getOrderDetailWorkflow } from "@medusajs/core-flows"
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
import { refetchOrder } from "../helpers"
import { StoreGetOrdersParamsType } from "../validators"

// TODO: Do we want to apply some sort of authentication here? My suggestion is that we do
export const GET = async (
req: MedusaRequest<StoreGetOrdersParamsType>,
res: MedusaResponse
) => {
const order = await refetchOrder(
req.params.id,
req.scope,
req.remoteQueryConfig.fields
)
const { result } = await getOrderDetailWorkflow(req.scope).run({
input: {
fields: req.remoteQueryConfig.fields,
order_id: req.params.id,
},
})

res.json({ order })
res.json({ order: result })
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const POST = async (
res: MedusaResponse
) => {
const collectionId = req.params.id
const { context = {}, data, provider_id } = req.body
const { context = {}, data, provider_id, amount } = req.body

// If the customer is logged in, we auto-assign them to the payment collection
if (req.auth_context?.actor_id) {
Expand All @@ -21,7 +21,8 @@ export const POST = async (
}
const workflowInput = {
payment_collection_id: collectionId,
provider_id: provider_id,
provider_id,
amount,
data,
context,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const StoreCreatePaymentSession = z
provider_id: z.string(),
context: z.record(z.unknown()).optional(),
data: z.record(z.unknown()).optional(),
amount: z.number().optional(),
})
.strict()

Expand Down
43 changes: 33 additions & 10 deletions packages/modules/payment/src/services/payment-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,38 +295,52 @@ export default class PaymentModuleService
@MedusaContext() sharedContext?: Context
): Promise<PaymentSessionDTO> {
let paymentSession: PaymentSession | undefined
let providerSessionData: Record<string, unknown> | undefined

try {
paymentSession = await this.createPaymentSession_(
paymentCollectionId,
input,
sharedContext
)

const providerSessionSession =
await this.paymentProviderService_.createSession(input.provider_id, {
providerSessionData = await this.paymentProviderService_.createSession(
input.provider_id,
{
context: { ...input.context, session_id: paymentSession.id },
amount: input.amount,
currency_code: input.currency_code,
})

token: input.provider_token,
}
)
paymentSession = (
await this.paymentSessionService_.update(
{
id: paymentSession.id,
data: { ...input.data, ...providerSessionSession },
data: { ...input.data, ...providerSessionData },
},
sharedContext
)
)[0]
if (input.provider_token) {
await this.authorizePaymentSession(
paymentSession!.id,
{},
sharedContext
)
paymentSession = await this.paymentSessionService_.retrieve(
paymentSession!.id,
{},
sharedContext
)
}
} catch (error) {
if (paymentSession) {
// In case the session is created, but fails to be updated in Medusa,
// we catch the error and delete the session and rethrow.
if (providerSessionData) {
await this.paymentProviderService_.deleteSession({
provider_id: input.provider_id,
data: input.data,
data: providerSessionData,
})
}
if (paymentSession) {
await this.paymentSessionService_.delete(
paymentSession.id,
sharedContext
Expand Down Expand Up @@ -862,6 +876,15 @@ export default class PaymentModuleService
{},
sharedContext
)

if (event.data.order_id && !event.data.cart_id) {
await this.authorizePaymentSession(
event.data.session_id,
{},
sharedContext
)
}

if (payment && !payment.captured_at) {
await this.capturePayment(
{ payment_id: payment.id, amount: event.data.amount },
Expand Down
Loading

0 comments on commit 211429c

Please sign in to comment.