コード例 #1
0
        public async Task <OAuthTokensPair> RefreshAccessToken(string refreshToken, CancellationToken cancellationToken)
        {
            Condition.Requires(refreshToken, "refreshToken").IsNotNullOrWhiteSpace();

            var mark = Mark.CreateNew();
            var requestParameters = new Dictionary <string, string>
            {
                { "client_id", base.Config.ApplicationId },
                { "grant_type", "refresh_token" },
                { "refresh_token", refreshToken },
            };

            var url = SquareEndPoint.ObtainOAuth2TokenUrl + "?" + string.Join("&", requestParameters.Select(item => $"{ item.Key }={ item.Value }"));

            try
            {
                SquareLogger.LogStarted(this.CreateMethodCallInfo(url, mark, additionalInfo: this.AdditionalLogInfo()));

                var body = new Dictionary <string, string>()
                {
                    { "client_secret", base.Config.ApplicationSecret }
                };
                var tokens = await base.PostAsync <OAuthTokensPair>(url, body, cancellationToken, mark).ConfigureAwait(false);

                SquareLogger.LogEnd(this.CreateMethodCallInfo(url, mark, methodResult: tokens.ToJson(), additionalInfo: this.AdditionalLogInfo()));

                return(tokens);
            }
            catch (Exception exception)
            {
                var squareException = new SquareException(this.CreateMethodCallInfo(url, mark, additionalInfo: this.AdditionalLogInfo()), exception);
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }
        }
コード例 #2
0
        /// <summary>
        ///	Returns Square items with the supplied catalogObjectIds
        /// </summary>
        /// <param name="catalogObjectsIds"></param>
        /// <param name="cancellationToken"></param>
        /// <param name="mark"></param>
        /// <returns></returns>
        public async Task <IEnumerable <SquareItem> > GetCatalogObjectsByIdsAsync(IEnumerable <string> catalogObjectsIds, CancellationToken cancellationToken, Mark mark)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(url: SquareEndPoint.BatchRetrieveCatalogObjectsUrl, mark: mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Search item by id request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            if (catalogObjectsIds == null || !catalogObjectsIds.Any())
            {
                return(null);
            }

            var requestBody = new BatchRetrieveCatalogObjectsRequest(catalogObjectsIds.ToList());

            var response = await base.ThrottleRequest(SquareEndPoint.SearchCatalogUrl, requestBody.ToJson(), mark, (token) =>
            {
                return(this._catalogApi.BatchRetrieveCatalogObjectsAsync(requestBody));
            }, cancellationToken).ConfigureAwait(false);

            var errors = response.Errors;

            if (errors != null && errors.Any())
            {
                var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.BatchRetrieveCatalogObjectsUrl, mark, additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson());
                var squareException = new SquareException(string.Format("{0}. Batch retrieve catalog objects errors", methodCallInfo));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            return(response.Objects?.Select(c => c.ToSvItemVariation()));
        }
コード例 #3
0
        private async Task <SearchOrdersResponse> SearchOrdersAsync(SearchOrdersRequest requestBody, CancellationToken token, Mark mark)
        {
            if (token.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(SquareEndPoint.OrdersSearchUrl, mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Search orders request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            var response = await base.ThrottleRequest(SquareEndPoint.SearchCatalogUrl, requestBody.ToJson(), mark, (_) =>
            {
                return(_ordersApi.SearchOrdersAsync(requestBody));
            }, token).ConfigureAwait(false);

            var errors = response.Errors;

            if (errors != null && errors.Any())
            {
                var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.OrdersSearchUrl, mark, additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson(), payload: requestBody.ToJson());
                var squareException = new SquareException(string.Format("{0}. Search orders returned errors", methodCallInfo));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            return(response);
        }
コード例 #4
0
        public async Task <SquareCustomer> GetCustomerByIdAsync(string customerId, CancellationToken token, Mark mark)
        {
            Condition.Requires(customerId, "customerId").IsNotNullOrWhiteSpace();

            if (token.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(SquareEndPoint.RetrieveCustomerByIdUrl, mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Get customer by id request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            var response = await base.ThrottleRequest(SquareEndPoint.RetrieveCustomerByIdUrl, customerId.ToJson(), mark, (_) =>
            {
                return(Task.FromResult(_customersApi.RetrieveCustomer(customerId)));
            }, token).ConfigureAwait(false);

            var errors = response.Errors;

            if (errors != null && errors.Any())
            {
                var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.RetrieveCustomerByIdUrl, mark, additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson());
                var squareException = new SquareException(string.Format("{0}. Get customer returned errors", methodCallInfo));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            return(response.Customer.ToSvCustomer());
        }
コード例 #5
0
        /// <summary>
        ///	Updates items variations quantity
        /// </summary>
        /// <param name="items"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task UpdateItemsQuantityAsync(IEnumerable <SquareItem> items, CancellationToken cancellationToken, string locationId = null)
        {
            if (items.Count() == 0)
            {
                return;
            }

            var mark = Mark.CreateNew();

            if (cancellationToken.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(url: SquareEndPoint.BatchChangeInventory, mark: mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Items quantities batch update request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            if (locationId == null)
            {
                locationId = this.GetDefaultLocationId();
            }

            var chunks = items.SplitToChunks(UpdateInventoryBatchSize);

            foreach (var chunk in chunks)
            {
                var request = new BatchChangeInventoryRequest()
                {
                    IdempotencyKey = Mark.CreateNew().ToString(),
                    Changes        = chunk.Select(i => new InventoryChange()
                    {
                        Type          = InventoryChangeType,
                        PhysicalCount = new InventoryPhysicalCount(
                            CatalogObjectId: i.VariationId,
                            State: InventoryItemState,
                            OccurredAt: DateTime.UtcNow.FromUtcToRFC3339(),
                            LocationId: locationId,
                            Quantity: i.Quantity.ToString())
                    }).ToList()
                };

                await base.ThrottleRequest(SquareEndPoint.BatchChangeInventory, request.ToJson(), mark, async token =>
                {
                    var response = await this._inventoryApi.BatchChangeInventoryAsync(request).ConfigureAwait(false);

                    if (response.Errors != null && response.Errors.Any())
                    {
                        var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.BatchChangeInventory, mark, additionalInfo: this.AdditionalLogInfo(), errors: response.Errors.ToJson());
                        var squareException = new SquareException(string.Format("{0}. Search items catalog returned errors", methodCallInfo));
                        SquareLogger.LogTraceException(squareException);
                        throw squareException;
                    }

                    return(response.Counts);
                }, cancellationToken).ConfigureAwait(false);
            }
        }
コード例 #6
0
        /// <summary>
        ///	Returns Square items which were updated or created after specified date
        /// </summary>
        /// <param name="date"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <IEnumerable <SquareItem> > GetChangedItemsAfterAsync(DateTime date, CancellationToken cancellationToken)
        {
            var items = new List <SquareItem>();
            var mark  = Mark.CreateNew();

            if (cancellationToken.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(url: SquareEndPoint.SearchCatalogUrl, mark: mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Search changed items request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            string paginationCursor = null;

            do
            {
                var request = new SearchCatalogObjectsRequest
                {
                    IncludeDeletedObjects = false,
                    IncludeRelatedObjects = true,
                    Cursor      = paginationCursor,
                    ObjectTypes = new string[] { ItemsExtensions.ItemCatalogObjectType }.ToList(),
                    BeginTime = date.ToUniversalTime().FromUtcToRFC3339()
                };

                var response = await base.ThrottleRequest(SquareEndPoint.SearchCatalogUrl, request.ToJson(), mark, (token) =>
                {
                    return(this._catalogApi.SearchCatalogObjectsAsync(request));
                }, cancellationToken).ConfigureAwait(false);

                var errors = response.Errors;
                if (errors != null && errors.Any())
                {
                    var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.SearchCatalogUrl, mark, additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson());
                    var squareException = new SquareException(string.Format("{0}. Search items catalog returned errors", methodCallInfo));
                    SquareLogger.LogTraceException(squareException);
                    throw squareException;
                }

                if (response.Objects != null)
                {
                    foreach (var obj in response.Objects)
                    {
                        items.AddRange(obj.ToSvItems());
                    }
                }

                paginationCursor = response.Cursor;
            }while(!string.IsNullOrWhiteSpace(paginationCursor));

            return(items);
        }
コード例 #7
0
        /// <summary>
        ///	Returns Square item variation with specified sku
        /// </summary>
        /// <param name="sku">Sku</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <SquareItem> GetItemBySkuAsync(string sku, CancellationToken cancellationToken)
        {
            Condition.Requires(sku, "sku").IsNotNullOrWhiteSpace();

            var mark = Mark.CreateNew();

            if (cancellationToken.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(url: SquareEndPoint.SearchCatalogUrl, mark: mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Search item by sku request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            var request = new SearchCatalogObjectsRequest
            {
                IncludeDeletedObjects = false,
                IncludeRelatedObjects = true,
                ObjectTypes           = new string[] { ItemsExtensions.ItemVariationCatalogObjectType }.ToList(),
                Query = new CatalogQuery()
                {
                    ExactQuery = new CatalogQueryExact("sku", sku)
                }
            };

            var response = await base.ThrottleRequest(SquareEndPoint.SearchCatalogUrl, request.ToJson(), mark, (token) =>
            {
                return(this._catalogApi.SearchCatalogObjectsAsync(request));
            }, cancellationToken).ConfigureAwait(false);

            var errors = response.Errors;

            if (errors != null && errors.Any())
            {
                var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.SearchCatalogUrl, mark, additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson());
                var squareException = new SquareException(string.Format("{0}. Search items catalog returned errors", methodCallInfo));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            var catalogItem = response.Objects?.FirstOrDefault(o => o.ItemVariationData != null);

            if (catalogItem != null)
            {
                var item = catalogItem.ToSvItems().First();
                var itemsWithQuantity = await this.FillItemsQuantities(new SquareItem[] { item }.ToList(), cancellationToken).ConfigureAwait(false);

                return(itemsWithQuantity.FirstOrDefault());
            }

            return(null);
        }
コード例 #8
0
        /// <summary>
        /// Get all locations for the store
        /// </summary>
        /// <param name="token">Cancellation token for cancelling call to endpoint</param>
        /// <param name="mark">Mark for log tracing</param>
        /// <returns>Locations</returns>
        public async Task <IEnumerable <SquareLocation> > GetLocationsAsync(CancellationToken token, Mark mark)
        {
            if (mark.IsBlank())
            {
                mark = Mark.CreateNew();
            }

            if (token.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo(SquareEndPoint.ListLocationsUrl, mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Get locations request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            var locationsResponse = await base.ThrottleRequest(SquareEndPoint.ListLocationsUrl, string.Empty, mark, cancellationToken =>
            {
                return(Task.FromResult(_locationsApi.ListLocations()));
            }, token).ConfigureAwait(false);

            List <Location> locations = new List <Location>();

            if (locationsResponse == null || !(locations = locationsResponse.Locations).Any())
            {
                var methodCallInfo = CreateMethodCallInfo(SquareEndPoint.ListLocationsUrl, mark,
                                                          additionalInfo: this.AdditionalLogInfo());
                var squareException = new SquareException(string.Format("{0}. No locations found", methodCallInfo));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            var errors = locationsResponse.Errors;

            if (errors != null && errors.Any())
            {
                var methodCallInfo = CreateMethodCallInfo(SquareEndPoint.ListLocationsUrl, mark,
                                                          additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson());
                var squareException =
                    new SquareException(string.Format("{0}. Get locations returned errors", methodCallInfo));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            return(locations.Select(l => l.ToSvLocation()));
        }
コード例 #9
0
        /// <summary>
        ///	Fills Square item quantity field using inventory api
        /// </summary>
        /// <param name="items"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task <IEnumerable <SquareItem> > FillItemsQuantities(IEnumerable <SquareItem> items, CancellationToken cancellationToken)
        {
            var mark = Mark.CreateNew();

            var request = new BatchRetrieveInventoryCountsRequest
            {
                CatalogObjectIds = items.Select(i => i.VariationId).ToList(),
                LocationIds      = GetLocationsId().ToList()
            };
            string paginationCursor = null;

            do
            {
                var response = await base.ThrottleRequest(SquareEndPoint.RetrieveInventoryCounts, request.ToJson(), mark, token => {
                    return(this._inventoryApi.BatchRetrieveInventoryCountsAsync(request));
                }, cancellationToken).ConfigureAwait(false);

                var errors = response.Errors;
                if (errors != null && errors.Any())
                {
                    var methodCallInfo  = CreateMethodCallInfo(SquareEndPoint.RetrieveInventoryCounts, mark, additionalInfo: this.AdditionalLogInfo(), errors: errors.ToJson());
                    var squareException = new SquareException(string.Format("{0}. Search items catalog returned errors", methodCallInfo));
                    SquareLogger.LogTraceException(squareException);
                    throw squareException;
                }

                if (response.Counts != null && response.Counts.Any())
                {
                    foreach (var inventoryItem in response.Counts)
                    {
                        var item = items.FirstOrDefault(i => i.VariationId == inventoryItem.CatalogObjectId);

                        if (item != null)
                        {
                            item.Quantity = decimal.Parse(inventoryItem.Quantity);
                        }
                    }
                }

                paginationCursor = response.Cursor;
            }while (!string.IsNullOrWhiteSpace(paginationCursor));

            return(items);
        }
コード例 #10
0
        /// <summary>
        ///	Returns orders created/modified between the start and end date
        /// </summary>
        /// <param name="startDateUtc"></param>
        /// <param name="endDateUtc"></param>
        /// <param name="token">Cancellation token for cancelling call to endpoint</param>
        /// <returns></returns>
        public async Task <IEnumerable <SquareOrder> > GetOrdersAsync(DateTime startDateUtc, DateTime endDateUtc, CancellationToken token)
        {
            Condition.Requires(startDateUtc).IsLessThan(endDateUtc);

            var mark = Mark.CreateNew();

            if (token.IsCancellationRequested)
            {
                var exceptionDetails = CreateMethodCallInfo("", mark, additionalInfo: this.AdditionalLogInfo());
                var squareException  = new SquareException(string.Format("{0}. Get orders request was cancelled", exceptionDetails));
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            IEnumerable <SquareOrder> response = null;

            try
            {
                SquareLogger.LogStarted(this.CreateMethodCallInfo("", mark, additionalInfo: this.AdditionalLogInfo()));

                var locations = await _locationsService.GetActiveLocationsAsync(token, mark).ConfigureAwait(false);

                SquareLogger.LogTrace(this.CreateMethodCallInfo("", mark, payload: locations.ToJson(), additionalInfo: this.AdditionalLogInfo()));

                response = await CollectOrdersFromAllPagesAsync(startDateUtc, endDateUtc, locations,
                                                                (requestBody) => GetOrdersWithRelatedDataAsync( requestBody, token, mark ), this.Config.OrdersPageSize).ConfigureAwait(false);

                SquareLogger.LogEnd(this.CreateMethodCallInfo("", mark, additionalInfo: this.AdditionalLogInfo()));
            }
            catch (Exception ex)
            {
                var squareException = new SquareException(this.CreateMethodCallInfo("", mark, additionalInfo: this.AdditionalLogInfo()), ex);
                SquareLogger.LogTraceException(squareException);
                throw squareException;
            }

            return(response);
        }