From 94cbcd3236d05a517025e69140a485c764c5ff40 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Fri, 23 Apr 2021 12:52:06 +0200 Subject: [PATCH] refactor to use the new price computation system based on ShoppingCart --- app/controllers/api/payments_controller.rb | 37 +--- app/controllers/api/payzen_controller.rb | 4 +- app/controllers/api/prices_controller.rb | 36 +--- .../api/reservations_controller.rb | 17 +- .../api/subscriptions_controller.rb | 20 +- app/models/cart_item/base_item.rb | 4 + app/models/cart_item/event_reservation.rb | 3 + app/models/cart_item/reservation.rb | 4 + app/models/cart_item/subscription.rb | 4 + app/models/payment_gateway_object.rb | 3 +- app/models/payment_schedule.rb | 4 +- app/models/price.rb | 203 ------------------ app/models/shopping_cart.rb | 3 +- app/models/subscription.rb | 2 + app/services/cart_service.rb | 8 +- app/services/invoices_service.rb | 15 +- app/services/payment_schedule_service.rb | 10 +- app/services/subscriptions/subscribe.rb | 20 +- lib/pay_zen/helper.rb | 16 +- lib/pay_zen/item.rb | 6 +- lib/pay_zen/token.rb | 19 ++ lib/payment/item.rb | 9 +- lib/payment/item_builder.rb | 10 +- lib/stripe/item.rb | 6 +- 24 files changed, 135 insertions(+), 328 deletions(-) create mode 100644 lib/pay_zen/token.rb diff --git a/app/controllers/api/payments_controller.rb b/app/controllers/api/payments_controller.rb index 795d57007..5cdc5c2b6 100644 --- a/app/controllers/api/payments_controller.rb +++ b/app/controllers/api/payments_controller.rb @@ -18,40 +18,9 @@ class API::PaymentsController < API::ApiController end def card_amount - if params[:cart_items][:reservation] - reservable = cart_items_params[:reservable_type].constantize.find(cart_items_params[:reservable_id]) - plan_id = cart_items_params[:plan_id] - slots = cart_items_params[:slots_attributes] || [] - nb_places = cart_items_params[:nb_reserve_places] - tickets = cart_items_params[:tickets_attributes] - user_id = if current_user.admin? || current_user.manager? - params[:cart_items][:reservation][:user_id] - else - current_user.id - end - else - raise NotImplementedError unless params[:cart_items][:subscription] - - reservable = nil - plan_id = subscription_params[:plan_id] - slots = [] - nb_places = nil - tickets = nil - user_id = if current_user.admin? || current_user.manager? - params[:cart_items][:subscription][:user_id] - else - current_user.id - end - end - - price_details = Price.compute(false, - User.find(user_id), - reservable, - slots, - plan_id: plan_id, - nb_places: nb_places, - tickets: tickets, - coupon_code: coupon_params[:coupon_code]) + cs = CartService.new(current_user) + cart = cs.from_hash(params[:cart_items]) + price_details = cart.total # Subtract wallet amount from total total = price_details[:total] diff --git a/app/controllers/api/payzen_controller.rb b/app/controllers/api/payzen_controller.rb index dc7faecf4..79f3d8b64 100644 --- a/app/controllers/api/payzen_controller.rb +++ b/app/controllers/api/payzen_controller.rb @@ -24,14 +24,14 @@ class API::PayzenController < API::PaymentsController client = PayZen::Charge.new @result = client.create_payment(amount: amount[:amount], order_id: @id, - customer: PayZen::Helper.generate_customer(params[:customer_id])) + customer: PayZen::Helper.generate_customer(params[:customer_id], params[:cart_items])) end def create_token @id = PayZen::Helper.generate_ref(cart_items_params, params[:customer_id]) client = PayZen::Charge.new @result = client.create_token(order_id: @id, - customer: PayZen::Helper.generate_customer(params[:customer_id])) + customer: PayZen::Helper.generate_customer(params[:customer_id], params[:cart_items])) end def check_hash diff --git a/app/controllers/api/prices_controller.rb b/app/controllers/api/prices_controller.rb index 9cc7db30c..83a74612a 100644 --- a/app/controllers/api/prices_controller.rb +++ b/app/controllers/api/prices_controller.rb @@ -37,39 +37,9 @@ class API::PricesController < API::ApiController end def compute - price_parameters = if params[:reservation] - compute_reservation_price_params - elsif params[:subscription] - compute_subscription_price_params - end - # user - user = User.find(price_parameters[:user_id]) - # reservable - if [nil, ''].include?(price_parameters[:reservable_id]) && ['', nil].include?(price_parameters[:plan_id]) - @amount = { elements: nil, total: 0, before_coupon: 0 } - else - reservable = if [nil, ''].include?(price_parameters[:reservable_id]) - nil - else - price_parameters[:reservable_type].constantize.find(price_parameters[:reservable_id]) - end - @amount = Price.compute(current_user.admin? || (current_user.manager? && current_user.id != user.id), - user, - reservable, - price_parameters[:slots_attributes] || [], - plan_id: price_parameters[:plan_id], - nb_places: price_parameters[:nb_reserve_places], - tickets: price_parameters[:tickets_attributes], - coupon_code: coupon_params[:coupon_code], - payment_schedule: price_parameters[:payment_schedule]) - end - - - if @amount.nil? - render status: :unprocessable_entity - else - render status: :ok - end + cs = CartService.new(current_user) + cart = cs.from_hash(params) + @amount = cart.total end private diff --git a/app/controllers/api/reservations_controller.rb b/app/controllers/api/reservations_controller.rb index fd52e4d9e..a240a8e66 100644 --- a/app/controllers/api/reservations_controller.rb +++ b/app/controllers/api/reservations_controller.rb @@ -64,14 +64,15 @@ class API::ReservationsController < API::ApiController def transaction_amount(is_admin, user_id) user = User.find(user_id) - price_details = Price.compute(is_admin, - user, - reservation_params[:reservable_type].constantize.find(reservation_params[:reservable_id]), - reservation_params[:slots_attributes] || [], - plan_id: reservation_params[:plan_id], - nb_places: reservation_params[:nb_reserve_places], - tickets: reservation_params[:tickets_attributes], - coupon_code: coupon_params[:coupon_code]) + cs = CartService.new(current_user) + cart = cs.from_hash(customer_id: user_id, + subscription: { + plan_id: reservation_params[:plan_id] + }, + reservation: reservation_params, + coupon_code: coupon_params[:coupon_code], + payment_schedule: !schedule.nil?) + price_details = cart.total # Subtract wallet amount from total total = price_details[:total] diff --git a/app/controllers/api/subscriptions_controller.rb b/app/controllers/api/subscriptions_controller.rb index db8c1ce12..f8e3a3d95 100644 --- a/app/controllers/api/subscriptions_controller.rb +++ b/app/controllers/api/subscriptions_controller.rb @@ -14,7 +14,7 @@ class API::SubscriptionsController < API::ApiController # Managers can create subscriptions for other users def create user_id = current_user.admin? || current_user.manager? ? params[:subscription][:user_id] : current_user.id - transaction = transaction_amount(current_user.admin? || (current_user.manager? && current_user.id != user_id), user_id) + transaction = transaction_amount(user_id) authorize SubscriptionContext.new(Subscription, transaction[:amount], user_id) @@ -50,16 +50,16 @@ class API::SubscriptionsController < API::ApiController private - def transaction_amount(is_admin, user_id) + def transaction_amount(user_id) + cs = CartService.new(current_user) + cart = cs.from_hash(customer_id: user_id, + subscription: { + plan_id: subscription_params[:plan_id] + }, + coupon_code: coupon_params[:coupon_code], + payment_schedule: !schedule.nil?) + price_details = cart.total user = User.find(user_id) - price_details = Price.compute(is_admin, - user, - nil, - [], - plan_id: subscription_params[:plan_id], - nb_places: nil, - tickets: nil, - coupon_code: coupon_params[:coupon_code]) # Subtract wallet amount from total total = price_details[:total] diff --git a/app/models/cart_item/base_item.rb b/app/models/cart_item/base_item.rb index 7de83bd18..38141fd29 100644 --- a/app/models/cart_item/base_item.rb +++ b/app/models/cart_item/base_item.rb @@ -10,4 +10,8 @@ class CartItem::BaseItem def price { elements: {}, amount: 0 } end + + def name + '' + end end diff --git a/app/models/cart_item/event_reservation.rb b/app/models/cart_item/event_reservation.rb index 6ed683c95..28e757123 100644 --- a/app/models/cart_item/event_reservation.rb +++ b/app/models/cart_item/event_reservation.rb @@ -33,4 +33,7 @@ class CartItem::EventReservation < CartItem::Reservation { elements: elements, amount: amount } end + def name + @reservable.title + end end diff --git a/app/models/cart_item/reservation.rb b/app/models/cart_item/reservation.rb index 004378c37..4f61eb7b8 100644 --- a/app/models/cart_item/reservation.rb +++ b/app/models/cart_item/reservation.rb @@ -29,6 +29,10 @@ class CartItem::Reservation < CartItem::BaseItem { elements: elements, amount: amount } end + def name + @reservable.name + end + protected def credits diff --git a/app/models/cart_item/subscription.rb b/app/models/cart_item/subscription.rb index 5abb90342..950ba87b4 100644 --- a/app/models/cart_item/subscription.rb +++ b/app/models/cart_item/subscription.rb @@ -14,4 +14,8 @@ class CartItem::Subscription < CartItem::BaseItem { elements: elements, amount: amount } end + + def name + @plan.name + end end diff --git a/app/models/payment_gateway_object.rb b/app/models/payment_gateway_object.rb index 69c74dae3..65005df06 100644 --- a/app/models/payment_gateway_object.rb +++ b/app/models/payment_gateway_object.rb @@ -12,8 +12,7 @@ class PaymentGatewayObject < ApplicationRecord belongs_to :payment_schedule_item, foreign_type: 'PaymentScheduleItem', foreign_key: 'item_id' def gateway_object - item = Payment::ItemBuilder.build(gateway_object_type) - item.retrieve(gateway_object_id) + Payment::ItemBuilder.build(gateway_object_type, gateway_object_id) end def gateway_object=(object) diff --git a/app/models/payment_schedule.rb b/app/models/payment_schedule.rb index 04948ade9..be956b4a6 100644 --- a/app/models/payment_schedule.rb +++ b/app/models/payment_schedule.rb @@ -48,8 +48,8 @@ class PaymentSchedule < PaymentDocument payment_schedule_items.order(due_date: :asc) end - def gateway_object(klass) - payment_gateway_objects.find_by(gateway_object_type: klass) + def gateway_payment_mean + payment_gateway_objects.map(&:gateway_object).find(&:payment_mean?) end def user diff --git a/app/models/price.rb b/app/models/price.rb index a400704b0..0a229fdb7 100644 --- a/app/models/price.rb +++ b/app/models/price.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true -MINUTES_PER_HOUR = 60.0 -SECONDS_PER_MINUTE = 60.0 - # Store customized price for various items (Machine, Space), depending on the group and on the plan -# Also provides a static helper method to compute the price details of a shopping cart class Price < ApplicationRecord belongs_to :group belongs_to :plan @@ -12,203 +8,4 @@ class Price < ApplicationRecord validates :priceable, :group_id, :amount, presence: true validates :priceable_id, uniqueness: { scope: %i[priceable_type plan_id group_id] } - - class << self - - ## - # @param admin {Boolean} true if the current user (ie.the user who requests the price) is an admin - # @param user {User} The user who's reserving (or selected if an admin is reserving) - # @param reservable {Machine|Training|Event} what the reservation is targeting - # @param slots {Array} when did the reservation will occur - # @param options {plan_id:Number, nb_places:Number, tickets:Array, coupon_code:String, payment_schedule:Boolean} - # - plan_id {Number} if the user is subscribing to a plan at the same time of his reservation, specify the plan's ID here - # - nb_places {Number} for _reservable_ of type Event, pass here the number of booked places - # - tickets {Array} for _reservable_ of type Event, mapping of the number of seats booked per price's category - # - coupon_code {String} Code of the coupon to apply to the total price - # - payment_schedule {Boolean} if the user is requesting a payment schedule for his subscription - # @return {Hash} total and price detail - ## - def compute(admin, user, reservable, slots, options = {}) - total_amount = 0 - all_elements = {} - all_elements[:slots] = [] - - # initialize Plan - plan = if user.subscribed_plan - new_plan_being_bought = false - user.subscribed_plan - elsif options[:plan_id] - new_plan_being_bought = true - Plan.find(options[:plan_id]) - else - new_plan_being_bought = false - nil - end - - # === compute reservation price === - - case reservable - - # Machine reservation - when Machine - base_amount = reservable.prices.find_by(group_id: user.group_id, plan_id: plan.try(:id)).amount - if plan - machine_credit = plan.machine_credits.select { |credit| credit.creditable_id == reservable.id }.first - if machine_credit - hours_available = credits_hours(machine_credit, user, new_plan_being_bought) - slots.each_with_index do |slot, index| - total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements, has_credits: (index < hours_available)) - end - else - slots.each do |slot| - total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements) - end - end - else - slots.each do |slot| - total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements) - end - end - - # Training reservation - when Training - amount = reservable.amount_by_group(user.group_id).amount - if plan - # Return True if the subscription link a training credit for training reserved by the user - space_is_creditable = plan.training_credits.select { |credit| credit.creditable_id == reservable.id }.any? - - # Training reserved by the user is free when : - - # |-> the user already has a current subscription and if space_is_creditable is true and has at least one credit available. - if !new_plan_being_bought - amount = 0 if user.training_credits.size < plan.training_credit_nb && space_is_creditable - # |-> the user buys a new subscription and if space_is_creditable is true. - else - amount = 0 if space_is_creditable - end - end - slots.each do |slot| - total_amount += get_slot_price(amount, slot, admin, elements: all_elements, is_division: false) - end - - # Event reservation - when Event - amount = reservable.amount * options[:nb_places] - options[:tickets]&.each do |ticket| - amount += ticket[:booked] * EventPriceCategory.find(ticket[:event_price_category_id]).amount - end - slots.each do |slot| - total_amount += get_slot_price(amount, slot, admin, elements: all_elements, is_division: false) - end - - # Space reservation - when Space - base_amount = reservable.prices.find_by(group_id: user.group_id, plan_id: plan.try(:id)).amount - - if plan - space_credit = plan.space_credits.select { |credit| credit.creditable_id == reservable.id }.first - if space_credit - hours_available = credits_hours(space_credit, user, new_plan_being_bought) - slots.each_with_index do |slot, index| - total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements, has_credits: (index < hours_available)) - end - else - slots.each do |slot| - total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements) - end - end - else - slots.each do |slot| - total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements) - end - end - - # No reservation (only subscription) - when nil - total_amount = 0 - - # Unknown reservation type - else - raise NotImplementedError - end - - # === compute Plan price (if any) === - unless options[:plan_id].nil? - all_elements[:plan] = plan.amount - total_amount += plan.amount - end - - # === apply Coupon if any === - _amount_no_coupon = total_amount - cs = CouponService.new - cp = cs.validate(options[:coupon_code], user.id) - total_amount = cs.apply(total_amount, cp) - - # == generate PaymentSchedule (if applicable) === - schedule = if options[:payment_schedule] && plan&.monthly_payment - PaymentScheduleService.new.compute(plan, _amount_no_coupon, coupon: cp) - else - nil - end - - total_amount = schedule[:items][0].amount if schedule - - # return result - { - elements: all_elements, - total: total_amount.to_i, - before_coupon: _amount_no_coupon.to_i, - coupon: cp, - schedule: schedule - } - end - - - private - - GET_SLOT_PRICE_DEFAULT_OPTS = { has_credits: false, elements: nil, is_division: true }.freeze - ## - # Compute the price of a single slot, according to the base price and the ability for an admin - # to offer the slot. - # @param hourly_rate {Number} base price of a slot - # @param slot {Hash} Slot object - # @param is_admin {Boolean} true if the current user has the 'admin' role - # @param [options] {Hash} optional parameters, allowing the following options: - # - elements {Array} if provided the resulting price will be append into elements.slots - # - has_credits {Boolean} true if the user still has credits for the given slot, false if not provided - # - is_division {boolean} false if the slot covers an full availability, true if it is a subdivision (default) - # @return {Number} price of the slot - ## - def get_slot_price(hourly_rate, slot, is_admin, options = {}) - options = GET_SLOT_PRICE_DEFAULT_OPTS.merge(options) - - slot_rate = options[:has_credits] || (slot[:offered] && is_admin) ? 0 : hourly_rate - real_price = if options[:is_division] - (slot_rate / MINUTES_PER_HOUR) * ((slot[:end_at].to_time - slot[:start_at].to_time) / SECONDS_PER_MINUTE) - else - slot_rate - end - - unless options[:elements].nil? - options[:elements][:slots].push( - start_at: slot[:start_at], - price: real_price, - promo: (slot_rate != hourly_rate) - ) - end - real_price - end - - ## - # Compute the number of remaining hours in the users current credits (for machine or space) - ## - def credits_hours(credits, user, new_plan_being_bought) - hours_available = credits.hours - unless new_plan_being_bought - user_credit = user.users_credits.find_by(credit_id: credits.id) - hours_available = credits.hours - user_credit.hours_used if user_credit - end - hours_available - end - end end diff --git a/app/models/shopping_cart.rb b/app/models/shopping_cart.rb index b803dc4df..f80edccd2 100644 --- a/app/models/shopping_cart.rb +++ b/app/models/shopping_cart.rb @@ -8,7 +8,7 @@ class ShoppingCart # @param coupon {CartItem::Coupon} # @param payment_schedule {CartItem::PaymentSchedule} # @param customer {User} - def initialize(customer, coupon, payment_method = '', items: [], payment_schedule: nil) + def initialize(customer, coupon, payment_schedule, payment_method = '', items: []) raise TypeError unless customer.class == User @customer = customer @@ -18,6 +18,7 @@ class ShoppingCart @payment_schedule = payment_schedule end + # compute the price details of the current shopping cart def total total_amount = 0 all_elements = { slots: [] } diff --git a/app/models/subscription.rb b/app/models/subscription.rb index b18b6ca58..377060347 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -87,8 +87,10 @@ class Subscription < ApplicationRecord end def original_payment_schedule + # if the payment schedule was associated with this subscription, return it directly return payment_schedule if payment_schedule + # if it was associated with a reservation, query payment schedule from one of its items PaymentScheduleItem.where("cast(details->>'subscription_id' AS int) = ?", id).first&.payment_schedule end diff --git a/app/services/cart_service.rb b/app/services/cart_service.rb index a25d08a25..6ec7ce20b 100644 --- a/app/services/cart_service.rb +++ b/app/services/cart_service.rb @@ -6,6 +6,10 @@ class CartService @operator = operator end + ## + # For details about the expected hash format + # @see app/frontend/src/javascript/models/payment.ts > interface CartItems + ## def from_hash(cart_items) items = [] plan_info = plan(cart_items) @@ -21,9 +25,9 @@ class CartService ShoppingCart.new( @customer, coupon, + schedule, cart_items[:payment_method], - items: items, - payment_schedule: schedule + items: items ) end diff --git a/app/services/invoices_service.rb b/app/services/invoices_service.rb index 1f5c20812..77c95219a 100644 --- a/app/services/invoices_service.rb +++ b/app/services/invoices_service.rb @@ -62,7 +62,7 @@ class InvoicesService ## # Create an Invoice with an associated array of InvoiceItem matching the given parameters - # @param payment_details {Hash} as generated by Price.compute + # @param payment_details {Hash} as generated by ShoppingCart.total # @param operator_profile_id {Number} ID of the user that operates the invoice generation (may be an admin, a manager or the customer himself) # @param reservation {Reservation} the booking reservation, if any # @param subscription {Subscription} the booking subscription, if any @@ -78,15 +78,18 @@ class InvoicesService operator&.admin? || (operator&.manager? && operator != user) ? nil : Setting.get('payment_gateway') end + pgo = unless payment_id.nil? + { + gateway_object_id: payment_id, + gateway_object_type: payment_type + } + end invoice = Invoice.new( invoiced: subscription || reservation, invoicing_profile: user.invoicing_profile, statistic_profile: user.statistic_profile, operator_profile_id: operator_profile_id, - payment_gateway_object_attributes: { - gateway_object_id: payment_id, - gateway_object_type: payment_type - }, + payment_gateway_object_attributes: pgo, payment_method: method ) @@ -98,7 +101,7 @@ class InvoicesService ## # Generate an array of {InvoiceItem} with the elements in provided reservation, price included. # @param invoice {Invoice} the parent invoice - # @param payment_details {Hash} as generated by Price.compute + # @param payment_details {Hash} as generated by ShoppingCart.total ## def self.generate_invoice_items(invoice, payment_details, reservation: nil, subscription: nil) if reservation diff --git a/app/services/payment_schedule_service.rb b/app/services/payment_schedule_service.rb index a31ce7d9a..1d6fe81fe 100644 --- a/app/services/payment_schedule_service.rb +++ b/app/services/payment_schedule_service.rb @@ -60,10 +60,12 @@ class PaymentScheduleService ps.scheduled = reservation || subscription ps.payment_method = payment_method - ps.payment_gateway_object = { - gateway_object_id: payment_id, - gateway_object_type: payment_type - } + if !payment_id.nil? && !payment_type.nil? + ps.payment_gateway_object = { + gateway_object_id: payment_id, + gateway_object_type: payment_type + } + end ps.operator_profile = operator.invoicing_profile ps.invoicing_profile = user.invoicing_profile ps.statistic_profile = user.statistic_profile diff --git a/app/services/subscriptions/subscribe.rb b/app/services/subscriptions/subscribe.rb index 3ddc1eab8..316e3f27a 100644 --- a/app/services/subscriptions/subscribe.rb +++ b/app/services/subscriptions/subscribe.rb @@ -11,7 +11,7 @@ class Subscriptions::Subscribe ## # @param subscription {Subscription} - # @param payment_details {Hash} as generated by Price.compute + # @param payment_details {Hash} as generated by ShoppingCart.total # @param payment_id {String} from the payment gateway # @param payment_type {String} the object type of payment_id # @param schedule {Boolean} @@ -61,21 +61,27 @@ class Subscriptions::Subscribe ) if new_sub.save schedule = subscription.original_payment_schedule - details = Price.compute(true, new_sub.user, nil, [], plan_id: subscription.plan_id) + + cs = CartService.new(current_user) + cart = cs.from_hash(customer_id: @user_id, + subscription: { + plan_id: subscription.plan_id + }, + payment_schedule: !schedule.nil?) + details = cart.total + payment = if schedule generate_schedule(subscription: new_sub, total: details[:before_coupon], operator_profile_id: operator_profile_id, user: new_sub.user, payment_method: schedule.payment_method, - payment_id: schedule.gateway_object('Stripe::SetupIntent').id) + payment_id: schedule.gateway_payment_mean&.id, + payment_type: schedule.gateway_payment_mean&.class) else generate_invoice(subscription, operator_profile_id, - details, - payment_id: schedule.gateway_object('Stripe::SetupIntent').id, - payment_type: 'Stripe::SetupIntent', - payment_method: schedule.payment_method) + details) end payment.save payment.post_save(schedule&.stp_setup_intent_id) diff --git a/lib/pay_zen/helper.rb b/lib/pay_zen/helper.rb index 941d29079..e31bcc15b 100644 --- a/lib/pay_zen/helper.rb +++ b/lib/pay_zen/helper.rb @@ -28,7 +28,7 @@ class PayZen::Helper end ## Generate a hash map compatible with PayZen 'V4/Customer/Customer' - def generate_customer(customer_id) + def generate_customer(customer_id, cart_items) customer = User.find(customer_id) address = if customer.organization? customer.invoicing_profile.organization.address&.address @@ -48,18 +48,24 @@ class PayZen::Helper shippingDetails: { category: customer.organization? ? 'COMPANY' : 'PRIVATE', shippingMethod: 'ETICKET' - } + }, + shoppingCart: generate_shopping_cart(cart_items, customer) } end ## Generate a hash map compatible with PayZen 'V4/Customer/ShoppingCart' def generate_shopping_cart(cart_items, customer) + cs = CartService.new(current_user) + cart = cs.from_hash(cart_items) { - cartItemInfo: cart_items.map do |type, value| + cartItemInfo: cart.items.map do |item| { - productAmount: item. - productType: customer.organization? ? 'SERVICE_FOR_BUSINESS' : 'SERVICE_FOR_INDIVIDUAL', + productAmount: item.price, + productLabel: item.name, + productQty: 1, + productType: customer.organization? ? 'SERVICE_FOR_BUSINESS' : 'SERVICE_FOR_INDIVIDUAL' } + end } end diff --git a/lib/pay_zen/item.rb b/lib/pay_zen/item.rb index d2841930a..b9b6b8a1b 100644 --- a/lib/pay_zen/item.rb +++ b/lib/pay_zen/item.rb @@ -9,9 +9,13 @@ module PayZen; end class PayZen::Item < Payment::Item attr_accessor :id - def retrieve(id) + def retrieve(id = nil) @id ||= id client = klass.constantize client.get(@id) end + + def payment_mean? + klass == 'PayZen::Token' + end end diff --git a/lib/pay_zen/token.rb b/lib/pay_zen/token.rb new file mode 100644 index 000000000..f4370c579 --- /dev/null +++ b/lib/pay_zen/token.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'pay_zen/client' + +# Token/* endpoints of the PayZen REST API +class PayZen::Token < PayZen::Client + def initialize(base_url: nil, username: nil, password: nil) + super(base_url: base_url, username: username, password: password) + end + + ## + # @see https://payzen.io/en-EN/rest/V4.0/api/playground/Token/Get/ + ## + def get(payment_method_token) + post('/Token/Get/', paymentMethodToken: payment_method_token) + end + +end + diff --git a/lib/payment/item.rb b/lib/payment/item.rb index 709edea9d..52a118c24 100644 --- a/lib/payment/item.rb +++ b/lib/payment/item.rb @@ -7,13 +7,18 @@ module Payment; end class Payment::Item attr_reader :klass - def initialize(klass) + def initialize(klass, id = nil) @klass = klass + @id = id end def class klass end - def retrieve(_id); end + def payment_mean? + false + end + + def retrieve(_id = nil); end end diff --git a/lib/payment/item_builder.rb b/lib/payment/item_builder.rb index 8fa0060b1..ae33055d6 100644 --- a/lib/payment/item_builder.rb +++ b/lib/payment/item_builder.rb @@ -10,19 +10,19 @@ module Payment; end class Payment::ItemBuilder attr_reader :instance - def self.build(klass) - builder = new(klass) + def self.build(klass, id = nil) + builder = new(klass, id) builder.instance end private - def initialize(klass) + def initialize(klass, id = nil) @instance = case klass when /^PayZen::/ - PayZen::Item.new(klass) + PayZen::Item.new(klass, id) when /^Stripe::/ - Stripe::Item.new(klass) + Stripe::Item.new(klass, id) else raise TypeError end diff --git a/lib/stripe/item.rb b/lib/stripe/item.rb index f6b571482..188c7c692 100644 --- a/lib/stripe/item.rb +++ b/lib/stripe/item.rb @@ -9,8 +9,12 @@ module Stripe; end class Stripe::Item < Payment::Item attr_accessor :id - def retrieve(id) + def retrieve(id = nil) @id ||= id klass.constantize.retrieve(@id, api_key: Setting.get('stripe_secret_key')) end + + def payment_mean? + klass == 'Stripe::SetupIntent' + end end