Currently I'm working with a Node.js integration for DocuSign (https://www.npmjs.com/package/docusign-esign), I made all the test with the sandbox account and worked perfectly, right now I'm trying to use a production account, the login process is fine but when I'm going to create the envelope I get a USER_AUTHENTICATION_FAILED error (even if the first login went without errors). I would like to know if someone has experienced same thing or has an idea of how can I fix this.
This is the code that I took from the docusign-esign to create the envelope:
var loginAccount = new docusign.LoginAccount();
loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var envelopesApi = new docusign.EnvelopesApi();
envelopesApi.createEnvelope(accountId, envDef, null, function (error, envelopeSummary, response)
The account Id is the same retrieved after the login process.
One possible cause could be that your DocuSign account is hosted on na2.docusign.net, na3.docusign.net or eu.docusign.net, while your code uses the default www.docusign.com as a base URL.
The login call will pass even if you use www, however all the subsequent API calls will fail if you are not hitting the exact base URL that corresponds to your production account. You should have received this information as part of the DocuSign Go-Live process (formerly known as API Certification). You can always get the base URL from the login call response.
For Node, here how to get the correct base URL from the login call and set it up to the API Client (lines in bold are likely what is missing in your code):
authApi.login(loginOps, function (err, loginInfo, response) {
if (err) {
return next(err);
}
if (loginInfo) {
// list of user account(s)
// note that a given user may be a member of multiple accounts
var loginAccounts = loginInfo.getLoginAccounts();
console.log('LoginInformation: ' + JSON.stringify(loginAccounts));
var loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var baseUrl = loginAccount.baseUrl;
var accountDomain = baseUrl.split("/v2");
apiClient.setBasePath(accountDomain[0]);
docusign.Configuration.default.setDefaultApiClient(apiClient);
next(null, loginAccount);
}
});
Related
In a signup custom policy, after the user is created, I want to add him or her to a group. I tried to do it the same way I get the group membership in my signin policy, with a custom Azure function that calls the GraphAPI.
For teststing purpose, I first tried calling GraphAPI with Postman to see if it works. I got it working following the docs and came back with this query :
POST https://graph.microsoft.com/v1.0/groups/{{b2c-beneficiaire-group-id}}/members/$ref
Body:
{
"#odata.id": "https://graph.microsoft.com/v1.0/users/{{b2c-user-id}}"
}
And that work just fine. I get a 204 response and the user is in fact now a member of the group.
Now here's the part where I try to replicate it in my Azure function :
var url = $"https://graph.microsoft.com/v1.0/groups/{groupId}/members/$ref)";
var keyOdataId = "#odata.id";
var valueODataId = $"https://graph.microsoft.com/v1.0/users/{userId}";
var bodyObject = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(keyOdataId, valueODataId)
};
var jsonData = $#"{{ ""{keyOdataId}"": ""{valueODataId}"" }}";
var groupBody = new StringContent(jsonData, Encoding.UTF8, "application/json");
log.LogInformation($"{url} + body:{await groupBody.ReadAsStringAsync()}");
using (var response = await httpClient.PostAsync(url, groupBody))
{
log.LogInformation("HttpStatusCode=" + response.StatusCode.ToString());
if (!response.IsSuccessStatusCode)
{
throw new InvalidOperationException($"{response.StatusCode} - Reason:{response.ReasonPhrase}. Content:{await response.Content.ReadAsStringAsync()}");
}
}
I've tried a few variations (with HttpRequest and other things) but I always end up with an Odata error :
"BadRequest","message":"The request URI is not valid. Since the segment 'members' refers to a collection,
this must be the last segment in the request URI or it must be followed by an function or action
that can be bound to it otherwise all intermediate segments must refer to a single resource."
From what I see it is related to the OData query (the $ref part). Do you have any idea about what do I have to do to make it work?
It looks like a typo in your url which ends with )
var url = $"https://graph.microsoft.com/v1.0/groups/{groupId}/members/$ref)";
Goal: Create a successful (test) Checkout Session using Stripe's API for checkout.
[the link for their tutorial on Checkout here: https://github.com/stripe-samples/checkout-one-time-payments]
I'm creating a checkout session using my UI & building the checkout session with the data supplied to the backend web service using the following code:
var options = new Stripe.Checkout.SessionCreateOptions
{
PaymentMethodTypes = new List<string>
{
"card",
},
LineItems = stripeCartLineItems,
Mode = "payment",
SuccessUrl = "https://" + HostName + "/Stripe/OrderPlaced",
CancelUrl = "https://example.com/cancel",
};
var requestOptions = new RequestOptions
{
StripeAccount = stripeConnectedAccountId,
ApiKey = StripeConfiguration.ApiKey
};
var service = new Stripe.Checkout.SessionService();
Stripe.Checkout.Session session = service.Create(options, requestOptions);
return Json(new { sessionId = session.Id });
As you can see, I receive acknowledgment back from Stripe's API with a valid checkout session id:
Logs on Stripe's Dashboard confirm a successful checkout session:
However, I keep getting this error message:
The API keys have already been refreshed and placed appropriately. That's not the issue... Loading up the test Checkout page is failing. My logs in Stripe's dashboard say this:
The Javascript call which initiates the redirect to Stripe's checkout experience is copied straight from their tutorial (pasted above). That code looks like this:
checkoutButton.addEventListener('click', function () {
$.ajax({
url: "/Stripe/CreateCheckoutSession",
method: "POST",
data: { stripeConnectedAccountId: stripeConnectedAccountId, cartLineItems: scope.cartLineItems },
}).done(function (resp) {
stripe.redirectToCheckout({
sessionId: resp.sessionId
}).then(function (result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
alert(result.error.message);
});
})
After going to: https://stripe.com/docs/error-codes/resource-missing. The docs says this for that specific error code: "The ID provided is not valid. Either the resource does not exist, or an ID for a different resource has been provided."
Ok Stripe. Sure sure. You made this API - I'll listen. However, according to your docs, Intellisense, & your sample code... my code is correct and I used the session.Id provided by the response object YOU sent me after initiating a Checkout Session:
I have no clue how to proceed.
Any ideas are appreciated.
If you have already verified the session and keys from server and stripe,
Please check the stripe key used in your client side. The public key used to initialise the stripe in both client & server should be same.
Check the logs in client side to make sure that the key is same.
I am using the Xero Api with Nodejs and the xero-node library.
I have completed the oAuth flow and saved the token to the database. The issue i am now having is continually getting a 403 forbidden error when attempting to get anything from Xero be that Contacts, Accounts or Users. Sample code is below
I can get tenants ok without an issue however anything else doesn't work. I have checked the scopes to make sure when I am setting up the client they are correct which they are.
var getStuff = async(tokenSet) => {
await xero.setTokenSet(tokenSet);
const tenants = await xero.updateTenants();
const xeroTenantId = tenants[0].id // {String} Xero identifier for Tenant
const ifModifiedSince = new Date("2020-02-06T12:17:43.202-08:00");
const where = 'IsSubscriber==true'; // {String} Filter by an any element
const order = 'LastName ASC'; // {String} Order by an any element
console.log(tenants);
try {
const response = await xero.accountingApi.getUsers(xeroTenantId, ifModifiedSince, where, order);
console.log(response.body || response.response.statusCode)
}
catch (err) {
/// console.log(err);
console.log(`There was an ERROR! \n Status Code: ${err.response.statusCode}.`);
console.log(`ERROR: \n ${JSON.stringify(err.response.body, null, 2)}`);
}
}
Which scopes have been added to the access token you are passing through? You can decode your token here https://jwt.io/
Also - you need to pass the ‘tenant.tenantId’ to the function. I believe the tenant.id actually relates to the connection id which is coming back from the /connections endpoint.
My hunch is that is the issue. Also curious how that’s working, as updateTenants() should have the empty function call on the end. Is that working for you?
I've built out an integration using DocuSign's Node SDK. While testing using a DocuSign sandbox account, the authentication flow works just fine using the example in the docs.
I'm now trying to do the same within a live DocuSign production account using the Integrator Key that was promoted from the sandbox account. authApi.login() seems to work just fine, I get no error and the status code of the response is 200. However, the value of loginInfo comes back as exports {} with no account info included.
I've made sure to change the base path from https://demo.docusign.net/restapi to www.docusign.net/restapi and as far as I can tell from the docs, there doesn't seem to be anything else I need to make the switch to production. Here is the code I am using:
apiClient.setBasePath('www.docusign.net/restapi');
apiClient.addDefaultHeader('Authorization', 'Bearer ' + token);
docusign.Configuration.default.setDefaultApiClient(apiClient);
const authApi = new docusign.AuthenticationApi();
const loginOps = {
apiPassword: true,
includeAccountIdGuid: true
};
authApi.login(loginOps, function (err, loginInfo, response) {
if (err) {
console.log(err);
}
if (loginInfo) {
// loginInfo returns 'exports {}' so the variables below cannot be set.
const loginAccounts = loginInfo.loginAccounts;
const loginAccount = loginAccounts[0];
const baseUrl = loginAccount.baseUrl;
const accountDomain = baseUrl.split('/v2');
const accountId = loginAccount.accountId;
apiClient.setBasePath(accountDomain[0]);
docusign.Configuration.default.setDefaultApiClient(apiClient);
www.docusign.net endpoint will only work if your PROD account is in NA1, if your PROD Account is in NA2, then you need to use na2.docusign.net and if it is in NA3 then na3.docusign.net. This is the main reason you should use /oauth/userinfo call with OAUTH2 Access Token to know your base URL, and then call all APIs with this baseURL. You can find more details at https://docs.docusign.com/esign/guide/authentication/userinfo.html
I've created service account with domain wide delegation and its scopes (in Admin console and Developer console) as described in documentation. I've been trying this for a week now and I am stuck. This is my code:
const google = require('googleapis');
const gmail = google.gmail('v1');
const directory = google.admin('directory_v1');
const scopes = [
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/admin.directory.user.readonly'
];
const key = require('./service_key.json');
var authClient = new google.auth.JWT(
key.client_email,
key,
key.private_key,
scopes,
"kruno#example.com"
);
authClient.authorize(function(err, tokens){
if (err) {
console.log(err);
return;
}
// API call methods here...
});
I get this error:
Error: unauthorized_client
I am unable to understand:
Is this proper technique for calling Google API methods from server-side scripts without any user interaction? (under domain only)
How do service account and actual user account communicate this way?
I heard about callback URI, am I missing it?
I think you are missing the final step which is giving access to your application in the control panel of your domain.
You can follow doc properly to activate it with your application
https://developers.google.com/+/domains/authentication/delegation
Also you can start with your first call step here
https://developers.google.com/adwords/api/docs/guides/first-api-call