How can I set up a test, Stripe connect account on the backend and skip onboarding? - stripe-payments

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",
},
},
},
});

Related

e_validation_failure: validation exception adonisjs

I am facing this error "e_validation_failure: validation exception" only on prod enviroment... I am using Adonis 5, in my local everything runs correctly, in stage as well.
my controller looks like this:
public async store({ request, response }: HttpContextContract) {
response.header('Cache-Control', 'no-cache, no-store');
try {
const payload = await request.validate(SignupUserValidator);
await UserService.store(payload);
return responseWithSuccess(response);
} catch (error) {
return responseWithError(response, error.message);
}
}
my validator looks like this:
import { schema, rules } from '#ioc:Adonis/Core/Validator';
import { HttpContextContract } from '#ioc:Adonis/Core/HttpContext';
import { UserRoleEnum } from 'Contracts/enums';
export default class SignupUserValidator {
constructor(protected ctx: HttpContextContract) {}
public schema = schema.create({
first_name: schema.string({ trim: true }, [rules.minLength(2)]),
last_name: schema.string({ trim: true }, [rules.minLength(2)]),
password: schema.string({}, [rules.minLength(8), rules.confirmed()]),
email: schema.string({}, [
rules.email(),
rules.unique({ table: 'users', column: 'email' }),
]),
role: schema.enum([UserRoleEnum.CLIENT, UserRoleEnum.COWORKING] as const),
photo_id: schema.number.optional([rules.exists({ table: 'photos', column: 'id' })]),
personal_address: schema.object.optional().members({
fulltext: schema.string.optional({ trim: true }),
latitude: schema.number.optional(),
longitude: schema.number.optional(),
city: schema.string.optional(),
state: schema.string.optional(),
country: schema.string.optional({ trim: true }),
}),
personal_phone: schema.string({}, [rules.maxLength(14), rules.minLength(10)]),
cowork: schema.object
.optional([rules.requiredWhen('role', '=', UserRoleEnum.COWORKING)])
.members({
name: schema.string({ trim: true }),
email: schema.string.optional({}, [
rules.email(),
rules.unique({ table: 'cowork_accounts', column: 'email' }),
]),
phone: schema.string.optional({}, [rules.maxLength(14), rules.minLength(10)]),
photo_id: schema.number.optional([
rules.exists({ table: 'photos', column: 'id' }),
]),
}),
client: schema.object
.optional([rules.requiredWhen('role', '=', UserRoleEnum.CLIENT)])
.members({
company_name: schema.string.optional({ trim: true }),
company_email: schema.string.optional({}, [rules.email()]),
company_phone: schema.string.optional({}, [
rules.maxLength(14),
rules.minLength(10),
]),
company_address: schema.object.optional().members({
fulltext: schema.string.optional({ trim: true }),
latitude: schema.number.optional(),
longitude: schema.number.optional(),
country: schema.string.optional({ trim: true }),
}),
company_photo_id: schema.number.optional([
rules.exists({ table: 'photos', column: 'id' }),
]),
}),
});
public messages = {
minLength: 'The {{ field }} must be at least {{ options.minLength }} characters',
maxLength: 'The {{ field }} must have at most {{ options.maxLength }} characters',
required: 'The {{ field }} is required',
exists: 'The {{ field }} is invalid',
number: 'The {{ field }} must be a number',
string: 'The {{ string }} must be a string',
'password_confirmation.confirmed': 'The passwords are different',
'email.email': 'The email is not valid',
'email.unique': 'User with email address already exists',
'cowork.requiredWhen': 'The cowork object must be sent when the user is a coworking',
'cowork.email.email': 'The email is not valid',
'cowork.email.unique': 'Company with email address already exists',
'client.requiredWhen': 'The client object must be sent when the user is a client',
};
My request looks like this:
{
"first_name": "Dan",
"last_name": "Abreu",
"password": "secret1233",
"password_confirmation": "secret1233",
"email": "test#gmail.com",
"role": "CLIENT",
"personal_phone": "1234567890",
"photo_id": null,
"personal_address": {
"fulltext": "Rua do Lead",
"city":"Gravatá",
"state":"Pe",
"country":"Brazil",
"longitude": -10.00,
"latitude": 1.00
},
"client": {
"company_name": "my company",
"company_email": "test1#gmail.com",
"company_phone": "10800-0000",
"company_photo_id": null,
"company_address": {
"fulltext": "Rua do labrador",
"longitude": -10.00,
"latitude": 1.00
}
}
I am following the rules when creating the validator:
node ace make:validator SignupUserValidator
is anyone facing the same issue on aws ec2 enviroment?
I tried to validate the request with the validator I created and everything works fine on my local and stage env but on prod it does not work.

How to get data from different schema in Nodejs

I have two schemas called employees (parent) and assessments(child)
Every assessment will have a pass percentage of employee id
so I have results like this
employees : [
{
"_id": 12345,
"name": "David",
"evaluated": false
},
{
"_id": 12346,
"name": "Miller",
"evaluated": false
}
]
Second Schema
assessments: [
{
"assessment_type": "basic",
"employee_id": 12345,
"qualified": true
},
{
"assessment_type": "advanced",
"employee_id": 12345,
"qualified": false
},
{
"assessment_type": "basic",
"employee_id": 12346,
"qualified": true
},
{
"assessment_type": "advanced",
"employee_id": 12346,
"qualified": true
}
]
So I want to get the employees with evaluated based on assessments qualified is true
can you please tell me what is the best approach for this?
Here is an example where we sort the employees by the assements they succeeded.
const employees = [{
_id: 12345,
name: 'David',
evaluated: false,
}, {
_id: 12346,
name: 'Miller',
evaluated: false,
}];
const assessments = [{
assessment_type: 'basic',
employee_id: 12345,
qualified: true,
}, {
assessment_type: 'advanced',
employee_id: 12345,
qualified: false,
}, {
assessment_type: 'basic',
employee_id: 12346,
qualified: true,
}, {
assessment_type: 'advanced',
employee_id: 12346,
qualified: true,
}];
// Loop at the employees
const sortByAssessment = employees.reduce((tmp, x) => {
// Get all the assessment about the employee
const employeeAssessment = assessments.filter(y => y.employee_id === x._id);
// Deal with each assessment
employeeAssessment.forEach((y) => {
// Only do something about successfull assessments
if (y.qualified) {
// In case this is the first time we are dealing with the assessment_type
// create an array where we are going to insert employees informations
tmp[y.assessment_type] = tmp[y.assessment_type] || [];
// Push the name of the employee inside of the assessment type array
tmp[y.assessment_type].push(x.name);
}
});
return tmp;
}, {});
console.log(sortByAssessment);
you can do 2 things join with $look up or populate with employee id
assessments.aggregate([
{
'$lookup': {
'from': 'employees',
'localField': 'employee_id',
'foreignField': '_id',
'as': 'datas'
}
},
{ "$unwind": "$datas" },
].exec(function(err,result){
console.log(result)
});
2nd way
//assessments your model name
assessments.populate('employee_id').exec(function(err,result){
console.log(result);
});

Not able to get authorization on 2checkout

I am trying to authorize orders on the 2checkout sandbox, it was working fine but suddenly it stopped. Now I am always getting:
Payment Authorization Failed: Please verify your information and try
again, or try another payment method.
var tco = new Twocheckout({
sellerId: "1234456688", //on my code I am sending my true seller id
privateKey: "XXXXXXX-XXXXXX-XXXXXX", //on my code I am sending my key
sandbox: true
});
var plan = SubscriptionService.getPlan(req.body.plan);
if(plan) {
var params = {
"merchantOrderId": new Date().valueOf()+"",
"token": req.body.token,
"currency": "USD",
"tangible": "N",
"lineItems": [
{
"name": plan.name,
"price": plan.price,
"type": "product",
"quantity": "1",
"productId": plan.id,
"recurrence": "1 Month",
"duration": "Forever",
"description": ""
}],
"billingAddr": {
"name": req.body.ccName,
"addrLine1": req.body.streetAddress,
"city": req.body.city,
"state": req.body.state,
"zipCode": req.body.zip,
"country": req.body.country,
"email": req.user.email,
"phoneNumber": "5555555555"
}
};
tco.checkout.authorize(params, function (error, data) {
if (error) {
res.send(error);
} else {
res.send(data.response);
}
});
}
}
this is the example of a json I am sending
{ merchantOrderId: '1494967223074',
token: 'ZTFiNmFkMjktZWNmMi00NjlhLWE0MDAtZmJkMGJlYjU5M2Q1',
currency: 'USD',
tangible: 'N',
lineItems:
[ { name: 'pro plan',
price: '149.00',
type: 'product',
quantity: '1',
productId: '002',
recurrence: '1 Month',
duration: 'Forever',
description: '' } ],
billingAddr:
{ name: 'Testing Tester',
addrLine1: '123 Main Street',
city: 'Townsville',
state: 'ohio',
zipCode: '43206',
country: 'USA',
email: 'victor.eloy#landmarkwebteam.com',
phoneNumber: '55555555' } }
If I go to my account >> site management and set demo to true I manage to get authorizations from the sandbox but the orders do not get logged to the sandbox. Previously even when the demo mode was off I managed to get the orders authorized but now I don't know what is happening.
here comes a log from one order:
I have the exact same problem. Just 4 days ago the code was working fine. I'm assuming it's something from 2checkout not from our code..
Only thing I can see is you are attempting to parse
"zipCode": req.body.zip
but you are sending
zipCode: '43206'
I assume this should be parsed as req.body.zipCode

TaxCloud: Lookup Sales Tax Throws 409

I used the Taxcloud POST API https://api.taxcloud.com/1.0/TaxCloud/Lookup for Lookup Sales Tax using request NPM package. I just used uuid NPM package to generate the unique identifier for customerID, ItemID, cartID of my request object.
Here is the documentation about TaxCloud where I referred.
My Request Object:
{ apiLoginID: 'XXXXXXXXX',
apiKey: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
customerID: '24d1d040-8673-4ecf-94e8-8512d5e8b022',
deliveredBySeller: false,
cartID: 'b974084e-1529-403b-afac-1097fe171faa',
destination:
{ Address1: '15083 US 19 S',
City: 'THOMASVILLE',
State: 'GA',
Zip5: '31792',
Zip4: '' },
origin:
{ Address1: '262 Rio Cir',
City: 'DECATUR',
State: 'GA',
Zip5: '30030',
Zip4: '' },
cartItems:
[ { Qty: 1,
Price: 30,
TIC: 40030,
ItemID: 'a7d5fe75-62f0-4d62-9381-39ea6191bbd8',
Index: 0 } ] }
Error Response:
{ CartID: null,
CartItemsResponse: [],
ResponseType: 0,
Messages:
[ { ResponseType: 0,
Message: 'An error has occurred proessing your request. Please contact TaxCloud (code:409)' } ] }
Your example is not valid JSON. All object parameter names need to be quoted as well, for example:
{apiLoginID: "XXXXXXXXX"}
should be:
{"apiLoginID": "XXXXXXXXX"}

Braintree accepting wrong value for account Number

I am using Braintree's Node.js SDK we got an issue regarding account number it accept garbage vale like that 11235***sdfsf**81321 which is wrong. Can anyone help? Braintree validation how to wrok?
merchantAccountParams = {
individual: {
firstName: "Jane",
lastName: "Doe",
email: "jane#14ladders.com",
phone: "5553334444",
dateOfBirth: "1981-11-19",
ssn: "456-45-4567",
address: {
streetAddress: "111 Main St",
locality: "Chicago",
region: "IL",
postalCode: "60622"
}
},
business: {
legalName: "Jane's Ladders",
dbaName: "Jane's Ladders",
taxId: "98-7654321",
address: {
streetAddress: "111 Main St",
locality: "Chicago",
region: "IL",
postalCode: "60622"
}
},
funding: {
descriptor: "Blue Ladders",
destination: braintree.MerchantAccount.FundingDestination.Bank,
email: "funding#blueladders.com",
mobilePhone: "5555555555",
accountNumber: "11235***sdfsf**81321",
routingNumber: "071101307"
},
tosAccepted: true,
masterMerchantAccountId: "14ladders_marketplace",
id: "blue_ladders_store"
};
gateway.merchantAccount.create(merchantAccountParams, function (err, result) {
});
We can validate the user input from our client side, then we can send a valid value to BrainTree. Account number validation result, we will get only after sending values to BrainTree, they will provide the result in their objects(using BrainTree dll) as a response value.
Please refer this article for more details.

Resources