Git Product home page Git Product logo

signnow / signnow.net Goto Github PK

View Code? Open in Web Editor NEW
15.0 15.0 12.0 1.61 MB

SignNow.Net is the official .NET 4.5+ and .NET Standard class library for the SignNow API. SignNow allows you to embed legally-binding e-signatures into your app, CRM or cloud storage. Send documents for signature directly from your website. Invite multiple signers to finalize contracts.

Home Page: https://www.signnow.com/developers

License: MIT License

C# 100.00%
api-client documents dotnet electronic-signatures esign esignature sdk signnow signnow-api

signnow.net's People

Contributors

alexndrmac avatar andriiyudaichev avatar isamozdran avatar ivanbil avatar paitoanderson avatar sashagolovach avatar scott-avery-gnmh avatar zolotarovleonid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

signnow.net's Issues

"Unexpected Character" error when using GetDocumentHistoryAsync

I received an unexpected character error when using the GetDocumentHistoryAsync method - being hit upon the deserialisation of the returned json.

Issue is with the "JsonAttributes" property in the DocumentHistoryResponse Class - it is defined as String, but I was receiving a Key/Value pair. I changed the type to "Dynamic" (locally) and the issue is resolved.

One time download link does not work with .NET HttpClient

I've encountered a problem with local API client.
I've obtained one time download link with the SignNow.NET API client as described here:
https://docs.signnow.com/docs/signnow/b3A6NDAwNjQwNTY-get-document-download-link
Download link works fine via web-browser. But if I try to download via .NET HttpClient the request fails with 400 Http status code:
image
Do I miss headers or anything else?
Yet DownloadDocumentResponse alternative is not very convenient for integration with our current project.
Thanks in advance.

error invalid_token

I am trying to call GetDocumentAsync using the following code:

    `Dim docId = "a561139515f0486ea3643fc7051ab8b6393c091f"
    Dim accessToken = xxx
    Dim tkn = New Token With {
                       .AccessToken = accessToken
                       }

    Dim ctx As New SignNowContext(tkn)

    Dim svc = New OAuth2Service(clientKey, secretKey)

    Dim valid As Boolean = svc.ValidateTokenAsync(tkn).GetAwaiter().GetResult()

    Console.WriteLine("Valid? " & valid)

    Try
        Dim doc As SignNowDocument = ctx.Documents.GetDocumentAsync(docId).GetAwaiter().GetResult()
    Catch ex As Exception
        Console.WriteLine(ex)
    End Try`

This is the output that I get:

Valid? True
SignNow.Net.Exceptions.SignNowException: invalid_token
at SignNow.Net.Internal.Service.SignNowClient.d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at SignNow.Net.Internal.Service.SignNowClient.d__121.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at SignNow.Net.Internal.Service.SignNowClient.<RequestAsync>d__101.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at SignNow.Net.Service.DocumentService.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at EsignNewApiTest.Module1.Test() in C:\Users\pc\source\repos\EsignNewApiTest\EsignNewApiTest\Module1.vb:line 29

As you can see, the token is validating properly, but I still get an error invalid_token when I try to get the document. I reached out to your support team by email but they were not able to help me. Can you tell me why this does not work and what I can do to make this work?

I cannot get the token using username and password because I am submitting this for a 3rd party. They log in on the front end, I save the token in the database, and then I need to use it in a back-end process to send to SignNow

"String was not recognized as a valid DateTime." on GetDocument

when I place a radio button on document and try to get Document using your packages.
It got crash with the following error

"String was not recognized as a valid DateTime."

Able to fetch using simple API but not using
var document = await signNowContext.Documents.GetDocumentAsync(documentId).ConfigureAwait(true);

How do you move a document into the archive folder?

I can't find any documentation for moving documents to the archive folder, am I missing something?

EDIT: I also can't find any code in .NET to create folders/move documents to folders, just the CURL commands. Do those exist?

Able to get Token but, nothing else

Any ideas why I am able to get a Token AND verify it as true but, whenever I try to do anything else (upload document, download document, get current user, etc.). I get a response that has "Invalid Token" "code 1537".

Spent about 8 hours trying different things and can't figure out what I may be doing wrong.

Thank you.

Create document from the template

When I use create document from template I get followiing error
Untitled

### Following is my code
public static async Task CreateDocumentFromTheTemplate(string documentName, string templateId, Token token)
{
// using token from the Authorization step
var signNowContext = new SignNowContext(token);

        return await signNowContext.Documents
            .CreateDocumentFromTemplateAsync(documentName, templateId)
            .ConfigureAwait(false);
    }

and I generated token using
public static async Task RequestAccessToken(Uri apiBase, CredentialModel clientInfo)
{
Uri apiBaseUrl =new Uri("https://api-eval.signnow.com");

        string clientId = clientInfo.ClientId;
        string clientSecret = clientInfo.ClientSecret;

        string userLogin = clientInfo.Login;
        string userPassword = clientInfo.Password;

        var oauth = new OAuth2Service(apiBaseUrl, clientId, clientSecret);

        return await oauth.GetTokenAsync(userLogin, userPassword, Scope.All)
            .ConfigureAwait(false);
    }

How can you get a non expiring API key?

I'm confused how the authentication for SignNow API works. Why does it seem to need a human's username and password? If I embed those in my web application and then change my password, the app will break.

What is the intended workflow so that you can use the API indefinitely without human intervention? I was expecting it to use just a Bearer token or API key but it seems this can only be used to request a token from a real person's account.

I don't think you can use Basic auth to actually upload documents (etc)?

Thanks!
Nick

Fails to parse error response

When I run the library against sandbox API that seemed to be down at that time I got a response that was not expected by the response handler.

SignNow.Net.Exceptions.SignNowException : Newtonsoft.Json.JsonReaderException thrown while parsing Json body from https://api-eval.signnow.com/oauth2/token (Invalid Json syntax in response (Unexpected character encountered while parsing value: [. Path 'error', line 1, position 10.))
Data:
  RawHeaders: System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.IEnumerable`1[System.String]]
  RawResponse: {"error":[{"code":"HY000","message":"Internal Api Error"}]}
  HttpStatusCode: 500
  ----> SignNow.Net.Exceptions.SignNowException : Invalid Json syntax in response (Unexpected character encountered while parsing value: [. Path 'error', line 1, position 10.)
  ----> Newtonsoft.Json.JsonReaderException : Unexpected character encountered while parsing value: [. Path 'error', line 1, position 10.
   at SignNow.Net.Internal.Service.SignNowClient.ProcessErrorResponse(RequestOptions requestOptions, HttpResponseMessage response)
   at SignNow.Net.Internal.Service.SignNowClient.RequestAsync[TResponse](RequestOptions requestOptions, IHttpContentAdapter`1 adapter, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at SignNow.Net.Internal.Service.SignNowClient.RequestAsync[TResponse](RequestOptions requestOptions, CancellationToken cancellationToken)
   at SignNow.Net.OAuth2Service.ExecuteTokenRequest(Dictionary`2 body, CancellationToken cancellationToken)
   at SignNow.Net.OAuth2Service.GetTokenAsync(String login, String password, Scope scope, CancellationToken cancellationToken)
--SignNowException

Add Ability to Resend Invites

I have added this to my local copy, but thought may be useful for others to include in release.

Need to add a property for Field_Request_Id to the ISignNowField interface (and the Field class):

        /// <summary>
        /// Field Request ID - Needed for Resend Invite
        /// </summary>
        [JsonProperty("field_request_id")]
        public string Field_Request_Id { get; }

This ID can then be retrieved from a Document and used for the Resend API call

ISignInvite Interface:

        /// <summary>
        /// ReSends a Role Based Invite to the Specified Invite ID.
        /// </summary>
        /// <param name="inviteFieldId">The Role identity to resend the invitation to.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns></returns>
        Task ReSendRoleBasedInviteAsync(string inviteFieldId, CancellationToken cancellationToken = default);

UserServices.cs:

        /// <inheritdoc cref="ISignInvite.ReSendRoleBasedInviteAsync(string, CancellationToken)" />
        /// <exception cref="ArgumentException">Invalid format of <paramref name="inviteFieldId"/>.</exception>
        public async Task ReSendRoleBasedInviteAsync(string inviteFieldId, CancellationToken cancellationToken = default)
        {
            await ProcessReSendRoleBasedInviteAsync($"/fieldinvite/{inviteFieldId.ValidateId()}/resend", cancellationToken).ConfigureAwait(false);
        }
        private async Task ProcessReSendRoleBasedInviteAsync(string inviteFieldId,CancellationToken cancellationToken)
        {
            var requestOptions = new PutHttpRequestOptions
            {
                RequestUrl = new Uri(ApiBaseUrl, inviteFieldId),
                Token = Token
            };

            await SignNowClient.RequestAsync(requestOptions, cancellationToken).ConfigureAwait(false);
        }

FieldContent Examples

Hello, could you provide a way to use the FieldContents when uploading a document please. I can't seem to get it uploaded with FieldContents such as the AttachmentContent.

is this a WiP? It Doesn't support many endpoints

Hi,
Does this package plan to support all the SignNow API endpoints in future? Looks like its currently supporting on the basic ones. If not do you accept pull requests to improve on this package?

Unable to use signNowContext.Documents.EditDocumentAsync

I am getting the following error:
Unable to cast object of type 'System.Collections.Generic.List1[Infrastructure.Models.SigningDocuments.SignNowFieldDto]' to type 'System.Collections.Generic.List1[SignNow.Net.Interfaces.IFieldEditable]'.

However my class SignNowFieldDto is implementing IFieldEditable.

image

Error getting token

I'm getting error when trying to connect to the demo api.

Here is my code

string clientId = ConfigurationManager.AppSettings["SignNowClientId"].ToString();
string clientSecret = ConfigurationManager.AppSettings["SignNowClientSecret"].ToString();
string SignNowUser = ConfigurationManager.AppSettings["SignNowUser"].ToString();
string SignNowPass = ConfigurationManager.AppSettings["SignNowPass"].ToString();
string SignNowApiPath = ConfigurationManager.AppSettings["SignNowAPIPath"].ToString();

        Uri apiPath = new Uri(SignNowApiPath);
        // init OAuth2 service
        var oauth = new OAuth2Service(apiPath, clientId, clientSecret);
        // Token retrieval
        var token = oauth.GetTokenAsync(SignNowUser, SignNowPass,Scope.User).Result;

Capture

Error converting value "initials" to type 'SignNow.Net.Model.FieldType'

If a document contains initials field type, GetDocumentAsync method fails with the following exception:

Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in System.Private.CoreLib.dll: 'Error converting value "initials" to type 'SignNow.Net.Model.FieldType'. Path 'fields[10].type', line 1, position 19518.'

Field.cs line 75, enum is missing 'initials' type it has 'Initial' field instead

RefreshAccessToken method

Hi,

I am able to RequestAccessToken, then VerifiyAccessToken but when I try to RefreshAccessToken I get invalid_client. When I take the same access token and try to refresh it through Postman it works. I am not sure if I am doing something wrong but I thought that to refresh access token I supposed to use the refresh token instead of .login and .password, which would be different from this method below?

Am I missing something?

Any help would be appreciated
Thank you
Tom

public static async Task RefreshAccessToken(Uri apiBaseUrl, CredentialModel clientInfo, Token token)
{
var oauth2 = new OAuth2Service(apiBaseUrl, clientInfo.Login, clientInfo.Password);

        return await oauth2.RefreshTokenAsync(token)
            .ConfigureAwait(false);
    }

Invalid token when creating a RoleBaseInvite

I'm using same token for all my calls. The upload works, but when sending the invite, I get invalid_token error.

var connToken = DigitalSignatureHelper.RequestAccessToken();
var uploadedDocument = DigitalSignatureHelper.UploadDocumentAsync(doc, co.approved_contract.Replace(" ", ""),connToken);
var inviteResponse = DigitalSignatureHelper.CreateRoleBasedInviteToSignTheDocument(
uploadedDocument,
emails,
connToken
);

Webhook implementation

Is there any way to use webhooks with this library?
I managed to fit all our integration with this library! Great job! Only the webhooks are missing

GetDocumentAsync fails for documents using stamp fields

When a stamp field is added to a document, the Documents.GetDocumentAsync(...) method fails with error:

Error converting value "stamp" to type 'SignNow.Net.Model.FieldType'. Path 'fields[3].type', line 1, position 7342.

It looks like this might be because the FieldType enum does not include an entry for the stamp type.

invalid_client in Asp MVC

Line 22: var oauth = new OAuth2Service(clientId, clientSecret);
Line 23: Line 24: var token = oauth.GetTokenAsync(userLogin, userPassword,Scope.All).Result;

We are getting an error message when we call the GetTokenAsync()

We are getting an error message stating that the below message System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. this occurs when we call the GetTokenAsync method and we have all the right set of credential details . help would be much appreciated

User provided HttpClient support

Looking through the SDK code, it appears that SignNowContext (and indeed anything that inherits WebClientBase) ends up instantiating an HttpClient each time that object is instantiated. This can lead to socket exhaustion and performance issues if used incorrectly (see Issues with the original HttpClient class available in .NET).

Fortunately, it is fairly simple to support integration with HttpClientFactory (without breaking .Net4.5 compatability). There's a couple of ways that could happen in this project:

  • Make SignNowClient public, and make the OAuth2Service and SignNowContext constructors accepting SignNowClient public
  • Add constructors accepting HttpClient to OAuth2Service and SignNowContext, and instantiate a SignNowClient within these classes.

Personally, I think the former would be the simplest approach and I would be happy to work on a PR to implement this. It might be worth noting that this also has other benefits aside from performance including the ability to use middleware like Polly as well as improved testability.

error 'The document owner cannot send invite to himself.'

My clients send documents to their tenants which they need to counter-sign. The way we have done this until now is by calling SignNow.Document.Invite (from your old SDK), with a signing objec that identifies the tenant as a signer with a signing order of 1 and the one who sent the document having a signing order of 2. This has been working fine. However, now we have a request to add embedded signing. In order to do this, I wanted to use your new SDK, and add an EmbeddedInvite.

Here is my code:


Dim invite = New EmbeddedSigningInvite(doc)

        Dim roleCounter = 0

        For Each email In emailToList 
            invite.AddEmbeddedSigningInvite(New EmbeddedInvite() With
                                                        {
                                                        .Email = email.Email,
                                                        .SigningOrder = 1,
                                                        .RoleId = roles.First(Function(r) r.Name = "Tenant" & roleCounter).Id
                                                        })

            roleCounter += 1
        Next

        roleCounter = 0

        For Each email In counterSignerList            
            invite.AddEmbeddedSigningInvite(New EmbeddedInvite() With
                                                        {
                                                        .Email = email,
                                                        .SigningOrder = 2,
                                                        .RoleId = roles.First(Function(r) r.Name = "Manager" & roleCounter).Id
                                                        })

            roleCounter += 1
        Next

Dim ctx As New SignNowContext(tkn)

                        Dim doc As SignNowDocument = ctx.Documents.GetDocumentAsync(docId).GetAwaiter().GetResult()

                        Try
                            Dim resp = ctx.Invites.CreateInviteAsync(docId, invite).GetAwaiter().GetResult()
                            success = True
                        Catch ex As Exception
                            errorMsg = ex.Message
                            success = False
                        End Try

However, this does not let me set the counter-signer email to be the same as the email sender - it gives me an error that 'The document owner cannot send invite to himself.'

How can I work around this?

Add "CC" string array property to SignInvite

Hi Guys,
My client is asking to include a CC on an invite. I'm hoping this is a fairly straightforward addition to the class along with the JsonProperty attribute.

If you know for sure it will be some time before this can be added that information would be useful as I'll need to fallback to a manual HttpClient request approach.

Thanks!

How to redirect after creating an embedded link

I am embedding sign now and upon signing would like to essentially reload the page, or redirect to the same page would be fine, or in some way notify my parent application that the process is done, how do I go about that, I use this currently:

    CreateEmbeddedSigningInviteToSignTheDocument(SignNowDocument document, string email, SignNowContext signNowContext)
        {
            // create embedded signing invite
            var invite = new EmbeddedSigningInvite(document);
            
            invite.AddEmbeddedSigningInvite(
                new EmbeddedInvite
                {
                    Email = email,
                    RoleId = document.Roles[0].Id,
                    SigningOrder = 1
                });

            return await signNowContext.Invites.CreateInviteAsync(document.Id, invite)
                .ConfigureAwait(false);
        }

and then

        public static async Task<EmbeddedInviteResponse>
    CreateEmbeddedSigningInviteToSignTheDocument(SignNowDocument document, string email, SignNowContext signNowContext)
        {
            // create embedded signing invite
            var invite = new EmbeddedSigningInvite(document);
            
            invite.AddEmbeddedSigningInvite(
                new EmbeddedInvite
                {
                    Email = email,
                    RoleId = document.Roles[0].Id,
                    SigningOrder = 1
                });

            return await signNowContext.Invites.CreateInviteAsync(document.Id, invite)
                .ConfigureAwait(false);
        }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.