@unchainedshop/plugins
Version:
Official plugin collection for the Unchained Engine with payment, delivery, and pricing adapters
88 lines (87 loc) • 3.63 kB
JavaScript
import { OrderPricingSheet, PaymentAdapter, PaymentDirector, PaymentError, } from '@unchainedshop/core';
import { createLogger } from '@unchainedshop/logger';
const logger = createLogger('unchained:paypal-checkout');
let checkoutNodeJssdk;
try {
checkoutNodeJssdk = await import('@paypal/checkout-server-sdk');
}
catch {
logger.warn("npm dependency '@paypal/checkout-server-sdk' is not installed, paypal adapter will not work");
}
const { PAYPAL_CLIENT_ID, PAYPAL_SECRET, PAYPAL_ENVIRONMENT = 'sandbox' } = process.env;
const environment = () => {
const clientId = PAYPAL_CLIENT_ID;
const clientSecret = PAYPAL_SECRET;
return PAYPAL_ENVIRONMENT !== 'live'
? new checkoutNodeJssdk.core.SandboxEnvironment(clientId, clientSecret)
: new checkoutNodeJssdk.core.LiveEnvironment(clientId, clientSecret);
};
const roundToDecimals = (number, decimals) => {
const num = Math.pow(10, decimals);
return Math.round(number * num) / num;
};
const PaypalCheckout = {
...PaymentAdapter,
key: 'shop.unchained.payment.paypal',
label: 'Paypal',
version: '1.0.1',
initialConfiguration: [],
typeSupported: (type) => {
return type === 'GENERIC';
},
actions: (config, context) => {
const adapter = {
...PaymentAdapter.actions(config, context),
configurationError: () => {
const publicCredentialsValid = PAYPAL_CLIENT_ID && PAYPAL_SECRET;
if (!publicCredentialsValid) {
return PaymentError.WRONG_CREDENTIALS;
}
return null;
},
isActive: () => {
if (adapter.configurationError() === null)
return true;
return false;
},
isPayLaterAllowed: () => {
return false;
},
sign: async () => {
return PAYPAL_CLIENT_ID || null;
},
charge: async ({ orderID }) => {
const { order } = context;
if (!order)
throw new Error('Order missing in payment context');
if (!orderID) {
throw new Error('You have to provide orderID in paymentContext');
}
try {
const request = new checkoutNodeJssdk.orders.OrdersGetRequest(orderID);
const client = new checkoutNodeJssdk.core.PayPalHttpClient(environment());
const paypalOrder = await client.execute(request);
const pricing = OrderPricingSheet({
calculation: order.calculation,
currencyCode: order.currencyCode,
});
const ourTotal = roundToDecimals(pricing.total({ useNetPrice: false }).amount / 100, 2);
const paypalTotal = roundToDecimals(paypalOrder.result.purchase_units[0].amount.value, 2);
if (ourTotal === paypalTotal) {
return order;
}
logger.warn('Missmatch PAYPAL ORDER', JSON.stringify(paypalOrder.result, null, 2));
logger.debug('OUR ORDER', order);
logger.debug('OUR PRICE', pricing);
throw new Error(`Payment mismatch`);
}
catch (e) {
logger.warn(e);
throw new Error(e.message, { cause: e });
}
},
};
return adapter;
},
};
PaymentDirector.registerAdapter(PaypalCheckout);