I'm integrating Stripe Payment Intent API and it's working well where 3D secure is not required, 3D secure authorization is popping up but I think I'm missing return_url
to confirm the payment.
Where do I need to mention return_url for 3D Secure in PaymentIntent?
I've tried multiple times but got stuck on 3D Secure Authorize. It returns an error in the object.
I've mentioned the code of view and controller below.
Thanks in Advance
Client Side Code:
form.addEventListener('submit', function(event) {
event.preventDefault();
$('#card-button').html('<i class="fa fa-circle-o-notch fa-spin" style="font-size:24px"></i>');
var fname = $('#firstname2').val();
var lname = $('#lastname2').val();
var cardholderName = fname + " " + lname;
var cardButton = document.getElementById('card-button');
var form_data = $("#payment-form").serialize();
cardButton.addEventListener('click', function(ev) {
stripe.createPaymentMethod('card', cardElement, {
billing_details: {name: cardholderName}
}).then(function(result) {
if (result.error) {
// Show error in payment form
} else {
console.log(result);
// Otherwise send paymentMethod.id to your server (see Step 2)
fetch('<?php echo base_url(); ?>payment/stripe_test/process_payment',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_method_id: result.paymentMethod.id, customer_detail: form_data})
}).then(function(result) {
// Handle server response (see Step 3)
result.json().then(function(result) {
console.log("Response" + result);
handleServerResponse(result);
});
});
}
});
});
}
function handleServerResponse(response) {
if (response.error) {
// Show error from server on payment form
} else if (response.requires_action) {
var action = response.next_action;
if (action && action.type === 'redirect_to_url') {
window.location = action.redirect_to_url.url;
}
// Use Stripe.js to handle required card action
stripe.handleCardAction(
response.payment_intent_client_secret
).then(function(result) {
if (result.error) {
// Show error in payment form
} else {
// The card action has been handled
// The PaymentIntent can be confirmed again on the server
fetch('<?php echo base_url(); ?>payment/stripe_test/process_payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_intent_id: result.paymentIntent.id })
}).then(function(confirmResult) {
return confirmResult.json();
}).then(handleServerResponse);
}
});
} else {
// Show success message
console.log("3D" + response);
}
}
CodeIgniter Controller:
//PaymentIntent Function
function process_payment() {
require_once (APPPATH."third_party/stripe/init.php");
$key = "STRIPE_KEY_HERE";
header('Content-Type: application/json');
# retrieve json from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$intent = null;
try {
if (isset($json_obj->payment_method_id)) {
# Create the PaymentIntent
//STRIPE PAYMENT INTENT
\Stripe\Stripe::setApiKey($key);
// Create a Customer:
$customer = \Stripe\Customer::create([
'email' => '[email protected]',
]);
// Attach payment method to the customer:
$customer_detail = $json_obj->customer_detail;
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $json_obj->payment_method_id,
'amount' => 1099,
'currency' => 'GBP',
'confirmation_method' => 'manual',
"customer" => $customer->id,
'confirm' => true,
]);
}
if (isset($json_obj->payment_intent_id)) {
$intent = \Stripe\PaymentIntent::retrieve(
$json_obj->payment_intent_id
);
$intent->confirm();
}
$this->generatePaymentResponse($intent);
} catch (\Stripe\Error\Base $e) {
# Display error on client
echo json_encode([
'error' => $e->getMessage()
]);
}
}
generatePaymentResponse Function:
function generatePaymentResponse($intent) {
if ($intent->status == 'requires_source_action' &&
$intent->next_action->type == 'use_stripe_sdk') {
# Tell the client to handle the action
echo json_encode([
'requires_action' => true,
'payment_intent_client_secret' => $intent->client_secret
]);
} else if ($intent->status == 'succeeded') {
# The payment didn’t need any additional actions and completed!
# Handle post-payment fulfillment
echo json_encode([
"success" => true
]);
} else {
# Invalid status
http_response_code(500);
echo json_encode(['error' => 'Invalid PaymentIntent status']);
}
}
return_url
as PaymentIntent will use Popup as 3DS confirmation instead of redirecting. So all you need to do is in your frontend, callstripe.handelCardAction
with the client secret. This function will have callback, in the callback, you would ajax to your backend again to confirm the paymentIntent. For details, check this link stripe.com/docs/payments/payment-intents/… – Hooks