Mark Payment Method as Paid From Return url query parameters.

Posted: January 09, 2019 at 7:13 AM Quote #217832
Hi, I'm trying to set the payment status after order has been paid in an external site and customer redirected back to the site. On site return, the payment site returns http query parameters on the url. I need to capture the "status" query string and set the payment status to paid or another if "status" matches a certain string. The payment site has specified the ipn url for verifying the payment result and it returns the status code. I've followed the paypal standard method in developing the plugin for nopcommerce 4.1 but I feel stuck. Can you help me in the best redirection and verification process so that the order can be marked as completed?
This post/answer is useful
1
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
Posted: January 09, 2019 at 11:21 PM Quote #217855
The Paypal Standard Payment Controller has a routine so it needs to be similar to that

        public IActionResult PDTHandler()

routes are registered via the plugin

            //PDT
            routeBuilder.MapRoute("Plugin.Payments.PayPalStandard.PDTHandler", "Plugins/PaymentPayPalStandard/PDTHandler",
                 new { controller = "PaymentPayPalStandard", action = "PDTHandler" });

when the command line is called

                //PDT, IPN and cancel URL
                ["return"] = $"{storeLocation}Plugins/PaymentPayPalStandard/PDTHandler",
This post/answer is useful
1
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
www.SelectSystems.com.au
Select Systems International is a computer systems technology solution developer and integration service provider.
Posted: January 11, 2019 at 12:25 AM Quote #217891
Hello, I've set up the return url to the PDT handler and also the IPN url for verification. In the payment controller, I have specified the url parameters that are needed for verifying payments but when I'm redirected back to site after payment, I get a 401 unauthorized error Httpcontext exception. How can I fix this error?

An unhandled exception occurred while processing the request.
WebException: The remote server returned an error: (401) Unauthorized.
System.Net.HttpWebRequest.GetResponse()

Stack Query Cookies Headers
WebException: The remote server returned an error: (401) Unauthorized.
System.Net.HttpWebRequest.GetResponse()
Nop.Plugin.Payments.IpayAfrica.IpayAfricaPaymentProcessor.GetPdtDetails(string tx, out Dictionary<string, string> values, out string response)
Nop.Plugin.Payments.IpayAfrica.PaymentIpayAfricaController.PDTHandler()
lambda_method(Closure , object , object[] )
Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor+SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in MiniProfilerMiddleware.cs
Nop.Services.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) in AuthenticationMiddleware.cs
+
            await _next(context);
Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
Nop.Core.Http.InstallUrlMiddleware.Invoke(HttpContext context, IWebHelper webHelper) in InstallUrlMiddleware.cs
+
            await _next(context);
Nop.Core.Http.KeepAliveMiddleware.Invoke(HttpContext context, IWebHelper webHelper) in KeepAliveMiddleware.cs
+
            await _next(context);
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
Nop.Web.Framework.Infrastructure.Extensions.ApplicationBuilderExtensions+<>c.<UseNopExceptionHandler>b__1_1(HttpContext context) in ApplicationBuilderExtensions.cs
+
                        ExceptionDispatchInfo.Throw(exception);
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)


But I can see that the query parameters are being received, and these are the ones that I need for verification purposes

Stack Query Cookies Headers
Variable  Value
afd  **********
agt  
channel  MPESA
hsh  **************************************************************************
id  6
ifd  ************
ivm  6
mc  25.00
msisdn_id  ****** ******
msisdn_idnum  ***********
p1  
p2  
p3  
p4  
poi  *************
qwh  **********
status  aei7p7yrx4ae34
txncd  ***************
uyt  *********


How can I proceed from here as the success status code should be like the one specified in the query
This post/answer is useful
1
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
Posted: January 11, 2019 at 1:05 AM Quote #217894
Not sure I understand but if you have the query parameters being received
Do you mean after making payment you are redirected back to the nopCommerce site ?
i.e. you have a response from the remote server

Then why do you need to do another request of the remote server url in GetPdtDetails which is giving you the error
WebException: The remote server returned an error: (401) Unauthorized.

If you already have the response then just interrogate that response to get the status of the transaction
This post/answer is useful
0
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
www.SelectSystems.com.au
Select Systems International is a computer systems technology solution developer and integration service provider.
Posted: January 11, 2019 at 3:46 AM Quote #217896
How can I do that to remove the error and capture the status response. The new error I'm getting is:

WebException: The remote server returned an error: (401) Unauthorized.
Nop.Web.Framework.Infrastructure.Extensions.ApplicationBuilderExtensions+<>c.<UseNopExceptionHandler>b__1_1(HttpContext context) in ApplicationBuilderExtensions.cs
-
                            EngineContext.Current.Resolve<ILogger>().Error(exception.Message, exception, currentCustomer);
                        }
                    }
                    finally
                    {
                        //rethrow the exception to show the error page
                        throw exception;
                    }
                });
            });
        }
        /// <summary>
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Show raw exception details
System.Net.WebException: The remote server returned an error: (401) Unauthorized.
   at Nop.Web.Framework.Infrastructure.Extensions.ApplicationBuilderExtensions.<>c.<UseNopExceptionHandler>b__1_1(HttpContext context) in F:\My Sites\nopCommerce-master\src\Presentation\Nop.Web.Framework\Infrastructure\Extensions\ApplicationBuilderExtensions.cs:line 83
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
This post/answer is useful
0
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
Posted: January 11, 2019 at 6:47 AM Quote #217901
So I assume you have been looking at this page

https://dev.ipayafrica.com/

So you got the successful response = aei7p7yrx4ae34

You get need to that out of the query string received and act on the values and write to the order
You have the id for the order you sent

As a quick example you could do Something like

                    //mark order as paid
                    if (Status == Success) // aei7p7yrx4ae34
                    {
                        // Read the order from the id

                        var order = GetOrderById(int orderId)

                        if (_orderProcessingService.CanMarkOrderAsPaid(order))
                        {
                            order.AuthorizationTransactionId = txn_id;

                            _orderService.UpdateOrder(order);

                            _orderProcessingService.MarkOrderAsPaid(order);
                        }
                    }

Also there are other fields in the order you can also use to store info as required

i.e.        
        public string AuthorizationTransactionCode { get; set; }
        public string AuthorizationTransactionResult { get; set; }
        public string CaptureTransactionId { get; set; }
        public string CaptureTransactionResult { get; set; }
        public string SubscriptionTransactionId { get; set; }
        public DateTime? PaidDateUtc { get; set; }
This post/answer is useful
1
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
www.SelectSystems.com.au
Select Systems International is a computer systems technology solution developer and integration service provider.
Posted: January 12, 2019 at 10:36 AM Quote #217935
Thanks so much. Let me try to implement this guide
This post/answer is useful
0
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
Posted: January 27, 2019 at 10:31 AM Quote #218409
Finally, I managed to get through this. I assigned values to new variables from the returning query parameters using HttpContext.Request.Query[""] and I using streamreader to read the response from the verification url

                string verify_url = "verification_url";

                string html = string.Empty;
                string url = verify_url;
              
                //use web request to read the response from verification_url
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (Stream stream = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(stream))
                {
                    html = reader.ReadToEnd();
                }
                if (html.Contains("success_code")
                {
                    if (_orderProcessingService.CanMarkOrderAsPaid(order))
                    {
                        _orderProcessingService.MarkOrderAsPaid(order);
                    }
                    return RedirectToRoute("CheckoutCompleted", new { orderId = order.Id });
                }
                else
                {
                    return //something else;
                }


I hope this might help someone else. Thanks.
This post/answer is useful
2
This post/answer is not useful

Please login or register
to vote for this post.

(click on this box to dismiss)
Premium support services
  • Dedicated premium support services provided by core developers are intended for persons who run mission critical websites, work on projects with tight deadlines, or want to get dedicated support.
Professional services
  • Want to open a new store? Want to take your store to the next level? Need a custom extension? We can customize nopCommerce to fit your store perfectly. Request a quote to get started.