~singpolyma/sgx-jmp

72b443688bca16f08858bcb13f6fbc24dd9efeab — Stephen Paul Weber 7 months ago c3bd04f
Credit card blacklist

Any card on the list is just treated as though it is not present, preventing it
from being used.
M lib/customer_finacials.rb => lib/customer_finacials.rb +7 -5
@@ 6,11 6,13 @@ class CustomerFinancials
	end

	def payment_methods
		BRAINTREE
			.customer
			.find(@customer_id)
			.catch { OpenStruct.new(payment_methods: []) }
			.then(PaymentMethods.method(:for_braintree_customer))
		EMPromise.all([
			BRAINTREE
				.customer
				.find(@customer_id)
				.catch { OpenStruct.new(payment_methods: []) },
			REDIS.smembers("block_credit_cards")
		]).then { |(braintree, badcards)| PaymentMethods.for(braintree, badcards) }
	end

	def btc_addresses

M lib/payment_methods.rb => lib/payment_methods.rb +4 -2
@@ 1,8 1,10 @@
# frozen_string_literal: true

class PaymentMethods
	def self.for_braintree_customer(braintree_customer)
		methods = braintree_customer.payment_methods
	def self.for(braintree_customer, badcards)
		methods = braintree_customer.payment_methods.reject { |m|
			badcards.include?(m.unique_number_identifier)
		}
		if methods.empty?
			Empty.new
		else

M lib/transaction.rb => lib/transaction.rb +18 -20
@@ 4,39 4,37 @@ require "bigdecimal"

class Transaction
	def self.sale(customer, amount:, payment_method: nil)
		customer.declines.then do |declines|
			raise "too many declines" if declines >= 2

		resolve_payment_method(customer, payment_method).then do |selected_method|
			BRAINTREE.transaction.sale(
				amount: amount,
				**sale_args_for(customer, payment_method)
				merchant_account_id: customer.merchant_account,
				options: { submit_for_settlement: true },
				payment_method_token: selected_method.token
			).then do |response|
				decline_guard(customer, response)
				new(response.transaction)
				new(decline_guard(customer, response))
			end
		end
	end

	def self.resolve_payment_method(customer, payment_method)
		EMPromise.all([
			customer.declines,
			payment_method || customer.payment_methods.then(&:default_payment_method)
		]).then do |(declines, selected_method)|
			raise "Declined" if declines >= 2
			raise "No valid payment method on file" unless selected_method

			selected_method
		end
	end

	def self.decline_guard(customer, response)
		return if response.success?
		return response.transaction if response.success?

		customer.mark_decline
		raise response.message
	end

	def self.sale_args_for(customer, payment_method=nil)
		{
			merchant_account_id: customer.merchant_account,
			options: { submit_for_settlement: true }
		}.merge(
			if payment_method
				{ payment_method_token: payment_method.token }
			else
				{ customer_id: customer.customer_id }
			end
		)
	end

	attr_reader :amount

	def initialize(braintree_transaction)

M test/test_buy_account_credit_form.rb => test/test_buy_account_credit_form.rb +3 -1
@@ 4,7 4,8 @@ require "test_helper"
require "buy_account_credit_form"
require "customer"

Customer::BRAINTREE = Minitest::Mock.new
CustomerFinancials::BRAINTREE = Minitest::Mock.new
CustomerFinancials::REDIS = Minitest::Mock.new

class BuyAccountCreditFormTest < Minitest::Test
	def setup


@@ 18,6 19,7 @@ class BuyAccountCreditFormTest < Minitest::Test
	def test_for
		braintree_customer = Minitest::Mock.new
		CustomerFinancials::BRAINTREE.expect(:customer, braintree_customer)
		CustomerFinancials::REDIS.expect(:smembers, [], ["block_credit_cards"])
		braintree_customer.expect(
			:find,
			EMPromise.resolve(OpenStruct.new(payment_methods: [])),

M test/test_payment_methods.rb => test/test_payment_methods.rb +24 -4
@@ 4,22 4,42 @@ require "test_helper"
require "payment_methods"

class PaymentMethodsTest < Minitest::Test
	def test_for_braintree_customer
	def test_for
		braintree_customer = Minitest::Mock.new
		braintree_customer.expect(:payment_methods, [
			OpenStruct.new(card_type: "Test", last_4: "1234")
		])
		methods = PaymentMethods.for_braintree_customer(braintree_customer)
		methods = PaymentMethods.for(braintree_customer, [])
		assert_kind_of PaymentMethods, methods
		assert_equal 1, methods.to_a.length
		refute methods.empty?
	end

	def test_for_braintree_customer_no_methods
	def test_for_badcards
		braintree_customer = Minitest::Mock.new
		braintree_customer.expect(:payment_methods, [
			OpenStruct.new(
				card_type: "Test",
				last_4: "1234",
				unique_number_identifier: "wut"
			)
		])
		methods = PaymentMethods.for(braintree_customer, ["wut"])
		assert_kind_of PaymentMethods, methods
		assert_equal 0, methods.to_a.length
		assert methods.empty?
	end

	def test_for_no_methods
		braintree_customer = Minitest::Mock.new
		braintree_customer.expect(:payment_methods, [])
		methods = PaymentMethods.for_braintree_customer(braintree_customer)
		methods = PaymentMethods.for(braintree_customer, [])
		assert_kind_of PaymentMethods, methods
		assert_raises do
			methods.to_list_single
		end
		assert_equal 0, methods.to_a.length
		assert methods.empty?
	end

	def test_default_payment_method

M test/test_registration.rb => test/test_registration.rb +1 -0
@@ 266,6 266,7 @@ class RegistrationTest < Minitest::Test
				:customer,
				braintree_customer
			)
			CustomerFinancials::REDIS.expect(:smembers, [], ["block_credit_cards"])
			braintree_customer.expect(
				:find,
				EMPromise.resolve(OpenStruct.new(payment_methods: [])),