public async Task should_handle_same_cc_same_amount() { // do nothing, payment doesn't need updating // Arrange var mockedCreditCardTotal = 50; var existing = PaymentMocks.PaymentList(PaymentMocks.CCPayment(creditcard1, 50, mockCCPaymentID)); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, mockOrderID) .Returns(Task.FromResult(existing)); var requested = PaymentMocks.Payments(PaymentMocks.CCPayment(creditcard1)); _orderCalc.GetCreditCardTotal(Arg.Any <HSOrderWorksheet>()) .Returns(mockedCreditCardTotal); // Act var result = await _sut.SavePayments(mockOrderID, requested, mockUserToken); // Assert await _oc.Payments.DidNotReceive().DeleteAsync(OrderDirection.Incoming, mockOrderID, Arg.Any <string>()); await _ccCommand.DidNotReceive().VoidTransactionAsync(Arg.Any <HSPayment>(), Arg.Any <HSOrder>(), mockUserToken); await _oc.Payments.DidNotReceive().CreateAsync <HSPayment>(Arg.Any <OrderDirection>(), mockOrderID, Arg.Any <HSPayment>(), mockUserToken); await _oc.Payments.DidNotReceive().PatchAsync <HSPayment>(Arg.Any <OrderDirection>(), mockOrderID, Arg.Any <string>(), Arg.Any <PartialPayment>()); }
public async Task should_handle_different_cc_different_amount() { // if the credit card has changed we need to delete the payment // but should void the existing authorization before that // Arrange var mockedCreditCardTotal = 50; var existing = PaymentMocks.PaymentList(PaymentMocks.CCPayment(creditcard1, 40, mockCCPaymentID)); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, mockOrderID) .Returns(Task.FromResult(existing)); var requested = PaymentMocks.Payments(PaymentMocks.CCPayment(creditcard2)); _orderCalc.GetCreditCardTotal(Arg.Any <HSOrderWorksheet>()) .Returns(mockedCreditCardTotal); // Act var result = await _sut.SavePayments(mockOrderID, requested, mockUserToken); // Assert await _oc.Payments.Received().DeleteAsync(OrderDirection.Incoming, mockOrderID, mockCCPaymentID); await _ccCommand.Received().VoidTransactionAsync(Arg.Is <HSPayment>(p => p.ID == mockCCPaymentID), Arg.Is <HSOrder>(o => o.ID == mockOrderID), mockUserToken); await _oc.Payments.Received().CreateAsync <HSPayment>(OrderDirection.Outgoing, mockOrderID, Arg.Is <HSPayment>(p => p.CreditCardID == creditcard2 && p.Amount == mockedCreditCardTotal && p.Accepted == false), mockUserToken); }
public async Task should_handle_same_cc_different_amount() { // if the credit card hasn't changed but the amount has // then we should void any existing transactions if necessary and update the payment // Arrange var mockedCreditCardTotal = 30; var existing = PaymentMocks.PaymentList(PaymentMocks.CCPayment(creditcard1, 20)); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, mockOrderID) .Returns(Task.FromResult(existing)); var requested = PaymentMocks.Payments(PaymentMocks.CCPayment(creditcard1)); _orderCalc.GetCreditCardTotal(Arg.Any <HSOrderWorksheet>()) .Returns(mockedCreditCardTotal); // Act var result = await _sut.SavePayments(mockOrderID, requested, mockUserToken); // Assert await _oc.Payments.DidNotReceive().DeleteAsync(OrderDirection.Incoming, mockOrderID, Arg.Any <string>()); await _ccCommand.Received().VoidTransactionAsync(Arg.Is <HSPayment>(p => p.ID == mockCCPaymentID), Arg.Is <HSOrder>(o => o.ID == mockOrderID), mockUserToken); await _oc.Payments.Received().PatchAsync <HSPayment>(OrderDirection.Incoming, mockOrderID, mockCCPaymentID, Arg.Is <PartialPayment>(p => p.Amount == mockedCreditCardTotal && p.Accepted == false)); }
public async Task should_handle_failed_auth_void() { // creates a new transaction when auth fails which // gives us full insight into transaction history as well as sets Accepted to false var paymentTotal = 30; // credit card total is 38 // Arrange var payment1transactions = new List <HSPaymentTransaction>() { new HSPaymentTransaction { ID = transactionID, Succeeded = true, Type = "CreditCard", xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = validretref } } } }; var mockedCCPayment = MockCCPayment(paymentTotal, true, payment1transactions); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, orderID, filters: Arg.Is <object>(f => (string)f == "Type=CreditCard")) .Returns(PaymentMocks.PaymentList(mockedCCPayment)); var payment = ValidIntegrationsPayment(); _cardConnect .When(x => x.VoidAuthorization(Arg.Any <CardConnectVoidRequest>())) .Do(x => throw new CreditCardVoidException(new ApiError { }, new CardConnectVoidResponse { })); // Act var ex = Assert.ThrowsAsync <OrderCloudIntegrationException>(async() => await _sut.AuthorizePayment(payment, userToken, merchantID)); // Assert Assert.AreEqual("Payment.FailedToVoidAuthorization", ex.ApiError.ErrorCode); // stuff that happens in catch block await _supportAlerts .Received() .VoidAuthorizationFailed(Arg.Any <HSPayment>(), transactionID, Arg.Any <HSOrder>(), Arg.Any <CreditCardVoidException>()); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Any <PaymentTransaction>()); }
public async Task should_still_create_transaction_on_failed_auths() { // this gives us full insight into transaction history // as well as sets Accepted to false var paymentTotal = 38; // credit card total is 38 // Arrange var payment1transactions = new List <HSPaymentTransaction>() { new HSPaymentTransaction { ID = transactionID, Succeeded = true, xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = validretref } } } }; var mockedCCPayment = MockCCPayment(paymentTotal, false, payment1transactions); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, orderID, filters: Arg.Is <object>(f => (string)f == "Type=CreditCard")) .Returns(PaymentMocks.PaymentList(mockedCCPayment)); _oc.Payments.PatchAsync <HSPayment>(OrderDirection.Incoming, orderID, Arg.Any <string>(), Arg.Any <PartialPayment>()) .Returns(Task.FromResult(mockedCCPayment)); var payment = ValidIntegrationsPayment(); _cardConnect .When(x => x.AuthWithoutCapture(Arg.Any <CardConnectAuthorizationRequest>())) .Do(x => throw new CreditCardAuthorizationException(new ApiError { }, new CardConnectAuthorizationResponse { })); // Act var ex = Assert.ThrowsAsync <OrderCloudIntegrationException>(async() => await _sut.AuthorizePayment(payment, userToken, merchantID)); // Assert Assert.AreEqual("CreditCardAuth.", ex.ApiError.ErrorCode); await _cardConnect.Received().AuthWithoutCapture(Arg.Any <CardConnectAuthorizationRequest>()); // stuff that happens in catch block await _oc.Payments.Received().PatchAsync <HSPayment>(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PartialPayment>(p => p.Accepted == false && p.Amount == ccTotal)); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Any <PaymentTransaction>()); }
public async Task should_handle_existing_po_payment() { // Arrange var mockedPOTotal = 20; var existing = PaymentMocks.PaymentList(PaymentMocks.POPayment(40)); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, mockOrderID) .Returns(Task.FromResult(existing)); var requested = PaymentMocks.Payments(PaymentMocks.POPayment()); // Act var result = await _sut.SavePayments(mockOrderID, requested, mockUserToken); // Assert await _oc.Payments.Received().PatchAsync <HSPayment>(OrderDirection.Incoming, mockOrderID, mockPoPaymentID, Arg.Is <PartialPayment>(p => p.Amount == mockedPOTotal)); }
public async Task should_delete_stale_payments() { // Arrange var mockedCreditCardTotal = 20; var existing = PaymentMocks.PaymentList(PaymentMocks.SpendingAccountPayment(20)); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, mockOrderID) .Returns(Task.FromResult(existing)); var requested = PaymentMocks.Payments(PaymentMocks.CCPayment(creditcard1)); // Act var result = await _sut.SavePayments(mockOrderID, requested, mockUserToken); // Assert await _oc.Payments.Received().DeleteAsync(OrderDirection.Incoming, mockOrderID, mockSpendingAccountID); await _oc.Payments.Received().CreateAsync <HSPayment>(OrderDirection.Outgoing, mockOrderID, Arg.Is <HSPayment>(p => p.ID == mockCCPaymentID && p.Type == PaymentType.CreditCard && p.Amount == mockedCreditCardTotal), mockUserToken); }
public async Task should_skip_auth_if_payment_valid() { // If a payment has already been accepted and is equal to the // order total then don't auth again // Arrange _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, orderID, filters: Arg.Is <object>(f => (string)f == "Type=CreditCard")) .Returns(Task.FromResult(PaymentMocks.PaymentList(PaymentMocks.CCPayment("creditcardid1", 38)))); var payment = ValidIntegrationsPayment(); // Act await _sut.AuthorizePayment(payment, userToken, merchantID); // Assert await _cardConnect.DidNotReceive().AuthWithCapture(Arg.Any <CardConnectAuthorizationRequest>()); await _oc.Payments.DidNotReceive().CreateTransactionAsync(OrderDirection.Incoming, orderID, Arg.Any <string>(), Arg.Any <PaymentTransaction>()); }
public async Task should_void_if_accepted_but_not_valid() { // if a payment is accepted but doesn't match order total than we need to void before authorizing again for new amount var paymentTotal = 30; // credit card total is 38 // Arrange var payment1transactions = new List <HSPaymentTransaction>() { new HSPaymentTransaction { ID = transactionID, Succeeded = true, Type = "CreditCard", xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = validretref } } } }; _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, orderID, filters: Arg.Is <object>(f => (string)f == "Type=CreditCard")) .Returns(PaymentMocks.PaymentList(MockCCPayment(paymentTotal, true, payment1transactions))); var payment = ValidIntegrationsPayment(); // Act await _sut.AuthorizePayment(payment, userToken, merchantID); // Assert await _cardConnect.Received().VoidAuthorization(Arg.Is <CardConnectVoidRequest>(x => x.retref == validretref && x.merchid == merchantID && x.currency == "CAD")); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PaymentTransaction>(x => x.Amount == paymentTotal)); await _cardConnect.Received().AuthWithoutCapture(Arg.Any <CardConnectAuthorizationRequest>()); await _oc.Payments.Received().PatchAsync <HSPayment>(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PartialPayment>(p => p.Accepted == true && p.Amount == ccTotal)); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Any <PaymentTransaction>()); }
public async Task should_handle_existing_voids_us() { // same as should_handle_existing_voids but handle usd merchant var paymentTotal = 30; // credit card total is 38 // Arrange var payment1transactions = new List <HSPaymentTransaction>() { new HSPaymentTransaction { ID = "authattempt1", Succeeded = true, Type = "CreditCard", xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = "retref1" } } }, new HSPaymentTransaction { ID = "voidattempt1", Succeeded = true, Type = "CreditCardVoidAuthorization", xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = "retref2" } } }, new HSPaymentTransaction { ID = "authattempt2", Type = "CreditCard", Succeeded = true, xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = "retref3" } } } }; _settings.CardConnectSettings.UsdMerchantID = merchantID; _settings.CardConnectSettings.CadMerchantID = "somethingelse"; _hsExchangeRates.GetCurrencyForUser(userToken) .Returns(Task.FromResult(CurrencySymbol.USD)); _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, orderID, filters: Arg.Is <object>(f => (string)f == "Type=CreditCard")) .Returns(PaymentMocks.PaymentList(MockCCPayment(paymentTotal, true, payment1transactions))); var payment = ValidIntegrationsPayment(); // Act await _sut.AuthorizePayment(payment, userToken, merchantID); // Assert await _cardConnect.Received().VoidAuthorization(Arg.Is <CardConnectVoidRequest>(x => x.retref == "retref3" && x.merchid == merchantID && x.currency == "USD")); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PaymentTransaction>(x => x.Amount == paymentTotal)); await _cardConnect.Received().AuthWithoutCapture(Arg.Any <CardConnectAuthorizationRequest>()); await _oc.Payments.Received().PatchAsync <HSPayment>(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PartialPayment>(p => p.Accepted == true && p.Amount == ccTotal)); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Any <PaymentTransaction>()); }
public async Task should_handle_existing_voids() { // in a scenario where a void has already been processed on the payment // we want to make sure to only try to void the last successful transaction of type "CreditCard" var paymentTotal = 30; // credit card total is 38 // Arrange var payment1transactions = new List <HSPaymentTransaction>() { new HSPaymentTransaction { ID = "authattempt1", Succeeded = true, Type = "CreditCard", xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = "retref1" } } }, new HSPaymentTransaction { ID = "voidattempt1", Succeeded = true, Type = "CreditCardVoidAuthorization", xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = "retref2" } } }, new HSPaymentTransaction { ID = "authattempt2", Type = "CreditCard", Succeeded = true, xp = new TransactionXP { CardConnectResponse = new CardConnectAuthorizationResponse { retref = "retref3" } } } }; _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, orderID, filters: Arg.Is <object>(f => (string)f == "Type=CreditCard")) .Returns(PaymentMocks.PaymentList(MockCCPayment(paymentTotal, true, payment1transactions))); var payment = ValidIntegrationsPayment(); // Act await _sut.AuthorizePayment(payment, userToken, merchantID); // Assert await _cardConnect.Received().VoidAuthorization(Arg.Is <CardConnectVoidRequest>(x => x.retref == "retref3" && x.merchid == merchantID && x.currency == "CAD")); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PaymentTransaction>(x => x.Amount == paymentTotal)); await _cardConnect.Received().AuthWithoutCapture(Arg.Any <CardConnectAuthorizationRequest>()); await _oc.Payments.Received().PatchAsync <HSPayment>(OrderDirection.Incoming, orderID, paymentID, Arg.Is <PartialPayment>(p => p.Accepted == true && p.Amount == ccTotal)); await _oc.Payments.Received().CreateTransactionAsync(OrderDirection.Incoming, orderID, paymentID, Arg.Any <PaymentTransaction>()); }