private void VerifyTask(IPNLocalContext ipnContext)
        {
            try
            {
                //var verificationRequest = System.Net.WebRequest.Create("https://ipnpb.sandbox.paypal.com/cgi-bin/webscr");

                var verificationRequest = System.Net.WebRequest.Create("https://ipnpb.paypal.com/cgi-bin/webscr");

                //Send response messages back to PayPal:

                //https://ipnpb.sandbox.paypal.com/cgi-bin/webscr (for Sandbox IPNs)
                //https://ipnpb.paypal.com/cgi-bin/webscr (for live IPNs)

                //Set values for the verification request
                verificationRequest.Method      = "POST";
                verificationRequest.ContentType = "application/x-www-form-urlencoded";

                //Add cmd=_notify-validate to the payload
                string strRequest = "cmd=_notify-validate&" + ipnContext.RequestBody;
                verificationRequest.ContentLength = strRequest.Length;

                //Attach payload to the verification request
                using (StreamWriter writer = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII))
                {
                    writer.Write(strRequest);
                }

                //Send the request to PayPal and get the response
                using (StreamReader reader = new StreamReader(verificationRequest.GetResponse().GetResponseStream()))
                {
                    ipnContext.Verification = reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                PaypalErrors error = new PaypalErrors
                {
                    Exception = ex.Message,
                    DateTime  = DateTime.Now
                };

                _dbcontext.PaypalErrors.Add(error);
                _dbcontext.SaveChanges();
            }

            ProcessVerificationResponse(ipnContext);
        }
 private void ProcessVerificationResponse(IPNLocalContext ipnContext)
 {
     if (ipnContext.Verification.Equals("VERIFIED"))
     {
         // check that Payment_status=Completed
         // check that Txn_id has not been previously processed
         // check that Receiver_email is your Primary PayPal email
         // check that Payment_amount/Payment_currency are correct
         // process payment
     }
     else if (ipnContext.Verification.Equals("INVALID"))
     {
         //Log for manual investigation
     }
     else
     {
         //Log error
     }
 }
        public async Task <IActionResult> Receive()
        {
            try
            {
                IPNLocalContext ipnContext = new IPNLocalContext()
                {
                    IPNRequest = Request
                };

                using (StreamReader reader = new StreamReader(ipnContext.IPNRequest.Body, Encoding.ASCII))
                {
                    ipnContext.RequestBody = reader.ReadToEnd();
                }

                //Store the IPN received from PayPal
                await LogAndEmailRequest(ipnContext);

                //React backend as per IPN Received
                await UpdateSubscription(ipnContext);

                //Fire and forget verification task
                VerifyTask(ipnContext);

                //Reply back a 200 code
                return(Ok());
            }
            catch (Exception)
            {
                await EmailSuperAdmin(Request.ToString(), "IPN Send back PayPal failed");

                PaypalErrors error = new PaypalErrors
                {
                    Exception = Request.ToString(),
                    DateTime  = DateTime.Now
                };

                _dbcontext.PaypalErrors.Add(error);
                _dbcontext.SaveChanges();

                return(Ok());
            }
        }
        private async Task LogAndEmailRequest(IPNLocalContext ipnContext)
        {
            var sendEmailsAndLog = true;

            // Persist the request values into a database or temporary data store
            IPNContext ipn = new IPNContext
            {
                RequestBody  = ipnContext.RequestBody,
                Verification = ipnContext.Verification
            };


            if (ipn != null && ipn.RequestBody != null)
            {
                var response = ipn.RequestBody;
                var keys     = response.Split('&');
                var data     = new Dictionary <string, string>();
                foreach (var key in keys)
                {
                    //payment_type = instant
                    var field = key.Split('=');
                    data.Add(field[0], field[1]);
                }


                if (data["txn_type"] == "recurring_payment_profile_created")
                {
                    if (data.ContainsKey("initial_payment_status"))
                    {
                        if (data["initial_payment_status"] == "Completed")
                        {
                            //do not send email
                            sendEmailsAndLog = true;
                        }
                    }
                }

                if (data["txn_type"] == "recurring_payment")
                {
                    if (data.ContainsKey("payment_status"))
                    {
                        if (data["payment_status"] == "Completed")
                        {
                            //do not send email
                            sendEmailsAndLog = true;
                        }
                    }
                }

                //An existing customer has decided to cancel. Set Expiry date on the subscription.
                if (data["txn_type"] == "recurring_payment_profile_cancel")
                {
                    //do not send email
                    sendEmailsAndLog = true;
                }

                //An existing customer has SKIPPED their payment. NO ACTION REQUIRED AT THE MOMENT..
                if (data["txn_type"] == "recurring_payment_skipped")
                {
                    //do not send email
                    sendEmailsAndLog = true;
                }


                //A new customer tried to subscribed but their payment is PENDING. Delete their subscription on the website and on PayPal side.
                if (data["txn_type"] == "recurring_payment_profile_created")
                {
                    if (data.ContainsKey("initial_payment_status"))
                    {
                        if (data["initial_payment_status"] == "Pending")
                        {
                            //do not send email
                            sendEmailsAndLog = true;
                        }
                    }
                }

                if (sendEmailsAndLog)
                {
                    //send email
                    var message = BuildEmailMessage(ipn);
                    var subject = BuildEmailSubject(ipn);
                    await EmailAdmin(message, subject);

                    _dbcontext.IPNContexts.Add(ipn);
                    _dbcontext.SaveChanges();
                }
            }
        }
        private async Task UpdateSubscription(IPNLocalContext ipn)
        {
            if (ipn != null && ipn.RequestBody != null)
            {
                var response = ipn.RequestBody;
                var keys     = response.Split('&');
                var data     = new Dictionary <string, string>();
                foreach (var key in keys)
                {
                    //payment_type = instant
                    var field = key.Split('=');
                    data.Add(field[0], field[1]);
                }


                //cancel Reversed transactions.
                if (data.ContainsKey("payment_status"))
                {
                    if (data["payment_status"] == "Reversed")
                    {
                        //update database
                        var payPalAgreement = data["recurring_payment_id"];

                        if (!String.IsNullOrEmpty(payPalAgreement))
                        {
                            await ReversedPaymentFound(payPalAgreement);
                            await TellPayPalToCancelSubscription(payPalAgreement);
                        }
                    }
                }


                if (data["txn_type"] == "recurring_payment_profile_created")
                {
                    //A new customer tried to subscribed but their payment failed. Delete their subscription on the website and on PayPal side.
                    if (data.ContainsKey("initial_payment_status"))
                    {
                        if (data["initial_payment_status"] == "Failed")
                        {
                            //update database
                            var payPalAgreement = data["recurring_payment_id"];

                            if (!String.IsNullOrEmpty(payPalAgreement))
                            {
                                await NewSubscriptionFirstPaymentFailedDeleteSubscription(payPalAgreement);
                                await TellPayPalToCancelSubscription(payPalAgreement);
                            }
                        }

                        //A new customer has just successfully subscribed.
                        if (data["initial_payment_status"] == "Completed")
                        {
                            //update database for start date.
                            var payPalAgreement = data["recurring_payment_id"];

                            if (!String.IsNullOrEmpty(payPalAgreement))
                            {
                                await NewSubscriptionUpdateStartDate(payPalAgreement);
                            }
                            else
                            {
                                var type   = data["txn_type"];
                                var status = data["initial_payment_status"];
                                await EmailSuperAdmin($"Null Agreement: IPN Type: {type}  Payment Status : {status}", "Null Agreement");
                            }
                        }

                        //A new customer tried to subscribed but their payment is PENDING. Delete their subscription on the website and on PayPal side.
                        if (data["initial_payment_status"] == "Pending")
                        {
                            //update database
                            var payPalAgreement = data["recurring_payment_id"];

                            if (!String.IsNullOrEmpty(payPalAgreement))
                            {
                                await NewSubscriptionFirstPaymentPendingDeleteSubscription(payPalAgreement);
                                await TellPayPalToCancelSubscription(payPalAgreement);
                            }
                        }
                    }
                }

                ////A new customer has just successfully subscribed.
                //if (data["txn_type"] == "recurring_payment_profile_created")
                //{
                //    if (data.ContainsKey("initial_payment_status"))
                //    {
                //        if (data["initial_payment_status"] == "Completed")
                //        {
                //            //update database for start date.
                //            var payPalAgreement = data["recurring_payment_id"];

                //            if (!String.IsNullOrEmpty(payPalAgreement))
                //            {
                //                await NewSubscriptionUpdateStartDate(payPalAgreement);
                //            }
                //            else
                //            {
                //                var type = data["txn_type"];
                //                var status = data["initial_payment_status"];
                //                await EmailSuperAdmin($"Null Agreement: IPN Type: {type}  Payment Status : {status}", "Null Agreement");
                //            }
                //        }
                //    }
                //}

                ////A new customer tried to subscribed but their payment is PENDING. Delete their subscription on the website and on PayPal side.
                //if (data["txn_type"] == "recurring_payment_profile_created")
                //{
                //    if (data.ContainsKey("initial_payment_status"))
                //    {
                //        if (data["initial_payment_status"] == "Pending")
                //        {
                //            //update database
                //            var payPalAgreement = data["recurring_payment_id"];

                //            if (!String.IsNullOrEmpty(payPalAgreement))
                //            {
                //                await NewSubscriptionFirstPaymentPendingDeleteSubscription(payPalAgreement);
                //                await TellPayPalToCancelSubscription(payPalAgreement);
                //            }
                //        }
                //    }
                //}

                //An existing customer has just renewed their subscription.
                if (data["txn_type"] == "recurring_payment")
                {
                    if (data.ContainsKey("payment_status"))
                    {
                        if (data["payment_status"] == "Completed")
                        {
                            //update database for start date.
                            var payPalAgreement = data["recurring_payment_id"];

                            if (!String.IsNullOrEmpty(payPalAgreement))
                            {
                                await NewSubscriptionUpdateStartDate(payPalAgreement);
                            }
                        }
                    }
                }

                //An existing customer has cancelled. Either Update or delete Subscription

                if (data["txn_type"] == "recurring_payment_profile_cancel")
                {
                    if ((!data.ContainsKey("initial_payment_status")))
                    {
                        if ((data.ContainsKey("profile_status")))
                        {
                            if (data["profile_status"] == "Cancelled")
                            {
                                var payPalAgreement = data["recurring_payment_id"];

                                //update profile and allow access until expired.
                                if (!String.IsNullOrEmpty(payPalAgreement))
                                {
                                    await ExistingSubscriptionHasbeenCancelledUpdateSubscription(payPalAgreement);
                                }
                                else
                                {
                                    var type   = data["txn_type"];
                                    var status = data["initial_payment_status"];
                                    await EmailSuperAdmin($"Null Agreement: IPN Type: {type}  Payment Status : {status}", "Update failed due to Null Agreement");
                                }
                            }
                        }
                    }

                    if ((data.ContainsKey("initial_payment_status")))
                    {
                        if (data["initial_payment_status"] == "Failed")
                        {
                            var payPalAgreement = data["recurring_payment_id"];

                            //ACTION : Remove subscription completly.
                            if (!String.IsNullOrEmpty(payPalAgreement))
                            {
                                await ExistingSubscriptionPaymentFailedUpdateSubscription(payPalAgreement);
                            }
                            else
                            {
                                var type   = data["txn_type"];
                                var status = data["initial_payment_status"];
                                await EmailSuperAdmin($"Null Agreement: IPN Type: {type}  Payment Status : {status}", "Delete failed due to Null Agreement");
                            }
                        }
                    }
                }

                //An existing customer has DENIED their payment. DEELTE Subscription.
                if ((data["txn_type"] == "recurring_payment") && (data["payment_status"] == "Denied"))
                {
                    //update database
                    var payPalAgreement = data["recurring_payment_id"];

                    if (!String.IsNullOrEmpty(payPalAgreement))
                    {
                        await ExistingSubscriptionPaymentHasbeenDeniedUpdateSubscription(payPalAgreement);
                        await TellPayPalToCancelSubscription(payPalAgreement);
                    }
                }


                //An existing customer has FAILED 3 PAYMENTS. Delete Subscription.
                if (data["txn_type"] == "recurring_payment_failed")
                {
                    //update database
                    var payPalAgreement = data["recurring_payment_id"];

                    if (!String.IsNullOrEmpty(payPalAgreement))
                    {
                        await ExistingSubscriptionPaymentFailedUpdateSubscription(payPalAgreement);
                        await TellPayPalToCancelSubscription(payPalAgreement);
                    }
                }


                //An existing customer has FAILED 3 PAYMENTS. Delete Subscription.
                if (data["txn_type"] == "recurring_payment_suspended_due_to_max_failed_payment")
                {
                    //update database
                    var payPalAgreement = data["recurring_payment_id"];

                    if (!String.IsNullOrEmpty(payPalAgreement))
                    {
                        await ExistingSubscriptionPaymentFailedMaxFailedPaymentsUpdateSubscription(payPalAgreement);
                        await TellPayPalToCancelSubscription(payPalAgreement);
                    }
                }

                //An existing customer has SKIPPED their payment. NO ACTION REQUIRED AT THE MOMENT..
                if (data["txn_type"] == "recurring_payment_skipped")
                {
                    // NO ACTION REQURIED.
                }
            }
        }