|
|
|
@@ -5,7 +5,10 @@ import { PaymentService } from "medusa-interfaces"
|
|
|
|
|
class KlarnaProviderService extends PaymentService {
|
|
|
|
|
static identifier = "klarna"
|
|
|
|
|
|
|
|
|
|
constructor({ shippingProfileService, totalsService, regionService }, options) {
|
|
|
|
|
constructor(
|
|
|
|
|
{ shippingProfileService, totalsService, regionService },
|
|
|
|
|
options
|
|
|
|
|
) {
|
|
|
|
|
super()
|
|
|
|
|
|
|
|
|
|
this.options_ = options
|
|
|
|
@@ -22,7 +25,8 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
|
|
|
|
|
this.klarnaOrderManagementUrl_ = "/ordermanagement/v1/orders"
|
|
|
|
|
|
|
|
|
|
this.backendUrl_ = process.env.BACKEND_URL || "https://58721b1f44d9.ngrok.io"
|
|
|
|
|
this.backendUrl_ =
|
|
|
|
|
process.env.BACKEND_URL || "https://2fe4e28015f5.ngrok.io"
|
|
|
|
|
|
|
|
|
|
this.totalsService_ = totalsService
|
|
|
|
|
|
|
|
|
@@ -77,7 +81,7 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
const quantity = item.content.quantity
|
|
|
|
|
const unit_price = item.content.unit_price * 100 * (taxRate + 1)
|
|
|
|
|
const total_discount_amount = itemDiscount * (taxRate + 1) * 100
|
|
|
|
|
const total_amount = unit_price * quantity - total_discount_amount
|
|
|
|
|
const total_amount = unit_price * quantity - total_discount_amount
|
|
|
|
|
const total_tax_amount = total_amount * (taxRate / (1 + taxRate))
|
|
|
|
|
|
|
|
|
|
order_lines.push({
|
|
|
|
@@ -98,6 +102,7 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
order_lines.push({
|
|
|
|
|
name: `${shippingMethod.name}`,
|
|
|
|
|
quantity: 1,
|
|
|
|
|
type: "shipping_fee",
|
|
|
|
|
unit_price: price * (1 + taxRate) * 100,
|
|
|
|
|
tax_rate: taxRate * 10000,
|
|
|
|
|
total_amount: price * (1 + taxRate) * 100,
|
|
|
|
@@ -141,8 +146,8 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
order.purchase_country = "SE"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order.order_amount = await this.totalsService_.getTotal(cart) * 100
|
|
|
|
|
order.order_tax_amount = await this.totalsService_.getTaxTotal(cart) * 100
|
|
|
|
|
order.order_amount = (await this.totalsService_.getTotal(cart)) * 100
|
|
|
|
|
order.order_tax_amount = (await this.totalsService_.getTaxTotal(cart)) * 100
|
|
|
|
|
// TODO: Check if currency matches ISO
|
|
|
|
|
order.purchase_currency = currency_code
|
|
|
|
|
|
|
|
|
@@ -155,45 +160,36 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
address_update: `${this.backendUrl_}/klarna/address`,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cart.shipping_address && cart.shipping_address.first_name) {
|
|
|
|
|
const shippingOptions = await this.shippingProfileService_.fetchCartOptions(
|
|
|
|
|
cart
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const shippingOptions = await this.shippingProfileService_.fetchCartOptions(cart)
|
|
|
|
|
// If the cart does not have shipping methods yet, preselect one from
|
|
|
|
|
// shipping_options and set the selected shipping method
|
|
|
|
|
if (cart.shipping_methods.length) {
|
|
|
|
|
const shipping_method = cart.shipping_methods[0]
|
|
|
|
|
order.selected_shipping_option = {
|
|
|
|
|
id: shipping_method._id,
|
|
|
|
|
name: shipping_method.name,
|
|
|
|
|
price: shipping_method.price * (1 + tax_rate) * 100,
|
|
|
|
|
tax_amount: shipping_method.price * tax_rate * 100,
|
|
|
|
|
tax_rate: tax_rate * 10000,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the cart does not have shipping methods yet, preselect one from
|
|
|
|
|
// shipping_options and set the selected shipping method
|
|
|
|
|
if (!cart.shipping_methods.length) {
|
|
|
|
|
const shipping_method = shippingOptions[0]
|
|
|
|
|
order.selected_shipping_option = {
|
|
|
|
|
id: shipping_method._id,
|
|
|
|
|
name: shipping_method.name,
|
|
|
|
|
price: shipping_method.price * (1 + tax_rate) * 100,
|
|
|
|
|
tax_amount: shipping_method.price * tax_rate * 100,
|
|
|
|
|
// Medusa tax rate of e.g. 0.25 (25%) needs to be 2500 in Klarna
|
|
|
|
|
// If the cart does have shipping methods, set the selected shipping method
|
|
|
|
|
|
|
|
|
|
order.shipping_options = shippingOptions.map((so) => ({
|
|
|
|
|
id: so._id,
|
|
|
|
|
name: so.name,
|
|
|
|
|
price: so.price * (1 + tax_rate) * 100,
|
|
|
|
|
tax_amount: so.price * tax_rate * 100,
|
|
|
|
|
tax_rate: tax_rate * 10000,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const shipping_method = cart.shipping_methods[0]
|
|
|
|
|
order.selected_shipping_option = {
|
|
|
|
|
id: shipping_method._id,
|
|
|
|
|
name: shipping_method.name,
|
|
|
|
|
price: shipping_method.price * (1 + tax_rate) * 100,
|
|
|
|
|
tax_amount: shipping_method.price * tax_rate * 100,
|
|
|
|
|
tax_rate: tax_rate * 10000,
|
|
|
|
|
}
|
|
|
|
|
preselected: shippingOptions.length === 1
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the cart does have shipping methods, set the selected shipping method
|
|
|
|
|
|
|
|
|
|
order.shipping_options = shippingOptions.map((so) => ({
|
|
|
|
|
id: so._id,
|
|
|
|
|
name: so.name,
|
|
|
|
|
price: so.price * (1 + tax_rate) * 100,
|
|
|
|
|
tax_amount: so.price * tax_rate * 100,
|
|
|
|
|
tax_rate: tax_rate * 10000,
|
|
|
|
|
preselected:
|
|
|
|
|
cart.shipping_methods[0] &&
|
|
|
|
|
`${cart.shipping_methods[0].provider_id}` === `${so.provider_id}`,
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
return order
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -204,11 +200,15 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
*/
|
|
|
|
|
async getStatus(paymentData) {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = paymentData
|
|
|
|
|
const order = await this.klarna_.get(`${this.klarnaOrderUrl_}/${id}`)
|
|
|
|
|
// TODO: Klarna docs does not provide a list of statues, so we need to
|
|
|
|
|
// play around our selves to figure it out
|
|
|
|
|
const { order_id } = paymentData
|
|
|
|
|
const { data: order } = await this.klarna_.get(
|
|
|
|
|
`${this.klarnaOrderUrl_}/${order_id}`
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
let status = "initial"
|
|
|
|
|
if (order.status === "checkout_complete") {
|
|
|
|
|
status = "authorized"
|
|
|
|
|
}
|
|
|
|
|
return status
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
@@ -224,7 +224,8 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
async createPayment(cart) {
|
|
|
|
|
try {
|
|
|
|
|
const order = await this.cartToKlarnaOrder(cart)
|
|
|
|
|
return this.klarna_.post(this.klarnaOrderUrl_, order)
|
|
|
|
|
return this.klarna_
|
|
|
|
|
.post(this.klarnaOrderUrl_, order)
|
|
|
|
|
.then(({ data }) => data)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
@@ -236,10 +237,10 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
* @param {string} cart - the cart to retrieve order for
|
|
|
|
|
* @returns {Object} Klarna order
|
|
|
|
|
*/
|
|
|
|
|
async retrievePayment(cart) {
|
|
|
|
|
async retrievePayment(paymentData) {
|
|
|
|
|
try {
|
|
|
|
|
const { data } = cart.payment_method
|
|
|
|
|
return this.klarna_.get(`${this.klarnaOrderUrl_}/${data.id}`)
|
|
|
|
|
return this.klarna_.get(`${this.klarnaOrderUrl_}/${paymentData.order_id}`)
|
|
|
|
|
.then(({ data }) => data)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
@@ -306,8 +307,9 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
*/
|
|
|
|
|
async updatePayment(paymentData, cart) {
|
|
|
|
|
try {
|
|
|
|
|
const order = await this.cartToKlarnaOrder(cart)
|
|
|
|
|
return this.klarna_.post(`${this.klarnaOrderUrl_}/${paymentData.order_id}`, order)
|
|
|
|
|
const order = await this.cartToKlarnaOrder(cart, true)
|
|
|
|
|
return this.klarna_
|
|
|
|
|
.post(`${this.klarnaOrderUrl_}/${paymentData.order_id}`, order)
|
|
|
|
|
.then(({ data }) => data)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
@@ -321,17 +323,19 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
*/
|
|
|
|
|
async capturePayment(paymentData) {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = paymentData
|
|
|
|
|
const orderData = await this.klarna_.get(`${this.klarnaOrderUrl_}/${id}`)
|
|
|
|
|
const { order_id } = paymentData
|
|
|
|
|
const orderData = await this.klarna_.get(
|
|
|
|
|
`${this.klarnaOrderUrl_}/${order_id}`
|
|
|
|
|
)
|
|
|
|
|
const { order_amount } = orderData.order
|
|
|
|
|
|
|
|
|
|
await this.klarna_.post(
|
|
|
|
|
`${this.klarnaOrderManagementUrl_}/${id}/captures`,
|
|
|
|
|
`${this.klarnaOrderManagementUrl_}/${order_id}/captures`,
|
|
|
|
|
{
|
|
|
|
|
captured_amount: order_amount,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
return id
|
|
|
|
|
return order_id
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
@@ -344,14 +348,14 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
*/
|
|
|
|
|
async refundPayment(paymentData, amount) {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = paymentData
|
|
|
|
|
const { order_id } = paymentData
|
|
|
|
|
await this.klarna_.post(
|
|
|
|
|
`${this.klarnaOrderManagementUrl_}/${id}/refunds`,
|
|
|
|
|
`${this.klarnaOrderManagementUrl_}/${order_id}/refunds`,
|
|
|
|
|
{
|
|
|
|
|
refunded_amount: amount,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
return id
|
|
|
|
|
return order_id
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
@@ -364,9 +368,9 @@ class KlarnaProviderService extends PaymentService {
|
|
|
|
|
*/
|
|
|
|
|
async cancelPayment(paymentData) {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = paymentData
|
|
|
|
|
await this.klarna_.post(`${this.klarnaOrderUrl_}/${id}/cancel`)
|
|
|
|
|
return id
|
|
|
|
|
const { order_id } = paymentData
|
|
|
|
|
await this.klarna_.post(`${this.klarnaOrderUrl_}/${order_id}/cancel`)
|
|
|
|
|
return order_id
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
|