@@ -48,9 +48,10 @@ class CreditCardGateway
end
end
- def initialize(jid, customer_id=nil)
+ def initialize(jid, customer_id, antifraud)
@jid = jid
@customer_id = customer_id
+ @antifraud = antifraud
@gateway = Braintree::Gateway.new(
environment: BRAINTREE_CONFIG[:environment].to_s,
@@ -115,18 +116,32 @@ class CreditCardGateway
!@gateway.customer.find(customer_id).payment_methods.empty?
end
+ def antifraud
+ REDIS.mget(@antifraud.map { |k| "jmp_antifraud-#{k}" }).find do |anti|
+ anti.to_i > 2
+ end &&
+ Braintree::ErrorResult.new(
+ @gateway, errors: {}, message: "Please contact support"
+ )
+ end
+
+ def incr_antifraud!
+ @antifraud.each do |k|
+ REDIS.incr("jmp_antifraud-#{k}")
+ REDIS.expire("jmp_antifraud-#{k}", 60 * 60 * 24)
+ end
+ end
+
def default_method(nonce)
- result = @gateway.payment_method.create(
- customer_id: customer_id,
- payment_method_nonce: nonce,
- options: {
- verify_card: true,
- make_default: true
- }
+ result = antifraud || @gateway.payment_method.create(
+ customer_id: customer_id, payment_method_nonce: nonce,
+ options: { verify_card: true, make_default: true }
)
- raise ErrorResult.for(result) unless result.success?
- result
+ return result if result.success?
+
+ incr_antifraud!
+ raise ErrorResult.for(result)
end
def remove_method(token)
@@ -192,6 +207,7 @@ end
class JmpPay < Roda
SENTRY_DSN = ENV["SENTRY_DSN"] && URI(ENV["SENTRY_DSN"])
plugin :render, engine: "slim"
+ plugin :cookies, path: "/"
plugin :common_logger, $stdout
extend Forwardable
@@ -230,16 +246,33 @@ class JmpPay < Roda
r.on :jid do |jid|
Sentry.set_user(id: params["customer_id"], jid: jid)
- gateway = CreditCardGateway.new(jid, params["customer_id"])
+ atfd = r.cookies["atfd"] || SecureRandom.uuid
+ one_year = 60 * 60 * 24 * 365
+ response.set_cookie(
+ "atfd",
+ value: atfd, expires: Time.now + one_year
+ )
+ params.delete("atfd") if params["atfd"].to_s == ""
+ antifrauds = [atfd, r.ip, params["atfd"]].compact.uniq
+ customer_id = params["customer_id"]
+ gateway = CreditCardGateway.new(jid, customer_id, antifrauds)
topup = AutoTopUpRepo.new
r.on "credit_cards" do
r.get do
+ if gateway.antifraud
+ return view(
+ :message,
+ locals: { message: "Please contact support" }
+ )
+ end
+
view(
"credit_cards",
locals: {
token: gateway.client_token,
customer_id: gateway.customer_id,
+ antifraud: atfd,
auto_top_up: topup.find(gateway.customer_id) ||
(gateway.payment_methods? ? "" : "15")
}
@@ -32,12 +32,22 @@ form method="post" action=""
small Leave blank for no auto top-up.
input type="hidden" name="customer_id" value=customer_id
+ input type="hidden" name="atfd" value=antifraud
input type="hidden" name="braintree_nonce"
script src="https://js.braintreegateway.com/web/dropin/1.33.0/js/dropin.js"
javascript:
document.querySelector("#braintree").innerHTML = "";
+ if(window.localStorage) {
+ var atfd = localStorage.getItem("atfd");
+ if(!atfd) {
+ atfd = "#{antifraud}";
+ localStorage.setItem("atfd", atfd);
+ }
+ document.querySelector("input[name=atfd]").value = atfd;
+ }
+
var button = document.createElement("button");
button.innerHTML = "Save";
document.querySelector("form").appendChild(button);