I have this stripe file StripePayment.php
<?php
require_once 'vendor/autoload.php';
use \Stripe\Stripe;
use \Stripe\Customer;
use \Stripe\ApiOperations\Create;
use \Stripe\Charge;
class StripePayment
{
private $apiKey;
private $stripeService;
public function __construct()
{
require_once "config.php";
$this->apiKey = STRIPE_SECRET_KEY;
$this->stripeService = new \Stripe\Stripe();
$this->stripeService->setVerifySslCerts(false);
$this->stripeService->setApiKey($this->apiKey);
}
public function addCustomer($customerDetailsAry)
{
$customer = new Customer();
$customerDetails = $customer->create($customerDetailsAry);
return $customerDetails;
}
public function chargeAmountFromCard($cardDetails)
{
$customerDetailsAry = array(
'email' => $cardDetails['email'],
'source' => $cardDetails['token']
);
$customerResult = $this->addCustomer($customerDetailsAry);
$charge = new Charge();
$cardDetailsAry = array(
'customer' => $customerResult->id,
'amount' => $cardDetails['amount']*100 ,
'currency' => $cardDetails['currency_code'],
'description' => $cardDetails['item_name'],
'metadata' => array(
'order_id' => $cardDetails['item_number']
)
);
$result = $charge->create($cardDetailsAry);
return $result->jsonSerialize();
}
}
and i am charging the card like this
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
require_once "config.php";
if (!empty($_POST["token"])) {
require_once 'StripePayment.php';
$stripePayment = new StripePayment();
$stripeResponse = $stripePayment->chargeAmountFromCard($_POST);
require_once "DBController.php";
$dbController = new DBController();
$amount = $stripeResponse["amount"] /100;
$param_type = 'ssdssss';
$param_value_array = array(
$_POST['email'],
$_POST['item_number'],
$amount,
$stripeResponse["currency"],
$stripeResponse["balance_transaction"],
$stripeResponse["status"],
json_encode($stripeResponse)
);
This code is able to charge cards but can't charge cards where 3D/SCA is required i.e European cards.
My question, is there a way i can request stripe to redirect the user to the card issuing bank for authentication so that the user can authorize the transaction?
My stripe form code looks like this
<form id="frmStripePayment" action=""
method="post">
<div class="field-row">
<label>Card Holder Name</label> <span
id="card-holder-name-info" class="info"></span><br>
<input type="text" id="name" name="name"
class="demoInputBox">
</div>
<div class="field-row">
<label>Email</label> <span id="email-info"
class="info"></span><br> <input type="text"
id="email" name="email" class="demoInputBox">
</div>
<div class="field-row">
<label>Card Number</label> <span
id="card-number-info" class="info"></span><br> <input
type="text" id="card-number" name="card-number"
class="demoInputBox">
</div>
<div class="field-row">
<div class="contact-row column-right">
<label>Expiry Month / Year</label> <span
id="userEmail-info" class="info"></span><br>
<select name="month" id="month"
class="demoSelectBox">
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="08">08</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select> <select name="year" id="year"
class="demoSelectBox">
<option value="21">2021</option>
<option value="22">2022</option>
<option value="23">2023</option>
<option value="24">2024</option>
<option value="25">2025</option>
<option value="26">2026</option>
<option value="27">2027</option>
<option value="28">2028</option>
<option value="29">2029</option>
<option value="30">2030</option>
</select>
</div>
<div class="contact-row cvv-box">
<label>CVC</label> <span id="cvv-info"
class="info"></span><br> <input type="text"
name="cvc" id="cvc"
class="demoInputBox cvv-input">
</div>
</div>
<div>
<input type="submit" name="pay_now" value="Submit"
id="submit-btn" class="btnAction"
onClick="stripePay(event);">
<div id="loader">
<img alt="loader" src="LoaderIcon.gif">
</div>
</div>
<input type='hidden' name='amount' value='1100'> <input
type='hidden' name='currency_code' value='USD'> <input
type='hidden' name='item_name' value='Solidroof Product'>
<input type='hidden' name='item_number'
value='SCA#Test'>
</form>
<script>
function cardValidation () {
var valid = true;
var name = $('#name').val();
var email = $('#email').val();
var cardNumber = $('#card-number').val();
var month = $('#month').val();
var year = $('#year').val();
var cvc = $('#cvc').val();
$("#error-message").html("").hide();
if (name.trim() == "") {
valid = false;
}
if (email.trim() == "") {
valid = false;
}
if (cardNumber.trim() == "") {
valid = false;
}
if (month.trim() == "") {
valid = false;
}
if (year.trim() == "") {
valid = false;
}
if (cvc.trim() == "") {
valid = false;
}
if(valid == false) {
$("#error-message").html("All Fields are required").show();
}
return valid;
}
//set your publishable key
Stripe.setPublishableKey("<?php echo STRIPE_PUBLISHABLE_KEY; ?>");
//callback to handle the response from stripe
function stripeResponseHandler(status, response) {
if (response.error) {
//enable the submit button
$("#submit-btn").show();
$( "#loader" ).css("display", "none");
//display the errors on the form
$("#error-message").html(response.error.message).show();
} else {
//get token id
var token = response['id'];
//insert the token into the form
$("#frmStripePayment").append("<input type='hidden' name='token' value='" + token + "' />");
//submit form to the server
$("#frmStripePayment").submit();
}
}
function stripePay(e) {
e.preventDefault();
var valid = cardValidation();
if(valid == true) {
$("#submit-btn").hide();
$( "#loader" ).css("display", "inline-block");
Stripe.createToken({
number: $('#card-number').val(),
cvc: $('#cvc').val(),
exp_month: $('#month').val(),
exp_year: $('#year').val()
}, stripeResponseHandler);
//submit from callback
return false;
}
}
</script>
According to the docs on how to manually require the user to be redirected to the bank url for further authentication https://stripe.com/docs/payments/3d-secure#manual-three-ds
next_action: {
type: 'redirect_to_url',
redirect_to_url: {
url: 'https://hooks.stripe.com/...',
return_url: 'https://example.com'
}
}
does the stripe sdk automatically know the bank url to redirect to or who feeds that info?
The bank-hosted authentication URL is handled by redirecting through that redirect_to_url.url
, or alternatively is managed automatically when using Stripe's Payment Intent API with confirmCardPayment
in Stripe.js v3 (migration guide). If you use confirmCardPayment
, you yourself don't need to manage the redirect at all. This is the recommendation approach to supporting 3D Secure.
You can support 3DS using the Sources API, but this is deprecated and no longer recommended.