PaySimple / PaySimpleSDK

.NET SDK for PaySimple API v4
Other
4 stars 1 forks source link

Recurring Payment: Exception of type 'PaySimpleSdk.Exceptions.PaySimpleException' was thrown. #13

Closed blashblash closed 7 years ago

blashblash commented 7 years ago

I'm new here, everything was fantastic in creating a customer and payment. So I tried the recurring payment, but I'm getting an exceptions error . I already QA testing it by individually removing each class until I remove all class. Still getting an error even I remove all the class inside and also I tried to null everything in the class, but still getting the error.

I tried the sample code in the documentation..

var customerRecurringPayment = new NewCustomerRecurringPayment<Ach>
{
    Customer = new Customer
    {
        FirstName = "Hoban",
        LastName = "Washburne"
    },
    Account = new Ach
    {       
        RoutingNumber = "30707529",
        AccountNumber = "751111111",
        BankName = "PaySimple Bank"
    },
    RecurringPayment = new RecurringPayment
    {
        PaymentAmount = 25.00M,
        ExecutionFrequencyType = ExecutionFrequencyType.FirstOfMonth,       
        StartDate = DateTime.Now
    }
};

var newCustomerRecurringPayment = await paymentScheduleService.CreateNewCustomerRecurringPaymentAsync<Ach>(customerRecurringPayment);`
WillBDaniels commented 7 years ago

In order to help you, we would need more specific details about your issue. Can you please provide the full stack trace of the error you're getting?

blashblash commented 7 years ago

So this is my code

` [HttpPost] [ValidateAntiForgeryToken] public async System.Threading.Tasks.Task Create(ParentModel apsp)

    {

        //Paysimple creation

        string username = "assa";
        string apiKey = "asasa";
        string baseUrl = "https://sandbox-api.paysimple.com";
        var settings = new PaySimpleSettings(apiKey, username, baseUrl);

        var paymentScheduleService = new PaymentScheduleService(settings);

        //customer

        string fn = apsps.FirstName;
        string ln = apsps.LastName;
        string street1 = apsp.Customer.BillingAddress.StreetAddress1;
        string street2 = apsp.Customer.BillingAddress.StreetAddress2;
        string city = apsp.Customer.BillingAddress.City;
        Enum statecode = apsp.Customer.BillingAddress.StateCode;
        Enum country = apsp.Customer.BillingAddress.Country;
        Enum zipcode= apsp.Customer.BillingAddress.ZipCode;

        //account
        string credit = apsp.CreditCard.CreditCardNumber;
         string expir = apsp.CreditCard.ExpirationDate;
          Enum issuer = apsp.CreditCard.Issuer;

        //payment
        decimal pamount = apsp.RecurringPayment.PaymentAmount;
        DateTime? end = apsp.RecurringPayment.EndDate;

            var customerPayment = new NewCustomerRecurringPayment<CreditCard>
            {
                Customer = new Customer()
                {
                    FirstName = fn,
                    LastName = ln,
                    BillingAddress = new Address
                    {
                        StreetAddress1 = street1,
                        StreetAddress2 = street2,
                        City = city,
                        StateCode = (StateCode)statecode,
                        Country = (CountryCode)country,
                        ZipCode = zipcode
                    }
                },
                Account = new CreditCard
                {
                    CreditCardNumber = credit,
                    ExpirationDate = expir,
                    Issuer = (Issuer)issuer
                },
                RecurringPayment = new RecurringPayment
                {
                    PaymentAmount = 25.00M,
                    ExecutionFrequencyType = ExecutionFrequencyType.FirstOfMonth,
                    StartDate = DateTime.Now
                }
            };

        var newCustomerPayment = await paymentScheduleService.CreateNewCustomerRecurringPaymentAsync<CreditCard>(customerPayment);

            return View(apsp);           
    }`
blashblash commented 7 years ago

Exception of type 'PaySimpleSdk.Exceptions.PaySimpleException' was thrown.

Line 250: var newAccountRecurringPayment = await paymentScheduleService.CreateNewAccountRecurringPaymentAsync(accountRecurringPayment);

WillBDaniels commented 7 years ago

I'll need the entire stack trace please, in order to assist further. Also, make sure your api usernamd and apikey are correct with what was provided to you via' partnerSupport.

scottlance commented 7 years ago

@blashblash Have you tried interrogating the ValidationErrors member of the PaySimpleException? That enumeration of errors should have any information you will need to fix the problem. The ValidationError.ErrorMessage member has the exact error message that percolates up from the API.

See: https://github.com/PaySimple/PaySimpleSDK/blob/master/src/PaySimpleSdk/Exceptions/ValidationError.cs

blashblash commented 7 years ago

@WillBDaniels yes my api username and apikey is correct,

[PaySimpleException: Exception of type 'PaySimpleSdk.Exceptions.PaySimpleException' was thrown.]
   PaySimpleSdk.Validation.ValidationService.Validate(IValidatable model) +73
   PaySimpleSdk.PaymentSchedules.<CreateNewCustomerRecurringPaymentAsync>d__6`1.MoveNext() +73
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +28
   ASPandCRM.Controllers.<Create>d__6.MoveNext() in C:\Users\cse-dev\Desktop\ASPandCRM\ASPandCRM\Controllers\RecurringController.cs:172
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +97
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +17
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9744373
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
WillBDaniels commented 7 years ago

@blashblash So the issue you're having is due to a slight error in the documentation (which I will fix momentarily), where we state the the 'startDate' of the recurring payment is at DateTime.now(). However we require that all recurring payment plans start at a future time. Thus the error. If you were to investigate the result of the errors as @ScottDLance suggested, you would see that the error you were getting stated as much.

The fix for you would be to change the StartDate = DateTime.Now to StartDate = DateTime.Now.AddDays(1) saying that the recurring payment will start tomorrow.

If you want the behavior of 'have the first payment fire right now', you must first send a regular payment (not a recurring one) for the current moment in time, and then in the future, the recurring payment will take over.

I'll be modifying both the documentation to reflect this, as well as the test harness to have a test case specifically addressing this. Speaking of the test harness, I highly recommend that if you have any additional errors/etc. The test harness is an excellent tool for debugging the application, as all of the framework for catching various exceptions, etc. is already laid out for you, and made the validation errors abundantly clear.

blashblash commented 7 years ago

@WillBDaniels Thanks it works fine...

I don't know how to use the exceptions thingy, is this the right way to used it?

`catch (PaySimpleException ex) { foreach (var e in ex.ValidationErrors) {

                e.CustomState.ToString();
              e.AttemptedValue.ToString();
                e.PropertyName.ToString();
               e.ErrorMessage.ToString();
          }
        `
scottlance commented 7 years ago

@blashblash: Yes, that's how you can look at the errors. You really don't need to .ToString() the PropertyName and ErrorMessage though, since they are already strings.

WillBDaniels commented 7 years ago

It's also worth mentioning, you don't need the addDays(1), you could do AddSeconds(30) even, it's a future enhancement that we should be only checking the day, not the actual time, since we don't have a concept of 'fire a payment on a specific day at a specific time'. I'll open an issue for that enhancement.

blashblash commented 7 years ago

@ScottDLance I'm getting an red line when I remove the .ToString, and it doesn't show any error,

blashblash commented 7 years ago

@WillBDaniels Thanks

scottlance commented 7 years ago

Well thats odd. If .ToString is working for you then by all means keep it in. Is there anything else we can do for you on this issue? If not please mark it as closed.

blashblash commented 7 years ago

Is there any exceptions that will show when I typed a wrong credit card?? or in any other fields? because when I tried there's nothing that showing up

scottlance commented 7 years ago

@blashblash The documentation is all here:

https://developer.paysimple.com/documentation.html#introduction

The documentation states:

Payment Object Response Attributes Key Attributes

Id: Integer -- this is the PaymentId number you will need to reference in future calls related to this transaction including void, refund, and view details.

Status: Integer -- payment Status set by the system. Enumeration: 0 = Pending; 1 = Posted; 2 = Settled; 3 = Failed; 5 = Voided; 6 = Reversed; 9 = ReversePosted; 10 = Chargeback; 12 = Authorized; 13 = Returned; 15 = ReverseNSF; 17 = Refund Settled

Expected Responses for new payments are Posted, Authorized or Failed.

NOTE: These labels do not all correspond to PaySimple Status names in the UI. Mapping is as follows: Reversed = Refunded; ReversePosted = Refund (Posted); ReverseNSF = Returned NSF

ProviderAuthCode: String -- a pass-through field that displays the authorization response for the transaction.

TraceNumber: String -- a pass-through field that displays the processor’s transaction identifier for a successful transaction or the provider’s error message for a failed transaction.

FailureData: String -- standardized system information about why a transaction failed; 4 components: Code --a 4-digit PaySimple Error Code

Description --a description of the Error

The last two are germane to your question. This won't be exposed as an exception, it will be exposed as a 200 response to the request. So you will need to interrogate the response for the FailureData and Description

blashblash commented 7 years ago

@ScottDLance Hi tried using the exception, is just go back to the create form whenever I put a wrong value?any way to show what is wrong in the field?

scottlance commented 7 years ago

@blashblash Again, if the response to the API was successful, you will get a 200 response back and the SDK will not throw an exception. This means you will get a Payment object back. The error will be in this object. I would look at the "IsDecline" flag and the "FailureData" member. This should contain the data you are looking for.

blashblash commented 7 years ago

I tried to not fill everything, I got this. is there any validation in here? Like a data annotation? Object reference not set to an instance of an object.

scottlance commented 7 years ago

@blashblash I'm not sure what you are referring to when you say 'this'. Where you trying to upload an image?

blashblash commented 7 years ago

sorry for that, whenever I tried to not to put a value in the fields I got the object reference error because it's null. So is there any way to prevent this??

scottlance commented 7 years ago

In that case you should get a PaySimpleException. Please refer to the SDK Documentation:

https://github.com/PaySimple/PaySimpleSDK/wiki/Exceptions

blashblash commented 7 years ago

Yes Itried that, here? e.CustomState.ToString(); e.AttemptedValue.ToString(); e.PropertyName.ToString(); e.ErrorMessage.ToString();

scottlance commented 7 years ago

Yes, the failure should be in one of the ValidationErrors returned by the exception. If you aren't seeing that and you are getting a Payment object back, then see what FailureData is in the returned object.

blashblash commented 7 years ago

is there any way that it will be like, first name must a value. below the field of firstname

scottlance commented 7 years ago

Surfacing the error conditions returned by the SDK is up to the implementer. We don't support writing your UI for you. As a suggestion, catch the PaySimpleValidationError, collect the messages in the ValidationError collection, continue execution, and then return the errors to your UI.

When submitting a payment, you will get error messages like:

Amount must be greater than 0.00 CVV is invalid

And so forth. I would look at the code for the Validation in each service to see what validation errors you will get back for different rule failures.

HTH

blashblash commented 7 years ago

also in recurring payment there's no ccv in that? I tried the 0 amount but doesn't show the Amount must be greater than 0.00

scottlance commented 7 years ago

That's because the member is called PaymentAmount so your error should be:

PaymentAmount must be greater than 0

blashblash commented 7 years ago

it doesn't show PaymentAmount must be greater than 0 but it go directly go to home

scottlance commented 7 years ago

I can't help you with anything outside the SDK. If you are having issues showing errors to your users, that's something you need to figure out on your own. You should do some basic debugging and see if you are getting errors in the SDK. If you can show that validation in the SDK is failing for cases where it shouldn't be, we would be more than happy to look at that.

blashblash commented 7 years ago

pkay thanks :)