public override byte[] ToBytes() { return(TLUtils.Combine( TLUtils.SignatureToBytes(Signature), PaymentToken.ToBytes(), GoogleTransactionId.ToBytes())); }
// 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); } }
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); }
public void TestWrongCoin() { PaymentToken euro = new PaymentToken(101, 99); ITokenConverter convertor = new SterlingTokenConverter(euro); ICoin c = convertor.Coin; Assert.AreEqual(c, null); }
public void ConvertMoneyForBuying() { PaymentToken pound = new PaymentToken(100, 100); ITokenConverter convertor = new SterlingTokenConverter(pound); ICoin c = convertor.Coin; Assert.AreEqual(c.Worth, 1); }
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); }
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); }
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); }
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)); }
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); } }
/// <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(); }
public override int GetHashCode() { unchecked { return(((PaymentProcessor != null ? PaymentProcessor.GetHashCode() : 0) * 397) ^ (PaymentToken != null ? PaymentToken.GetHashCode() : 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." } } }); }