public override byte[] ToBytes()
 {
     return(TLUtils.Combine(
                TLUtils.SignatureToBytes(Signature),
                PaymentToken.ToBytes(),
                GoogleTransactionId.ToBytes()));
 }
Exemple #2
0
        // POST /api/payments
        public async Task <PaymentCompleteResponse> Post([FromBody] PaymentResponse payment)
        {
            // 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

            // Parse the token
            PaymentToken parsedToken = new PaymentToken(payment.Details.PaymentToken);

            // The sample only supports test tokens
            if (!parsedToken.IsTestToken)
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            // Check the format
            switch (parsedToken.Format.ToLower())
            {
            case "stripe":
                return(CreateMockStripePaymentResponse(parsedToken, payment));

            default:
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }
        }
Exemple #3
0
        public void ConvertorEqualToCoin()
        {
            PaymentToken    ten       = new PaymentToken(10, 10);
            ITokenConverter convertor = new SterlingTokenConverter(ten);
            ICoin           c         = convertor.Coin;
            ICoin           coin      = new TenPence();

            Assert.AreEqual(coin.Worth, c.Worth);
        }
Exemple #4
0
        public void TestWrongCoin()
        {
            PaymentToken euro = new PaymentToken(101, 99);

            ITokenConverter convertor = new SterlingTokenConverter(euro);
            ICoin           c         = convertor.Coin;

            Assert.AreEqual(c, null);
        }
Exemple #5
0
        public void ConvertMoneyForBuying()
        {
            PaymentToken pound = new PaymentToken(100, 100);

            ITokenConverter convertor = new SterlingTokenConverter(pound);
            ICoin           c         = convertor.Coin;

            Assert.AreEqual(c.Worth, 1);
        }
Exemple #6
0
        public void IsCoinGoodForMachine()
        {
            PaymentToken    two       = new PaymentToken(2, 2);
            ITokenConverter convertor = new SterlingTokenConverter(two);
            var             a         = vm.CurrentPayment;

            vm.MakePayment(convertor.Coin);
            var b = vm.CurrentPayment;

            Assert.AreEqual(b, 0);
            Assert.AreEqual(a, 0);
        }
Exemple #7
0
        public void RollingChangeCalculator()
        {
            PaymentToken    fifty      = new PaymentToken(50, 50);
            ITokenConverter convertor1 = new SterlingTokenConverter(fifty);


            vm.MakePayment(convertor1.Coin);
            vm.MakePurchase("A1");


            var coinChange = vm.GetChange.Sum(c => c.Worth);
            var a          = vm.AvailableChange;

            Assert.AreEqual(0, a);
            Assert.AreEqual(0.1, coinChange);
        }
Exemple #8
0
        public void ResetCoins()
        {
            PaymentToken pound = new PaymentToken(100, 100);
            PaymentToken five  = new PaymentToken(5, 5);

            ITokenConverter convertor1 = new SterlingTokenConverter(pound);
            ICoin           c1         = convertor1.Coin;

            ITokenConverter convertor2 = new SterlingTokenConverter(five);
            ICoin           c2         = convertor2.Coin;

            vm.MakePayment(c1);
            vm.MakePayment(c1);
            vm.ReturnCoins();

            Assert.AreEqual(vm.CurrentPayment, 0);
        }
Exemple #9
0
        public async Task Create_a_new_payment_token_with_success()
        {
            // Arrange
            var expectedResponse = new PaymentTokenResponse
            {
                Id     = "e06809b9da0a3118fa282a18c1f5dc09",
                Method = Constants.PaymentMethod.CREDIT_CARD
            };

            var paymentRequest = new PaymentTokenRequest
            {
                AccountId   = "2d8b228d-4183-44b8-ad3b-b8ab0db2aacd",
                Method      = Constants.PaymentMethod.CREDIT_CARD,
                Test        = true,
                PaymentData = new PaymentInfoModel
                {
                    FirstName         = "Rodrigo",
                    LastName          = "Couto",
                    Month             = "12",
                    Year              = "2018",
                    Number            = "4111111111111111",
                    VerificationValue = "123"
                }
            };

            PaymentTokenResponse paymentTokenResponse;

            // Act
            using (var apiClient = new PaymentToken())
            {
                paymentTokenResponse = await apiClient.CreateAsync(paymentRequest).ConfigureAwait(false);
            }

            // Assert
            Assert.That(paymentTokenResponse.Id, Is.Not.Empty);
            Assert.That(paymentTokenResponse.Method, Is.EqualTo(expectedResponse.Method));
        }
Exemple #10
0
        public async Task <PaymentRecord> ProcessPaymentAsync(PaymentRequest paymentRequest, PaymentResponse paymentResponse)
        {
            if (paymentRequest == null)
            {
                throw new ArgumentNullException(nameof(paymentRequest));
            }

            if (paymentResponse == null)
            {
                throw new ArgumentNullException(nameof(paymentResponse));
            }

            if (!MicrosoftPayMethodData.MethodName.Equals(paymentResponse.MethodName, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentOutOfRangeException("Payment method is not supported.");
            }

            var details = JObject.FromObject(paymentResponse.Details);

            var paymentToken = PaymentToken.Parse(details.GetValue("paymentToken").Value <string>());

            if (string.IsNullOrWhiteSpace(paymentToken.Source))
            {
                throw new ArgumentNullException("Payment token source is empty.");
            }

            if (paymentToken.Format != PaymentTokenFormat.Stripe)
            {
                throw new ArgumentOutOfRangeException("Payment token format is not Stripe.");
            }

            if (!AppSettings.MerchantId.Equals(paymentToken.MerchantId, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentOutOfRangeException("Merchant id is not supported.");
            }

            if (!paymentToken.Amount.Currency.Equals(paymentRequest.Details.Total.Amount.Currency))
            {
                throw new ArgumentOutOfRangeException("Payment token amount currency mismatch.");
            }

            if (!paymentToken.Amount.Value.Equals(paymentRequest.Details.Total.Amount.Value))
            {
                throw new ArgumentOutOfRangeException("Payment token amount value mismatch.");
            }

            var result = new PaymentRecord()
            {
                OrderId          = Guid.Parse(paymentRequest.Id),
                TransactionId    = Guid.NewGuid(),
                MethodName       = paymentResponse.MethodName,
                PaymentProcessor = paymentToken.Format.ToString(),
                ShippingAddress  = paymentResponse.ShippingAddress,
                ShippingOption   = paymentResponse.ShippingOption,
                Items            = paymentRequest.Details.DisplayItems,
                Total            = paymentRequest.Details.Total,
                LiveMode         = !paymentToken.IsEmulated,
            };

            // If the payment token is microsoft emulated do not charge (as it will fail)
            if (paymentToken.IsEmulated)
            {
                return(result);
            }

            var chargeOptions = new StripeChargeCreateOptions()
            {
                Currency    = paymentToken.Amount.Currency,
                Amount      = (int)(double.Parse(paymentToken.Amount.Value) * 100), // Amount in cents
                Description = paymentRequest.Id,
                SourceTokenOrExistingSourceId = paymentToken.Source,
            };

            try
            {
                var charge = await this.chargeService.CreateAsync(chargeOptions);

                if (charge.Status.Equals("succeeded", StringComparison.OrdinalIgnoreCase) && charge.Captured == true)
                {
                    // Charge succeeded, return payment paymentRecord
                    // Ideally, you should register the transaction using the PaymentRecord and charge.Id
                    return(result);
                }

                // Other statuses may include processing "pending" or "success" with non captured funds. It is up to the merchant how to handle these cases.
                // If payment is captured but not charged this would be considered "unknown" (charge the captured amount after shipping scenario)
                // Merchant might choose to handle "pending" and "failed" status or handle "success" status with funds captured null or false
                // More information @ https://stripe.com/docs/api#charge_object-captured
                throw new PaymentException($"Could not process charge using Stripe with charge.status: {charge.Status} and charge.captured: {charge.Captured}");
            }
            catch (StripeException ex)
            {
                Debug.Write($"Error processing payment with Stripe: {ex.Message}");
                throw new PaymentException("Error processing payment with Stripe.", ex);
            }
        }
Exemple #11
0
        /// <summary>
        /// Starts a checkout operation and runs it to completion.
        /// </summary>
        public static async Task CheckoutAsync(ShoppingCart shoppingCart)
        {
            Uri merchantUri = new Uri("http://www.contoso.com");
            PaymentMerchantInfo merchantInfo = new PaymentMerchantInfo(merchantUri);

            PaymentOptions options = new PaymentOptions();

            options.RequestShipping         = true;
            options.ShippingType            = PaymentShippingType.Delivery;
            options.RequestPayerEmail       = PaymentOptionPresence.Optional;
            options.RequestPayerName        = PaymentOptionPresence.Required;
            options.RequestPayerPhoneNumber = PaymentOptionPresence.Optional;

            PaymentRequest request = new PaymentRequest(
                CreatePaymentDetails(shoppingCart),
                SupportedPaymentMethods,
                merchantInfo,
                options);

            IAsyncOperation <PaymentRequestSubmitResult> submitOperation = null;

            Action abortSubmitFunc = () =>
            {
                submitOperation.Cancel();
            };

            PaymentRequestChangedHandler changedHandler = (sender, args) =>
            {
                PaymentRequestChangedEventHandler(abortSubmitFunc, args, shoppingCart);
            };

            PaymentMediator mediator = new PaymentMediator();

            submitOperation = mediator.SubmitPaymentRequestAsync(request, changedHandler);

            PaymentRequestSubmitResult result = await submitOperation;

            if (result.Status != PaymentRequestStatus.Succeeded)
            {
                string message = result.Status == PaymentRequestStatus.Canceled ?
                                 "The payment was canceled." :
                                 "The payment failed.";

                MessageDialog failedMessageDialog = new MessageDialog(message);
                await failedMessageDialog.ShowAsync();

                return;
            }

            PaymentResponse response = result.Response;
            PaymentToken    token    = response.PaymentToken;

            bool paymentSucceeded = false;

            switch (token.PaymentMethodId)
            {
            case BasicCardPaymentProtocol.PaymentMethodId:
                BasicCardResponse basicCardResponse = BasicCardPaymentProtocol.ParseResponse(token.JsonDetails);

                //
                // TODO: Use data inside 'basicCardResponse' to collect payment.
                //

                paymentSucceeded = true;
                break;

            case MicrosoftPayProtocol.PaymentMethodId:
                MicrosoftPayProtocolResponse microsoftPayResponse = MicrosoftPayProtocol.ParseResponse(token.JsonDetails);

                switch (microsoftPayResponse.Format)
                {
                case "Stripe":
                    //
                    // TODO: Use data inside 'microsoftPayResponse.Token' to collect payment.
                    //

                    paymentSucceeded = true;
                    break;

                case "Error":
                    paymentSucceeded = false;
                    break;

                case "Invalid":
                    throw new Exception("The payment request was invalid.");

                default:
                    throw new Exception("Unsupported payment gateway.");
                }
                break;

            default:
                await result.Response.CompleteAsync(PaymentRequestCompletionStatus.Unknown);

                throw new Exception("Unsupported payment method ID.");
            }

            await result.Response.CompleteAsync(paymentSucceeded?PaymentRequestCompletionStatus.Succeeded : PaymentRequestCompletionStatus.Failed);

            string completionMessage = paymentSucceeded ?
                                       "The payment succeeded." :
                                       "Unable to process the payment.";

            MessageDialog messageDialog = new MessageDialog(completionMessage);
            await messageDialog.ShowAsync();
        }
Exemple #12
0
 public override int GetHashCode()
 {
     unchecked
     {
         return(((PaymentProcessor != null ? PaymentProcessor.GetHashCode() : 0) * 397) ^ (PaymentToken != null ? PaymentToken.GetHashCode() : 0));
     }
 }
Exemple #13
0
        private PaymentCompleteResponse CreateMockStripePaymentResponse(PaymentToken token, PaymentResponse payment)
        {
            // Returns a mock response
            // Typically you would use the Stripe API here to submit the payment
            // token for processing, then build your response based on the Stripe
            // API response.

            // Since we only handle test tokens, we can do simple
            // string compares for the values specified in
            // https://stripe.com/docs/testing#cards
            if (token.Payload == "tok_chargeDeclined")
            {
                return(CreateMockCardDeclinedResponse(
                           payment.RequestId, payment.Details.ProductContext.InvoiceId,
                           payment.Details.Amount));
            }

            if (token.Payload == "tok_visa" ||
                token.Payload == "tok_mastercard" ||
                token.Payload == "tok_amex")
            {
                return(new PaymentCompleteResponse()
                {
                    RequestId = payment.RequestId,
                    Details = "Thank you for paying your bill!",
                    Entity = new Invoice()
                    {
                        Identifier = payment.Details.ProductContext.InvoiceId,
                        Url = "https://contoso.com/invoice",
                        Broker = new LocalBusiness()
                        {
                            Name = "Contoso"
                        },
                        PaymentDueDate = new DateTime(2019, 1, 31),
                        PaymentStatus = PaymentStatus.PaymentComplete,
                        TotalPaymentDue = new PriceSpecification()
                        {
                            // Bill is paid so amount due is set to 0
                            Price = 0.00,
                            PriceCurrency = "USD"
                        },
                        ConfirmationNumber = "98765"
                    },
                    Result = PaymentResult.Success
                });
            }

            // Not one of the TEST mode cards, return invalid number error
            return(new PaymentCompleteResponse()
            {
                RequestId = payment.RequestId,
                Details = "We were unable to charge your credit card.",
                Result = PaymentResult.Fail,
                Error = new PaymentCompleteError()
                {
                    Code = "card_error",
                    Message = "Card cannot be processed.",
                    Target = "stripeToken",
                    InnerError = new PaymentCompleteError()
                    {
                        Code = PaymentErrorCodes.InvalidNumber,
                        Message = "Sample expects test tokens only."
                    }
                }
            });
        }