Esempio n. 1
0
        // POST /api/invoices
        public async Task <InvoicePayload> Post([FromBody] InvoicePayload incomingPayload)
        {
            // Validate the bearer token
            string actionPerformer = await TokenValidator.ValidateAuthorizationHeader(Request.Headers.Authorization);

            if (string.IsNullOrEmpty(actionPerformer))
            {
                throw new UnauthorizedAccessException();
            }

            // TODO: A real payment processor should validate that the action performer
            // matches the email address that the invoice was sent to

            // Get the event type
            string eventType = incomingPayload.MethodData[0].Data.Event;

            if (eventType == PayEvent.LoadEntity)
            {
                return(CreateMockLoadEntityResponse(incomingPayload));
            }

            if (eventType == PayEvent.ShippingAddressChange)
            {
                return(CreateMockShippingAddressResponse(incomingPayload));
            }

            if (eventType == PayEvent.ShippingOptionChange)
            {
                return(CreateMockShippingOptionResponse(incomingPayload));
            }

            throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
        /// <inheritdoc />
        public async Task <InvoicePayload> LoadInvoiceInformationAsync(Hash bundleHash)
        {
            var bundleTransactions = await this.IotaRepository.FindTransactionsByBundlesAsync(new List <Hash> {
                bundleHash
            });

            var bundle = await this.IotaRepository.GetBundlesAsync(bundleTransactions.Hashes, false);

            var rawPayload = bundle.First().AggregateFragments();

            return(InvoicePayload.FromTrytePayload(rawPayload));
        }
Esempio n. 3
0
        public async Task TestInvoiceHashMismatchShouldReturnFalse()
        {
            var dltPayload = new InvoicePayload(Encoding.UTF8.GetBytes("Somebody once told me"),
                                                Encoding.UTF8.GetBytes("the world is gonna roll me"));

            var invoiceRepository = new Mock <IInvoiceRepository>();

            invoiceRepository.Setup(i => i.LoadInvoiceInformationAsync(It.IsAny <Hash>())).ReturnsAsync(dltPayload);

            var verificator = new InvoiceVerificator(invoiceRepository.Object, new Mock <IKvkRepository>().Object);

            Assert.IsFalse(await verificator.IsValid(new Invoice
            {
                Hash = Hash.Empty, KvkNumber = "123456789", Payload = Encoding.UTF8.GetBytes("Somebody once")
            }));
        }
        /// <inheritdoc />
        public async Task <TryteString> PublishInvoiceHashAsync(byte[] document, CngKey key)
        {
            var payload = new InvoicePayload(DocumentHash.Create(document),
                                             Encryption.CreateSignatureScheme(key).SignData(document));

            var bundle = new Bundle();

            bundle.AddTransfer(new Transfer
            {
                Address   = new Address(Seed.Random().Value),
                Message   = payload.ToTryteString(),
                Timestamp = Timestamp.UnixSecondsTimestamp,
                Tag       = new Tag("CHECKCHEQUE")
            });

            bundle.Finalize();
            bundle.Sign();

            await this.IotaRepository.SendTrytesAsync(bundle.Transactions, 2);

            return(bundle.Hash);
        }
Esempio n. 5
0
        private InvoicePayload CreateMockShippingAddressResponse(InvoicePayload payload)
        {
            // Returns a mock response
            // This method is typically used for scenarios where you are collecting a shipping
            // address from the user as part of the pay experience. Here you could
            // dynamically update what shipping options are available based on the address.
            // For example, maybe "rush" delivery is only available in certain areas.

            // The address is provided in the ShippingAddress property

            // Add static shipping options
            payload.Details.ShippingOptions = new List <PaymentShippingOption>()
            {
                new PaymentShippingOption()
                {
                    Id     = Shipping.NoRush,
                    Label  = "Regular Shipping",
                    Amount = new PaymentCurrencyAmount()
                    {
                        Currency = "USD",
                        Value    = "0.00"
                    },
                    Selected = true
                },
                new PaymentShippingOption()
                {
                    Id     = Shipping.Priority,
                    Label  = "Priority Shipping",
                    Amount = new PaymentCurrencyAmount()
                    {
                        Currency = "USD",
                        Value    = "3.00"
                    }
                }
            };

            return(payload);
        }
Esempio n. 6
0
        public async Task TestSignatureMatchShouldReturnTrue()
        {
            var invoice = new Invoice
            {
                Hash = Hash.Empty, KvkNumber = "123456789", Payload = Encoding.UTF8.GetBytes("Somebody once told me")
            };
            var signatureScheme = Encryption.CreateSignatureScheme(Encryption.Create());

            var dltPayload = new InvoicePayload(DocumentHash.Create(invoice.Payload),
                                                signatureScheme.SignData(invoice.Payload));

            var invoiceRepository = new Mock <IInvoiceRepository>();

            invoiceRepository.Setup(i => i.LoadInvoiceInformationAsync(It.IsAny <Hash>())).ReturnsAsync(dltPayload);

            var kvkRepository = new Mock <IKvkRepository>();

            kvkRepository.Setup(k => k.GetCompanyPublicKeyAsync(It.IsAny <string>()))
            .ReturnsAsync(signatureScheme.Key.Export(CngKeyBlobFormat.EccFullPublicBlob));

            var verificator = new InvoiceVerificator(invoiceRepository.Object, kvkRepository.Object);

            Assert.IsTrue(await verificator.IsValid(invoice));
        }
Esempio n. 7
0
        private InvoicePayload CreateMockLoadEntityResponse(InvoicePayload payload)
        {
            // Returns a mock response
            // Typically this would be where you would retrieve the invoice details
            // from a database and build the response.
            // For our sample, the invoice ID is in the ProductContext as InvoiceId

            // Turn on "test" mode
            payload.MethodData[0].Data.Mode = "TEST";

            // Specify supported credit card networks
            payload.MethodData[0].Data.SupportedNetworks = supportedNetworks;
            payload.MethodData[0].Data.SupportedTypes    = supportedTypes;

            // Add the schema.org Invoice entity
            payload.MethodData[0].Data.Entity = new Invoice()
            {
                Identifier = payload.MethodData[0].Data.ProductContext.InvoiceId,
                Url        = "https://contoso.com/invoice",
                Broker     = new LocalBusiness()
                {
                    Name = "Contoso"
                },
                PaymentDueDate  = new DateTime(2019, 1, 31),
                PaymentStatus   = PaymentStatus.PaymentDue,
                TotalPaymentDue = new PriceSpecification()
                {
                    Price         = 10.00,
                    PriceCurrency = "USD"
                }
            };

            // Set the options
            payload.Options = new PaymentOptions()
            {
                RequestPayerEmail = true,
                RequestPayerName  = true,
                RequestPayerPhone = true,
                RequestShipping   = true,
                ShippingType      = ShippingType.Shipping
            };

            // Set the details on what gets displayed

            payload.Details = new PaymentDetailsInit()
            {
                Id           = payload.MethodData[0].Data.ProductContext.InvoiceId,
                DisplayItems = new List <PaymentItem>()
                {
                    new PaymentItem()
                    {
                        Label  = "Large Widget",
                        Amount = new PaymentCurrencyAmount()
                        {
                            Currency = "USD",
                            Value    = "7.00"
                        }
                    },
                    new PaymentItem()
                    {
                        Label  = "Small Widget",
                        Amount = new PaymentCurrencyAmount()
                        {
                            Currency = "USD",
                            Value    = "3.00"
                        }
                    },
                    new PaymentItem()
                    {
                        Label  = "Shipping",
                        Amount = new PaymentCurrencyAmount()
                        {
                            Currency = "USD",
                            Value    = "0.00"
                        },
                        // Set the total as pending since
                        // we've set to 0 as the default
                        Pending = true
                    }
                },
                Total = new PaymentItem
                {
                    Label  = "Total Due",
                    Amount = new PaymentCurrencyAmount()
                    {
                        Currency = "USD",
                        Value    = "10.00"
                    },
                    // Set the total as pending since
                    // it is not final until shipping is added
                    Pending = true
                }
            };

            return(payload);
        }
Esempio n. 8
0
        private InvoicePayload CreateMockShippingOptionResponse(InvoicePayload payload)
        {
            // Returns a mock response
            // This method is typically used for scenarios where you are updating the
            // invoice based on shipping. For example, priority shipping may incur an
            // additional cost.

            // The shipping option selected is provided in the ShippingOption property

            string shippingOption = payload.ShippingOption;

            if (shippingOption == Shipping.Priority)
            {
                // If shipping is already present, just update it
                var shippingItem = payload.Details.DisplayItems.Find(i => i.Label.Equals("Shipping"));
                if (shippingItem != null)
                {
                    shippingItem.Amount = new PaymentCurrencyAmount()
                    {
                        Currency = "USD",
                        Value    = "3.00"
                    };
                }
                else
                {
                    // Add a new item
                    payload.Details.DisplayItems.Add(new PaymentItem()
                    {
                        Label  = "Shipping",
                        Amount = new PaymentCurrencyAmount()
                        {
                            Currency = "USD",
                            Value    = "3.00"
                        }
                    });
                }

                // Update the invoice total
                payload.Details.Total.Amount.Value = "13.00";

                // Update the total in the Invoice entity
                payload.MethodData[0].Data.Entity.TotalPaymentDue.Price = 13.00;
            }
            else
            {
                // Regular shipping, set shipping line item to 0 and reset total
                var shippingItem = payload.Details.DisplayItems.Find(i => i.Label.Equals("Shipping"));
                if (shippingItem != null)
                {
                    shippingItem.Amount.Value = "0.00";
                }

                // Update total
                payload.Details.Total.Amount.Value = "10.00";

                // Update the total in the Invoice entity
                payload.MethodData[0].Data.Entity.TotalPaymentDue.Price = 10.00;
            }

            return(payload);
        }