config.ru

 1# frozen_string_literal: true
 2
 3require "braintree"
 4require "delegate"
 5require "dhall"
 6require "redis"
 7require "roda"
 8
 9REDIS = Redis.new
10BRAINTREE_CONFIG = Dhall.load("env:BRAINTREE_CONFIG").sync
11
12class CreditCardGateway
13	def initialize(jid, customer_id=nil)
14		@jid = jid
15		@customer_id = customer_id
16
17		@gateway = Braintree::Gateway.new(
18			environment: BRAINTREE_CONFIG[:environment].to_s,
19			merchant_id: BRAINTREE_CONFIG[:merchant_id].to_s,
20			public_key: BRAINTREE_CONFIG[:public_key].to_s,
21			private_key: BRAINTREE_CONFIG[:private_key].to_s
22		)
23	end
24
25	def check_customer_id(cid)
26		return cid unless ENV["RACK_ENV"] == "production"
27
28		raise "customer_id does not match" unless @customer_id == cid
29
30		cid
31	end
32
33	def customer_id
34		customer_id = REDIS.get(redis_key)
35		return customer_id if check_customer_id(customer_id)
36
37		cresult = @gateway.customer.create
38		raise "Braintree customer create failed" unless cresult.success?
39
40		result = REDIS.set(redis_key, cresult.customer.id)
41		raise "Saving new customer to redis failed" unless result == "OK"
42
43		cresult.customer.id
44	end
45
46	def client_token
47		@gateway.client_token.generate(customer_id: customer_id)
48	end
49
50	def default_payment_method=(nonce)
51		@gateway.payment_method.create(
52			customer_id: customer_id,
53			payment_method_nonce: nonce,
54			options: {
55				make_default: true
56			}
57		)
58	end
59
60protected
61
62	def redis_key
63		"jmp_customer_id-#{@jid}"
64	end
65end
66
67class JmpPay < Roda
68	plugin :render, engine: "slim"
69	plugin :common_logger, $stdout
70
71	route do |r|
72		r.on :jid do |jid|
73			r.on "credit_cards" do
74				gateway = CreditCardGateway.new(
75					jid,
76					request.params["customer_id"]
77				)
78
79				r.get do
80					view(
81						"credit_cards",
82						locals: {
83							token: gateway.client_token,
84							customer_id: gateway.customer_id
85						}
86					)
87				end
88
89				r.post do
90					gateway.default_payment_method = request.params["braintree_nonce"]
91					"OK"
92				end
93			end
94		end
95	end
96end
97
98run JmpPay.freeze.app