如何在客户端验证信用卡信息而不向服务器传递任何信息(PCI遵从性)?
我使用的API用令牌响应我的请求,这是我需要存储在数据库中的唯一信息。我为他们发送信用卡信息,他们用令牌回应。我已经有了通过javascript验证信用卡并进行API调用的方法,javascript也是,但信息正在我的服务器中传递,正如我可以在服务器日志中看到的:
Started POST "/api_checkout" for 127.0.0.1 at 2014-08-04 21:53:02 -0300
Processing by Marketplace::CheckoutController#api_buy as JS
Parameters: {"utf8"=>"✓", "number"=>"4111 1111 1111 1111", "verification_value"=>"123", "full_name"=>"Test user", "expiration"=>"14/15", "token"=>"B5E7A1F1-9822-4433-9FEE-30B625B8B070"}
Rendered marketplace/checkout/api_buy.js.erb (0.4ms)
Completed 200 OK in 43ms (Views: 39.2ms | ActiveRecord: 0.0ms | Solr: 0.0ms)
Started POST "/api_checkout" for 127.0.0.1 at 2014-08-04 21:53:03 -0300
Processing by Marketplace::CheckoutController#api_buy as HTML
Parameters: {"utf8"=>"✓", "number"=>"4111 1111 1111 1111", "verification_value"=>"123", "full_name"=>"Test user", "expiration"=>"14/15", "token"=>"B5E7A1F1-9822-4433-9FEE-30B625B8B070"}
Completed 500 Internal Server Error in 21ms (no problem here, didn`t made the view yet)
我不知道我是否在做正确的事情,但这是我今天所做的
这是我的表格:
<%= form_tag api_buy_path,:method => :post, :id => 'payment-form', :remote => true do %>
<div class="usable-creditcard-form">
<div class="wrapper">
<div class="input-group nmb_a">
<div class="icon ccic-brand"></div>
<%= text_field_tag :number, params[:number], :class=>"credit_card_number", :"data-api"=>"number" %>
</div>
<div class="input-group nmb_b">
<div class="icon ccic-cvv"></div>
<%= text_field_tag :verification_value, params[:verification_value], :class=>"credit_card_cvv", :"data-api"=>"verification_value" %>
</div>
<div class="input-group nmb_c">
<div class="icon ccic-name"></div>
<%= text_field_tag :full_name, params[:full_name], :class=>"credit_card_name", :"data-api"=>"full_name" %>
</div>
<div class="input-group nmb_d">
<div class="icon ccic-exp"></div>
<%= text_field_tag :expiration, params[:expiration], :class=>"credit_card_expiration", :"data-api"=>"expiration" %>
</div>
</div>
</div>
<div class="token-area">
<%= label_tag :token, "Card token:"%>
<%= text_field_tag :token, params[:token],:id=>"token", :readonly=> true, :value=>""%>
</div>
<%= submit_tag 'Submit' %>
<% end %>
这是我使用的javascript:
SomeAPI.setAccountID("some-id");
SomeAPI.setTestMode(true);
jQuery(function($) {
$('#payment-form').submit(function(evt) {
var form = $(this);
var cardNumber = document.getElementById("number").value;
//Check with the number is valid
if(SomeAPI.utils.validateCreditCardNumber(cardNumber)){
var brand = SomeAPI.utils.getBrandByCreditCardNumber(cardNumber);
var cvv = document.getElementById("verification_value").value;
//Check the CVV by brand
if(SomeAPI.utils.validateCVV(cvv, brand)){
var expiration = document.getElementById("expiration").value.split("/");
var expiration_year = expiration[1];
var expiration_month = expiration[0];
//Check the Expiration Date
if(SomeAPI.utils.validateExpiration(expiration_month, expiration_year)){
var name = document.getElementById("full_name").value.split(" ");
var firstName = name[0];
var lastName = name[name.length - 1];
//Check everything
cc = SomeAPI.CreditCard(cardNumber, expiration_month, expiration_year, firstName, lastName, cvv);
var tokenResponseHandler = function(data) {
if (data.errors) {
//console.log(data.errors);
alert("Error: " + JSON.stringify(data.errors));
}
else {
$("#token").val( data.id );
form.get(0).submit();
}
// Send the form
form.trigger("submit.rails");
}
SomeAPI.createPaymentToken(cc, tokenResponseHandler);
return true;
}else{
alert("Invalid")
return false;
}
}else{
alert("Invalid")
return false;
}
}else{
alert("Invalid")
return false
}
});
});
问题是您需要在调用form.submit:
之前清除敏感表单数据 $("#token").val( data.id );
form.get(0).submit();
表单需要敏感的信用卡数据来执行验证,但是您的Rails应用程序不需要这些数据——它只需要令牌。
我通常将卡号设置为只包含卡号最后四位数字的字符串,如** ** **** 1234
你的SomeAPI可能已经返回一个掩码CC给你,否则你需要通过Javascript来做。