question

demskigroup avatar image
demskigroup asked rachel Deactivated commented

Cloud Pay Display API Error

I am having an issue with cloud pay. It works if the cloud pay display app on a clover device is already up but if the cloud pay connector has to trigger the app to start it brings the app up but doesn't actually present an amount to pay until I disconnect my listener. This has been happening since the weekend.

Here is our connector script
<script>
        $.fn.serializeObject = function() {
            var o = {};
            var a = this.serializeArray();
            $.each(a, function() {
                if (o[this.name] !== undefined) {
                    if (!o[this.name].push) {
                        o[this.name] = [o[this.name]];
                    }
                    o[this.name].push(this.value || '');
                } else {
                    o[this.name] = this.value || '';
                }
            });
            return o;
        };
        $(document).ready(function() {
			
			console.log('check salerequest on jump');
			
		//	return false;
			var CloverConnectorFactory =  sdk;
		//	var ICloverConnectorListener =  sdk.remotepay.ICloverConnectorListener.call(this);
			
		//	var ICloverConnectorListener = sdk.remotepay.ICloverConnectorListener.prototype;
			var ICloverConnectorListener = Object.create(sdk.remotepay.ICloverConnectorListener.prototype);
		//	sdk.remotepay.ICloverConnectorListener.call(this);
		//	clover.remotepay.ICloverConnectorListener.call(this);
				console.log(ICloverConnectorListener);
				
			var SaleRequest = new sdk.remotepay.SaleRequest();
			
			var CloverID =  sdk.CloverID;
		
            var userReporting = document.getElementById("log");
            var reporting = reportingObjectFactory(console, userReporting);
            //real
            var listenerClassDefinition = createListener(reporting, Class, ICloverConnectorListener, SaleRequest, sdk);
					
			
            var paymentProxy = paymentProxyFactory(jQuery, listenerClassDefinition, CloverConnectorFactory, CloverID, reporting);
            //fake
            //var paymentProxy = paymentProxyFactory(jQuery, CloverID, false);
            paymentsController(jQuery, reporting, configRepositoryFactory, paymentProxy, jsPDF);
        });
    </script>

and here is our paymentProxyFactory
'use strict'


var responseObj = {};


function paymentProxyFactory(jQuery, listenerClassDefinition, CloverConnectorFactory, CloverID, reporting) {
 
 var prevconnector = undefined;
   


    return {
        send: function(device, authData, amount, data, callbacks){
			
			//onConfirmPaymentRequest
			console.log('*****************************');


			var paymentDevice = device; //device serial Id
			var merchantsAuthToken = authData.token;
			var paymentAmount = amount;
			var deviceSerial = data.Device;
			
			var clientId = authData.clientId;
			var merchantId = authData.merchant;
			var employeeId = authData.employee;
			console.log(device);
			console.log(authData);
			console.log(amount);
			console.log(data);
			console.log(callbacks);
			
			console.log("all received data");
			
		//	return false;
			
			var currentonSaleResponse = callbacks.onSaleResponse;
			var currentonDisconnected = callbacks.onDisconnected;
			
		//	return false;
		//	C030UQ54340349 C030UQ53430336 -- actual one
			var connector  = new sdk.CloverConnectorFactory().createICloverConnector({
				"oauthToken": merchantsAuthToken,
				"merchantId": merchantId,
				"employeeId": employeeId,
				"clientId": clientId,
				"remoteApplicationId": "http://ec2-52-40-82-196.us-west-2.compute.amazonaws.com/Remote-Pay-Acceptance/",
				"deviceSerialId": paymentDevice,
				"domain": "https://sandbox.dev.clover.com/"
			});


			var ExampleCloverConnectorListener = function(cloverConnector) {
				sdk.remotepay.ICloverConnectorListener.call(this);
				this.cloverConnector = cloverConnector;
			};
			


			ExampleCloverConnectorListener.prototype = Object.create(sdk.remotepay.ICloverConnectorListener.prototype);
			ExampleCloverConnectorListener.prototype.constructor = ExampleCloverConnectorListener;


			ExampleCloverConnectorListener.prototype.onReady = function (merchantInfo) {
				
				console.log('1');							
				
				var saleRequest = new sdk.remotepay.SaleRequest();
				saleRequest.setExternalId(sdk.CloverID.getNewId());
				saleRequest.setAmount(amount);
				
				reporting.info("Ready to request payment", saleRequest);
				
				this.cloverConnector.sale(saleRequest); // makes the start sale request
				console.log("started sale");
			};
			


			ExampleCloverConnectorListener.prototype.onDeviceReady = function (request) {
				
					console.log('onDeviceReady worked!!');   
					reporting.info("Device is Ready", request);
				//	console.log( this.cloverConnector );  
			};
			
			ExampleCloverConnectorListener.prototype.onDeviceConnected = function (request) {
				
					console.log('onDeviceConnected worked!!');
					reporting.info("Device is Connected", request);					
					console.log( this.cloverConnector );  
			};


			ExampleCloverConnectorListener.prototype.onDeviceActivityStart = function (deviceEvent) {
				
					console.log('onDeviceActivityStart');
					//console.log(request);		
					var reportInfo = "Activity";
					if (deviceEvent) reportInfo += ": " + deviceEvent.message + " (" + deviceEvent.eventState + ")";
						reporting.info(reportInfo, deviceEvent);
					};




			ExampleCloverConnectorListener.prototype.onVerifySignatureRequest = function (request) {
				console.log('2');
				log.info(request);
				reporting.info("Client provided signature", request);
				reporting.info("Signature is accepted by default");
				this.cloverConnector.acceptSignature(request);
			};
			
			
			
			ExampleCloverConnectorListener.prototype.onDeviceActivityEnd =  function(deviceEvent) {


				console.log('onDeviceActivityEnd');		
				reporting.debug("End activity", deviceEvent);
				var devicejson = JSON.parse(deviceEvent);			 
			
					
				if( (responseObj.result !== undefined) && ( responseObj.result == "SUCCESS"  ) ){
					currentonDisconnected();
				}
			},
			ExampleCloverConnectorListener.prototype.onDeviceError =  function (deviceErrorEvent) {
				
				console.log('onDeviceError');	
				reporting.info("Error", deviceErrorEvent);
			//	alert('onDeviceError!');					
				console.log( deviceErrorEvent );								
				
			};
			


			ExampleCloverConnectorListener.prototype.onConfirmPaymentRequest = function (request) {
				
				console.log('3');
				reporting.info("Payment confirmation request", request);
				this.cloverConnector.acceptPayment(request.payment);
			};


			ExampleCloverConnectorListener.prototype.onSaleResponse = function (response) {
				
				console.log('4');
				console.log(response);
				responseObj = response;
				var json = JSON.parse(response)
				
				reporting.info("Sale finished", response);
				reporting.info("Response : ", json.success);
				
				currentonSaleResponse(response);
								
					log.info(response);
					console.log('to reload');							
					connector.dispose();								
							
					if(!response.getIsSale()) {
						console.error("Response is not an sale!");
						console.error(response);
					}
					
			};
			
			//additional listeners start
			ExampleCloverConnectorListener.prototype.onAuthResponse = function(response) {
			
             reporting.info("Auth response", response);
			};
			ExampleCloverConnectorListener.prototype.onTipAdjustAuthResponse = function(response) {
				
				reporting.info("Tip adjustment response", response);
			};
			ExampleCloverConnectorListener.prototype.onCapturePreAuthResponse = function(response) {
				
				 reporting.info("Captured pre-auth response", response);
			};
			ExampleCloverConnectorListener.prototype.onPreAuthResponse = function(response) {
			
				 reporting.info("Pre-auth response", response);
			};
			ExampleCloverConnectorListener.prototype.onCloseoutResponse = function(response) {
				
				 reporting.info("Closeout response", response);
			};
			ExampleCloverConnectorListener.prototype.onManualRefundResponse = function(response) {
				
				 reporting.info("Manual refund response", response);
			};
			ExampleCloverConnectorListener.prototype.onRefundPaymentResponse = function(response) {
				
				 reporting.info("Refund payment response", response);
			};
			ExampleCloverConnectorListener.prototype.onTipAdded = function(tipAdded) {
				
				 reporting.info("Tip added", tipAdded);
			};
			ExampleCloverConnectorListener.prototype.onVoidPaymentResponse = function(response) {
				
				 reporting.info("Void payment response", response);
			};
			ExampleCloverConnectorListener.prototype.onVaultCardResponse =  function(response) {
				
				 reporting.info("Vault card response", response);
			}
			//addititional listeners stop
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			


			var connectorListener = new ExampleCloverConnectorListener(connector);


			connector.addCloverConnectorListener(connectorListener);
			connector.initializeConnection();
			
			
			
			
			
			jQuery(window).on('beforeunload ', function () {
				try {
					if(connector){}
						connector.dispose(); //commented dispose
				} catch (e) {
					console.log(e);
				}
			});
			
			
			
			function reloader(){
				console.log("reloader was called");
				var url = window.location.href;
				window.location.href = url;
				window.location.reload();
			}
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
        },
        generateId: function () {
			console.log('devtest proxy generateId');
            return CloverID.getNewId();
        }
    };
}


Cloud Pay Display
1 comment
10 |2000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

rachel avatar image rachel commented ·

Hi @demskigroup -- I noticed that you're calling ICloverConnector.sale() inside ICloverConnectorListener.OnReady(). That is not a recommended design pattern for production, where unexpected onReady() callbacks could result in unintended, overlapping SaleRequests. Additionally, onReady() was deprecated in favor of onDeviceReady() with the release of Remote Pay Cloud 1.3.1.

0 Likes 0 ·

1 Answer

rachel avatar image
rachel Deactivated answered
Thank you for reporting this issue.

A timing issue in Cloud Pay Display can cause it to become unresponsive when launched by the push server, or if the app is initially launched manually but is later moved to the background (such as after a four-finger exit).

Clover Engineering is already working on a fix and will be rolling it out as soon as possible.

In the short term, this has a simple workaround: merchants should launch Cloud Pay Display manually before the POS calls ICloverConnector.initializeConnection() and then keep Cloud Pay Display running in the foreground.

If a merchant reports that Cloud Pay Display is unresponsive, they should:

1. Completely exit Cloud Pay Display by closing it from the Recent Apps screen: four-finger exit Cloud Pay Display if it's running in the foreground, and then tap the Recent Apps button and drag Cloud Pay Display off.

2. From the Clover device launcher, tap Cloud Pay Display. (This may require merchants to scroll to see additional pages of installed apps.)

3. Try taking payments again.
10 |2000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Welcome to the
Clover Developer Community