I am using docusign (production account) to allow users to sign documents. I am trying to add data to textTabs that I create through the docusign dashboard. So say if I add a text box and call it nbShares, the below code does not populate the box. All the boxes I add in the dashboard such as signature, text, checkboxes etc are not shown in the generated link. I get no API errors either. I also tried to create customFields, and pass data to them as textTab - however this did not work either.
I think I may misunderstand the flow, I add all recipients and signers programatically - is that why I cant see the placeholders/buttons I add? I have also allowed collaboration in the fields I add, made them mandatory - yet they still do not appear.
Would really appreciate some help on this. This is my envelope definition - Im using the node sdk along with ts types.
const makeEnvelopeDefinition = async (
templateName: string,
user: User,
dealId?: string,
): Promise<EnvelopeDefinition> => {
const personToSign: Signer = {
email: user.email,
name: user.name,
roleName: 'Signer',
// Should this work?
tabs: {
textTabs: [
{ tabLabel: 'nbShares', value: '1000' },
],
},
clientUserId: DOCUSIGN_CLIENT_USER_ID,
recipientId: '1',
}
const compositeTemplate: CompositeTemplate = {
serverTemplates: [
{ sequence: '1', templateId: 'remote-template-id' },
],
inlineTemplates: [
{
sequence: '1',
recipients: {
signers: [personToSign],
certifiedDeliveries: [
{
email: 'someemail#something.com',
recipientId: '77',
name: 'Receipt of transaction',
},
{
email: user.email,
recipientId: '771',
name: user.name,
},
],
},
},
],
}
// create the envelope definition
const envelope: EnvelopeDefinition = {
emailSubject: 'Review signed document',
status: 'sent',
compositeTemplates: [compositeTemplate],
}
return envelope
}
For me the solution was changing my signer to this
const personToSign: Signer = {
email: user.email,
name: user.name,
clientUserId: await getDocusignConfig().DOCUSIGN_CLIENT_USER_ID,
recipientId: '1',
routingOrder: '1', // Was missing this
roleName: 'Signer', // Must match signer specified on docusign dashboard
tabs: {
textTabs: [
{
xPosition: '150',
yPosition: '200',
name: 'First Name',
tabLabel: 'name', // Must match the dataLabel name specified on docusign
value: 'Test',
},
],
},
}
And enabling this setting 'When an envelope is sent, write the initial value of the field for all recipients' in 'Signing Settings' on docusign.
Related
When I try to set up a test, Stripe connect account on the backend and skip onboarding, I run into address and identity verification issues. How can I resolve these?
Background: for testing backend features other than Stripe onboarding, it would be helpful to set up a test Stripe connect account that has completed onboarding. There are other answers here indicating that there is no one-call process to complete that, but it's not clear exactly what the steps are.
Below I try to complete this in 3 steps; but I am running into an issue: the address is unverified even though I'm using the address 'token' that the documentation says will automatically verify.
My steps:
Create an account token
Create a bank_account token
Create an account, using those tokens
Result: when I check the account after a few seconds (I wait 10 seconds for verification) I get:
account.payouts_enabled: true
account.charges_enabled: true
account.currently_due: [
"individual.address.line1"
]
account.past_due: []
account.eventually_due: []
account.disabled_reason: requirements.pending_verification
account.pending_verification: [
'individual.address.city',
'individual.address.line1',
'individual.address.postal_code',
'individual.address.state',
'individual.id_number'
]
The problem: why is the address line marked "currently_due" (when I'm using the documented token "address_full_match") and address verification incomplete? Additionally, why is the individual.id_number pending verification (when I'm using the documented token "222222222")?
Code below, using the Stripe Node API:
const accountToken = await stripe.tokens.create({
account: {
business_type: 'individual',
individual: {
first_name: 'Jenny',
last_name: 'Rosen',
// https://stripe.com/docs/connect/testing
// Use these addresses for line1 to trigger certain verification conditions. You must pass in legitimate values for the city, state, and postal_code arguments.
// address_full_match Successful verification.
// address_no_match Unsuccessful verification.
address: {
line1: 'address_full_match',
city: 'Columbus',
state: 'OH',
postal_code: '43214',
// country: 'US'
},
// https://stripe.com/docs/connect/testing#test-dobs
// 1901-01-01 Successful verification. Any other DOB results in unsuccessful verification.
// 1902-01-01 Successful, immediate verification. The verification result is returned directly in the response, not as part of a webhook event.
// 1900-01-01 This DOB will trigger an Office of Foreign Assets Control (OFAC) alert.
dob: {
day: 1,
month: 1,
year: 1902
},
// https://stripe.com/docs/connect/testing
// Use these personal ID numbers for individual[id_number] or the id_number attribute on the Person object to trigger certain verification conditions.
// 000000000 Successful verification. 0000 also works for SSN last 4 verification.
// 111111111 Unsuccessful verification (identity mismatch).
// 222222222 Successful, immediate verification. The verification result is returned directly in the response, not as part of a webhook event.
id_number: '222222222',
// ssn_last_4: '0000',
email: 'jenny.rosen#example.com',
phone: '000 000 0000'
},
tos_shown_and_accepted: true,
},
});
const bankAccountToken = await stripe.tokens.create({
bank_account: {
country: 'US',
currency: 'usd',
account_holder_name: 'Jenny Rosen',
account_holder_type: 'individual',
routing_number: '110000000',
account_number: '000123456789',
},
});
const account = await stripe.accounts.create({
type: 'custom',
country: 'US',
business_profile: {
mcc: '5734', // Merchant Category Code. 5734 = Computer Software Stores
product_description: 'Cool Beans, Inc',
},
external_account: bankAccountToken.id,
capabilities: {
card_payments: {
requested: true,
},
transfers: {
requested: true,
},
},
account_token: accountToken.id,
});
Here's the config that works for me:
async function createTestStripeAccount() {
return await stripe.accounts.create({
type: 'custom',
country: 'US',
capabilities: {
card_payments: { requested: true },
transfers: { requested: true }
},
business_type: 'individual',
external_account: {
object: 'bank_account',
country: 'US',
currency: 'usd',
routing_number: '110000000',
account_number: '000123456789'
},
tos_acceptance: { date: 1609798905, ip: '8.8.8.8' },
business_profile: { mcc: 5045, url: 'https://bestcookieco.com' },
individual: {
first_name: 'Test',
last_name: 'User',
phone: '+16505551234',
email: 'test#example.com',
id_number: '222222222',
address: {
line1: '123 State St',
city: 'Schenectady',
postal_code: '12345',
state: 'NY'
},
dob: {
day: 10,
month: 11,
year: 1980
}
}
})
}
I've managed to set it up today for my client in sandbox and production.
PHP version with using the official library SDK from stripe.
composer require stripe/stripe-php
At the time of this writing the above version of stripe/stripe-php is exactly v9.6.0
<?php
\Stripe\Stripe::setApiKey('yourSandbox-STRIPE_SECRET_KEY-Here');
\Stripe\Account::create([
"type" => "custom",
"country" => "GB",
"capabilities" => [
"card_payments" => [
"requested" => true,
],
"transfers" => [
"requested" => true,
],
],
"business_type" => "individual",
"external_account" => [
"object" => "bank_account",
"country" => "GB",
"currency" => "gbp",
"account_number" => "00012345",
],
'tos_acceptance' => ['date' => 1609798905, 'ip' => '8.8.8.8'],
"business_profile" => [
"mcc" => 5045,
"url" => "https://exmple.com",
],
"individual" => [
"first_name" => "Test",
"last_name" => "User",
"phone" => "+16505551234",
"email" => "test#example.com",
"id_number" => "222222222",
"address" => [
"line1" => "123 State St",
"city" => "London",
"postal_code" => "TF5 0DL",
],
"dob" => [
"day" => 01,
"month" => 01,
"year" => 1901,
],
],
]);
I hope it will help somebody to save some time. Cheers and good luck.
References:
https://stripe.com/docs/connect/custom-accounts#create
https://stripe.com/docs/connect/testing#identity-and-address-verification
https://stripe.com/docs/connect/updating-accounts
You have to add document field as well for upload document to make the account active for testing purpose.
const account = await stripe.accounts.create({
type: "custom",
country: "US",
capabilities: {
card_payments: { requested: true },
transfers: { requested: true },
},
business_type: "individual",
external_account: {
object: "bank_account",
country: "US",
currency: "usd",
routing_number: "110000000",
account_number: "000123456789",
},
tos_acceptance: { date: new Date(), ip: "8.8.8.8" },
business_profile: { mcc: 5045, url: "https://bestcookieco.com" },
individual: {
first_name: "custom_user",
last_name: "one",
phone: "+16505551234",
email: "custom_user1#yopmail.com",
id_number: "222222222",
address: {
line1: "address_full_match",
city: "Schenectady",
postal_code: "12345",
state: "NY",
},
dob: {
day: 01,
month: 01,
year: 1901,
},
verification: {
document: {
front: "file_identity_document_success",
},
},
},
});
And thanks in advance for any help !
When I create en envelope with the status "sent", the signers does not get e-mail any more.
Friday morning, everything was working I was receiving e-mail.
But since friday noon, i can not receive a single e-mail (for recipients).
When I use: envelopeApi.createEnvelope(this.config.accountId, { envelopeDefinition })
My code receive:
{
"envelopeId": "xxx",
"status": "sent",
"statusDateTime": "2021-07-26T09:29:11.1800000Z",
"uri": "/envelopes/xxx"
}
And When I check in the envelope administration panel, I see
If I try to create the envelope from the administration panel, emails are sent but not from API calls...
Is it my account which limited or did I missed something?
Complete code example:
async testSendEnvelope2() {
const signers: TemplateRole[] = [
{
email: 'sirko.alexandre#gmail.com',
name: 'alexander',
clientUserId: 'toto',
tabs: {
textTabs: [
{
tabLabel: 'toto',
locked: 'true',
required: 'true',
value: 'blabla',
},
],
},
roleName: 'Freeluper',
},
{
email: 'alexandre#jump-biz.com',
name: 'jalexandre',
clientUserId: 'titi',
tabs: {
textTabs: [
{
tabLabel: 'titi',
locked: 'true',
required: 'true',
value: 'blibli',
},
],
},
roleName: 'Company',
},
];
const env: EnvelopeDefinition = {
emailSubject: 'le sujet du mail',
status: 'sent',
templateId: 'xxx',
templateRoles: signers,
};
const results = await this.docusignService.sendEnvelope(env);
console.log(results);
}
And this.docusignService.sendEnvelope simply calls the envelopeApi.createEnvelope (with credentials)
Re: Why aren't my recipients receiving email invitations to the signing ceremony?
The reason is that you are setting the clientUserId attribute for the recipient objects.
When you do that, the recipients become captive (embedded) recipients. In this case, email is not sent since the assumption is that you want your application to offer the signing ceremony to them.
If you want to record recipient metadata without causing the recipients to become embedded signers, use the customFields attribute
Re: Limitations for developer accounts?
The main limitations for the developer (demo) accounts are:
the envelopes cannot be used for legally binding agreements
the envelopes are cleared out periodically.
Re slow email
On rare occasions the developer system gets a bit backed up and email delivery is slow.
A way to check is to use the DocuSign web app to send a test envelope from your developer account. If it works then you should suspect your API app.
I'm allowing credit card payment with paypal smart buttons. This is how my createOrder looks like:
createOrder: function(data, actions) {
paypalActions = actions;
return fetch('/basket/get/lineitems', {
method: 'get'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
orderDataArray = [orderData]
return actions.order.create({
payer: {
name: {
given_name: "PayPal",
surname: "Customer"
},
address: {
address_line_1: '123 ABC Street',
address_line_2: 'Apt 2',
admin_area_2: 'San Jose',
admin_area_1: 'CA',
postal_code: '95121',
country_code: 'US'
},
email_address: "customer#domain.com",
phone: {
phone_type: "MOBILE",
phone_number: {
national_number: "12345678"
}
}
},
purchase_units: orderDataArray,
shipping_type: 'PICKUP',
application_context: { shipping_preference: 'NO_SHIPPING' }
})
});
},
(The fetch requests gets my card items.)
Following the docs: https://developer.paypal.com/docs/checkout/integration-features/standard-card-fields/#optimize-the-card-fields it's working nicely to pass the billing address which I already have. Only the phone Number does not get filled.
What is needed to fill the phone field with above example? Or even better is it possible to set it to not required?
The number length for National Numbers is a validation for the API; using the US example you needed the correct length of the phone number. For US Numbers it expects 1 ### ### ####
I am using Amazon Cognito user pool and AdminCreateUser api to create a new user so that we don't allow users to sign themselves up. It works great but it seems that email verification step is being skipped so when making an api call, I needed to set email_verified attribute to true to make reset password flow to work.
Can I make email verification to happen before sending out an inviatation email?
const params = {
DesiredDeliveryMediums: ['EMAIL'],
UserAttributes: [
{
Name: 'email',
Value: email
},
{
Name: 'email_verified',
Value: 'True'
},
],
Username: email,
UserPoolId: userPoolId,
}
cognitoIdentityService.adminCreateUser(params, function(err, data) {
// ...
To prevent backend to send verification email, set MessageACtion="SUPPRESS"
response = client.admin_create_user(
UserPoolId='USER_POOL_ID',
Username='USERNAME',
TemporaryPassword='PASSWORD',
UserAttributes=[
{
'Name': 'email',
'Value': 'email#example.com'
},
{
'Name': 'email_verified',
'Value': 'true'
}
],
MessageAction='SUPPRESS'
)
I tried to run a script which creates a specific intent by using the Dialogflow API. The API is enabled already a couple of weeks.
After I called my script i received the following error:
Error: Dialogflow API has not been used in project usable-auth-library before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/dialogflow.googleapis.com/overview?project=usable-auth-library then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
at /Users/$USER"/Desktop/node_modules/grpc/src/client.js:554:15
code: 7,
metadata:
Metadata {
_internal_repr:
{ 'google.rpc.help-bin': [Array],
'grpc-status-details-bin': [Array],
'grpc-server-stats-bin': [Array] } } }
Here is my script.
// Imports the Dialogflow library
const dialogflow = require('dialogflow');
// Instantiates clients
const contextsClient = new dialogflow.ContextsClient();
const intentsClient = new dialogflow.IntentsClient();
projectId="1000-1505-ecom-conx-dev"
projectId="conrad-test"
// The path to identify the agent that owns the created intent.
const agentPath = intentsClient.projectAgentPath(projectId);
// Setup intents for ordering a pizza.
// First of all, let's create an intent that triggers pizza order flow.
// Output contexts for ordering pizza. They are used for matching follow-up
// intents. For pizza ordering intents, a "pizza" output context is used for
// hinting the conversation is about pizza ordering, not beer or something
// else. For the first intent, it returns responses asking users to provide
// size information, with a "size" output context for matching the intent
// asking for the size of the pizza.
// Note that session ID is unknown here, using asterisk.
const accountOutputContexts = [
{
name: contextsClient.contextPath(
projectId,
'*' /* sessionId */,
'EComerceAgent'
),
lifespanCount: 5,
},
];
// The result of the matched intent.
const accountResult = {
action: '',
parameters: [
{
displayName: 'Account for',
value: '$application',
entityTypeDisplayName: '#application',
mandatory: true,
prompts: [
'You need appliation access, please describe for which and which permissions do you need?',
'Would you like access to jirra?',
'Would you like access to confluence?',
'Would you like access to AEM?',
],
},
{
displayName: 'user',
value: '$user',
entityTypeDisplayName: '#user',
mandatory: true,
prompts: ['For wich user'],
isList: true,
},
{
displayName: 'permission',
value: '$permission',
// The API provides a built-in entity type #sys.address for addresses.
entityTypeDisplayName: 'permission',
mandatory: true,
prompts: ['Which permission do you need?'],
},
],
messages: [
{
text: {
text: [
'No problem. We will create an account on $application for $user with the following permission: $permission'
],
},
},
{
text: {
text: [
'Reply "check" to place your order. Reply "cancel" to cancel ' +
'your order. You can change your delivery address as well.',
],
},
},
{
quickReplies: {
title:
'No problem. We will create an account on $application for $user with the following permissions: $permission',
quickReplies: ['Create account', 'Cancel']
},
platform: 'PLATFORM_UNSPECIFIED',
},
],
outputContexts: accountOutputContexts,
};
// The phrases for training the linguistic model.
const accountPhrases = [
{type: 'TYPE_EXAMPLE', parts: [{text: 'Get account'}]},
{type: 'TYPE_EXAMPLE', parts: [{text: 'acction'}]},
{
type: 'TYPE_EXAMPLE',
parts: [
{text: 'Create an account '},
{text: 'for', entityType: '#application', alias: 'application'},
{text: ' '},
{text: 'for ', entityType: '#user', alias: 'user'},
{text: 'with the followin permissions ', entityType: '#permission', alias: 'permission'},
],
},
{
type: 'TYPE_EXAMPLE',
parts: [
{text: "I'd like to have access "},
{text: 'to', entityType: '#application', alias: 'application'},
],
}
];
// The intent to be created.
const accountIntent = {
displayName: 'Account',
events: ['create_account'],
// Webhook is disabled because we are not ready to call the webhook yet.
webhookState: 'WEBHOOK_STATE_DISABLED',
trainingPhrases: accountPhrases,
mlEnabled: true,
priority: 500000,
result: accountResult,
};
const accountRequest = {
parent: agentPath,
intent: accountIntent,
};
// Create the pizza intent
intentsClient
.createIntent(accountRequest)
.then(responses => {
console.log('Created account intent:');
logIntent(responses[0]);
})
.catch(err => {
console.error('ERROR:', err);
});
The error is not clear at all, it means that your are not authorized to access the remote ressource without credentials. Here is the quick solution that worked for me :
Go to https://console.cloud.google.com/apis/credentials/serviceaccountkey
Download json auth file (eg. foobar-123.json)
Add environement variable :
export GOOGLE_APPLICATION_CREDENTIALS="/home/me/secure/foobar-123.json"
And the full tutorial & documentation here : https://cloud.google.com/docs/authentication/getting-started
I reported this issue : https://github.com/dialogflow/dialogflow-nodejs-client-v2/issues/28