mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-31 04:58:28 +08:00
229 lines
7.7 KiB
JavaScript
229 lines
7.7 KiB
JavaScript
import Product from '../Entity/Product';
|
|
import BookingProduct from "../Entity/BookingProduct";
|
|
import onApprove from '../OnApproveHandler/onApproveForContinue';
|
|
import {payerData} from "../Helper/PayerData";
|
|
import {PaymentMethods} from "../Helper/CheckoutMethodState";
|
|
import CartHelper from "../Helper/CartHelper";
|
|
import FormHelper from "../Helper/FormHelper";
|
|
|
|
class SingleProductActionHandler {
|
|
|
|
constructor(
|
|
config,
|
|
updateCart,
|
|
formElement,
|
|
errorHandler
|
|
) {
|
|
this.config = config;
|
|
this.updateCart = updateCart;
|
|
this.formElement = formElement;
|
|
this.errorHandler = errorHandler;
|
|
this.cartHelper = null;
|
|
}
|
|
|
|
subscriptionsConfiguration(subscription_plan) {
|
|
return {
|
|
createSubscription: (data, actions) => {
|
|
return actions.subscription.create({
|
|
'plan_id': subscription_plan
|
|
});
|
|
},
|
|
onApprove: (data, actions) => {
|
|
fetch(this.config.ajax.approve_subscription.endpoint, {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
body: JSON.stringify({
|
|
nonce: this.config.ajax.approve_subscription.nonce,
|
|
order_id: data.orderID,
|
|
subscription_id: data.subscriptionID
|
|
})
|
|
}).then((res)=>{
|
|
return res.json();
|
|
}).then(() => {
|
|
const products = this.getSubscriptionProducts();
|
|
|
|
fetch(this.config.ajax.change_cart.endpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
credentials: 'same-origin',
|
|
body: JSON.stringify({
|
|
nonce: this.config.ajax.change_cart.nonce,
|
|
products,
|
|
})
|
|
}).then((result) => {
|
|
return result.json();
|
|
}).then((result) => {
|
|
if (!result.success) {
|
|
console.log(result)
|
|
throw Error(result.data.message);
|
|
}
|
|
|
|
location.href = this.config.redirect;
|
|
})
|
|
});
|
|
},
|
|
onError: (err) => {
|
|
console.error(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
getSubscriptionProducts()
|
|
{
|
|
const id = document.querySelector('[name="add-to-cart"]').value;
|
|
return [new Product(id, 1, this.variations(), this.extraFields())];
|
|
}
|
|
|
|
configuration()
|
|
{
|
|
return {
|
|
createOrder: this.createOrder(),
|
|
onApprove: onApprove(this, this.errorHandler),
|
|
onError: (error) => {
|
|
this.refreshMiniCart();
|
|
|
|
if (this.isBookingProduct() && error.message) {
|
|
this.errorHandler.clear();
|
|
this.errorHandler.message(error.message);
|
|
return;
|
|
}
|
|
this.errorHandler.genericError();
|
|
},
|
|
onCancel: () => {
|
|
// Could be used for every product type,
|
|
// but only clean the cart for Booking products for now.
|
|
if (this.isBookingProduct()) {
|
|
this.cleanCart();
|
|
} else {
|
|
this.refreshMiniCart();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
getProducts()
|
|
{
|
|
if ( this.isBookingProduct() ) {
|
|
const id = document.querySelector('[name="add-to-cart"]').value;
|
|
return [new BookingProduct(id, 1, FormHelper.getPrefixedFields(this.formElement, "wc_bookings_field"), this.extraFields())];
|
|
} else if ( this.isGroupedProduct() ) {
|
|
const products = [];
|
|
this.formElement.querySelectorAll('input[type="number"]').forEach((element) => {
|
|
if (! element.value) {
|
|
return;
|
|
}
|
|
const elementName = element.getAttribute('name').match(/quantity\[([\d]*)\]/);
|
|
if (elementName.length !== 2) {
|
|
return;
|
|
}
|
|
const id = parseInt(elementName[1]);
|
|
const quantity = parseInt(element.value);
|
|
products.push(new Product(id, quantity, null, this.extraFields()));
|
|
})
|
|
return products;
|
|
} else {
|
|
const id = document.querySelector('[name="add-to-cart"]').value;
|
|
const qty = document.querySelector('[name="quantity"]').value;
|
|
const variations = this.variations();
|
|
return [new Product(id, qty, variations, this.extraFields())];
|
|
}
|
|
}
|
|
|
|
extraFields() {
|
|
return FormHelper.getFilteredFields(
|
|
this.formElement,
|
|
['add-to-cart', 'quantity', 'product_id', 'variation_id'],
|
|
['attribute_', 'wc_bookings_field']
|
|
);
|
|
}
|
|
|
|
createOrder()
|
|
{
|
|
this.cartHelper = null;
|
|
|
|
return (data, actions, options = {}) => {
|
|
this.errorHandler.clear();
|
|
|
|
const onResolve = (purchase_units) => {
|
|
this.cartHelper = (new CartHelper()).addFromPurchaseUnits(purchase_units);
|
|
|
|
const payer = payerData();
|
|
const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
|
|
this.config.bn_codes[this.config.context] : '';
|
|
return fetch(this.config.ajax.create_order.endpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
credentials: 'same-origin',
|
|
body: JSON.stringify({
|
|
nonce: this.config.ajax.create_order.nonce,
|
|
purchase_units,
|
|
payer,
|
|
bn_code:bnCode,
|
|
payment_method: PaymentMethods.PAYPAL,
|
|
funding_source: window.ppcpFundingSource,
|
|
context:this.config.context
|
|
})
|
|
}).then(function (res) {
|
|
return res.json();
|
|
}).then(function (data) {
|
|
if (!data.success) {
|
|
console.error(data);
|
|
throw Error(data.data.message);
|
|
}
|
|
return data.data.id;
|
|
});
|
|
};
|
|
|
|
return this.updateCart.update(onResolve, this.getProducts(), options.updateCartOptions || {});
|
|
};
|
|
}
|
|
|
|
variations()
|
|
{
|
|
if (! this.hasVariations()) {
|
|
return null;
|
|
}
|
|
return [...this.formElement.querySelectorAll("[name^='attribute_']")].map(
|
|
(element) => {
|
|
return {
|
|
value:element.value,
|
|
name:element.name
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
hasVariations()
|
|
{
|
|
return this.formElement.classList.contains('variations_form');
|
|
}
|
|
|
|
isGroupedProduct()
|
|
{
|
|
return this.formElement.classList.contains('grouped_form');
|
|
}
|
|
|
|
isBookingProduct()
|
|
{
|
|
// detection for "woocommerce-bookings" plugin
|
|
return !!this.formElement.querySelector('.wc-booking-product-id');
|
|
}
|
|
|
|
cleanCart() {
|
|
this.cartHelper.removeFromCart().then(() => {
|
|
this.refreshMiniCart();
|
|
}).catch(error => {
|
|
this.refreshMiniCart();
|
|
});
|
|
}
|
|
|
|
refreshMiniCart() {
|
|
jQuery(document.body).trigger('wc_fragment_refresh');
|
|
}
|
|
|
|
}
|
|
export default SingleProductActionHandler;
|