<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: P2Flux</title>
    <description>The latest articles on DEV Community by P2Flux (@p2flux).</description>
    <link>https://dev.to/p2flux</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4115450%2F616f1572-b977-408a-a4b8-cf842608d862.jpg</url>
      <title>DEV Community: P2Flux</title>
      <link>https://dev.to/p2flux</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/p2flux"/>
    <language>en</language>
    <item>
      <title>Accept USDC payments in Laravel without requiring buyers to hold ETH</title>
      <dc:creator>P2Flux</dc:creator>
      <pubDate>Tue, 08 Sep 2026 10:06:34 +0000</pubDate>
      <link>https://dev.to/p2flux/accept-usdc-payments-in-laravel-without-requiring-buyers-to-hold-eth-15l3</link>
      <guid>https://dev.to/p2flux/accept-usdc-payments-in-laravel-without-requiring-buyers-to-hold-eth-15l3</guid>
      <description>&lt;h1&gt;
  
  
  Accept USDC payments in Laravel without requiring buyers to hold ETH
&lt;/h1&gt;

&lt;p&gt;Accepting USDC sounds simple until the customer has enough USDC to pay you, but no ETH in the wallet for the network fee.&lt;/p&gt;

&lt;p&gt;Then a payment flow starts looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer has USDC
→ customer clicks Pay
→ wallet requires ETH for gas
→ customer first has to acquire ETH
→ then come back and try again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For someone who just wants to make a payment, that is a lot of blockchain knowledge.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll use &lt;strong&gt;P2Flux for Laravel&lt;/strong&gt; to create a USDC payment on Base where the buyer can also pay the network cost in USDC.&lt;/p&gt;

&lt;p&gt;The Laravel application will still verify the transaction server-side before marking an order as paid.&lt;/p&gt;

&lt;p&gt;P2Flux is non-custodial: the merchant payment settles directly to the merchant wallet rather than sitting in a P2Flux balance waiting to be withdrawn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the Laravel package
&lt;/h2&gt;

&lt;p&gt;P2Flux has an official integration for Laravel 12 and 13.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require p2flux/laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Laravel discovers the package automatically, so there is no service provider to register manually.&lt;/p&gt;

&lt;p&gt;You also don't need a P2Flux API key.&lt;/p&gt;

&lt;p&gt;If you want to publish the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan vendor:publish &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;p2flux-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default configuration points to the production P2Flux API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'api_url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'P2FLUX_API_URL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://api.p2flux.com'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'timeout'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'P2FLUX_TIMEOUT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package intentionally stays small.&lt;/p&gt;

&lt;p&gt;Installing it does &lt;strong&gt;not&lt;/strong&gt; add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;payment tables&lt;/li&gt;
&lt;li&gt;migrations&lt;/li&gt;
&lt;li&gt;routes&lt;/li&gt;
&lt;li&gt;controllers&lt;/li&gt;
&lt;li&gt;scheduled jobs&lt;/li&gt;
&lt;li&gt;queue workers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your Laravel application remains responsible for its own orders, subscriptions and business logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inject P2Flux into your controller
&lt;/h2&gt;

&lt;p&gt;The recommended approach is normal Laravel dependency injection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;P2Flux\P2FluxClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;P2FluxClient&lt;/span&gt; &lt;span class="nv"&gt;$p2flux&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Laravel package registers &lt;code&gt;P2FluxClient&lt;/code&gt; as a singleton.&lt;/p&gt;

&lt;p&gt;There is also an optional facade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;P2Flux\Laravel\Facades\P2Flux&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;P2Flux&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prefer constructor injection because it makes the dependency explicit and is easier to replace in tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check whether sponsored payments are supported
&lt;/h2&gt;

&lt;p&gt;Before relying on payment-token sponsorship, check the capabilities exposed by P2Flux.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;p2flux&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Base, P2Flux can support a payment mode where the network cost is paid using USDC instead of requiring the buyer to separately hold ETH.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal USDC payment

buyer pays USDC
+
buyer needs ETH for network gas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With payment-token sponsorship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;buyer pays USDC
+
network cost is paid in USDC
+
P2Flux relayer supplies the required Base ETH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;not a gas-free transaction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The blockchain still has a network cost.&lt;/p&gt;

&lt;p&gt;The difference is that the buyer does not need to acquire and hold another asset just to pay it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the payment from your Laravel backend
&lt;/h2&gt;

&lt;p&gt;Payment creation should happen on your backend, next to the order the payment belongs to.&lt;/p&gt;

&lt;p&gt;A typical application flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /checkout
→ create merchant order
→ create P2Flux payment
→ store the P2Flux reference against the order
→ return/open hosted checkout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the sponsored flow, the payment uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gas_payment_mode = payment_token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The official Laravel package contains a complete controller for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;examples/Http/Controllers/CreateSponsoredPaymentController.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important Laravel pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;P2Flux\P2FluxClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateSponsoredPaymentController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;P2FluxClient&lt;/span&gt; &lt;span class="nv"&gt;$p2flux&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;p2flux&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// 1. Check that payment-token sponsorship is available&lt;/span&gt;
        &lt;span class="c1"&gt;//    for the network/token you intend to use.&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Create the P2Flux payment for your order&lt;/span&gt;
        &lt;span class="c1"&gt;//    using payment_token sponsorship.&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Store the P2Flux intent/reference&lt;/span&gt;
        &lt;span class="c1"&gt;//    against your own Order model.&lt;/span&gt;

        &lt;span class="c1"&gt;// 4. Return the hosted checkout URL to the browser.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend copying the current working controller from the official repository rather than copying payment-field definitions from an article.&lt;/p&gt;

&lt;p&gt;The repository examples are tested together with the package and stay aligned with the PHP SDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens in the browser?
&lt;/h2&gt;

&lt;p&gt;The buyer opens the P2Flux hosted checkout and completes the wallet interaction there.&lt;/p&gt;

&lt;p&gt;When checkout appears to finish, the browser receives a completion message.&lt;/p&gt;

&lt;p&gt;The flow looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laravel backend
→ P2Flux hosted checkout
→ buyer signs/pays
→ checkout reports completion
→ browser sends that claim back to Laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there is an important rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not mark an order as paid because the browser said the checkout completed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser message is only a claim.&lt;/p&gt;

&lt;p&gt;Do not do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p2flux.payment.completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;markOrderAsPaid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;browser reports completion
→ Laravel receives transaction/payment information
→ Laravel verifies it with P2Flux
→ Laravel marks the order paid only after verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verify the payment on the server
&lt;/h2&gt;

&lt;p&gt;Your Laravel backend should be the authority that changes the order state.&lt;/p&gt;

&lt;p&gt;A simplified controller looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\Order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Illuminate\Support\Facades\DB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;P2Flux\P2FluxClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VerifyPaymentController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;P2FluxClient&lt;/span&gt; &lt;span class="nv"&gt;$p2flux&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Order&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;lockForUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;firstOrFail&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paid_at&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                    &lt;span class="s1"&gt;'paid'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;]);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="cm"&gt;/*
             * Call P2Flux verification here using the
             * payment data/reference stored for this order.
             *
             * Only after P2Flux returns an authoritative
             * valid result should the order become paid.
             */&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                &lt;span class="s1"&gt;'paid'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paid_at&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The official package includes the full implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;examples/Http/Controllers/VerifyPaymentController.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That example also covers recovery and repeat-safe order updates.&lt;/p&gt;

&lt;p&gt;The important principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Browser result = claim. Server verification = truth.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Make payment fulfilment idempotent
&lt;/h2&gt;

&lt;p&gt;Verification may happen more than once.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;buyer completes checkout
→ browser sends result
→ browser retries
→ customer refreshes
→ background recovery sees the same payment later
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application should safely reach the same final state every time.&lt;/p&gt;

&lt;p&gt;That is why the example uses a database transaction and row lock.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paid_at&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Verify through P2Flux.&lt;/span&gt;

&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paid_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a real application, you will probably also persist things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your order reference
P2Flux payment reference
transaction hash
settlement information
payment timestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;according to your own accounting requirements.&lt;/p&gt;

&lt;p&gt;P2Flux does not try to replace your application's order database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if the request times out?
&lt;/h2&gt;

&lt;p&gt;Payments have another interesting backend problem.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laravel sends an operation
→ blockchain transaction is submitted
→ HTTP connection disappears
→ Laravel never receives the response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dangerous response would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Didn't get a response. Just send it again."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a money-moving operation, that can create duplicate behavior.&lt;/p&gt;

&lt;p&gt;P2Flux therefore has recovery operations.&lt;/p&gt;

&lt;p&gt;The Laravel examples include patterns around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;recoverPayment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;recoverCharge&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The safer pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request result is ambiguous
→ recover the existing operation
→ determine what already happened
→ only then decide whether another action is required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes especially important for recurring payments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the buyer need?
&lt;/h2&gt;

&lt;p&gt;For a sponsored USDC payment on Base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Buyer needs:

USDC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They do not need to separately hold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ETH just for the network fee
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And they do not need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a P2Flux account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;P2Flux's relayer supplies the ETH required for the sponsored transaction.&lt;/p&gt;

&lt;p&gt;The corresponding network cost is paid in USDC.&lt;/p&gt;

&lt;p&gt;The merchant payment itself remains direct wallet-to-wallet settlement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recurring USDC payments
&lt;/h2&gt;

&lt;p&gt;P2Flux also supports recurring payments.&lt;/p&gt;

&lt;p&gt;The Laravel package deliberately does not install its own scheduler.&lt;/p&gt;

&lt;p&gt;Your Laravel application decides when a subscription should be charged.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laravel scheduler
→ find subscriptions due for collection
→ call P2Flux charge()
→ record the result
→ recover ambiguous results when necessary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package includes an application-level Artisan command showing this pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;examples/Console/ChargeDueSubscriptions.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also a recovery command for pending payments.&lt;/p&gt;

&lt;p&gt;This keeps responsibilities clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laravel application:
billing schedule
customer/order state
business rules

P2Flux:
payment execution
verification
recovery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cancellation and allowance restoration
&lt;/h2&gt;

&lt;p&gt;The Laravel repository also contains examples for subscription lifecycle operations.&lt;/p&gt;

&lt;p&gt;These include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CancelSubscriptionController
RestoreAllowanceController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, these are application examples.&lt;/p&gt;

&lt;p&gt;Installing &lt;code&gt;p2flux/laravel&lt;/code&gt; does not automatically register controllers or routes in your project.&lt;/p&gt;

&lt;p&gt;You copy/adapt only the pieces your application needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refunds
&lt;/h2&gt;

&lt;p&gt;Refund handling is another place where repeat safety matters.&lt;/p&gt;

&lt;p&gt;The package contains a &lt;code&gt;RefundController&lt;/code&gt; example that demonstrates the application-side pattern while protecting against duplicate or stranded refund operations.&lt;/p&gt;

&lt;p&gt;The Laravel integration itself does not create a refund database or change your application models.&lt;/p&gt;

&lt;p&gt;Your application remains responsible for recording the relationship between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;order
original payment
refund state
refund transaction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test your integration without spending crypto
&lt;/h2&gt;

&lt;p&gt;You should not need a real wallet or Mainnet transaction to test application logic.&lt;/p&gt;

&lt;p&gt;The underlying P2Flux PHP SDK supports an injectable transport.&lt;/p&gt;

&lt;p&gt;That means your Laravel tests can replace the normal client with a client using a fake transport and simulate responses such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;payment valid
payment confirming
payment rejected
network failure
rate limit
recovery success
recovery unavailable
recurring collection
already charged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The general Laravel pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;P2FluxClient&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$fakeClient&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then test what &lt;strong&gt;your application&lt;/strong&gt; does with each payment result.&lt;/p&gt;

&lt;p&gt;No USDC or ETH needs to move.&lt;/p&gt;

&lt;p&gt;The official Laravel package itself uses this approach extensively in its automated test suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel production configuration
&lt;/h2&gt;

&lt;p&gt;The package supports Laravel's normal production optimization flow.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan config:cache
php artisan optimize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;P2Flux configuration continues to resolve correctly after config caching.&lt;/p&gt;

&lt;p&gt;You can also see the active package configuration using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan about
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The P2Flux section reports non-secret operational information such as the API URL, timeout and installed PHP SDK version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install it
&lt;/h2&gt;

&lt;p&gt;To add P2Flux to a Laravel 12 or Laravel 13 application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require p2flux/laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The official PHP SDK is installed automatically as a dependency.&lt;/p&gt;

&lt;p&gt;P2Flux is live on Base Mainnet and currently supports workflows including:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one-time USDC payments
recurring payments
hosted checkout
server-side verification
payment recovery
refunds
subscription cancellation
allowance restoration
network fees paid in USDC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Laravel package is intentionally only the Laravel integration layer.&lt;/p&gt;

&lt;p&gt;The underlying payment behavior stays in the official P2Flux PHP SDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Laravel package on Packagist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://packagist.org/packages/p2flux/laravel" rel="noopener noreferrer"&gt;https://packagist.org/packages/p2flux/laravel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel package source, documentation and examples&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/P2Flux/laravel" rel="noopener noreferrer"&gt;https://github.com/P2Flux/laravel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Official PHP SDK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/P2Flux/sdk-php" rel="noopener noreferrer"&gt;https://github.com/P2Flux/sdk-php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P2Flux documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://p2flux.com/docs/" rel="noopener noreferrer"&gt;https://p2flux.com/docs/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P2Flux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://p2flux.com" rel="noopener noreferrer"&gt;https://p2flux.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Laravel integration is new, so feedback from developers working on real Laravel payment flows is very welcome.&lt;/p&gt;

</description>
      <category>article</category>
      <category>laravel</category>
      <category>php</category>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
