# frozen_string_literal: true class Transaction def self.sale(customer, amount:, payment_method: nil) REDIS.get("jmp_pay_decline-#{customer.customer_id}").then do |declines| raise "too many declines" if declines.to_i >= 2 BRAINTREE.transaction.sale( amount: amount, **sale_args_for(customer, payment_method) ).then do |response| decline_guard(customer, response) new(response.transaction) end end end def self.decline_guard(customer, response) return if response.success? REDIS.incr("jmp_pay_decline-#{customer.customer_id}").then do REDIS.expire("jmp_pay_decline-#{customer.customer_id}", 60 * 60 * 24) end raise response.message end def self.sale_args_for(customer, payment_method=nil) { merchant_account_id: customer.merchant_account, options: { submit_for_settlement: true } }.merge( if payment_method { payment_method_token: payment_method.token } else { customer_id: customer.id } end ) end attr_reader :amount def initialize(braintree_transaction) @customer_id = braintree_transaction.customer_details.id @transaction_id = braintree_transaction.id @created_at = braintree_transaction.created_at @amount = braintree_transaction.amount end def insert params = [@customer_id, @transaction_id, @created_at, @amount] DB.exec_defer(<<~SQL, params) INSERT INTO transactions (customer_id, transaction_id, created_at, amount) VALUES ($1, $2, $3, $4) SQL end end