-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: changed details related to new method signatures #2876
Changes from 6 commits
14a53e6
a8e6536
04574f7
f785f76
974905a
d4fb094
12b98e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,51 +53,44 @@ For example, create the file `src/services/my-payment.ts` with the following con | |
<!-- eslint-disable max-len --> | ||
|
||
```ts title=src/services/my-payment.ts | ||
import { | ||
AbstractPaymentService, | ||
Cart, Data, Payment, PaymentSession, | ||
PaymentSessionStatus, TransactionBaseService, | ||
} from "@medusajs/medusa" | ||
import { AbstractPaymentService, Context, Data, Payment, PaymentSession, PaymentSessionStatus, TransactionBaseService } from "@medusajs/medusa" | ||
import { EntityManager } from "typeorm" | ||
|
||
class MyPaymentService extends AbstractPaymentService<TransactionBaseService> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: The class is not template, rm TransactionBaseService |
||
protected manager_: EntityManager | ||
protected transactionManager_: EntityManager | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: | undefined |
||
|
||
getPaymentData(paymentSession: PaymentSession): Promise<Data> { | ||
async getPaymentData(paymentSession: PaymentSession): Promise<Data> { | ||
throw new Error("Method not implemented.") | ||
} | ||
updatePaymentData(paymentSessionData: Data, data: Data): Promise<Data> { | ||
async updatePaymentData(paymentSessionData: Data, data: Data): Promise<Data> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: |
||
throw new Error("Method not implemented.") | ||
} | ||
createPayment(cart: Cart): Promise<Data> { | ||
async createPayment(context: Context): Promise<PaymentSessionResponse> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we include Cart though? Because we're moving to PaymentContext and Cart is used for backwards compatibility (from my understanding) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The thing is that TS will error out because the typings are mismatched. PaymentContext can't be assigned to Cart & PaymentContext There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah ok I didn't notice that. Will make the change! |
||
throw new Error("Method not implemented.") | ||
} | ||
retrievePayment(paymentData: Data): Promise<Data> { | ||
async retrievePayment(paymentData: Data): Promise<Data> { | ||
throw new Error("Method not implemented.") | ||
} | ||
updatePayment(paymentSessionData: Data, cart: Cart): Promise<Data> { | ||
async updatePayment(paymentSessionData: Data, context: Context): Promise<PaymentSessionResponse> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: |
||
throw new Error("Method not implemented.") | ||
} | ||
authorizePayment( | ||
paymentSession: PaymentSession, | ||
context: Data | ||
): Promise<{ data: Data; status: PaymentSessionStatus; }> { | ||
async authorizePayment(paymentSession: PaymentSession, context: Data): Promise<{ data: Data; status: PaymentSessionStatus; }> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: |
||
throw new Error("Method not implemented.") | ||
} | ||
capturePayment(payment: Payment): Promise<Data> { | ||
async capturePayment(payment: Payment): Promise<Data> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: Promise There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what this comment refers to. Can you explain more? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, |
||
throw new Error("Method not implemented.") | ||
} | ||
refundPayment(payment: Payment, refundAmount: number): Promise<Data> { | ||
async refundPayment(payment: Payment, refundAmount: number): Promise<Data> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From looking at the payment provider interface, I can see that Data = PaymentSessionData = PaymentData. I think, unless there's a reason I'm not aware of, we should default to one of them in the documentation. Which one do you think we should choose? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @adrien2p just in case you missed this comment 👆🏻 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oups sorry, indeed they are the same. We did split them in order to make sense of what type of object it correspond to. I am fine with choosing one and in that case we can stick to data as you did. I am just afraid that the user don't understand why we say data but the interface says something else There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, that makes sense too. I'll look into it and see the best approach here. |
||
throw new Error("Method not implemented.") | ||
} | ||
cancelPayment(payment: Payment): Promise<Data> { | ||
async cancelPayment(payment: Payment): Promise<Data> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: |
||
throw new Error("Method not implemented.") | ||
} | ||
deletePayment(paymentSession: PaymentSession): Promise<void> { | ||
async deletePayment(paymentSession: PaymentSession): Promise<void> { | ||
throw new Error("Method not implemented.") | ||
} | ||
getStatus(data: Data): Promise<PaymentSessionStatus> { | ||
async getStatus(data: Data): Promise<PaymentSessionStatus> { | ||
throw new Error("Method not implemented.") | ||
} | ||
|
||
|
@@ -137,8 +130,8 @@ Additionally, if you’re creating your Payment Provider as an external plugin t | |
```ts | ||
class MyPaymentService extends AbstractPaymentService<TransactionBaseService> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: rm template |
||
// ... | ||
constructor({ productService }, options) { | ||
super() | ||
constructor(container, options) { | ||
super(container) | ||
// you can access options here | ||
} | ||
// ... | ||
|
@@ -147,26 +140,56 @@ class MyPaymentService extends AbstractPaymentService<TransactionBaseService> { | |
|
||
### createPayment | ||
|
||
This method is called during checkout when [Payment Sessions are initialized](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCartPaymentSessions) to present payment options to the customer. It is used to allow you to make any necessary calls to the third-party provider to initialize the payment. For example, in Stripe this method is used to initialize a Payment Intent for the customer. | ||
This method is called during checkout when [Payment Sessions are initialized](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCartPaymentSessions) to present payment options to the customer. It is used to allow you to make any necessary calls to the third-party provider to initialize the payment. | ||
|
||
For example, in Stripe this method is used to initialize a Payment Intent for the customer. | ||
|
||
The method receives a context object as a first parameter. This object is of type `PaymentContext` and has the following properties: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: is of type Cart & PaymentContext. |
||
|
||
```ts | ||
type PaymentContext = { | ||
cart: { | ||
context: Record<string, unknown> | ||
id: string | ||
email: string | ||
shipping_address: Address | null | ||
shipping_methods: ShippingMethod[] | ||
} | ||
currency_code: string | ||
amount: number | ||
resource_id?: string | ||
customer?: Customer | ||
} | ||
``` | ||
|
||
This method must return an object of type `PaymentSessionResponse`. It should have the following properties: | ||
|
||
The method receives the cart as an object for its first parameter. It holds all the necessary information you need to know about the cart and the customer that owns this cart. | ||
```ts | ||
type PaymentSessionResponse = { | ||
update_requests: { customer_metadata: Record<string, unknown> } | ||
session_data: Record<string, unknown> | ||
} | ||
``` | ||
|
||
This method must return an object that is going to be stored in the `data` field of the Payment Session to be created. As mentioned in the [Architecture Overview](./overview.md), the `data` field is useful to hold any data required by the third-party provider to process the payment or retrieve its details at a later point. | ||
Where: | ||
|
||
An example of a minimal implementation of `createPayment` that does not interact with any third-party providers: | ||
- `session_data` is the data that is going to be stored in the `data` field of the Payment Session to be created. As mentioned in the [Architecture Overview](./overview.md), the `data` field is useful to hold any data required by the third-party provider to process the payment or retrieve its details at a later point. | ||
- `update_requests` is an object that can be used to pass data from the payment provider plugin to the core to update internal resources. Currently, it only has one attribute `customer_metadata` which allows updating the `metadata` field of the customer. | ||
|
||
An example of a minimal implementation of `createPayment`: | ||
|
||
<!-- eslint-disable max-len --> | ||
|
||
```ts | ||
import { Cart, Data } from "@medusajs/medusa" | ||
// ... | ||
import { PaymentContext, PaymentSessionResponse } from "@medusajs/medusa" | ||
|
||
class MyPaymentService extends AbstractPaymentService<TransactionBaseService> { | ||
// ... | ||
async createPayment(cart: Cart): Promise<Data> { | ||
async createPayment(context: PaymentContext): Promise<PaymentSessionResponse> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: Cart & PaymentContext |
||
// prepare data | ||
return { | ||
id: "test-payment", | ||
status: "pending", | ||
session_data, | ||
update_requests, | ||
} | ||
} | ||
} | ||
|
@@ -244,24 +267,56 @@ A line item refers to a product in the cart. | |
|
||
::: | ||
|
||
It accepts the `data` field of the Payment Session as the first parameter and the cart as an object for the second parameter. | ||
It accepts the `data` field of the Payment Session as the first parameter and a context object as a second parameter. This object is of type `PaymentContext` and has the following properties: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: same as the previous one |
||
|
||
```ts | ||
type PaymentContext = { | ||
cart: { | ||
context: Record<string, unknown> | ||
id: string | ||
email: string | ||
shipping_address: Address | null | ||
shipping_methods: ShippingMethod[] | ||
} | ||
currency_code: string | ||
amount: number | ||
resource_id?: string | ||
customer?: Customer | ||
} | ||
``` | ||
|
||
You can utilize this method to interact with the third-party provider and update any details regarding the payment if necessary. | ||
|
||
This method must return an object that will be stored in the `data` field of the Payment Session. | ||
This method must return an object of type `PaymentSessionResponse`. It should have the following properties: | ||
|
||
```ts | ||
type PaymentSessionResponse = { | ||
update_requests: { customer_metadata: Record<string, unknown> } | ||
session_data: Record<string, unknown> | ||
} | ||
``` | ||
|
||
An example of a minimal implementation of `updatePayment` that does not need to make any updates on the third-party provider or the `data` field of the Payment Session: | ||
Where: | ||
|
||
- `session_data` is the data that is going to be stored in the `data` field of the Payment Session to be created. As mentioned in the [Architecture Overview](./overview.md), the `data` field is useful to hold any data required by the third-party provider to process the payment or retrieve its details at a later point. | ||
- `update_requests` is an object that can be used to request from the Medusa core to update internal resources. Currently, it only has one attribute `customer_metadata` which allows updating the `metadata` field of the customer. | ||
|
||
An example of a minimal implementation of `updatePayment`: | ||
|
||
<!-- eslint-disable max-len --> | ||
|
||
```ts | ||
import { Cart, Data } from "@medusajs/medusa" | ||
import { PaymentContext, Data } from "@medusajs/medusa" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: To update according to previous todo's |
||
// ... | ||
|
||
class MyPaymentService extends AbstractPaymentService<TransactionBaseService> { | ||
// ... | ||
async updatePayment(paymentSessionData: Data, cart: Cart): Promise<Data> { | ||
return paymentSessionData | ||
async updatePayment(paymentSessionData: Data, context: PaymentContext): Promise<PaymentSessionResponse> { | ||
// prepare data | ||
return { | ||
session_data, | ||
update_requests, | ||
} | ||
} | ||
} | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: The import needs to be changed