feat(medusa,medusa-payment-stripe): Migrate Stripe to Abstract payment service (#1790)

This commit is contained in:
Adrien de Peretti
2022-10-04 10:49:43 +02:00
committed by GitHub
parent 00959f79bc
commit df62e618bc
19 changed files with 546 additions and 387 deletions

View File

@@ -0,0 +1,6 @@
---
"medusa-payment-stripe": patch
"@medusajs/medusa": patch
---
Migrate Stripe providers to the new AbstractPaymentService

View File

@@ -185,6 +185,9 @@ export const carts = {
}
export const CartServiceMock = {
withTransaction: function () {
return this
},
retrieve: jest.fn().mockImplementation((cartId) => {
if (cartId === IdMap.getId("fr-cart")) {
return Promise.resolve(carts.frCart)

View File

@@ -1,6 +1,9 @@
import { IdMap } from "medusa-test-utils"
export const CustomerServiceMock = {
withTransaction: function () {
return this
},
retrieve: jest.fn().mockImplementation((id) => {
if (id === IdMap.getId("lebron")) {
return Promise.resolve({

View File

@@ -1,4 +1,7 @@
export const TotalsServiceMock = {
withTransaction: function () {
return this
},
getTotal: jest.fn(),
}

View File

@@ -1 +1,3 @@
export default (fn) => (...args) => fn(...args).catch(args[2])
export default (fn) =>
(...args) =>
fn(...args).catch(args[2])

View File

@@ -12,6 +12,7 @@ export default async (req, res) => {
const paymentIntent = event.data.object
const manager = req.scope.resolve("manager")
const cartService = req.scope.resolve("cartService")
const orderService = req.scope.resolve("orderService")
@@ -24,24 +25,19 @@ export default async (req, res) => {
switch (event.type) {
case "payment_intent.succeeded":
if (order && order.payment_status !== "captured") {
await orderService.capturePayment(order.id)
await manager.transaction(async (manager) => {
await orderService.withTransaction(manager).capturePayment(order.id)
})
}
break
//case "payment_intent.canceled":
// if (order) {
// await orderService.update(order._id, {
// status: "canceled",
// })
// }
// break
case "payment_intent.payment_failed":
// TODO: Not implemented yet
break
case "payment_intent.amount_capturable_updated":
if (!order) {
await cartService.setPaymentSession(cartId, "stripe")
await cartService.authorizePayment(cartId)
await orderService.createFromCart(cartId)
await manager.transaction(async (manager) => {
const cartServiceTx = cartService.withTransaction(manager)
await cartServiceTx.setPaymentSession(cartId, "stripe")
await cartServiceTx.authorizePayment(cartId)
await orderService.withTransaction(manager).createFromCart(cartId)
})
}
break
default:

View File

@@ -1,6 +1,9 @@
import { IdMap } from "medusa-test-utils"
export const StripeProviderServiceMock = {
withTransaction: function () {
return this
},
retrievePayment: jest.fn().mockImplementation((payData) => {
if (payData.id === "pi_123456789") {
return Promise.resolve({

View File

@@ -5,6 +5,9 @@ import { carts } from "../../__mocks__/cart"
import { TotalsServiceMock } from "../../__mocks__/totals"
const RegionServiceMock = {
withTransaction: function () {
return this
},
retrieve: jest.fn().mockReturnValue(Promise.resolve({})),
}

View File

@@ -1,15 +1,29 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
import { AbstractPaymentService, PaymentSessionData } from "@medusajs/medusa"
class BancontactProviderService extends PaymentService {
class BancontactProviderService extends AbstractPaymentService {
static identifier = "stripe-bancontact"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
) {
super()
super(
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
)
/**
* Required Stripe options:
@@ -36,22 +50,25 @@ class BancontactProviderService extends PaymentService {
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
/** @private @const {EntityManager} */
this.manager_ = manager
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
* @param {PaymentSessionData} paymentSessionData - payment method data from cart
* @return {Promise<PaymentSessionStatus>} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
async getStatus(paymentSessionData) {
return await this.stripeProviderService_.getStatus(paymentSessionData)
}
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
* @return {Promise<Data[]>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
@@ -60,7 +77,7 @@ class BancontactProviderService extends PaymentService {
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
@@ -69,28 +86,35 @@ class BancontactProviderService extends PaymentService {
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
return await this.stripeProviderService_
.withTransaction(this.manager_)
.createCustomer(customer)
}
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
* @param {Cart} cart - cart to create a payment for
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const region = await this.regionService_
.withTransaction(this.manager_)
.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const amount = await this.totalsService_
.withTransaction(this.manager_)
.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
description: cart?.context?.payment_description ?? this.options_?.payment_description,
description:
cart?.context?.payment_description ?? this.options?.payment_description,
currency: currency_code,
payment_method_types: ["bancontact"],
capture_method: "automatic",
@@ -98,7 +122,9 @@ class BancontactProviderService extends PaymentService {
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
const customer = await this.customerService_
.withTransaction(this.manager_)
.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
@@ -118,70 +144,69 @@ class BancontactProviderService extends PaymentService {
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
return await this.stripe_.paymentIntents.create(intentRequest)
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentData} paymentData - the data of the payment to retrieve
* @return {Promise<Data>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
async retrievePayment(paymentData) {
return await this.stripeProviderService_.retrievePayment(paymentData)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
* @return {Promise<PaymentData>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
async getPaymentData(paymentSession) {
return await this.stripeProviderService_.getPaymentData(paymentSession)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {PaymentSession} paymentSession - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
* @return {Promise<{data: PaymentSessionData; status: PaymentSessionStatus}>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
async authorizePayment(paymentSession, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
paymentSession,
context
)
}
async updatePaymentData(sessionData, update) {
async updatePaymentData(paymentSessionData, data) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
paymentSessionData,
data
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
* @param {PaymentSessionData} paymentSessionData - payment session data.
* @param {Cart} cart
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
async updatePayment(paymentSessionData, cart) {
try {
const stripeId = cart.customer?.metadata?.stripe_id || undefined
if (stripeId !== sessionData.customer) {
if (stripeId !== paymentSessionData.customer) {
return this.createPayment(cart)
} else {
if (cart.total && sessionData.amount === Math.round(cart.total)) {
if (
cart.total &&
paymentSessionData.amount === Math.round(cart.total)
) {
return sessionData
}
return this.stripe_.paymentIntents.update(sessionData.id, {
return this.stripe_.paymentIntents.update(paymentSessionData.id, {
amount: Math.round(cart.total),
})
}
@@ -190,15 +215,15 @@ class BancontactProviderService extends PaymentService {
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
async deletePayment(paymentSession) {
return await this.stripeProviderService_.deletePayment(paymentSession)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
* @return {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
@@ -209,8 +234,8 @@ class BancontactProviderService extends PaymentService {
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
@@ -218,21 +243,21 @@ class BancontactProviderService extends PaymentService {
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
* @param {Payment} payment - payment method data from cart
* @param {number} refundAmount - amount to refund
* @return {Promise<PaymentData>} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
async refundPayment(payment, refundAmount) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
refundAmount
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)

View File

@@ -1,15 +1,29 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
import { AbstractPaymentService, PaymentSessionStatus } from "@medusajs/medusa"
class BlikProviderService extends PaymentService {
class BlikProviderService extends AbstractPaymentService {
static identifier = "stripe-blik"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
) {
super()
super(
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
)
/**
* Required Stripe options:
@@ -36,22 +50,24 @@ class BlikProviderService extends PaymentService {
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
this.manager_ = manager
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
* @param {PaymentSessionData} paymentSessionData - payment method data from cart
* @return {Promise<PaymentSessionStatus>} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
async getStatus(paymentSessionData) {
return await this.stripeProviderService_.getStatus(paymentSessionData)
}
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
* @return {Promise<Data[]>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
@@ -60,7 +76,7 @@ class BlikProviderService extends PaymentService {
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
@@ -69,24 +85,30 @@ class BlikProviderService extends PaymentService {
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
return await this.stripeProviderService_
.withTransaction(this.manager_)
.createCustomer(customer)
}
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
* @param {Cart} cart - cart to create a payment for
* @returns {PaymentSessionData} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const region = await this.regionService_
.withTransaction(this.manager_)
.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const amount = await this.totalsService_
.withTransaction(this.manager_)
.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
@@ -97,7 +119,9 @@ class BlikProviderService extends PaymentService {
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
const customer = await this.customerService_
.withTransaction(this.manager_)
.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
@@ -117,70 +141,69 @@ class BlikProviderService extends PaymentService {
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
return await this.stripe_.paymentIntents.create(intentRequest)
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentData} paymentData - the data of the payment to retrieve
* @return {Promise<Data>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
async retrievePayment(paymentData) {
return await this.stripeProviderService_.retrievePayment(paymentData)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
* @return {Promise<PaymentData>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
async getPaymentData(paymentSession) {
return await this.stripeProviderService_.getPaymentData(paymentSession)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {PaymentSession} paymentSession - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
* @return {Promise<{data: PaymentSessionData; status: PaymentSessionStatus}>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
async authorizePayment(paymentSession, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
paymentSession,
context
)
}
async updatePaymentData(sessionData, update) {
async updatePaymentData(paymentSessionData, data) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
paymentSessionData,
data
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
* @param {PaymentSessionData} paymentSessionData - payment session data.
* @param {Cart} cart
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
async updatePayment(paymentSessionData, cart) {
try {
const stripeId = cart.customer?.metadata?.stripe_id || undefined
if (stripeId !== sessionData.customer) {
if (stripeId !== paymentSessionData.customer) {
return this.createPayment(cart)
} else {
if (cart.total && sessionData.amount === Math.round(cart.total)) {
if (
cart.total &&
paymentSessionData.amount === Math.round(cart.total)
) {
return sessionData
}
return this.stripe_.paymentIntents.update(sessionData.id, {
return this.stripe_.paymentIntents.update(paymentSessionData.id, {
amount: Math.round(cart.total),
})
}
@@ -189,15 +212,15 @@ class BlikProviderService extends PaymentService {
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
async deletePayment(paymentSession) {
return await this.stripeProviderService_.deletePayment(paymentSession)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
* @return {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
@@ -208,8 +231,8 @@ class BlikProviderService extends PaymentService {
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
@@ -217,21 +240,21 @@ class BlikProviderService extends PaymentService {
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
* @param {Payment} payment - payment method data from cart
* @param {number} refundAmount - amount to refund
* @return {Promise<PaymentData>} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
async refundPayment(payment, refundAmount) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
refundAmount
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)

View File

@@ -1,15 +1,29 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
import { AbstractPaymentService, PaymentSessionStatus } from "@medusajs/medusa"
class GiropayProviderService extends PaymentService {
class GiropayProviderService extends AbstractPaymentService {
static identifier = "stripe-giropay"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
) {
super()
super(
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
)
/**
* Required Stripe options:
@@ -36,22 +50,25 @@ class GiropayProviderService extends PaymentService {
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
/** @private @const {EntityManager} */
this.manager_ = manager
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
* @param {PaymentSessionData} paymentSessionData - payment method data from cart
* @return {Promise<PaymentSessionStatus>} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
async getStatus(paymentSessionData) {
return await this.stripeProviderService_.getStatus(paymentSessionData)
}
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
* @param {Customer} customer - customer to fetch saved cards for
* @return {Promise<Data[]>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
@@ -60,7 +77,7 @@ class GiropayProviderService extends PaymentService {
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
@@ -69,28 +86,35 @@ class GiropayProviderService extends PaymentService {
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
return await this.stripeProviderService_
.withTransaction(this.manager_)
.createCustomer(customer)
}
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
* @param {Cart} cart - cart to create a payment for
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const region = await this.regionService_
.withTransaction(this.manager_)
.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const amount = await this.totalsService_
.withTransaction(this.manager_)
.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
description: cart?.context?.payment_description ?? this.options_?.payment_description,
description:
cart?.context?.payment_description ?? this.options?.payment_description,
currency: currency_code,
payment_method_types: ["giropay"],
capture_method: "automatic",
@@ -98,7 +122,9 @@ class GiropayProviderService extends PaymentService {
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
const customer = await this.customerService_
.withTransaction(this.manager_)
.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
@@ -118,70 +144,69 @@ class GiropayProviderService extends PaymentService {
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
return await this.stripe_.paymentIntents.create(intentRequest)
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentData} paymentData - the data of the payment to retrieve
* @return {Promise<Data>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
async retrievePayment(paymentData) {
return await this.stripeProviderService_.retrievePayment(paymentData)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
* @return {Promise<PaymentData>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
async getPaymentData(paymentSession) {
return await this.stripeProviderService_.getPaymentData(paymentSession)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
* @param {PaymentSession} paymentSession - payment session data
* @param {Data} context - properties relevant to current context
* @return {Promise<{data: PaymentSessionData; status: PaymentSessionStatus}>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
async authorizePayment(paymentSession, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
paymentSession,
context
)
}
async updatePaymentData(sessionData, update) {
async updatePaymentData(paymentSessionData, data) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
paymentSessionData,
data
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
* @param {PaymentSessionData} paymentSessionData - payment session data.
* @param {Cart} cart
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
async updatePayment(paymentSessionData, cart) {
try {
const stripeId = cart.customer?.metadata?.stripe_id || undefined
if (stripeId !== sessionData.customer) {
if (stripeId !== paymentSessionData.customer) {
return this.createPayment(cart)
} else {
if (cart.total && sessionData.amount === Math.round(cart.total)) {
return sessionData
if (
cart.total &&
paymentSessionData.amount === Math.round(cart.total)
) {
return paymentSessionData
}
return this.stripe_.paymentIntents.update(sessionData.id, {
return this.stripe_.paymentIntents.update(paymentSessionData.id, {
amount: Math.round(cart.total),
})
}
@@ -190,15 +215,15 @@ class GiropayProviderService extends PaymentService {
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
async deletePayment(paymentSession) {
return await this.stripeProviderService_.deletePayment(paymentSession)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
* @return {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
@@ -209,8 +234,8 @@ class GiropayProviderService extends PaymentService {
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
@@ -218,21 +243,21 @@ class GiropayProviderService extends PaymentService {
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
* @param {Payment} payment - payment method data from cart
* @param {number} refundAmount - amount to refund
* @return {Promise<PaymentData>} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
async refundPayment(payment, refundAmount) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
refundAmount
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)

View File

@@ -1,4 +1,3 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
@@ -6,10 +5,25 @@ class IdealProviderService extends PaymentService {
static identifier = "stripe-ideal"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
) {
super()
super(
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
)
/**
* Required Stripe options:
@@ -36,13 +50,15 @@ class IdealProviderService extends PaymentService {
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
this.manager_ = manager
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
* @param {PaymentSessionData} paymentSessionData - payment method data from cart
* @return {Promise<PaymentSessionStatus>} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
@@ -51,7 +67,7 @@ class IdealProviderService extends PaymentService {
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
* @return {Promise<Data[]>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
@@ -60,7 +76,7 @@ class IdealProviderService extends PaymentService {
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
@@ -69,28 +85,36 @@ class IdealProviderService extends PaymentService {
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
return await this.stripeProviderService_
.withTransaction(this.manager_)
.createCustomer(customer)
}
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
* @param {Cart} cart - cart to create a payment for
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const region = await this.regionService_
.withTransaction(this.manager_)
.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const amount = await this.totalsService_
.withTransaction(this.manager_)
.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
description: cart?.context?.payment_description ?? this.options_?.payment_description,
description:
cart?.context?.payment_description ??
this.options_?.payment_description,
currency: currency_code,
payment_method_types: ["ideal"],
capture_method: "automatic",
@@ -98,7 +122,9 @@ class IdealProviderService extends PaymentService {
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
const customer = await this.customerService_
.withTransaction(this.manager_)
.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
@@ -118,57 +144,53 @@ class IdealProviderService extends PaymentService {
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
return await this.stripe_.paymentIntents.create(intentRequest)
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentData} paymentData - the data of the payment to retrieve
* @return {Promise<Data>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
async retrievePayment(paymentData) {
return await this.stripeProviderService_.retrievePayment(paymentData)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
* @return {Promise<PaymentData>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
async getPaymentData(paymentSession) {
return await this.stripeProviderService_.getPaymentData(paymentSession)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {PaymentSession} paymentSession - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
* @return {Promise<{data: PaymentSessionData; status: PaymentSessionStatus}>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
async authorizePayment(paymentSession, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
paymentSession,
context
)
}
async updatePaymentData(sessionData, update) {
async updatePaymentData(paymentSessionData, data) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
paymentSessionData,
data
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
* @param {PaymentSessionData} paymentSessionData - payment session data.
* @param {Cart} cart
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
try {
@@ -190,15 +212,15 @@ class IdealProviderService extends PaymentService {
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
async deletePayment(paymentSession) {
return await this.stripeProviderService_.deletePayment(paymentSession)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
* @return {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
@@ -209,8 +231,8 @@ class IdealProviderService extends PaymentService {
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
@@ -218,21 +240,21 @@ class IdealProviderService extends PaymentService {
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
* @param {Payment} payment - payment method data from cart
* @param {number} refundAmount - amount to refund
* @return {Promise<PaymentData>} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
async refundPayment(payment, refundAmount) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
refundAmount
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)

View File

@@ -1,12 +1,18 @@
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
import { PaymentSessionStatus } from '@medusajs/medusa/dist'
import {
AbstractPaymentService,
PaymentSessionData,
PaymentSessionStatus,
} from "@medusajs/medusa"
class StripeProviderService extends PaymentService {
class StripeProviderService extends AbstractPaymentService {
static identifier = "stripe"
constructor({ customerService, totalsService, regionService }, options) {
super()
constructor(
{ customerService, totalsService, regionService, manager },
options
) {
super({ customerService, totalsService, regionService, manager }, options)
/**
* Required Stripe options:
@@ -30,13 +36,16 @@ class StripeProviderService extends PaymentService {
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
/** @private @const {EntityManager} */
this.manager_ = manager
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
* Get payment session status
* statuses.
* @param {PaymentSessionData} paymentData - the data stored with the payment session
* @return {Promise<PaymentSessionStatus>} the status of the order
*/
async getStatus(paymentData) {
const { id } = paymentData
@@ -61,8 +70,8 @@ class StripeProviderService extends PaymentService {
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
* @param {Customer} customer - customer to fetch saved cards for
* @return {Promise<Data[]>} saved payments methods
*/
async retrieveSavedMethods(customer) {
if (customer.metadata && customer.metadata.stripe_id) {
@@ -101,9 +110,11 @@ class StripeProviderService extends PaymentService {
})
if (customer.id) {
await this.customerService_.update(customer.id, {
metadata: { stripe_id: stripeCustomer.id },
})
await this.customerService_
.withTransaction(this.manager_)
.update(customer.id, {
metadata: { stripe_id: stripeCustomer.id },
})
}
return stripeCustomer
@@ -115,17 +126,23 @@ class StripeProviderService extends PaymentService {
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
* @param {Cart} cart - cart to create a payment for
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const { currency_code } = await this.regionService_.retrieve(region_id)
const { currency_code } = await this.regionService_
.withTransaction(this.manager_)
.retrieve(region_id)
const amount = await this.totalsService_.getTotal(cart)
const amount = await this.totalsService_
.withTransaction(this.manager_)
.getTotal(cart)
const intentRequest = {
description: cart?.context?.payment_description ?? this.options_?.payment_description,
description:
cart?.context?.payment_description ??
this.options_?.payment_description,
amount: Math.round(amount),
currency: currency_code,
setup_future_usage: "on_session",
@@ -134,7 +151,9 @@ class StripeProviderService extends PaymentService {
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
const customer = await this.customerService_
.withTransaction(this.manager_)
.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
@@ -154,15 +173,13 @@ class StripeProviderService extends PaymentService {
intentRequest.customer = stripeCustomer.id
}
return await this.stripe_.paymentIntents.create(
intentRequest
)
return await this.stripe_.paymentIntents.create(intentRequest)
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentData} paymentData - the data of the payment to retrieve
* @return {Promise<Data>} Stripe payment intent
*/
async retrievePayment(data) {
try {
@@ -174,12 +191,12 @@ class StripeProviderService extends PaymentService {
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
* @return {Promise<PaymentData>} Stripe payment intent
*/
async getPaymentData(sessionData) {
async getPaymentData(paymentSession) {
try {
return this.stripe_.paymentIntents.retrieve(sessionData.data.id)
return this.stripe_.paymentIntents.retrieve(paymentSession.data.id)
} catch (error) {
throw error
}
@@ -188,15 +205,15 @@ class StripeProviderService extends PaymentService {
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
* @param {PaymentSession} paymentSession - payment session data
* @param {Data} context - properties relevant to current context
* @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
const stat = await this.getStatus(sessionData.data)
async authorizePayment(paymentSession, context = {}) {
const stat = await this.getStatus(paymentSession.data)
try {
return { data: sessionData.data, status: stat }
return { data: paymentSession.data, status: stat }
} catch (error) {
throw error
}
@@ -214,9 +231,9 @@ class StripeProviderService extends PaymentService {
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
* @param {PaymentSessionData} paymentSessionData - payment session data.
* @param {Cart} cart
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
try {
@@ -270,8 +287,8 @@ class StripeProviderService extends PaymentService {
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} Stripe payment intent
*/
async capturePayment(payment) {
const { id } = payment.data
@@ -290,9 +307,9 @@ class StripeProviderService extends PaymentService {
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
* @param {Payment} payment - payment method data from cart
* @param {number} refundAmount - amount to refund
* @return {Promise<PaymentData>} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
const { id } = payment.data
@@ -310,8 +327,8 @@ class StripeProviderService extends PaymentService {
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} canceled payment intent
*/
async cancelPayment(payment) {
const { id } = payment.data

View File

@@ -1,15 +1,29 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
import { AbstractPaymentService, PaymentSessionStatus } from "@medusajs/medusa"
class Przelewy24ProviderService extends PaymentService {
class Przelewy24ProviderService extends AbstractPaymentService {
static identifier = "stripe-przelewy24"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
) {
super()
super(
{
stripeProviderService,
customerService,
totalsService,
regionService,
manager,
},
options
)
/**
* Required Stripe options:
@@ -36,13 +50,15 @@ class Przelewy24ProviderService extends PaymentService {
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
this.manager_ = manager
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
* @param {PaymentSessionData} paymentSessionData - payment method data from cart
* @return {Promise<PaymentSessionStatus>} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
@@ -51,7 +67,7 @@ class Przelewy24ProviderService extends PaymentService {
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
* @return {Promise<Data[]>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
@@ -60,7 +76,7 @@ class Przelewy24ProviderService extends PaymentService {
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
@@ -69,10 +85,12 @@ class Przelewy24ProviderService extends PaymentService {
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
* @return {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
return await this.stripeProviderService_
.withTransaction(this.manager_)
.createCustomer(customer)
}
/**
@@ -83,10 +101,14 @@ class Przelewy24ProviderService extends PaymentService {
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const region = await this.regionService_
.withTransaction(this.manager_)
.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const amount = await this.totalsService_
.withTransaction(this.manager_)
.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
@@ -97,7 +119,9 @@ class Przelewy24ProviderService extends PaymentService {
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
const customer = await this.customerService_
.withTransaction(this.manager_)
.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
@@ -117,57 +141,53 @@ class Przelewy24ProviderService extends PaymentService {
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
return await this.stripe_.paymentIntents.create(intentRequest)
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentData} paymentData - the data of the payment to retrieve
* @return {Promise<Data>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
async retrievePayment(paymentData) {
return await this.stripeProviderService_.retrievePayment(paymentData)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
* @return {Promise<PaymentData>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
async getPaymentData(paymentSession) {
return await this.stripeProviderService_.getPaymentData(paymentSession)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {PaymentSession} paymentSession - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
* @return {Promise<{data: PaymentSessionData; status: PaymentSessionStatus}>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
async authorizePayment(paymentSession, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
paymentSession,
context
)
}
async updatePaymentData(sessionData, update) {
async updatePaymentData(paymentSessionData, data) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
paymentSessionData,
data
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
* @param {PaymentSessionData} paymentSessionData - payment session data.
* @param {Cart} cart
* @return {Promise<PaymentSessionData>} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
try {
@@ -189,15 +209,15 @@ class Przelewy24ProviderService extends PaymentService {
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
async deletePayment(paymentSession) {
return await this.stripeProviderService_.deletePayment(paymentSession)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
* @return {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
@@ -208,8 +228,8 @@ class Przelewy24ProviderService extends PaymentService {
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
@@ -217,21 +237,21 @@ class Przelewy24ProviderService extends PaymentService {
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
* @param {Payment} payment - payment method data from cart
* @param {number} refundAmount - amount to refund
* @return {Promise<PaymentData>} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
async refundPayment(payment, refundAmount) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
refundAmount
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
* @param {Payment} payment - payment method data from cart
* @return {Promise<PaymentData>} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)

View File

@@ -1,14 +1,14 @@
class CartSubscriber {
constructor({
manager,
cartService,
customerService,
paymentProviderService,
eventBusService,
}) {
this.cartService_ = cartService
this.customerService_ = customerService
this.paymentProviderService_ = paymentProviderService
this.eventBus_ = eventBusService
this.manager_ = manager
this.eventBus_.subscribe("cart.customer_updated", async (cart) => {
await this.onCustomerUpdated(cart)
@@ -16,38 +16,44 @@ class CartSubscriber {
}
async onCustomerUpdated(cartId) {
const cart = await this.cartService_.retrieve(cartId, {
select: [
"subtotal",
"tax_total",
"shipping_total",
"discount_total",
"total",
],
relations: [
"items",
"billing_address",
"shipping_address",
"region",
"region.payment_providers",
"items",
"items.adjustments",
"payment_sessions",
"customer",
],
await this.manager_.transaction(async (transactionManager) => {
const cart = await this.cartService_
.withTransaction(transactionManager)
.retrieve(cartId, {
select: [
"subtotal",
"tax_total",
"shipping_total",
"discount_total",
"gift_card_total",
"total",
],
relations: [
"billing_address",
"shipping_address",
"region",
"region.payment_providers",
"items",
"items.adjustments",
"payment_sessions",
"customer",
],
})
if (!cart.payment_sessions?.length) {
return Promise.resolve()
}
const session = cart.payment_sessions.find(
(ps) => ps.provider_id === "stripe"
)
if (session) {
return await this.paymentProviderService_
.withTransaction(transactionManager)
.updateSession(session, cart)
}
})
if (!cart.payment_sessions?.length) {
return Promise.resolve()
}
const session = cart.payment_sessions.find(
(ps) => ps.provider_id === "stripe"
)
if (session) {
return await this.paymentProviderService_.updateSession(session, cart)
}
}
}

View File

@@ -12,8 +12,7 @@ export type Data = Record<string, unknown>
export type PaymentData = Data
export type PaymentSessionData = Data
export interface PaymentService<T extends TransactionBaseService>
extends TransactionBaseService {
export interface PaymentService extends TransactionBaseService {
getIdentifier(): string
getPaymentData(paymentSession: PaymentSession): Promise<PaymentData>
@@ -50,9 +49,9 @@ export interface PaymentService<T extends TransactionBaseService>
getStatus(data: Data): Promise<PaymentSessionStatus>
}
export abstract class AbstractPaymentService<T extends TransactionBaseService>
export abstract class AbstractPaymentService
extends TransactionBaseService
implements PaymentService<T>
implements PaymentService
{
protected constructor(container: unknown, config?: Record<string, unknown>) {
super(container, config)

View File

@@ -1,6 +1,6 @@
import {
BaseNotificationService,
BaseFulfillmentService,
BaseNotificationService,
BasePaymentService,
} from "medusa-interfaces"
import { currencies } from "../utils/currencies"
@@ -82,7 +82,8 @@ export default async ({
const hasCountries = await countryRepo.findOne()
if (!hasCountries) {
for (const c of countries) {
const query = `INSERT INTO "country" ("iso_2", "iso_3", "num_code", "name", "display_name") VALUES ($1, $2, $3, $4, $5)`
const query = `INSERT INTO "country" ("iso_2", "iso_3", "num_code", "name", "display_name")
VALUES ($1, $2, $3, $4, $5)`
const iso2 = c.alpha2.toLowerCase()
const iso3 = c.alpha3.toLowerCase()
@@ -106,7 +107,8 @@ export default async ({
const hasCurrencies = await currencyRepo.findOne()
if (!hasCurrencies) {
for (const [, c] of Object.entries(currencies)) {
const query = `INSERT INTO "currency" ("code", "symbol", "symbol_native", "name") VALUES ($1, $2, $3, $4)`
const query = `INSERT INTO "currency" ("code", "symbol", "symbol_native", "name")
VALUES ($1, $2, $3, $4)`
const code = c.code.toLowerCase()
const sym = c.symbol
@@ -122,9 +124,11 @@ export default async ({
await storeService.withTransaction(manager).create()
const payProviders =
silentResolution<
(typeof BasePaymentService | AbstractPaymentService<never>)[]
>(container, "paymentProviders", logger) || []
silentResolution<(typeof BasePaymentService | AbstractPaymentService)[]>(
container,
"paymentProviders",
logger
) || []
const payIds = payProviders.map((p) => p.getIdentifier())
const pProviderService = container.resolve<PaymentProviderService>(

View File

@@ -1,9 +1,7 @@
import { isEmpty, isEqual } from "lodash"
import { MedusaError } from "medusa-core-utils"
import { DeepPartial, EntityManager, In } from "typeorm"
import { TransactionBaseService } from "../interfaces"
import { IPriceSelectionStrategy } from "../interfaces/price-selection-strategy"
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
import { IPriceSelectionStrategy, TransactionBaseService } from "../interfaces"
import {
Address,
Cart,
@@ -36,7 +34,6 @@ import CustomerService from "./customer"
import DiscountService from "./discount"
import EventBusService from "./event-bus"
import GiftCardService from "./gift-card"
import { SalesChannelService } from "./index"
import InventoryService from "./inventory"
import LineItemService from "./line-item"
import LineItemAdjustmentService from "./line-item-adjustment"
@@ -45,9 +42,11 @@ import ProductService from "./product"
import ProductVariantService from "./product-variant"
import RegionService from "./region"
import ShippingOptionService from "./shipping-option"
import StoreService from "./store"
import TaxProviderService from "./tax-provider"
import TotalsService from "./totals"
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
import StoreService from "./store"
import { SalesChannelService } from "./index"
type InjectedDependencies = {
manager: EntityManager

View File

@@ -26,7 +26,7 @@ type InjectedDependencies = {
refundRepository: typeof RefundRepository
} & {
[key in `${PaymentProviderKey}`]:
| AbstractPaymentService<never>
| AbstractPaymentService
| typeof BasePaymentService
}
@@ -275,11 +275,11 @@ export default class PaymentProviderService extends TransactionBaseService {
* @return {PaymentService} the payment provider
*/
retrieveProvider<
TProvider extends AbstractPaymentService<never> | typeof BasePaymentService
TProvider extends AbstractPaymentService | typeof BasePaymentService
>(
providerId: string
): TProvider extends AbstractPaymentService<never>
? AbstractPaymentService<never>
): TProvider extends AbstractPaymentService
? AbstractPaymentService
: typeof BasePaymentService {
try {
let provider