<?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: Digvijay singh</title>
    <description>The latest articles on DEV Community by Digvijay singh (@digvijay_singh_aa2f2e168e).</description>
    <link>https://dev.to/digvijay_singh_aa2f2e168e</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3967791%2Fff89926f-e849-4e63-a2c0-2d284b44697a.jpg</url>
      <title>DEV Community: Digvijay singh</title>
      <link>https://dev.to/digvijay_singh_aa2f2e168e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/digvijay_singh_aa2f2e168e"/>
    <language>en</language>
    <item>
      <title>I Built a WooCommerce Payment Gateway for a Government Portal — Here's How AI Made It Possible</title>
      <dc:creator>Digvijay singh</dc:creator>
      <pubDate>Thu, 04 Jun 2026 08:04:01 +0000</pubDate>
      <link>https://dev.to/digvijay_singh_aa2f2e168e/i-built-a-woocommerce-payment-gateway-for-a-government-portal-heres-how-ai-made-it-possible-6ib</link>
      <guid>https://dev.to/digvijay_singh_aa2f2e168e/i-built-a-woocommerce-payment-gateway-for-a-government-portal-heres-how-ai-made-it-possible-6ib</guid>
      <description>&lt;p&gt;&lt;strong&gt;Intro&lt;/strong&gt;&lt;br&gt;
Most WooCommerce payment gateway tutorials use Stripe or Razorpay — well-documented, with SDKs and community support everywhere. My project was different. I had to build a custom gateway for a  government portal — sparse documentation, non-standard callback behavior, and zero Stack Overflow answers.&lt;/p&gt;

&lt;p&gt;What got me through it was a combination of 4+ years of PHP/WordPress experience and two AI tools: Claude and ChatGPT. In this article I'll walk you through exactly what I built, where AI genuinely helped, and where it failed me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;br&gt;
The client needed to accept payments via PSU's government payment infrastructure — think portal callbacks, strict server-side verification, and an API that behaved nothing like a modern payment SDK. WooCommerce has no official support for this. There was no existing plugin. I had to build from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The requirements were:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redirect customer to PSU payment portal on checkout&lt;/li&gt;
&lt;li&gt;Handle payment callback (success/failure) from PSU's server&lt;/li&gt;
&lt;li&gt;Verify the transaction server-side before updating order status&lt;/li&gt;
&lt;li&gt;Send email confirmations&lt;/li&gt;
&lt;li&gt;Admin configuration panel for API credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How I used AI — and how I didn't&lt;/strong&gt;&lt;br&gt;
I used both Claude and ChatGPT throughout this project. Here's the honest breakdown:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boilerplate &amp;amp; architecture&lt;/strong&gt;&lt;br&gt;
I asked Claude to scaffold the WooCommerce payment gateway class structure. It gave me a clean starting point with WC_Payment_Gateway extended correctly — something that would have taken me 30 minutes to piece together from docs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging PHP logic&lt;/strong&gt;&lt;br&gt;
Whenever I hit a logic error — wrong hook priority, order status not updating — I pasted the relevant function into ChatGPT. It caught a missing wc_reduce_stock_levels() call I'd overlooked for 2 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where AI failed: payment callbacks&lt;/strong&gt;&lt;br&gt;
This is where I had to rely on my own experience. BSNL's callback didn't follow standard patterns. Neither AI tool had seen this API before. They gave me generic answers. I had to read the portal's PDF documentation line by line, test with live transactions, and debug raw POST data myself. AI got me 60% there. The last 40% was pure engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;code snippet -&lt;br&gt;
The callback handler&lt;/strong&gt;&lt;br&gt;
Here's a simplified version of the payment callback logic. The key insight: always verify the transaction server-side before trusting the callback data.&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;payment_callback&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_id&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sanitize_text_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'order_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$txn_id&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sanitize_text_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'txn_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$status&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sanitize_text_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&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="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$order_id&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$txn_id&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="nf"&gt;wp_die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Invalid callback data'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Always verify server-side — never trust callback alone&lt;/span&gt;
    &lt;span class="nv"&gt;$verified&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="nf"&gt;verify_transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$txn_id&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="nf"&gt;wc_get_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$order_id&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;$verified&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'SUCCESS'&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;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;payment_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$txn_id&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;add_order_note&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Payment verified via BSNL. TXN: '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$txn_id&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;update_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'failed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Payment verification failed.'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;wp_redirect&lt;/span&gt;&lt;span class="p"&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="nf"&gt;get_return_url&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="k"&gt;exit&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;blockquote&gt;
&lt;p&gt;The verify_transaction() method makes a separate server-to-server API call to BSNL to confirm the payment — this is the critical step most tutorials skip.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What I learned&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI tools are excellent for scaffolding and boilerplate — use them aggressively for that&lt;/li&gt;
&lt;li&gt;For undocumented or niche APIs, AI hallucinates. Always verify against official docs&lt;/li&gt;
&lt;li&gt;Always verify payments server-side. Never trust client-side or callback data alone&lt;/li&gt;
&lt;li&gt;Government portals often have quirky behavior — log everything during development&lt;/li&gt;
&lt;li&gt;Claude was better at architecture decisions. ChatGPT was faster at quick debugging snippets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Outro&lt;/strong&gt;&lt;br&gt;
This was one of the more challenging plugins I've shipped — not because the code was complex, but because the external system was unpredictable. AI compressed my development time significantly, but the real work was still mine: reading the docs, testing edge cases, and understanding WooCommerce's order lifecycle deeply enough to plug everything together.&lt;/p&gt;

&lt;p&gt;If you're building a custom payment gateway — government portal or otherwise — happy to answer questions in the comments.&lt;/p&gt;




&lt;p&gt;GitHub: &lt;a href="https://dev.togithub"&gt;github.com/singhdigvijay99&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://dev.togithub"&gt;singhdigvijay99.github.io/portfolio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
