I've got FastTrack working now with my existing Umbraco site (U 7.4.3, M 2.1.0, FT 2.1.0), but I have a new problem and a question or two.
I have been running the site from within VS2015 in debug mode. This has been working just fine, and I've been able to process transactions on a PayPal Sandbox account successfully.
I've just copied my site from my desktop to our development server so that the client can see how the project is coming along. Everything seems to work until the point where you click the Pay Now PayPal button. When you click the button the current page just gets reloaded. This was working on my desktop.
There's nothing in the Umbraco log, but in the server log I have the following:
Application information:
Application domain: /LM/W3SVC/4/ROOT-4-131141928384472225
Trust level: Full
Application Virtual Path: /
Application Path: C:\inetpub\vhosts\xxxx\
Machine name: WIN-31OTGVUD76F
Process information:
Process ID: 1972
Process name: w3wp.exe
Account name: NT AUTHORITY\NETWORK SERVICE
Exception information:
Exception type: NullReferenceException
Exception message: PaymentMethod was null
at Merchello.Web.Controllers.CheckoutPaymentControllerBase`1.HandlePaymentException(TPaymentModel model, Exception ex)
at Merchello.Web.Store.Controllers.Payment.PayPalExpressPaymentController.Process(StorePaymentModel model)
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Request information:
Request URL: http://xxxx/umbraco/RenderMvc
Request path: /umbraco/RenderMvc
User host address: 79.78.36.171
User:
Is authenticated: False
Authentication Type:
Thread account name: NT AUTHORITY\NETWORK SERVICE
Thread information:
Thread ID: 142
Thread account name: NT AUTHORITY\NETWORK SERVICE
Is impersonating: False
Stack trace: at Merchello.Web.Controllers.CheckoutPaymentControllerBase`1.HandlePaymentException(TPaymentModel model, Exception ex)
at Merchello.Web.Store.Controllers.Payment.PayPalExpressPaymentController.Process(StorePaymentModel model)
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
The relevant bit would seem to be:
Exception type: NullReferenceException
Exception message: PaymentMethod was null
I haven't been able to find any hard coded paths or anything like that, I'm using the same database as I was from my desktop, I have just modified the connection string - but the rest of the site works so I don't think it can be that. I've set the permissions on the entire site folder to be wide open just in case it's that, but no joy.
Any suggestions would be appreciated.
My other questions are:
Merchello seems to mark the transaction as successful before it completes the PayPal payment process. Is that right or have I missed something? Seems like the wrong way to do it ...
Also I need to find an event that gets fired once a payment has been made successfully as I need to add details of the transaction to a separate CRM system (SalesForce). I've written the library I need to communicate with the SalesForce system, just need to find the right trigger in Merchello when the transaction is complete and all the transaction and customer information is available so I can inject it into SalesForce. Any ideas?
In the merchPayment table, can you find one of the failed (erroring) payments and look in the extendedData field. The PayPal provider saves a record of each transaction with PayPal in a JSON object stored there.
This may give you a better idea of what is happening between environments.
Merchello actually does two transactions when paying with PayPal - the first is authorize (when it redirects) and the second is the capture when it comes back successful. The authorize transaction is completed almost immediately but the capture transaction (in your scenario) probably has not started.
In the event of a failed transaction on PayPal, Merchello will delete the authorize attempt so that it can repeat the attempt ...
<extendedData>
<paypalexpresstransaction>
{
"Success":false,
"Data":
{
"Token":"",
"CurrencyCode":"GBP",
"PayerId":"",
"CheckoutPaymentTransactionId":null,
"AuthorizationTransactionId":"",
"AuthorizedAmount":"",
"CaptureTransactionId":"",
"CurrencyId":"",
"Authorized":false
},
"SetExpressCheckout":
{
"Token":null,
"Ack":6,
"Version":null,
"Build":null,
"ErrorTypes":[
{
"ShortMessage":"Invalid HTTP response The underlying connection was closed: An unexpected error occurred on a receive.",
"LongMessage":"Invalid HTTP response The underlying connection was closed: An unexpected error occurred on a receive.",
"ErrorCode":"PPEService",
"SeverityCode":3,"ErrorParameters":[]
}],
"RedirectUrl":null
},
"GetExpressCheckoutDetails":null,
"DoExpressCheckoutPayment":null,
"DoAuthorization":null,
"DoCapture":null,
"RefundTransactions":[]
}
</paypalexpresstransaction>
</extendedData>
After a bit of Googling I've found a couple of others with the same problem, but no fix. The opinion seems to be that the initial connection to PayPal to get an authorisation token is failing.
This has to be something about the specific server I am running it on. The same code (same database, exact copy of source files) runs perfectly happily in debug mode in VS2015. So it must be to do with some dependency on the server that needs updating, or something like that I think.
It looks like the initial connection to PayPal is not being established - That's the "SetExpressCheckout". It basically authenticates with PayPal and gets a token.
Do you have firewall that is blocking outgoing requests (or maybe some overbearing anti-virus app)?
I wondered about the firewall, so I disabled it - no change. This is running on a Windows Web Server 2008, and I transferred the site from my development box by a simple copy of the files at the root of the site. Is there anything outside of that file structure, or is there anything that needs to be registered with the operating system to work?
It might be useful to be able to get at any inner exception being throws, as that might give us more of a clue ...
The routing to the server is handled by our router using NAT to redirect an outside IP address to the server. I've explicitly opened port 443, but that hasn't helped yet, and I can view https web pages from a browser running on the server.
Does the initial authorization token request use a different port? We've demilitarized the router so it should now be passing all ports backwards and forwards, but just in case there is something odd I've missed ...
Clutching at straws a bit here.
Is it an encryption issue of some sort? Does the plugin require something that isn't routinely installed on IIS 7?
PayPal requires TLS 1.1 (and 1.2 June 2017!) and as far as I understand you have a Windows Server 2008. TLS 1.1 (better you use 1.2) is only supported from 2008 R2 and up ;-).
I think that seems like quite a likely explanation. I'm not in a position to upgrade this server terribly easily, but it's only a testing server anyway, not the final platform, so I'm going to continue on the basis that this is the answer and that it will work on the real box.
PayPal Pay Now raises PaymentMethod was null error
Hi,
I've got FastTrack working now with my existing Umbraco site (U 7.4.3, M 2.1.0, FT 2.1.0), but I have a new problem and a question or two.
I have been running the site from within VS2015 in debug mode. This has been working just fine, and I've been able to process transactions on a PayPal Sandbox account successfully.
I've just copied my site from my desktop to our development server so that the client can see how the project is coming along. Everything seems to work until the point where you click the Pay Now PayPal button. When you click the button the current page just gets reloaded. This was working on my desktop.
There's nothing in the Umbraco log, but in the server log I have the following:
The relevant bit would seem to be:
I haven't been able to find any hard coded paths or anything like that, I'm using the same database as I was from my desktop, I have just modified the connection string - but the rest of the site works so I don't think it can be that. I've set the permissions on the entire site folder to be wide open just in case it's that, but no joy.
Any suggestions would be appreciated.
My other questions are:
Merchello seems to mark the transaction as successful before it completes the PayPal payment process. Is that right or have I missed something? Seems like the wrong way to do it ...
Also I need to find an event that gets fired once a payment has been made successfully as I need to add details of the transaction to a separate CRM system (SalesForce). I've written the library I need to communicate with the SalesForce system, just need to find the right trigger in Merchello when the transaction is complete and all the transaction and customer information is available so I can inject it into SalesForce. Any ideas?
Cheers,
Crac
Hey Crac,
In the merchPayment table, can you find one of the failed (erroring) payments and look in the extendedData field. The PayPal provider saves a record of each transaction with PayPal in a JSON object stored there.
This may give you a better idea of what is happening between environments.
Merchello actually does two transactions when paying with PayPal - the first is authorize (when it redirects) and the second is the capture when it comes back successful. The authorize transaction is completed almost immediately but the capture transaction (in your scenario) probably has not started.
In the event of a failed transaction on PayPal, Merchello will delete the authorize attempt so that it can repeat the attempt ...
Hi Rusty,
Thanks for getting back to me.
I had a look in the merchPayment table:
After a bit of Googling I've found a couple of others with the same problem, but no fix. The opinion seems to be that the initial connection to PayPal to get an authorisation token is failing.
This has to be something about the specific server I am running it on. The same code (same database, exact copy of source files) runs perfectly happily in debug mode in VS2015. So it must be to do with some dependency on the server that needs updating, or something like that I think.
Any clues would be appreciated.
Cheers,
Crac
It looks like the initial connection to PayPal is not being established - That's the "SetExpressCheckout". It basically authenticates with PayPal and gets a token.
Do you have firewall that is blocking outgoing requests (or maybe some overbearing anti-virus app)?
I wondered about the firewall, so I disabled it - no change. This is running on a Windows Web Server 2008, and I transferred the site from my development box by a simple copy of the files at the root of the site. Is there anything outside of that file structure, or is there anything that needs to be registered with the operating system to work?
It might be useful to be able to get at any inner exception being throws, as that might give us more of a clue ...
Cheers,
Crac
The routing to the server is handled by our router using NAT to redirect an outside IP address to the server. I've explicitly opened port 443, but that hasn't helped yet, and I can view https web pages from a browser running on the server.
Does the initial authorization token request use a different port? We've demilitarized the router so it should now be passing all ports backwards and forwards, but just in case there is something odd I've missed ...
Clutching at straws a bit here.
Is it an encryption issue of some sort? Does the plugin require something that isn't routinely installed on IIS 7?
Cheers,
Crac
The actual call is made via the PayPal SDK
https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Providers/Payment/PayPal/Services/PayPalExpressCheckoutService.cs#L470
The service is created here:
https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Providers/Payment/PayPal/Services/PayPalExpressCheckoutService.cs#L493
PayPal requires a security protocol that is ensured here:
https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Providers/Payment/PayPal/Services/PayPalApiServiceBase.cs#L51
PayPal requires TLS 1.1 (and 1.2 June 2017!) and as far as I understand you have a Windows Server 2008. TLS 1.1 (better you use 1.2) is only supported from 2008 R2 and up ;-).
https://devblog.paypal.com/upcoming-security-changes-notice/#tls
https://blogs.msdn.microsoft.com/kaushal/2011/10/02/support-for-ssltls-protocols-on-windows/
Hi Calvin,
I think that seems like quite a likely explanation. I'm not in a position to upgrade this server terribly easily, but it's only a testing server anyway, not the final platform, so I'm going to continue on the basis that this is the answer and that it will work on the real box.
If it doesn't I'll be back!
Cheers,
Crac
is working on a reply...