feat: align avatax with plugin (#414)

* refactor: 🚚 OrderLineFragmentFragment -> OrderLineFragment

* refactor: 🚚 getLine... to getTaxBaseLine...

* refactor: ♻️ temporarily remove usage of getTaxBaseLineTaxCode

* feat:  add shipping as line to avatax-order-created

* feat:  add description to order-created lines

* feat:  add itemCode to avatax-order-created line

* feat:  add tests for avatax maps

* feat:  add basic discounts logic

* docs: 🔥 remove comment

* build: 👷 add changeset

* fix: 🐛 shipping amount
This commit is contained in:
Adrian Pilarczyk 2023-04-26 13:40:51 +02:00 committed by GitHub
parent aa27f9d6ef
commit 9eacc88b53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 426 additions and 50 deletions

View file

@ -0,0 +1,5 @@
---
"saleor-app-taxes": minor
---
Map new fields from Saleor to Avatax (e.g. discounts, itemCode, description).

View file

@ -1,4 +1,4 @@
fragment OrderLineFragment on OrderLine { fragment OrderLine on OrderLine {
productSku productSku
productName productName
quantity quantity
@ -42,12 +42,21 @@ fragment OrderCreatedSubscription on Order {
} }
} }
shippingPrice { shippingPrice {
gross {
amount
}
net { net {
amount amount
} }
} }
lines { lines {
...OrderLineFragment ...OrderLine
}
discounts {
id
amount {
amount
}
} }
} }
fragment OrderCreatedEventSubscription on Event { fragment OrderCreatedEventSubscription on Event {

View file

@ -1,4 +1,4 @@
fragment OrderLineFragment on OrderLine { fragment OrderLine on OrderLine {
productSku productSku
productName productName
quantity quantity
@ -46,7 +46,7 @@ fragment OrderFulfilledSubscription on Order {
value value
} }
lines { lines {
...OrderLineFragment ...OrderLine
} }
} }
fragment OrderFulfilledEventSubscription on Event { fragment OrderFulfilledEventSubscription on Event {

View file

@ -45,7 +45,7 @@ export class AvataxWebhookService implements ProviderWebhookService {
async createOrder(order: OrderCreatedSubscriptionFragment, channel: ChannelConfig) { async createOrder(order: OrderCreatedSubscriptionFragment, channel: ChannelConfig) {
this.logger.debug({ order, channel }, "createOrder called with:"); this.logger.debug({ order, channel }, "createOrder called with:");
const model = avataxOrderCreatedMaps.mapPayload(order, channel, this.config); const model = avataxOrderCreatedMaps.mapPayload({ order, channel, config: this.config });
this.logger.debug({ model }, "will call createTransaction with"); this.logger.debug({ model }, "will call createTransaction with");
const result = await this.client.createTransaction(model); const result = await this.client.createTransaction(model);
@ -56,7 +56,7 @@ export class AvataxWebhookService implements ProviderWebhookService {
async fulfillOrder(order: OrderFulfilledSubscriptionFragment, channel: ChannelConfig) { async fulfillOrder(order: OrderFulfilledSubscriptionFragment, channel: ChannelConfig) {
this.logger.debug({ order, channel }, "fulfillOrder called with:"); this.logger.debug({ order, channel }, "fulfillOrder called with:");
const args = avataxOrderFulfilledMaps.mapPayload(order, this.config); const args = avataxOrderFulfilledMaps.mapPayload({ order, config: this.config });
this.logger.debug({ args }, "will call commitTransaction with"); this.logger.debug({ args }, "will call commitTransaction with");
const result = await this.client.commitTransaction(args); const result = await this.client.commitTransaction(args);

View file

@ -4,12 +4,11 @@ import { TaxBaseFragment } from "../../../../generated/graphql";
import { DocumentType } from "avatax/lib/enums/DocumentType"; import { DocumentType } from "avatax/lib/enums/DocumentType";
import { ChannelConfig } from "../../channels-configuration/channels-config"; import { ChannelConfig } from "../../channels-configuration/channels-config";
import { taxLineResolver } from "../../taxes/tax-line-resolver"; import { numbers } from "../../taxes/numbers";
import { CalculateTaxesResponse } from "../../taxes/tax-provider-webhook"; import { CalculateTaxesResponse } from "../../taxes/tax-provider-webhook";
import { CreateTransactionArgs } from "../avatax-client"; import { CreateTransactionArgs } from "../avatax-client";
import { AvataxConfig } from "../avatax-config"; import { AvataxConfig } from "../avatax-config";
import { avataxAddressFactory } from "./address-factory"; import { avataxAddressFactory } from "./address-factory";
import { numbers } from "../../taxes/numbers";
/** /**
* * Shipping is a regular line item in Avatax * * Shipping is a regular line item in Avatax
@ -22,7 +21,7 @@ function mapLines(taxBase: TaxBaseFragment): LineItemModel[] {
amount: line.unitPrice.amount, amount: line.unitPrice.amount,
taxIncluded: line.chargeTaxes, taxIncluded: line.chargeTaxes,
// todo: get from tax code matcher // todo: get from tax code matcher
taxCode: taxLineResolver.getLineTaxCode(line), taxCode: "",
quantity: line.quantity, quantity: line.quantity,
})); }));

View file

@ -1,14 +1,190 @@
import { describe, it } from "vitest"; import { describe, expect, it } from "vitest";
import { OrderStatus } from "../../../../generated/graphql";
import {
CreateTransactionMapPayloadArgs,
avataxOrderCreatedMaps,
} from "./avatax-order-created-map";
describe.skip("avataxOrderCreatedMaps", () => { const MOCKED_ORDER: CreateTransactionMapPayloadArgs = {
order: {
id: "T3JkZXI6OTU4MDA5YjQtNDUxZC00NmQ1LThhMWUtMTRkMWRmYjFhNzI5",
created: "2023-04-11T11:03:09.304109+00:00",
status: OrderStatus.Unfulfilled,
user: {
id: "VXNlcjo5ZjY3ZjY0Zi1iZjY5LTQ5ZjYtYjQ4Zi1iZjY3ZjY0ZjY0ZjY=",
email: "tester@saleor.io",
},
channel: {
id: "Q2hhbm5lbDoy",
slug: "channel-pln",
},
shippingAddress: {
streetAddress1: "123 Palm Grove Ln",
streetAddress2: "",
city: "LOS ANGELES",
countryArea: "CA",
postalCode: "90002",
country: {
code: "US",
},
},
billingAddress: {
streetAddress1: "123 Palm Grove Ln",
streetAddress2: "",
city: "LOS ANGELES",
countryArea: "CA",
postalCode: "90002",
country: {
code: "US",
},
},
total: {
net: {
amount: 183.33,
},
tax: {
amount: 12.83,
},
currency: "USD",
},
shippingPrice: {
gross: {
amount: 48.33,
},
net: {
amount: 43.74,
},
},
lines: [
{
productSku: "328223581",
productName: "Monospace Tee",
quantity: 1,
unitPrice: {
net: {
amount: 90,
},
},
totalPrice: {
tax: {
amount: 8.55,
},
},
},
{
productSku: "328223580",
productName: "Polyspace Tee",
quantity: 1,
unitPrice: {
net: {
amount: 45,
},
},
totalPrice: {
tax: {
amount: 4.28,
},
},
},
],
discounts: [
{
amount: {
amount: 10,
},
id: "RGlzY291bnREaXNjb3VudDox",
},
{
amount: {
amount: 21.45,
},
id: "RGlzY291bnREaXNjb3VudDoy",
},
],
},
channel: {
providerInstanceId: "b8c29f49-7cae-4762-8458-e9a27eb83081",
enabled: false,
address: {
country: "US",
zip: "92093",
state: "CA",
city: "La Jolla",
street: "9500 Gilman Drive",
},
},
config: {
companyCode: "DEFAULT",
isAutocommit: true,
isSandbox: true,
name: "Avatax-1",
password: "user-password",
username: "user-name",
},
};
describe("avataxOrderCreatedMaps", () => {
describe.todo("mapResponse", () => { describe.todo("mapResponse", () => {
it.todo("calculation of fields"); it.todo("calculation of fields");
it.todo("formatting the fields"); it.todo("formatting the fields");
it.todo("rounding of numbers"); it.todo("rounding of numbers");
}); });
describe.todo("mapPayload", () => { describe("mapPayload", () => {
it("returns lines with discounted: true when there are discounts", () => {
const payload = avataxOrderCreatedMaps.mapPayload(MOCKED_ORDER);
const linesWithoutShipping = payload.model.lines.slice(0, -1);
const check = linesWithoutShipping.every((line) => line.discounted === true);
expect(check).toBeTruthy();
});
it.todo("calculation of fields"); it.todo("calculation of fields");
it.todo("formatting the fields"); it.todo("formatting the fields");
it.todo("rounding of numbers"); it.todo("rounding of numbers");
}); });
describe("mapLines", () => {
const lines = avataxOrderCreatedMaps.mapLines(MOCKED_ORDER.order);
it("returns the correct number of lines", () => {
expect(lines).toHaveLength(3);
});
it("includes shipping as a line", () => {
expect(lines).toContainEqual({
itemCode: avataxOrderCreatedMaps.consts.shippingItemCode,
quantity: 1,
amount: 48.33,
});
});
it("includes products as lines", () => {
const [first, second] = lines;
expect(first).toContain({
itemCode: "328223581",
description: "Monospace Tee",
quantity: 1,
amount: 90,
});
expect(second).toContain({
itemCode: "328223580",
description: "Polyspace Tee",
quantity: 1,
amount: 45,
});
});
});
describe("mapDiscounts", () => {
it("sums up all discounts", () => {
const discounts = avataxOrderCreatedMaps.mapDiscounts(MOCKED_ORDER.order.discounts);
expect(discounts).toEqual(31.45);
});
it("returns 0 if there are no discounts", () => {
const discounts = avataxOrderCreatedMaps.mapDiscounts([]);
expect(discounts).toEqual(0);
});
});
}); });

View file

@ -8,26 +8,64 @@ import { CreateTransactionArgs } from "../avatax-client";
import { AvataxConfig } from "../avatax-config"; import { AvataxConfig } from "../avatax-config";
import { avataxAddressFactory } from "./address-factory"; import { avataxAddressFactory } from "./address-factory";
const mapLines = (order: OrderCreatedSubscriptionFragment): LineItemModel[] => { /**
const productLines = order.lines.map((line) => ({ * * Shipping is a regular line item in Avatax
* https://developer.avalara.com/avatax/dev-guide/shipping-and-handling/taxability-of-shipping-charges/
*/
const SHIPPING_ITEM_CODE = "Shipping";
function mapLines(order: OrderCreatedSubscriptionFragment): LineItemModel[] {
const productLines: LineItemModel[] = order.lines.map((line) => ({
amount: line.unitPrice.net.amount, amount: line.unitPrice.net.amount,
quantity: line.quantity,
// todo: get from tax code matcher // todo: get from tax code matcher
taxCode: "", taxCode: "",
quantity: line.quantity,
description: line.productName,
itemCode: line.productSku ?? "",
discounted: order.discounts.length > 0,
})); }));
if (order.shippingPrice.net.amount !== 0) {
// * In Avatax, shipping is a regular line
const shippingLine: LineItemModel = {
amount: order.shippingPrice.gross.amount,
taxIncluded: true,
itemCode: SHIPPING_ITEM_CODE,
/**
* todo: add taxCode
* * Different shipping methods can have different tax codes.
* https://developer.avalara.com/ecommerce-integration-guide/sales-tax-badge/designing/non-standard-items/\
*/
quantity: 1,
};
return [...productLines, shippingLine];
}
return productLines; return productLines;
}
function mapDiscounts(discounts: OrderCreatedSubscriptionFragment["discounts"]): number {
return discounts.reduce((total, current) => total + Number(current.amount.amount), 0);
}
export type CreateTransactionMapPayloadArgs = {
order: OrderCreatedSubscriptionFragment;
channel: ChannelConfig;
config: AvataxConfig;
}; };
const mapPayload = ( const mapPayload = ({
order: OrderCreatedSubscriptionFragment, order,
channel: ChannelConfig, channel,
config: AvataxConfig config,
): CreateTransactionArgs => { }: CreateTransactionMapPayloadArgs): CreateTransactionArgs => {
return { return {
model: { model: {
type: DocumentType.SalesInvoice, type: DocumentType.SalesInvoice,
customerCode: order.user?.id ?? "", customerCode:
order.user?.id ??
"" /* In Saleor Avatax plugin, the customer code is 0. In Taxes App, we set it to the user id. */,
companyCode: config.companyCode, companyCode: config.companyCode,
// * commit: If true, the transaction will be committed immediately after it is created. See: https://developer.avalara.com/communications/dev-guide_rest_v2/commit-uncommit // * commit: If true, the transaction will be committed immediately after it is created. See: https://developer.avalara.com/communications/dev-guide_rest_v2/commit-uncommit
commit: config.isAutocommit, commit: config.isAutocommit,
@ -40,6 +78,7 @@ const mapPayload = (
email: order.user?.email ?? "", email: order.user?.email ?? "",
lines: mapLines(order), lines: mapLines(order),
date: new Date(order.created), date: new Date(order.created),
discount: mapDiscounts(order.discounts),
}, },
}; };
}; };
@ -53,4 +92,9 @@ const mapResponse = (response: TransactionModel): CreateOrderResponse => {
export const avataxOrderCreatedMaps = { export const avataxOrderCreatedMaps = {
mapPayload, mapPayload,
mapResponse, mapResponse,
mapLines,
mapDiscounts,
consts: {
shippingItemCode: SHIPPING_ITEM_CODE,
},
}; };

View file

@ -1,14 +1,127 @@
import { describe, it } from "vitest"; import { describe, expect, it } from "vitest";
import {
CommitTransactionMapPayloadArgs,
avataxOrderFulfilledMaps,
} from "./avatax-order-fulfilled-map";
import { OrderFulfilledSubscriptionFragment, OrderStatus } from "../../../../generated/graphql";
import { DocumentType } from "avatax/lib/enums/DocumentType";
describe.skip("avataxOrderFulfilledMaps", () => { const MOCKED_METADATA: OrderFulfilledSubscriptionFragment["privateMetadata"] = [
describe.todo("mapResponse", () => { {
it.todo("calculation of fields"); key: avataxOrderFulfilledMaps.providerOrderIdKey,
it.todo("formatting the fields"); value: "transaction-code",
it.todo("rounding of numbers"); },
];
const MOCKED_MAP_PAYLOAD_ARGS: CommitTransactionMapPayloadArgs = {
order: {
id: "T3JkZXI6OTU4MDA5YjQtNDUxZC00NmQ1LThhMWUtMTRkMWRmYjFhNzI5",
created: "2023-04-11T11:03:09.304109+00:00",
privateMetadata: MOCKED_METADATA,
channel: {
id: "Q2hhbm5lbDoy",
slug: "channel-pln",
},
shippingAddress: {
streetAddress1: "123 Palm Grove Ln",
streetAddress2: "",
city: "LOS ANGELES",
countryArea: "CA",
postalCode: "90002",
country: {
code: "US",
},
},
billingAddress: {
streetAddress1: "123 Palm Grove Ln",
streetAddress2: "",
city: "LOS ANGELES",
countryArea: "CA",
postalCode: "90002",
country: {
code: "US",
},
},
total: {
net: {
amount: 183.33,
},
tax: {
amount: 12.83,
},
},
shippingPrice: {
net: {
amount: 48.33,
},
},
lines: [
{
productSku: "328223581",
productName: "Monospace Tee",
quantity: 1,
unitPrice: {
net: {
amount: 90,
},
},
totalPrice: {
tax: {
amount: 8.55,
},
},
},
{
productSku: "328223580",
productName: "Polyspace Tee",
quantity: 1,
unitPrice: {
net: {
amount: 45,
},
},
totalPrice: {
tax: {
amount: 4.28,
},
},
},
],
},
config: {
companyCode: "DEFAULT",
isAutocommit: true,
isSandbox: true,
name: "Avatax-1",
password: "user-password",
username: "user-name",
},
};
describe("avataxOrderFulfilledMaps", () => {
describe("getTransactionCodeFromMetadata", () => {
it("should return transaction code", () => {
expect(avataxOrderFulfilledMaps.getTransactionCodeFromMetadata(MOCKED_METADATA)).toBe(
"transaction-code"
);
});
it("should throw error when transaction code not found", () => {
expect(() => avataxOrderFulfilledMaps.getTransactionCodeFromMetadata([])).toThrowError();
});
});
describe("mapPayload", () => {
it("should return mapped payload", () => {
const mappedPayload = avataxOrderFulfilledMaps.mapPayload(MOCKED_MAP_PAYLOAD_ARGS);
expect(mappedPayload).toEqual({
transactionCode: "transaction-code",
companyCode: "DEFAULT",
documentType: DocumentType.SalesInvoice,
model: {
commit: true,
},
});
}); });
describe.todo("mapPayload", () => {
it.todo("calculation of fields");
it.todo("formatting the fields");
it.todo("rounding of numbers");
}); });
}); });

View file

@ -1,9 +1,12 @@
import { DocumentType } from "avatax/lib/enums/DocumentType"; import { DocumentType } from "avatax/lib/enums/DocumentType";
import { OrderFulfilledSubscriptionFragment } from "../../../../generated/graphql"; import { OrderFulfilledSubscriptionFragment } from "../../../../generated/graphql";
import { PROVIDER_ORDER_ID_KEY } from "../../../pages/api/webhooks/order-created";
import { CommitTransactionArgs } from "../avatax-client"; import { CommitTransactionArgs } from "../avatax-client";
import { AvataxConfig } from "../avatax-config"; import { AvataxConfig } from "../avatax-config";
// * This is the key that we use to store the provider order id in the Saleor order metadata.
export const PROVIDER_ORDER_ID_KEY = "externalId";
function getTransactionCodeFromMetadata( function getTransactionCodeFromMetadata(
metadata: OrderFulfilledSubscriptionFragment["privateMetadata"] metadata: OrderFulfilledSubscriptionFragment["privateMetadata"]
) { ) {
@ -16,10 +19,12 @@ function getTransactionCodeFromMetadata(
return transactionCode.value; return transactionCode.value;
} }
const mapPayload = ( export type CommitTransactionMapPayloadArgs = {
order: OrderFulfilledSubscriptionFragment, order: OrderFulfilledSubscriptionFragment;
config: AvataxConfig config: AvataxConfig;
): CommitTransactionArgs => { };
const mapPayload = ({ order, config }: CommitTransactionMapPayloadArgs): CommitTransactionArgs => {
const transactionCode = getTransactionCodeFromMetadata(order.privateMetadata); const transactionCode = getTransactionCodeFromMetadata(order.privateMetadata);
return { return {
@ -34,4 +39,6 @@ const mapPayload = (
export const avataxOrderFulfilledMaps = { export const avataxOrderFulfilledMaps = {
mapPayload, mapPayload,
getTransactionCodeFromMetadata,
providerOrderIdKey: PROVIDER_ORDER_ID_KEY,
}; };

View file

@ -1,10 +1,10 @@
import { TaxBaseLineFragment } from "../../../generated/graphql"; import { TaxBaseLineFragment } from "../../../generated/graphql";
const getLineDiscount = ( function getTaxBaseLineDiscount(
line: TaxBaseLineFragment, line: TaxBaseLineFragment,
totalDiscount: number, totalDiscount: number,
allLinesTotal: number allLinesTotal: number
) => { ) {
if (totalDiscount === 0 || allLinesTotal === 0) { if (totalDiscount === 0 || allLinesTotal === 0) {
return 0; return 0;
} }
@ -15,9 +15,15 @@ const getLineDiscount = (
return lineTotalAmount; return lineTotalAmount;
} }
return discountAmount; return discountAmount;
}; }
const getLineTaxCode = (line: TaxBaseLineFragment): string => { /**
* * currently the CalculateTaxes subscription uses only the taxjar code (see: TaxBaseLine in TaxBase.graphql)
* todo: add ability to pass providers or get codes for all providers
* todo: add `getOrderLineTaxCode`
* todo: later, replace with tax code matcher
*/
function getTaxBaseLineTaxCode(line: TaxBaseLineFragment): string {
if (line.sourceLine.__typename === "OrderLine") { if (line.sourceLine.__typename === "OrderLine") {
return ( return (
line.sourceLine.variant?.product.metafield ?? line.sourceLine.variant?.product.metafield ??
@ -31,9 +37,9 @@ const getLineTaxCode = (line: TaxBaseLineFragment): string => {
line.sourceLine.productVariant.product.productType.metafield) ?? line.sourceLine.productVariant.product.productType.metafield) ??
"" ""
); );
}; }
export const taxLineResolver = { export const taxLineResolver = {
getLineDiscount, getTaxBaseLineDiscount,
getLineTaxCode, getTaxBaseLineTaxCode,
}; };

View file

@ -39,13 +39,17 @@ const prepareLinesWithDiscountPayload = (
const totalDiscount = discountsSum <= allLinesTotal ? discountsSum : allLinesTotal; const totalDiscount = discountsSum <= allLinesTotal ? discountsSum : allLinesTotal;
return lines.map((line) => { return lines.map((line) => {
const discountAmount = taxLineResolver.getLineDiscount(line, totalDiscount, allLinesTotal); const discountAmount = taxLineResolver.getTaxBaseLineDiscount(
const taxCode = taxLineResolver.getLineTaxCode(line); line,
totalDiscount,
allLinesTotal
);
return { return {
id: line.sourceLine.id, id: line.sourceLine.id,
chargeTaxes: line.chargeTaxes, chargeTaxes: line.chargeTaxes,
taxCode: taxCode, // todo: get from tax code matcher
taxCode: "",
quantity: line.quantity, quantity: line.quantity,
totalAmount: Number(line.totalPrice.amount), totalAmount: Number(line.totalPrice.amount),
unitAmount: Number(line.unitPrice.amount), unitAmount: Number(line.unitPrice.amount),

View file

@ -48,9 +48,12 @@ const MOCKED_ORDER: TaxJarOrderCreatedMapPayloadArgs = {
currency: "USD", currency: "USD",
}, },
shippingPrice: { shippingPrice: {
net: { gross: {
amount: 48.33, amount: 48.33,
}, },
net: {
amount: 43.74,
},
}, },
lines: [ lines: [
{ {
@ -84,6 +87,14 @@ const MOCKED_ORDER: TaxJarOrderCreatedMapPayloadArgs = {
}, },
}, },
], ],
discounts: [
{
amount: {
amount: 10,
},
id: "RGlzY291bnREaXNjb3VudDox",
},
],
}, },
channel: { channel: {
providerInstanceId: "b8c29f49-7cae-4762-8458-e9a27eb83081", providerInstanceId: "b8c29f49-7cae-4762-8458-e9a27eb83081",

View file

@ -14,6 +14,7 @@ function mapLines(lines: OrderCreatedSubscriptionFragment["lines"]): LineItem[]
// todo: add from tax code matcher // todo: add from tax code matcher
product_tax_code: "", product_tax_code: "",
sales_tax: line.totalPrice.tax.amount, sales_tax: line.totalPrice.tax.amount,
description: line.productName,
})); }));
} }

View file

@ -68,6 +68,7 @@ export default checkoutCalculateTaxesSyncWebhook.createHandler(async (req, res,
logger.info({ calculatedTaxes }, "Taxes calculated"); logger.info({ calculatedTaxes }, "Taxes calculated");
return webhookResponse.success(ctx.buildResponse(calculatedTaxes)); return webhookResponse.success(ctx.buildResponse(calculatedTaxes));
} catch (error) { } catch (error) {
logger.error({ error });
return webhookResponse.failureRetry("Error while calculating taxes"); return webhookResponse.failureRetry("Error while calculating taxes");
} }
}); });

View file

@ -68,6 +68,7 @@ export default orderCalculateTaxesSyncWebhook.createHandler(async (req, res, ctx
logger.info({ calculatedTaxes }, "Taxes calculated"); logger.info({ calculatedTaxes }, "Taxes calculated");
return webhookResponse.success(ctx.buildResponse(calculatedTaxes)); return webhookResponse.success(ctx.buildResponse(calculatedTaxes));
} catch (error) { } catch (error) {
logger.error({ error });
return webhookResponse.failureRetry("Error while calculating taxes"); return webhookResponse.failureRetry("Error while calculating taxes");
} }
}); });

View file

@ -13,6 +13,7 @@ import { getActiveTaxProvider } from "../../../modules/taxes/active-tax-provider
import { createClient } from "../../../lib/graphql"; import { createClient } from "../../../lib/graphql";
import { Client } from "urql"; import { Client } from "urql";
import { WebhookResponse } from "../../../modules/app/webhook-response"; import { WebhookResponse } from "../../../modules/app/webhook-response";
import { PROVIDER_ORDER_ID_KEY } from "../../../modules/avatax/maps/avatax-order-fulfilled-map";
export const config = { export const config = {
api: { api: {
@ -33,9 +34,6 @@ export const orderCreatedAsyncWebhook = new SaleorAsyncWebhook<OrderCreatedPaylo
webhookPath: "/api/webhooks/order-created", webhookPath: "/api/webhooks/order-created",
}); });
// * This is the key that we use to store the provider order id in the Saleor order metadata.
export const PROVIDER_ORDER_ID_KEY = "externalId";
/** /**
* We need to store the provider order id in the Saleor order metadata so that we can * We need to store the provider order id in the Saleor order metadata so that we can
* update the provider order when the Saleor order is fulfilled. * update the provider order when the Saleor order is fulfilled.
@ -105,6 +103,7 @@ export default orderCreatedAsyncWebhook.createHandler(async (req, res, ctx) => {
return webhookResponse.success(); return webhookResponse.success();
} catch (error) { } catch (error) {
logger.error({ error });
return webhookResponse.failureRetry("Error while creating order in tax provider"); return webhookResponse.failureRetry("Error while creating order in tax provider");
} }
}); });