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 710ff38
Show file tree
Hide file tree
Showing 18 changed files with 288 additions and 147 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
35 changes: 31 additions & 4 deletions 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 Expand Up @@ -282,10 +307,12 @@ export interface IPaymentProvider {
* In this method, you can interact with the third-party provider and perform any actions necessary to capture the payment.
*
* @param {Record<string, unknown>} paymentSessionData - The `data` field of the payment.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>} Either an error object or a value that's stored in the `data` field of the payment.
* @param {BigNumberInput} captureAmount - The amount to capture.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>} Either an error object or a value that's stored in the `data` field of the payment capture.
*/
capturePayment(
paymentSessionData: Record<string, unknown>
paymentSessionData: Record<string, unknown>,
captureAmount?: BigNumberInput
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>

/**
Expand All @@ -295,7 +322,7 @@ export interface IPaymentProvider {
*
* @param {Record<string, unknown>} paymentSessionData - The `data` field of a Payment.
* @param {BigNumberInput} refundAmount - The amount to refund.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>} Either an error object or an object that's stored in the `data` field of the payment.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>} Either an error object or an object that's stored in the `data` field of the payment refund.
*/
refundPayment(
paymentSessionData: Record<string, unknown>,
Expand Down
38 changes: 20 additions & 18 deletions packages/core/utils/src/payment/abstract-payment-provider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
BigNumberInput,
CreatePaymentProviderSession,
IPaymentProvider,
MedusaContainer,
Expand All @@ -7,55 +8,55 @@ import {
PaymentSessionStatus,
ProviderWebhookPayload,
UpdatePaymentProviderSession,
WebhookActionResult
WebhookActionResult,
} from "@medusajs/types"

/**
* ## Overview
*
* A payment provider is used to handle and process payments, such as authorizing, capturing, and refund payments.
*
*
* :::note
*
*
* This guide is a work in progress.
*
*
* :::
*
*
* ---
*
*
* ## How to Create a Payment Provider
*
*
* A payment provider is a TypeScript or JavaScript class that extends the `AbstractPaymentProvider` class imported from `@medusajsa/utils`.
*
*
* You can create the payment provider in a module or plugin, then pass that module/plugin in the Payment Module's `providers` option. You can also pass the path to the file
* that defines the provider if it's created in the Medusa application's codebase.
*
*
* For example:
*
*
* ```ts
* abstract class MyPayment extends AbstractPaymentProvider<MyConfigurations> {
* // ...
* }
* ```
*
* ---
*
*
* ## Configuration Type Parameter
*
*
* The `AbstractPaymentProvider` class accepts an optional type parameter that defines the type of configuration that your payment provider expects.
*
*
* For example:
*
*
* ```ts
* interface MyConfigurations {
* apiKey: string
* }
*
*
* abstract class MyPayment extends AbstractPaymentProvider<MyConfigurations> {
* // ...
* }
* ```
*
*
* ---
*
* ## Identifier Property
Expand Down Expand Up @@ -215,7 +216,8 @@ export abstract class AbstractPaymentProvider<TConfig = Record<string, unknown>>
}

abstract capturePayment(
paymentSessionData: Record<string, unknown>
paymentSessionData: Record<string, unknown>,
captureAmount?: BigNumberInput
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>

abstract authorizePayment(
Expand Down Expand Up @@ -247,7 +249,7 @@ export abstract class AbstractPaymentProvider<TConfig = Record<string, unknown>>

abstract refundPayment(
paymentSessionData: Record<string, unknown>,
refundAmount: number
refundAmount: BigNumberInput
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>

abstract retrievePayment(
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 })
}
Loading

0 comments on commit 710ff38

Please sign in to comment.