I have an issue with the test environnement of Stripe about the 3 d secure process and Subscription. And I'm afraid to push the process to production without validation or explanation of the problem.
I performed all of the 3d secure and Subscription process according to the documentation.
https://stripe.com/docs/sources/three-d-secure/subscriptions
When I would activate the subscription by disabling the trial period, all what I tried failed.

I'm using the test card with 3d secure required : 4000 0000 0000 3063
My code process :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Source test Stripe</title>
<script src="https://js.stripe.com/v3/"></script>
<style>
.StripeElement {
background-color: white;
height: 40px;
padding: 10px 12px;
border-radius: 4px;
border: 1px solid transparent;
box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease;
}
.StripeElement--focus {
box-shadow: 0 1px 3px 0 #cfd7df;
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}
</style>
</head>
<body>
<h1>create source</h1>
<form action="javascript:charge()" method="post" id="payment-form">
<div class="form-row">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element">
</div>
<div id="card-errors" role="alert"></div>
</div>
<button>Submit Payment</button>
</form>
</body>
<script>
var stripe = Stripe('pk_test_xxxx');
var elements = stripe.elements();
var style = {
base: {
color: '#32325d',
lineHeight: '18px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
var card = elements.create('card', {style: style});
card.mount('#card-element');
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
var ownerInfo = {
owner: {
name: 'Jenny Rosen',
address: {
line1: 'Nollendorfstraße 27',
city: 'Berlin',
postal_code: '10777',
country: 'DE',
},
email: '[email protected]'
},
};
stripe.createSource(card, ownerInfo).then(function(result) {
if (result.error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
console.log(result.source.id)
}
});
});
function charge() {
}
</script>
</html>
I got the source id src_xxxxx
And I put in my php script:
<?php
require_once('stripe-php/init.php');
Stripe\Stripe::setApiKey(
'sk_test_xxxxx'
);
$sourceId = 'src_xxxxx';
$customer = Stripe\Customer::create([
'description' => 'test desc',
'email' => '[email protected]',
'source' => $sourceId,
]);
$param = [
"amount" => 2995,
"currency" => 'eur',
"type" => "three_d_secure",
'three_d_secure' => [
'card' => $sourceId
],
"redirect" => [
"return_url" => "http://localhost:8080/stripeProcess2.php?customerId=".$customer->id
],
];
$source = Stripe\Source::create($param);
$customer->sources->create(['source' => $source->id]);
var_dump($source->redirect);
In the var_dump, I got the redirection url
I accept the 3d secure payment and the redirect link execute this following script:
<?php
require_once('stripe-php/init.php');
Stripe\Stripe::setApiKey(
'sk_test_xxxx'
);
$source = $_GET['source'];
$customerId = $_GET['customerId'];
$charges = \Stripe\Charge::create(array(
"amount" => 2995,
"currency" => "eur",
'source' => $source,
'customer' => $customerId,
"description" => "Charge for [email protected]"
));
$params = [
'items' => [
[
"plan" => "annual-basic",
]
],
'customer' => $customerId,
'trial_end' => strtotime('+1 day')
];
$sub = \Stripe\Subscription::create($params);
var_dump($sub->id);
And with The subscription Stripe id, I would activate the subscription immediately (This charge the customer)
$subscription = \Stripe\Subscription::retrieve("sub_C7eVRi9WLynMdh");
$subscription->trial_end = "now";
$subscription->save();
And Here, I got the failed payment with generic_decline code.
I want to know if in my process, I performed something wrong, if I need to wait the month end to recharge customer or if the Stripe test card is not available to be used for this process?
Thanks in advance
I think the reason for the decline is because the test card 4000000000003063 (https://stripe.com/docs/sources/three-d-secure) are only for single payments and 3D Secure must be completed for a charge to be successful. (Use credit card 4000000000003055 - "3D Secure is supported but not required on this card" instead.)
This means if this card is attached to a customer, you are only able to test the initial payment but not the recurring payments because you can not complete the 3D Secure procedure again.
You need to store the original credit card source with the stripe default procedure (https://stripe.com/docs/sources/cards) to use this source again for your ongoing subscription payments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With