title: How to implement Stripe ACH with PLAID in PHP
body: <p>Step 1: First Connect with PLAID with Stripe and using public key receive public_token and account_id </p>
  
  <pre><code>&lt;script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"&gt;&lt;/script&gt;
  
   &lt;script&gt;
   var linkHandler = Plaid.create({
      clientName: 'Scholastic Expeditions',
      countryCodes: ['US'],
      env: 'sandbox',
      // Replace with your public_key from the Dashboard
      key: '071e075d1d6a109d6g2adb12c426c08',
      product: ['auth'],
      // Optional, use webhooks to get transaction and error updates
      webhook: 'http://test.code.org',
      // Optional, specify a language to localize Link
      language: 'en',
      onLoad: function() {
        // Optional, called when Link loads
      },
      onSuccess: function(public_token, metadata) {
          //account_id = metadata.account_id
          account_id = metadata.accounts[0].id
          sendBackendServer(public_token,account_id);
      },
      onExit: function(err, metadata) {
          // The user exited the Link flow.
          if (err != null) {
              // The user encountered a Plaid API error prior to exiting.
          }
      }
  });
  document.getElementById('linkButton').onclick = function() {
     linkHandler.open();
  };
  &lt;/script&gt;
  </code></pre>
  
  <p>Step 2: On Serverside receive access_token and stripe_token using curl</p>
  
  <pre><code>$plaid_client_id = '5d82ff239085b9001306139c';
  $public_token = $_REQUEST['public_token'];
  $plaid_secret = '565228fd7511c2d1ea2d1bc46eab15';
  $env = 'sandbox';
  $account_id = $_REQUEST['account_id'];
  
  
  $headers[] = 'Content-Type: application/json';
  
  $params = array(
      "client_id" =&gt; $plaid_client_id,
      "secret" =&gt; $plaid_secret,
      "public_token" =&gt; $public_token
  );
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://" . $env . ".plaid.com/item/public_token/exchange");
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  curl_setopt($ch, CURLOPT_TIMEOUT, 80);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  
  if(!$result = curl_exec($ch)) {
      trigger_error(curl_error($ch));
  }
  curl_close($ch);
  
  $jsonParsed = json_decode($result);
  
  $btok_params = array(
      'client_id'    =&gt; $plaid_client_id,
      'secret'       =&gt; $plaid_secret,
      'access_token' =&gt; $jsonParsed-&gt;access_token,
      'account_id'   =&gt; $account_id
   );
  
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://" . $env . ".plaid.com/processor/stripe/bank_account_token/create");
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($btok_params));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  curl_setopt($ch, CURLOPT_TIMEOUT, 80);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  
  if(!$result = curl_exec($ch)) {
      trigger_error(curl_error($ch));
  }
  curl_close($ch);
  
  $btoken = json_decode($result);
  
  $stripe_bank_account_token = $btoken-&gt;stripe_bank_account_token;
  </code></pre>
  
  <p>Step 3 : using stripe_bank_account_token charge amount</p>
  
  <pre><code>$charge = Stripe_Charge::create(array(       
      "amount" =&gt; $totalPayAmount,
      "currency" =&gt; 'USD',
      "source" =&gt; $tokenID,
      "description" =&gt; 'test_account')              
  );
  </code></pre>
  
  <p>My Question are:
  1. On production may be bank verification and charge takes time so How can we handle it at our end.
  2. How can I automatically re-charge amount automatically from user account</p>