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); }