module Spree module Mollie class OrderSerializer include ::Spree::Mollie::MoneyFormatter def self.serialize(total_amount, source, gateway_options, gateway_preferences) new(total_amount, source, gateway_options, gateway_preferences).serialize end def initialize(total_amount, source, gateway_options, gateway_preferences) @total_amount = total_amount @source = source @gateway_options = gateway_options @gateway_preferences = gateway_preferences @order = gateway_options[:order] end def serialize spree_routes = ::Spree::Core::Engine.routes.url_helpers currency = @gateway_options[:currency] order_number = @gateway_options[:order_id] order_params = { amount: { currency: currency, value: format_money(@total_amount) }, metadata: { order_number: order_number }, orderNumber: order_number, redirectUrl: spree_routes.mollie_validate_payment_mollie_url( order_number: order_number, host: @gateway_preferences[:hostname] ), webhookUrl: spree_routes.mollie_update_payment_status_mollie_url( order_number: order_number, host: @gateway_preferences[:hostname] ), locale: 'en_US', api_key: @gateway_preferences[:api_key] } if @gateway_options[:billing_address].present? order_params.merge! ({ billingAddress: serialize_address(@gateway_options[:billing_address]) }) end if @gateway_options[:shipping_address].present? order_params.merge! ({ shippingAddress: serialize_address(@gateway_options[:shipping_address]) }) end order_params.merge! ({ lines: prepare_line_items }) # User has already selected a payment method if @source.try(:payment_method_name).present? order_params.merge! ({ method: @source.payment_method_name }) end # User has selected an issuer (available for iDEAL payments) if @source.try(:issuer).present? order_params.merge! ({ payment: { issuer: @source.issuer } }) end order_params end private def prepare_line_items order_lines = [] @order.line_items.each do |line| order_lines << serialize_line_item(line) end order_lines << serialize_discounts if @order.has_order_adjustments? order_lines << serialize_shipping_costs if @order.shipping_discount.positive? order_lines << serialize_shipping_discounts end order_lines end def serialize_address(address) { streetAndNumber: address[:address1], city: address[:city], postalCode: address[:zip], country: address[:country], region: address[:state], givenName: address[:firstname], familyName: address[:lastname], email: @order.email } end def serialize_shipping_costs { type: 'shipping_fee', name: 'Shipping costs', quantity: 1, unitPrice: { currency: @order.currency, value: format_money(@order.display_ship_total.money) }, totalAmount: { currency: @order.currency, value: format_money(@order.display_ship_total.money) }, vatAmount: { currency: @order.currency, value: '0.00' }, vatRate: '0' } end def serialize_discounts { type: 'discount', name: 'Order discount', quantity: 1, unitPrice: { currency: @order.currency, value: format_money(@order.display_order_adjustment_total.money) }, totalAmount: { currency: @order.currency, value: format_money(@order.display_order_adjustment_total.money) }, vatAmount: { currency: @order.currency, value: '0.00' }, vatRate: '0' } end def serialize_shipping_discounts { type: 'discount', name: 'Shipping discount', quantity: 1, unitPrice: { currency: @order.currency, value: format_money(-@order.display_shipping_discount.money) }, totalAmount: { currency: @order.currency, value: format_money(-@order.display_shipping_discount.money) }, vatAmount: { currency: @order.currency, value: '0.00' }, vatRate: '0' } end def serialize_line_item(line) { type: 'physical', name: line.name, quantity: line.quantity, unitPrice: { currency: line.currency, value: format_money(line.display_price.money) }, discountAmount: { currency: line.currency, value: format_money(line.display_discount_amount.money) }, totalAmount: { currency: line.currency, value: format_money(line.display_final_amount.money) }, vatAmount: { currency: line.currency, value: format_money(line.display_vat_amount.money) }, vatRate: line.vat_rate * 100, sku: "#{line.id}-#{line.variant.sku}" } end end end end