/// <summary> /// handles the server-to-server transaction happening when cartasì wants to report the end of a transaction /// </summary> /// <param name="qs"></param> /// <returns></returns> public string HandleS2STransaction(NameValueCollection qs) { var settings = _orchardServices.WorkContext.CurrentSite.As <PaymentCartaSiSettingsPart>(); //this is the method where the transaction information is trustworthy StringBuilder sr = new StringBuilder(); int paymentId = 0; //assign here because compiler does not understand that we won't use this without assigning it first bool validMessage = !string.IsNullOrWhiteSpace(qs["codTrans"]) && int.TryParse(qs["codTrans"].Replace("LASER", ""), out paymentId); //has an id validMessage = validMessage && !string.IsNullOrWhiteSpace(qs["esito"]); //has a result validMessage = validMessage && !string.IsNullOrWhiteSpace(qs["alias"]) && qs["alias"] == settings.CartaSiShopAlias; //has right shop alias //Logger.Error("HandleS2STransaction: " + paymentId.ToString()); if (validMessage) { PaymentOutcomeMessage pom = new PaymentOutcomeMessage(qs); pom.secret = settings.CartaSiSecretKey; //sr.Clear(); sr.AppendLine("HandleS2STransaction: MESSAGE VALID"); sr.AppendLine(pom.ToString()); //Logger.Error(sr.ToString()); try { Validator.ValidateObject(pom, new ValidationContext(pom), true); } catch (Exception ex) { //Logger.Error(ex.Message); //throw ex; LocalizedString error = T(@"Transaction information not valid for transaction {0}: {1}", paymentId.ToString(), ex.Message); //Log the error sr.AppendLine(string.Format("ERROR: {0}", error.Text)); //Logger.Error(error.Text); //throw new Exception(error.Text); //We do not update the PaymentRecord here, because we have been unable to verify the hash that we received } //Logger.Error("HandleS2STransaction: VALIDATION PASSED"); //verify the hash if (pom.PaymentOutcomeMAC == qs["mac"]) { //transaction valid //update the PaymentRecord for this transaction //TODO: add to info the decoding of the pom.codiceEsito based off the codetables string info = CodeTables.ErrorCodes[int.Parse(pom.codiceEsito)]; EndPayment(paymentId, pom.esito == "OK", pom.codiceEsito, pom.messaggio + (string.IsNullOrWhiteSpace(info) ? "" : (" " + info))); //Logger.Error(string.Format(@"Payment {0} S2S outcome {1}", paymentId.ToString(), pom.esito)); //return the URL of a suitable error page (call this.GetPaymentInfoUrl after inserting the error in the PaymentRecord) return(pom.esito); } else { LocalizedString error = T("HandleS2STransaction: MAC NOT VALID:\nComputed: {0}\nReceived: {1}", pom.PaymentOutcomeMAC, qs["mac"]); sr.AppendLine(string.Format("ERROR: {0}", error.Text)); } } Logger.Error(sr.ToString()); throw new Exception(string.Format("Transaction message not valid: codTrans: {0}, esito: {1}, alias: {2}", qs["codTrans"] ?? "null", qs["esito"] ?? "null", qs["alias"] ?? "null")); }
/// <summary> /// Gets the inforation about the transaction result back from CartaSì and returns an URL showing the transaction's result. /// Depending on the way the transaction was set, this may not actually be an url. /// </summary> /// <param name="qs">The query string received in the attempt by CartaSì to redirect the browser.</param> /// <returns>The Url for the transaction results.</returns> public string HandleOutcomeTransaction(NameValueCollection qs) { //transaction information here may not be trustworthy int paymentId; if (!string.IsNullOrWhiteSpace(qs["codTrans"]) && int.TryParse(qs["codTrans"].Replace("LASER", ""), out paymentId)) { PaymentOutcomeMessage pom = new PaymentOutcomeMessage(qs); PaymentRecord pRecord = GetPaymentInfo(paymentId); if (pRecord != null) { return(GetPaymentInfoUrl(paymentId)); } } LocalizedString error = T("Impossible to identify transaction. There was a communication error between CartaSì and our servers"); Logger.Error(error.Text); throw new Exception(error.Text); }