Test the checkout code; publish images only for releases (#5)
- src/checkout/ (PayPal order request, pricing, VAT) and src/logging/format.ts hold the checkout's pure code, moved out of PayPalApi, the product service and config without a behaviour change. - npm test runs node:test on the TypeScript sources (type stripping), with no dependencies: 21 tests, 13 pin today's output, 8 describe the correct behaviour for the known defects of libretech/mp#67 and are marked todo. - CI: the tests run in the image's base (node:22.14.0-alpine) for every pull request, push to main and release tag. The image is built for pull requests and built and published only for v* tags; main no longer publishes :main and :sha-* images. Refs libretech/mp#71 Co-authored-by: Michael Czechowski <mail@librete.ch>
This commit was merged in pull request #5.
This commit is contained in:
1 parent
901a3b385f
commit
9b0c6af8b7
15 files changed
+542
-96
No files matched your search
@@ -1,16 +1,7 @@
|
||||
import {
|
||||
Client,
|
||||
Environment,
|
||||
LogLevel,
|
||||
OrdersController,
|
||||
CheckoutPaymentIntent,
|
||||
OrderRequest,
|
||||
OrderApplicationContextShippingPreference,
|
||||
Item
|
||||
} from "@paypal/paypal-server-sdk";
|
||||
import { paypalClientId, paypalClientSecret, paypalEnvironment, vatIncludedDecimal, vatDecimalExcluded } from "../../config/constants";
|
||||
import { Client, Environment, LogLevel, OrdersController, OrderRequest } from "@paypal/paypal-server-sdk";
|
||||
import { paypalClientId, paypalClientSecret, paypalEnvironment } from "../../config/constants";
|
||||
import { Order } from "../../types";
|
||||
import { calculateTotalProductPrice } from "../api/product/services/product";
|
||||
import { buildPayPalOrderItems, buildPayPalOrderRequest } from "../checkout/paypal-order";
|
||||
|
||||
class PayPalApi {
|
||||
private readonly client: Client;
|
||||
@@ -34,76 +25,12 @@ class PayPalApi {
|
||||
}
|
||||
|
||||
async createSessionOrThrow(returnUrl: string, order: Order) {
|
||||
if (!order.total) throw new Error("Cart is empty or has no total");
|
||||
|
||||
const items = order.cart.map((item) => {
|
||||
const totalProductPrice = calculateTotalProductPrice(item.product);
|
||||
const amount = totalProductPrice / vatIncludedDecimal;
|
||||
const tax = totalProductPrice - amount;
|
||||
|
||||
return {
|
||||
name: item.product.name,
|
||||
unitAmount: {
|
||||
currencyCode: "EUR",
|
||||
value: amount.toFixed(2)
|
||||
},
|
||||
tax: {
|
||||
currencyCode: "EUR",
|
||||
value: tax.toFixed(2)
|
||||
},
|
||||
quantity: item.count.toString()
|
||||
} as Item;
|
||||
});
|
||||
// Outside the try block, so these throws are not logged here. The items are computed but not sent.
|
||||
buildPayPalOrderItems(order);
|
||||
|
||||
try {
|
||||
const collect = {
|
||||
body: {
|
||||
intent: CheckoutPaymentIntent.Capture,
|
||||
purchaseUnits: [
|
||||
{
|
||||
// items,
|
||||
referenceId: order.uuid,
|
||||
amount: {
|
||||
currencyCode: "EUR",
|
||||
value: order.total.toFixed(2),
|
||||
breakdown: {
|
||||
itemTotal: {
|
||||
currencyCode: "EUR",
|
||||
value: (Math.round((order.subtotal / vatIncludedDecimal) * 100) / 100).toFixed(2)
|
||||
},
|
||||
taxTotal: {
|
||||
currencyCode: "EUR",
|
||||
value: order.VAT.toFixed(2)
|
||||
},
|
||||
shipping: order.delivery
|
||||
? {
|
||||
currencyCode: "EUR",
|
||||
value: order.delivery.price.toFixed(2)
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
},
|
||||
shipping: {
|
||||
name: {
|
||||
fullName: order.deliveryAddress.split("\n")[0]
|
||||
},
|
||||
address: {
|
||||
addressLine1: order.deliveryAddress.split("\n")[1],
|
||||
postalCode: order.deliveryAddress.split("\n")[2].slice(0, 5),
|
||||
adminArea2: order.deliveryAddress.split("\n")[2].slice(6),
|
||||
countryCode: "DE"
|
||||
}
|
||||
},
|
||||
customId: order.uuid,
|
||||
invoiceId: order.invoiceNumber
|
||||
}
|
||||
],
|
||||
applicationContext: {
|
||||
returnUrl: returnUrl,
|
||||
cancelUrl: returnUrl,
|
||||
shippingPreference: OrderApplicationContextShippingPreference.SetProvidedAddress
|
||||
}
|
||||
} as OrderRequest,
|
||||
body: buildPayPalOrderRequest(returnUrl, order) as OrderRequest,
|
||||
prefer: "return=minimal"
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user