~singpolyma/jmp-pay

ref: 56244eb81f77789d966b2342f195042c528be8e3 jmp-pay/config.ru -rw-r--r-- 2.2 KiB
56244eb8Stephen Paul Weber Save bidirectional association for customer_id in redis 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# frozen_string_literal: true

require "braintree"
require "delegate"
require "dhall"
require "redis"
require "roda"

REDIS = Redis.new
BRAINTREE_CONFIG = Dhall.load("env:BRAINTREE_CONFIG").sync

class CreditCardGateway
	def initialize(jid, customer_id=nil)
		@jid = jid
		@customer_id = customer_id

		@gateway = Braintree::Gateway.new(
			environment: BRAINTREE_CONFIG[:environment].to_s,
			merchant_id: BRAINTREE_CONFIG[:merchant_id].to_s,
			public_key: BRAINTREE_CONFIG[:public_key].to_s,
			private_key: BRAINTREE_CONFIG[:private_key].to_s
		)
	end

	def check_customer_id(cid)
		return cid unless ENV["RACK_ENV"] == "production"

		raise "customer_id does not match" unless @customer_id == cid

		cid
	end

	def customer_id
		customer_id = REDIS.get(redis_key_jid)
		return customer_id if check_customer_id(customer_id)

		result = @gateway.customer.create
		raise "Braintree customer create failed" unless result.success?
		@customer_id = result.customer.id
		save_customer_id!
	end

	def save_customer_id!
		unless REDIS.set(redis_key_jid, @customer_id) == "OK"
			raise "Saving new jid,customer to redis failed"
		end

		unless REDIS.set(redis_key_customer_id, @jid) == "OK"
			raise "Saving new customer,jid to redis failed"
		end

		@customer_id
	end

	def client_token
		@gateway.client_token.generate(customer_id: customer_id)
	end

	def default_payment_method=(nonce)
		@gateway.payment_method.create(
			customer_id: customer_id,
			payment_method_nonce: nonce,
			options: {
				make_default: true
			}
		)
	end

protected

	def redis_key_jid
		"jmp_customer_id-#{@jid}"
	end

	def redis_key_customer_id
		"jmp_customer_jid-#{@customer_id}"
	end
end

class JmpPay < Roda
	plugin :render, engine: "slim"
	plugin :common_logger, $stdout

	route do |r|
		r.on :jid do |jid|
			r.on "credit_cards" do
				gateway = CreditCardGateway.new(
					jid,
					request.params["customer_id"]
				)

				r.get do
					view(
						"credit_cards",
						locals: {
							token: gateway.client_token,
							customer_id: gateway.customer_id
						}
					)
				end

				r.post do
					gateway.default_payment_method = request.params["braintree_nonce"]
					"OK"
				end
			end
		end
	end
end

run JmpPay.freeze.app