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