/// <inheritdoc />
        public async Task MakePaymentAsync(IAgentContext agentContext, PaymentRecord paymentRecord,
                                           PaymentAddressRecord addressFromRecord = null)
        {
            if (paymentRecord.Amount == 0)
            {
                throw new AriesFrameworkException(ErrorCode.InvalidRecordData, "Cannot make a payment with 0 amount");
            }

            await paymentRecord.TriggerAsync(PaymentTrigger.ProcessPayment);

            if (paymentRecord.Address == null)
            {
                throw new AriesFrameworkException(ErrorCode.InvalidRecordData, "Payment record is missing an address");
            }

            var provisioning = await provisioningService.GetProvisioningAsync(agentContext.Wallet);

            if (addressFromRecord == null)
            {
                addressFromRecord = await GetDefaultPaymentAddressAsync(agentContext);
            }

            await RefreshBalanceAsync(agentContext, addressFromRecord);

            if (addressFromRecord.Balance < paymentRecord.Amount)
            {
                throw new AriesFrameworkException(ErrorCode.PaymentInsufficientFunds,
                                                  "Address doesn't have enough funds to make this payment");
            }
            var txnFee = await GetTransactionFeeAsync(agentContext, TransactionTypes.XFER_PUBLIC);

            var paymentResult = await IndyPayments.BuildPaymentRequestAsync(
                wallet : agentContext.Wallet,
                submitterDid : null,
                inputsJson : addressFromRecord.Sources.Select(x => x.Source).ToJson(),
                outputsJson : new[]
            {
                new IndyPaymentOutputSource
                {
                    Amount    = paymentRecord.Amount,
                    Recipient = paymentRecord.Address
                },
                new IndyPaymentOutputSource
                {
                    Recipient = addressFromRecord.Address,
                    Amount    = addressFromRecord.Balance - paymentRecord.Amount - txnFee
                }
            }.ToJson(),
                extra : null);

            var response = await IndyLedger.SignAndSubmitRequestAsync(await agentContext.Pool, agentContext.Wallet,
                                                                      provisioning.Endpoint.Did, paymentResult.Result);

            var paymentResponse = await IndyPayments.ParsePaymentResponseAsync(TokenConfiguration.MethodName, response);

            var paymentOutputs = paymentResponse.ToObject <IList <IndyPaymentOutputSource> >();
            var paymentOutput  = paymentOutputs.SingleOrDefault(x => x.Recipient == paymentRecord.Address);

            paymentRecord.ReceiptId   = paymentOutput.Receipt;
            addressFromRecord.Sources = paymentOutputs
                                        .Where(x => x.Recipient == addressFromRecord.Address)
                                        .Select(x => new IndyPaymentInputSource
            {
                Amount         = x.Amount,
                PaymentAddress = x.Recipient,
                Source         = x.Receipt
            })
                                        .ToList();

            await recordService.UpdateAsync(agentContext.Wallet, paymentRecord);

            await recordService.UpdateAsync(agentContext.Wallet, addressFromRecord);
        }