import { CartBaseController } from "./cart_base_controller"; /* * Al pagar lo que podamos, primero hay que crear una orden y luego * contactarse con la APIv2 para generar la variante con el precio que * queramos agregar. Agregamos la variante al carrito y lanzamos el * proceso de pago. */ export default class extends CartBaseController { static targets = ["form"]; static values = { variantId: Number, currency: String, price: Number, firstname: String, }; connect() { this.paymentMethodByCurrency = { ARS: "Spree::PaymentMethod::MercadoPago", USD: "Spree::PaymentMethod::Paypal", }; } store(event) { const target = event.currentTarget || event.target; this[`${target.dataset.name}Value`] = target.value; } set formDisable(disable) { this.formTarget.elements.forEach((x) => (x.disabled = disable)); } /* * Realiza todos los pasos: * * * Crear pedido * * Crear variante con el monto y moneda * * Agregar al pedido * * Agregar dirección al pedido * * Obtener métodos de envío * * Obtener métodos de pago * * Pagar * * Reenviar a confirmación * * Ejecutar el pago (si aplica) */ async pay(event = undefined) { if (event) { event.preventDefault(); event.stopPropagation(); } if (!this.formTarget.checkValidity()) { this.formTarget.classList.add("was-validated"); return; } this.formDisable = true; // Crear pedido. Todos los pedidos van a ser hechos desde // Argentina, no hay forma de cambiar esto. const orderToken = await this.tempCartCreate(); const quantity = 1; const include = "line_items"; const currency = this.currencyValue; const price = this.priceValue; const email = "noreply@sutty.nl"; const firstname = this.firstnameValue; const lastname = "-"; const address1 = "-"; const country_id = 250; // XXX: Internet const city = "-"; const phone = "11111111"; const zipcode = "1111"; const ship_address_attributes = { firstname, lastname, address1, city, country_id, zipcode, phone, }; const bill_address_attributes = ship_address_attributes; const confirmation_delivered = true; const custom_return_url = this.customReturnUrl(); let variant_id = this.variantIdValue; // Crear la variante const payWhatYouCanResponse = await this.spree.sutty.payWhatYouCan( { orderToken }, { variant_id, price, currency, quantity } ); variant_id = payWhatYouCanResponse.data.id; if (!variant_id) { this.formDisable = false; console.error("No se pudo generar la variante", { variant_id, price, currency, quantity, }); return; } // Configurar la moneda del pedido let response = await this.spree.sutty.updateOrder( { orderToken }, { currency, confirmation_delivered, custom_return_url } ); if (response.status > 299) { console.error(response); this.formDisable = false; return; } // Agregar al carrito response = await this.spree.cart.addItem( { orderToken }, { variant_id, quantity, include } ); if (response.isFail()) { this.handleFailure(response); this.formDisable = false; return; } // Actualizar la dirección response = await this.spree.checkout.orderUpdate( { orderToken }, { order: { email, ship_address_attributes, bill_address_attributes } } ); if (response.isFail()) { this.handleFailure(response); this.formDisable = false; return; } // Obtener los medios de envío response = await this.spree.checkout.shippingMethods( { orderToken }, { include: "shipping_rates" } ); if (response.isFail()) { this.handleFailure(response); this.formDisable = false; return; } // Elegir medio de envío response = await this.spree.checkout.orderUpdate( { orderToken }, { order: { shipments_attributes: [ { id: response.success().data[0].id, selected_shipping_rate_id: response .success() .included.filter((x) => x.type == "shipping_rate")[0].id, }, ], }, } ); // Elegir medio de pago response = await this.spree.checkout.paymentMethods({ orderToken }); if (response.isFail()) { this.handleFailure(response); this.formDisable = false; return; } const payment_method_id = response .success() .data.find( (x) => this.paymentMethodByCurrency[this.currencyValue] == x.attributes.type ).id; response = await this.spree.checkout.orderUpdate( { orderToken }, { order: { payments_attributes: [{ payment_method_id }] }, payment_source: { [payment_method_id]: { name: "Pepitx", month: 12, year: 2021, }, }, } ); if (response.isFail()) { this.handleFailure(response); this.formDisable = false; return; } response = await this.spree.checkout.complete({ orderToken }); if (response.isFail()) { this.handleFailure(response); this.formDisable = false; return; } // Reenviar al medio de pago const checkoutUrls = await this.spree.sutty.getCheckoutURL({ orderToken }); const redirectUrl = checkoutUrls.data[0]; Turbolinks.visit(redirectUrl); // Volver } async tempCartCreate() { const response = await this.spree.cart.create(); // If we fail here it's probably a server error, so we inform the // user. if (response.isFail()) { this.handleFailure(response); return; } return response.success().data.attributes.token; } // @return [String] customReturnUrl() { const url = new URL(window.location.href); url.searchParams.set("open", ""); return url.toString(); } }