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 a 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.
Contents
Step 1: Stripe connect 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).

- 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 front name = tigren
2/ Make 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 a 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/Stripe Connect/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 the 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\Stripe Connect\etc\di.xml” add new preference:
<preference for="Stripeofficial\Core\Model\Payment" type="Tigren\ StripeConnect \Model\Stripe\Payment" />
- Create new php file “Tigren\Stripe Connect\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 the vendor account.
[ratings]