php - insert purchase order in database before submit data to payment gateway
I am new to PHP, and I don't know if this can be done. I am building an online shop, and I would like to save the order in the database before sending the data to the payment gateway. As I am sending the data to an external page (payment gateway), I cannot record the buyer's data first without having to perform an extra step (page).
EDIT: I should have mentioned that I have shortened the code I have attached. Yes, there is a cart which is in SESSION and where I have all the order details. The problem is that the method I use from Redsys is redirection. I delegate the payment to their gateway by sending it some fields in an array. So when the user clicks the "Pay" button, I leave my website and go to the gateway, the payment is made there and if everything has worked, the gateway allows me to go to a URLOK or URLKO. What I try is that in the checkout form, which consists of the buyer / client data and the "sumit" button that redirects to the gateway, before going to the gateway URL, insert the order in status "PENDING", and then when it returns from the URLOK or URLKO update the status. In short, I need to perform these two steps with a single click:
- INSERT in DB
- SUBMIT data to REDSYS Gatewey
Otherwise, you would have to carry out an extra step, first making a form in which the buyer and order data are saved and second making an extra screen of the type "Check your data" and then send what is necessary to the gateway.
<?php
include 'config/apiRedsys.php';
$miObj = new RedsysAPI;
$currency="978";
$url="";
$urlOKKO="http://localhost/confirmed";
$urlKO="http://localhost/ko";
$id=time();
$amount=50000;
// Fill fields
$miObj->setParameter("DS_MERCHANT_AMOUNT",$amount);
$miObj->setParameter("DS_MERCHANT_ORDER",$id);
$miObj->setParameter("DS_MERCHANT_CURRENCY",$currency);
$miObj->setParameter("DS_MERCHANT_MERCHANTURL",$url);
$miObj->setParameter("DS_MERCHANT_URLOK",$urlOKKO);
$miObj->setParameter("DS_MERCHANT_URLKO",$urlKO);
$version="HMAC_SHA256_V1";
$kc = 'key';
$request = "";
$params = $miObj->createMerchantParameters();
$signature = $miObj->createMerchantSignature($kc);
?>
<form class="needs-validation" novalidate action="https://sis-t.redsys.es:25443/sis/realizarPago" method="POST" target="_blank">
<input type="hidden" name="Ds_SignatureVersion" value="<?php echo $version; ?>"/>
<input type="hidden" name="Ds_MerchantParameters" value="<?php echo $params; ?>"/>
<input type="hidden" name="Ds_Signature" value="<?php echo $signature; ?>"/>
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName">Name</label>
<input type="text" class="form-control" id="firstName" name="firstName" placeholder="" required>
<div class="invalid-feedback">
Required valid name
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastName">Apellidos</label>
<input type="text" class="form-control" id="lastName" name="lastName" placeholder="" required>
<div class="invalid-feedback">
Required valid surname
</div>
</div>
</div>
<div>
<input type="submit" value="Confirm and pay" class="a-button-input" />
</div>
</form>
Answer
Solution:
Traditionally, in an online store all ordered items are collected in a virtual cart before being made into an order. Typically, you'd then assign an id to your order, which you might then use in all your customer communication.
This way, you'd have your own persistent copy of the order which you can use to keep state. If the payment fails, you can alert the user and provide a retry attempt, without them having to go through the whole process again.
However, your code makes no mention of a cart or order items, so I won't assume this is the case. If your flow needs to redirect the user to the gateway immediately upon confirming the purchase, then you should consider making the API request from PHP. From looking at the Redsys API, this is functionality that they provide. Take a look at their REST API.
UPDATE
It seems your flow requires the user to actually leave your website and visit the PSP. This is a common scenario.
If you just want to catch the confirmation action before the user leaves your site, you could issue the redirect in JavaScript, just after an XHR ('Ajax') to your server completes. If you haven't saved the $_SESSION
data before this point, this will be a good time and place to do that too.
The XHR will only call some back-end PHP that you wrote which sole job is to catch the confirmation action. Write your script to update the order in the database when you're receiving a POST request containing purchase_confirmed=1
. It might output some JSON back to your JavaScript (json_encode(['success' => TRUE])
), which in turn will trigger a form submit.
One of many possible approaches is to use jQuery for this, as demonstrated below (UNTESTED!). If you need vanilla JavaScript, then please consult You Might Not Need jQuery. Getting into the details of the Fetch API or other (possibly better) solutions is beyond the scope of your question.
$.ajax({
type: 'POST',
url: '/path/to/your/script.php',
data: { purchase_confirmed: 1 },
dataType: 'json'
}).done((json) => {
// Your backend may choose to signal server-side success/failure by passing
// a 'success' element to the JSON.
if (json.success)
// All good. This will initiate the redirect to Redsys.
$('#your-form-id').submit();
else
// Something went wrong as indicated by your backend code.
// Determine what to say and how to inform the user.
// alert() for demo purposes.
alert('Your error message here');
}).fail(() => {
// Something else went wrong. Determine what to say and how to inform the user.
// Write something informative according to your business logic and the error detected.
alert('Something went wrong.');
});
Source