Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PayPal payment standard returns GET instead of POST from mobile devices, hence not able to validate-record payment

I have integrated PayPal Payment Standard couple of years back to acquire payment.

My application is in Asp.Net. It is in sandbox mode currently.

I have a Pay Now button in my website having PostBackURL to PayPal site with all the required parameters. When user clicks on the button it redirects to PayPal their user can pay via his account or debit/credit card. And on successful transaction user is sent back to my application. When user comes back to my application I am getting various parameters like "payment_status" in Request.Form collection. I validate the response and show the success / failure message accordingly.

Above flow is working fine when user is on a browser in desktop.

But when user is in mobile devices and working with mobile browser. User is landed on PayPal mobile friendly page. There user pays with his account. Then success message is shown. But when user is redirected to my application I does not get any values in Request.Form collection. Due to which I am not able to validate the response from PayPal.

Further I have learned that when on desktop browsers PayPal returns response via POST method to my website, hence Request.Form contains the data.

Whereas, in case of mobile browsers PayPal returns response via GET method, hence Request.Form does not contain any data.

Why PayPal returns response via GET? In such case data is not available even in querystring, then how can I validate the response, whether payment is successful or not?

I have read documentation and it says that there are not other specific setting for mobile PayPal payment standard.

I don't want to migrate to express checkout or any other configuration.

Also I have searched many threads on SO related to same and didn't find any proper solution which caters my need hence asking as a new question.

like image 857
Dinesh Prajapati Avatar asked Dec 24 '16 10:12

Dinesh Prajapati


1 Answers

I've done like this for PayPal in my WebAPI Asp.NET project .. hope it help you:

[AllowAnonymous]
        [HttpPost]
        [Route("api/PayPal/IPN")]
        [ResponseType(typeof(OrderPayPalDTO))]
        public async Task<IHttpActionResult> PayPalIPN()
        {
            try
            {
                decimal tot;

                var data = this.Request.Content.ReadAsStringAsync().Result;
                if (data == null) return BadRequest();

                // Parse the query string variables into a NameValueCollection.
                NameValueCollection qscoll = HttpUtility.ParseQueryString(data);
                PayPalViewModel payPalModel = new PayPalViewModel();

                var payPal = payPalModel.ToPayPalVM(qscoll); //HRE IS A EXTENSION METHOD TO MAP to a CLASS

                if (payPal == null) return InternalServerError(new Exception());

                //Try cast total from paypal
                if (!decimal.TryParse(payPal.mc_gross, out tot)) return InternalServerError(new Exception(Constant.Error.PAYMENT_ERROR_TOTAL_CAST));




                // If status is Ok /or Completed
                if (payPal.payment_status.Equals(Constant.PaymentStatus.PAYED) || payPal.payment_status.Equals(Constant.PaymentStatus.COMPLETED))
                {
                    // update payment
                    bool ok = await this.UpdatePayment(order, user);
                    if (!ok) return InternalServerError(new Exception(Constant.Error.PAYMENT_ERROR_UPDATE));
                }

                return Ok(order);
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
                return (Constant.CONFIGURATION_GLOBALS.IS_DEVELOPMENT_MODE)
                  ? InternalServerError(ex)
                  : InternalServerError(new Exception(Constant.Error.ERROR_GENERIC_500));
            }
        }

And my mapper and class PayPalViewModel

  public class PayPalViewModel
    {
        public string mc_gross { get; set; }
        public string custom { get; set; }
        public string payment_status { get; set; }

        public string payment_type { get; set; }
        public string mc_currency { get; set; }

        public string payer_id { get; set; }
        public DateTime payment_date { get; set; }
        public string payment_gross { get; set; }

        /// <summary>
        /// ToPayPalVM From NameValueCollection
        /// </summary>
        /// <returns></returns>
        public PayPalViewModel ToPayPalVM(NameValueCollection qscoll)
        {
            if (qscoll == null) return null;
            DateTime date = DateTime.Now;
            string mcGross = qscoll["mc_gross"];
            string paymentType = qscoll["payment_type"];
            string mcCurrency = qscoll["mc_currency"];
            string paymentStatus = qscoll["payment_status"];
            string payerId = qscoll["payer_id"];
            string paymentDate = qscoll["payment_date"];
            string paymentGross = qscoll["payment_gross"];
            string cust = qscoll["custom"];

            var datePay = DateTime.TryParse(paymentDate, out date);

            return new PayPalViewModel
            {
                mc_gross = mcGross,
                custom = cust,
                payment_status = paymentStatus,
                payment_type = paymentType,
                mc_currency = mcCurrency,
                payer_id = payerId,
                payment_gross = paymentGross,
                payment_date = (datePay) ? date : DateTime.Now
            };
        }
    }
like image 54
federico scamuzzi Avatar answered Oct 22 '22 09:10

federico scamuzzi