title: How to successfully complete an in app purchase using flutter on android?
body: <h2>What I want</h2>
  <p>I want to integrate Google Play in app purchases into my flutter app, the product I want to sell is a consumable. Right now I am using the <code>in_app_purchase: (0.3.4+16)</code> package.</p>
  <h2>What I did</h2>
  <ul>
  <li>Create the product in the google play developer console</li>
  <li>Set up the project according to the documentation of the in_app_purchase package</li>
  <li>Implemented some logic to buy a consumable item (see below)</li>
  <li>Built an alpha release and uploaded it to the alpha test track in order to test it</li>
  <li>Created a new google account on my developer phone, registered it as tester and downloaded the alpha version</li>
  <li>Purchased with a &quot;test card, always approves&quot;</li>
  <li>Purchased with my PayPal account</li>
  </ul>
  <h2>Expected and actual result</h2>
  <p>I expect the payment to work and all api calls to return ok.</p>
  <p>When I initiate a purchase on my phone the purchase flow starts and I can select the desired payment method. After I accept the payment the <code>_listenToPurchaseUpdated(...)</code> method is called, as expected.
  However, the call to <code>InAppPurchaseConnection.instance.completePurchase(p)</code> returns a <code>BillingResponse.developerError</code> and I get the following debug messages:</p>
  <pre><code>W/BillingHelper: Couldn't find purchase lists, trying to find single data.
  I/flutter: result: BillingResponse.developerError (Purchase is in an invalid state.)
  </code></pre>
  <p>This error comes with the &quot;test card, always approves&quot; and also when I start a real transaction using PayPal. For the PayPal purchase I got a confirmation Email, that the transaction was successful.
  In the documentation it says:</p>
  <blockquote>
  <p>Warning! Failure to call this method and get a successful response within 3 days of the purchase will result a refund on Android.</p>
  </blockquote>
  <h2>Summarized question</h2>
  <p>How can I get the call to <code>InAppPurchaseConnection.instance.completePurchase(p)</code> to return a successful result?</p>
  <h2>The purchase implementation</h2>
  <p>The code to setup in app purchases is implemented as shown in the documentation:</p>
  <pre class="lang-dart prettyprint-override"><code>InAppPurchaseConnection.enablePendingPurchases();
  
  Stream&lt;List&lt;PurchaseDetails&gt;&gt; purchaseUpdated = InAppPurchaseConnection.instance.purchaseUpdatedStream;
  
  _subscription = purchaseUpdated.listen(_listenToPurchaseUpdated, onDone: () {
      _subscription.cancel();
  }, onError: (error) {
    // handle error here.
  });
  
  ...
  
  Future&lt;void&gt; _listenToPurchaseUpdated(List&lt;PurchaseDetails&gt; purchaseDetailsList) async {
    for (var p in purchaseDetailsList) {
     
      // Code to validate the payment
  
      if (!p.pendingCompletePurchase) continue;
  
      var result = await InAppPurchaseConnection.instance.completePurchase(p);
  
      if (result.responseCode != BillingResponse.ok) {
        print(&quot;result: ${result.responseCode} (${result.debugMessage})&quot;);
      }
    }
  }
  </code></pre>
  <p>To buy a consumable I have this method which queries the product details and calls <code>buyConsumable(...)</code></p>
  <pre class="lang-dart prettyprint-override"><code>Future&lt;bool&gt; _buyConsumableById(String id) async {
    final ProductDetailsResponse response = await InAppPurchaseConnection
        .instance
        .queryProductDetails([id].toSet());
  
    if (response.notFoundIDs.isNotEmpty || response.productDetails.isEmpty) {
      return false;
    }
  
    List&lt;ProductDetails&gt; productDetails = response.productDetails;
  
    final PurchaseParam purchaseParam = PurchaseParam(
      productDetails: productDetails[0],
    );
  
    return await InAppPurchaseConnection.instance.buyConsumable(
      purchaseParam: purchaseParam,
    );
  }
  </code></pre>