DEV Community

Victor Ayomipo
Victor Ayomipo

Posted on

I Monetized My VS Code Extension: Building a Payment Workflow Agent with Creem CLI

Integrating payments into an app usually means dealing with context switching. You write some code for the payment system. You open the browser. Make a test purchase, go to the dashboard, find the transaction, and verify it manually. Then you go back to the editor. Then something else breaks. Back to the browser. Rinse and repeat.

It's exhausting.

So what if you never had to leave the terminal? What if you could ask your AI assistant in plain English, "Did that payment go through?" and it would just... check?

That's what I built. And this is how I did it.

What We're Building

I have a VS Code extension called SnippetFuse, a smart AI context packaging tool that helps developers structure their code and context before sending it to AI assistants like Claude or ChatGPT. It's free, open source, and has active users.

VS Code Marketplace page for SnippetFuse

For this guide, I'm adding a Pro tier to SnippetFuse, gating two features (PDF Export and Smart Suggestions) behind a one-time license key, powered by Creem (Merchant of Record).

The main tools for this monetization demonstration would be the Creem CLI and Cline AI Agent, which are all free for what we want to do.

The whole thing is live on a feat/snippetfuse-pro branch on GitHub. You can check it out to follow along easily. Let's begin.

Step 1: Let the AI Set Up the CLI For You

First thing I did was open Cline and paste this single prompt:

Read https://creem.io/SKILL.md and set up the Creem CLI for me
Enter fullscreen mode Exit fullscreen mode

Thankfully, Creem built their entire documentation to be AI-readable, giving any AI assistant everything it needs to understand Creem, the CLI, and how to work with both.

So Cline fetched the SKILL.md file, understood the setup steps, and asked me some questions:

  1. Do you already have a Creem account?

  2. Do you prefer Homebrew or npm?

I like to use Cline Plan mode first as it saves me a lot of headache down the line.

I answered both, switched to Act Mode, and watched Cline install the CLI, run creem --version to verify (successful), and then check the authentication with creem whoami which returned ⚠ Not logged in.

It is always recommended to never share your API key with any service, tool, or agent. So I had to step in to handle the login myself:

creem login
# Enter your API key from the Creem dashboard
Enter fullscreen mode Exit fullscreen mode

I pasted my test API key (creem_test_6xI1...), Creem validated it, and now, the CLI is authenticated and ready.

Terminal showing Creem Authenticated Info

Step 2: Create the Product

To monetize SnippetFuse, I needed to sell a License Key.

To do this, I initially asked Cline to create a product with the license key feature using the Creem CLI, but I discovered that you can't enable add-ons like "License Keys" via the Creem CLI. Those specific features require the dashboard.

However, for subscription-type products, those can be created entirely using the Creem CLI.

So, I quickly accessed the Creem dashboard, created the "SnippetFuse Pro" product, set the pricing at $15, billing type one-time with the License Key feature enabled, and got the payment link.

Now, I asked Cline to use the Creem CLI to verify if a "SnippetFuse Pro" product exists. It ran the command creem products list --json

Terminal showing the SnippetFuse Pro product JSON

And, Cline got back to me: "SnippetFuse Pro, $15.00 USD, one-time purchase, status: active."

Just like that, I got everything I need to know about my product (price, billing type, product URL, product ID) without touching the browser.

So let's take it a step further, I asked Cline: "Create a checkout URL for the SnippetFuse Pro product."

And it ran:

creem checkouts create --product prod_1ZRv7tBMqhXAMrfMXBUAgK --json
Enter fullscreen mode Exit fullscreen mode

The CLI returned a live checkout session object with a checkoutUrl which can be forwarded to a user, and when opened, directs to the SnippetFuse Pro checkout page.

Terminal showing Checkout Session JSON with checkoutUrl

You should know that the CLI generates checkout sessions, which are single-use (not a reusable payment link). Once a payment is made, that session URL is permanently marked. So generally, for a permanent "Buy" button in your UI, you can either use server-side helpers for creating checkout sessions or use the product's payment link from the dashboard's share button.

But in this case, if I needed to test again, I'd just tell Cline to "Generate a fresh checkout session."

Step 3: Build a Creem MCP Server

I know even the name looks complicated and perhaps... overwhelming. Trust me, it's not.

MCP Server means Model Context Protocol Server.

A simple way to think of it is that an MCP server is a menu of tools that you give your AI assistant. Each tool is a thing it can call, like a function. Once Cline has access to an MCP server, it can invoke those tools, chain them together autonomously, in context, without you having to copy-paste commands.

Basically, we're gonna be using a custom MCP Server to plug the Creem CLI into Cline's brain.

Let's build one.

I gave Cline the official Cline MCP development docs, the Creem SKILL.md, and the full Creem API documentation, then told it:

Build a MCP server that wraps the Creem CLI as callable tools.
Create it in a folder called `creem-mcp` for this project.

The server should expose the necessary creem CLI tools for :
- products
- customers
- subscriptions
- checkouts
- transactions
- configurations
- whoami / switch_mode
- and other relevant ones
---
Follow how it is done in the official cline MCP docs provided.
[paste cline mcp docs here]
---
Each tool executes the CLI command, parses the JSON output, and returns it.
Include error handling — if CLI returns an error, return it as a tool error.
Enter fullscreen mode Exit fullscreen mode

Cline built the whole thing: ~18 tools, TypeScript, proper error handling, timeouts, and handles CLI output to JSON. It even generated a README with the exact config to add to Cline's MCP settings.

Creem MCP Server in CLine UI

Next was to click the "Configure MCP Servers" in Cline, open the config, and add:

{
  "mcpServers": {
    "creem-mcp": {
      "command": "node",
      "args": ["/path/to/snippetfuse/creem-mcp/build/index.js"],
      "disabled": false
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

So instead of Cline trying to remember terminal commands, it now has 18 dedicated tools like list_transactions etc., and under the hood, these tools run the Creem CLI (e.g., creem transactions list --json), parse the output, and return it to the AI.

Now, let's test it out. I opened a fresh Cline chat and asked: "How many sales did I make today?"

And instead of me running any commands, Cline called list_transactions through the MCP server and responded:

📊 Today's Sales (March 23, 2026)
You made 4 sales today totaling $63.00 USD!

07:53 AM — bola t (NC) — $15.00 ✅ Paid
07:37 AM — Customer (NG) — $15.00 ✅ Paid
06:48 AM — holly g (NL) — $18.15 ✅ Paid (incl. VAT)
05:49 AM — gd sss (NG) — $15.00 ✅ Paid
Enter fullscreen mode Exit fullscreen mode

MCP response of Summary of Today's Sales

And just like that, I didn't write a single command. We've set up an AI coding assistant to use the Creem CLI as a native tool. Just natural language.

Test the Checkout and Verify With the CLI

The license integration in SnippetFuse is already built with an activation modal, VS Code globalState, and calls to the Creem License API. But does it actually work?

Let's find out.

I opened the extension in dev mode, clicked Smart Suggestions (a Pro feature), and the Pro modal appeared. Clicked "Get License Key".

SnippetFuse Pro Modal

The checkout page opened in the browser, and I completed a test purchase; it was successful with an order confirmation page.

Then I proceeded to use the CLI to verify the transaction. I asked Cline, "Check the latest transaction in my Creem store and tell me what you see."

Cline called list_transactions via the MCP server and reported back:

A successful $15.00 USD one-time payment, status: paid. Customer ID: cust_7cJFr...

Transaction Report from the Creem MCP Server

Which means the CLI has verified that the transaction registered and the payment is confirmed. We built, made a test purchase, verified it with the CLI, and confirmed the purchase.

Debug the Webhook by Querying Transactions

Unfortunately, I was met with an unexpected bug on my local server.

SnippetFuse, by nature, has no server as it is a local VSCode extension; however, I wanted to send users a personalized Welcome Email with the license key. And to do this, I need a server with a webhook listener.

So to test things out, I already built a local Express server (server/index.ts) which listens for Creem events, verifies the HMAC signature, and processes checkout.completed.

The server goes live by using Ngrok (which exposes a local port by creating a temporary public URL):

cd server && npm run dev      # start webhook server on port 3000
ngrok http 3000               # expose it to the internet
Enter fullscreen mode Exit fullscreen mode

The ngrok URL goes in the Creem config as a webhook endpoint. HMAC signature verification needs CREEM_WEBHOOK_SECRET, which is wired into the server.

Now, remember the test purchase we made earlier, and I mentioned I met a bug; well, the server crashed:

✅ Webhook received: checkout.completed
TypeError: Cannot read properties of undefined (reading 'customer')
Enter fullscreen mode Exit fullscreen mode

Now, I'm thinking, did Creem send bad data? Or is my code broken?

But since I had the Creem CLI right in the terminal, I just fed the error to Cline and told it: "My webhook server threw an error after I completed a test purchase. Check it out and fix."

And Cline did something smart, it fetched the actual Creem webhook docs:

curl -s "https://docs.creem.io/llms-full.txt" | grep -A 50 "checkout.completed"
Enter fullscreen mode Exit fullscreen mode

And found that the issue was that my webhook handler was accessing event.data.customer, but the actual Creem payload structure uses event.object.customer. My server was accessing the wrong key.

Creem Webhook correct payload structure

Cline fixed it, I restarted the server, made another test purchase, and:

🚀 SnippetFuse webhook server running on port 3000
✅ Webhook received: checkout.completed [Event ID: evt_3mpvXy...]
Customer: fast@example.com
Order ID: ord_5JXnKQ...
🎉 License purchased!
Product: SnippetFuse Pro
License Key: 1HK4A-HHF5F-JVMAL-JQ8OM-4V0I1
Enter fullscreen mode Exit fullscreen mode

Now that I have the License Key, I pasted it into the activation input in SnippetFuse, clicked Activate, and got a VS Code notification: "SnippetFuse Pro activated successfully!"


Another classic issue is what if the server had been down during a purchase?

To simulate this, I killed the server with Ctrl+C, made another test purchase, then asked Cline: "My webhook server was down for a few minutes. What transactions came in that I might have missed?"

Using the Creem CLI through the MCP, Cline called list_transactions, scanned by timestamp, and found the missed transaction:

New Transaction During Downtime:
Customer: Ragnar Floki (rest@gtub.com) — Norway 🇳🇴
Amount: $15.00 USD
Status: ✅ Paid
Timestamp: March 23, 2026 at 3:21 PM
---
This transaction came through approximately 2 minutes ago and likely missed your webhook since the server was down.
Enter fullscreen mode Exit fullscreen mode

So even if webhook deliveries fail or servers are down, I can still query and audit exactly what happened using the CLI.

Manage Your Entire Store From the Terminal

Now that the payment integration is completed and works as expected. I realized that I can talk to the Creem CLI in natural language through Cline (via MCP server).

Here are some scenarios that I tested.

I simulated a customer support ticket for a user who emailed saying they've lost access to their license key.

Instead of opening the dashboard, I asked Cline:

Me: "Can you look up the customer with email jenny.rosen@example.com and tell me their purchase history?"

Cline: "Customer found. ID: cust_1phXGDO.... They have made 2 successful one-time purchases with a total value of $20.00 USD. No active or past subscriptions were found."

Now that I have verified that the user is real, I can just tell my AI Agent to generate a billing portal link for them, and I send the link to them. Ticket Solved.

Another scenario is the store health check.

Me: "Give me a summary of the current state of my SnippetFuse Pro store. How many transactions, how many customers do we have, any payment issues, what products are active?"

Cline called whoami, list_products, list_transactions, list_customers, and list_subscriptions, then synthesized everything.

Cline: "10 transactions. $118.15 total revenue. 9 unique customers across 8 countries. 100% payment success rate. 0 subscriptions (one-time product). ✅ No payment issues."

Creem Store Health Summary via MCP Server

That's Cline, an AI agent acting as a store analytics tool, powered entirely by the Creem CLI under the hood.

Conclusion

I think that, even though I could have used the CLI by typing commands, it doesn't beat the convenience of using an AI agent like Cline, Claude, or Cursor, which makes it more efficient and easier to work with.

I built a paywall, tested checkout, verified transactions, debugged webhook issues, and pulled store analytics... all from within the terminal using Creem CLI and Cline.

Oh, and you can find me on X (Twitter) — @vayospot

Top comments (1)

Collapse
 
botanica_andina profile image
Botánica Andina

The idea of not having to leave the terminal to verify payments is genuinely appealing. That context-switching loop of editor -> browser -> dashboard -> editor is such a productivity killer. How robust is the agent at handling edge cases like network issues or delayed payment notifications?