transaction.rb

 1# frozen_string_literal: true
 2
 3class Transaction
 4	def self.sale(customer, amount, payment_method=nil)
 5		REDIS.get("jmp_pay_decline-#{customer.customer_id}").then do |declines|
 6			raise "too many declines" if declines.to_i >= 2
 7
 8			BRAINTREE.transaction.sale(
 9				amount: amount,
10				**sale_args_for(customer, payment_method)
11			).then do |response|
12				decline_guard(customer, response)
13				new(response.transaction)
14			end
15		end
16	end
17
18	def self.decline_guard(customer, response)
19		return if response.success?
20
21		REDIS.incr("jmp_pay_decline-#{customer.customer_id}").then do
22			REDIS.expire("jmp_pay_decline-#{customer.customer_id}", 60 * 60 * 24)
23		end
24		raise response.message
25	end
26
27	def self.sale_args_for(customer, payment_method=nil)
28		{
29			merchant_account_id: customer.merchant_account,
30			options: { submit_for_settlement: true }
31		}.merge(
32			if payment_method
33				{ payment_method_token: payment_method.token }
34			else
35				{ customer_id: customer.id }
36			end
37		)
38	end
39
40	attr_reader :amount
41
42	def initialize(braintree_transaction)
43		@customer_id = braintree_transaction.customer_details.id
44		@transaction_id = braintree_transaction.id
45		@created_at = braintree_transaction.created_at
46		@amount = braintree_transaction.amount
47	end
48
49	def insert
50		params = [@customer_id, @transaction_id, @created_at, @amount]
51		DB.exec_defer(<<~SQL, params)
52			INSERT INTO transactions
53				(customer_id, transaction_id, created_at, amount)
54			VALUES
55				($1, $2, $3, $4)
56		SQL
57	end
58end