# 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) return customer_id if check_customer_id(customer_id) cresult = @gateway.customer.create raise "Braintree customer create failed" unless cresult.success? result = REDIS.set(redis_key, cresult.customer.id) raise "Saving new customer to redis failed" unless result == "OK" cresult.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 "jmp_customer_id-#{@jid}" 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