Reputation: 3398
I'm using PayPal express checkout (checkout.js V4.0.0) with asp.net mvc to allow a user to pay for data transactions. What I need to do when the express checkout button is clicked is perform some checks on the database and confirm that PayPal can proceed (this is also time related, as the database could be in a locked processing state).
I've setup the Advanced Server Integration and I then call the create-payment controller from the payment section in paypal.Button.render
, but this expects a json
object with a PaymentID
element to be returned. At what point am I able to perform these checks on server side and abort from the paypal process if PayPal can't continue? If a check fails, the server side also needs to return an appropriate error page or message to be displayed.
This is the paypal button code:
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
env: 'sandbox',
payment: function (resolve, reject) {
var CREATE_PAYMENT_URL = '@Url.Action("PayTransactions","Pending")';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data) { resolve(data.paymentID); })
.catch(function (err) { reject(err); });
},
onAuthorize: function(data) {
var EXECUTE_PAYMENT_URL = 'https://my-store.com/paypal/execute-payment';
paypal.request.post(EXECUTE_PAYMENT_URL,
{
paymentID: data.paymentID,
payerID: data.payerID
})
.then(function(data) { /* Go to a success page */ })
.catch(function (err) { /* Go to an error page */ });
},
onCancel: function (data, actions) {
return actions.redirect();
},
onError: function (err) {
// Show an error page here, when an error occurs
}
}, '#paypal-button');
</script>
which at the payment section calls this:
public async Task<string> PayTransactions()
{
// check if payment is still necessary or end of month is running
var condition = await CheckDatabaseIsUsable();
switch (condition)
{
case 1:
ModelState.AddModelError("error", "some error message");
return RedirectToAction("Index", "Pending");
case 2:
ModelState.AddModelError("error", "some other error");
return RedirectToAction("Index", "Pending");
}
var paypalPayment = FormPayPalPaymentObject();
return JsonConvert.SerializeObject(new { paymentID = paypalPayment.PaymentId });
}
The problem is that I am now mixing the ActionResult
and json string
return types.
Upvotes: 0
Views: 827
Reputation: 2414
You can return json also for the redirection responses and control with javascript when it is a redirection or and ok response.
Server side:
return JsonConvert.SerializeObject(new { redirect= Url.Action("Index", "Pending") });
Javascript:
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data) {
if(data.redirect)
{
//cancel the flow and redirect if needed
window.location.href = data.redirect;
}else{
resolve(data.paymentID);
}
})
.catch(function (err) { reject(err); });
},
Using an IActionResult
object as the return value for the PayTransactions is preferable
public async Task<IActionResult> PayTransactions()
{
...
return Json(new { paymentID = paypalPayment.PaymentId });
}
Also consider that the modelstate errors you are adding are useless because of the redirection.
Upvotes: 1