Latest news

How To Use Stripe Connect With Custom Account (Vendor Account) In Magento 2?

No comments

Stripe is one of the most popular payment gateways for Magento 2 e-commerce stores. In this Magento tutorial, we will show you how to integrate Stripe to Magento 2 websites and use custom account.

With the custom account (vendor account), you can modify the connected account’s details and settings through the API, including managing their bank accounts and payout schedule.

Step 1: Stripe module installation & configuration

  • Download the Stripe Payment For Magento 2 module here and install it on your site.
  • Create a new Stripe account here.
  • After finishing the installation process, open your admin panel, navigate to STORES > Configuration > SALES > Payment Methods. Under Stripe Payment Gateway, expand Stripe Core, and enter your Production Publishable API Key and Production Secret API Key (taken from your Stripe account information).

stripe connect magento 2

  • Enable all Stripe payment method(s) you want to use.

 

Step 2: Module customization to use with the custom account

1/ Create a module named Tigren_StripeConnect with frontname = tigren

2/ Create a new form for connecting Stripe custom account

  • Create a new controller in Tigren/StripeConnect/Controller/Stripe name account with the following content:
<?php

namespace Tigren\StripeConnect\Controller\Stripe;

use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

class Account extends \Magento\Backend\App\Action
{
    /**
     * @var PageFactory
     */
    protected $resultPagee;

    /**
     * @param Context     $context
     * @param PageFactory $resultPageFactory
     */
    public function __construct(
        Context $context,
        PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }

    /**
     * Index action
     *
     * @return void
     */
    public function execute()
    {
        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
        $resultPage = $this->resultPageFactory->create();


        return $resultPage;
    }
}

?>
  • Create new layout in Tigren/StripeConnect/view/frontend/layout named tigren_stripe_account.xml with the following content:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Tigren\StripeConnect\Block\Stripe\Form" name="tigren-stripeconnnect-form " template="Tigren_StripeConnect::stripe/form.phtml"/>
        </referenceContainer>
    </body>
</page>
  • In “Tigren\StripeConnect\Block\Stripe\Form” add the following content:
<?php
namespace Tigren\StripeConnect\Block\Stripe;

class Form extends \Magento\Backend\Block\Template
{

    protected $_url;

    public function __construct(
        \Magento\Framework\UrlInterface $url,
        \Magento\Backend\Block\Template\Context $context, array $data = []
    ) {
        parent::__construct($context, $data);
        $this->Url = $url;
    }
    public function getPostUrl()
    {
        $url = $this->url->getUrl("tigren/stripe/createandconnect");
        return $url;
    }

}
  • In Tigren/StripeConnect /view/templates/stripe/form.phtml add the following content:
<form class="form" action='<?php echo $this->getPostUrl() ?>' method="post">
    <input name="form_key" type="hidden" value="<?php /* @escapeNotVerified */ echo $this->getFormKey() ?>" />
    <fieldset class="fieldset">
        <legend class="legend"><span><?php echo __('Create Account') ?></span></legend><br>
        <div class="field required">
            <label for="account_country" class="label">
                <span><?php echo __('Country') ?></span>
            </label>
            <div class="control">
                <select name="account_country" id="account_country">
                    <option value="NZ">New Zealand</option>
                </select>
            </div>
        </div>
        <div class="field required">
            <label for="account_currency" class="label">
                <span><?php echo __('Currency') ?></span>
            </label>
            <div class="control">
                <select name="account_currency" id="account_currency">
                    <option value="NZD">New Zealand Dollar
                    </option>
                </select>
            </div>
        </div>
        <div class="field required">
            <label for="account_number" class="label">
                <span><?php echo __('Account Number') ?></span>
            </label>

            <div class="control">
                <input type="text" id="account_number"
                       name="account_number"
                       class="input-text">
            </div>
        </div>
<div class="field required">
            <label for="account_holder_name" class="label">
                <span><?php echo __('Account Holder Name') ?></span>
            </label>

            <div class="control">
                <input type="text" id="account_holder_name"
                       name="account_holder_name"
                       class="input-text">
            </div>
        </div>
        <div class="field required">
            <label for="account_holder_type" class="label">
                <span><?php echo __('Account Holder Type  ') ?></span>
            </label>

            <div class="control">
                <select name="account_holder_type"  id="account_holder_type">
                    <option value="company">Company</option>
                </select>
            </div>
        </div>
<div class="field required">
            <label for="account_email" class="label">
                <span><?php echo __('Account Email') ?></span>
            </label>

            <div class="control">
                <input type="text" id="account_email"
                       name="account_email"
                       class="input-text">
            </div>
        </div>
        <div class="field required">
            <label for="business_name" class="label">
                <span><?php echo __('Business name') ?></span>
            </label>

            <div class="control">
                <input type="text" id="business_name"
                       name="business_name"
                       class="input-text">
            </div>
        </div>
        <div class="field required">
            <label for="support_phone" class="label">
                <span><?php echo __('Support Phone') ?></span>
            </label>

            <div class="control">
                <input type="text" id="support_phone"
                       name="support_phone"
                       class="input-text">
            </div>
        </div>
<div class="field required">
            <label for="support_url" class="label">
                <span><?php echo __('Support Url') ?></span>
            </label>

            <div class="control">
                <input type="text" id="support_url"
                       name="support_url"
                       class="input-text">
            </div>
        </div>
        <div class="field required">
            <label for="account_url" class="label">
                <span><?php echo __('Url') ?></span>
            </label>

            <div class="control">
                <input type="text" id="account_url"
                       name="account_url"
                       class="input-text">
            </div>
        </div>



    </fieldset>

    <div class="actions-toolbar">
        <div class="primary">
            <button type="submit" class="action submit primary" title="<?php echo __('Submit') ?>">
                <span><?php echo __('Submit') ?></span>
            </button>
        </div>
    </div>

</form>

Note: Your form field may vary, depending on which country you are in.

3/ Create a function to create and connect the custom account to the main account:

  • Create new config to save Account ID of your Stripe account, under “app/code/Tigren/StripeConnect/etc/adminhtml/system.xml” with the following content:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="payment">
            <group id="stripecore" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                <field id="client_account_id" translate="label" type="text" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Client Account Id</label>
                    <config_path>payment/stripecore/client_account_id</config_path>
                </field>
                <field id="test_client_account_id" translate="label" type="text" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Test Client Account Id</label>
                    <config_path>payment/stripecore/test_client_account_id</config_path>
                </field>
            </group>
        </section>
    </system>
</config>
  • Go to STORES > Configuration > SALES > Payment Methods > Stripe > Stripe Core, enter Client Account ID (taken from your Stripe account information). The Test Client Account ID is only needed for testing using sandbox.
  • Create “app\code\Tigren\StripeConnect\etc\di.xml” with the following content:
<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Stripeofficial\Core\Helper\Data" type="Tigren\StripeConnect\Helper\Stripe\Data" />
</config>
  • Create new helper under “app/code/Tigren/StripeConnect/Helper/Stripe” name Stripe.php with the following content:
<?php

namespace Tigren\StripeConnect\Helper\Stripe;

use Magento\Store\Model\ScopeInterface;
use \Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\Encryption\EncryptorInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Stripeofficial\Core\Model\Logger;

// class Data extends \Magento\Framework\App\Helper\AbstractHelper
class Data extends \Stripeofficial\Core\Helper\Data
{
    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * @var EncryptorInterface
     */
    protected $encryptor;

    /**
     * @var Logger
     */
    protected $logger;

    /**
     * @var bool|null
     */
    protected $isDebug = null;

    protected $checkoutSession;
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        EncryptorInterface $encryptor,
        Logger $logger,
        CheckoutSession $checkoutSession
    ) {
        parent::__construct($scopeConfig, $encryptor, $logger);
        $this->scopeConfig = $scopeConfig;
        $this->encryptor = $encryptor;
        $this->logger = $logger;
        $this->checkoutSession = $checkoutSession;
    }



    /**
     * Get default statement descriptor;
     *
     * @return string
     */
    public function getStatementDescriptor()
    {
        $result = (string)$this->scopeConfig->getValue('payment/stripecore/statement_descriptor', ScopeInterface::SCOPE_STORE);

        if (empty($result)) {
            return '';
        }

        return $result;
    }

    /**
     * Get the publishable api key
     *
     * @return string
     */
    public function getAPIKey()
    {
        if ($this->getTestMode()) {
            return $this->encryptor->decrypt((string)$this->scopeConfig->getValue('payment/stripecore/test_api_key', \Magento\Store\Model\ScopeInterface::SCOPE_STORE));
        } else {
            return $this->encryptor->decrypt((string)$this->scopeConfig->getValue('payment/stripecore/api_key', \Magento\Store\Model\ScopeInterface::SCOPE_STORE));
        }
    }

    /**
     * Get the secret api key
     *
     * @return string
     */
    public function getAPISecretKey()
    {
        if ($this->getTestMode()) {
            return $this->encryptor->decrypt((string)$this->scopeConfig->getValue('payment/stripecore/test_api_secret_key', \Magento\Store\Model\ScopeInterface::SCOPE_STORE));
        } else {
            return $this->encryptor->decrypt((string)$this->scopeConfig->getValue('payment/stripecore/api_secret_key', \Magento\Store\Model\ScopeInterface::SCOPE_STORE));
        }
    }
    /**
     * @return bool
     */
    public function getTestMode()
    {
        return $this->scopeConfig->isSetFlag('payment/stripecore/test_mode', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    }

    /**
     * @return bool
     */
    public function getDebugMode()
    {
        if ($this->isDebug === null) {
            $this->isDebug = $this->scopeConfig->isSetFlag('payment/stripecore/debug', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        }

        return $this->isDebug;
    }

    /**
     * @return Logger
     */
    public function getLogger()
    {
        return $this->logger;
    }

    /**
     * @return ScopeConfigInterface
     */
    public function getScopeConfig()
    {
        return $this->scopeConfig;
    }
    public function getClientId()
    {
        if ($this->getTestMode()) {
            return (string)$this->scopeConfig->getValue('payment/stripecore/test_client_account_id', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        } else {
            return (string)$this->scopeConfig->getValue('payment/stripecore/client_account_id', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        }
    }
}
  • Create new controller under “app/code/Tigren/StripeConnect/Controller/Stripe” named Createandconnect.php with following content:
<?php

namespace Tigren\StripeConnect\Controller\Stripe;

use Stripe\Stripe;
use Stripe\Account;
use Stripe\Token;

class Createandconnect extends \Magento\Backend\App\Action
{
    public $data;
    protected $session;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Tigren\StripeConnect\Helper\Stripe\Data $data

    )
    {
        $this->data = $data;
        parent::__construct($context);
    }

    public function execute()
    {
        Stripe::setApiKey($this->data->getAPISecretKey());
        $formData = $this->getRequest()->getParams();
            ///create bank token
            $bankToken = Token::create(
                [
                    'bank_account' => [
                        'country' => $formData['account_country'],
                        'currency' => $formData['account_currency'],
                        'account_holder_name' => $formData['account_holder_name'],
                        'account_holder_type' => $formData['account_holder_type'],
                        'account_number' => $formData['account_number']
                    ]
                ]
            );
            if (isset($bankToken['id'])) {
                //create custom account
                $account = Account::create([
                    'country' => $formData['account_country'],
                    'type' => 'custom',
                    'email' => $formData['account_email'],
                    'tos_acceptance' => array(
                        'date' => time(),
                        'ip' => $_SERVER['REMOTE_ADDR']
                    ),
                    "business_type" => "company",
                    "business_profile" => array(
                        "mcc" => null,
                        "name" => $formData['business_name'],
                        "product_description" => 'treatment',
                        "support_email" => $formData['account_email'],
                        "support_phone" => $formData['support_phone'],
                        "support_url" => $formData['support_url'],
                        "url" => $formData['account_url']
                    ),

                ]);
                if (isset($account['id'])) {
                    //creat bank account for custom account

                    $bank_account = Account::createExternalAccount(
                        $account['id'],
                        [
                            'external_account' => $bankToken['id'],
                        ]
                    );
                }
                else {
                    $this->handleError("can't create account");
                }
            }
            else {
                $this->handleError("can't create bank token");
            }
            
            ///////you should save account id and bank account id to  your model
            
            $yourModel->setData('account_id', $account['id']);
            $yourModel->setData('bank_account_id', $bank_account['id']);
            $yourModel->save();
           
            $this->getMessageManager()->addSuccessMessage('your account is now connected');
            $this->_redirect('/');


    }
    public function handleError($message)
    {
        $this->getMessageManager()->addErrorMessage($message);
        $this->_redirect('/');
    }
}
  • Now you can go to BaseUrl/tigren/stripe/account fill out the information, and then the custom account will be created and connected to your main platform

 

Step 3: Check out and transfer money to the custom account (vendor account)

  • In “app\code\Tigren\StripeConnect\etc\di.xml” add new preference:
<preference for="Stripeofficial\Core\Model\Payment" type="Tigren\ StripeConnect \Model\Stripe\Payment" />
  • Create new php file “Tigren\StripeConnect\Model\Stripe\Payment” with the following content:
<?php
namespace Tigren\StripeConnect\Model\Stripe;

use Stripe\Charge as StripeCharge;
use Stripe\Customer;
use Stripe\Error\InvalidRequest;
use Magento\Framework\Exception\LocalizedException;


class Payment extends \Stripeofficial\Core\Model\Payment
{

    public function charge($capture, $token, $amount, $currencyCode, $customerId, $method = null, $metaData = null, $saveSource = null)
    {
        $isCoin = $this->data->checkQuoteIsHealthCoin();
        if($isCoin){
            return parent::charge($capture, $token, $amount, $currencyCode, $customerId, $method, $metaData, $saveSource);
        }
        $statement = $this->data->getStatementDescriptor();
        $this->init();
        $request = [
            "amount" => $amount,
            "currency" => $currencyCode,
            "source" => $token,
            "metadata" => $metaData,
        ];

        if (!empty($customerId)) {
            $request['customer'] = $customerId;
        }

        if (!in_array($method, ['giropay', 'sofort','bancontact','sepa', 'sepa_debit', 'p24','ideal', 'alipay'])) {
            // Add statement_descriptior when payment is not redirect methods
            $request['capture'] = $capture;

            if ($currencyCode == 'jpy') {
                $statement = self::DEFAULT_STATEMENT;
            }

            if (!empty($statement)) {
                $request['statement_descriptor'] = $statement;
            }
        }

        if ($customerId !== null) {
            $source = $this->getSource($token);

            if ($source->usage == 'reusable') {
                $request["customer"] = $customerId;
                $customer = Customer::retrieve($customerId);
                /** @var Collection $collection */
                $collection = $customer->sources;

                try {
                    if ($collection->total_count > 5) {
                        $data = $collection->all();
                        foreach ($data->data as $c) {
                            /** @var StripeSource $c */
                            $c->detach();
                        }
                    }

                    $collection->retrieve($token);
                } catch (InvalidRequest $e) {
                    $customer->sources->create(["source" => $token]);
                }
            }
        }

        if ($this->data->getDebugMode()) {
            $this->logger->info('Make charge request', $request);
        }

        //add transfer_data/destination to request
        $vendorAccountId=$yourModel->getData('account_id');
        if($vendorAccountId!=null && $ vendorAccountId!=false)
        {
            $request['transfer_data']=["destination"=> vendorAccountId];

        }else
        {
            throw new LocalizedException(__('This account not yet connected to platform account'));
        }

        //end
        return StripeCharge::create($request);
    }

}

Now, after checkout the money will be transferred instantly from the platform to vendor account.
 
1 Star2 Stars3 Stars4 Stars5 Stars (10 votes, average: 5.00 out of 5)

Loading...

April LeeHow To Use Stripe Connect With Custom Account (Vendor Account) In Magento 2?

Leave a Reply

Your email address will not be published. Required fields are marked *