Upload
ngokien
View
214
Download
0
Embed Size (px)
Citation preview
From 1,000 Transactions a Month to 1 Million in a DayLessons in Credit Card Processing from
Tuesday, May 17, 2011
Customer
Payment Gateway
Merchant(You)
Merchant Account(Acquiring
Bank)
Customer’s Bank
(Issuing Bank)
Credit Card Network
Tuesday, May 17, 2011
Customer
Payment Gateway
Merchant(You)
Merchant Account(Acquiring
Bank)
Customer’s Bank
(Issuing Bank)
Credit Card Network
Tuesday, May 17, 2011
Creating the Gateway
@gateway = ActiveMerchant::Billing:: AuthorizeNetGateway.new( :login => 'LOGIN', :password => 'PASSWORD' )
Tuesday, May 17, 2011
@credit_card = ActiveMerchant::Billing::CreditCard.new( :number => '4242424242424242', :month => 9, :year => 2013, :first_name => 'Longbob', :last_name => 'Longsen', :verification_value => '123', :type => 'visa')
Tuesday, May 17, 2011
#<ActiveMerchant::Billing::Response:0x108f13a98 @authorization="2159970110", @avs_result= {"code"=>"Y", "postal_match"=>"Y", "street_match"=>"Y", "message"=>"Street address and 5-digit postal code match."}, @cvv_result={"code"=>"P", "message"=>"Not Processed"}, @fraud_review=false, @message="This transaction has been approved", @params= {"response_reason_text"=>"This transaction has been approved.", "transaction_id"=>"2159970110", "response_code"=>1, "response_reason_code"=>"1", "avs_result_code"=>"Y", "card_code"=>"P"}, @success=true, @test=true>
Tuesday, May 17, 2011
class ApplicationController < ActionController::Base filter_parameter_logging :card_number, :verification_valueend
/app/controllers/application_controller.rbTuesday, May 17, 2011
config.filter_parameters += [:card_number, :verification_value]
/config/application.rbTuesday, May 17, 2011
Creating the Gateway
@gateway = ActiveMerchant::Billing:: AuthorizeNetCimGateway.new( :login => 'LOGIN', :password => 'PASSWORD' )
Tuesday, May 17, 2011
@credit_card = ActiveMerchant::Billing::CreditCard.new( :number => '4242424242424242', :month => 9, :year => 2013, :first_name => 'Longbob', :last_name => 'Longsen', :verification_value => '123', :type => 'visa')
Tuesday, May 17, 2011
@gateway.create_customer_profile( :profile => { :description => "meaningful to you", :payment_profiles => { :payment => { :credit_card => @credit_card } } })
Tuesday, May 17, 2011
response.success? => true
response.authorization => 2011761response.params['customer_profile_id'] => 2011761
response.params['customer_payment_profile_id_list']['numeric_string'] => 1646547
Tuesday, May 17, 2011
@gateway.create_customer_profile_transaction( :transaction => { :customer_profile_id => '2011761', :customer_payment_profile_id => '1646547', :type => :auth_capture, :amount => 50 })
Tuesday, May 17, 2011
Section 3.4:
Render PAN, at minimum, unreadable anywhere it is stored ... by using any of the following approaches: - Strong one-way hash functions (hashed indexes)
Verify that data is rendered unreadable using one of the following methods: - One-way hashes (hashed indexes) such as SHA-1
www.pcisecuritystandards.org/pdfs/pci_audit_procedures_v1-1.pdf
PCI DSS
Tuesday, May 17, 2011
hashed_card_number = '62163a017b168ad4a229c64ae1bed6ffd5e8fb2d'
masked_card_number = '401288******1881'
Tuesday, May 17, 2011
require 'digest/sha1'
def reverse_hashed_card_number( hashed_card_number, first_six, last_four) 0.upto(999_999) do |i| card_number_to_test = "#{first_six}%06d#{last_four}" % i hashed_to_test = Digest::SHA1.hexdigest(card_number_to_test)
if hashed_card_number == hashed_card_number_to_test return card_number_to_test end
endend
Tuesday, May 17, 2011
Benchmark.measure do puts reverse_hashed_card_number( '62163a017b168ad4a229c64ae1bed6ffd5e8fb2d', '401288', '1881' )end.real
4012888888881881
=> 5.33522081375122
Tuesday, May 17, 2011
$('#transaction_form').submit(function () { encryptedForm().submit(); return false;});
Tuesday, May 17, 2011
var encryptedForm = function () { var originalForm = $('#transaction_form'); var newForm = originalForm.clone(); newForm.css('display', 'none') updateIds(newForm); copyCheckboxAndRadioButtonState(originalForm, newForm) $('body').append(newForm); encryptFormValues(); return newForm;};
Tuesday, May 17, 2011
var encryptedForm = function () { var originalForm = $('#transaction_form'); var newForm = originalForm.clone(); newForm.css('display', 'none') updateIds(newForm); copyCheckboxAndRadioButtonState(originalForm, newForm); $('body').append(newForm); encryptFormValues(); return newForm;};
Tuesday, May 17, 2011
copyCheckboxAndRadioButtonState = function (originalForm, newForm) { fields = originalForm.find("*").filter(":checkbox | :radio") fields.each(function (index, originalElement) { if ($(originalElement).attr("id")) { id = $(originalElement).attr("id") $("new_" + id).checked = originalElement.checked; } });};
Tuesday, May 17, 2011
var encryptedForm = function () { var originalForm = $('#transaction_form'); var newForm = originalForm.clone(); newForm.css('display', 'none') updateIds(newForm); copyCheckboxAndRadioButtonState(originalForm, newForm); $('body').append(newForm); encryptFormValues(); return newForm;};
Tuesday, May 17, 2011
var encryptFormValues = function () { var inputs = $('#transaction_form').find(":input") inputs.each(function (index, element) { var id = $(element).attr("id"); $("#new_" + id).val(selectivelyEncryptedValue(element)); });};
var selectivelyEncryptedValue = function (element) { if (shouldEncrypt(element)) { return dls.braintree.encrypt($(element).val()); } else { return $(element).val(); }};
Tuesday, May 17, 2011
$('#transaction_form').submit(function () { encryptedForm().submit(); return false;});
Tuesday, May 17, 2011
Braintree::Customer.create( :first_name => 'Patrick', :last_name => 'Joyce', :credit_card => { :cardholder_name => 'Patrick Joyce', :number => '4012888888881881', :expiration_month => 1, :expiration_year => 2013, :cvv => '123' })
Tuesday, May 17, 2011
Braintree::Customer.create( :first_name => 'Patrick', :last_name => 'Joyce', :credit_card => { :cardholder_name => 'Patrick Joyce', :number => '$bt$JKuPh2et4NznbT4RJYZ...', :expiration_month => 1, :expiration_year => 2013, :cvv => '$bt$H9LKEhZUb0yFbFVAncoenz0...' })
Tuesday, May 17, 2011
class CreditCard < ActiveRecord::Base before_validation :store_at_braintree, :unless => Proc.new {|cc| cc.store_offline? }
after_save :fire_store_at_braintree_event, :if => Proc.new {|cc| cc.store_offline? }
attr_accessor :store_now def store_offline? store_now || encrypted?(card_number) endend
Tuesday, May 17, 2011
def fire_store_at_braintree_event queue_action_event(:store_braintree_credit_card, :credit_card_id => self.id, :card_number => self.card_number, :verification_value => self.verification_value )end
Tuesday, May 17, 2011
class StoreBraintreeCreditCardEvent < ApplicationEvent def process @credit_card = CreditCard.find_by_id(params[:credit_card_id]) @credit_card.update_attributes!( :card_number => params[:card_number], :verification_value => params[:verification_value], :store_now => true ) endend
Tuesday, May 17, 2011