github medusajs/medusa v2.5.0

one day ago

Highlights

Revamped Payment Provider interface

Warning

Breaking changes

The payment provider interface, originally designed for Medusa V1, has now been redesigned for V2–a long overdue update. These changes deliver a more unified and intuitive API.

We apologise in advance for the inconvenience it might cause for your payment provider implementations.

The following are breaking changes:

Payment Provider interface

export interface IPaymentProvider {
   ...
 
-  initiatePayment(
-    data: CreatePaymentProviderSession
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse>
+  initiatePayment(data: InitiatePaymentInput): Promise<InitiatePaymentOutput>
 
-  updatePayment(
-    context: UpdatePaymentProviderSession
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse>
+  updatePayment(data: UpdatePaymentInput): Promise<UpdatePaymentOutput>
 
-  deletePayment(
-    paymentSessionData: Record<string, unknown>
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
+  deletePayment(data: DeletePaymentInput): Promise<DeletePaymentOutput>
 
-  authorizePayment(
-    paymentSessionData: Record<string, unknown>,
-    context: Record<string, unknown>
-  ): Promise<PaymentProviderError | PaymentProviderAuthorizeResponse>
+  authorizePayment(data: AuthorizePaymentInput): Promise<AuthorizePaymentOutput>
 
-  capturePayment(
-    paymentSessionData: Record<string, unknown>
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
+  capturePayment(data: CapturePaymentInput): Promise<CapturePaymentOutput>
 
-  refundPayment(
-    paymentSessionData: Record<string, unknown>,
-    refundAmount: BigNumberInput
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
+  refundPayment(data: RefundPaymentInput): Promise<RefundPaymentOutput>
 
-  retrievePayment(
-    paymentSessionData: Record<string, unknown>
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
+  retrievePayment(data: RetrievePaymentInput): Promise<RetrievePaymentOutput>
 
-  cancelPayment(
-    paymentSessionData: Record<string, unknown>
-  ): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
+  cancelPayment(data: CancelPaymentInput): Promise<CancelPaymentOutput>
+
+  createAccountHolder?(
+    data: CreateAccountHolderInput
+  ): Promise<CreateAccountHolderOutput>
+
+  deleteAccountHolder?(
+    data: DeleteAccountHolderInput
+  ): Promise<DeleteAccountHolderOutput>
 
-  listPaymentMethods?(
-    context: PaymentProviderContext
-  ): Promise<PaymentMethodResponse[]>
+  listPaymentMethods?(
+    data: ListPaymentMethodsInput
+  ): Promise<ListPaymentMethodsOutput>
 
-  savePaymentMethod?(
-    input: SavePaymentMethod
-  ): Promise<PaymentProviderError | SavePaymentMethodResponse>
+  savePaymentMethod?(
+    data: SavePaymentMethodInput
+  ): Promise<SavePaymentMethodOutput>
 
-  getPaymentStatus(
-    paymentSessionData: Record<string, unknown>
-  ): Promise<PaymentSessionStatus>
+  getPaymentStatus(data: GetPaymentStatusInput): Promise<GetPaymentStatusOutput>
}

The input and return types of the updated interface can be found in this file.

Additionally, we've updated the interface to require payment providers to throw errors instead of returning them to the upstream payment module service.

Create Payment Sessions endpoint

In addition to the interface changes, we've also removed the context field from the endpoint creating payment sessions:

`POST /store/payment-collections/:id/payment-sessions

This change addresses a security risk. The context accepted by the payment module now only accept known fields, limiting the surface area of what can be passed through it.

Account Holders
Fortunately, the revamp did not only introduce breaking changes. This release also introduces support for Account Holders in payment providers. In Stripe, for example, we will create a customer for every signed up user on your platform so you can track payments more easily within Stripe. These methods are optional for payment providers.

You can find all the changes in this pull request.

Overriding Shipping Option for Fulfillments

Note

Schemas changes

This release improves fulfillment capabilities, allowing merchants to override the shipping option originally selected during order creation. For example, a different shipping option can now be specified directly in the dashboard when creating a fulfillment.

Key changes:

  • Product <> Shipping Profile link

A link between Products and Shipping Profiles has been introduced, similar to the relationship in Medusa V1. Products now require a Shipping Profile upon creation. The create and update forms in the dashboard have been updated accordingly.

  • Override Shipping Option on Fulfillments

The fulfillment creation endpoint now accept an optional shipping_option_id. If passed, it will override the shipping option used when placing the order.

POST /admin/orders/:id/fulfillments

{ ..., shipping_option_id: "so_1234"}

This functionality is also available in the dashboard, allowing merchants to specify the override when creating a fulfillment.

  • Data migration script

Since products now require a shipping profile, this release includes a data migration script. The script will assign all products to the default shipping profile, if it exists. The default shipping profile is determined by looking for a shipping profile with default (case insensitive) in its name.

By default, data migration scripts run as part of the medusa db:migrate command.

Alternatively, you can run the data migration separately from the regular database migrations. To do this, first run the migration command with an argument skipping scripts:

medusa db:migrate --skip-scripts

Then, run the command again without the argument:

medusa db:migrate

Type-hinting for custom module services

This release improves type-hinting for custom module services. The input types of autogenerated create and update methods will provide an approximate type inferred from the related data model. Please note, in this first iteration, all properties will be marked as optional in the type, even though they might be required at the DB-level. We intend to further improve this to bring the type even closer to what the database expects.

Clearing workflow_executions exceeding their retention time

Note

Schemas changes

This release introduces a recurring job within the workflow engine to clear stale workflow executions from the database. The job runs every hour and deletes workflow executions that have exceeded their configured retention time.

Retention time is set in the workflow execution options. However, to simplify this operation, we’ve introduced a retention_time column in the workflow_execution table.

For existing workflow executions, the retention time will be automatically set if it was previously configured in the workflow execution options. The retention time is expected to be specified in seconds. If it was mistakenly configured in milliseconds, you may encounter a Postgres error when casting the retention time to an integer.

If you run into this issue, you can manually run the migration while specifying the correct retention time for your workflow executions.

Other noteworthy changes

Changes to medusa start

The medusa start command is intended to be used for production envionments. Therefore, the NODE_ENV now defaults to production instead of development.

New Divider component

The Divider component has been added to the UI library.

Added Metadata forms

Metadata forms have been added for the Product Collection and Order pages.

Features

Bugs

Documentation

Chores

Other Changes

New Contributors

Full Changelog: v2.4.0...v2.5.0

Don't miss a new medusa release

NewReleases is sending notifications on new releases.