<?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: karan kartikeya</title>
    <description>The latest articles on DEV Community by karan kartikeya (@karankartikeya).</description>
    <link>https://dev.to/karankartikeya</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%2F425183%2F744b7849-46d9-4ffb-9bbc-1c22ab92219d.jpeg</url>
      <title>DEV Community: karan kartikeya</title>
      <link>https://dev.to/karankartikeya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karankartikeya"/>
    <language>en</language>
    <item>
      <title>Pheromone: Coding Agents works together like Ants using Falkor DB</title>
      <dc:creator>karan kartikeya</dc:creator>
      <pubDate>Sun, 18 Oct 2026 10:39:12 +0000</pubDate>
      <link>https://dev.to/karankartikeya/pheromone-coding-agents-works-together-like-ants-using-falkor-db-2gd4</link>
      <guid>https://dev.to/karankartikeya/pheromone-coding-agents-works-together-like-ants-using-falkor-db-2gd4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;A quick thanks to @WeMakeDevs and FalkorDB for hosting this awesome hackathon Graph Hacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The problem🤷‍♂️
&lt;/h2&gt;

&lt;p&gt;Upgrading a Python codebase from Pydantic v1 to v2 is a classic long-tail job. The official codemod, &lt;code&gt;bump-pydantic&lt;/code&gt;, rewrites the easy parts and leaves &lt;code&gt;# TODO[pydantic]&lt;/code&gt; markers on the rest: validators that read &lt;code&gt;values&lt;/code&gt;, &lt;code&gt;.dict()&lt;/code&gt; and &lt;code&gt;.json()&lt;/code&gt; calls it can't see, removed config keys, custom types built on &lt;code&gt;__get_validators__&lt;/code&gt;, and behaviour that quietly changed (unions, coercion, JSON output). That tail is exactly the kind of work you'd like to hand to several agents at once.&lt;/p&gt;

&lt;p&gt;Problems that occur while several LLM agents work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They don't share memory&lt;/li&gt;
&lt;li&gt;They attempt the same method and try to fix the already fixed library&lt;/li&gt;
&lt;li&gt;Keep running into same failures&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Stigmergy (A fancy term)😎
&lt;/h2&gt;

&lt;p&gt;Ants don't hold meetings. An ant that finds food lays a pheromone trail on the way back; other ants are more likely to follow strong trails; trails nobody reinforces evaporate. Coordination emerges from the environment, not from messages. Biologists call this stigmergy.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Pheromone&lt;/code&gt; applies that to coding agents. The environment is a FalkorDB graph. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A failing test points to a Failure; each Failure has candidate fixes (Hypotheses); &lt;/li&gt;
&lt;li&gt;The edge between them carries a pheromone value. Agents pick hypotheses by a weighted roulette over pheromone, claim one with a single atomic query, try it, and report. &lt;/li&gt;
&lt;li&gt;Only test results change pheromone: a fix that passes reinforces its trail, a fix that fails decays it, and everything evaporates a little every ten seconds. &lt;/li&gt;
&lt;li&gt;The idea got motivated from &lt;code&gt;LLM agents in MIT's SwarmWorld&lt;/code&gt; work; here it runs on real code with tests as the only judge.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwfkvueictv5jts38fgoe.png" width="800" height="500"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Why a graph, not a key-value blackboard📊
&lt;/h2&gt;

&lt;p&gt;I have worked on Agentic memory for sometime and also have had the experience of building an agentic open source memory named &lt;a href="https://github.com/karankartikeya/Engram-Causal" rel="noopener noreferrer"&gt;Engram-Causal&lt;/a&gt;, which mainly answers &lt;code&gt;why did a particular function call passed/failed instead of what the agent did&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A shared dictionary of "who is doing what" would cover claims. The graph earns its place in three other ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast radius.&lt;/strong&gt; Every repo file is a node with &lt;code&gt;IMPORTS&lt;/code&gt; edges to the files it imports. Before a patch merges, the merge gate collects every test that could notice the change with one variable-length match, &lt;code&gt;(f:File {path:$path})&amp;lt;-[:IMPORTS*0..3]-(dep:File)&amp;lt;-[:DEFINED_IN]-(t:Test)&lt;/code&gt;, and requires them to stay green. That's a multi-hop question a flat store can't answer cheaply.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trail behind a fix.&lt;/strong&gt; Every attempt is a node linked to the agent that made it, the hypothesis it tested and the tests it fixed or broke. "Why is this test green?" is one path query from &lt;code&gt;Test&lt;/code&gt; through &lt;code&gt;Failure&lt;/code&gt;, &lt;code&gt;Hypothesis&lt;/code&gt; and &lt;code&gt;Attempt&lt;/code&gt; to &lt;code&gt;Agent&lt;/code&gt;, and the dashboard renders that path with the diff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory that outlives a run.&lt;/strong&gt; When the same kind of fix wins in several places, it becomes a Recipe in a separate &lt;code&gt;recipes&lt;/code&gt; graph. A run on a different repo seeds its hypotheses from Recipes whose signature matches. Signatures (&lt;code&gt;dict-call&lt;/code&gt;, &lt;code&gt;validator-values&lt;/code&gt;, &lt;code&gt;json-encoders&lt;/code&gt;) never contain file paths, which is what lets them transfer.&lt;/p&gt;

&lt;p&gt;Graph algorithms help the agents too: PageRank over the import graph raises the prior on central modules, and weakly connected components group failures into independent clusters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftja9y5x3q6i2r3wmhkb7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftja9y5x3q6i2r3wmhkb7.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Two FalkorDB lessons (and two lessons about tests)👨‍💻
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;There are no multi-query transactions, so every coordination step is one query.&lt;/strong&gt; FalkorDB serializes writes to a graph and each query is atomic, but you can't wrap a read and a write from Python in a transaction. A claim is therefore a compare-and-set in a single statement: match the hypothesis where it's open or its lease has expired, set the new owner, return the id. An empty result means another agent won. Twenty concurrent claims on the same hypothesis produce exactly one winner, and that's a test in the repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;SET&lt;/code&gt; runs on every matched row, even if a &lt;code&gt;LIMIT&lt;/code&gt; comes later.&lt;/strong&gt; A "pick the top candidate and claim it" query with &lt;code&gt;SET ... LIMIT 1&lt;/code&gt; claims every candidate. So the frontier read and the claim are separate queries, and the claim always targets one id.&lt;/p&gt;

&lt;p&gt;We also hit a server crash: a read returning node properties together with &lt;code&gt;collect()&lt;/code&gt; on a hypothesis that had just been claimed panicked inside &lt;code&gt;reply_compact&lt;/code&gt;. Splitting it into plain-row queries fixed it.&lt;/p&gt;

&lt;p&gt;Two lessons came from the tests, not the database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tests decide, so tests can be fooled.&lt;/strong&gt; An agent once made a frozen-model test pass by overriding &lt;code&gt;__eq__&lt;/code&gt; and &lt;code&gt;__setattr__&lt;/code&gt; instead of setting &lt;code&gt;frozen=True&lt;/code&gt;. Pydantic's warning about the leftover &lt;code&gt;allow_mutation&lt;/code&gt; key was only a &lt;code&gt;UserWarning&lt;/code&gt;, so the suite didn't catch it. Treating &lt;code&gt;UserWarning&lt;/code&gt; as an error, and telling agents not to override dunder methods, fixed it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real test suites hide the real error.&lt;/strong&gt; On robusta-dev/krr the swarm stalled with 13 red tests. The CLI under test caught the actual exception (a deprecated &lt;code&gt;.dict()&lt;/code&gt; call in the runner), logged it and exited with code 1, so the test only reported an exit code. And krr's tests depend on run order: a subset of tests can fail where the full suite passes, so correct fixes were rejected as regressions. Reading the logged traceback as the failure's cause, and judging regressions against the same test selection run before the patch, took krr from 42 to all 55 tests green. Along the way the swarm also fixed a deprecated &lt;code&gt;result.json(indent=2)&lt;/code&gt; that the human migration PR had left in place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvqga1qz9f0wsda5s6c62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvqga1qz9f0wsda5s6c62.png" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The scoreboard🧮
&lt;/h2&gt;

&lt;p&gt;I ran the same six agents four ways, with the same model (gpt-6-luna), budget, prompts, hypothesis templates and merge gate. Fifty runs, shuffled, on frozen code, every one ending with all tests green:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseline&lt;/strong&gt;: independent agents, no shared graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coordinated&lt;/strong&gt;: shared graph, claims, leases and attempt history, with pheromone switched off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swarm&lt;/strong&gt;: Coordinated plus pheromone-weighted selection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swarm + Recipes&lt;/strong&gt;: Swarm plus fixes learned on earlier runs (krr only).&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Tokens&lt;/th&gt;
&lt;th&gt;Time to green&lt;/th&gt;
&lt;th&gt;Collisions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gym, Baseline (10 runs)&lt;/td&gt;
&lt;td&gt;150k&lt;/td&gt;
&lt;td&gt;166 s&lt;/td&gt;
&lt;td&gt;124&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gym, Coordinated (10)&lt;/td&gt;
&lt;td&gt;47k&lt;/td&gt;
&lt;td&gt;72 s&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gym, Swarm (10)&lt;/td&gt;
&lt;td&gt;48k&lt;/td&gt;
&lt;td&gt;73 s&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;krr, Baseline (5)&lt;/td&gt;
&lt;td&gt;178k&lt;/td&gt;
&lt;td&gt;243 s&lt;/td&gt;
&lt;td&gt;88&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;krr, Coordinated (5)&lt;/td&gt;
&lt;td&gt;121k&lt;/td&gt;
&lt;td&gt;207 s&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;krr, Swarm (5)&lt;/td&gt;
&lt;td&gt;119k&lt;/td&gt;
&lt;td&gt;205 s&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;krr, Swarm + Recipes (5)&lt;/td&gt;
&lt;td&gt;101k&lt;/td&gt;
&lt;td&gt;253 s&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Shared state is what works. Against independent agents, the graph-coordinated modes used about two thirds fewer tokens on the gym and a third fewer on krr, and collided roughly ten times less often. On the gym they were also more than twice as fast. krr's failures form a chain where each fix reveals the next layer, so the time gain there is smaller.&lt;/p&gt;

&lt;p&gt;Where it didn't win: pheromone. Turning pheromone-weighted selection off changed nothing measurable on either repo. The gains come from shared claims, leases and attempt history. That's partly because the model fixes most of these failures on the first try, which leaves pheromone little to choose between; harder targets, where most attempts fail, are where reinforcement would have to prove itself. Recipes are inconclusive too: they produced 80% of the merged krr fixes and lowered median tokens by 15%, but the ranges overlap and one run was slow.&lt;/p&gt;

&lt;p&gt;The coordination itself held up under load. Thirty agents hammering the claim and report queries for a minute, with short leases and agents that stall on purpose, produced no double claims, no reports accepted after another agent took over, and pheromone values identical to an exact replay. FalkorDB's default queue cap pushed back at that load, which the agents absorbed with backoff.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpbj1xvihh378hmvk3ez6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpbj1xvihh378hmvk3ez6.png" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi89ihapbpy17o6wdynrd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi89ihapbpy17o6wdynrd.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What's next⏭️
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Find out if Recipes compound&lt;/strong&gt;: Recipes produced most of the fixes on krr but didn't measurably cut cost over five runs, partly because the hand-written templates already covered what krr needed. The interesting experiment is a run of ten or more real repositories in a row. If the tenth migration is clearly cheaper than the first, the shared memory is worth something no single run can show.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isolate the graph itself&lt;/strong&gt; Our baseline compares coordinated agents with independent ones. It doesn't tell you how much of the gain needs a graph rather than any shared store. Rebuilding the claims, leases and history on a key-value store, with the same scheduler, would answer that directly. My bet is that the graph's value lies in the questions you can ask afterwards (blast radius, provenance, why a fix won) more than in raw speed, and I'd like to measure it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leave the gym&lt;/strong&gt;: The gym was written for this project and krr is one repository. Next is a handful of real open-source repos with pending Pydantic v2 migrations, opening the swarm's diffs as pull requests and counting how many maintainers merge. Other long-tail upgrades (SQLAlchemy 2.0, Django, NumPy 2) fit the same loop.&lt;/p&gt;

</description>
      <category>wemakedevs</category>
      <category>falkordb</category>
      <category>graphhacks</category>
      <category>agents</category>
    </item>
    <item>
      <title>ERC-8004, Explained for People Who Don't Want to Read the EIP</title>
      <dc:creator>karan kartikeya</dc:creator>
      <pubDate>Mon, 13 Jul 2026 09:14:06 +0000</pubDate>
      <link>https://dev.to/karankartikeya/erc-8004-explained-for-people-who-dont-want-to-read-the-eip-258d</link>
      <guid>https://dev.to/karankartikeya/erc-8004-explained-for-people-who-dont-want-to-read-the-eip-258d</guid>
      <description>&lt;p&gt;Two agents try to transact. One was built on LangChain, the other on a completely different stack nobody's heard of. Neither has any shared way to prove who it is to the other, let alone whether it's done this before and done it well.&lt;/p&gt;

&lt;p&gt;They can still send a payment. Wallets don't care what framework built you. But payment was never the hard part — knowing who's on the other end of it is.&lt;/p&gt;

&lt;p&gt;This happens constantly right now, and almost nobody building agent products is talking about it, because it's not a flashy problem. It's a plumbing problem. Every agent framework today is excellent at orchestration inside its own walls and useless at identity outside them. An agent built in one system is functionally invisible to an agent built in another. No shared name, no shared history, no shared anything.&lt;/p&gt;

&lt;p&gt;That fragmentation is the actual ceiling on agent-to-agent commerce. Not compute, not payments rails, not even trust in the abstract sense — just the boring fact that agents can't legibly recognize each other across systems.&lt;/p&gt;

&lt;p&gt;ERC-8004 is the attempt to fix that. Not a product, not a company's internal solution — a shared on-chain standard so any agent, from any framework, can be identified and read the same way by anyone else, anywhere.&lt;/p&gt;

&lt;p&gt;It's built around two registries, and they solve two genuinely different problems.&lt;/p&gt;

&lt;p&gt;The Identity Registry gives an agent a durable, portable identity that lives on-chain instead of inside whatever platform spun it up. Right now, an agent's "identity" is usually just an account inside someone else's system — delete the account, and the agent's entire existence goes with it. An on-chain identity survives that. It's not owned by the marketplace, the framework, or the hosting provider. It's the agent's own.&lt;/p&gt;

&lt;p&gt;The Reputation Registry does the equivalent for history. Instead of an agent's track record being trapped inside one marketplace's private database — invisible to everyone else, worthless the moment the agent shows up somewhere new — it gives history a standard place to live where any counterparty can read it. Same structure, whoever's asking.&lt;/p&gt;

&lt;p&gt;Here's the part that's easy to undersell: this only works if it's a standard and not a product. If every marketplace built its own version of an identity or reputation registry, agents would be back to square one — legible in one place, invisible everywhere else. The value isn't the registry itself. It's that everyone reads it the same way. That's a coordination problem, not an engineering one, and coordination problems are usually the hardest ones to actually ship.&lt;/p&gt;

&lt;p&gt;Think about what DNS did for the internet. Nobody wakes up excited about DNS. It's invisible until the moment it isn't there, and then nothing resolves. That's the category ERC-8004 is aiming for — boring, load-bearing infrastructure that everything downstream just assumes exists. Once it does, entire categories of products get built on the assumption, the same way nobody building a website today thinks twice about domain resolution.&lt;/p&gt;

&lt;p&gt;But a standard existing doesn't automatically make the data inside it useful. This is the part most explanations skip. An Identity Registry entry tells you an agent exists and has a durable identifier. A Reputation Registry entry gives that agent a place where its history could live. Neither one, by itself, tells a counterparty whether that agent is actually trustworthy.&lt;/p&gt;

&lt;p&gt;Raw entries in a registry are closer to a filing cabinet than a credit score. The registry says the folder exists. It doesn't read the folder for you, weigh what's in it, or tell you whether the pattern of behavior inside it should worry you or reassure you. Someone still has to turn on-chain activity into an actual usable signal — something an insurer, a marketplace, or a service provider can query in real time and get a real answer from, not just a pointer to raw data they'd have to interpret themselves.&lt;/p&gt;

&lt;p&gt;That gap — the standard exists, the interpretation layer doesn't yet — is exactly where the next piece gets built. Not a competing standard. A layer that sits on top of ERC-8004 and does the work of turning registry entries into something you can actually act on.&lt;/p&gt;

&lt;p&gt;We've deployed both the Identity Registry and Reputation Registry live on Base mainnet at SwarmPay, and we're building the indexing layer on top that turns what's in them into an actual queryable reputation score. More on how that scoring works soon.&lt;/p&gt;

&lt;p&gt;If you want early access as this rolls out, sign up for the SwarmPay waitlist.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agenticpayments</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Build a paid membership site using SAWO and Stripe</title>
      <dc:creator>karan kartikeya</dc:creator>
      <pubDate>Thu, 25 Nov 2021 08:17:21 +0000</pubDate>
      <link>https://dev.to/karankartikeya/build-a-paid-membership-site-using-sawo-and-stripe-2gda</link>
      <guid>https://dev.to/karankartikeya/build-a-paid-membership-site-using-sawo-and-stripe-2gda</guid>
      <description>&lt;h1&gt;
  
  
  Build a paid membership site with Stripe and Sawo
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Stripe:&lt;/strong&gt; &amp;nbsp;Online payment processing for internet businesses. Stripe is a suite of payment APIs that powers commerce for online businesses of all sizes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Requirements
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/"&gt;Node.js 15.5+&lt;/a&gt; or later&lt;/li&gt;
&lt;li&gt;MacOS, Windows (including WSL), and Linux are supported&lt;/li&gt;
&lt;li&gt;npm (comes bundled with node.js) or &lt;a href="https://yarnpkg.com/getting-started/install"&gt;yarn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Steps
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Generate SAWO API key
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Navigate to SAWO Dashboard or create a new account &lt;a href="https://dev.sawolabs.com/"&gt;here&lt;/a&gt; and log in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the SAWO dashboard, click on the create project button at the bottom left to create a new project.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GPDss-DP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrv2euag692ks36ym3mo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GPDss-DP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrv2euag692ks36ym3mo.png" alt="Image description" width="619" height="103"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose web and then code since we're working with react framework and will be writing the custom code ourselves.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rq68sJAx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejrjawqw2l9zulq2fb47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rq68sJAx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejrjawqw2l9zulq2fb47.png" alt="Image description" width="880" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click continue. You'll see a similar prompt like the one below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zeHppNXF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dz3x7j51zaoaehswyzq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zeHppNXF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dz3x7j51zaoaehswyzq3.png" alt="Image description" width="502" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name your project with a relevant name.
2.1 For development in a local machine, the hostname should be set to 'localhost'.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If using "localhost" as hostname is not working for you, try "127.0.0.1"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;2.2 For production, the hostname should be set to your domain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are adding your domain do not add 'https://', ''http://', 'www' or even trailing backslash. Example: &lt;a href="https://dev.sawolabs.com/"&gt;https://dev.sawolabs.com/&lt;/a&gt; should be kept as dev.sawolabs.com&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On clicking the create button, we can successfully see the API key created prompt and SAWO keys csv file downloaded.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Generate Stripe API key and create a product with price
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Navigate to Stripe Dashboard or create a new account &lt;a href="https://stripe.com/"&gt;here&lt;/a&gt; and log in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the Stripe dashboard, click on the developers option.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--62Lsv9hy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrs7rzx4ale3q6fogo6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--62Lsv9hy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrs7rzx4ale3q6fogo6c.png" alt="Image description" width="880" height="407"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the developers section head to API keys, and there you can find the secret key and publishable key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move to the products option to create your products with prices.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IGCB7-Y0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eehnlqvfujtq5dgpsi5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IGCB7-Y0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eehnlqvfujtq5dgpsi5e.png" alt="Image description" width="679" height="951"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will be able to see your price id in front of the price info after creating the product.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  3. Install the dependencies
&lt;/h2&gt;

&lt;p&gt;Enter the following command in the terminal to create a Next.js app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i stripe, express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Make endpoints in index.js file and serve your HTML files
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now, create an instance of express and path
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Serve the html files
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/index.html&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/public/login.html&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/success&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/public/success.html&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Listening on port 3000.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Next, let's create an instance of stripe
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stripe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_STRIPE_SECRET_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Import the price id generated above
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;priceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_PRICE_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a Checkout Session for Stripe
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;billing_address_collection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;line_items&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="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prices&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// For metered billing, do not pass quantity&lt;/span&gt;
        &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;success_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;YOUR_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/success.html?session_id={CHECKOUT_SESSION_ID}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cancel_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;YOUR_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/cancel.html`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;303&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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;ul&gt;
&lt;li&gt;Get the price from lookup key
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;lookup_keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lookup_key&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;expand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data.product&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Define the line items:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;line_items&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="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prices&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// For metered billing, do not pass quantity&lt;/span&gt;
        &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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;ul&gt;
&lt;li&gt;Define the success and cancel urls:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;success_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;YOUR_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/success.html?session_id={CHECKOUT_SESSION_ID}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;cancel_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;YOUR_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/cancel.html`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a customer portal session:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;returnUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YOUR_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;portalSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;billingPortal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;checkoutSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;return_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;returnUrl&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;ul&gt;
&lt;li&gt;Provision access:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/webhook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Replace this endpoint secret with your endpoint's unique secret&lt;/span&gt;
    &lt;span class="c1"&gt;// If you are testing with the CLI, find the secret by running 'stripe listen'&lt;/span&gt;
    &lt;span class="c1"&gt;// If you are using an endpoint defined with the API or dashboard, look in your webhook settings&lt;/span&gt;
    &lt;span class="c1"&gt;// at https://dashboard.stripe.com/webhooks&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endpointSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whsec_12345&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Only verify the event if you have an endpoint secret defined.&lt;/span&gt;
    &lt;span class="c1"&gt;// Otherwise use the basic event deserialized with JSON.parse&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endpointSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Get the signature sent by Stripe&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stripe-signature&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;constructEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;endpointSecret&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`⚠️  Webhook signature verification failed.`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendStatus&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="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle the event&lt;/span&gt;
    &lt;span class="k"&gt;switch&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;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.subscription.trial_will_end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&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;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subscription status is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Then define and call a method to handle the subscription trial ending.&lt;/span&gt;
        &lt;span class="c1"&gt;// handleSubscriptionTrialEnding(subscription);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.subscription.deleted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&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;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subscription status is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Then define and call a method to handle the subscription deleted.&lt;/span&gt;
        &lt;span class="c1"&gt;// handleSubscriptionDeleted(subscriptionDeleted);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.subscription.created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&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;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subscription status is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Then define and call a method to handle the subscription created.&lt;/span&gt;
        &lt;span class="c1"&gt;// handleSubscriptionCreated(subscription);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.subscription.updated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&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;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subscription status is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Then define and call a method to handle the subscription update.&lt;/span&gt;
        &lt;span class="c1"&gt;// handleSubscriptionUpdated(subscription);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// Unexpected event type&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Unhandled event type &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;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Return a 200 response to acknowledge receipt of the event&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&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;ul&gt;
&lt;li&gt;If you have followed the tutorial well, you'll see a checkout form similar to the one given below when you head to buying membership button on homepage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RRW9jgXF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/leewt1477jrhe271zr5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RRW9jgXF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/leewt1477jrhe271zr5m.png" alt="Image description" width="880" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9pNtyyx0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2ru93oue59y6k7ag0y3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9pNtyyx0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2ru93oue59y6k7ag0y3.png" alt="Image description" width="880" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Congratulations! You have made it till the end and have learnt how to implement authentication in  SAWO and also integrated Stripe API for paid membership. In case you're facing difficulties, here's a &lt;a href="https://youtu.be/pCR0LZMO2to"&gt;working demo&lt;/a&gt; of the tutorial you just went over. Find the source code for the same &lt;a href="https://github.com/karankartikeya/Paid_membership_site_source_code-Sawo-labs-.git"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;Now that you've learnt how to build a paid-membership site using Stripe and Sawo, feel free to look at the &lt;a href="https://docs.sawolabs.com/sawo/"&gt;SAWO documentation&lt;/a&gt; and integrate some new features in this demo application by forking it in your repo.&lt;/p&gt;

</description>
      <category>sawo</category>
      <category>stripe</category>
      <category>opensource</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to contribute to a NodeJS project uploaded on the Github account of an organization or developer using Git?</title>
      <dc:creator>karan kartikeya</dc:creator>
      <pubDate>Thu, 24 Dec 2020 11:31:20 +0000</pubDate>
      <link>https://dev.to/karankartikeya/how-to-contribute-to-a-nodejs-project-uploaded-on-the-github-account-of-an-organization-or-developer-using-git-5ehe</link>
      <guid>https://dev.to/karankartikeya/how-to-contribute-to-a-nodejs-project-uploaded-on-the-github-account-of-an-organization-or-developer-using-git-5ehe</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;STEPS&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Installation of the dependencies and IDE&lt;/li&gt;
&lt;li&gt;Forking the Project&lt;/li&gt;
&lt;li&gt;Cloning it on your local system &lt;/li&gt;
&lt;li&gt;Make changes&lt;/li&gt;
&lt;li&gt;Committing changes to the Forked repository&lt;/li&gt;
&lt;li&gt;Make a pull request&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Installation of the dependencies
&lt;/h2&gt;

&lt;p&gt;Dependencies that are to be installed for a NodeJs project are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1w315p0s2bm1ybhyeoqa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh4v13cemoousmrqgysfv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/Download" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fegbzn9izu9wtua9798j4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;Install the above dependencies as per your operating system.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Forking the Project
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;This step is not necessary for those wishing to directly contribute and does not want to just pile up the repositories in their account.Those people can skip to the 3rd step directly.&lt;/code&gt;&lt;br&gt;
Now suppose we have to contribute to the below repository, therefore we would need to fork this on our own repository first to edit it. Forking is just like making a copy of something. Therefore we click the Fork button available at the top right corner.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgvco8x5gtzm3sneoy1do.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgvco8x5gtzm3sneoy1do.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
 Then choose the account in which you want to fork it.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fri4b95j4ckn9vgjdbxw5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fri4b95j4ckn9vgjdbxw5.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well done!!!&lt;/strong&gt; You have successfully forked the repository.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqdngk00nn2uvkw2hrkkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqdngk00nn2uvkw2hrkkw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Cloning it on your local system
&lt;/h2&gt;

&lt;p&gt;Now lets start cloning it to our local system.&lt;br&gt;
Head to the forked repository in your account and click on option 'Code' which would result in a dropdown menu. Select the notepad like icon next to the given link and the given link would be copied.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb2na7h5mi0swyiefyi0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb2na7h5mi0swyiefyi0g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Next, open your VS code and click the 'clone repository' option available next to the 'Open folder'.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvmmir9g1lpvnvht5z623.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvmmir9g1lpvnvht5z623.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
After clicking it paste the link to the dialog box which appears and press the Enter key.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm4w8q9q3vffi87zz8ksj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm4w8q9q3vffi87zz8ksj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
A pop-up window appears asking for the local storage of the repository. Choose the desired location and wait for the cloning process to finish.&lt;br&gt;
&lt;strong&gt;Great job!!!&lt;/strong&gt; You have successfully cloned the repository and it's showing in the sidebar.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0pqjyknfwiszhv5fr3dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0pqjyknfwiszhv5fr3dm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4.Make Changes
&lt;/h2&gt;

&lt;p&gt;Now we are good to make the changes in the project. So I would be showing you how to make this project a NodeJs project.&lt;br&gt;
So follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the Terminal option and choose New Terminal&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;npm init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After this fill in the asked details according to your preference or just keep pressing the Enter key.&lt;/li&gt;
&lt;li&gt;Now you can see a package.json file created in the root directory.&lt;/li&gt;
&lt;li&gt;After this you can install &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt;(NodeJs Framework) by typing &lt;code&gt;npm install express&lt;/code&gt;. This would install the Express.js framework in your package file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For users who get an error like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; npm is not recognized as an internal command...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can get it solved from &lt;a href="https://stackoverflow.com/questions/20992723/npm-is-not-recognized-as-internal-or-external-command-operable-program-or-bat" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For users who get an error like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; git is not recognized as an internal command...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can get it solved from &lt;a href="https://stackoverflow.com/questions/4492979/git-is-not-recognized-as-an-internal-or-external-command" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After installing Express.Js, Make an index.js file in the root directory by clicking the new file option in the sidebar above package.json file.&lt;/li&gt;
&lt;li&gt;In the index.js file paste the code given &lt;a href="https://expressjs.com/en/starter/hello-world.html" rel="noopener noreferrer"&gt;here.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Now again head to the terminal window and type &lt;code&gt;node index.js&lt;/code&gt;. You will see a output like this
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example app listening at http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open up your browser and open the port 3000 and congrats you have successfully set up an express app. Move back to the terminal in the VS code and press &lt;code&gt;ctrl+c&lt;/code&gt; to close the server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5.Committing changes to the Forked repository
&lt;/h2&gt;

&lt;p&gt;Now what's left is just committing your work to the Github repository of yours. So let's begin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the terminal and type
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git add .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command would add all the changes made to the Local &lt;br&gt;
 Repository.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next command is
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  git commit -m "Project Upload"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command would commit your changes which are ready to be pushed to the main branch. You can change the message("Project Upload") according to your convenience.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the end type
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  git push -u origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command would push all the changes to your Github account Repository. Refresh your Github Repository page and you would see the changes like this.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa18coao14gp92n96atm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa18coao14gp92n96atm3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Making a pull request
&lt;/h2&gt;

&lt;p&gt;Click on the pull requests option from above and click the &lt;code&gt;New Pull Request&lt;/code&gt; option.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsr5cd6j4alh5tq3x96zj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsr5cd6j4alh5tq3x96zj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Click the &lt;code&gt;Create Pull Request&lt;/code&gt; option and your works done.&lt;br&gt;
Great Job!!! You have successfully made changes to the project and created a pull request. Now just relax and wait for your pull request to get merged by the organization.&lt;/p&gt;

&lt;p&gt;So now you all know how to set up the environment for a NodeJs project and some of the git commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contact me:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karankartikeya" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/karankartikeya/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//mailto:karankartikey72@gmail.com"&gt;Gmail&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vscode</category>
      <category>node</category>
      <category>git</category>
      <category>github</category>
    </item>
  </channel>
</rss>
