Esempio n. 1
0
        public void HandleAuthorizationRequest(NameValueCollection parameters, HttpResponse response)
        {
            logger.Info("Handling /authorize with ExampleAuthorizationHandler");

            logger.Debug("Verifying Signature...");
            bool validSignature = SignatureUtils.Signature(parameters, Constants.SECRET).Equals(parameters["signature"]);

            if (!validSignature)
            {
                /**
                 *  InvalidSignatureException
                 *   Invalid Signature is a special case of exception that throws an HTTP Error.  With the
                 *   exception of Invalid Signature and Internal Server errors, it is expected that the callback
                 *   response be properly formatted XML per the PayNearMe specification.
                 *
                 *   This is a security exception and may highlight a configuration problem (wrong secret or
                 *   siteIdentifier) OR it may highlight a possible payment injection from a source other than
                 *   PayNearMe.  You may choose to notify your IT department when this error class is raised.
                 *   PayNearMe strongly recommends that your callback listeners be whitelisted to ONLY allow
                 *   traffic from PayNearMe IP addresses.
                 *
                 *   When this class of error is raised in a production environment you may choose to not respond
                 *   to PayNearMe, which will trigger a timeout exception, leading to PayNearMe to retry the
                 *   callbacks up to 40 times.  If the error persists, callbacks will be suspended.
                 *
                 *   In development environment this default message will aid with debugging.
                 */

                logger.Error("Invalid signature, declining authorization request.");
            }

            // If the url contains the parameter test=true (part of the signed params too!) then we flag this.
            // Do not handle test=true requests as real requests.
            bool isTest = parameters["test"] != null && Boolean.Parse(parameters["test"]);

            if (isTest)
            {
                logger.Info("This authorize request is a TEST!");
            }

            // Special behavior for testing/demonstration
            string special = parameters["site_order_annotation"];

            if (special != null)
            {
                if (special.StartsWith("confirm_delay_"))
                {
                    int delay = Convert.ToInt32(special.Substring(special.LastIndexOf('_') + 1)) * 1000;
                    logger.Info("Delaying response by " + delay + " seconds");
                    Thread.Sleep(delay);
                }
                else if (special.Equals("confirm_bad_xml"))
                {
                    logger.Info("Responding with bad/broken xml");
                    response.Output.Write("<result");
                    response.Output.Flush();
                    logger.Debug("End handleConfirmationRequest (early: bad xml)");
                    return;
                }
                else if (special.Equals("confirm_blank"))
                {
                    logger.Info("Responding with a blank/empty response");
                    logger.Debug("End handleConfirmationRequest (early: blank response)");
                    return;
                }
                else if (special.Equals("confirm_redirect"))
                {
                    logger.Info("Redirecting to /");
                    response.Redirect("/");
                    logger.Debug("End handleConfirmationRequest (early: redirect)");
                    return;
                }
            }
            else
            {
                logger.Debug("No special behavior specified by site_order_annotation");
            }

            String pnmOrderIdentifier  = parameters["pnm_order_identifier"];
            String siteOrderIdentifier = parameters["site_order_identifier"];

            /* This is where you verify the information sent with the
             * request, validate it within your system, and then return a
             * response. Here we just accept payments with order identifiers of
             * "TEST-123" if the request is test mode.
             */

            AuthorizationResponseBuilder auth = new AuthorizationResponseBuilder("2.0");

            //auth.SitePaymentIdentifier = siteOrderIdentifier;
            auth.PnmOrderIdentifier = pnmOrderIdentifier;

            bool accept = false;

            if (siteOrderIdentifier != null && siteOrderIdentifier.StartsWith("TEST"))
            {
                accept = true;
                logger.Info("Example authorization " + siteOrderIdentifier + " will be ACCEPTED");
            }
            else
            {
                logger.Info("Example authorization " + siteOrderIdentifier + " will be DECLINED");
            }

            if (accept && validSignature)
            {
                auth.AcceptPayment = true;

                /* You can set custom receipt text here (if you want) - if you
                 * don't want custom text, you can omit this
                 */
                auth.Receipt = "Thank you for your order!";
                auth.Memo    = DateTime.Now.ToString();
            }
            else
            {
                auth.AcceptPayment = false;
                auth.Receipt       = "Declined";
                auth.Memo          = "Invalid payment: " + siteOrderIdentifier;
            }

            response.ContentType = "application/xml";

            auth.Build().Save(response.Output);
            response.Output.Flush();

            logger.Debug("End handleAuthorizationRequest");
        }
        public void ProcessRequest(HttpContext context)
        {
            stopWatch.Start();
            logger.Info("Incoming request begin.");
            string req = context.Request.CurrentExecutionFilePath;

            try
            {
                if (req.Equals("/authorize"))
                {
                    IAuthorizationHandler handler = new ExampleAuthorizationHandler();
                    handler.HandleAuthorizationRequest(context.Request.QueryString, context.Response);
                }
                else if (req.Equals("/confirm"))
                {
                    string signature = SignatureUtils.Signature(context.Request.QueryString, Constants.SECRET);
                    if (signature.Equals(context.Request.QueryString["signature"]))
                    {
                        IConfirmationHandler handler = new ExampleConfirmationHandler();
                        handler.HandleConfirmationRequest(context.Request.QueryString, context.Response);
                    }
                    else
                    {
                        /**
                         *  InvalidSignatureException
                         *   Invalid Signature is a special case of exception that throws an HTTP Error.  With the
                         *   exception of Invalid Signature and Internal Server errors, it is expected that the callback
                         *   response be properly formatted XML per the PayNearMe specification.
                         *
                         *   This is a security exception and may highlight a configuration problem (wrong secret or
                         *   siteIdentifier) OR it may highlight a possible payment injection from a source other than
                         *   PayNearMe.  You may choose to notify your IT department when this error class is raised.
                         *   PayNearMe strongly recommends that your callback listeners be whitelisted to ONLY allow
                         *   traffic from PayNearMe IP addresses.
                         *
                         *   When this class of error is raised in a production environment you may choose to not respond
                         *   to PayNearMe, which will trigger a timeout exception, leading to PayNearMe to retry the
                         *   callbacks up to 40 times.  If the error persists, callbacks will be suspended.
                         *
                         *   In development environment this default message will aid with debugging.
                         */

                        logger.Warn("Invalid signature for /confirm");
                        logger.Warn("  Got: " + context.Request.QueryString["signature"] + ", expected: " + signature);
                        throw new RequestException("Invalid signature for /confirm", 400);
                    }
                }
                else
                {
                    throw new RequestException("Callback request not found!", 404);
                }
            }
            catch (RequestException e)
            {
                /**
                 * Internal Server Error
                 *  Internal Server Error is a special case of exception that throws an HTTP Error.  With the exception
                 *  of Invalid Signature and Internal Server errors, it is expected that the callback response be
                 *  properly formatted XML per the PayNearMe specification.
                 *
                 *  When this class of error is raised in a production environment you may choose to not respond to
                 *  PayNearMe, which will trigger a timeout exception, leading to PayNearMe to retry the callbacks up
                 *  to 40 times.  If the error persists, callbacks will be suspended.
                 *
                 *  This error may highlight a server outage in your infrastructure. You may choose to notify your IT
                 *  department when this error class is raised.
                 */
                context.Response.ContentType = "text/plain";
                context.Response.StatusCode  = e.StatusCode;
                context.Response.Output.WriteLine(e.Message);
                context.Response.Output.Flush();
            }

            stopWatch.Stop();
            logger.Info("Request " + req + " handled in " + stopWatch.ElapsedMilliseconds + "ms");
            if (stopWatch.Elapsed.Seconds >= 6)
            {
                logger.Warn("Request was longer than 6 seconds!");
            }
            logger.Info("End Incoming Request.");
        }