private PaymentWrite BuildCustomerRefund(ShopifyTransaction transactionRecord)
        {
            var transaction    = _shopifyJsonService.RetrieveTransaction(transactionRecord.ShopifyTransactionId);
            var paymentGateway = _settingsRepository.RetrievePaymentGatewayByShopifyId(transaction.gateway);

            // Locate the Acumatica Customer
            //
            var shopifyCustomerId = transactionRecord.CustomerId();
            var customer          = _syncOrderRepository.RetrieveCustomer(shopifyCustomerId);
            var acumaticaCustId   = customer.AcumaticaCustId();

            // Build the Payment Ref and Description
            //
            var order = _syncOrderRepository.RetrieveShopifyOrder(transactionRecord.OrderId());

            // Create the payload for Acumatica
            //
            var refundPayment = new PaymentWrite();

            refundPayment.CustomerID = acumaticaCustId.ToValue();
            refundPayment.Type       = PaymentType.CustomerRefund.ToValue();
            refundPayment.PaymentRef = $"{transaction.id}".ToValue();

            // Reference to the original Payment
            //
            if (transactionRecord.NeedManualApply())
            {
                refundPayment.Hold          = true.ToValue();
                refundPayment.PaymentAmount = ((double)transaction.amount).ToValue();
            }
            else
            {
                var acumaticaPayment = order.PaymentTransaction().AcumaticaPayment;
                var balance          = _paymentClient.RetrievePaymentBalance(acumaticaPayment.AcumaticaRefNbr, PaymentType.Payment);

                var amountToApply = transaction.amount > balance ? balance : transaction.amount;

                refundPayment.Hold          = false.ToValue();
                refundPayment.PaymentAmount = ((double)amountToApply).ToValue();
                refundPayment.DocumentsToApply
                    = PaymentDocumentsToApply.ForDocument(
                          acumaticaPayment.AcumaticaRefNbr, acumaticaPayment.AcumaticaDocType, (double)amountToApply);
            }

            // Amounts
            //
            refundPayment.PaymentMethod = paymentGateway.AcumaticaPaymentMethod.ToValue();
            refundPayment.CashAccount   = paymentGateway.AcumaticaCashAccount.ToValue();
            refundPayment.Description   = $"Refund for Order #{order.ShopifyOrderNumber} (TransId #{transaction.id})".ToValue();
            return(refundPayment);
        }
        private void PushPaymentAndWriteSync(ShopifyTransaction transactionRecord, PaymentWrite payment)
        {
            // Push to Acumatica
            //
            string resultJson;

            try
            {
                resultJson = _paymentClient.WritePayment(payment.SerializeToJson());
                _syncOrderRepository.ResetOrderErrorCount(transactionRecord.ShopifyOrderId);
            }
            catch (Exception ex)
            {
                _systemLogger.Error(ex);
                _logService.Log($"Encounter error syncing {transactionRecord.LogDescriptor()}");
                _syncOrderRepository.IncreaseOrderErrorCount(transactionRecord.ShopifyOrderId);
                return;
            }

            var resultPayment  = resultJson.DeserializeFromJson <PaymentWrite>();
            var existingRecord = _syncOrderRepository.RetreivePayment(transactionRecord.MonsterId);

            if (existingRecord == null)
            {
                // Create Monster Sync Record
                //
                var paymentRecord = new AcumaticaPayment();
                paymentRecord.ShopifyTransactionMonsterId = transactionRecord.MonsterId;

                if (resultPayment == null)
                {
                    // Workaround for Acumatica Bug
                    //
                    paymentRecord.AcumaticaRefNbr = AcumaticaSyncConstants.UnknownRefNbr;
                }
                else
                {
                    paymentRecord.AcumaticaRefNbr = resultPayment.ReferenceNbr.value;
                }

                paymentRecord.AcumaticaDocType        = payment.Type.value;
                paymentRecord.AcumaticaAmount         = (decimal)payment.PaymentAmount.value;
                paymentRecord.AcumaticaAppliedToOrder = (decimal)payment.AmountAppliedToOrder;

                if (transactionRecord.IsRefund())
                {
                    if (transactionRecord.NeedManualApply())
                    {
                        // Users are tasked with creating their Return for Credit
                        //
                        paymentRecord.NeedRelease     = false;
                        paymentRecord.NeedManualApply = true;
                    }
                    else
                    {
                        paymentRecord.NeedRelease     = true;
                        paymentRecord.NeedManualApply = false;
                    }
                }

                if (!transactionRecord.IsRefund())
                {
                    paymentRecord.NeedRelease     = true;
                    paymentRecord.NeedManualApply = false;
                }

                paymentRecord.DateCreated = DateTime.UtcNow;
                paymentRecord.LastUpdated = DateTime.UtcNow;
                _syncOrderRepository.InsertPayment(paymentRecord);
            }
            else
            {
                existingRecord.AcumaticaAppliedToOrder = (decimal)payment.AmountAppliedToOrder;
                existingRecord.LastUpdated             = DateTime.UtcNow;
                _syncOrderRepository.SaveChanges();
            }

            _syncOrderRepository.UpdateShopifyOriginalPaymentNeedPut(transactionRecord.ShopifyOrderMonsterId, false);
            _syncOrderRepository.ResetOrderErrorCount(transactionRecord.ShopifyOrderId);
        }