/// <summary> /// /// </summary> /// <param name="vendor"></param> /// <param name="postedData"></param> public HttpResponseMessage PostTransactionByIpn([FromUri] string id, [FromBody] FormDataCollection postedData) { var vendorId = Guid.Parse(id); var txn = new Transaction(); var d = postedData.ReadAsNameValueCollection(); //To calculate 'handshake', run 'md5 -s [password]', then 'md5 -s [email protected][Last MD5 result]' string handshakeParameter = d.Pluck("handshake", null); if (handshakeParameter == null) { throw new Exception("Missing parameter 'handshake'."); } using (var dataContext = dataContextFactory.Create()) { var vendor = dataContext.Vendors.Where(v => v.ObjectId == vendorId) .Include(v => v.VendorCredentials) .FirstOrDefault(); if (vendor == null) { throw new Exception("Could not find vendor with id: " + vendorId); } string[] vendorCredentials = vendor.VendorCredentials.Select( c => Encoding.UTF8.GetString(SymmetricEncryption.DecryptForDatabase(c.CredentialValue)).ToLower()).ToArray(); if (!vendorCredentials.Contains(handshakeParameter.ToLower())) { throw new Exception("Invalid handshake provided"); } } string txn_id = d.Pluck("txn_id"); //TODO: We must ignore duplicate POSTs with the same txn_id - all POSTs will contain the same information if (!"Completed".Equals(d.Pluck("payment_status"), StringComparison.OrdinalIgnoreCase)) { throw new Exception("Only completed transactions should be sent to this URL"); } //var txn = new Transaction(); txn.VendorId = vendorId; txn.ExternalTransactionId = txn_id; txn.PaymentDate = ConvertPayPalDateTime(d.Pluck("payment_date")); txn.PayerEmail = d.Pluck("payer_email"); txn.PassThroughData = d.Pluck("custom"); txn.Currency = d.Pluck("mc_currency"); txn.InvoiceId = d.Pluck("invoice"); txn.Gross = d.Pluck <double>("mc_gross"); txn.TransactionFee = d.Pluck <double>("mc_fee"); txn.Tax = d.Pluck <double>("tax"); txn.TransactionType = d.Pluck("transaction_type"); if (d["payer_name"] == null) { d["payer_name"] = d["first_name"] + " " + d["last_name"]; } txn.Billing = ParseFrom(d, "payer_"); txn.Shipping = ParseFrom(d, "address_"); var itemCount = d.Pluck <int>("num_cart_items", 1); txn.Items = new List <TransactionItem>(); for (var i = 1; i <= itemCount; i++) { string suffix = i.ToString(); var item = new TransactionItem(); item.Gross = d.Pluck <double>("mc_gross_" + i.ToString()).Value; item.ItemName = d.Pluck("item_name" + i.ToString()); item.SkuString = d.Pluck("item_number" + i.ToString()); item.Options = new List <KeyValuePair <string, string> >(); for (var j = 1; j < 4; j++) { string opt_key = d.Pluck("option_name" + j.ToString() + "_" + i.ToString()); string opt_val = d.Pluck("option_selection" + j.ToString() + "_" + i.ToString()); if (string.IsNullOrEmpty(opt_val)) { continue; } item.Options.Add(new KeyValuePair <string, string>(opt_key, opt_val)); } var qty = d.Pluck <int>("quantity" + i.ToString(), 1).Value; for (var j = 0; j < qty; j++) { txn.Items.Add(item.DeepCopy()); } } if (!string.IsNullOrEmpty(d["gc_xml"])) { txn.ProcessorXml = new XmlDocument(); txn.ProcessorXml.LoadXml(d.Pluck("gc_xml")); } txn.Other = d; //All transactions go through TransactionController using (var basket = BasketWrapper.CreateNewByVendor(dataContextFactory, vendorId)) { base.ProcessTransaction(txn.ToTransactionRequest(dataContextFactory), basket); } return(new HttpResponseMessage(HttpStatusCode.OK)); }
/// <summary> /// /// </summary> /// <param name="vendor"></param> /// <param name="postedData"></param> public HttpResponseMessage PostTransactionByIpn([FromUri]string id, [FromBody]FormDataCollection postedData) { var vendorId = Guid.Parse(id); var txn = new Transaction(); var d = postedData.ReadAsNameValueCollection(); //To calculate 'handshake', run 'md5 -s [password]', then 'md5 -s [email protected][Last MD5 result]' string handshakeParameter = d.Pluck("handshake",null); if (handshakeParameter == null) throw new Exception("Missing parameter 'handshake'."); using (var dataContext = dataContextFactory.Create()) { var vendor = dataContext.Vendors.Where(v => v.ObjectId == vendorId) .Include(v => v.VendorCredentials) .FirstOrDefault(); if (vendor == null) throw new Exception("Could not find vendor with id: " + vendorId); string[] vendorCredentials = vendor.VendorCredentials.Select( c => Encoding.UTF8.GetString(SymmetricEncryption.DecryptForDatabase(c.CredentialValue)).ToLower()).ToArray(); if (!vendorCredentials.Contains(handshakeParameter.ToLower())) throw new Exception("Invalid handshake provided"); } string txn_id = d.Pluck("txn_id"); //TODO: We must ignore duplicate POSTs with the same txn_id - all POSTs will contain the same information if (!"Completed".Equals(d.Pluck("payment_status"), StringComparison.OrdinalIgnoreCase)) throw new Exception("Only completed transactions should be sent to this URL"); //var txn = new Transaction(); txn.VendorId = vendorId; txn.ExternalTransactionId = txn_id; txn.PaymentDate = ConvertPayPalDateTime(d.Pluck("payment_date")); txn.PayerEmail = d.Pluck("payer_email"); txn.PassThroughData = d.Pluck("custom"); txn.Currency = d.Pluck("mc_currency"); txn.InvoiceId = d.Pluck("invoice"); txn.Gross = d.Pluck<double>("mc_gross"); txn.TransactionFee = d.Pluck<double>("mc_fee"); txn.Tax = d.Pluck<double>("tax"); txn.TransactionType = d.Pluck("transaction_type"); if (d["payer_name"] == null) d["payer_name"] = d["first_name"] + " " + d["last_name"]; txn.Billing = ParseFrom(d,"payer_"); txn.Shipping = ParseFrom(d,"address_"); var itemCount = d.Pluck<int>("num_cart_items",1); txn.Items = new List<TransactionItem>(); for (var i = 1; i <= itemCount; i++) { string suffix = i.ToString(); var item = new TransactionItem(); item.Gross = d.Pluck<double>("mc_gross_" + i.ToString()).Value; item.ItemName = d.Pluck("item_name" + i.ToString()); item.SkuString = d.Pluck("item_number" + i.ToString()); item.Options = new List<KeyValuePair<string, string>>(); for (var j = 1; j < 4; j++) { string opt_key = d.Pluck("option_name" + j.ToString() + "_" + i.ToString()); string opt_val = d.Pluck("option_selection" + j.ToString() + "_" + i.ToString()); if (string.IsNullOrEmpty(opt_val)) continue; item.Options.Add(new KeyValuePair<string, string>(opt_key, opt_val)); } var qty = d.Pluck<int>("quantity" + i.ToString(),1).Value; for(var j = 0; j < qty; j++) txn.Items.Add(item.DeepCopy()); } if (!string.IsNullOrEmpty(d["gc_xml"])){ txn.ProcessorXml = new XmlDocument(); txn.ProcessorXml.LoadXml(d.Pluck("gc_xml")); } txn.Other = d; //All transactions go through TransactionController using (var basket = BasketWrapper.CreateNewByVendor(dataContextFactory, vendorId)) { base.ProcessTransaction(txn.ToTransactionRequest(dataContextFactory), basket); } return new HttpResponseMessage(HttpStatusCode.OK); }