mirror of
https://gh.wpcy.net/https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2026-04-30 04:42:19 +08:00
341 lines
8.9 KiB
TypeScript
341 lines
8.9 KiB
TypeScript
/**
|
|
* External dependencies
|
|
*/
|
|
import {
|
|
WooCommerceApi,
|
|
RequestUtils,
|
|
Plugins,
|
|
WooCommerceUtils,
|
|
restLogin,
|
|
} from '@inpsyde/playwright-utils/build';
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import {
|
|
PayForOrder,
|
|
Checkout,
|
|
ClassicCheckout,
|
|
OrderReceived,
|
|
} from './frontend';
|
|
import {
|
|
subscriptionsPlugin,
|
|
wpDebuggingPlugin,
|
|
pcpPlugin,
|
|
ShopOrder,
|
|
} from '../resources';
|
|
import { getCustomerStorageStateName } from './helpers';
|
|
import urls from './urls';
|
|
|
|
export class Utils {
|
|
requestUtils: RequestUtils;
|
|
wooCommerceApi: WooCommerceApi;
|
|
visitorWooCommerceApi: WooCommerceApi;
|
|
wooCommerceUtils: WooCommerceUtils;
|
|
plugins: Plugins;
|
|
payForOrder: PayForOrder;
|
|
checkout: Checkout;
|
|
classicCheckout: ClassicCheckout;
|
|
orderReceived: OrderReceived;
|
|
|
|
constructor( {
|
|
requestUtils,
|
|
wooCommerceApi,
|
|
visitorWooCommerceApi,
|
|
wooCommerceUtils,
|
|
plugins,
|
|
payForOrder,
|
|
checkout,
|
|
classicCheckout,
|
|
orderReceived,
|
|
} ) {
|
|
this.requestUtils = requestUtils;
|
|
this.wooCommerceApi = wooCommerceApi;
|
|
this.visitorWooCommerceApi = visitorWooCommerceApi;
|
|
this.wooCommerceUtils = wooCommerceUtils;
|
|
this.plugins = plugins;
|
|
this.payForOrder = payForOrder;
|
|
this.checkout = checkout;
|
|
this.classicCheckout = classicCheckout;
|
|
this.orderReceived = orderReceived;
|
|
}
|
|
|
|
/**
|
|
* (Re)creates registered customer and refreshes his storage state.
|
|
* May be required for testing subscriptions/vaulting.
|
|
*
|
|
* @param customer
|
|
*/
|
|
restoreCustomer = async ( customer: WooCommerce.CreateCustomer ) => {
|
|
await this.wooCommerceUtils.deleteCustomer( customer );
|
|
if ( customer.username ) {
|
|
const user = await this.requestUtils.getUserByName(
|
|
customer.username
|
|
);
|
|
if ( user.length ) {
|
|
await this.requestUtils.deleteUser( user[ 0 ].id );
|
|
}
|
|
}
|
|
await this.wooCommerceUtils.createCustomer( customer );
|
|
const storageStateName = getCustomerStorageStateName( customer );
|
|
const storageStatePath = `${ process.env.STORAGE_STATE_PATH }/${ storageStateName }.json`;
|
|
await restLogin( {
|
|
baseURL: process.env.WP_BASE_URL,
|
|
httpCredentials: {
|
|
username: process.env.WP_BASIC_AUTH_USER,
|
|
password: process.env.WP_BASIC_AUTH_PASS,
|
|
},
|
|
storageStatePath,
|
|
user: {
|
|
username: customer.username,
|
|
password: customer.password,
|
|
},
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Pays for order created via API (dashboard order).
|
|
* May be used for testing refunds/vaulting/subscriptions.
|
|
*
|
|
* @param orderId
|
|
* @param orderKey
|
|
* @param order
|
|
*/
|
|
payForApiOrder = async (
|
|
orderId: number,
|
|
orderKey: string,
|
|
order: ShopOrder
|
|
) => {
|
|
await this.payForOrder.visit( orderId, orderKey );
|
|
await this.payForOrder.payPalUi.makePayment( {
|
|
merchant: order.merchant,
|
|
payment: order.payment,
|
|
} );
|
|
return await this.wooCommerceApi.getOrderByIdAndStatus(
|
|
orderId,
|
|
'processing'
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Fills cart with array of products.
|
|
*
|
|
* - Creates WooCommerce.CartProduct from WooCommerce.CreateProduct (or gets CartProduct from process.env).
|
|
* - Clears cart.
|
|
* - Adds provided products.
|
|
*
|
|
* @param products
|
|
*/
|
|
fillVisitorsCart = async ( products: WooCommerce.CreateProduct[] ) => {
|
|
const cartProducts = await this.wooCommerceUtils.createCartProducts(
|
|
products
|
|
);
|
|
await this.visitorWooCommerceApi.clearCart();
|
|
await this.visitorWooCommerceApi.addProductsToCart( cartProducts );
|
|
};
|
|
|
|
/**
|
|
* Pays for order on checkout page
|
|
*
|
|
* @param shopOrder
|
|
*/
|
|
completeOrderOnCheckout = async ( shopOrder: ShopOrder ) => {
|
|
await this.fillVisitorsCart( shopOrder.products );
|
|
|
|
await this.checkout.makeOrder( shopOrder );
|
|
const orderId = await this.orderReceived.getOrderNumber();
|
|
return await this.wooCommerceApi.getOrderByIdAndStatus(
|
|
orderId,
|
|
'processing'
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Pays for order on classic checkout page
|
|
*
|
|
* @param shopOrder
|
|
*/
|
|
completeOrderOnClassicCheckout = async ( shopOrder: ShopOrder ) => {
|
|
await this.fillVisitorsCart( shopOrder.products );
|
|
await this.classicCheckout.makeOrder( shopOrder );
|
|
const orderId = await this.orderReceived.getOrderNumber();
|
|
return await this.wooCommerceApi.getOrderByIdAndStatus(
|
|
orderId,
|
|
'processing'
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Checks if the product type is "subscription", connected to PayPal
|
|
*
|
|
* @param product
|
|
*/
|
|
isPayPalSubscriptionProduct = (
|
|
product: WooCommerce.CreateProduct
|
|
): boolean => {
|
|
if ( product.type !== 'subscription' ) {
|
|
return false;
|
|
}
|
|
|
|
const payPalMeta = product.meta_data.find(
|
|
( meta ) => meta.key === '_ppcp_enable_subscription_product'
|
|
);
|
|
|
|
if ( ! payPalMeta ) {
|
|
return false;
|
|
}
|
|
|
|
return payPalMeta.value === 'yes';
|
|
};
|
|
|
|
/**
|
|
* Connects existing Subscription product to PayPal plan
|
|
*
|
|
* @param subscriptionId
|
|
*/
|
|
connectPayPalSubscriptionProduct = async ( subscriptionId: number ) => {
|
|
const url = urls.admin.post.edit + subscriptionId;
|
|
const wpnonce = await this.requestUtils.getPageNonce( url );
|
|
const wcsnonce = await this.requestUtils.getRegexMatchValueOnPage(
|
|
url,
|
|
/<input[^>]*id="_wcsnonce"[^>]*value="([^"]*)"/
|
|
);
|
|
const formData = {
|
|
_wpnonce: wpnonce,
|
|
_wcsnonce: wcsnonce,
|
|
_ppcp_enable_subscription_product: 'yes',
|
|
_ppcp_subscription_plan_name: 'test',
|
|
post_ID: subscriptionId,
|
|
action: 'editpost',
|
|
};
|
|
const response = await this.requestUtils.submitPageForm(
|
|
url,
|
|
formData
|
|
);
|
|
return response.ok();
|
|
};
|
|
|
|
/**
|
|
* Configures store according to the data provided:
|
|
*
|
|
* wpDebugging: Is WP Debugging plugin activated
|
|
* subscription: Is WC Subscriptions plugin activated
|
|
* classicPages: Are classic cart and checkout pages set in WC > Settings > Advanced
|
|
* settings: WooCommerce settings by tabs (general, advanced, etc.)
|
|
* taxes: Tax settings in WC > Settings > General tab and Taxes > Tax rates tab
|
|
* customer: Registered customer to be created
|
|
*
|
|
* @param {Object} data see also /resources/woocommerce-config.ts
|
|
* @param data.wpDebugging
|
|
* @param data.subscription
|
|
* @param data.classicPages
|
|
* @param data.settings
|
|
* @param data.taxes
|
|
* @param data.taxes.options
|
|
* @param data.taxes.rates
|
|
* @param data.customer
|
|
* @param data.products
|
|
*/
|
|
configureStore = async ( data: {
|
|
wpDebugging?: boolean; // Is WP Debugging plugin activated
|
|
subscription?: boolean; // Is WC Subscriptions plugin activated
|
|
classicPages?: boolean; // Are classic cart and checkout pages set in WC > Settings > Advanced
|
|
settings?: WooCommerce.Settings; // WooCommerce settings by tabs (general, advanced, etc.)
|
|
taxes?: {
|
|
options: WooCommerce.Settings; // Tax settings in WC > Settings > General tab
|
|
rates: WooCommerce.CreateTax[]; // Tax rates to be active in WC > Settings > Taxes > Tax rates tab
|
|
};
|
|
customer?: WooCommerce.CreateCustomer; // Registered customer to be created
|
|
products?: WooCommerce.CreateProduct[]; // Products to be created if not existing
|
|
} ) => {
|
|
const {
|
|
wpDebugging,
|
|
subscription,
|
|
classicPages,
|
|
settings,
|
|
taxes,
|
|
customer,
|
|
products,
|
|
} = data;
|
|
|
|
if ( subscription === true ) {
|
|
await this.requestUtils.activatePlugin( subscriptionsPlugin.slug );
|
|
}
|
|
|
|
if ( subscription === false ) {
|
|
await this.requestUtils.deactivatePlugin(
|
|
subscriptionsPlugin.slug
|
|
);
|
|
}
|
|
|
|
if ( wpDebugging === true ) {
|
|
await this.requestUtils.activatePlugin( wpDebuggingPlugin.slug );
|
|
}
|
|
|
|
if ( wpDebugging === false ) {
|
|
await this.requestUtils.deactivatePlugin( wpDebuggingPlugin.slug );
|
|
}
|
|
|
|
if ( classicPages === true ) {
|
|
await this.wooCommerceUtils.activateClassicCartPage();
|
|
await this.wooCommerceUtils.activateClassicCheckoutPage();
|
|
}
|
|
|
|
if ( classicPages === false ) {
|
|
await this.wooCommerceUtils.activateBlockCartPage();
|
|
await this.wooCommerceUtils.activateBlockCheckoutPage();
|
|
}
|
|
|
|
if ( settings?.general ) {
|
|
await this.wooCommerceApi.updateGeneralSettings( settings.general );
|
|
}
|
|
|
|
if ( taxes ) {
|
|
await this.wooCommerceUtils.setTaxes( taxes );
|
|
}
|
|
|
|
if ( customer ) {
|
|
await this.restoreCustomer( customer );
|
|
}
|
|
|
|
if ( products ) {
|
|
// create test products
|
|
const cartItems = {};
|
|
await Promise.all(
|
|
products.map( async ( product ) => {
|
|
const createdProduct =
|
|
await this.wooCommerceUtils.createProduct( product );
|
|
if ( this.isPayPalSubscriptionProduct( product ) ) {
|
|
await this.connectPayPalSubscriptionProduct(
|
|
createdProduct.id
|
|
);
|
|
}
|
|
// Create cart items { id: 123 }
|
|
cartItems[ product.slug ] = { id: createdProduct.id };
|
|
} )
|
|
);
|
|
|
|
// Parse existing PRODUCTS, if any
|
|
const existingProducts = process.env.PRODUCTS
|
|
? JSON.parse( process.env.PRODUCTS )
|
|
: {};
|
|
|
|
// Merge created products with existing and store back as JSON string
|
|
process.env.PRODUCTS = JSON.stringify( {
|
|
...existingProducts,
|
|
...cartItems,
|
|
} );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Installs and activates PCP plugin
|
|
*/
|
|
installAndActivatePcp = async () => {
|
|
if (
|
|
! ( await this.requestUtils.isPluginInstalled( pcpPlugin.slug ) )
|
|
) {
|
|
await this.plugins.installPluginFromFile( pcpPlugin.zipFilePath );
|
|
}
|
|
await this.requestUtils.activatePlugin( pcpPlugin.slug );
|
|
};
|
|
}
|