This wasn't exactly provided in the samples for processing IPN, so I thought I'd share the pattern I followed to process IPN with a .NET WebApi 2.x endpoint (in my case, this is all in Azure). first, you'll need references to System.Web.Http and System.Net.Http. It breaks down to 3 pretty simple code blocks. >> The controller action -- ReceiveIPN() >> Method to get the body from the content of the IPN POST -- ProcessIpn() >> Method to send the response back to PayPal -- VerifyIpn() in my case, i'm updating my sales system (Dynamics 365 for Sales Engagement) by simply creating a record in a transaction table and then updating that record a bit further down stream. You'll put your own logging in those places. hope you find it helpful as a starting point! [HttpPost] [AllowAnonymous] public IHttpActionResult ReceiveIPN() { //log ipn recieved Guid newId = Guid.NewGuid(); string qs = ProcessIpn(Request, newId); //fire and forget verification Task.Run(() => VerifyIpn(qs, newId)); //reply return Ok(); } private string ProcessIpn(HttpRequestMessage requestMessage, Guid newId) { HttpContent requestContent = requestMessage.Content; string strContent = requestContent.ReadAsStringAsync().Result; //******stuff you don't care about - put your specific logging here****** Entity ppipn = new Entity("kewi_paypalipn"); ppipn["kewi_paypalipnid"] = newId; ppipn["kewi_name"] = "testing paypal ipn"; ppipn["kewi_ipnmessagebody"] = strContent; client.Create(ppipn); //return the body return strContent; } private void VerifyIpn(string qs, Guid recId) { var url = "https://ipnpb.paypal.com/cgi-bin/webscr?cmd=_notify-validate&" + qs; var handler = new HttpClientHandler(); var httpClient = new HttpClient(handler); var requestMessage = new HttpRequestMessage(HttpMethod.Post, url); var responseMessage = httpClient.SendAsync(requestMessage).Result; var result = responseMessage.Content.ReadAsStringAsync().Result; //**** a little more stuff you don't care about... put your logging here******** string[] qsPairs = qs.Split('&'); var custom = ""; decimal trxAmount = 0; var trxId = ""; foreach (string pair in qsPairs) { if (pair.IndexOf("custom", StringComparison.OrdinalIgnoreCase) >= 0) { custom = pair.Split('=')[1]; } if (pair.IndexOf("mc_gross", StringComparison.OrdinalIgnoreCase) >= 0) { trxAmount = decimal.Parse(pair.Split('=')[1]); } if (pair.IndexOf("txn_id", StringComparison.OrdinalIgnoreCase) >= 0) { trxId = pair.Split('=')[1]; } } if (result.ToLower() == "verified") { var ppipn = new Entity("kewi_paypalipn"); ppipn["kewi_paypalipnid"] = recId; ppipn["kewi_ipnresult"] = result.ToLower(); ppipn["kewi_accountlookup"] = new EntityReference{LogicalName = "account", Id = Guid.Parse(custom)}; ppipn["kewi_paymentamount"] = new Money {Value = trxAmount}; ppipn["kewi_merchantservice"] = "PayPal"; ppipn["kewi_paymenttrxid"] = trxId; client.Update(ppipn); } }
... View more