...
 
Commits (2)
......@@ -67,4 +67,55 @@ class Stripe extends Cli\Controller implements Interfaces\CliControllerInterface
$intent = $intentManager->get($id);
var_dump($intent);
}
public function fix_connect()
{
$connectManager = new Core\Payments\Stripe\Connect\Manager();
$i = 0;
foreach ($connectManager->getList() as $account) {
++$i;
echo "\n$i $account->id";
var_dump($account->requirements->currently_due);
}
}
public function remove_business_type()
{
$connectManager = new Core\Payments\Stripe\Connect\Manager();
$account = $connectManager->getByAccountId($this->getOpt('id'));
$connectManager->update($account);
}
public function create_stripe_lookups()
{
$connectManager = new Core\Payments\Stripe\Connect\Manager();
$iterator = new Core\Analytics\Iterators\SignupsOffsetIterator();
$iterator->token = $this->getOpt('token');
$i = 0;
$s = 0;
foreach ($iterator as $user) {
if (!$user instanceof Entities\User) {
continue;
}
++$i;
var_dump($user->getMerchant());
if ($stripeId = $user->getMerchant()['id']) {
++$s;
}
echo "\n$s/$i $user->guid {$stripeId} ($iterator->token)";
if (!$stripeId) {
continue;
}
try {
$account = $connectManager->getByAccountId($stripeId);
$account->setEmail($user->getEmail());
$account->setUrl('https://www.minds.com/' . $user->username);
$account->setMetadata([
'guid' => (string) $user->guid,
]);
$connectManager->update($account);
} catch (\Exception $e) {
}
}
}
}
......@@ -12,7 +12,7 @@ use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class photoid implements Interfaces\Api
class document implements Interfaces\Api
{
public function get($pages)
{
......@@ -21,11 +21,20 @@ class photoid implements Interfaces\Api
public function post($pages)
{
$documentType = $pages[0] ?? null;
if (!$documentType) {
return Factory::response([
'status' => 'error',
'message' => '/:documentType must be provided',
]);
}
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
$fp = fopen($_FILES['file']['tmp_name'], 'r');
$connectManager->addPhotoId($account, $fp);
$connectManager->addDocument($account, $fp, $documentType);
return Factory::response([ 'account_id' => $account->getId() ]);
}
......
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe\connect;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class update implements Interfaces\Api
{
public function get($pages)
{
return Factory::response([]);
}
public function post($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
if ($_POST['phone'] ?? null) {
$account->setPhoneNumber($_POST['phone']);
}
if ($_POST['id_number'] ?? null) {
$account->setPersonalIdNumber($_POST['id_number']);
}
try {
$connectManager->update($account);
} catch (\Exception $e) {
return Factory::response([
'status' => 'error',
'message' => $e->getMessage(),
]);
}
return Factory::response([]);
}
public function put($pages)
{
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
......@@ -8,6 +8,7 @@
namespace Minds\Controllers\api\v2\wallet\usd;
use Minds\Core;
use Minds\Core\Config;
use Minds\Helpers;
use Minds\Interfaces;
use Minds\Api\Factory;
......@@ -105,9 +106,11 @@ class account implements Interfaces\Api
$vars = Core\Router::getPutVars();
$user = Core\Session::getLoggedInUser();
$account = (new Payments\Stripe\Connect\Account())
->setUserGuid(Core\Session::getLoggedInUser()->guid)
->setUser(Core\Session::getLoggedInUser())
->setUserGuid($user->guid)
->setUser($user)
->setDestination('bank')
->setCountry($vars['country'])
->setSSN($vars['ssn'] ? str_pad((string) $vars['ssn'], 4, '0', STR_PAD_LEFT) : '')
......@@ -121,7 +124,9 @@ class account implements Interfaces\Api
->setState($vars['state'])
->setPostCode($vars['postCode'])
->setPhoneNumber($vars['phoneNumber'])
->setIp($_SERVER['HTTP_X_FORWARDED_FOR']);
->setIp($_SERVER['HTTP_X_FORWARDED_FOR'])
->setEmail($user->getEmail())
->setUrl(Config::_()->get('site_url') . $user->username);
try {
$stripeConnectManager = Core\Di\Di::_()->get('Stripe\Connect\Manager');
......
......@@ -24,6 +24,12 @@ use Minds\Traits\MagicAttributes;
* @method Account getSSN(): string
* @method Account getPersonalIdNumber(): string
* @method Account getUser(): User
* @method string getEmail()
* @method Account setEmail(string $email)
* @method string getUrl()
* @method Account setUrl(string $url)
* @method array getMetadata()
* @method Account setMetdata(array $metadata)
*/
class Account
{
......@@ -32,6 +38,9 @@ class Account
/** @var string $id */
private $id;
/** @var User */
private $user;
/** @var string $userGuid */
private $userGuid;
......@@ -47,11 +56,14 @@ class Account
/** @var string $email */
private $email;
/** @var string $url */
private $url;
/** @var string $dob */
private $dob;
private $dateOfBirth;
/** @var string $ssn */
private $ssn;
private $sSN;
/** @var string $personalIdNumber */
private $personalIdNumber;
......@@ -113,6 +125,12 @@ class Account
/** @var string $requirement */
private $requirement;
/** @var string */
private $ip;
/** @var array */
private $metadata;
/** @var array $exportable */
private $exportable = [
'guid',
......
......@@ -81,15 +81,23 @@ class Manager
$data['individual']['gender'] = $account->getGender();
}
if ($account->getEmail()) {
$data['individual']['email'] = $account->getEmail();
}
if ($account->getUrl()) {
$data['business_profile']['url'] = $account->getUrl();
}
if ($account->getPhoneNumber()) {
$data['individual']['phone'] = $account->getPhoneNumber();
$data['individual']['phone'] = "+" . $account->getPhoneNumber();
}
// US 1099 requires SSN
if ($account->getSSN()) {
$data['individual']['ssn_last_4'] = $account->getSSN();
$data['requested_capabilities'] = ['card_payments', 'transfers'];
$data['requested_capabilities'] = ['legacy_payments', 'card_payments', 'transfers'];
}
if ($account->getPersonalIdNumber()) {
......@@ -132,46 +140,51 @@ class Manager
{
try {
$stripeAccount = $this->accountInstance->retrieve($account->getId());
if ($stripeAccount->individual->verification->status !== 'verified') {
$stripeAccount->individual->first_name = $account->getFirstName();
$stripeAccount->individual->last_name = $account->getLastName();
if ($stripeAccount->legal_entity->verification->status !== 'verified') {
$stripeAccount->legal_entity->first_name = $account->getFirstName();
$stripeAccount->legal_entity->last_name = $account->getLastName();
$stripeAccount->legal_entity->address->city = $account->getCity();
$stripeAccount->legal_entity->address->line1 = $account->getStreet();
$stripeAccount->legal_entity->address->postal_code = $account->getPostCode();
$stripeAccount->legal_entity->address->state = $account->getState();
$stripeAccount->individual->address->city = $account->getCity();
$stripeAccount->individual->address->line1 = $account->getStreet();
$stripeAccount->individual->address->postal_code = $account->getPostCode();
$stripeAccount->individual->address->state = $account->getState();
$dob = explode('-', $account->getDateOfBirth());
$stripeAccount->legal_entity->dob->day = $dob[2];
$stripeAccount->legal_entity->dob->month = $dob[1];
$stripeAccount->legal_entity->dob->year = $dob[0];
$stripeAccount->individual->dob->day = $dob[2];
$stripeAccount->individual->dob->month = $dob[1];
$stripeAccount->individual->dob->year = $dob[0];
if ($account->getGender()) {
$stripeAccount->legal_entity->gender = $account->getGender();
$stripeAccount->individual->gender = $account->getGender();
}
if ($account->getPhoneNumber()) {
$stripeAccount->legal_entity->phone_number = $account->getPhoneNumber();
$stripeAccount->individual->phone = $account->getPhoneNumber();
}
} else {
if (!$stripeAccount->legal_entity->ssn_last_4_provided && $account->getSSN()) {
$stripeAccount->legal_entity->ssn_last_4 = $account->getSSN();
if (!($stripeAccount->individual->ssn_last_4i ?? null) && $account->getSSN()) {
$stripeAccount->individual->ssn_last_4 = $account->getSSN();
}
}
if (!$account->legal_entity->personal_id_number_provided && $account->getPersonalIdNumber()) {
$account->legal_entity->personal_id_number = $account->getPersonalIdNumber();
}
if (!$account->individual->id_number_provided && $account->getPersonalIdNumber()) {
$stripeAccount->individual->id_number = $account->getPersonalIdNumber();
}
if ($account->getEmail()) {
$stripeAccount->individual->email = $account->getEmail();
}
if ($account->getAccountNumber()) {
$stripeAccount->external_account->account_number = $account->getAccountNumber();
if ($account->getUrl()) {
$stripeAccount->business_profile->url = $account->getUrl();
}
if ($account->getRoutingNumber()) {
$stripeAccount->external_account->routing_number = $account->getRoutingNumber();
if ($account->getPhoneNumber()) {
$stripeAccount->individual->phone = $account->getPhoneNumber();
}
$stripeAccount->metadata = $account->getMetadata();
$stripeAccount->save();
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
......@@ -230,17 +243,28 @@ class Manager
}
/**
* Add photo Id
* Add document
* @param Account $account
* @param resource $file
* @param string $documentType
* @return bool
*/
public function addPhotoId(Account $account, $file) : bool
public function addDocument(Account $account, $file, string $documentType) : bool
{
return (bool) $this->fileInstance->create([
$fileId = $this->fileInstance->create([
'purpose' => 'identity_document',
'file' => $file,
], [ 'stripe_account' => $account->getId() ]);
return (bool) $this->accountInstance->update($account->getId(), [
'individual' => [
'verification' => [
$documentType => [
'front' => $fileId,
],
],
]
]);
}
/**
......@@ -252,41 +276,37 @@ class Manager
{
try {
$result = $this->accountInstance->retrieve($id);
$account = (new Account())
->setId($result->id)
->setStatus('active')
->setCountry($result->country)
->setFirstName($result->legal_entity->first_name)
->setLastName($result->legal_entity->last_name)
->setGender($result->legal_entity->gender)
->setDateOfBirth($result->legal_entity->dob->year . '-' . str_pad($result->legal_entity->dob->month, 2, '0', STR_PAD_LEFT) . '-' . str_pad($result->legal_entity->dob->day, 2, '0', STR_PAD_LEFT))
->setStreet($result->legal_entity->address->line1)
->setCity($result->legal_entity->address->city)
->setPostCode($result->legal_entity->address->postal_code)
->setState($result->legal_entity->address->state)
->setPhoneNumber($result->legal_entity->phone_number)
->setSSN($result->legal_entity->ssn_last_4)
->setPersonalIdNumber($result->legal_entity->personal_id_number)
->setFirstName($result->individual->first_name)
->setLastName($result->individual->last_name)
->setGender($result->individual->gender ?? null)
->setDateOfBirth($result->individual->dob->year . '-' . str_pad($result->individual->dob->month, 2, '0', STR_PAD_LEFT) . '-' . str_pad($result->individual->dob->day, 2, '0', STR_PAD_LEFT))
->setStreet($result->individual->address->line1)
->setCity($result->individual->address->city)
->setPostCode($result->individual->address->postal_code)
->setState($result->individual->address->state)
->setPhoneNumber($result->individual->phone ?? null)
->setSSN($result->individual->ssn_last_4 ?? null)
->setPersonalIdNumber($result->individual->id_number ?? null)
->setBankAccount($result->external_accounts->data[0])
->setAccountNumber($result->external_accounts->data[0]['last4'])
->setRoutingNumber($result->external_accounts->data[0]['routing_number'])
->setDestination('bank')
->setPayoutInterval($result->settings->payouts->schedule->interval)
->setPayoutDelay($result->settings->payouts->schedule->delay_days)
->setPayoutAnchor($result->settings->payouts->schedule->monthly_anchor);
->setPayoutAnchor($result->settings->payouts->schedule->monthly_anchor ?? null)
->setMetadata($result->metadata);
//verifiction check
if ($result->legal_entity->verification->status === 'verified') {
if ($result->individual->verification->status === 'verified') {
$account->setVerified(true);
}
if (!$account->getVerified()) {
switch ($result->requirements->disabled_reason) {
case 'requirements.past_due':
$account->setRequirement($result->requirements->currently_due[0]);
break;
}
$account->setRequirement($result->requirements->currently_due[0]);
}
$account->setTotalBalance($this->getBalanceById($result->id, 'available'));
......@@ -351,4 +371,30 @@ class Manager
return true;
}
/**
* Return an iterator of accounts
* @return iterable
*/
public function getList(): iterable
{
$startingAfter = null;
while (true) {
$opts = [
'limit' => 10,
];
if ($startingAfter) {
$opts['starting_after'] = $startingAfter;
}
$accounts = $this->accountInstance->all($opts);
if (!$accounts) {
return null;
}
foreach ($accounts as $account) {
yield $account;
$startingAfter = $account->id;
}
}
}
}
......@@ -64,6 +64,10 @@ class ManagerSpec extends ObjectBehavior
->willReturn(null);
$account->getPersonalIdNumber()
->willReturn(null);
$account->getEmail()
->willReturn('test@minds.com');
$account->getUrl()
->willReturn('https://minds.com/test');
$this->accountInstance->create(Argument::any())
->shouldBeCalled()
......@@ -99,7 +103,7 @@ class ManagerSpec extends ObjectBehavior
->willReturn((object) [
'id' => 'acc_123',
'country' => 'GB',
'legal_entity' => (object) [
'individual' => (object) [
'first_name' => 'George',
'last_name' => 'Harrison',
'gender' => null,
......@@ -141,6 +145,7 @@ class ManagerSpec extends ObjectBehavior
],
],
],
'metadata' => [],
]);
$this->balanceInstance->retrieve([ 'stripe_account' => 'acc_123'])
......@@ -179,7 +184,7 @@ class ManagerSpec extends ObjectBehavior
->willReturn((object) [
'id' => 'acc_123',
'country' => 'GB',
'legal_entity' => (object) [
'individual' => (object) [
'first_name' => 'George',
'last_name' => 'Harrison',
'gender' => null,
......@@ -220,7 +225,8 @@ class ManagerSpec extends ObjectBehavior
'monthly_anchor' => 31,
]
]
]
],
'metadata' => [],
]);
$this->balanceInstance->retrieve([ 'stripe_account' => 'acc_123'])
......