feat(payment): provider service (#6308)

This commit is contained in:
Frane Polić
2024-02-12 20:57:41 +01:00
committed by GitHub
parent 869dc751a0
commit a6a4b3f01a
21 changed files with 1511 additions and 637 deletions
+70
View File
@@ -31,6 +31,34 @@ export enum PaymentCollectionStatus {
CANCELED = "canceled",
}
/**
* @enum
*
* The status of a payment session.
*/
export enum PaymentSessionStatus {
/**
* The payment is authorized.
*/
AUTHORIZED = "authorized",
/**
* The payment is pending.
*/
PENDING = "pending",
/**
* The payment requires an action.
*/
REQUIRES_MORE = "requires_more",
/**
* An error occurred while processing the payment.
*/
ERROR = "error",
/**
* The payment is canceled.
*/
CANCELED = "canceled",
}
export interface PaymentCollectionDTO {
/**
* The ID of the Payment Collection
@@ -255,6 +283,48 @@ export interface PaymentSessionDTO {
* The ID of the Payment Session
*/
id: string
/**
* The amount
*/
amount: number
/**
* Payment session currency
*/
currency_code: string
/**
* The ID of payment provider
*/
provider_id: string
/**
* Payment provider data
*/
data: Record<string, unknown>
/**
* The status of the payment session
*/
status: PaymentSessionStatus
/**
* When the session was authorized
*/
authorized_at?: Date
/**
* The payment collection the session is associated with
* @expandable
*/
payment_collection?: PaymentCollectionDTO
/**
* The payment created from the session
* @expandable
*/
payment?: PaymentDTO
}
export interface PaymentProviderDTO {
+1 -1
View File
@@ -1,4 +1,4 @@
export * from "./common"
export * from "./mutations"
export * from "./provider"
export * from "./service"
+14 -12
View File
@@ -1,4 +1,5 @@
import { PaymentCollectionStatus } from "./common"
import { PaymentProviderContext } from "./provider"
/**
* Payment Collection
@@ -26,6 +27,7 @@ export interface UpdatePaymentCollectionDTO
export interface CreatePaymentDTO {
amount: number
currency_code: string
provider_id: string
data: Record<string, unknown>
@@ -46,8 +48,6 @@ export interface UpdatePaymentDTO {
order_id?: string
order_edit_id?: string
customer_id?: string
data?: Record<string, unknown>
}
export interface CreateCaptureDTO {
@@ -69,17 +69,19 @@ export interface CreateRefundDTO {
*/
export interface CreatePaymentSessionDTO {
amount: number
currency_code: string
provider_id: string
cart_id?: string
resource_id?: string
customer_id?: string
providerContext: PaymentProviderContext
}
export interface SetPaymentSessionsDTO {
provider_id: string
amount: number
session_id?: string
export interface UpdatePaymentSessionDTO {
id: string
providerContext: PaymentProviderContext
}
/**
* Payment Provider
*/
export interface CreatePaymentProviderDTO {
id: string
is_enabled?: boolean
}
+212
View File
@@ -0,0 +1,212 @@
import { PaymentSessionStatus } from "./common"
/**
* @interface
*
* A payment's context.
*/
export type PaymentProviderContext = {
/**
* The payment's billing address.
*/
billing_address?: Record<string, unknown> | null // TODO: revisit types
/**
* The customer's email.
*/
email?: string
/**
* The selected currency code.
*/
currency_code: string
/**
* The payment's amount.
*/
amount: number
/**
* The ID of the resource the payment is associated with. For example, the cart's ID.
*/
resource_id: string
/**
* The customer associated with this payment.
*/
customer?: Record<string, unknown> // TODO: type
/**
* The context.
*/
context: Record<string, unknown>
/**
* If the payment session hasn't been created or initiated yet, it'll be an empty object.
* If the payment session exists, it'll be the value of the payment session's `data` field.
*/
payment_session_data: Record<string, unknown>
}
/**
* @interface
*
* The response of operations on a payment.
*/
export type PaymentProviderSessionResponse = {
/**
* The data to be stored in the `data` field of the Payment Session to be created.
* 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.
*/
data: Record<string, unknown>
}
export type PaymentProviderAuthorizeResponse = {
/**
* The status of the payment, which will be stored in the payment session's `status` field.
*/
status: PaymentSessionStatus
/**
* The `data` to be stored in the payment session's `data` field.
*/
data: PaymentProviderSessionResponse["data"]
}
export type PaymentProviderDataInput = {
provider_id: string
data: Record<string, unknown>
}
/**
* An object that is returned in case of an error.
*/
export interface PaymentProviderError {
/**
* The error message
*/
error: string
/**
* The error code.
*/
code?: string
/**
* Any additional helpful details.
*/
detail?: any
}
export interface IPaymentProvider {
/**
* @ignore
*
* Return a unique identifier to retrieve the payment plugin provider
*/
getIdentifier(): string
/**
* Make calls to the third-party provider to initialize the payment. For example, in Stripe this method is used to create a Payment Intent for the customer.
*
* @param {PaymentProviderContext} context - The context of the payment.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse>} Either the payment's data or an error object.
*/
initiatePayment(
context: PaymentProviderContext
): Promise<PaymentProviderError | PaymentProviderSessionResponse>
/**
* This method is used to update the payment session.
*
* @param {PaymentProviderContext} context - The context of the payment.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse | void>} Either the payment's data or an error object.
*/
updatePayment(
context: PaymentProviderContext
): Promise<PaymentProviderError | PaymentProviderSessionResponse>
/**
* This method is used to perform any actions necessary before a Payment Session is deleted. The Payment Session is deleted in one of the following cases:
*
* @param {Record<string, unknown>} paymentSessionData - The `data` field of the Payment Session.
* @returns Either an error object or an empty object.
*/
deletePayment(
paymentSessionData: Record<string, unknown>
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
/**
* This method is used to authorize payment using the Payment Session.
* You can interact with a third-party provider and perform any actions necessary to authorize the payment.
*
* The payment authorization might require additional action from the customer before it is declared authorized. Once that additional action is performed,
* the `authorizePayment` method will be called again to validate that the payment is now fully authorized. So, make sure to implement it for this case as well, if necessary.
*
* :::note
*
* The payment authorization status is determined using the {@link getPaymentStatus} method. If the status is `requires_more`, then it means additional actions are required
* from the customer.
*
* :::
*
* @param {Record<string, unknown>} paymentSessionData - The `data` field of the payment session.
* @param {Record<string, unknown>} context - The context of the authorization.
* @returns The authorization details or an error object.
*/
authorizePayment(
paymentSessionData: Record<string, unknown>,
context: Record<string, unknown>
): Promise<PaymentProviderError | PaymentProviderAuthorizeResponse>
/**
* This method is used to capture the payment amount. This is typically triggered manually by the store operator from the admin.
*
* You can utilize this method to 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 for its first parameter.
* @returns Either an error object or a value that's stored in the `data` field of the Payment.
*/
capturePayment(
paymentSessionData: Record<string, unknown>
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
/**
* This method is used to refund a payment. This is typically triggered manually by the store operator from the admin. The refund amount might be the total amount or part of it.
*
* You can utilize this method to interact with the third-party provider and perform any actions necessary to refund the payment.
*
* @param {Record<string, unknown>} paymentSessionData - The `data` field of a Payment.
* @param {number} refundAmount - the amount to refund.
* @returns Either an error object or a value that's stored in the `data` field of the Payment.
*/
refundPayment(
paymentSessionData: Record<string, unknown>,
refundAmount: number
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
/**
* This method is used to provide a uniform way of retrieving the payment information from the third-party provider.
* For example, in Stripes Payment Provider this method is used to retrieve the payment intent details from Stripe.
*
* @param {Record<string, unknown>} paymentSessionData -
* The `data` field of a Payment Session. Make sure to store in the `data` field any necessary data that would allow you to retrieve the payment data from the third-party provider.
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse["session_data"]>} The payment's data, typically retrieved from a third-party provider.
*/
retrievePayment(
paymentSessionData: Record<string, unknown>
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
/**
* This method is used to cancel a payment. This method is typically triggered by one of the following situations:
*
* You can utilize this method to interact with the third-party provider and perform any actions necessary to cancel the payment.
*
* @param {Record<string, unknown>} paymentSessionData - The `data` field of the Payment.
* @returns Either an error object or a value that's stored in the `data` field of the Payment.
*/
cancelPayment(
paymentSessionData: Record<string, unknown>
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
/**
* This method is used to get the status of a Payment or a Payment Session.
*
* @param {Record<string, unknown>} paymentSessionData -
* The `data` field of a Payment as a parameter. You can use this data to interact with the third-party provider to check the status of the payment if necessary.
* @returns {Promise<PaymentSessionStatus>} The status of the Payment or Payment Session.
*/
getPaymentStatus(
paymentSessionData: Record<string, unknown>
): Promise<PaymentSessionStatus>
}
+40 -73
View File
@@ -6,25 +6,26 @@ import {
CreatePaymentDTO,
CreatePaymentSessionDTO,
CreateRefundDTO,
SetPaymentSessionsDTO,
UpdatePaymentCollectionDTO,
UpdatePaymentDTO,
UpdatePaymentSessionDTO,
} from "./mutations"
import {
FilterablePaymentCollectionProps,
PaymentCollectionDTO,
PaymentDTO,
PaymentSessionDTO,
} from "./common"
import { FindConfig } from "../common"
export interface IPaymentModuleService extends IModuleService {
/* ********** PAYMENT COLLECTION ********** */
createPaymentCollection(
createPaymentCollections(
data: CreatePaymentCollectionDTO[],
sharedContext?: Context
): Promise<PaymentCollectionDTO[]>
createPaymentCollection(
createPaymentCollections(
data: CreatePaymentCollectionDTO,
sharedContext?: Context
): Promise<PaymentCollectionDTO>
@@ -47,11 +48,11 @@ export interface IPaymentModuleService extends IModuleService {
sharedContext?: Context
): Promise<[PaymentCollectionDTO[], number]>
updatePaymentCollection(
updatePaymentCollections(
data: UpdatePaymentCollectionDTO[],
sharedContext?: Context
): Promise<PaymentCollectionDTO[]>
updatePaymentCollection(
updatePaymentCollections(
data: UpdatePaymentCollectionDTO,
sharedContext?: Context
): Promise<PaymentCollectionDTO>
@@ -65,59 +66,14 @@ export interface IPaymentModuleService extends IModuleService {
sharedContext?: Context
): Promise<void>
authorizePaymentCollection(
completePaymentCollections(
paymentCollectionId: string,
sharedContext?: Context
): Promise<PaymentCollectionDTO>
completePaymentCollection(
paymentCollectionId: string,
completePaymentCollections(
paymentCollectionId: string[],
sharedContext?: Context
): Promise<PaymentCollectionDTO>
/* ********** PAYMENT ********** */
createPayment(
data: CreatePaymentDTO,
sharedContext?: Context
): Promise<PaymentDTO>
createPayment(
data: CreatePaymentDTO[],
sharedContext?: Context
): Promise<PaymentDTO[]>
capturePayment(
data: CreateCaptureDTO,
sharedContext?: Context
): Promise<PaymentDTO>
capturePayment(
data: CreateCaptureDTO[],
sharedContext?: Context
): Promise<PaymentDTO[]>
refundPayment(
data: CreateRefundDTO,
sharedContext?: Context
): Promise<PaymentDTO>
refundPayment(
data: CreateRefundDTO[],
sharedContext?: Context
): Promise<PaymentDTO[]>
cancelPayment(paymentId: string, sharedContext?: Context): Promise<PaymentDTO>
cancelPayment(
paymentId: string[],
sharedContext?: Context
): Promise<PaymentDTO[]>
updatePayment(
data: UpdatePaymentDTO,
sharedContext?: Context
): Promise<PaymentDTO>
updatePayment(
data: UpdatePaymentDTO[],
sharedContext?: Context
): Promise<PaymentDTO[]>
): Promise<PaymentCollectionDTO[]>
/* ********** PAYMENT SESSION ********** */
@@ -125,28 +81,39 @@ export interface IPaymentModuleService extends IModuleService {
paymentCollectionId: string,
data: CreatePaymentSessionDTO,
sharedContext?: Context
): Promise<PaymentCollectionDTO>
createPaymentSession(
paymentCollectionId: string,
data: CreatePaymentSessionDTO[],
sharedContext?: Context
): Promise<PaymentCollectionDTO>
): Promise<PaymentSessionDTO>
authorizePaymentSessions(
paymentCollectionId: string,
sessionIds: string[],
updatePaymentSession(
data: UpdatePaymentSessionDTO,
sharedContext?: Context
): Promise<PaymentCollectionDTO>
): Promise<PaymentSessionDTO>
completePaymentSessions(
paymentCollectionId: string,
sessionIds: string[],
sharedContext?: Context
): Promise<PaymentCollectionDTO>
deletePaymentSession(id: string, sharedContext?: Context): Promise<void>
setPaymentSessions(
paymentCollectionId: string,
data: SetPaymentSessionsDTO[],
authorizePaymentSession(
id: string,
context: Record<string, unknown>,
sharedContext?: Context
): Promise<PaymentCollectionDTO>
): Promise<PaymentDTO>
/* ********** PAYMENT ********** */
updatePayment(
data: UpdatePaymentDTO,
sharedContext?: Context
): Promise<PaymentDTO>
capturePayment(
data: CreateCaptureDTO,
sharedContext?: Context
): Promise<PaymentDTO>
refundPayment(
data: CreateRefundDTO,
sharedContext?: Context
): Promise<PaymentDTO>
cancelPayment(paymentId: string, sharedContext?: Context): Promise<PaymentDTO>
createProvidersOnLoad(): Promise<void>
}