public async Task <PaymentDetail> CreatePayment(Guid gatewayId, decimal amount,
                                                        string currency, string reference, string memo)
        {
            _logger.LogInformation(ServerEventId.CreatePayment, "Gateway {0}, create payment request for {1} [ref: {2}]", gatewayId, amount, reference);

            // Create payment request
            var gateway        = _repository.Gateways().First(x => x.Id == gatewayId);
            var paymentRequest = new PaymentRequest(gateway, amount, currency, reference, memo);
            await _repository.Add(paymentRequest);

            await _repository.Save();

            _logger.LogDebug("Payment request {0} created", paymentRequest.PaymentId);

            // Convert the amount to BTC
            string  originalCurrency;
            decimal amountBtc;
            decimal?conversionRate;

            if (string.IsNullOrEmpty(currency) || string.Equals(currency, "BTC", StringComparison.OrdinalIgnoreCase))
            {
                originalCurrency = null;
                amountBtc        = amount;
                conversionRate   = null;
            }
            else
            {
                var convertedBtcAmount = _currencyConversionService.ConvertAmount(currency, amount);
                originalCurrency = currency;
                amountBtc        = convertedBtcAmount.AmountBtc;
                conversionRate   = convertedBtcAmount.ConversionRate;
                _logger.LogDebug("Converted {0} {1} to {2} BTC", amount, currency, amountBtc);
            }

            // Generate the ID of the order and the address
            var keyIndex = await _repository.NextKeyIndex(gateway);

            if (keyIndex == 0)
            {
                throw new Exception("Payment index number not set.");
            }
            var masterPubKey      = new BitcoinExtPubKey(gateway.ExtPubKey);
            var derivedOrderKey   = masterPubKey.ExtPubKey.Derive((uint)keyIndex);
            var paymentAddress    = derivedOrderKey.PubKey.GetAddress(masterPubKey.Network);
            var paymentAddressWif = paymentAddress.ToWif();

            _logger.LogDebug("Derived payment address [{0}] '{1}'", keyIndex, paymentAddressWif);

            // Save the details
            var paymentDetail = new PaymentDetail(paymentRequest,
                                                  keyIndex, paymentAddressWif,
                                                  amountBtc, originalCurrency, conversionRate);
            await _repository.Add(paymentDetail);

            await _repository.Save();

            // Register address with bitcoin server
            _logger.LogDebug("Registering {0} with verification service", paymentAddressWif);
            var registered = _verificationService.RegisterPaymentAddress(gateway.GatewayNumber, paymentAddressWif);

            _logger.LogDebug("Verification result: {0}", registered);
            if (registered)
            {
                paymentDetail.SetRegistered();
                await _repository.Save();
            }

            return(paymentDetail);
        }